| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| |
| #include <cstdint> |
| #include <functional> |
| #include <memory> |
| #include <string> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include <cm3p/cppdap/protocol.h> |
| #include <cm3p/cppdap/types.h> |
| |
| #include "cmDebuggerVariables.h" |
| #include "cmDebuggerVariablesManager.h" |
| |
| #include "testCommon.h" |
| #include "testDebugger.h" |
| |
| static dap::VariablesRequest CreateVariablesRequest(int64_t reference) |
| { |
| dap::VariablesRequest variableRequest; |
| variableRequest.variablesReference = reference; |
| return variableRequest; |
| } |
| |
| static bool testUniqueIds() |
| { |
| auto variablesManager = |
| std::make_shared<cmDebugger::cmDebuggerVariablesManager>(); |
| |
| std::unordered_set<int64_t> variableIds; |
| bool noDuplicateIds = true; |
| for (int i = 0; i < 10000 && noDuplicateIds; ++i) { |
| auto variable = |
| cmDebugger::cmDebuggerVariables(variablesManager, "Locals", true, []() { |
| return std::vector<cmDebugger::cmDebuggerVariableEntry>(); |
| }); |
| |
| if (variableIds.find(variable.GetId()) != variableIds.end()) { |
| noDuplicateIds = false; |
| } |
| variableIds.insert(variable.GetId()); |
| } |
| |
| ASSERT_TRUE(noDuplicateIds); |
| |
| return true; |
| } |
| |
| static bool testConstructors() |
| { |
| auto variablesManager = |
| std::make_shared<cmDebugger::cmDebuggerVariablesManager>(); |
| |
| auto parent = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "Parent", true, [=]() { |
| return std::vector<cmDebugger::cmDebuggerVariableEntry>{ |
| { "ParentKey", "ParentValue", "ParentType" } |
| }; |
| }); |
| |
| auto children1 = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "Children1", true, [=]() { |
| return std::vector<cmDebugger::cmDebuggerVariableEntry>{ |
| { "ChildKey1", "ChildValue1", "ChildType1" }, |
| { "ChildKey2", "ChildValue2", "ChildType2" } |
| }; |
| }); |
| |
| parent->AddSubVariables(children1); |
| |
| auto children2 = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "Children2", true); |
| |
| auto grandChildren21 = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "GrandChildren21", true); |
| grandChildren21->SetValue("GrandChildren21 Value"); |
| children2->AddSubVariables(grandChildren21); |
| parent->AddSubVariables(children2); |
| |
| dap::array<dap::Variable> variables = |
| variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(parent->GetId())); |
| ASSERT_TRUE(variables.size() == 3); |
| ASSERT_VARIABLE_REFERENCE(variables[0], "Children1", "", "collection", |
| children1->GetId()); |
| ASSERT_VARIABLE_REFERENCE(variables[1], "Children2", "", "collection", |
| children2->GetId()); |
| ASSERT_VARIABLE(variables[2], "ParentKey", "ParentValue", "ParentType"); |
| |
| variables = variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(children1->GetId())); |
| ASSERT_TRUE(variables.size() == 2); |
| ASSERT_VARIABLE(variables[0], "ChildKey1", "ChildValue1", "ChildType1"); |
| ASSERT_VARIABLE(variables[1], "ChildKey2", "ChildValue2", "ChildType2"); |
| |
| variables = variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(children2->GetId())); |
| ASSERT_TRUE(variables.size() == 1); |
| ASSERT_VARIABLE_REFERENCE(variables[0], "GrandChildren21", |
| "GrandChildren21 Value", "collection", |
| grandChildren21->GetId()); |
| |
| return true; |
| } |
| |
| static bool testIgnoreEmptyStringEntries() |
| { |
| auto variablesManager = |
| std::make_shared<cmDebugger::cmDebuggerVariablesManager>(); |
| |
| auto vars = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "Variables", true, []() { |
| return std::vector<cmDebugger::cmDebuggerVariableEntry>{ |
| { "IntValue1", 5 }, { "StringValue1", "" }, |
| { "StringValue2", "foo" }, { "StringValue3", "" }, |
| { "StringValue4", "bar" }, { "StringValue5", "" }, |
| { "IntValue2", int64_t(99) }, { "BooleanTrue", true }, |
| { "BooleanFalse", false }, |
| }; |
| }); |
| |
| vars->SetIgnoreEmptyStringEntries(true); |
| vars->SetEnableSorting(false); |
| |
| dap::array<dap::Variable> variables = |
| variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(vars->GetId())); |
| ASSERT_TRUE(variables.size() == 6); |
| ASSERT_VARIABLE(variables[0], "IntValue1", "5", "int"); |
| ASSERT_VARIABLE(variables[1], "StringValue2", "foo", "string"); |
| ASSERT_VARIABLE(variables[2], "StringValue4", "bar", "string"); |
| ASSERT_VARIABLE(variables[3], "IntValue2", "99", "int"); |
| ASSERT_VARIABLE(variables[4], "BooleanTrue", "TRUE", "bool"); |
| ASSERT_VARIABLE(variables[5], "BooleanFalse", "FALSE", "bool"); |
| |
| return true; |
| } |
| |
| static bool testSortTheResult() |
| { |
| auto variablesManager = |
| std::make_shared<cmDebugger::cmDebuggerVariablesManager>(); |
| |
| auto vars = std::make_shared<cmDebugger::cmDebuggerVariables>( |
| variablesManager, "Variables", true, []() { |
| return std::vector<cmDebugger::cmDebuggerVariableEntry>{ |
| { "4", "4" }, { "2", "2" }, { "1", "1" }, { "3", "3" }, { "5", "5" }, |
| }; |
| }); |
| |
| dap::array<dap::Variable> variables = |
| variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(vars->GetId())); |
| ASSERT_TRUE(variables.size() == 5); |
| ASSERT_VARIABLE(variables[0], "1", "1", "string"); |
| ASSERT_VARIABLE(variables[1], "2", "2", "string"); |
| ASSERT_VARIABLE(variables[2], "3", "3", "string"); |
| ASSERT_VARIABLE(variables[3], "4", "4", "string"); |
| ASSERT_VARIABLE(variables[4], "5", "5", "string"); |
| |
| vars->SetEnableSorting(false); |
| |
| variables = variablesManager->HandleVariablesRequest( |
| CreateVariablesRequest(vars->GetId())); |
| ASSERT_TRUE(variables.size() == 5); |
| ASSERT_VARIABLE(variables[0], "4", "4", "string"); |
| ASSERT_VARIABLE(variables[1], "2", "2", "string"); |
| ASSERT_VARIABLE(variables[2], "1", "1", "string"); |
| ASSERT_VARIABLE(variables[3], "3", "3", "string"); |
| ASSERT_VARIABLE(variables[4], "5", "5", "string"); |
| |
| return true; |
| } |
| |
| int testDebuggerVariables(int, char*[]) |
| { |
| return runTests(std::vector<std::function<bool()>>{ |
| testUniqueIds, |
| testConstructors, |
| testIgnoreEmptyStringEntries, |
| testSortTheResult, |
| }); |
| } |