forked from OSchip/llvm-project
176 lines
5.7 KiB
C++
176 lines
5.7 KiB
C++
//===-- TestOptionValue.cpp -------- -------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Interpreter/OptionValues.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace lldb_private;
|
|
|
|
class Callback {
|
|
public:
|
|
virtual void Invoke() const {}
|
|
void operator()() const { Invoke(); }
|
|
protected:
|
|
~Callback() = default;
|
|
};
|
|
|
|
class MockCallback final : public Callback {
|
|
public:
|
|
MOCK_CONST_METHOD0(Invoke, void());
|
|
};
|
|
|
|
// Test a single-value class.
|
|
TEST(OptionValueString, DeepCopy) {
|
|
OptionValueString str;
|
|
str.SetValueFromString("ab");
|
|
|
|
MockCallback callback;
|
|
str.SetValueChangedCallback([&callback] { callback(); });
|
|
EXPECT_CALL(callback, Invoke());
|
|
|
|
auto copy_sp = str.DeepCopy(nullptr);
|
|
|
|
// Test that the base class data members are copied/set correctly.
|
|
ASSERT_TRUE(copy_sp);
|
|
ASSERT_EQ(copy_sp->GetParent().get(), nullptr);
|
|
ASSERT_TRUE(copy_sp->OptionWasSet());
|
|
ASSERT_EQ(copy_sp->GetStringValue(), "ab");
|
|
|
|
// Trigger the callback.
|
|
copy_sp->SetValueFromString("c", eVarSetOperationAppend);
|
|
ASSERT_EQ(copy_sp->GetStringValue(), "abc");
|
|
}
|
|
|
|
// Test an aggregate class.
|
|
TEST(OptionValueArgs, DeepCopy) {
|
|
OptionValueArgs args;
|
|
args.SetValueFromString("A B");
|
|
|
|
MockCallback callback;
|
|
args.SetValueChangedCallback([&callback] { callback(); });
|
|
EXPECT_CALL(callback, Invoke());
|
|
|
|
auto copy_sp = args.DeepCopy(nullptr);
|
|
|
|
// Test that the base class data members are copied/set correctly.
|
|
ASSERT_TRUE(copy_sp);
|
|
ASSERT_EQ(copy_sp->GetParent(), nullptr);
|
|
ASSERT_TRUE(copy_sp->OptionWasSet());
|
|
|
|
auto *args_copy_ptr = copy_sp->GetAsArgs();
|
|
ASSERT_EQ(args_copy_ptr->GetSize(), 2U);
|
|
ASSERT_EQ((*args_copy_ptr)[0]->GetParent(), copy_sp);
|
|
ASSERT_EQ((*args_copy_ptr)[0]->GetStringValue(), "A");
|
|
ASSERT_EQ((*args_copy_ptr)[1]->GetParent(), copy_sp);
|
|
ASSERT_EQ((*args_copy_ptr)[1]->GetStringValue(), "B");
|
|
|
|
// Trigger the callback.
|
|
copy_sp->SetValueFromString("C", eVarSetOperationAppend);
|
|
ASSERT_TRUE(args_copy_ptr);
|
|
ASSERT_EQ(args_copy_ptr->GetSize(), 3U);
|
|
ASSERT_EQ((*args_copy_ptr)[2]->GetStringValue(), "C");
|
|
}
|
|
|
|
class TestProperties : public OptionValueProperties {
|
|
public:
|
|
static std::shared_ptr<TestProperties> CreateGlobal() {
|
|
auto props_sp = std::make_shared<TestProperties>();
|
|
const bool is_global = false;
|
|
|
|
auto dict_sp = std::make_shared<OptionValueDictionary>(1 << eTypeUInt64);
|
|
props_sp->AppendProperty(ConstString("dict"), ConstString(), is_global,
|
|
dict_sp);
|
|
|
|
auto file_list_sp = std::make_shared<OptionValueFileSpecList>();
|
|
props_sp->AppendProperty(ConstString("file-list"), ConstString(), is_global,
|
|
file_list_sp);
|
|
return props_sp;
|
|
}
|
|
|
|
void SetDictionaryChangedCallback(const MockCallback &callback) {
|
|
SetValueChangedCallback(m_dict_index, [&callback] { callback(); });
|
|
}
|
|
|
|
void SetFileListChangedCallback(const MockCallback &callback) {
|
|
SetValueChangedCallback(m_file_list_index, [&callback] { callback(); });
|
|
}
|
|
|
|
OptionValueDictionary *GetDictionary() {
|
|
return GetPropertyAtIndexAsOptionValueDictionary(nullptr, m_dict_index);
|
|
}
|
|
|
|
OptionValueFileSpecList *GetFileList() {
|
|
return GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true,
|
|
m_file_list_index);
|
|
}
|
|
|
|
private:
|
|
lldb::OptionValueSP Clone() const {
|
|
return std::make_shared<TestProperties>(*this);
|
|
}
|
|
|
|
uint32_t m_dict_index = 0;
|
|
uint32_t m_file_list_index = 1;
|
|
};
|
|
|
|
// Test a user-defined propery class.
|
|
TEST(TestProperties, DeepCopy) {
|
|
auto props_sp = TestProperties::CreateGlobal();
|
|
props_sp->GetDictionary()->SetValueFromString("A=1 B=2");
|
|
props_sp->GetFileList()->SetValueFromString("path/to/file");
|
|
|
|
MockCallback callback;
|
|
props_sp->SetDictionaryChangedCallback(callback);
|
|
props_sp->SetFileListChangedCallback(callback);
|
|
EXPECT_CALL(callback, Invoke()).Times(2);
|
|
|
|
auto copy_sp = props_sp->DeepCopy(nullptr);
|
|
|
|
// Test that the base class data members are copied/set correctly.
|
|
ASSERT_TRUE(copy_sp);
|
|
ASSERT_EQ(copy_sp->GetParent(), nullptr);
|
|
|
|
// This cast is safe only if the class overrides Clone().
|
|
auto *props_copy_ptr = static_cast<TestProperties *>(copy_sp.get());
|
|
ASSERT_TRUE(props_copy_ptr);
|
|
|
|
// Test the first child.
|
|
auto dict_copy_ptr = props_copy_ptr->GetDictionary();
|
|
ASSERT_TRUE(dict_copy_ptr);
|
|
ASSERT_EQ(dict_copy_ptr->GetParent(), copy_sp);
|
|
ASSERT_TRUE(dict_copy_ptr->OptionWasSet());
|
|
ASSERT_EQ(dict_copy_ptr->GetNumValues(), 2U);
|
|
|
|
auto value_ptr = dict_copy_ptr->GetValueForKey(ConstString("A"));
|
|
ASSERT_TRUE(value_ptr);
|
|
ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
|
|
ASSERT_EQ(value_ptr->GetUInt64Value(), 1U);
|
|
|
|
value_ptr = dict_copy_ptr->GetValueForKey(ConstString("B"));
|
|
ASSERT_TRUE(value_ptr);
|
|
ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
|
|
ASSERT_EQ(value_ptr->GetUInt64Value(), 2U);
|
|
|
|
// Test the second child.
|
|
auto file_list_copy_ptr = props_copy_ptr->GetFileList();
|
|
ASSERT_TRUE(file_list_copy_ptr);
|
|
ASSERT_EQ(file_list_copy_ptr->GetParent(), copy_sp);
|
|
ASSERT_TRUE(file_list_copy_ptr->OptionWasSet());
|
|
|
|
auto file_list_copy = file_list_copy_ptr->GetCurrentValue();
|
|
ASSERT_EQ(file_list_copy.GetSize(), 1U);
|
|
ASSERT_EQ(file_list_copy.GetFileSpecAtIndex(0), FileSpec("path/to/file"));
|
|
|
|
// Trigger the callback first time.
|
|
dict_copy_ptr->SetValueFromString("C=3", eVarSetOperationAppend);
|
|
|
|
// Trigger the callback second time.
|
|
file_list_copy_ptr->SetValueFromString("0 another/path", eVarSetOperationReplace);
|
|
}
|