Skip to content

Commit 8193294

Browse files
authored
[lldb-dap] Add unit test for ColumnDescriptor, BreakpointMode and Breakpoint (#139627)
Implement `fromJSON` for `ColumnDescriptor`, `BreakpointMode` and `Breakpoint` and use it to implement the corresponding unit tests.
1 parent af54c70 commit 8193294

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,28 @@ json::Value toJSON(const ExceptionBreakpointsFilter &EBF) {
9494
return result;
9595
}
9696

97+
bool fromJSON(const json::Value &Params, ColumnType &CT, json::Path P) {
98+
auto rawColumnType = Params.getAsString();
99+
if (!rawColumnType) {
100+
P.report("expected a string");
101+
return false;
102+
}
103+
std::optional<ColumnType> columnType =
104+
StringSwitch<std::optional<ColumnType>>(*rawColumnType)
105+
.Case("string", eColumnTypeString)
106+
.Case("number", eColumnTypeNumber)
107+
.Case("boolean", eColumnTypeBoolean)
108+
.Case("unixTimestampUTC ", eColumnTypeTimestamp)
109+
.Default(std::nullopt);
110+
if (!columnType) {
111+
P.report("unexpected value, expected 'string', 'number', 'boolean', or "
112+
"'unixTimestampUTC'");
113+
return false;
114+
}
115+
CT = *columnType;
116+
return true;
117+
}
118+
97119
json::Value toJSON(const ColumnType &T) {
98120
switch (T) {
99121
case eColumnTypeString:
@@ -108,6 +130,14 @@ json::Value toJSON(const ColumnType &T) {
108130
llvm_unreachable("unhandled column type.");
109131
}
110132

133+
bool fromJSON(const llvm::json::Value &Params, ColumnDescriptor &CD,
134+
llvm::json::Path P) {
135+
llvm::json::ObjectMapper O(Params, P);
136+
return O && O.map("attributeName", CD.attributeName) &&
137+
O.map("label", CD.label) && O.mapOptional("format", CD.format) &&
138+
O.mapOptional("type", CD.type) && O.mapOptional("width", CD.width);
139+
}
140+
111141
json::Value toJSON(const ColumnDescriptor &CD) {
112142
json::Object result{{"attributeName", CD.attributeName}, {"label", CD.label}};
113143

@@ -149,6 +179,30 @@ json::Value toJSON(const BreakpointModeApplicability &BMA) {
149179
llvm_unreachable("unhandled breakpoint mode applicability.");
150180
}
151181

182+
bool fromJSON(const llvm::json::Value &Params, BreakpointModeApplicability &BMA,
183+
llvm::json::Path P) {
184+
auto rawApplicability = Params.getAsString();
185+
if (!rawApplicability) {
186+
P.report("expected a string");
187+
return false;
188+
}
189+
std::optional<BreakpointModeApplicability> applicability =
190+
llvm::StringSwitch<std::optional<BreakpointModeApplicability>>(
191+
*rawApplicability)
192+
.Case("source", eBreakpointModeApplicabilitySource)
193+
.Case("exception", eBreakpointModeApplicabilityException)
194+
.Case("data", eBreakpointModeApplicabilityData)
195+
.Case("instruction", eBreakpointModeApplicabilityInstruction)
196+
.Default(std::nullopt);
197+
if (!applicability) {
198+
P.report("unexpected value, expected 'source', 'exception', 'data', or "
199+
"'instruction'");
200+
return false;
201+
}
202+
BMA = *applicability;
203+
return true;
204+
}
205+
152206
json::Value toJSON(const BreakpointMode &BM) {
153207
json::Object result{
154208
{"mode", BM.mode},
@@ -162,6 +216,14 @@ json::Value toJSON(const BreakpointMode &BM) {
162216
return result;
163217
}
164218

219+
bool fromJSON(const llvm::json::Value &Params, BreakpointMode &BM,
220+
llvm::json::Path P) {
221+
llvm::json::ObjectMapper O(Params, P);
222+
return O && O.map("mode", BM.mode) && O.map("label", BM.label) &&
223+
O.mapOptional("description", BM.description) &&
224+
O.map("appliesTo", BM.appliesTo);
225+
}
226+
165227
static llvm::StringLiteral ToString(AdapterFeature feature) {
166228
switch (feature) {
167229
case eAdapterFeatureANSIStyling:
@@ -320,6 +382,26 @@ llvm::json::Value toJSON(const BreakpointReason &BR) {
320382
llvm_unreachable("unhandled breakpoint reason.");
321383
}
322384

385+
bool fromJSON(const llvm::json::Value &Params, BreakpointReason &BR,
386+
llvm::json::Path P) {
387+
auto rawReason = Params.getAsString();
388+
if (!rawReason) {
389+
P.report("expected a string");
390+
return false;
391+
}
392+
std::optional<BreakpointReason> reason =
393+
llvm::StringSwitch<std::optional<BreakpointReason>>(*rawReason)
394+
.Case("pending", BreakpointReason::eBreakpointReasonPending)
395+
.Case("failed", BreakpointReason::eBreakpointReasonFailed)
396+
.Default(std::nullopt);
397+
if (!reason) {
398+
P.report("unexpected value, expected 'pending' or 'failed'");
399+
return false;
400+
}
401+
BR = *reason;
402+
return true;
403+
}
404+
323405
json::Value toJSON(const Breakpoint &BP) {
324406
json::Object result{{"verified", BP.verified}};
325407

@@ -348,6 +430,20 @@ json::Value toJSON(const Breakpoint &BP) {
348430
return result;
349431
}
350432

433+
bool fromJSON(const llvm::json::Value &Params, Breakpoint &BP,
434+
llvm::json::Path P) {
435+
llvm::json::ObjectMapper O(Params, P);
436+
return O && O.mapOptional("id", BP.id) && O.map("verified", BP.verified) &&
437+
O.mapOptional("message", BP.message) &&
438+
O.mapOptional("source", BP.source) && O.mapOptional("line", BP.line) &&
439+
O.mapOptional("column", BP.column) &&
440+
O.mapOptional("endLine", BP.endLine) &&
441+
O.mapOptional("endColumn", BP.endColumn) &&
442+
O.mapOptional("instructionReference", BP.instructionReference) &&
443+
O.mapOptional("offset", BP.offset) &&
444+
O.mapOptional("reason", BP.reason);
445+
}
446+
351447
bool fromJSON(const llvm::json::Value &Params, SourceBreakpoint &SB,
352448
llvm::json::Path P) {
353449
json::ObjectMapper O(Params, P);

lldb/tools/lldb-dap/Protocol/ProtocolTypes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ enum ColumnType : unsigned {
6565
eColumnTypeBoolean,
6666
eColumnTypeTimestamp
6767
};
68+
bool fromJSON(const llvm::json::Value &, ColumnType &, llvm::json::Path);
69+
llvm::json::Value toJSON(const ColumnType &);
6870

6971
/// A ColumnDescriptor specifies what module attribute to show in a column of
7072
/// the modules view, how to format it, and what the column’s label should be.
@@ -89,6 +91,7 @@ struct ColumnDescriptor {
8991
/// Width of this column in characters (hint only).
9092
std::optional<int> width;
9193
};
94+
bool fromJSON(const llvm::json::Value &, ColumnDescriptor &, llvm::json::Path);
9295
llvm::json::Value toJSON(const ColumnDescriptor &);
9396

9497
/// Names of checksum algorithms that may be supported by a debug adapter.
@@ -114,6 +117,8 @@ enum BreakpointModeApplicability : unsigned {
114117
/// In `InstructionBreakpoint`'s.
115118
eBreakpointModeApplicabilityInstruction
116119
};
120+
bool fromJSON(const llvm::json::Value &, BreakpointModeApplicability &,
121+
llvm::json::Path);
117122
llvm::json::Value toJSON(const BreakpointModeApplicability &);
118123

119124
/// A `BreakpointMode` is provided as a option when setting breakpoints on
@@ -133,6 +138,7 @@ struct BreakpointMode {
133138
/// Describes one or more type of breakpoint this mode applies to.
134139
std::vector<BreakpointModeApplicability> appliesTo;
135140
};
141+
bool fromJSON(const llvm::json::Value &, BreakpointMode &, llvm::json::Path);
136142
llvm::json::Value toJSON(const BreakpointMode &);
137143

138144
/// Debug Adapter Features flags supported by lldb-dap.
@@ -364,6 +370,7 @@ enum class BreakpointReason : unsigned {
364370
/// adapter does not believe it can be verified without intervention.
365371
eBreakpointReasonFailed,
366372
};
373+
bool fromJSON(const llvm::json::Value &, BreakpointReason &, llvm::json::Path);
367374
llvm::json::Value toJSON(const BreakpointReason &);
368375

369376
/// Information about a breakpoint created in `setBreakpoints`,
@@ -415,6 +422,7 @@ struct Breakpoint {
415422
/// should omit this property.
416423
std::optional<BreakpointReason> reason;
417424
};
425+
bool fromJSON(const llvm::json::Value &, Breakpoint &, llvm::json::Path);
418426
llvm::json::Value toJSON(const Breakpoint &);
419427

420428
/// Properties of a breakpoint or logpoint passed to the `setBreakpoints`

lldb/unittests/DAP/ProtocolTypesTest.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,75 @@ TEST(ProtocolTypesTest, Source) {
6060
EXPECT_EQ(source.sourceReference, deserialized_source->sourceReference);
6161
EXPECT_EQ(source.presentationHint, deserialized_source->presentationHint);
6262
}
63+
64+
TEST(ProtocolTypesTest, ColumnDescriptor) {
65+
ColumnDescriptor column;
66+
column.attributeName = "moduleName";
67+
column.label = "Module Name";
68+
column.format = "uppercase";
69+
column.type = eColumnTypeString;
70+
column.width = 20;
71+
72+
llvm::Expected<ColumnDescriptor> deserialized_column = roundtrip(column);
73+
ASSERT_THAT_EXPECTED(deserialized_column, llvm::Succeeded());
74+
75+
EXPECT_EQ(column.attributeName, deserialized_column->attributeName);
76+
EXPECT_EQ(column.label, deserialized_column->label);
77+
EXPECT_EQ(column.format, deserialized_column->format);
78+
EXPECT_EQ(column.type, deserialized_column->type);
79+
EXPECT_EQ(column.width, deserialized_column->width);
80+
}
81+
82+
TEST(ProtocolTypesTest, BreakpointMode) {
83+
BreakpointMode mode;
84+
mode.mode = "testMode";
85+
mode.label = "Test Mode";
86+
mode.description = "This is a test mode";
87+
mode.appliesTo = {eBreakpointModeApplicabilitySource,
88+
eBreakpointModeApplicabilityException};
89+
90+
llvm::Expected<BreakpointMode> deserialized_mode = roundtrip(mode);
91+
ASSERT_THAT_EXPECTED(deserialized_mode, llvm::Succeeded());
92+
93+
EXPECT_EQ(mode.mode, deserialized_mode->mode);
94+
EXPECT_EQ(mode.label, deserialized_mode->label);
95+
EXPECT_EQ(mode.description, deserialized_mode->description);
96+
EXPECT_EQ(mode.appliesTo, deserialized_mode->appliesTo);
97+
}
98+
99+
TEST(ProtocolTypesTest, Breakpoint) {
100+
Breakpoint breakpoint;
101+
breakpoint.id = 42;
102+
breakpoint.verified = true;
103+
breakpoint.message = "Breakpoint set successfully";
104+
breakpoint.source =
105+
Source{"test.cpp", "/path/to/test.cpp", 123, ePresentationHintNormal};
106+
breakpoint.line = 10;
107+
breakpoint.column = 5;
108+
breakpoint.endLine = 15;
109+
breakpoint.endColumn = 10;
110+
breakpoint.instructionReference = "0x12345678";
111+
breakpoint.offset = 4;
112+
breakpoint.reason = BreakpointReason::eBreakpointReasonPending;
113+
114+
llvm::Expected<Breakpoint> deserialized_breakpoint = roundtrip(breakpoint);
115+
ASSERT_THAT_EXPECTED(deserialized_breakpoint, llvm::Succeeded());
116+
117+
EXPECT_EQ(breakpoint.id, deserialized_breakpoint->id);
118+
EXPECT_EQ(breakpoint.verified, deserialized_breakpoint->verified);
119+
EXPECT_EQ(breakpoint.message, deserialized_breakpoint->message);
120+
EXPECT_EQ(breakpoint.source->name, deserialized_breakpoint->source->name);
121+
EXPECT_EQ(breakpoint.source->path, deserialized_breakpoint->source->path);
122+
EXPECT_EQ(breakpoint.source->sourceReference,
123+
deserialized_breakpoint->source->sourceReference);
124+
EXPECT_EQ(breakpoint.source->presentationHint,
125+
deserialized_breakpoint->source->presentationHint);
126+
EXPECT_EQ(breakpoint.line, deserialized_breakpoint->line);
127+
EXPECT_EQ(breakpoint.column, deserialized_breakpoint->column);
128+
EXPECT_EQ(breakpoint.endLine, deserialized_breakpoint->endLine);
129+
EXPECT_EQ(breakpoint.endColumn, deserialized_breakpoint->endColumn);
130+
EXPECT_EQ(breakpoint.instructionReference,
131+
deserialized_breakpoint->instructionReference);
132+
EXPECT_EQ(breakpoint.offset, deserialized_breakpoint->offset);
133+
EXPECT_EQ(breakpoint.reason, deserialized_breakpoint->reason);
134+
}

0 commit comments

Comments
 (0)