summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/tests
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/tests')
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.gd21
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.out7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out11
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out15
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.gd7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out15
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out5
-rw-r--r--modules/gdscript/tests/scripts/parser/.editorconfig2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.gd20
-rw-r--r--modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd17
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.gd14
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd34
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out25
32 files changed, 277 insertions, 1 deletions
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.gd b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.gd
new file mode 100644
index 0000000000..57ae41922f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.gd
@@ -0,0 +1,4 @@
+var v1 = v1
+
+func test():
+ print(v1)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.out b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.out
new file mode 100644
index 0000000000..c337882d9c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_var_self.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Could not resolve member "v1": Cyclic reference.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.gd
new file mode 100644
index 0000000000..7e3b6e3c39
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.gd
@@ -0,0 +1,4 @@
+func test():
+ var a: Array[Resource] = []
+ for node: Node in a:
+ print(node)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.out b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.out
new file mode 100644
index 0000000000..8f8a368f9a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Unable to iterate on value of type "Array[Resource]" with variable of type "Node".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.gd b/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.gd
new file mode 100644
index 0000000000..caeea46977
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.gd
@@ -0,0 +1,9 @@
+# GH-75645
+
+extends Node
+
+static func static_func():
+ var a = $Node
+
+func test():
+ pass
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.out b/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.out
new file mode 100644
index 0000000000..1910b3e66b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/get_node_shorthand_in_static_function.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot use shorthand "get_node()" notation ("$") in a static function.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.gd b/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.gd
new file mode 100644
index 0000000000..51c589b8e0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.gd
@@ -0,0 +1,21 @@
+# GH-80508
+
+class A:
+ func a():
+ return A.new()
+ func b():
+ return B.new()
+
+class B:
+ func a():
+ return A.new()
+ func b():
+ return B.new()
+
+func test():
+ var a := A.new()
+ var b := B.new()
+ print(a.a() is A)
+ print(a.b() is B)
+ print(b.a() is A)
+ print(b.b() is B)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.out b/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.out
new file mode 100644
index 0000000000..f9783e4362
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/inner_class_access_from_inside.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+true
+true
+true
+true
diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
index c4108f50de..b000c82717 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
+++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
@@ -126,7 +126,7 @@ func test():
assert(a_objects.get_typed_builtin() == TYPE_OBJECT)
assert(a_objects.get_typed_script() == A)
- var a_passed = (func check_a_passing(a_objects: Array[A]): return a_objects.size()).call(a_objects)
+ var a_passed = (func check_a_passing(p_objects: Array[A]): return p_objects.size()).call(a_objects)
assert(a_passed == 4)
var b_passed = (func check_b_passing(basic: Array): return basic[0] != null).call(b_objects)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.gd
new file mode 100644
index 0000000000..3178f8d496
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.gd
@@ -0,0 +1,6 @@
+func test():
+ if true:
+ var a = 1
+ print(a)
+ var a = 2
+ print(a)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.out
new file mode 100644
index 0000000000..7365072ea7
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_declaration.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+>> WARNING
+>> Line: 3
+>> CONFUSABLE_LOCAL_DECLARATION
+>> The variable "a" is declared below in the parent block.
+1
+2
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.gd
new file mode 100644
index 0000000000..4462c067bc
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.gd
@@ -0,0 +1,6 @@
+var a = 1
+
+func test():
+ print(a)
+ var a = 2
+ print(a)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out
new file mode 100644
index 0000000000..0e0d607831
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out
@@ -0,0 +1,11 @@
+GDTEST_OK
+>> WARNING
+>> Line: 4
+>> CONFUSABLE_LOCAL_USAGE
+>> The identifier "a" will be shadowed below in the block.
+>> WARNING
+>> Line: 5
+>> SHADOWED_VARIABLE
+>> The local variable "a" is shadowing an already-declared variable at line 1.
+1
+2
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.gd
new file mode 100644
index 0000000000..eef8eb66e6
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.gd
@@ -0,0 +1,6 @@
+var a = 1
+
+func test():
+ print(a)
+ var a = a + 1
+ print(a)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out
new file mode 100644
index 0000000000..228a510490
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out
@@ -0,0 +1,15 @@
+GDTEST_OK
+>> WARNING
+>> Line: 4
+>> CONFUSABLE_LOCAL_USAGE
+>> The identifier "a" will be shadowed below in the block.
+>> WARNING
+>> Line: 5
+>> CONFUSABLE_LOCAL_USAGE
+>> The identifier "a" will be shadowed below in the block.
+>> WARNING
+>> Line: 5
+>> SHADOWED_VARIABLE
+>> The local variable "a" is shadowing an already-declared variable at line 1.
+1
+2
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.gd
new file mode 100644
index 0000000000..1f207f27ac
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.gd
@@ -0,0 +1,7 @@
+var a = 1
+
+func test():
+ for _i in 3:
+ print(a)
+ var a = 2
+ print(a)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out
new file mode 100644
index 0000000000..0d20e9f7a0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out
@@ -0,0 +1,15 @@
+GDTEST_OK
+>> WARNING
+>> Line: 5
+>> CONFUSABLE_LOCAL_USAGE
+>> The identifier "a" will be shadowed below in the block.
+>> WARNING
+>> Line: 6
+>> SHADOWED_VARIABLE
+>> The local variable "a" is shadowing an already-declared variable at line 1.
+1
+2
+1
+2
+1
+2
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd
new file mode 100644
index 0000000000..1b32491e48
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd
@@ -0,0 +1,4 @@
+func test():
+ var a: Array[Node] = []
+ for node: Node in a:
+ print(node)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out
new file mode 100644
index 0000000000..3b3fbd9bd1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+>> WARNING
+>> Line: 3
+>> REDUNDANT_FOR_VARIABLE_TYPE
+>> The for loop iterator "node" already has inferred type "Node", the specified type is redundant.
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd
new file mode 100644
index 0000000000..fcbc13c53d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd
@@ -0,0 +1,4 @@
+func test():
+ var a: Array[Node2D] = []
+ for node: Node in a:
+ print(node)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out
new file mode 100644
index 0000000000..36d4a161d3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+>> WARNING
+>> Line: 3
+>> REDUNDANT_FOR_VARIABLE_TYPE
+>> The for loop iterator "node" has inferred type "Node2D" but its supertype "Node" is specified.
diff --git a/modules/gdscript/tests/scripts/parser/.editorconfig b/modules/gdscript/tests/scripts/parser/.editorconfig
new file mode 100644
index 0000000000..fa43b3ad78
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/.editorconfig
@@ -0,0 +1,2 @@
+[*.{gd,out}]
+trim_trailing_whitespace = false
diff --git a/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.gd b/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.gd
new file mode 100644
index 0000000000..7ee2708999
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.gd
@@ -0,0 +1,20 @@
+# Empty line:
+
+
+# Comment line:
+ # Comment.
+
+func test():
+ print(1)
+
+ if true:
+
+ # Empty line:
+
+
+ print(2)
+
+ # Comment line:
+ # Comment.
+
+ print(3)
diff --git a/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.out b/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.out
new file mode 100644
index 0000000000..c40e402ba3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+1
+2
+3
diff --git a/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.gd b/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.gd
new file mode 100644
index 0000000000..cdc278ecf5
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.gd
@@ -0,0 +1,4 @@
+func test():
+ var a: Array = [Resource.new()]
+ for node: Node in a:
+ print(node)
diff --git a/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.out b/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.out
new file mode 100644
index 0000000000..b7ef07afb2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/for_loop_iterator_type_not_match_specified.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/for_loop_iterator_type_not_match_specified.gd
+>> 3
+>> Trying to assign value of type 'Resource' to a variable of type 'Node'.
diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd
new file mode 100644
index 0000000000..e46f24cc5f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd
@@ -0,0 +1,17 @@
+extends RefCounted # TODO: Fix standalone annotations parsing.
+
+# GH-73843
+@export_group("Resource")
+
+# GH-78252
+@export var prop_1: int
+@export_category("prop_1")
+@export var prop_2: int
+
+func test():
+ var resource := Resource.new()
+ prints("Not shadowed:", resource.get_class())
+
+ for property in get_property_list():
+ if property.name in ["prop_1", "prop_2"]:
+ print(property)
diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out
new file mode 100644
index 0000000000..96ae84e986
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+Not shadowed: Resource
+{ "name": "prop_1", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "prop_1", "class_name": &"", "type": 0, "hint": 0, "hint_string": "", "usage": 128 }
+{ "name": "prop_2", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
diff --git a/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.gd b/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.gd
new file mode 100644
index 0000000000..f17fb9823d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.gd
@@ -0,0 +1,14 @@
+# GH-80157
+
+extends Node
+
+func f():
+ pass
+
+signal s()
+
+func test():
+ print(f)
+ print(s)
+ print(get_child)
+ print(ready)
diff --git a/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.out b/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.out
new file mode 100644
index 0000000000..e5e9ff7043
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/first_class_callable_and_signal.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+Node::f
+Node::[signal]s
+Node::get_child
+Node::[signal]ready
diff --git a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd
new file mode 100644
index 0000000000..58b4df5a79
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd
@@ -0,0 +1,34 @@
+func test():
+ print("Test range.")
+ for e: float in range(2, 5):
+ var elem := e
+ prints(var_to_str(e), var_to_str(elem))
+
+ print("Test int.")
+ for e: float in 3:
+ var elem := e
+ prints(var_to_str(e), var_to_str(elem))
+
+ print("Test untyped int array.")
+ var a1 := [10, 20, 30]
+ for e: float in a1:
+ var elem := e
+ prints(var_to_str(e), var_to_str(elem))
+
+ print("Test typed int array.")
+ var a2: Array[int] = [10, 20, 30]
+ for e: float in a2:
+ var elem := e
+ prints(var_to_str(e), var_to_str(elem))
+
+ print("Test String-keys dictionary.")
+ var d1 := {a = 1, b = 2, c = 3}
+ for k: StringName in d1:
+ var key := k
+ prints(var_to_str(k), var_to_str(key))
+
+ print("Test RefCounted-keys dictionary.")
+ var d2 := {RefCounted.new(): 1, Resource.new(): 2, ConfigFile.new(): 3}
+ for k: RefCounted in d2:
+ var key := k
+ prints(k.get_class(), key.get_class())
diff --git a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out
new file mode 100644
index 0000000000..f67f7d89d5
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out
@@ -0,0 +1,25 @@
+GDTEST_OK
+Test range.
+2.0 2.0
+3.0 3.0
+4.0 4.0
+Test int.
+0.0 0.0
+1.0 1.0
+2.0 2.0
+Test untyped int array.
+10.0 10.0
+20.0 20.0
+30.0 30.0
+Test typed int array.
+10.0 10.0
+20.0 20.0
+30.0 30.0
+Test String-keys dictionary.
+&"a" &"a"
+&"b" &"b"
+&"c" &"c"
+Test RefCounted-keys dictionary.
+RefCounted RefCounted
+Resource Resource
+ConfigFile ConfigFile