-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[lldb-dap] Add unit test for ColumnDescriptor, BreakpointMode and Breakpoint #139627
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
[lldb-dap] Add unit test for ColumnDescriptor, BreakpointMode and Breakpoint #139627
Conversation
…akpoint Implement fromJSON for ColumnDescriptor, BreakpointMode and Breakpoint and use it to implement the corresponding unit tests.
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesImplement Full diff: https://github.com/llvm/llvm-project/pull/139627.diff 3 Files Affected:
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
index c9cab350f9f12..7c2f4b20f4956 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
@@ -94,6 +94,28 @@ json::Value toJSON(const ExceptionBreakpointsFilter &EBF) {
return result;
}
+bool fromJSON(const json::Value &Params, ColumnType &CT, json::Path P) {
+ auto rawColumnType = Params.getAsString();
+ if (!rawColumnType) {
+ P.report("expected a string");
+ return false;
+ }
+ std::optional<ColumnType> columnType =
+ StringSwitch<std::optional<ColumnType>>(*rawColumnType)
+ .Case("string", eColumnTypeString)
+ .Case("number", eColumnTypeNumber)
+ .Case("boolean", eColumnTypeBoolean)
+ .Case("unixTimestampUTC ", eColumnTypeTimestamp)
+ .Default(std::nullopt);
+ if (!columnType) {
+ P.report("unexpected value, expected 'string', 'number', 'boolean', or "
+ "'unixTimestampUTC'");
+ return false;
+ }
+ CT = *columnType;
+ return true;
+}
+
json::Value toJSON(const ColumnType &T) {
switch (T) {
case eColumnTypeString:
@@ -108,6 +130,14 @@ json::Value toJSON(const ColumnType &T) {
llvm_unreachable("unhandled column type.");
}
+bool fromJSON(const llvm::json::Value &Params, ColumnDescriptor &CD,
+ llvm::json::Path P) {
+ llvm::json::ObjectMapper O(Params, P);
+ return O && O.map("attributeName", CD.attributeName) &&
+ O.map("label", CD.label) && O.mapOptional("format", CD.format) &&
+ O.mapOptional("type", CD.type) && O.mapOptional("width", CD.width);
+}
+
json::Value toJSON(const ColumnDescriptor &CD) {
json::Object result{{"attributeName", CD.attributeName}, {"label", CD.label}};
@@ -149,6 +179,30 @@ json::Value toJSON(const BreakpointModeApplicability &BMA) {
llvm_unreachable("unhandled breakpoint mode applicability.");
}
+bool fromJSON(const llvm::json::Value &Params, BreakpointModeApplicability &BMA,
+ llvm::json::Path P) {
+ auto rawApplicability = Params.getAsString();
+ if (!rawApplicability) {
+ P.report("expected a string");
+ return false;
+ }
+ std::optional<BreakpointModeApplicability> applicability =
+ llvm::StringSwitch<std::optional<BreakpointModeApplicability>>(
+ *rawApplicability)
+ .Case("source", eBreakpointModeApplicabilitySource)
+ .Case("exception", eBreakpointModeApplicabilityException)
+ .Case("data", eBreakpointModeApplicabilityData)
+ .Case("instruction", eBreakpointModeApplicabilityInstruction)
+ .Default(std::nullopt);
+ if (!applicability) {
+ P.report("unexpected value, expected 'source', 'exception', 'data', or "
+ "'instruction'");
+ return false;
+ }
+ BMA = *applicability;
+ return true;
+}
+
json::Value toJSON(const BreakpointMode &BM) {
json::Object result{
{"mode", BM.mode},
@@ -162,6 +216,14 @@ json::Value toJSON(const BreakpointMode &BM) {
return result;
}
+bool fromJSON(const llvm::json::Value &Params, BreakpointMode &BM,
+ llvm::json::Path P) {
+ llvm::json::ObjectMapper O(Params, P);
+ return O && O.map("mode", BM.mode) && O.map("label", BM.label) &&
+ O.mapOptional("description", BM.description) &&
+ O.map("appliesTo", BM.appliesTo);
+}
+
static llvm::StringLiteral ToString(AdapterFeature feature) {
switch (feature) {
case eAdapterFeatureANSIStyling:
@@ -320,6 +382,26 @@ llvm::json::Value toJSON(const BreakpointReason &BR) {
llvm_unreachable("unhandled breakpoint reason.");
}
+bool fromJSON(const llvm::json::Value &Params, BreakpointReason &BR,
+ llvm::json::Path P) {
+ auto rawReason = Params.getAsString();
+ if (!rawReason) {
+ P.report("expected a string");
+ return false;
+ }
+ std::optional<BreakpointReason> reason =
+ llvm::StringSwitch<std::optional<BreakpointReason>>(*rawReason)
+ .Case("pending", BreakpointReason::eBreakpointReasonPending)
+ .Case("failed", BreakpointReason::eBreakpointReasonFailed)
+ .Default(std::nullopt);
+ if (!reason) {
+ P.report("unexpected value, expected 'pending' or 'failed'");
+ return false;
+ }
+ BR = *reason;
+ return true;
+}
+
json::Value toJSON(const Breakpoint &BP) {
json::Object result{{"verified", BP.verified}};
@@ -348,6 +430,20 @@ json::Value toJSON(const Breakpoint &BP) {
return result;
}
+bool fromJSON(const llvm::json::Value &Params, Breakpoint &BP,
+ llvm::json::Path P) {
+ llvm::json::ObjectMapper O(Params, P);
+ return O && O.mapOptional("id", BP.id) && O.map("verified", BP.verified) &&
+ O.mapOptional("message", BP.message) &&
+ O.mapOptional("source", BP.source) && O.mapOptional("line", BP.line) &&
+ O.mapOptional("column", BP.column) &&
+ O.mapOptional("endLine", BP.endLine) &&
+ O.mapOptional("endColumn", BP.endColumn) &&
+ O.mapOptional("instructionReference", BP.instructionReference) &&
+ O.mapOptional("offset", BP.offset) &&
+ O.mapOptional("reason", BP.reason);
+}
+
bool fromJSON(const llvm::json::Value &Params, SourceBreakpoint &SB,
llvm::json::Path P) {
json::ObjectMapper O(Params, P);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
index d1e86b0897675..cab188637acd5 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
@@ -65,6 +65,8 @@ enum ColumnType : unsigned {
eColumnTypeBoolean,
eColumnTypeTimestamp
};
+bool fromJSON(const llvm::json::Value &, ColumnType &, llvm::json::Path);
+llvm::json::Value toJSON(const ColumnType &);
/// A ColumnDescriptor specifies what module attribute to show in a column of
/// the modules view, how to format it, and what the column’s label should be.
@@ -89,6 +91,7 @@ struct ColumnDescriptor {
/// Width of this column in characters (hint only).
std::optional<int> width;
};
+bool fromJSON(const llvm::json::Value &, ColumnDescriptor &, llvm::json::Path);
llvm::json::Value toJSON(const ColumnDescriptor &);
/// Names of checksum algorithms that may be supported by a debug adapter.
@@ -114,6 +117,8 @@ enum BreakpointModeApplicability : unsigned {
/// In `InstructionBreakpoint`'s.
eBreakpointModeApplicabilityInstruction
};
+bool fromJSON(const llvm::json::Value &, BreakpointModeApplicability &,
+ llvm::json::Path);
llvm::json::Value toJSON(const BreakpointModeApplicability &);
/// A `BreakpointMode` is provided as a option when setting breakpoints on
@@ -133,6 +138,7 @@ struct BreakpointMode {
/// Describes one or more type of breakpoint this mode applies to.
std::vector<BreakpointModeApplicability> appliesTo;
};
+bool fromJSON(const llvm::json::Value &, BreakpointMode &, llvm::json::Path);
llvm::json::Value toJSON(const BreakpointMode &);
/// Debug Adapter Features flags supported by lldb-dap.
@@ -364,6 +370,7 @@ enum class BreakpointReason : unsigned {
/// adapter does not believe it can be verified without intervention.
eBreakpointReasonFailed,
};
+bool fromJSON(const llvm::json::Value &, BreakpointReason &, llvm::json::Path);
llvm::json::Value toJSON(const BreakpointReason &);
/// Information about a breakpoint created in `setBreakpoints`,
@@ -415,6 +422,7 @@ struct Breakpoint {
/// should omit this property.
std::optional<BreakpointReason> reason;
};
+bool fromJSON(const llvm::json::Value &, Breakpoint &, llvm::json::Path);
llvm::json::Value toJSON(const Breakpoint &);
/// Properties of a breakpoint or logpoint passed to the `setBreakpoints`
diff --git a/lldb/unittests/DAP/ProtocolTypesTest.cpp b/lldb/unittests/DAP/ProtocolTypesTest.cpp
index fa46816ca4a10..56b21f18fa7cd 100644
--- a/lldb/unittests/DAP/ProtocolTypesTest.cpp
+++ b/lldb/unittests/DAP/ProtocolTypesTest.cpp
@@ -60,3 +60,75 @@ TEST(ProtocolTypesTest, Source) {
EXPECT_EQ(source.sourceReference, deserialized_source->sourceReference);
EXPECT_EQ(source.presentationHint, deserialized_source->presentationHint);
}
+
+TEST(ProtocolTypesTest, ColumnDescriptor) {
+ ColumnDescriptor column;
+ column.attributeName = "moduleName";
+ column.label = "Module Name";
+ column.format = "uppercase";
+ column.type = eColumnTypeString;
+ column.width = 20;
+
+ llvm::Expected<ColumnDescriptor> deserialized_column = roundtrip(column);
+ ASSERT_THAT_EXPECTED(deserialized_column, llvm::Succeeded());
+
+ EXPECT_EQ(column.attributeName, deserialized_column->attributeName);
+ EXPECT_EQ(column.label, deserialized_column->label);
+ EXPECT_EQ(column.format, deserialized_column->format);
+ EXPECT_EQ(column.type, deserialized_column->type);
+ EXPECT_EQ(column.width, deserialized_column->width);
+}
+
+TEST(ProtocolTypesTest, BreakpointMode) {
+ BreakpointMode mode;
+ mode.mode = "testMode";
+ mode.label = "Test Mode";
+ mode.description = "This is a test mode";
+ mode.appliesTo = {eBreakpointModeApplicabilitySource,
+ eBreakpointModeApplicabilityException};
+
+ llvm::Expected<BreakpointMode> deserialized_mode = roundtrip(mode);
+ ASSERT_THAT_EXPECTED(deserialized_mode, llvm::Succeeded());
+
+ EXPECT_EQ(mode.mode, deserialized_mode->mode);
+ EXPECT_EQ(mode.label, deserialized_mode->label);
+ EXPECT_EQ(mode.description, deserialized_mode->description);
+ EXPECT_EQ(mode.appliesTo, deserialized_mode->appliesTo);
+}
+
+TEST(ProtocolTypesTest, Breakpoint) {
+ Breakpoint breakpoint;
+ breakpoint.id = 42;
+ breakpoint.verified = true;
+ breakpoint.message = "Breakpoint set successfully";
+ breakpoint.source =
+ Source{"test.cpp", "/path/to/test.cpp", 123, ePresentationHintNormal};
+ breakpoint.line = 10;
+ breakpoint.column = 5;
+ breakpoint.endLine = 15;
+ breakpoint.endColumn = 10;
+ breakpoint.instructionReference = "0x12345678";
+ breakpoint.offset = 4;
+ breakpoint.reason = BreakpointReason::eBreakpointReasonPending;
+
+ llvm::Expected<Breakpoint> deserialized_breakpoint = roundtrip(breakpoint);
+ ASSERT_THAT_EXPECTED(deserialized_breakpoint, llvm::Succeeded());
+
+ EXPECT_EQ(breakpoint.id, deserialized_breakpoint->id);
+ EXPECT_EQ(breakpoint.verified, deserialized_breakpoint->verified);
+ EXPECT_EQ(breakpoint.message, deserialized_breakpoint->message);
+ EXPECT_EQ(breakpoint.source->name, deserialized_breakpoint->source->name);
+ EXPECT_EQ(breakpoint.source->path, deserialized_breakpoint->source->path);
+ EXPECT_EQ(breakpoint.source->sourceReference,
+ deserialized_breakpoint->source->sourceReference);
+ EXPECT_EQ(breakpoint.source->presentationHint,
+ deserialized_breakpoint->source->presentationHint);
+ EXPECT_EQ(breakpoint.line, deserialized_breakpoint->line);
+ EXPECT_EQ(breakpoint.column, deserialized_breakpoint->column);
+ EXPECT_EQ(breakpoint.endLine, deserialized_breakpoint->endLine);
+ EXPECT_EQ(breakpoint.endColumn, deserialized_breakpoint->endColumn);
+ EXPECT_EQ(breakpoint.instructionReference,
+ deserialized_breakpoint->instructionReference);
+ EXPECT_EQ(breakpoint.offset, deserialized_breakpoint->offset);
+ EXPECT_EQ(breakpoint.reason, deserialized_breakpoint->reason);
+}
|
low-priority ping (I'm doing this in the background and dealing with stacked PRs is a nuisance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Implement
fromJSON
forColumnDescriptor
,BreakpointMode
andBreakpoint
and use it to implement the corresponding unit tests.