[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / unittests / Interpreter / TestOptionValue.cpp
blob704f460e43b8bf2dd75be349a5a84a98783dbc79
1 //===-- TestOptionValue.cpp -------- -------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/OptionValues.h"
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
13 using namespace lldb_private;
15 class Callback {
16 public:
17 virtual void Invoke() const {}
18 void operator()() const { Invoke(); }
20 protected:
21 ~Callback() = default;
24 class MockCallback final : public Callback {
25 public:
26 MOCK_CONST_METHOD0(Invoke, void());
29 // Test a single-value class.
30 TEST(OptionValueString, DeepCopy) {
31 OptionValueString str;
32 str.SetValueFromString("ab");
34 MockCallback callback;
35 str.SetValueChangedCallback([&callback] { callback(); });
36 EXPECT_CALL(callback, Invoke());
38 auto copy_sp = str.DeepCopy(nullptr);
40 // Test that the base class data members are copied/set correctly.
41 ASSERT_TRUE(copy_sp);
42 ASSERT_EQ(copy_sp->GetParent().get(), nullptr);
43 ASSERT_TRUE(copy_sp->OptionWasSet());
44 ASSERT_EQ(copy_sp->GetValueAs<llvm::StringRef>(), "ab");
46 // Trigger the callback.
47 copy_sp->SetValueFromString("c", eVarSetOperationAppend);
48 ASSERT_EQ(copy_sp->GetValueAs<llvm::StringRef>(), "abc");
51 // Test an aggregate class.
52 TEST(OptionValueArgs, DeepCopy) {
53 OptionValueArgs args;
54 args.SetValueFromString("A B");
56 MockCallback callback;
57 args.SetValueChangedCallback([&callback] { callback(); });
58 EXPECT_CALL(callback, Invoke());
60 auto copy_sp = args.DeepCopy(nullptr);
62 // Test that the base class data members are copied/set correctly.
63 ASSERT_TRUE(copy_sp);
64 ASSERT_EQ(copy_sp->GetParent(), nullptr);
65 ASSERT_TRUE(copy_sp->OptionWasSet());
67 auto *args_copy_ptr = copy_sp->GetAsArgs();
68 ASSERT_EQ(args_copy_ptr->GetSize(), 2U);
69 ASSERT_EQ((*args_copy_ptr)[0]->GetParent(), copy_sp);
70 ASSERT_EQ((*args_copy_ptr)[0]->GetValueAs<llvm::StringRef>(), "A");
71 ASSERT_EQ((*args_copy_ptr)[1]->GetParent(), copy_sp);
72 ASSERT_EQ((*args_copy_ptr)[1]->GetValueAs<llvm::StringRef>(), "B");
74 // Trigger the callback.
75 copy_sp->SetValueFromString("C", eVarSetOperationAppend);
76 ASSERT_TRUE(args_copy_ptr);
77 ASSERT_EQ(args_copy_ptr->GetSize(), 3U);
78 ASSERT_EQ((*args_copy_ptr)[2]->GetValueAs<llvm::StringRef>(), "C");
81 class TestProperties : public OptionValueProperties {
82 public:
83 static std::shared_ptr<TestProperties> CreateGlobal() {
84 auto props_sp = std::make_shared<TestProperties>();
85 const bool is_global = false;
87 auto dict_sp = std::make_shared<OptionValueDictionary>(1 << eTypeUInt64);
88 props_sp->AppendProperty("dict", "", is_global, dict_sp);
90 auto file_list_sp = std::make_shared<OptionValueFileSpecList>();
91 props_sp->AppendProperty("file-list", "", is_global, file_list_sp);
92 return props_sp;
95 void SetDictionaryChangedCallback(const MockCallback &callback) {
96 SetValueChangedCallback(m_dict_index, [&callback] { callback(); });
99 void SetFileListChangedCallback(const MockCallback &callback) {
100 SetValueChangedCallback(m_file_list_index, [&callback] { callback(); });
103 OptionValueDictionary *GetDictionary() {
104 return GetPropertyAtIndexAsOptionValueDictionary(m_dict_index);
107 OptionValueFileSpecList *GetFileList() {
108 return GetPropertyAtIndexAsOptionValueFileSpecList(m_file_list_index);
111 private:
112 lldb::OptionValueSP Clone() const override {
113 return std::make_shared<TestProperties>(*this);
116 uint32_t m_dict_index = 0;
117 uint32_t m_file_list_index = 1;
120 // Test a user-defined propery class.
121 TEST(TestProperties, DeepCopy) {
122 auto props_sp = TestProperties::CreateGlobal();
123 props_sp->GetDictionary()->SetValueFromString("A=1 B=2");
124 props_sp->GetFileList()->SetValueFromString("path/to/file");
126 MockCallback callback;
127 props_sp->SetDictionaryChangedCallback(callback);
128 props_sp->SetFileListChangedCallback(callback);
129 EXPECT_CALL(callback, Invoke()).Times(2);
131 auto copy_sp = props_sp->DeepCopy(nullptr);
133 // Test that the base class data members are copied/set correctly.
134 ASSERT_TRUE(copy_sp);
135 ASSERT_EQ(copy_sp->GetParent(), nullptr);
137 // This cast is safe only if the class overrides Clone().
138 auto *props_copy_ptr = static_cast<TestProperties *>(copy_sp.get());
139 ASSERT_TRUE(props_copy_ptr);
141 // Test the first child.
142 auto dict_copy_ptr = props_copy_ptr->GetDictionary();
143 ASSERT_TRUE(dict_copy_ptr);
144 ASSERT_EQ(dict_copy_ptr->GetParent(), copy_sp);
145 ASSERT_TRUE(dict_copy_ptr->OptionWasSet());
146 ASSERT_EQ(dict_copy_ptr->GetNumValues(), 2U);
148 auto value_ptr = dict_copy_ptr->GetValueForKey("A");
149 ASSERT_TRUE(value_ptr);
150 ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
151 ASSERT_EQ(value_ptr->GetValueAs<uint64_t>(), 1U);
153 value_ptr = dict_copy_ptr->GetValueForKey("B");
154 ASSERT_TRUE(value_ptr);
155 ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
156 ASSERT_EQ(value_ptr->GetValueAs<uint64_t>(), 2U);
158 // Test the second child.
159 auto file_list_copy_ptr = props_copy_ptr->GetFileList();
160 ASSERT_TRUE(file_list_copy_ptr);
161 ASSERT_EQ(file_list_copy_ptr->GetParent(), copy_sp);
162 ASSERT_TRUE(file_list_copy_ptr->OptionWasSet());
164 auto file_list_copy = file_list_copy_ptr->GetCurrentValue();
165 ASSERT_EQ(file_list_copy.GetSize(), 1U);
166 ASSERT_EQ(file_list_copy.GetFileSpecAtIndex(0), FileSpec("path/to/file"));
168 // Trigger the callback first time.
169 dict_copy_ptr->SetValueFromString("C=3", eVarSetOperationAppend);
171 // Trigger the callback second time.
172 file_list_copy_ptr->SetValueFromString("0 another/path",
173 eVarSetOperationReplace);