Skip to content

Commit 5fdd0d6

Browse files
committed
[lldb-dap] Add unit tests for protocol types
Add unit tests for serializing and deserializing protocol types.
1 parent 5b91756 commit 5fdd0d6

File tree

2 files changed

+269
-0
lines changed

2 files changed

+269
-0
lines changed

lldb/unittests/DAP/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_lldb_unittest(DAPTests
22
JSONUtilsTest.cpp
33
LLDBUtilsTest.cpp
4+
ProtocolTypesTest.cpp
45

56
LINK_LIBS
67
lldbDAP
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
//===-- ProtocolTypesTest.cpp -----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "Protocol/ProtocolTypes.h"
10+
#include "gtest/gtest.h"
11+
12+
using namespace llvm;
13+
using namespace lldb;
14+
using namespace lldb_dap;
15+
using namespace lldb_dap::protocol;
16+
17+
TEST(ProtocolTypesTest, ExceptionBreakpointsFilter) {
18+
ExceptionBreakpointsFilter filter;
19+
filter.filter = "testFilter";
20+
filter.label = "Test Filter";
21+
filter.description = "This is a test filter";
22+
filter.defaultState = true;
23+
filter.supportsCondition = true;
24+
filter.conditionDescription = "Condition for test filter";
25+
26+
llvm::json::Value value = toJSON(filter);
27+
const json::Object *obj = value.getAsObject();
28+
ASSERT_NE(obj, nullptr);
29+
30+
EXPECT_EQ(obj->getString("filter"), "testFilter");
31+
EXPECT_EQ(obj->getString("label"), "Test Filter");
32+
EXPECT_EQ(obj->getString("description"), "This is a test filter");
33+
EXPECT_EQ(obj->getBoolean("default"), true);
34+
EXPECT_EQ(obj->getBoolean("supportsCondition"), true);
35+
EXPECT_EQ(obj->getString("conditionDescription"),
36+
"Condition for test filter");
37+
}
38+
39+
TEST(ProtocolTypesTest, ColumnDescriptor) {
40+
ColumnDescriptor column;
41+
column.attributeName = "testAttribute";
42+
column.label = "Test Label";
43+
column.format = "testFormat";
44+
column.type = eColumnTypeString;
45+
column.width = 20;
46+
47+
llvm::json::Value value = toJSON(column);
48+
const json::Object *obj = value.getAsObject();
49+
ASSERT_NE(obj, nullptr);
50+
51+
EXPECT_EQ(obj->getString("attributeName"), "testAttribute");
52+
EXPECT_EQ(obj->getString("label"), "Test Label");
53+
EXPECT_EQ(obj->getString("format"), "testFormat");
54+
EXPECT_EQ(obj->getString("type"), "string");
55+
EXPECT_EQ(obj->getInteger("width"), 20);
56+
}
57+
58+
TEST(ProtocolTypesTest, BreakpointMode) {
59+
BreakpointMode mode;
60+
mode.mode = "testMode";
61+
mode.label = "Test Label";
62+
mode.description = "This is a test description";
63+
mode.appliesTo = {eBreakpointModeApplicabilitySource,
64+
eBreakpointModeApplicabilityException};
65+
66+
llvm::json::Value value = toJSON(mode);
67+
const json::Object *obj = value.getAsObject();
68+
ASSERT_NE(obj, nullptr);
69+
70+
EXPECT_EQ(obj->getString("mode"), "testMode");
71+
EXPECT_EQ(obj->getString("label"), "Test Label");
72+
EXPECT_EQ(obj->getString("description"), "This is a test description");
73+
74+
const auto *appliesToArray = obj->getArray("appliesTo");
75+
ASSERT_NE(appliesToArray, nullptr);
76+
ASSERT_EQ(appliesToArray->size(), 2UL);
77+
EXPECT_EQ(appliesToArray->front().getAsString(), "source");
78+
EXPECT_EQ(appliesToArray->back().getAsString(), "exception");
79+
}
80+
81+
TEST(ProtocolTypesTest, Capabilities) {
82+
Capabilities capabilities;
83+
capabilities.supportedFeatures = {eAdapterFeatureANSIStyling,
84+
eAdapterFeatureTerminateRequest};
85+
capabilities.exceptionBreakpointFilters = {
86+
{"filter1", "Filter 1", "Description 1", true, true, "Condition 1"},
87+
{"filter2", "Filter 2", "Description 2", false, false, "Condition 2"}};
88+
capabilities.completionTriggerCharacters = {"."};
89+
capabilities.additionalModuleColumns = {
90+
{"attribute1", "Label 1", "Format 1", eColumnTypeString, 10},
91+
{"attribute2", "Label 2", "Format 2", eColumnTypeNumber, 20}};
92+
capabilities.supportedChecksumAlgorithms = {eChecksumAlgorithmMD5,
93+
eChecksumAlgorithmSHA256};
94+
capabilities.breakpointModes = {{"mode1",
95+
"Mode 1",
96+
"Description 1",
97+
{eBreakpointModeApplicabilitySource}},
98+
{"mode2",
99+
"Mode 2",
100+
"Description 2",
101+
{eBreakpointModeApplicabilityException}}};
102+
capabilities.lldbExtVersion = "1.0.0";
103+
104+
llvm::json::Value value = toJSON(capabilities);
105+
const json::Object *obj = value.getAsObject();
106+
ASSERT_NE(obj, nullptr);
107+
108+
// Verify supported features.
109+
EXPECT_EQ(obj->getBoolean("supportsANSIStyling"), true);
110+
EXPECT_EQ(obj->getBoolean("supportsTerminateRequest"), true);
111+
112+
// Verify exception breakpoint filters.
113+
const auto *filtersArray = obj->getArray("exceptionBreakpointFilters");
114+
ASSERT_NE(filtersArray, nullptr);
115+
ASSERT_EQ(filtersArray->size(), 2UL);
116+
const auto *filter1 = filtersArray->front().getAsObject();
117+
ASSERT_NE(filter1, nullptr);
118+
EXPECT_EQ(filter1->getString("filter"), "filter1");
119+
EXPECT_EQ(filter1->getString("label"), "Filter 1");
120+
EXPECT_EQ(filter1->getString("description"), "Description 1");
121+
EXPECT_EQ(filter1->getBoolean("default"), true);
122+
EXPECT_EQ(filter1->getBoolean("supportsCondition"), true);
123+
EXPECT_EQ(filter1->getString("conditionDescription"), "Condition 1");
124+
125+
const auto *filter2 = filtersArray->back().getAsObject();
126+
ASSERT_NE(filter2, nullptr);
127+
EXPECT_EQ(filter2->getString("filter"), "filter2");
128+
EXPECT_EQ(filter2->getString("label"), "Filter 2");
129+
EXPECT_EQ(filter2->getString("description"), "Description 2");
130+
EXPECT_EQ(filter2->getBoolean("default"), false);
131+
EXPECT_EQ(filter2->getBoolean("supportsCondition"), false);
132+
EXPECT_EQ(filter2->getString("conditionDescription"), "Condition 2");
133+
134+
// Verify completion trigger characters.
135+
const auto *completionArray = obj->getArray("completionTriggerCharacters");
136+
ASSERT_NE(completionArray, nullptr);
137+
ASSERT_EQ(completionArray->size(), 1UL);
138+
EXPECT_EQ(completionArray->front().getAsString(), ".");
139+
140+
// Verify additional module columns.
141+
const auto *columnsArray = obj->getArray("additionalModuleColumns");
142+
ASSERT_NE(columnsArray, nullptr);
143+
ASSERT_EQ(columnsArray->size(), 2UL);
144+
const auto *column1 = columnsArray->front().getAsObject();
145+
ASSERT_NE(column1, nullptr);
146+
EXPECT_EQ(column1->getString("attributeName"), "attribute1");
147+
EXPECT_EQ(column1->getString("label"), "Label 1");
148+
EXPECT_EQ(column1->getString("format"), "Format 1");
149+
EXPECT_EQ(column1->getString("type"), "string");
150+
EXPECT_EQ(column1->getInteger("width"), 10);
151+
152+
const auto *column2 = columnsArray->back().getAsObject();
153+
ASSERT_NE(column2, nullptr);
154+
EXPECT_EQ(column2->getString("attributeName"), "attribute2");
155+
EXPECT_EQ(column2->getString("label"), "Label 2");
156+
EXPECT_EQ(column2->getString("format"), "Format 2");
157+
EXPECT_EQ(column2->getString("type"), "number");
158+
EXPECT_EQ(column2->getInteger("width"), 20);
159+
160+
// Verify supported checksum algorithms.
161+
const auto *checksumArray = obj->getArray("supportedChecksumAlgorithms");
162+
ASSERT_NE(checksumArray, nullptr);
163+
ASSERT_EQ(checksumArray->size(), 2UL);
164+
EXPECT_EQ(checksumArray->front().getAsString(), "MD5");
165+
EXPECT_EQ(checksumArray->back().getAsString(), "SHA256");
166+
167+
// Verify breakpoint modes.
168+
const auto *modesArray = obj->getArray("breakpointModes");
169+
ASSERT_NE(modesArray, nullptr);
170+
ASSERT_EQ(modesArray->size(), 2UL);
171+
const auto *mode1 = modesArray->front().getAsObject();
172+
ASSERT_NE(mode1, nullptr);
173+
EXPECT_EQ(mode1->getString("mode"), "mode1");
174+
EXPECT_EQ(mode1->getString("label"), "Mode 1");
175+
EXPECT_EQ(mode1->getString("description"), "Description 1");
176+
const auto *appliesTo1 = mode1->getArray("appliesTo");
177+
ASSERT_NE(appliesTo1, nullptr);
178+
ASSERT_EQ(appliesTo1->size(), 1UL);
179+
EXPECT_EQ(appliesTo1->front().getAsString(), "source");
180+
181+
const auto *mode2 = modesArray->back().getAsObject();
182+
ASSERT_NE(mode2, nullptr);
183+
EXPECT_EQ(mode2->getString("mode"), "mode2");
184+
EXPECT_EQ(mode2->getString("label"), "Mode 2");
185+
EXPECT_EQ(mode2->getString("description"), "Description 2");
186+
const auto *appliesTo2 = mode2->getArray("appliesTo");
187+
ASSERT_NE(appliesTo2, nullptr);
188+
ASSERT_EQ(appliesTo2->size(), 1UL);
189+
EXPECT_EQ(appliesTo2->front().getAsString(), "exception");
190+
191+
// Verify lldb extension version.
192+
EXPECT_EQ(obj->getString("$__lldb_version"), "1.0.0");
193+
}
194+
195+
TEST(ProtocolTypesTest, Source) {
196+
Source source;
197+
source.name = "testName";
198+
source.path = "/path/to/source";
199+
source.sourceReference = 12345;
200+
source.presentationHint = ePresentationHintEmphasize;
201+
202+
llvm::json::Value value = toJSON(source);
203+
204+
Source deserialized_source;
205+
llvm::json::Path::Root root;
206+
ASSERT_TRUE(fromJSON(value, deserialized_source, root));
207+
208+
ASSERT_EQ(source.name, deserialized_source.name);
209+
ASSERT_EQ(source.path, deserialized_source.path);
210+
ASSERT_EQ(source.sourceReference, deserialized_source.sourceReference);
211+
ASSERT_EQ(source.presentationHint, deserialized_source.presentationHint);
212+
}
213+
214+
TEST(ProtocolTypesTest, BreakpointLocation) {
215+
BreakpointLocation location;
216+
location.line = 42;
217+
location.column = 5;
218+
location.endLine = 50;
219+
location.endColumn = 10;
220+
221+
llvm::json::Value value = toJSON(location);
222+
const json::Object *obj = value.getAsObject();
223+
ASSERT_NE(obj, nullptr);
224+
225+
EXPECT_EQ(obj->getInteger("line"), 42);
226+
EXPECT_EQ(obj->getInteger("column"), 5);
227+
EXPECT_EQ(obj->getInteger("endLine"), 50);
228+
EXPECT_EQ(obj->getInteger("endColumn"), 10);
229+
}
230+
231+
TEST(ProtocolTypesTest, Breakpoint) {
232+
Breakpoint breakpoint;
233+
breakpoint.id = 1;
234+
breakpoint.verified = true;
235+
breakpoint.message = "Breakpoint set successfully";
236+
breakpoint.source = {"testSource", "/path/to/source", 12345,
237+
ePresentationHintNormal};
238+
breakpoint.line = 42;
239+
breakpoint.column = 5;
240+
breakpoint.endLine = 50;
241+
breakpoint.endColumn = 10;
242+
breakpoint.instructionReference = "0x1234";
243+
breakpoint.offset = -4;
244+
breakpoint.reason = BreakpointReason::eBreakpointReasonPending;
245+
246+
llvm::json::Value value = toJSON(breakpoint);
247+
const json::Object *obj = value.getAsObject();
248+
ASSERT_NE(obj, nullptr);
249+
250+
EXPECT_EQ(obj->getInteger("id"), 1);
251+
EXPECT_EQ(obj->getBoolean("verified"), true);
252+
EXPECT_EQ(obj->getString("message"), "Breakpoint set successfully");
253+
254+
const auto *source_obj = obj->getObject("source");
255+
ASSERT_NE(source_obj, nullptr);
256+
EXPECT_EQ(source_obj->getString("name"), "testSource");
257+
EXPECT_EQ(source_obj->getString("path"), "/path/to/source");
258+
EXPECT_EQ(source_obj->getInteger("sourceReference"), 12345);
259+
EXPECT_EQ(source_obj->getString("presentationHint"), "normal");
260+
261+
EXPECT_EQ(obj->getInteger("line"), 42);
262+
EXPECT_EQ(obj->getInteger("column"), 5);
263+
EXPECT_EQ(obj->getInteger("endLine"), 50);
264+
EXPECT_EQ(obj->getInteger("endColumn"), 10);
265+
EXPECT_EQ(obj->getString("instructionReference"), "0x1234");
266+
EXPECT_EQ(obj->getInteger("offset"), -4);
267+
EXPECT_EQ(obj->getString("reason"), "pending");
268+
}

0 commit comments

Comments
 (0)