brintos

brintos / llvm-project-archived public Read only

0
0
Text · 42.0 KiB · 6a4620a Raw
1179 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Protocol/ProtocolTypes.h"10#include "Protocol/ProtocolEvents.h"11#include "Protocol/ProtocolRequests.h"12#include "TestingSupport/TestUtilities.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/Support/JSON.h"15#include "llvm/Testing/Support/Error.h"16#include "gmock/gmock.h"17#include "gtest/gtest.h"18#include <optional>19 20using namespace llvm;21using namespace lldb;22using namespace lldb_dap;23using namespace lldb_dap::protocol;24using lldb_private::roundtripJSON;25using llvm::json::parse;26using llvm::json::Value;27 28/// Returns a pretty printed json string of a `llvm::json::Value`.29static std::string pp(const json::Value &E) {30  return formatv("{0:2}", E).str();31}32 33TEST(ProtocolTypesTest, ExceptionBreakpointsFilter) {34  ExceptionBreakpointsFilter filter;35  filter.filter = "testFilter";36  filter.label = "Test Filter";37  filter.description = "This is a test filter";38  filter.defaultState = true;39  filter.supportsCondition = true;40  filter.conditionDescription = "Condition for test filter";41 42  llvm::Expected<ExceptionBreakpointsFilter> deserialized_filter =43      roundtripJSON(filter);44  ASSERT_THAT_EXPECTED(deserialized_filter, llvm::Succeeded());45 46  EXPECT_EQ(filter.filter, deserialized_filter->filter);47  EXPECT_EQ(filter.label, deserialized_filter->label);48  EXPECT_EQ(filter.description, deserialized_filter->description);49  EXPECT_EQ(filter.defaultState, deserialized_filter->defaultState);50  EXPECT_EQ(filter.supportsCondition, deserialized_filter->supportsCondition);51  EXPECT_EQ(filter.conditionDescription,52            deserialized_filter->conditionDescription);53}54 55TEST(ProtocolTypesTest, Source) {56  Source source;57  source.name = "testName";58  source.path = "/path/to/source";59  source.sourceReference = 12345;60  source.presentationHint = Source::eSourcePresentationHintEmphasize;61 62  llvm::Expected<Source> deserialized_source = roundtripJSON(source);63  ASSERT_THAT_EXPECTED(deserialized_source, llvm::Succeeded());64 65  EXPECT_EQ(source.name, deserialized_source->name);66  EXPECT_EQ(source.path, deserialized_source->path);67  EXPECT_EQ(source.sourceReference, deserialized_source->sourceReference);68  EXPECT_EQ(source.presentationHint, deserialized_source->presentationHint);69}70 71TEST(ProtocolTypesTest, ColumnDescriptor) {72  ColumnDescriptor column;73  column.attributeName = "moduleName";74  column.label = "Module Name";75  column.format = "uppercase";76  column.type = eColumnTypeString;77  column.width = 20;78 79  llvm::Expected<ColumnDescriptor> deserialized_column = roundtripJSON(column);80  ASSERT_THAT_EXPECTED(deserialized_column, llvm::Succeeded());81 82  EXPECT_EQ(column.attributeName, deserialized_column->attributeName);83  EXPECT_EQ(column.label, deserialized_column->label);84  EXPECT_EQ(column.format, deserialized_column->format);85  EXPECT_EQ(column.type, deserialized_column->type);86  EXPECT_EQ(column.width, deserialized_column->width);87}88 89TEST(ProtocolTypesTest, BreakpointMode) {90  BreakpointMode mode;91  mode.mode = "testMode";92  mode.label = "Test Mode";93  mode.description = "This is a test mode";94  mode.appliesTo = {eBreakpointModeApplicabilitySource,95                    eBreakpointModeApplicabilityException};96 97  llvm::Expected<BreakpointMode> deserialized_mode = roundtripJSON(mode);98  ASSERT_THAT_EXPECTED(deserialized_mode, llvm::Succeeded());99 100  EXPECT_EQ(mode.mode, deserialized_mode->mode);101  EXPECT_EQ(mode.label, deserialized_mode->label);102  EXPECT_EQ(mode.description, deserialized_mode->description);103  EXPECT_EQ(mode.appliesTo, deserialized_mode->appliesTo);104}105 106TEST(ProtocolTypesTest, Breakpoint) {107  Breakpoint breakpoint;108  breakpoint.id = 42;109  breakpoint.verified = true;110  breakpoint.message = "Breakpoint set successfully";111  breakpoint.source =112      Source{"test.cpp", "/path/to/test.cpp", 123,113             Source::eSourcePresentationHintNormal, std::nullopt};114  breakpoint.line = 10;115  breakpoint.column = 5;116  breakpoint.endLine = 15;117  breakpoint.endColumn = 10;118  breakpoint.instructionReference = "0x12345678";119  breakpoint.offset = 4;120  breakpoint.reason = BreakpointReason::eBreakpointReasonPending;121 122  llvm::Expected<Breakpoint> deserialized_breakpoint =123      roundtripJSON(breakpoint);124  ASSERT_THAT_EXPECTED(deserialized_breakpoint, llvm::Succeeded());125 126  EXPECT_EQ(breakpoint.id, deserialized_breakpoint->id);127  EXPECT_EQ(breakpoint.verified, deserialized_breakpoint->verified);128  EXPECT_EQ(breakpoint.message, deserialized_breakpoint->message);129  EXPECT_EQ(breakpoint.source->name, deserialized_breakpoint->source->name);130  EXPECT_EQ(breakpoint.source->path, deserialized_breakpoint->source->path);131  EXPECT_EQ(breakpoint.source->sourceReference,132            deserialized_breakpoint->source->sourceReference);133  EXPECT_EQ(breakpoint.source->presentationHint,134            deserialized_breakpoint->source->presentationHint);135  EXPECT_EQ(breakpoint.line, deserialized_breakpoint->line);136  EXPECT_EQ(breakpoint.column, deserialized_breakpoint->column);137  EXPECT_EQ(breakpoint.endLine, deserialized_breakpoint->endLine);138  EXPECT_EQ(breakpoint.endColumn, deserialized_breakpoint->endColumn);139  EXPECT_EQ(breakpoint.instructionReference,140            deserialized_breakpoint->instructionReference);141  EXPECT_EQ(breakpoint.offset, deserialized_breakpoint->offset);142  EXPECT_EQ(breakpoint.reason, deserialized_breakpoint->reason);143}144 145TEST(ProtocolTypesTest, SourceBreakpoint) {146  SourceBreakpoint source_breakpoint;147  source_breakpoint.line = 42;148  source_breakpoint.column = 5;149  source_breakpoint.condition = "x > 10";150  source_breakpoint.hitCondition = "5";151  source_breakpoint.logMessage = "Breakpoint hit at line 42";152  source_breakpoint.mode = "hardware";153 154  llvm::Expected<SourceBreakpoint> deserialized_source_breakpoint =155      roundtripJSON(source_breakpoint);156  ASSERT_THAT_EXPECTED(deserialized_source_breakpoint, llvm::Succeeded());157 158  EXPECT_EQ(source_breakpoint.line, deserialized_source_breakpoint->line);159  EXPECT_EQ(source_breakpoint.column, deserialized_source_breakpoint->column);160  EXPECT_EQ(source_breakpoint.condition,161            deserialized_source_breakpoint->condition);162  EXPECT_EQ(source_breakpoint.hitCondition,163            deserialized_source_breakpoint->hitCondition);164  EXPECT_EQ(source_breakpoint.logMessage,165            deserialized_source_breakpoint->logMessage);166  EXPECT_EQ(source_breakpoint.mode, deserialized_source_breakpoint->mode);167}168 169TEST(ProtocolTypesTest, FunctionBreakpoint) {170  FunctionBreakpoint function_breakpoint;171  function_breakpoint.name = "myFunction";172  function_breakpoint.condition = "x == 0";173  function_breakpoint.hitCondition = "3";174 175  llvm::Expected<FunctionBreakpoint> deserialized_function_breakpoint =176      roundtripJSON(function_breakpoint);177  ASSERT_THAT_EXPECTED(deserialized_function_breakpoint, llvm::Succeeded());178 179  EXPECT_EQ(function_breakpoint.name, deserialized_function_breakpoint->name);180  EXPECT_EQ(function_breakpoint.condition,181            deserialized_function_breakpoint->condition);182  EXPECT_EQ(function_breakpoint.hitCondition,183            deserialized_function_breakpoint->hitCondition);184}185 186TEST(ProtocolTypesTest, DataBreakpoint) {187  DataBreakpoint data_breakpoint_info;188  data_breakpoint_info.dataId = "variable1";189  data_breakpoint_info.accessType = eDataBreakpointAccessTypeReadWrite;190  data_breakpoint_info.condition = "x > 100";191  data_breakpoint_info.hitCondition = "10";192 193  llvm::Expected<DataBreakpoint> deserialized_data_breakpoint_info =194      roundtripJSON(data_breakpoint_info);195  ASSERT_THAT_EXPECTED(deserialized_data_breakpoint_info, llvm::Succeeded());196 197  EXPECT_EQ(data_breakpoint_info.dataId,198            deserialized_data_breakpoint_info->dataId);199  EXPECT_EQ(data_breakpoint_info.accessType,200            deserialized_data_breakpoint_info->accessType);201  EXPECT_EQ(data_breakpoint_info.condition,202            deserialized_data_breakpoint_info->condition);203  EXPECT_EQ(data_breakpoint_info.hitCondition,204            deserialized_data_breakpoint_info->hitCondition);205}206 207TEST(ProtocolTypesTest, Capabilities) {208  Capabilities capabilities;209 210  // Populate supported features.211  capabilities.supportedFeatures.insert(eAdapterFeatureANSIStyling);212  capabilities.supportedFeatures.insert(213      eAdapterFeatureBreakpointLocationsRequest);214 215  // Populate optional fields.216  capabilities.exceptionBreakpointFilters = {217      {{"filter1", "Filter 1", "Description 1", true, true, "Condition 1"},218       {"filter2", "Filter 2", "Description 2", false, false, "Condition 2"}}};219 220  capabilities.completionTriggerCharacters = {".", "->"};221  capabilities.additionalModuleColumns = {222      {"moduleName", "Module Name", "uppercase", eColumnTypeString, 20}};223  capabilities.supportedChecksumAlgorithms = {eChecksumAlgorithmMD5,224                                              eChecksumAlgorithmSHA256};225  capabilities.breakpointModes = {{"hardware",226                                   "Hardware Breakpoint",227                                   "Description",228                                   {eBreakpointModeApplicabilitySource}}};229  capabilities.lldbExtVersion = "1.0.0";230 231  // Perform roundtripJSON serialization and deserialization.232  llvm::Expected<Capabilities> deserialized_capabilities =233      roundtripJSON(capabilities);234  ASSERT_THAT_EXPECTED(deserialized_capabilities, llvm::Succeeded());235 236  // Verify supported features.237  EXPECT_EQ(capabilities.supportedFeatures,238            deserialized_capabilities->supportedFeatures);239 240  // Verify exception breakpoint filters.241  EXPECT_EQ(capabilities.exceptionBreakpointFilters.size(),242            deserialized_capabilities->exceptionBreakpointFilters.size());243  for (size_t i = 0; i < capabilities.exceptionBreakpointFilters.size(); ++i) {244    const auto &original = capabilities.exceptionBreakpointFilters.at(i);245    const auto &deserialized =246        deserialized_capabilities->exceptionBreakpointFilters.at(i);247    EXPECT_EQ(original.filter, deserialized.filter);248    EXPECT_EQ(original.label, deserialized.label);249    EXPECT_EQ(original.description, deserialized.description);250    EXPECT_EQ(original.defaultState, deserialized.defaultState);251    EXPECT_EQ(original.supportsCondition, deserialized.supportsCondition);252    EXPECT_EQ(original.conditionDescription, deserialized.conditionDescription);253  }254 255  // Verify completion trigger characters.256  EXPECT_EQ(capabilities.completionTriggerCharacters,257            deserialized_capabilities->completionTriggerCharacters);258 259  // Verify additional module columns.260  EXPECT_EQ(capabilities.additionalModuleColumns.size(),261            deserialized_capabilities->additionalModuleColumns.size());262  for (size_t i = 0; i < capabilities.additionalModuleColumns.size(); ++i) {263    const auto &original = capabilities.additionalModuleColumns.at(i);264    const auto &deserialized =265        deserialized_capabilities->additionalModuleColumns.at(i);266    EXPECT_EQ(original.attributeName, deserialized.attributeName);267    EXPECT_EQ(original.label, deserialized.label);268    EXPECT_EQ(original.format, deserialized.format);269    EXPECT_EQ(original.type, deserialized.type);270    EXPECT_EQ(original.width, deserialized.width);271  }272 273  // Verify supported checksum algorithms.274  EXPECT_EQ(capabilities.supportedChecksumAlgorithms,275            deserialized_capabilities->supportedChecksumAlgorithms);276 277  // Verify breakpoint modes.278  EXPECT_EQ(capabilities.breakpointModes.size(),279            deserialized_capabilities->breakpointModes.size());280  for (size_t i = 0; i < capabilities.breakpointModes.size(); ++i) {281    const auto &original = capabilities.breakpointModes.at(i);282    const auto &deserialized = deserialized_capabilities->breakpointModes.at(i);283    EXPECT_EQ(original.mode, deserialized.mode);284    EXPECT_EQ(original.label, deserialized.label);285    EXPECT_EQ(original.description, deserialized.description);286    EXPECT_EQ(original.appliesTo, deserialized.appliesTo);287  }288 289  // Verify lldb extension version.290  EXPECT_EQ(capabilities.lldbExtVersion,291            deserialized_capabilities->lldbExtVersion);292}293 294TEST(ProtocolTypesTest, Scope) {295  Scope scope;296  scope.name = "Locals";297  scope.presentationHint = Scope::eScopePresentationHintLocals;298  scope.variablesReference = 1;299  scope.namedVariables = 2;300  scope.indexedVariables = std::nullopt;301  scope.expensive = false;302  scope.line = 2;303  scope.column = 3;304  scope.endLine = 10;305  scope.endColumn = 20;306 307  Source source;308  source.name = "testName";309  source.path = "/path/to/source";310  source.sourceReference = 12345;311  source.presentationHint = Source::eSourcePresentationHintNormal;312  scope.source = source;313 314  llvm::Expected<Scope> deserialized_scope = roundtripJSON(scope);315  ASSERT_THAT_EXPECTED(deserialized_scope, llvm::Succeeded());316  EXPECT_EQ(scope.name, deserialized_scope->name);317  EXPECT_EQ(scope.presentationHint, deserialized_scope->presentationHint);318  EXPECT_EQ(scope.variablesReference, deserialized_scope->variablesReference);319  EXPECT_EQ(scope.namedVariables, deserialized_scope->namedVariables);320  EXPECT_EQ(scope.indexedVariables, deserialized_scope->indexedVariables);321  EXPECT_EQ(scope.expensive, deserialized_scope->expensive);322  EXPECT_EQ(scope.line, deserialized_scope->line);323  EXPECT_EQ(scope.column, deserialized_scope->column);324  EXPECT_EQ(scope.endLine, deserialized_scope->endLine);325  EXPECT_EQ(scope.endColumn, deserialized_scope->endColumn);326 327  EXPECT_THAT(deserialized_scope->source.has_value(), true);328  const Source &deserialized_source = deserialized_scope->source.value();329 330  EXPECT_EQ(source.path, deserialized_source.path);331  EXPECT_EQ(source.sourceReference, deserialized_source.sourceReference);332  EXPECT_EQ(source.presentationHint, deserialized_source.presentationHint);333}334 335TEST(ProtocolTypesTest, PresentationHint) {336  // Test all PresentationHint values.337  std::vector<std::pair<Source::PresentationHint, llvm::StringRef>> test_cases =338      {{Source::eSourcePresentationHintNormal, "normal"},339       {Source::eSourcePresentationHintEmphasize, "emphasize"},340       {Source::eSourcePresentationHintDeemphasize, "deemphasize"}};341 342  for (const auto &test_case : test_cases) {343    // Serialize the PresentationHint to JSON.344    llvm::json::Value serialized = toJSON(test_case.first);345    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);346    EXPECT_EQ(serialized.getAsString(), test_case.second);347 348    // Deserialize the JSON back to PresentationHint.349    Source::PresentationHint deserialized;350    llvm::json::Path::Root root;351    ASSERT_TRUE(fromJSON(serialized, deserialized, root))352        << llvm::toString(root.getError());353    EXPECT_EQ(deserialized, test_case.first);354  }355 356  // Test invalid value.357  llvm::json::Value invalid_value = "invalid_hint";358  Source::PresentationHint deserialized_invalid;359  llvm::json::Path::Root root;360  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));361}362 363TEST(ProtocolTypesTest, SteppingGranularity) {364  // Test all SteppingGranularity values.365  std::vector<std::pair<SteppingGranularity, llvm::StringRef>> test_cases = {366      {eSteppingGranularityStatement, "statement"},367      {eSteppingGranularityLine, "line"},368      {eSteppingGranularityInstruction, "instruction"}};369 370  for (const auto &test_case : test_cases) {371    // Serialize the SteppingGranularity to JSON.372    llvm::json::Value serialized = toJSON(test_case.first);373    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);374    EXPECT_EQ(serialized.getAsString(), test_case.second);375 376    // Deserialize the JSON back to SteppingGranularity.377    SteppingGranularity deserialized;378    llvm::json::Path::Root root;379    ASSERT_TRUE(fromJSON(serialized, deserialized, root))380        << llvm::toString(root.getError());381    EXPECT_EQ(deserialized, test_case.first);382  }383 384  // Test invalid value.385  llvm::json::Value invalid_value = "invalid_granularity";386  SteppingGranularity deserialized_invalid;387  llvm::json::Path::Root root;388  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));389}390 391TEST(ProtocolTypesTest, BreakpointReason) {392  // Test all BreakpointReason values.393  std::vector<std::pair<BreakpointReason, llvm::StringRef>> test_cases = {394      {BreakpointReason::eBreakpointReasonPending, "pending"},395      {BreakpointReason::eBreakpointReasonFailed, "failed"}};396 397  for (const auto &test_case : test_cases) {398    // Serialize the BreakpointReason to JSON.399    llvm::json::Value serialized = toJSON(test_case.first);400    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);401    EXPECT_EQ(serialized.getAsString(), test_case.second);402 403    // Deserialize the JSON back to BreakpointReason.404    BreakpointReason deserialized;405    llvm::json::Path::Root root;406    ASSERT_TRUE(fromJSON(serialized, deserialized, root))407        << llvm::toString(root.getError());408    EXPECT_EQ(deserialized, test_case.first);409  }410 411  // Test invalid value.412  llvm::json::Value invalid_value = "invalid_reason";413  BreakpointReason deserialized_invalid;414  llvm::json::Path::Root root;415  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));416}417 418TEST(ProtocolTypesTest, DataBreakpointAccessType) {419  // Test all DataBreakpointAccessType values.420  std::vector<std::pair<DataBreakpointAccessType, llvm::StringRef>> test_cases =421      {{eDataBreakpointAccessTypeRead, "read"},422       {eDataBreakpointAccessTypeWrite, "write"},423       {eDataBreakpointAccessTypeReadWrite, "readWrite"}};424 425  for (const auto &test_case : test_cases) {426    // Serialize the DataBreakpointAccessType to JSON.427    llvm::json::Value serialized = toJSON(test_case.first);428    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);429    EXPECT_EQ(serialized.getAsString(), test_case.second);430 431    // Deserialize the JSON back to DataBreakpointAccessType.432    DataBreakpointAccessType deserialized;433    llvm::json::Path::Root root;434    ASSERT_TRUE(fromJSON(serialized, deserialized, root))435        << llvm::toString(root.getError());436    EXPECT_EQ(deserialized, test_case.first);437  }438 439  // Test invalid value440  llvm::json::Value invalid_value = "invalid_access_type";441  DataBreakpointAccessType deserialized_invalid;442  llvm::json::Path::Root root;443  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));444}445 446TEST(ProtocolTypesTest, ColumnType) {447  // Test all ColumnType values.448  std::vector<std::pair<ColumnType, llvm::StringRef>> test_cases = {449      {eColumnTypeString, "string"},450      {eColumnTypeNumber, "number"},451      {eColumnTypeBoolean, "boolean"},452      {eColumnTypeTimestamp, "unixTimestampUTC"}};453 454  for (const auto &test_case : test_cases) {455    // Serialize the ColumnType to JSON.456    llvm::json::Value serialized = toJSON(test_case.first);457    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);458    EXPECT_EQ(serialized.getAsString(), test_case.second);459 460    // Deserialize the JSON back to ColumnType.461    ColumnType deserialized;462    llvm::json::Path::Root root;463    ASSERT_TRUE(fromJSON(serialized, deserialized, root))464        << llvm::toString(root.getError());465    EXPECT_EQ(deserialized, test_case.first);466  }467 468  // Test invalid value.469  llvm::json::Value invalid_value = "invalid_column_type";470  ColumnType deserialized_invalid;471  llvm::json::Path::Root root;472  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));473}474 475TEST(ProtocolTypesTest, BreakpointModeApplicability) {476  // Test all BreakpointModeApplicability values.477  std::vector<std::pair<BreakpointModeApplicability, llvm::StringRef>>478      test_cases = {{eBreakpointModeApplicabilitySource, "source"},479                    {eBreakpointModeApplicabilityException, "exception"},480                    {eBreakpointModeApplicabilityData, "data"},481                    {eBreakpointModeApplicabilityInstruction, "instruction"}};482 483  for (const auto &test_case : test_cases) {484    // Serialize the BreakpointModeApplicability to JSON.485    llvm::json::Value serialized = toJSON(test_case.first);486    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);487    EXPECT_EQ(serialized.getAsString(), test_case.second);488 489    // Deserialize the JSON back to BreakpointModeApplicability.490    BreakpointModeApplicability deserialized;491    llvm::json::Path::Root root;492    ASSERT_TRUE(fromJSON(serialized, deserialized, root))493        << llvm::toString(root.getError());494    EXPECT_EQ(deserialized, test_case.first);495  }496 497  // Test invalid value.498  llvm::json::Value invalid_value = "invalid_applicability";499  BreakpointModeApplicability deserialized_invalid;500  llvm::json::Path::Root root;501  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));502}503 504TEST(ProtocolTypesTest, ChecksumAlgorithm) {505  // Test all ChecksumAlgorithm values.506  std::vector<std::pair<ChecksumAlgorithm, llvm::StringRef>> test_cases = {507      {eChecksumAlgorithmMD5, "MD5"},508      {eChecksumAlgorithmSHA1, "SHA1"},509      {eChecksumAlgorithmSHA256, "SHA256"},510      {eChecksumAlgorithmTimestamp, "timestamp"}};511 512  for (const auto &test_case : test_cases) {513    // Serialize the ChecksumAlgorithm to JSON.514    llvm::json::Value serialized = toJSON(test_case.first);515    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);516    EXPECT_EQ(serialized.getAsString(), test_case.second);517 518    // Deserialize the JSON back to ChecksumAlgorithm.519    ChecksumAlgorithm deserialized;520    llvm::json::Path::Root root;521    ASSERT_TRUE(fromJSON(serialized, deserialized, root))522        << llvm::toString(root.getError());523    EXPECT_EQ(deserialized, test_case.first);524  }525 526  // Test invalid value.527  llvm::json::Value invalid_value = "invalid_algorithm";528  ChecksumAlgorithm deserialized_invalid;529  llvm::json::Path::Root root;530  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));531}532 533TEST(ProtocolTypesTest, DisassembledInstructionPresentationHint) {534  // Test all PresentationHint values.535  std::vector<536      std::pair<DisassembledInstruction::PresentationHint, llvm::StringRef>>537      test_cases = {{DisassembledInstruction::538                         eDisassembledInstructionPresentationHintNormal,539                     "normal"},540                    {DisassembledInstruction::541                         eDisassembledInstructionPresentationHintInvalid,542                     "invalid"}};543 544  for (const auto &test_case : test_cases) {545    // Serialize the PresentationHint to JSON.546    llvm::json::Value serialized = toJSON(test_case.first);547    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);548    EXPECT_EQ(serialized.getAsString(), test_case.second);549 550    // Deserialize the JSON back to PresentationHint.551    DisassembledInstruction::PresentationHint deserialized;552    llvm::json::Path::Root root;553    ASSERT_TRUE(fromJSON(serialized, deserialized, root))554        << llvm::toString(root.getError());555    EXPECT_EQ(deserialized, test_case.first);556  }557 558  // Test invalid value.559  llvm::json::Value invalid_value = "invalid_hint";560  DisassembledInstruction::PresentationHint deserialized_invalid;561  llvm::json::Path::Root root;562  EXPECT_FALSE(fromJSON(invalid_value, deserialized_invalid, root));563}564 565TEST(ProtocolTypesTest, DisassembledInstruction) {566  DisassembledInstruction instruction;567  instruction.address = 0x12345678;568  instruction.instructionBytes = "0F 1F 00";569  instruction.instruction = "mov eax, ebx";570  instruction.symbol = "main";571  instruction.location =572      Source{"test.cpp", "/path/to/test.cpp", 123,573             Source::eSourcePresentationHintNormal, std::nullopt};574  instruction.line = 10;575  instruction.column = 5;576  instruction.endLine = 15;577  instruction.endColumn = 10;578  instruction.presentationHint =579      DisassembledInstruction::eDisassembledInstructionPresentationHintNormal;580 581  StringLiteral json = R"({582  "address": "0x12345678",583  "column": 5,584  "endColumn": 10,585  "endLine": 15,586  "instruction": "mov eax, ebx",587  "instructionBytes": "0F 1F 00",588  "line": 10,589  "location": {590    "name": "test.cpp",591    "path": "/path/to/test.cpp",592    "presentationHint": "normal",593    "sourceReference": 123594  },595  "presentationHint": "normal",596  "symbol": "main"597})";598 599  // Validate toJSON600  EXPECT_EQ(json, pp(instruction));601 602  // Validate fromJSON603  EXPECT_THAT_EXPECTED(parse<DisassembledInstruction>(json),604                       HasValue(Value(instruction)));605  // Validate parsing errors606  EXPECT_THAT_EXPECTED(607      parse<DisassembledInstruction>(R"({"address":1})",608                                     "disassemblyInstruction"),609      FailedWithMessage("expected string at disassemblyInstruction.address"));610  EXPECT_THAT_EXPECTED(611      parse<DisassembledInstruction>(R"({"address":"-1"})",612                                     "disassemblyInstruction"),613      FailedWithMessage(614          "malformed memory reference at disassemblyInstruction.address"));615  EXPECT_THAT_EXPECTED(616      parse<DisassembledInstruction>(617          R"({"address":"0xfffffffffffffffffffffffffff"})",618          "disassemblyInstruction"),619      FailedWithMessage(620          "malformed memory reference at disassemblyInstruction.address"));621}622 623TEST(ProtocolTypesTest, Thread) {624  const Thread thread{1, "thr1"};625  const StringRef json = R"({626  "id": 1,627  "name": "thr1"628})";629  // Validate toJSON630  EXPECT_EQ(json, pp(thread));631  // Validate fromJSON632  EXPECT_THAT_EXPECTED(parse<Thread>(json), HasValue(Value(thread)));633  // Validate parsing errors634  EXPECT_THAT_EXPECTED(parse<Thread>(R"({"id":1})", "thread"),635                       FailedWithMessage("missing value at thread.name"));636  EXPECT_THAT_EXPECTED(parse<Thread>(R"({"id":"one"})", "thread"),637                       FailedWithMessage("expected uint64_t at thread.id"));638  EXPECT_THAT_EXPECTED(parse<Thread>(R"({"id":1,"name":false})", "thread"),639                       FailedWithMessage("expected string at thread.name"));640}641 642TEST(ProtocolTypesTest, ThreadResponseBody) {643  const ThreadsResponseBody body{{{1, "thr1"}, {2, "thr2"}}};644  const StringRef json = R"({645  "threads": [646    {647      "id": 1,648      "name": "thr1"649    },650    {651      "id": 2,652      "name": "thr2"653    }654  ]655})";656  // Validate toJSON657  EXPECT_EQ(json, pp(body));658}659 660TEST(ProtocolTypesTest, CapabilitiesEventBody) {661  Capabilities capabilities;662  capabilities.supportedFeatures = {663      eAdapterFeatureANSIStyling,664      eAdapterFeatureBreakpointLocationsRequest,665  };666  CapabilitiesEventBody body;667  body.capabilities = capabilities;668  StringRef json = R"({669  "capabilities": {670    "supportsANSIStyling": true,671    "supportsBreakpointLocationsRequest": true672  }673})";674  // Validate toJSON675  EXPECT_EQ(json, pp(body));676}677 678TEST(ProtocolTypesTest, ExceptionFilterOptions) {679  EXPECT_THAT_EXPECTED(parse<ExceptionFilterOptions>(R"({"filterId":"id"})"),680                       HasValue(Value(ExceptionFilterOptions{681                           /*filterId=*/"id", /*condition=*/"", /*mode*/ ""})));682  EXPECT_THAT_EXPECTED(683      parse<ExceptionFilterOptions>(R"({"filterId":"id","condition":"1+2"})"),684      HasValue(Value(ExceptionFilterOptions{685          /*filterId=*/"id", /*condition=*/"1+2", /*mode*/ ""})));686  EXPECT_THAT_EXPECTED(687      parse<ExceptionFilterOptions>(688          R"({"filterId":"id","condition":"1+2","mode":"m"})"),689      HasValue(Value(ExceptionFilterOptions{690          /*filterId=*/"id", /*condition=*/"1+2", /*mode*/ "m"})));691 692  // Validate parsing errors693  EXPECT_THAT_EXPECTED(694      parse<ExceptionFilterOptions>(R"({})", "exceptionFilterOptions"),695      FailedWithMessage("missing value at exceptionFilterOptions.filterId"));696  EXPECT_THAT_EXPECTED(697      parse<ExceptionFilterOptions>(R"({"filterId":"id","condition":42})",698                                    "exceptionFilterOptions"),699      FailedWithMessage("expected string at exceptionFilterOptions.condition"));700  EXPECT_THAT_EXPECTED(701      parse<ExceptionFilterOptions>(R"({"filterId":"id","mode":42})",702                                    "exceptionFilterOptions"),703      FailedWithMessage("expected string at exceptionFilterOptions.mode"));704}705 706TEST(ProtocolTypesTest, SetExceptionBreakpointsArguments) {707  EXPECT_THAT_EXPECTED(708      parse<SetExceptionBreakpointsArguments>(R"({"filters":[]})"),709      HasValue(testing::FieldsAre(/*filters=*/testing::IsEmpty(),710                                  /*filterOptions=*/testing::IsEmpty())));711  EXPECT_THAT_EXPECTED(712      parse<SetExceptionBreakpointsArguments>(R"({"filters":["abc"]})"),713      HasValue(testing::FieldsAre(/*filters=*/std::vector<std::string>{"abc"},714                                  /*filterOptions=*/testing::IsEmpty())));715  EXPECT_THAT_EXPECTED(716      parse<SetExceptionBreakpointsArguments>(717          R"({"filters":[],"filterOptions":[{"filterId":"abc"}]})"),718      HasValue(testing::FieldsAre(719          /*filters=*/testing::IsEmpty(),720          /*filterOptions=*/testing::Contains(testing::FieldsAre(721              /*filterId=*/"abc", /*condition=*/"", /*mode=*/"")))));722 723  // Validate parse errors724  EXPECT_THAT_EXPECTED(parse<SetExceptionBreakpointsArguments>(R"({})"),725                       FailedWithMessage("missing value at (root).filters"));726  EXPECT_THAT_EXPECTED(727      parse<SetExceptionBreakpointsArguments>(R"({"filters":false})"),728      FailedWithMessage("expected array at (root).filters"));729}730 731TEST(ProtocolTypesTest, SetExceptionBreakpointsResponseBody) {732  SetExceptionBreakpointsResponseBody body;733  Breakpoint bp;734  bp.id = 12, bp.verified = true;735  body.breakpoints = {bp};736  EXPECT_EQ(R"({737  "breakpoints": [738    {739      "id": 12,740      "verified": true741    }742  ]743})",744            pp(body));745}746 747TEST(ProtocolTypesTest, StepInTarget) {748  StepInTarget target;749  target.id = 230;750  target.label = "the_function_name";751  target.line = 2;752  target.column = 320;753  target.endLine = 32;754  target.endColumn = 23;755 756  llvm::Expected<StepInTarget> deserialized_target = roundtripJSON(target);757  ASSERT_THAT_EXPECTED(deserialized_target, llvm::Succeeded());758 759  EXPECT_EQ(target.id, deserialized_target->id);760  EXPECT_EQ(target.label, deserialized_target->label);761  EXPECT_EQ(target.line, deserialized_target->line);762  EXPECT_EQ(target.column, deserialized_target->column);763  EXPECT_EQ(target.endLine, deserialized_target->endLine);764  EXPECT_EQ(target.endColumn, deserialized_target->endColumn);765}766 767TEST(ProtocolTypesTest, ReadMemoryArguments) {768  ReadMemoryArguments args;769  args.count = 20;770  args.memoryReference = 43962;771  args.offset = 0;772 773  llvm::Expected<ReadMemoryArguments> expected =774      parse<ReadMemoryArguments>(R"({"memoryReference":"-4000", "count": 20})");775  ASSERT_THAT_EXPECTED(expected, llvm::Failed());776  expected = parse<ReadMemoryArguments>(777      R"({"memoryReference":"0xabba", "count": 20})");778  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());779 780  EXPECT_EQ(args.count, expected->count);781  EXPECT_EQ(args.memoryReference, expected->memoryReference);782  EXPECT_EQ(args.offset, expected->offset);783}784 785TEST(ProtocolTypesTest, ReadMemoryResponseBody) {786  ReadMemoryResponseBody response;787  response.address = 0xdeadbeef;788  const std::string data_str = "hello world!";789  std::transform(data_str.begin(), data_str.end(),790                 std::back_inserter(response.data),791                 [](char letter) { return std::byte(letter); });792  response.unreadableBytes = 1;793 794  Expected<Value> expected = json::parse(795      R"({ "address": "0xDEADBEEF", "data": "aGVsbG8gd29ybGQh", "unreadableBytes": 1})");796  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());797  EXPECT_EQ(pp(*expected), pp(response));798}799 800TEST(ProtocolTypesTest, Modules) {801  Module module;802  module.id = "AC805E8E-B6A4-CD92-4B05-5CFA7CE24AE8-8926C776";803  module.name = "libm.so.6";804  module.path = "/some/path/to/libm.so.6";805  module.isOptimized = true;806  module.isUserCode = true;807  module.version = "0.0.1";808  module.symbolStatus = "Symbol not found.";809  module.symbolFilePath = "/some/file/path/to/the/symbol/module";810  module.dateTimeStamp = "2020-12-09T16:09:53+00:00";811  module.addressRange = "0xcafeface";812  module.debugInfoSizeBytes = 1572864;813 814  Expected<json::Value> expected = json::parse(815      R"({816                  "id" : "AC805E8E-B6A4-CD92-4B05-5CFA7CE24AE8-8926C776",817                  "name": "libm.so.6",818                  "path": "/some/path/to/libm.so.6",819                  "isOptimized": true,820                  "isUserCode": true,821                  "version": "0.0.1",822                  "symbolStatus": "Symbol not found.",823                  "symbolFilePath": "/some/file/path/to/the/symbol/module",824                  "dateTimeStamp": "2020-12-09T16:09:53+00:00",825                  "addressRange": "0xcafeface",826                  "debugInfoSize": "1.5MB" })");827  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());828  EXPECT_EQ(pp(*expected), pp(module));829 830  // Test without optional values.831  module.path.clear();832  module.isOptimized = false;833  module.isUserCode = false;834  module.version.clear();835  module.symbolStatus.clear();836  module.symbolFilePath.clear();837  module.dateTimeStamp.clear();838  module.addressRange.clear();839  module.debugInfoSizeBytes = 0;840  EXPECT_NE(pp(*expected), pp(module));841 842  Expected<json::Value> expected_no_opt = json::parse(843      R"({844                  "id" : "AC805E8E-B6A4-CD92-4B05-5CFA7CE24AE8-8926C776",845                  "name": "libm.so.6"})");846  ASSERT_THAT_EXPECTED(expected_no_opt, llvm::Succeeded());847  EXPECT_EQ(pp(*expected_no_opt), pp(module));848}849 850TEST(ProtocolTypesTest, ModulesArguments) {851  ModulesArguments args;852 853  llvm::Expected<ModulesArguments> expected = parse<ModulesArguments>(R"({})");854  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());855  EXPECT_EQ(args.startModule, expected->startModule);856  EXPECT_EQ(args.moduleCount, expected->moduleCount);857 858  // Non Default values.859  args.startModule = 1;860  args.moduleCount = 2;861  llvm::Expected<ModulesArguments> expected_no_default =862      parse<ModulesArguments>(R"({ "startModule": 1, "moduleCount": 2})");863  ASSERT_THAT_EXPECTED(expected_no_default, llvm::Succeeded());864  EXPECT_EQ(args.startModule, expected_no_default->startModule);865  EXPECT_EQ(args.moduleCount, expected_no_default->moduleCount);866}867 868TEST(ProtocolTypesTest, ModulesResponseBody) {869  ModulesResponseBody response;870  Module module1;871  module1.id = "first id";872  module1.name = "first name";873 874  Module module2;875  module2.id = "second id";876  module2.name = "second name";877  response.modules = {std::move(module1), std::move(module2)};878  response.totalModules = 2;879 880  Expected<json::Value> expected = json::parse(881      R"({882                  "modules": [883                    { "id": "first id", "name": "first name"},884                    { "id": "second id", "name": "second name"}885                  ],886                  "totalModules": 2 })");887  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());888  EXPECT_EQ(pp(*expected), pp(response));889}890 891TEST(ProtocolTypesTest, VariablePresentationHint) {892  VariablePresentationHint hint;893  hint.kind = "kind";894  hint.attributes = {"a", "b", "c"};895  hint.visibility = "public";896  hint.lazy = true;897 898  const StringRef json = R"({899  "attributes": [900    "a",901    "b",902    "c"903  ],904  "kind": "kind",905  "lazy": true,906  "visibility": "public"907})";908 909  EXPECT_EQ(pp(Value(hint)), json);910  EXPECT_THAT_EXPECTED(json::parse(json), HasValue(Value(hint)));911}912 913TEST(ProtocolTypesTest, Variable) {914  Variable var;915  var.name = "var1";916  var.variablesReference = 42;917  var.value = "value";918  var.type = "type";919 920  VariablePresentationHint hint;921  hint.kind = "kind";922  var.presentationHint = std::move(hint);923  var.evaluateName = "my_name";924  var.namedVariables = 7;925  var.indexedVariables = 7;926  var.memoryReference = 291u;927  var.declarationLocationReference = 24;928  var.valueLocationReference = 100;929 930  const StringRef json = R"({931  "declarationLocationReference": 24,932  "evaluateName": "my_name",933  "indexedVariables": 7,934  "memoryReference": "0x123",935  "name": "var1",936  "namedVariables": 7,937  "presentationHint": {938    "kind": "kind"939  },940  "type": "type",941  "value": "value",942  "valueLocationReference": 100,943  "variablesReference": 42944})";945 946  EXPECT_EQ(pp(Value(var)), json);947  EXPECT_THAT_EXPECTED(json::parse(json), HasValue(Value(var)));948}949 950TEST(ProtocolTypesTest, VariablesArguments) {951  llvm::Expected<VariablesArguments> expected = parse<VariablesArguments>(R"({952    "variablesReference": 42,953    "filter": "indexed",954    "start": 10,955    "count": 5,956    "format": {957      "hex": true958    }959  })");960  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());961  EXPECT_EQ(expected->variablesReference, 42u);962  EXPECT_EQ(expected->filter, VariablesArguments::eVariablesFilterIndexed);963  EXPECT_EQ(expected->start, 10u);964  EXPECT_EQ(expected->count, 5u);965  EXPECT_EQ(expected->format->hex, true);966 967  EXPECT_THAT_EXPECTED(968      parse<VariablesArguments>(R"({})"),969      FailedWithMessage("missing value at (root).variablesReference"));970  EXPECT_THAT_EXPECTED(971      parse<VariablesArguments>(972          R"({"variablesReference": 42, "filter": "my-filter"})"),973      FailedWithMessage(974          "unexpected value, expected 'named' or 'indexed' at (root).filter"));975}976 977TEST(ProtocolTypesTest, VariablesResponseBody) {978  Variable var1;979  var1.name = "var1";980  var1.variablesReference = 42;981  var1.value = "<var1-value>";982 983  Variable var2;984  var2.name = "var2";985  var2.variablesReference = 3;986  var2.value = "<var2-value>";987 988  VariablesResponseBody response{{var1, var2}};989 990  Expected<json::Value> expected = json::parse(R"({991      "variables": [992        {993          "name": "var1",994          "value": "<var1-value>",995          "variablesReference": 42996        },997        {998          "name": "var2",999          "value": "<var2-value>",1000          "variablesReference": 31001        }1002      ]1003    })");1004  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1005  EXPECT_EQ(pp(*expected), pp(response));1006}1007 1008TEST(ProtocolTypesTest, CompletionItem) {1009  CompletionItem item;1010  item.label = "label";1011  item.text = "text";1012  item.sortText = "sortText";1013  item.detail = "detail";1014  item.type = eCompletionItemTypeConstructor;1015  item.start = 1;1016  item.length = 3;1017  item.selectionStart = 4;1018  item.selectionLength = 8;1019 1020  const StringRef json = R"({1021  "detail": "detail",1022  "label": "label",1023  "length": 3,1024  "selectionLength": 8,1025  "selectionStart": 4,1026  "sortText": "sortText",1027  "start": 1,1028  "text": "text",1029  "type": "constructor"1030})";1031 1032  EXPECT_EQ(pp(Value(item)), json);1033  EXPECT_THAT_EXPECTED(json::parse(json), HasValue(Value(item)));1034}1035 1036TEST(ProtocolTypesTest, CompletionsArguments) {1037  llvm::Expected<CompletionsArguments> expected =1038      parse<CompletionsArguments>(R"({1039    "column": 8,1040    "frameId": 7,1041    "line": 9,1042    "text": "abc"1043  })");1044  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1045  EXPECT_EQ(expected->frameId, 7u);1046  EXPECT_EQ(expected->text, "abc");1047  EXPECT_EQ(expected->column, 8);1048  EXPECT_EQ(expected->line, 9);1049 1050  // Check required keys.1051  EXPECT_THAT_EXPECTED(parse<CompletionsArguments>(R"({})"),1052                       FailedWithMessage("missing value at (root).text"));1053  EXPECT_THAT_EXPECTED(parse<CompletionsArguments>(R"({"text":"abc"})"),1054                       FailedWithMessage("missing value at (root).column"));1055}1056 1057TEST(ProtocolTypesTest, CompletionsResponseBody) {1058  CompletionItem item;1059  item.label = "label";1060  item.text = "text";1061  item.detail = "detail";1062  CompletionsResponseBody response{{item}};1063 1064  Expected<json::Value> expected = json::parse(R"({1065      "targets": [1066        {1067          "detail": "detail",1068          "label": "label",1069          "text": "text"1070        }1071      ]1072    })");1073  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1074  EXPECT_EQ(pp(*expected), pp(response));1075}1076 1077TEST(ProtocolTypesTest, InvalidatedEventBody) {1078  InvalidatedEventBody body;1079  body.areas = {InvalidatedEventBody::eAreaStacks,1080                InvalidatedEventBody::eAreaThreads};1081  body.stackFrameId = 1;1082  body.threadId = 20;1083  Expected<json::Value> expected = json::parse(R"({1084    "areas": [1085      "stacks",1086      "threads"1087    ],1088    "stackFrameId": 1,1089    "threadId": 201090    })");1091  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1092  EXPECT_EQ(pp(*expected), pp(body));1093}1094 1095TEST(ProtocolTypesTest, MemoryEventBody) {1096  MemoryEventBody body;1097  body.memoryReference = 12345;1098  body.offset = 0;1099  body.count = 4;1100  StringRef json = R"({1101  "count": 4,1102  "memoryReference": "0x3039",1103  "offset": 01104})";1105  EXPECT_EQ(json, pp(body));1106}1107 1108TEST(ProtocolTypesTest, DataBreakpointInfoArguments) {1109  llvm::Expected<DataBreakpointInfoArguments> expected =1110      parse<DataBreakpointInfoArguments>(R"({1111    "name": "data",1112    "variablesReference": 8,1113    "frameId": 9,1114    "bytes": 10,1115    "asAddress": false,1116    "mode": "source"1117  })");1118  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1119  EXPECT_EQ(expected->name, "data");1120  EXPECT_EQ(expected->variablesReference, 8);1121  EXPECT_EQ(expected->frameId, 9u);1122  EXPECT_EQ(expected->bytes, 10);1123  EXPECT_EQ(expected->asAddress, false);1124  EXPECT_EQ(expected->mode, "source");1125 1126  // Check required keys.1127  EXPECT_THAT_EXPECTED(parse<DataBreakpointInfoArguments>(R"({})"),1128                       FailedWithMessage("missing value at (root).name"));1129  EXPECT_THAT_EXPECTED(parse<DataBreakpointInfoArguments>(R"({"name":"data"})"),1130                       llvm::Succeeded());1131}1132 1133TEST(ProtocolTypesTest, ExceptionBreakMode) {1134  const std::vector<std::pair<ExceptionBreakMode, llvm::StringRef>> test_cases =1135      {{ExceptionBreakMode::eExceptionBreakModeAlways, "always"},1136       {ExceptionBreakMode::eExceptionBreakModeNever, "never"},1137       {ExceptionBreakMode::eExceptionBreakModeUnhandled, "unhandled"},1138       {ExceptionBreakMode::eExceptionBreakModeUserUnhandled, "userUnhandled"}};1139 1140  for (const auto [value, expected] : test_cases) {1141    json::Value const serialized = toJSON(value);1142    ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);1143    EXPECT_EQ(serialized.getAsString(), expected);1144  }1145}1146 1147TEST(ProtocolTypesTest, ExceptionDetails) {1148  ExceptionDetails details;1149 1150  // Check required keys.1151  Expected<json::Value> expected = parse(R"({})");1152  ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());1153  EXPECT_EQ(pp(*expected), pp(details));1154 1155  // Check optional keys.1156  details.message = "SIGABRT exception";1157  details.typeName = "signal";1158  details.fullTypeName = "SIGABRT";1159  details.evaluateName = "process handle SIGABRT";1160  details.stackTrace = "some stacktrace";1161  ExceptionDetails inner_details;1162  inner_details.message = "inner message";1163  details.innerException = {std::move(inner_details)};1164 1165  Expected<json::Value> expected_opt = parse(R"({1166    "message": "SIGABRT exception",1167    "typeName": "signal",1168    "fullTypeName": "SIGABRT",1169    "evaluateName": "process handle SIGABRT",1170    "stackTrace": "some stacktrace",1171    "innerException": [{1172      "message": "inner message"1173    }]1174    })");1175 1176  ASSERT_THAT_EXPECTED(expected_opt, llvm::Succeeded());1177  EXPECT_EQ(pp(*expected_opt), pp(details));1178}1179