Skip to content

Commit d2ce6b8

Browse files
authored
Merge pull request #436 from godot-rust/bugfix/test-failure
Smaller integration and unit-test updates (NaN eq, list failed, ...)
2 parents 639aeb4 + fb13d1a commit d2ce6b8

File tree

11 files changed

+92
-28
lines changed

11 files changed

+92
-28
lines changed

.github/workflows/full-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ on:
1515

1616
env:
1717
GDEXT_FEATURES: ''
18+
# GDEXT_FEATURES: '--features godot/serde'
1819
RETRY: ${{ github.workspace }}/.github/other/retry.sh
1920

2021
# LSan options: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer

godot-bindings/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ godot4-prebuilt = { optional = true, git = "https://github.com/godot-rust/godot4
2525
bindgen = { optional = true, version = "0.65", default-features = false, features = ["runtime"] }
2626
regex = { optional = true, version = "1.5.5", default-features = false, features = ["std", "unicode-gencat"] }
2727
which = { optional = true, version = "4" }
28+
29+
[dev-dependencies]
30+
# For tests, we need regex unconditionally. Keep this in sync with above dependency.
31+
regex = { version = "1.5.5", default-features = false, features = ["std", "unicode-gencat"] }

godot-bindings/src/godot_version.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn parse_godot_version(version_str: &str) -> Result<GodotVersion, Box<dyn Er
1616
// https://github.com/godot-rust/gdext/issues/118#issuecomment-1465748123
1717
// We assume that it's on a line of its own, but it may be surrounded by other lines.
1818
let regex = Regex::new(
19-
r#"(?xm)
19+
r"(?xm)
2020
# x: ignore whitespace and allow line comments (starting with `#`)
2121
# m: multi-line mode, ^ and $ match start and end of line
2222
^
@@ -32,15 +32,17 @@ pub fn parse_godot_version(version_str: &str) -> Result<GodotVersion, Box<dyn Er
3232
(\.[^.]+)+?
3333
# Git commit SHA1, currently truncated to 9 chars, but accept the full thing
3434
(?:\.(?P<custom_rev>[a-f0-9]{9,40}))?
35+
# Optional newline printed in some systems (e.g. Arch Linux, see #416)
36+
(?:\\n)?
3537
$
36-
"#,
38+
",
3739
)?;
3840

3941
let fail = || format!("Version substring cannot be parsed: `{version_str}`");
4042
let caps = regex.captures(version_str).ok_or_else(fail)?;
4143

4244
Ok(GodotVersion {
43-
full_string: caps.get(0).unwrap().as_str().to_string(),
45+
full_string: caps.get(0).unwrap().as_str().trim().to_string(),
4446
major: cap(&caps, "major")?.unwrap(),
4547
minor: cap(&caps, "minor")?.unwrap(),
4648
patch: cap(&caps, "patch")?.unwrap_or(0),
@@ -86,6 +88,7 @@ fn test_godot_versions() {
8688
("4.0.beta8.mono.custom_build.b28ddd918", 4, 0, 0, "beta8", s("b28ddd918")),
8789
("4.0.rc1.official.8843d9ad3", 4, 0, 0, "rc1", s("8843d9ad3")),
8890
("4.0.stable.arch_linux", 4, 0, 0, "stable", None),
91+
("4.1.1.stable.arch_linux\n", 4, 1, 1, "stable", None),
8992
// Output from 4.0.stable on MacOS in debug mode:
9093
// https://github.com/godotengine/godot/issues/74906
9194
("arguments
@@ -104,7 +107,7 @@ Current path: /Users/runner/work/gdext/gdext/godot-core
104107
for (full, major, minor, patch, status, custom_rev) in good_versions {
105108
let expected = GodotVersion {
106109
// Version line is last in every test at the moment.
107-
full_string: full.lines().last().unwrap().to_owned(),
110+
full_string: full.lines().last().unwrap().trim().to_owned(),
108111
major,
109112
minor,
110113
patch,

godot-bindings/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub struct GodotVersion {
4040
// ----------------------------------------------------------------------------------------------------------------------------------------------
4141
// Regenerate all files
4242

43+
// This file is explicitly included in unit tests. Needs regex dependency.
44+
#[cfg(test)]
45+
mod godot_version;
46+
4347
#[cfg(feature = "custom-godot")]
4448
#[path = ""]
4549
mod custom {

godot-core/src/builtin/callable.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,4 @@ mod custom_callable {
425425
w.name.clone().move_string_ptr(r_out);
426426
*r_is_valid = true as sys::GDExtensionBool;
427427
}
428-
429-
pub fn unqualified_type_name<T>() -> &'static str {
430-
let type_name = std::any::type_name::<T>();
431-
type_name.split("::").last().unwrap()
432-
}
433428
}

godot-core/src/builtin/dictionary.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ impl Dictionary {
142142
}
143143

144144
/// Returns a 32-bit integer hash value representing the dictionary and its contents.
145+
#[must_use]
145146
pub fn hash(&self) -> u32 {
146147
self.as_inner().hash().try_into().unwrap()
147148
}

godot-ffi/src/toolbox.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ pub fn hash_value<T: std::hash::Hash>(t: &T) -> u64 {
138138
hasher.finish()
139139
}
140140

141+
/*
142+
pub fn unqualified_type_name<T>() -> &'static str {
143+
let type_name = std::any::type_name::<T>();
144+
type_name.split("::").last().unwrap()
145+
}
146+
*/
147+
141148
// ----------------------------------------------------------------------------------------------------------------------------------------------
142149
// Private helpers
143150

itest/godot/ManualFfiTests.gd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ func test_missing_init():
99

1010
var expr = Expression.new()
1111
var error = expr.parse("WithoutInit.new()")
12-
if !assert_eq(error, OK, "Failed to parse dynamic expression"):
12+
if not assert_eq(error, OK, "Failed to parse dynamic expression"):
1313
return
1414

1515
var instance = expr.execute()
16-
if !assert_that(!expr.has_execute_failed(), "Failed to evaluate dynamic expression"):
16+
if not assert_that(!expr.has_execute_failed(), "Failed to evaluate dynamic expression"):
1717
return
1818

1919
print("[GD] WithoutInit is: ", instance)

itest/godot/TestRunner.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class GDScriptExecutableTestCase extends GDScriptTestCase:
9292
# This is a no-op if the suite doesn't have this property.
9393
suite.set("_assertion_failed", false)
9494
var result = suite.call(method_name)
95-
var ok: bool = (result == true || result == null) && !suite.get("_assertion_failed")
95+
var ok: bool = (result == true or result == null) and not suite.get("_assertion_failed")
9696
return ok
9797

9898
# Hardcoded test case used for special cases where the standard testing API is not sufficient.

itest/rust/src/builtin_tests/containers/dictionary_test.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ fn dictionary_clone() {
9595
"foo": 0,
9696
"bar": subdictionary.clone()
9797
};
98+
9899
#[allow(clippy::redundant_clone)]
99100
let clone = dictionary.clone();
100101
Dictionary::from_variant(&clone.get("bar").unwrap()).insert("final", 4);
@@ -103,12 +104,33 @@ fn dictionary_clone() {
103104

104105
#[itest]
105106
fn dictionary_hash() {
106-
let dictionary = dict! {
107+
use godot::builtin::Vector2i;
108+
109+
let a = dict! {
107110
"foo": 0,
108111
"bar": true,
109-
"baz": "foobar"
112+
(Vector2i::new(4, -1)): "foobar",
113+
};
114+
let b = dict! {
115+
"foo": 0,
116+
"bar": true,
117+
(Vector2i::new(4, -1)): "foobar" // No comma to test macro.
110118
};
111-
dictionary.hash();
119+
let c = dict! {
120+
"foo": 0,
121+
(Vector2i::new(4, -1)): "foobar",
122+
"bar": true,
123+
};
124+
125+
assert_eq!(a.hash(), b.hash(), "equal dictionaries have same hash");
126+
assert_ne!(
127+
a.hash(),
128+
c.hash(),
129+
"dictionaries with reordered content have different hash"
130+
);
131+
132+
// NaNs are not equal (since Godot 4.2) but share same hash.
133+
assert_eq!(dict! {772: f32::NAN}.hash(), dict! {772: f32::NAN}.hash());
112134
}
113135

114136
#[itest]
@@ -328,8 +350,13 @@ fn dictionary_keys_values() {
328350
#[itest]
329351
fn dictionary_equal() {
330352
assert_eq!(dict! {"foo": "bar"}, dict! {"foo": "bar"});
331-
assert_eq!(dict! {1: f32::NAN}, dict! {1: f32::NAN}); // yes apparently Godot considers these equal
332353
assert_ne!(dict! {"foo": "bar"}, dict! {"bar": "foo"});
354+
355+
// Changed in https://github.com/godotengine/godot/pull/74588.
356+
#[cfg(before_api = "4.2")]
357+
assert_eq!(dict! {1: f32::NAN}, dict! {1: f32::NAN});
358+
#[cfg(since_api = "4.2")]
359+
assert_ne!(dict! {1: f32::NAN}, dict! {1: f32::NAN});
333360
}
334361

335362
#[itest]

0 commit comments

Comments
 (0)