Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying a scene in completion tests #86961

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions modules/gdscript/tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,44 @@ and output files.
See the
[Integration tests for GDScript documentation](https://docs.godotengine.org/en/latest/contributing/development/core_and_modules/unit_testing.html#integration-tests-for-gdscript)
for information about creating and running GDScript integration tests.

# GDScript Autocompletion tests

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 config file contains two section:

`[input]` contains keys that configure the test environment. The following keys are possible:

- `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.

`[output]` specifies the expected results for the test. The following key are supported:

- `include: Array`: An unordered list of suggestions that should be in the result. Each entry is one dictionary with the following keys: `display`, `insert_text`, `kind`, `location`, which correspond to the suggestion struct which is used in the code. The runner only tests against specified keys, so in most cases `display` will suffice.
- `exclude: Array`: An array of suggestions which should not be in the result. The entries take the same form as for `include`.
- `call_hint: String`: The expected call hint returned by autocompletion.
- `forced: boolean`: Whether autocompletion is expected to force opening a completion window.

Tests will only test against entries in `[output]` that were specified.

## Writing autocompletion tests

To avoid failing edge cases a certain behaviour needs to be tested multiple times. Some things that tests should account for:

- All possible types: Test with all possible types that apply to the tested behaviour. (For the last points testing against `SCRIPT` and `CLASS` should suffice. `CLASS` can be obtained through C#, `SCRIPT` through GDScript. Relying on autoloads to be of type `SCRIPT` is not good, since this might change in the future.)

- `BUILTIN`
- `NATIVE`
- GDScripts (with `class_name` as well as `preload`ed)
- C# (as standin for all other language bindings) (with `class_name` as well as `preload`ed)
- Autoloads

- Possible contexts: the completion might be placed in different places of the program. e.g:
- initializers of class members
- directly inside a suite
- assignments inside a suite
- as parameter to a call
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[output]
expected=[
include=[
{"display": "autoplay"},
]
18 changes: 11 additions & 7 deletions modules/gdscript/tests/test_completion.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,23 @@ static void test_directory(const String &p_dir) {
EditorSettings::get_singleton()->set_setting("text_editor/completion/use_single_quotes", conf.get_value("input", "use_single_quotes", false));

List<Dictionary> include;
to_dict_list(conf.get_value("result", "include", Array()), include);
to_dict_list(conf.get_value("output", "include", Array()), include);

List<Dictionary> exclude;
to_dict_list(conf.get_value("result", "exclude", Array()), exclude);
to_dict_list(conf.get_value("output", "exclude", Array()), exclude);

List<ScriptLanguage::CodeCompletionOption> options;
String call_hint;
bool forced;

Node *owner = nullptr;
if (dir->file_exists(next.get_basename() + ".tscn")) {
String project_path = "res://completion";
Ref<PackedScene> scene = ResourceLoader::load(project_path.path_join(next.get_basename() + ".tscn"), "PackedScene");
if (conf.has_section_key("input", "scene")) {
Ref<PackedScene> scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene");
if (scene.is_valid()) {
owner = 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();
}
Expand Down Expand Up @@ -169,8 +173,8 @@ static void test_directory(const String &p_dir) {
CHECK_MESSAGE(contains_excluded.is_empty(), "Autocompletion suggests illegal option '", contains_excluded, "' for '", path.path_join(next), "'.");
CHECK(include.is_empty());

String expected_call_hint = conf.get_value("result", "call_hint", call_hint);
bool expected_forced = conf.get_value("result", "forced", forced);
String expected_call_hint = conf.get_value("output", "call_hint", call_hint);
bool expected_forced = conf.get_value("output", "forced", forced);

CHECK(expected_call_hint == call_hint);
CHECK(expected_forced == forced);
Expand Down
Loading