mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
362 lines
18 KiB
C++
362 lines
18 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
|
* reserved. This project is released under the MIT License.
|
|
*/
|
|
#include "GDCore/IDE/Events/ExpressionCompletionFinder.h"
|
|
|
|
#include "DummyPlatform.h"
|
|
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
|
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
|
#include "GDCore/Extensions/Platform.h"
|
|
#include "GDCore/Extensions/PlatformExtension.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "catch.hpp"
|
|
|
|
TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
|
gd::Project project;
|
|
gd::Platform platform;
|
|
SetupProjectWithDummyPlatform(project, platform);
|
|
auto& layout1 = project.InsertNewLayout("Layout1", 0);
|
|
|
|
gd::ExpressionParser2 parser(platform, project, layout1);
|
|
|
|
auto getCompletionsFor = [&](const gd::String& type,
|
|
const gd::String& expression,
|
|
size_t location) {
|
|
auto node = parser.ParseExpression(type, expression);
|
|
REQUIRE(node != nullptr);
|
|
return gd::ExpressionCompletionFinder::GetCompletionDescriptionsFor(
|
|
*node, location);
|
|
};
|
|
|
|
const std::vector<gd::ExpressionCompletionDescription>
|
|
expectedEmptyCompletions;
|
|
|
|
SECTION("Identifier") {
|
|
SECTION("Object or expression completions when type is string") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject("string", "My", 0, 2),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "My", 0, 2)};
|
|
REQUIRE(getCompletionsFor("string", "My", 0) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("string", "My", 1) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("string", "My", 2) == expectedEmptyCompletions);
|
|
}
|
|
SECTION("Object or expression completions when type is number") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject("number", "My", 0, 2),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"number", "My", 0, 2)};
|
|
REQUIRE(getCompletionsFor("number", "My", 0) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("number", "My", 1) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("number", "My", 2) == expectedEmptyCompletions);
|
|
}
|
|
SECTION("Object or expression completions when type is number|string") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"number|string", "My", 0, 2),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"number|string", "My", 0, 2)};
|
|
REQUIRE(getCompletionsFor("number|string", "My", 0) ==
|
|
expectedCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "My", 1) ==
|
|
expectedCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "My", 2) ==
|
|
expectedEmptyCompletions);
|
|
}
|
|
SECTION("Object when type is an object") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject("object", "My", 0, 2)};
|
|
REQUIRE(getCompletionsFor("object", "My", 0) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("object", "My", 1) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("object", "My", 2) == expectedEmptyCompletions);
|
|
}
|
|
|
|
SECTION("Object when type is an object (alternate type)") {
|
|
// Also test alternate types also considered as objects (but that can
|
|
// result in different code generation):
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"objectPtr", "My", 0, 2)};
|
|
REQUIRE(getCompletionsFor("objectPtr", "My", 0) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("objectPtr", "My", 1) == expectedCompletions);
|
|
REQUIRE(getCompletionsFor("objectPtr", "My", 2) ==
|
|
expectedEmptyCompletions);
|
|
}
|
|
}
|
|
SECTION("Operator (number)") {
|
|
REQUIRE(getCompletionsFor("number", "1 + ", 1) == expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("number", "1 + ", 2) == expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("number", "1 + ", 3) == expectedEmptyCompletions);
|
|
}
|
|
SECTION("Operator (string)") {
|
|
REQUIRE(getCompletionsFor("string", "\"a\" + ", 3) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "\"a\" + ", 4) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "\"a\" + ", 5) ==
|
|
expectedEmptyCompletions);
|
|
}
|
|
|
|
SECTION("Free function") {
|
|
SECTION("Test 1") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Function", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription> expectedExactCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Function", 0, 8)
|
|
.SetIsExact(true)};
|
|
REQUIRE(getCompletionsFor("string", "Function(", 0) ==
|
|
expectedCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function(", 1) ==
|
|
expectedCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function(", 7) ==
|
|
expectedCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function(", 8) ==
|
|
expectedExactCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function(", 9) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function()", 9) ==
|
|
expectedExactCompletions);
|
|
}
|
|
SECTION("Unknown function, test with arguments") {
|
|
REQUIRE(getCompletionsFor("string", "Function(1", 9) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "Function(\"", 9) ==
|
|
expectedEmptyCompletions);
|
|
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject("unknown", "a", 9, 10),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"unknown", "a", 9, 10)};
|
|
REQUIRE(getCompletionsFor("string", "Function(a", 9) ==
|
|
expectedCompletions);
|
|
}
|
|
SECTION("Function with a Variable as argument") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForVariable(
|
|
"scenevar", "myVar", 33, 38)};
|
|
REQUIRE(getCompletionsFor("number",
|
|
"MyExtension::GetVariableAsNumber(myVar",
|
|
33) == expectedCompletions);
|
|
}
|
|
SECTION("Function with a Layer as argument") {
|
|
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
|
gd::ExpressionCompletionDescription::ForText(
|
|
"layer",
|
|
gd::MetadataProvider::GetExpressionMetadata(platform,
|
|
"MyExtension::MouseX")
|
|
.GetParameter(0),
|
|
"",
|
|
20,
|
|
21,
|
|
false)};
|
|
REQUIRE(getCompletionsFor("number", "MyExtension::MouseX(\"", 20) ==
|
|
expectedCompletions);
|
|
}
|
|
}
|
|
|
|
SECTION("Partial object or behavior function") {
|
|
SECTION("Test with string type") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorOrFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"Func", 9, 13, "MyObject"),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 9, 13, "MyObject")};
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 8) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 9) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 12) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func", 13) ==
|
|
expectedEmptyCompletions);
|
|
}
|
|
SECTION("Test with 'number|string' type") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"number|string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorOrFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"Func", 9, 13, "MyObject"),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"number|string", "Func", 9, 13, "MyObject")};
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 8) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 9) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 12) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 13) ==
|
|
expectedEmptyCompletions);
|
|
}
|
|
}
|
|
|
|
SECTION("Object function") {
|
|
SECTION("Test 1") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorOrFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"Func", 9, 13, "MyObject"),
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 9, 13, "MyObject")};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedExactFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 9, 13, "MyObject")
|
|
.SetIsExact(true)};
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 8) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 9) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 12) ==
|
|
expectedBehaviorOrFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 13) ==
|
|
expectedExactFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 14) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.Func()", 14) ==
|
|
expectedExactFunctionCompletions);
|
|
}
|
|
}
|
|
|
|
SECTION("Partial behavior function") {
|
|
SECTION("Test 1") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"MyBehavior", 9, 19, "MyObject")};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 21, 25, "MyObject", "MyBehavior")};
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 8) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 9) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 18) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 19) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 20) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 21) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 23) ==
|
|
expectedFunctionCompletions);
|
|
}
|
|
SECTION("Test 2") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"MyBehavior", 9, 19, "MyObject")};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "", 21, 21, "MyObject", "MyBehavior")};
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 8) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 9) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 18) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 19) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 20) ==
|
|
expectedFunctionCompletions);
|
|
}
|
|
}
|
|
|
|
SECTION("Behavior function") {
|
|
SECTION("Test 1") {
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedObjectCompletions{
|
|
gd::ExpressionCompletionDescription::ForObject(
|
|
"string", "MyObject", 0, 8)};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedBehaviorCompletions{
|
|
gd::ExpressionCompletionDescription::ForBehavior(
|
|
"MyBehavior", 9, 19, "MyObject")};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 21, 25, "MyObject", "MyBehavior")};
|
|
std::vector<gd::ExpressionCompletionDescription>
|
|
expectedExactFunctionCompletions{
|
|
gd::ExpressionCompletionDescription::ForExpression(
|
|
"string", "Func", 21, 25, "MyObject", "MyBehavior")
|
|
.SetIsExact(true)};
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 0) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 7) ==
|
|
expectedObjectCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 8) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 9) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 18) ==
|
|
expectedBehaviorCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 19) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 20) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 21) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 22) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 23) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 24) ==
|
|
expectedFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 25) ==
|
|
expectedExactFunctionCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 26) ==
|
|
expectedEmptyCompletions);
|
|
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func()", 26) ==
|
|
expectedExactFunctionCompletions);
|
|
}
|
|
}
|
|
}
|