Skip to content

[lldb-dap] Add unit test for protocol enum types #139848

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

Merged
merged 1 commit into from
May 14, 2025

Conversation

JDevlieghere
Copy link
Member

Add dedicated unit tests for the protocol enum types.

Add dedicated unit tests for the protocol enum types.
@llvmbot
Copy link
Member

llvmbot commented May 14, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Add dedicated unit tests for the protocol enum types.


Full diff: https://github.com/llvm/llvm-project/pull/139848.diff

3 Files Affected:

  • (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp (+13-1)
  • (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.h (+1)
  • (modified) lldb/unittests/DAP/ProtocolTypesTest.cpp (+198)
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
index fafd061334bc9..857503b3a0084 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
@@ -105,7 +105,7 @@ bool fromJSON(const json::Value &Params, ColumnType &CT, json::Path P) {
           .Case("string", eColumnTypeString)
           .Case("number", eColumnTypeNumber)
           .Case("boolean", eColumnTypeBoolean)
-          .Case("unixTimestampUTC ", eColumnTypeTimestamp)
+          .Case("unixTimestampUTC", eColumnTypeTimestamp)
           .Default(std::nullopt);
   if (!columnType) {
     P.report("unexpected value, expected 'string', 'number',  'boolean', or "
@@ -482,6 +482,18 @@ bool fromJSON(const llvm::json::Value &Params, SteppingGranularity &SG,
   return true;
 }
 
+llvm::json::Value toJSON(const SteppingGranularity &SG) {
+  switch (SG) {
+  case eSteppingGranularityStatement:
+    return "statement";
+  case eSteppingGranularityLine:
+    return "line";
+  case eSteppingGranularityInstruction:
+    return "instruction";
+  }
+  llvm_unreachable("unhandled stepping granularity.");
+}
+
 bool fromJSON(const llvm::json::Value &Params, ValueFormat &VF,
               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 f8d2b35ce3e14..757037a7b6ed2 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
@@ -339,6 +339,7 @@ enum SteppingGranularity : unsigned {
 };
 bool fromJSON(const llvm::json::Value &, SteppingGranularity &,
               llvm::json::Path);
+llvm::json::Value toJSON(const SteppingGranularity &);
 
 /// Provides formatting information for a value.
 struct ValueFormat {
diff --git a/lldb/unittests/DAP/ProtocolTypesTest.cpp b/lldb/unittests/DAP/ProtocolTypesTest.cpp
index fd3e3be073183..d97bbaffa2bc0 100644
--- a/lldb/unittests/DAP/ProtocolTypesTest.cpp
+++ b/lldb/unittests/DAP/ProtocolTypesTest.cpp
@@ -291,3 +291,201 @@ TEST(ProtocolTypesTest, Capabilities) {
   EXPECT_EQ(capabilities.lldbExtVersion,
             deserialized_capabilities->lldbExtVersion);
 }
+
+TEST(ProtocolTypesTest, PresentationHint) {
+  // Test all PresentationHint values.
+  std::vector<std::pair<PresentationHint, llvm::StringRef>> test_cases = {
+      {ePresentationHintNormal, "normal"},
+      {ePresentationHintEmphasize, "emphasize"},
+      {ePresentationHintDeemphasize, "deemphasize"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the PresentationHint to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to PresentationHint.
+    PresentationHint deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_hint";
+  PresentationHint deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, SteppingGranularity) {
+  // Test all SteppingGranularity values.
+  std::vector<std::pair<SteppingGranularity, llvm::StringRef>> test_cases = {
+      {eSteppingGranularityStatement, "statement"},
+      {eSteppingGranularityLine, "line"},
+      {eSteppingGranularityInstruction, "instruction"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the SteppingGranularity to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to SteppingGranularity.
+    SteppingGranularity deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_granularity";
+  SteppingGranularity deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, BreakpointReason) {
+  // Test all BreakpointReason values.
+  std::vector<std::pair<BreakpointReason, llvm::StringRef>> test_cases = {
+      {BreakpointReason::eBreakpointReasonPending, "pending"},
+      {BreakpointReason::eBreakpointReasonFailed, "failed"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the BreakpointReason to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to BreakpointReason.
+    BreakpointReason deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_reason";
+  BreakpointReason deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, DataBreakpointAccessType) {
+  // Test all DataBreakpointAccessType values.
+  std::vector<std::pair<DataBreakpointAccessType, llvm::StringRef>> test_cases =
+      {{eDataBreakpointAccessTypeRead, "read"},
+       {eDataBreakpointAccessTypeWrite, "write"},
+       {eDataBreakpointAccessTypeReadWrite, "readWrite"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the DataBreakpointAccessType to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to DataBreakpointAccessType.
+    DataBreakpointAccessType deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value
+  llvm::json::Value invalid_value = "invalid_access_type";
+  DataBreakpointAccessType deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, ColumnType) {
+  // Test all ColumnType values.
+  std::vector<std::pair<ColumnType, llvm::StringRef>> test_cases = {
+      {eColumnTypeString, "string"},
+      {eColumnTypeNumber, "number"},
+      {eColumnTypeBoolean, "boolean"},
+      {eColumnTypeTimestamp, "unixTimestampUTC"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the ColumnType to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to ColumnType.
+    ColumnType deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_column_type";
+  ColumnType deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, BreakpointModeApplicability) {
+  // Test all BreakpointModeApplicability values.
+  std::vector<std::pair<BreakpointModeApplicability, llvm::StringRef>>
+      test_cases = {{eBreakpointModeApplicabilitySource, "source"},
+                    {eBreakpointModeApplicabilityException, "exception"},
+                    {eBreakpointModeApplicabilityData, "data"},
+                    {eBreakpointModeApplicabilityInstruction, "instruction"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the BreakpointModeApplicability to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to BreakpointModeApplicability.
+    BreakpointModeApplicability deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_applicability";
+  BreakpointModeApplicability deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}
+
+TEST(ProtocolTypesTest, ChecksumAlgorithm) {
+  // Test all ChecksumAlgorithm values.
+  std::vector<std::pair<ChecksumAlgorithm, llvm::StringRef>> test_cases = {
+      {eChecksumAlgorithmMD5, "MD5"},
+      {eChecksumAlgorithmSHA1, "SHA1"},
+      {eChecksumAlgorithmSHA256, "SHA256"},
+      {eChecksumAlgorithmTimestamp, "timestamp"}};
+
+  for (const auto &test_case : test_cases) {
+    // Serialize the ChecksumAlgorithm to JSON.
+    llvm::json::Value serialized = toJSON(test_case.first);
+    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+    EXPECT_EQ(serialized.getAsString(), test_case.second);
+
+    // Deserialize the JSON back to ChecksumAlgorithm.
+    ChecksumAlgorithm deserialized;
+    llvm::json::Path::Root root;
+    ASSERT_TRUE(fromJSON(serialized, deserialized, root))
+        << llvm::toString(root.getError());
+    EXPECT_EQ(deserialized, test_case.first);
+  }
+
+  // Test invalid value.
+  llvm::json::Value invalid_value = "invalid_algorithm";
+  ChecksumAlgorithm deserialized_invalid;
+  llvm::json::Path::Root root;
+  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));
+}

@@ -105,7 +105,7 @@ bool fromJSON(const json::Value &Params, ColumnType &CT, json::Path P) {
.Case("string", eColumnTypeString)
.Case("number", eColumnTypeNumber)
.Case("boolean", eColumnTypeBoolean)
.Case("unixTimestampUTC ", eColumnTypeTimestamp)
.Case("unixTimestampUTC", eColumnTypeTimestamp)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My unit test found an actual bug/typo :-)

Copy link
Contributor

@ashgti ashgti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@JDevlieghere JDevlieghere merged commit 998dca4 into llvm:main May 14, 2025
13 checks passed
@JDevlieghere JDevlieghere deleted the lldb-dap-enum-types branch May 14, 2025 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants