xref: /llvm-project/lldb/unittests/Interpreter/TestOptionValue.cpp (revision 2014572d9a6839745a920ec19ebfa73814548061)
1f0f183eeSTatyana Krasnukha //===-- TestOptionValue.cpp --------        -------------------------------===//
2f0f183eeSTatyana Krasnukha //
3f0f183eeSTatyana Krasnukha // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f0f183eeSTatyana Krasnukha // See https://llvm.org/LICENSE.txt for license information.
5f0f183eeSTatyana Krasnukha // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f0f183eeSTatyana Krasnukha //
7f0f183eeSTatyana Krasnukha //===----------------------------------------------------------------------===//
8f0f183eeSTatyana Krasnukha 
9f0f183eeSTatyana Krasnukha #include "lldb/Interpreter/OptionValues.h"
10f0f183eeSTatyana Krasnukha #include "gmock/gmock.h"
11f0f183eeSTatyana Krasnukha #include "gtest/gtest.h"
12f0f183eeSTatyana Krasnukha 
13f0f183eeSTatyana Krasnukha using namespace lldb_private;
14f0f183eeSTatyana Krasnukha 
15f0f183eeSTatyana Krasnukha class Callback {
16f0f183eeSTatyana Krasnukha public:
Invoke() const17f0f183eeSTatyana Krasnukha   virtual void Invoke() const {}
operator ()() const18f0f183eeSTatyana Krasnukha   void operator()() const { Invoke(); }
19611bd6c6SJonas Devlieghere 
20776be16bSDavid Blaikie protected:
21776be16bSDavid Blaikie   ~Callback() = default;
22f0f183eeSTatyana Krasnukha };
23f0f183eeSTatyana Krasnukha 
24776be16bSDavid Blaikie class MockCallback final : public Callback {
25f0f183eeSTatyana Krasnukha public:
26f0f183eeSTatyana Krasnukha   MOCK_CONST_METHOD0(Invoke, void());
27f0f183eeSTatyana Krasnukha };
28f0f183eeSTatyana Krasnukha 
29f0f183eeSTatyana Krasnukha // Test a single-value class.
TEST(OptionValueString,DeepCopy)30f0f183eeSTatyana Krasnukha TEST(OptionValueString, DeepCopy) {
31f0f183eeSTatyana Krasnukha   OptionValueString str;
32f0f183eeSTatyana Krasnukha   str.SetValueFromString("ab");
33f0f183eeSTatyana Krasnukha 
34f0f183eeSTatyana Krasnukha   MockCallback callback;
35f0f183eeSTatyana Krasnukha   str.SetValueChangedCallback([&callback] { callback(); });
36f0f183eeSTatyana Krasnukha   EXPECT_CALL(callback, Invoke());
37f0f183eeSTatyana Krasnukha 
38f0f183eeSTatyana Krasnukha   auto copy_sp = str.DeepCopy(nullptr);
39f0f183eeSTatyana Krasnukha 
40f0f183eeSTatyana Krasnukha   // Test that the base class data members are copied/set correctly.
41f0f183eeSTatyana Krasnukha   ASSERT_TRUE(copy_sp);
42f0f183eeSTatyana Krasnukha   ASSERT_EQ(copy_sp->GetParent().get(), nullptr);
43f0f183eeSTatyana Krasnukha   ASSERT_TRUE(copy_sp->OptionWasSet());
443ebb3363SJonas Devlieghere   ASSERT_EQ(copy_sp->GetValueAs<llvm::StringRef>(), "ab");
45f0f183eeSTatyana Krasnukha 
46f0f183eeSTatyana Krasnukha   // Trigger the callback.
47f0f183eeSTatyana Krasnukha   copy_sp->SetValueFromString("c", eVarSetOperationAppend);
483ebb3363SJonas Devlieghere   ASSERT_EQ(copy_sp->GetValueAs<llvm::StringRef>(), "abc");
49f0f183eeSTatyana Krasnukha }
50f0f183eeSTatyana Krasnukha 
51f0f183eeSTatyana Krasnukha // Test an aggregate class.
TEST(OptionValueArgs,DeepCopy)52f0f183eeSTatyana Krasnukha TEST(OptionValueArgs, DeepCopy) {
53f0f183eeSTatyana Krasnukha   OptionValueArgs args;
54f0f183eeSTatyana Krasnukha   args.SetValueFromString("A B");
55f0f183eeSTatyana Krasnukha 
56f0f183eeSTatyana Krasnukha   MockCallback callback;
57f0f183eeSTatyana Krasnukha   args.SetValueChangedCallback([&callback] { callback(); });
58f0f183eeSTatyana Krasnukha   EXPECT_CALL(callback, Invoke());
59f0f183eeSTatyana Krasnukha 
60f0f183eeSTatyana Krasnukha   auto copy_sp = args.DeepCopy(nullptr);
61f0f183eeSTatyana Krasnukha 
62f0f183eeSTatyana Krasnukha   // Test that the base class data members are copied/set correctly.
63f0f183eeSTatyana Krasnukha   ASSERT_TRUE(copy_sp);
64f0f183eeSTatyana Krasnukha   ASSERT_EQ(copy_sp->GetParent(), nullptr);
65f0f183eeSTatyana Krasnukha   ASSERT_TRUE(copy_sp->OptionWasSet());
66f0f183eeSTatyana Krasnukha 
67f0f183eeSTatyana Krasnukha   auto *args_copy_ptr = copy_sp->GetAsArgs();
68f0f183eeSTatyana Krasnukha   ASSERT_EQ(args_copy_ptr->GetSize(), 2U);
69f0f183eeSTatyana Krasnukha   ASSERT_EQ((*args_copy_ptr)[0]->GetParent(), copy_sp);
703ebb3363SJonas Devlieghere   ASSERT_EQ((*args_copy_ptr)[0]->GetValueAs<llvm::StringRef>(), "A");
71f0f183eeSTatyana Krasnukha   ASSERT_EQ((*args_copy_ptr)[1]->GetParent(), copy_sp);
723ebb3363SJonas Devlieghere   ASSERT_EQ((*args_copy_ptr)[1]->GetValueAs<llvm::StringRef>(), "B");
73f0f183eeSTatyana Krasnukha 
74f0f183eeSTatyana Krasnukha   // Trigger the callback.
75f0f183eeSTatyana Krasnukha   copy_sp->SetValueFromString("C", eVarSetOperationAppend);
76f0f183eeSTatyana Krasnukha   ASSERT_TRUE(args_copy_ptr);
77f0f183eeSTatyana Krasnukha   ASSERT_EQ(args_copy_ptr->GetSize(), 3U);
783ebb3363SJonas Devlieghere   ASSERT_EQ((*args_copy_ptr)[2]->GetValueAs<llvm::StringRef>(), "C");
79f0f183eeSTatyana Krasnukha }
80f0f183eeSTatyana Krasnukha 
81f0f183eeSTatyana Krasnukha class TestProperties : public OptionValueProperties {
82f0f183eeSTatyana Krasnukha public:
CreateGlobal()83f0f183eeSTatyana Krasnukha   static std::shared_ptr<TestProperties> CreateGlobal() {
84f0f183eeSTatyana Krasnukha     auto props_sp = std::make_shared<TestProperties>();
85f0f183eeSTatyana Krasnukha     const bool is_global = false;
86f0f183eeSTatyana Krasnukha 
87f0f183eeSTatyana Krasnukha     auto dict_sp = std::make_shared<OptionValueDictionary>(1 << eTypeUInt64);
88*2014572dSAlex Langford     props_sp->AppendProperty("dict", "", is_global, dict_sp);
89f0f183eeSTatyana Krasnukha 
90f0f183eeSTatyana Krasnukha     auto file_list_sp = std::make_shared<OptionValueFileSpecList>();
91*2014572dSAlex Langford     props_sp->AppendProperty("file-list", "", is_global, file_list_sp);
92f0f183eeSTatyana Krasnukha     return props_sp;
93f0f183eeSTatyana Krasnukha   }
94f0f183eeSTatyana Krasnukha 
SetDictionaryChangedCallback(const MockCallback & callback)95f0f183eeSTatyana Krasnukha   void SetDictionaryChangedCallback(const MockCallback &callback) {
96f0f183eeSTatyana Krasnukha     SetValueChangedCallback(m_dict_index, [&callback] { callback(); });
97f0f183eeSTatyana Krasnukha   }
98f0f183eeSTatyana Krasnukha 
SetFileListChangedCallback(const MockCallback & callback)99f0f183eeSTatyana Krasnukha   void SetFileListChangedCallback(const MockCallback &callback) {
100f0f183eeSTatyana Krasnukha     SetValueChangedCallback(m_file_list_index, [&callback] { callback(); });
101f0f183eeSTatyana Krasnukha   }
102f0f183eeSTatyana Krasnukha 
GetDictionary()103f0f183eeSTatyana Krasnukha   OptionValueDictionary *GetDictionary() {
104611bd6c6SJonas Devlieghere     return GetPropertyAtIndexAsOptionValueDictionary(m_dict_index);
105f0f183eeSTatyana Krasnukha   }
106f0f183eeSTatyana Krasnukha 
GetFileList()107f0f183eeSTatyana Krasnukha   OptionValueFileSpecList *GetFileList() {
108611bd6c6SJonas Devlieghere     return GetPropertyAtIndexAsOptionValueFileSpecList(m_file_list_index);
109f0f183eeSTatyana Krasnukha   }
110f0f183eeSTatyana Krasnukha 
111f0f183eeSTatyana Krasnukha private:
Clone() const112fd146460SShafik Yaghmour   lldb::OptionValueSP Clone() const override {
113f0f183eeSTatyana Krasnukha     return std::make_shared<TestProperties>(*this);
114f0f183eeSTatyana Krasnukha   }
115f0f183eeSTatyana Krasnukha 
116f0f183eeSTatyana Krasnukha   uint32_t m_dict_index = 0;
117f0f183eeSTatyana Krasnukha   uint32_t m_file_list_index = 1;
118f0f183eeSTatyana Krasnukha };
119f0f183eeSTatyana Krasnukha 
120f0f183eeSTatyana Krasnukha // Test a user-defined propery class.
TEST(TestProperties,DeepCopy)121f0f183eeSTatyana Krasnukha TEST(TestProperties, DeepCopy) {
122f0f183eeSTatyana Krasnukha   auto props_sp = TestProperties::CreateGlobal();
123f0f183eeSTatyana Krasnukha   props_sp->GetDictionary()->SetValueFromString("A=1 B=2");
124f0f183eeSTatyana Krasnukha   props_sp->GetFileList()->SetValueFromString("path/to/file");
125f0f183eeSTatyana Krasnukha 
126f0f183eeSTatyana Krasnukha   MockCallback callback;
127f0f183eeSTatyana Krasnukha   props_sp->SetDictionaryChangedCallback(callback);
128f0f183eeSTatyana Krasnukha   props_sp->SetFileListChangedCallback(callback);
129f0f183eeSTatyana Krasnukha   EXPECT_CALL(callback, Invoke()).Times(2);
130f0f183eeSTatyana Krasnukha 
131f0f183eeSTatyana Krasnukha   auto copy_sp = props_sp->DeepCopy(nullptr);
132f0f183eeSTatyana Krasnukha 
133f0f183eeSTatyana Krasnukha   // Test that the base class data members are copied/set correctly.
134f0f183eeSTatyana Krasnukha   ASSERT_TRUE(copy_sp);
135f0f183eeSTatyana Krasnukha   ASSERT_EQ(copy_sp->GetParent(), nullptr);
136f0f183eeSTatyana Krasnukha 
137f0f183eeSTatyana Krasnukha   // This cast is safe only if the class overrides Clone().
138f0f183eeSTatyana Krasnukha   auto *props_copy_ptr = static_cast<TestProperties *>(copy_sp.get());
139f0f183eeSTatyana Krasnukha   ASSERT_TRUE(props_copy_ptr);
140f0f183eeSTatyana Krasnukha 
141f0f183eeSTatyana Krasnukha   // Test the first child.
142f0f183eeSTatyana Krasnukha   auto dict_copy_ptr = props_copy_ptr->GetDictionary();
143f0f183eeSTatyana Krasnukha   ASSERT_TRUE(dict_copy_ptr);
144f0f183eeSTatyana Krasnukha   ASSERT_EQ(dict_copy_ptr->GetParent(), copy_sp);
145f0f183eeSTatyana Krasnukha   ASSERT_TRUE(dict_copy_ptr->OptionWasSet());
146f0f183eeSTatyana Krasnukha   ASSERT_EQ(dict_copy_ptr->GetNumValues(), 2U);
147f0f183eeSTatyana Krasnukha 
148e53e1de5SAlex Langford   auto value_ptr = dict_copy_ptr->GetValueForKey("A");
149f0f183eeSTatyana Krasnukha   ASSERT_TRUE(value_ptr);
150f0f183eeSTatyana Krasnukha   ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
1513ebb3363SJonas Devlieghere   ASSERT_EQ(value_ptr->GetValueAs<uint64_t>(), 1U);
152f0f183eeSTatyana Krasnukha 
153e53e1de5SAlex Langford   value_ptr = dict_copy_ptr->GetValueForKey("B");
154f0f183eeSTatyana Krasnukha   ASSERT_TRUE(value_ptr);
155f0f183eeSTatyana Krasnukha   ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
1563ebb3363SJonas Devlieghere   ASSERT_EQ(value_ptr->GetValueAs<uint64_t>(), 2U);
157f0f183eeSTatyana Krasnukha 
158f0f183eeSTatyana Krasnukha   // Test the second child.
159f0f183eeSTatyana Krasnukha   auto file_list_copy_ptr = props_copy_ptr->GetFileList();
160f0f183eeSTatyana Krasnukha   ASSERT_TRUE(file_list_copy_ptr);
161f0f183eeSTatyana Krasnukha   ASSERT_EQ(file_list_copy_ptr->GetParent(), copy_sp);
162f0f183eeSTatyana Krasnukha   ASSERT_TRUE(file_list_copy_ptr->OptionWasSet());
163f0f183eeSTatyana Krasnukha 
164f0f183eeSTatyana Krasnukha   auto file_list_copy = file_list_copy_ptr->GetCurrentValue();
165f0f183eeSTatyana Krasnukha   ASSERT_EQ(file_list_copy.GetSize(), 1U);
166f0f183eeSTatyana Krasnukha   ASSERT_EQ(file_list_copy.GetFileSpecAtIndex(0), FileSpec("path/to/file"));
167f0f183eeSTatyana Krasnukha 
168f0f183eeSTatyana Krasnukha   // Trigger the callback first time.
169f0f183eeSTatyana Krasnukha   dict_copy_ptr->SetValueFromString("C=3", eVarSetOperationAppend);
170f0f183eeSTatyana Krasnukha 
171f0f183eeSTatyana Krasnukha   // Trigger the callback second time.
172611bd6c6SJonas Devlieghere   file_list_copy_ptr->SetValueFromString("0 another/path",
173611bd6c6SJonas Devlieghere                                          eVarSetOperationReplace);
174f0f183eeSTatyana Krasnukha }
175