ソースを参照

Completion Tests: Add script to owner

HolonProduction 1 年間 前
コミット
d2c2194937
39 ファイル変更100 行追加11 行削除
  1. 7 0
      modules/gdscript/tests/README.md
  2. 3 0
      modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn
  3. 8 0
      modules/gdscript/tests/scripts/completion/argument_options/connect.cfg
  4. 7 0
      modules/gdscript/tests/scripts/completion/argument_options/connect.gd
  5. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd
  6. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd
  7. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd
  8. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd
  9. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd
  10. 1 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd
  11. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local/local.gd
  12. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
  13. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
  14. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
  15. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd
  16. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd
  17. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd
  18. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd
  19. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd
  20. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd
  21. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd
  22. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd
  23. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd
  24. 1 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd
  25. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member/member.gd
  26. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
  27. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
  28. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
  29. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd
  30. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd
  31. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd
  32. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd
  33. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd
  34. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd
  35. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd
  36. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd
  37. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd
  38. 1 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd
  39. 41 11
      modules/gdscript/tests/test_completion.h

+ 7 - 0
modules/gdscript/tests/README.md

@@ -13,6 +13,12 @@ The `script/completion` folder contains test for the GDScript autocompletion.
 
 Each test case consists of at least one `.gd` file, which contains the code, and one `.cfg` file, which contains expected results and configuration. Inside of the GDScript file the character `➡` represents the cursor position, at which autocompletion is invoked.
 
+The script files won't be parsable GDScript since it contains an invalid char and and often the code is not complete during autocompletion. To allow for a valid base when used with a scene, the
+runner will remove the line which contains `➡`. Therefore the scripts need to be valid if this line is removed, otherwise the test might behave in unexpected ways. This may for example require
+adding an additional `pass` statement.
+
+This also means, that the runner will add the script to its owner node, so the script should not be loaded through the scene file.
+
 The config file contains two section:
 
 `[input]` contains keys that configure the test environment. The following keys are possible:
@@ -20,6 +26,7 @@ The config file contains two section:
 - `cs: boolean = false`: If `true`, the test will be skipped when running a non C# build.
 - `use_single_quotes: boolean = false`: Configures the corresponding editor setting for the test.
 - `scene: String`: Allows to specify a scene which is opened while autocompletion is performed. If this is not set the test runner will search for a `.tscn` file with the same basename as the GDScript file. If that isn't found either, autocompletion will behave as if no scene was opened.
+- `node_path: String`: The node path of the node which holds the current script inside of the scene. Defaults to the scene root node.
 
 `[output]` specifies the expected results for the test. The following key are supported:
 

+ 3 - 0
modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn

@@ -0,0 +1,3 @@
+[gd_scene load_steps=1 format=3 uid="uid://dl28pdkxcjvym"]
+
+[node name="GetNode" type="Node"]

+ 8 - 0
modules/gdscript/tests/scripts/completion/argument_options/connect.cfg

@@ -0,0 +1,8 @@
+[input]
+scene="res://completion/argument_options/argument_options.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "\"signal_a\""},
+    {"display": "\"child_entered_tree\""},
+]

+ 7 - 0
modules/gdscript/tests/scripts/completion/argument_options/connect.gd

@@ -0,0 +1,7 @@
+extends Node
+
+signal signal_a()
+
+func _ready():
+    connect(➡)
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     %AnimationPlayer.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     $UniqueAnimationPlayer.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     $A.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     $AnimationPlayer.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     %UniqueA.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd

@@ -2,3 +2,4 @@ extends Node
 
 func a():
     %UniqueAnimationPlayer.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local/local.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test := $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test := $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test := $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test = $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd

@@ -5,3 +5,4 @@ const A := preload("res://completion/class_a.notest.gd")
 func a():
     var test: A = $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test: AnimationPlayer = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd

@@ -5,3 +5,4 @@ const A := preload("res://completion/class_a.notest.gd")
 func a():
     var test: A = $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test: AnimationPlayer = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd

@@ -4,3 +4,4 @@ extends Node
 func a():
     var test: Node = $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd

@@ -4,3 +4,4 @@ extends Node
 func a():
     var test: Node = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test: Area2D = $A
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd

@@ -3,3 +3,4 @@ extends Node
 func a():
     var test: Area2D = $AnimationPlayer
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member/member.gd

@@ -4,3 +4,4 @@ var test = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd

@@ -4,3 +4,4 @@ var test := $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd

@@ -4,3 +4,4 @@ var test := $A
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd

@@ -4,3 +4,4 @@ var test := $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd

@@ -4,3 +4,4 @@ var test = $A
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd

@@ -4,3 +4,4 @@ var test = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd

@@ -6,3 +6,4 @@ var test: A = $A
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd

@@ -4,3 +4,4 @@ var test: AnimationPlayer = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd

@@ -6,3 +6,4 @@ const A := preload("res://completion/class_a.notest.gd")
 
 func a():
 	test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd

@@ -4,3 +4,4 @@ var test: AnimationPlayer = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd

@@ -4,3 +4,4 @@ var test: Node = $A
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd

@@ -4,3 +4,4 @@ var test: Node = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd

@@ -4,3 +4,4 @@ var test: Area2D = $A
 
 func a():
     test.➡
+    pass

+ 1 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd

@@ -4,3 +4,4 @@ var test: Area2D = $AnimationPlayer
 
 func a():
     test.➡
+    pass

+ 41 - 11
modules/gdscript/tests/test_completion.h

@@ -33,6 +33,7 @@
 
 #ifdef TOOLS_ENABLED
 
+#include "core/config/project_settings.h"
 #include "core/io/config_file.h"
 #include "core/io/dir_access.h"
 #include "core/io/file_access.h"
@@ -111,7 +112,10 @@ static void test_directory(const String &p_dir) {
 			// For ease of reading ➡ (0x27A1) acts as sentinel char instead of 0xFFFF in the files.
 			code = code.replace_first(String::chr(0x27A1), String::chr(0xFFFF));
 			// Require pointer sentinel char in scripts.
-			CHECK(code.find_char(0xFFFF) != -1);
+			int location = code.find_char(0xFFFF);
+			CHECK(location != -1);
+
+			String res_path = ProjectSettings::get_singleton()->localize_path(path.path_join(next));
 
 			ConfigFile conf;
 			if (conf.load(path.path_join(next.get_basename() + ".cfg")) != OK) {
@@ -137,20 +141,46 @@ static void test_directory(const String &p_dir) {
 			String call_hint;
 			bool forced;
 
-			Node *owner = nullptr;
+			Node *scene = nullptr;
 			if (conf.has_section_key("input", "scene")) {
-				Ref<PackedScene> scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP);
-				if (scene.is_valid()) {
-					owner = scene->instantiate();
+				Ref<PackedScene> packed_scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP);
+				if (packed_scene.is_valid()) {
+					scene = packed_scene->instantiate();
 				}
 			} else if (dir->file_exists(next.get_basename() + ".tscn")) {
-				Ref<PackedScene> scene = ResourceLoader::load(path.path_join(next.get_basename() + ".tscn"), "PackedScene");
-				if (scene.is_valid()) {
-					owner = scene->instantiate();
+				Ref<PackedScene> packed_scene = ResourceLoader::load(path.path_join(next.get_basename() + ".tscn"), "PackedScene");
+				if (packed_scene.is_valid()) {
+					scene = packed_scene->instantiate();
+				}
+			}
+			Node *owner = nullptr;
+			if (scene != nullptr) {
+				owner = scene->get_node(conf.get_value("input", "node_path", "."));
+			}
+
+			if (owner != nullptr) {
+				// Remove the line which contains the sentinel char, to get a valid script.
+				Ref<GDScript> scr;
+				scr.instantiate();
+				int start = location;
+				int end = location;
+				for (; start >= 0; --start) {
+					if (code.get(start) == '\n') {
+						break;
+					}
+				}
+				for (; end < code.size(); ++end) {
+					if (code.get(end) == '\n') {
+						break;
+					}
 				}
+				scr->set_source_code(code.erase(start, end - start));
+				scr->reload();
+				scr->set_path(res_path);
+				owner->set_script(scr);
 			}
 
-			GDScriptLanguage::get_singleton()->complete_code(code, path.path_join(next), owner, &options, forced, call_hint);
+			GDScriptLanguage::get_singleton()->complete_code(code, res_path, owner, &options, forced, call_hint);
 			String contains_excluded;
 			for (ScriptLanguage::CodeCompletionOption &option : options) {
 				for (const Dictionary &E : exclude) {
@@ -179,8 +209,8 @@ static void test_directory(const String &p_dir) {
 			CHECK(expected_call_hint == call_hint);
 			CHECK(expected_forced == forced);
 
-			if (owner) {
-				memdelete(owner);
+			if (scene) {
+				memdelete(scene);
 			}
 		}
 		next = dir->get_next();