Value now carries a shared_ptr<Bindings>, and all Bindings constructors return a unique_ptr<Bindings>. The test that wanted to compare two Bindings by putting them into Values has been modified to use the new Equal() method on Bindings (extracted from EvalState). Change-Id: I8dfb60e65fdabb717e3b3e5d56d5b3fc82f70883 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1744 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi> Reviewed-by: tazjin <mail@tazj.in>
155 lines
4.3 KiB
C++
155 lines
4.3 KiB
C++
#include "libexpr/attr-set.hh"
|
|
|
|
#include <cstdio>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <absl/container/btree_map.h>
|
|
#include <bits/stdint-intn.h>
|
|
#include <gtest/gtest.h>
|
|
#include <rapidcheck.h>
|
|
#include <rapidcheck/Assertions.h>
|
|
#include <rapidcheck/gen/Arbitrary.h>
|
|
#include <rapidcheck/gen/Build.h>
|
|
#include <rapidcheck/gen/Create.h>
|
|
#include <rapidcheck/gen/Transform.h>
|
|
#include <rapidcheck/gtest.h>
|
|
|
|
#include "libexpr/eval.hh"
|
|
#include "libexpr/nixexpr.hh"
|
|
#include "libexpr/symbol-table.hh"
|
|
#include "libexpr/value.hh"
|
|
#include "tests/dummy-store.hh"
|
|
|
|
static nix::SymbolTable* symbol_table;
|
|
|
|
namespace rc {
|
|
using nix::Pos;
|
|
using nix::Value;
|
|
|
|
// TODO(grfn): These arbitrary implementations should be pulled out to a util
|
|
// file sooner rather than later
|
|
|
|
template <>
|
|
struct Arbitrary<nix::Symbol> {
|
|
static Gen<nix::Symbol> arbitrary() {
|
|
return gen::map(gen::arbitrary<std::string>(),
|
|
[](std::string s) { return symbol_table->Create(s); });
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<Value> {
|
|
static Gen<nix::Value> arbitrary() {
|
|
return gen::build(gen::construct<Value>(),
|
|
// TODO(grfn) generalize to more types
|
|
gen::set(&Value::type, gen::just(nix::ValueType::tInt)),
|
|
gen::set(&Value::integer, gen::arbitrary<int64_t>()));
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<Value*> {
|
|
static Gen<nix::Value*> arbitrary() {
|
|
return gen::apply(
|
|
[](nix::ValueType typ, int i) {
|
|
auto ret = new Value();
|
|
ret->type = typ;
|
|
ret->integer = i;
|
|
return ret;
|
|
},
|
|
gen::just(nix::ValueType::tInt), gen::arbitrary<int64_t>());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<nix::Pos> {
|
|
static Gen<nix::Pos> arbitrary() {
|
|
return gen::construct<nix::Pos>(gen::arbitrary<nix::Symbol>(),
|
|
gen::arbitrary<unsigned int>(),
|
|
gen::arbitrary<unsigned int>());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<nix::Pos*> {
|
|
static Gen<nix::Pos*> arbitrary() {
|
|
return gen::apply(
|
|
[](unsigned int line, unsigned int column) {
|
|
return new Pos({}, line, column);
|
|
},
|
|
gen::arbitrary<unsigned int>(), gen::arbitrary<unsigned int>());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<nix::Attr> {
|
|
static Gen<nix::Attr> arbitrary() {
|
|
return gen::construct<nix::Attr>(gen::arbitrary<nix::Symbol>(),
|
|
gen::arbitrary<Value*>(),
|
|
gen::arbitrary<nix::Pos*>());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct Arbitrary<nix::Bindings> {
|
|
static Gen<nix::Bindings> arbitrary() {
|
|
return gen::map(gen::arbitrary<std::vector<nix::Attr>>(), [](auto attrs) {
|
|
nix::Bindings res;
|
|
for (const auto& attr : attrs) {
|
|
res.push_back(attr);
|
|
}
|
|
return res;
|
|
});
|
|
}
|
|
};
|
|
|
|
} // namespace rc
|
|
|
|
namespace nix {
|
|
|
|
using nix::tests::DummyStore;
|
|
|
|
class AttrSetTest : public ::testing::Test {
|
|
protected:
|
|
EvalState* eval_state_;
|
|
void SetUp() override {
|
|
nix::expr::InitGC();
|
|
auto store = std::make_shared<DummyStore>();
|
|
eval_state_ = new EvalState({"."}, ref<Store>(store));
|
|
symbol_table = &eval_state_->symbols;
|
|
}
|
|
|
|
void assert_bindings_equal(nix::Bindings* lhs, nix::Bindings* rhs) {
|
|
RC_ASSERT(lhs->Equal(rhs, *eval_state_));
|
|
}
|
|
};
|
|
|
|
class AttrSetMonoidTest : public AttrSetTest {};
|
|
|
|
RC_GTEST_FIXTURE_PROP(AttrSetMonoidTest, mergeLeftIdentity,
|
|
(nix::Bindings && bindings)) {
|
|
auto empty_bindings = nix::Bindings::New();
|
|
auto result = Bindings::Merge(*empty_bindings, bindings);
|
|
assert_bindings_equal(result.get(), &bindings);
|
|
}
|
|
|
|
RC_GTEST_FIXTURE_PROP(AttrSetMonoidTest, mergeRightIdentity,
|
|
(nix::Bindings && bindings)) {
|
|
auto empty_bindings = nix::Bindings::New();
|
|
auto result = Bindings::Merge(bindings, *empty_bindings);
|
|
assert_bindings_equal(result.get(), &bindings);
|
|
}
|
|
|
|
RC_GTEST_FIXTURE_PROP(AttrSetMonoidTest, mergeAssociative,
|
|
(nix::Bindings && bindings_1, nix::Bindings&& bindings_2,
|
|
nix::Bindings&& bindings_3)) {
|
|
auto b231 =
|
|
Bindings::Merge(bindings_1, *Bindings::Merge(bindings_2, bindings_3));
|
|
auto b123 =
|
|
Bindings::Merge(*Bindings::Merge(bindings_1, bindings_2), bindings_3);
|
|
assert_bindings_equal(b231.get(), b123.get());
|
|
}
|
|
|
|
} // namespace nix
|