aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-08-25 10:20:28 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-12-01 13:05:03 -0500
commitf7f37035c81fa825a4dfc2df1ad2589013ac6380 (patch)
treebfcfef3efeb73cb0c3c6d812280191d03bda1233 /src/libexpr
parent30dcc19d1f30fc203be460134c4578509cce704f (diff)
Move tests to separate directories, and document
Today, with the tests inside a `tests` intermingled with the corresponding library's source code, we have a few problems: - We have to be careful that wildcards don't end up with tests being built as part of Nix proper, or test headers being installed as part of Nix proper. - Tests in libraries but not executables is not right: - It means each executable runs the previous unit tests again, because it needs the libraries. - It doesn't work right on Windows, which doesn't want you to load a DLL just for the side global variable . It could be made to work with the dlopen equivalent, but that's gross! This reorg solves these problems. There is a remaining problem which is that sibbling headers (like `hash.hh` the test header vs `hash.hh` the main `libnixutil` header) end up shadowing each other. This PR doesn't solve that. That is left as future work for a future PR. Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io> (cherry picked from commit 91b6833686a6a6d9eac7f3f66393ec89ef1d3b57) (cherry picked from commit a61e42adb528b3d40ce43e07c79368d779a8b624)
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/tests/derived-path.cc68
-rw-r--r--src/libexpr/tests/error_traces.cc1298
-rw-r--r--src/libexpr/tests/flakeref.cc22
-rw-r--r--src/libexpr/tests/json.cc68
-rw-r--r--src/libexpr/tests/libexpr.hh140
-rw-r--r--src/libexpr/tests/local.mk19
-rw-r--r--src/libexpr/tests/primops.cc832
-rw-r--r--src/libexpr/tests/search-path.cc90
-rw-r--r--src/libexpr/tests/trivial.cc196
-rw-r--r--src/libexpr/tests/value/context.cc162
-rw-r--r--src/libexpr/tests/value/context.hh31
-rw-r--r--src/libexpr/tests/value/print.cc236
12 files changed, 0 insertions, 3162 deletions
diff --git a/src/libexpr/tests/derived-path.cc b/src/libexpr/tests/derived-path.cc
deleted file mode 100644
index d5fc6f201..000000000
--- a/src/libexpr/tests/derived-path.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-
-#include "tests/derived-path.hh"
-#include "tests/libexpr.hh"
-
-namespace nix {
-
-// Testing of trivial expressions
-class DerivedPathExpressionTest : public LibExprTest {};
-
-// FIXME: `RC_GTEST_FIXTURE_PROP` isn't calling `SetUpTestSuite` because it is
-// no a real fixture.
-//
-// See https://github.com/emil-e/rapidcheck/blob/master/doc/gtest.md#rc_gtest_fixture_propfixture-name-args
-TEST_F(DerivedPathExpressionTest, force_init)
-{
-}
-
-#ifndef COVERAGE
-
-RC_GTEST_FIXTURE_PROP(
- DerivedPathExpressionTest,
- prop_opaque_path_round_trip,
- (const SingleDerivedPath::Opaque & o))
-{
- auto * v = state.allocValue();
- state.mkStorePathString(o.path, *v);
- auto d = state.coerceToSingleDerivedPath(noPos, *v, "");
- RC_ASSERT(SingleDerivedPath { o } == d);
-}
-
-// TODO use DerivedPath::Built for parameter once it supports a single output
-// path only.
-
-RC_GTEST_FIXTURE_PROP(
- DerivedPathExpressionTest,
- prop_derived_path_built_placeholder_round_trip,
- (const SingleDerivedPath::Built & b))
-{
- /**
- * We set these in tests rather than the regular globals so we don't have
- * to worry about race conditions if the tests run concurrently.
- */
- ExperimentalFeatureSettings mockXpSettings;
- mockXpSettings.set("experimental-features", "ca-derivations");
-
- auto * v = state.allocValue();
- state.mkOutputString(*v, b, std::nullopt, mockXpSettings);
- auto [d, _] = state.coerceToSingleDerivedPathUnchecked(noPos, *v, "");
- RC_ASSERT(SingleDerivedPath { b } == d);
-}
-
-RC_GTEST_FIXTURE_PROP(
- DerivedPathExpressionTest,
- prop_derived_path_built_out_path_round_trip,
- (const SingleDerivedPath::Built & b, const StorePath & outPath))
-{
- auto * v = state.allocValue();
- state.mkOutputString(*v, b, outPath);
- auto [d, _] = state.coerceToSingleDerivedPathUnchecked(noPos, *v, "");
- RC_ASSERT(SingleDerivedPath { b } == d);
-}
-
-#endif
-
-} /* namespace nix */
diff --git a/src/libexpr/tests/error_traces.cc b/src/libexpr/tests/error_traces.cc
deleted file mode 100644
index 285651256..000000000
--- a/src/libexpr/tests/error_traces.cc
+++ /dev/null
@@ -1,1298 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "tests/libexpr.hh"
-
-namespace nix {
-
- using namespace testing;
-
- // Testing eval of PrimOp's
- class ErrorTraceTest : public LibExprTest { };
-
- TEST_F(ErrorTraceTest, TraceBuilder) {
- ASSERT_THROW(
- state.error("Not much").debugThrow<EvalError>(),
- EvalError
- );
-
- ASSERT_THROW(
- state.error("Not much").withTrace(noPos, "No more").debugThrow<EvalError>(),
- EvalError
- );
-
- ASSERT_THROW(
- try {
- try {
- state.error("Not much").withTrace(noPos, "No more").debugThrow<EvalError>();
- } catch (Error & e) {
- e.addTrace(state.positions[noPos], "Something", "");
- throw;
- }
- } catch (BaseError & e) {
- ASSERT_EQ(PrintToString(e.info().msg),
- PrintToString(hintfmt("Not much")));
- auto trace = e.info().traces.rbegin();
- ASSERT_EQ(e.info().traces.size(), 2);
- ASSERT_EQ(PrintToString(trace->hint),
- PrintToString(hintfmt("No more")));
- trace++;
- ASSERT_EQ(PrintToString(trace->hint),
- PrintToString(hintfmt("Something")));
- throw;
- }
- , EvalError
- );
- }
-
- TEST_F(ErrorTraceTest, NestedThrows) {
- try {
- state.error("Not much").withTrace(noPos, "No more").debugThrow<EvalError>();
- } catch (BaseError & e) {
- try {
- state.error("Not much more").debugThrow<EvalError>();
- } catch (Error & e2) {
- e.addTrace(state.positions[noPos], "Something", "");
- //e2.addTrace(state.positions[noPos], "Something", "");
- ASSERT_TRUE(e.info().traces.size() == 2);
- ASSERT_TRUE(e2.info().traces.size() == 0);
- ASSERT_FALSE(&e.info() == &e2.info());
- }
- }
- }
-
-#define ASSERT_TRACE1(args, type, message) \
- ASSERT_THROW( \
- std::string expr(args); \
- std::string name = expr.substr(0, expr.find(" ")); \
- try { \
- Value v = eval("builtins." args); \
- state.forceValueDeep(v); \
- } catch (BaseError & e) { \
- ASSERT_EQ(PrintToString(e.info().msg), \
- PrintToString(message)); \
- ASSERT_EQ(e.info().traces.size(), 1) << "while testing " args << std::endl << e.what(); \
- auto trace = e.info().traces.rbegin(); \
- ASSERT_EQ(PrintToString(trace->hint), \
- PrintToString(hintfmt("while calling the '%s' builtin", name))); \
- throw; \
- } \
- , type \
- )
-
-#define ASSERT_TRACE2(args, type, message, context) \
- ASSERT_THROW( \
- std::string expr(args); \
- std::string name = expr.substr(0, expr.find(" ")); \
- try { \
- Value v = eval("builtins." args); \
- state.forceValueDeep(v); \
- } catch (BaseError & e) { \
- ASSERT_EQ(PrintToString(e.info().msg), \
- PrintToString(message)); \
- ASSERT_EQ(e.info().traces.size(), 2) << "while testing " args << std::endl << e.what(); \
- auto trace = e.info().traces.rbegin(); \
- ASSERT_EQ(PrintToString(trace->hint), \
- PrintToString(context)); \
- ++trace; \
- ASSERT_EQ(PrintToString(trace->hint), \
- PrintToString(hintfmt("while calling the '%s' builtin", name))); \
- throw; \
- } \
- , type \
- )
-
- TEST_F(ErrorTraceTest, genericClosure) {
- ASSERT_TRACE2("genericClosure 1",
- TypeError,
- hintfmt("value is %s while a set was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure {}",
- TypeError,
- hintfmt("attribute '%s' missing", "startSet"),
- hintfmt("in the attrset passed as argument to builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = 1; }",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the 'startSet' attribute passed as argument to builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = [{ key = 1;}]; operator = true; }",
- TypeError,
- hintfmt("value is %s while a function was expected", "a Boolean"),
- hintfmt("while evaluating the 'operator' attribute passed as argument to builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = [{ key = 1;}]; operator = item: true; }",
- TypeError,
- hintfmt("value is %s while a list was expected", "a Boolean"),
- hintfmt("while evaluating the return value of the `operator` passed to builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = [{ key = 1;}]; operator = item: [ true ]; }",
- TypeError,
- hintfmt("value is %s while a set was expected", "a Boolean"),
- hintfmt("while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = [{ key = 1;}]; operator = item: [ {} ]; }",
- TypeError,
- hintfmt("attribute '%s' missing", "key"),
- hintfmt("in one of the attrsets generated by (or initially passed to) builtins.genericClosure"));
-
- ASSERT_TRACE2("genericClosure { startSet = [{ key = 1;}]; operator = item: [{ key = ''a''; }]; }",
- EvalError,
- hintfmt("cannot compare %s with %s", "a string", "an integer"),
- hintfmt("while comparing the `key` attributes of two genericClosure elements"));
-
- ASSERT_TRACE2("genericClosure { startSet = [ true ]; operator = item: [{ key = ''a''; }]; }",
- TypeError,
- hintfmt("value is %s while a set was expected", "a Boolean"),
- hintfmt("while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure"));
-
- }
-
-
- TEST_F(ErrorTraceTest, replaceStrings) {
- ASSERT_TRACE2("replaceStrings 0 0 {}",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.replaceStrings"));
-
- ASSERT_TRACE2("replaceStrings [] 0 {}",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the second argument passed to builtins.replaceStrings"));
-
- ASSERT_TRACE1("replaceStrings [ 0 ] [] {}",
- EvalError,
- hintfmt("'from' and 'to' arguments passed to builtins.replaceStrings have different lengths"));
-
- ASSERT_TRACE2("replaceStrings [ 1 ] [ \"new\" ] {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating one of the strings to replace passed to builtins.replaceStrings"));
-
- ASSERT_TRACE2("replaceStrings [ \"oo\" ] [ true ] \"foo\"",
- TypeError,
- hintfmt("value is %s while a string was expected", "a Boolean"),
- hintfmt("while evaluating one of the replacement strings passed to builtins.replaceStrings"));
-
- ASSERT_TRACE2("replaceStrings [ \"old\" ] [ \"new\" ] {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a set"),
- hintfmt("while evaluating the third argument passed to builtins.replaceStrings"));
-
- }
-
-
- TEST_F(ErrorTraceTest, scopedImport) {
- }
-
-
- TEST_F(ErrorTraceTest, import) {
- }
-
-
- TEST_F(ErrorTraceTest, typeOf) {
- }
-
-
- TEST_F(ErrorTraceTest, isNull) {
- }
-
-
- TEST_F(ErrorTraceTest, isFunction) {
- }
-
-
- TEST_F(ErrorTraceTest, isInt) {
- }
-
-
- TEST_F(ErrorTraceTest, isFloat) {
- }
-
-
- TEST_F(ErrorTraceTest, isString) {
- }
-
-
- TEST_F(ErrorTraceTest, isBool) {
- }
-
-
- TEST_F(ErrorTraceTest, isPath) {
- }
-
-
- TEST_F(ErrorTraceTest, break) {
- }
-
-
- TEST_F(ErrorTraceTest, abort) {
- }
-
-
- TEST_F(ErrorTraceTest, throw) {
- }
-
-
- TEST_F(ErrorTraceTest, addErrorContext) {
- }
-
-
- TEST_F(ErrorTraceTest, ceil) {
- ASSERT_TRACE2("ceil \"foo\"",
- TypeError,
- hintfmt("value is %s while a float was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.ceil"));
-
- }
-
-
- TEST_F(ErrorTraceTest, floor) {
- ASSERT_TRACE2("floor \"foo\"",
- TypeError,
- hintfmt("value is %s while a float was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.floor"));
-
- }
-
-
- TEST_F(ErrorTraceTest, tryEval) {
- }
-
-
- TEST_F(ErrorTraceTest, getEnv) {
- ASSERT_TRACE2("getEnv [ ]",
- TypeError,
- hintfmt("value is %s while a string was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.getEnv"));
-
- }
-
-
- TEST_F(ErrorTraceTest, seq) {
- }
-
-
- TEST_F(ErrorTraceTest, deepSeq) {
- }
-
-
- TEST_F(ErrorTraceTest, trace) {
- }
-
-
- TEST_F(ErrorTraceTest, placeholder) {
- ASSERT_TRACE2("placeholder []",
- TypeError,
- hintfmt("value is %s while a string was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.placeholder"));
-
- }
-
-
- TEST_F(ErrorTraceTest, toPath) {
- ASSERT_TRACE2("toPath []",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.toPath"));
-
- ASSERT_TRACE2("toPath \"foo\"",
- EvalError,
- hintfmt("string '%s' doesn't represent an absolute path", "foo"),
- hintfmt("while evaluating the first argument passed to builtins.toPath"));
-
- }
-
-
- TEST_F(ErrorTraceTest, storePath) {
- ASSERT_TRACE2("storePath true",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a Boolean"),
- hintfmt("while evaluating the first argument passed to builtins.storePath"));
-
- }
-
-
- TEST_F(ErrorTraceTest, pathExists) {
- ASSERT_TRACE2("pathExists []",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a list"),
- hintfmt("while realising the context of a path"));
-
- ASSERT_TRACE2("pathExists \"zorglub\"",
- EvalError,
- hintfmt("string '%s' doesn't represent an absolute path", "zorglub"),
- hintfmt("while realising the context of a path"));
-
- }
-
-
- TEST_F(ErrorTraceTest, baseNameOf) {
- ASSERT_TRACE2("baseNameOf []",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.baseNameOf"));
-
- }
-
-
- TEST_F(ErrorTraceTest, dirOf) {
- }
-
-
- TEST_F(ErrorTraceTest, readFile) {
- }
-
-
- TEST_F(ErrorTraceTest, findFile) {
- }
-
-
- TEST_F(ErrorTraceTest, hashFile) {
- }
-
-
- TEST_F(ErrorTraceTest, readDir) {
- }
-
-
- TEST_F(ErrorTraceTest, toXML) {
- }
-
-
- TEST_F(ErrorTraceTest, toJSON) {
- }
-
-
- TEST_F(ErrorTraceTest, fromJSON) {
- }
-
-
- TEST_F(ErrorTraceTest, toFile) {
- }
-
-
- TEST_F(ErrorTraceTest, filterSource) {
- ASSERT_TRACE2("filterSource [] []",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a list"),
- hintfmt("while evaluating the second argument (the path to filter) passed to builtins.filterSource"));
-
- ASSERT_TRACE2("filterSource [] \"foo\"",
- EvalError,
- hintfmt("string '%s' doesn't represent an absolute path", "foo"),
- hintfmt("while evaluating the second argument (the path to filter) passed to builtins.filterSource"));
-
- ASSERT_TRACE2("filterSource [] ./.",
- TypeError,
- hintfmt("value is %s while a function was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.filterSource"));
-
- // Usupported by store "dummy"
-
- // ASSERT_TRACE2("filterSource (_: 1) ./.",
- // TypeError,
- // hintfmt("attempt to call something which is not a function but %s", "an integer"),
- // hintfmt("while adding path '/home/layus/projects/nix'"));
-
- // ASSERT_TRACE2("filterSource (_: _: 1) ./.",
- // TypeError,
- // hintfmt("value is %s while a Boolean was expected", "an integer"),
- // hintfmt("while evaluating the return value of the path filter function"));
-
- }
-
-
- TEST_F(ErrorTraceTest, path) {
- }
-
-
- TEST_F(ErrorTraceTest, attrNames) {
- ASSERT_TRACE2("attrNames []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the argument passed to builtins.attrNames"));
-
- }
-
-
- TEST_F(ErrorTraceTest, attrValues) {
- ASSERT_TRACE2("attrValues []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the argument passed to builtins.attrValues"));
-
- }
-
-
- TEST_F(ErrorTraceTest, getAttr) {
- ASSERT_TRACE2("getAttr [] []",
- TypeError,
- hintfmt("value is %s while a string was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.getAttr"));
-
- ASSERT_TRACE2("getAttr \"foo\" []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the second argument passed to builtins.getAttr"));
-
- ASSERT_TRACE2("getAttr \"foo\" {}",
- TypeError,
- hintfmt("attribute '%s' missing", "foo"),
- hintfmt("in the attribute set under consideration"));
-
- }
-
-
- TEST_F(ErrorTraceTest, unsafeGetAttrPos) {
- }
-
-
- TEST_F(ErrorTraceTest, hasAttr) {
- ASSERT_TRACE2("hasAttr [] []",
- TypeError,
- hintfmt("value is %s while a string was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.hasAttr"));
-
- ASSERT_TRACE2("hasAttr \"foo\" []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the second argument passed to builtins.hasAttr"));
-
- }
-
-
- TEST_F(ErrorTraceTest, isAttrs) {
- }
-
-
- TEST_F(ErrorTraceTest, removeAttrs) {
- ASSERT_TRACE2("removeAttrs \"\" \"\"",
- TypeError,
- hintfmt("value is %s while a set was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.removeAttrs"));
-
- ASSERT_TRACE2("removeAttrs \"\" [ 1 ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.removeAttrs"));
-
- ASSERT_TRACE2("removeAttrs \"\" [ \"1\" ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.removeAttrs"));
-
- }
-
-
- TEST_F(ErrorTraceTest, listToAttrs) {
- ASSERT_TRACE2("listToAttrs 1",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the argument passed to builtins.listToAttrs"));
-
- ASSERT_TRACE2("listToAttrs [ 1 ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "an integer"),
- hintfmt("while evaluating an element of the list passed to builtins.listToAttrs"));
-
- ASSERT_TRACE2("listToAttrs [ {} ]",
- TypeError,
- hintfmt("attribute '%s' missing", "name"),
- hintfmt("in a {name=...; value=...;} pair"));
-
- ASSERT_TRACE2("listToAttrs [ { name = 1; } ]",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the `name` attribute of an element of the list passed to builtins.listToAttrs"));
-
- ASSERT_TRACE2("listToAttrs [ { name = \"foo\"; } ]",
- TypeError,
- hintfmt("attribute '%s' missing", "value"),
- hintfmt("in a {name=...; value=...;} pair"));
-
- }
-
-
- TEST_F(ErrorTraceTest, intersectAttrs) {
- ASSERT_TRACE2("intersectAttrs [] []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.intersectAttrs"));
-
- ASSERT_TRACE2("intersectAttrs {} []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the second argument passed to builtins.intersectAttrs"));
-
- }
-
-
- TEST_F(ErrorTraceTest, catAttrs) {
- ASSERT_TRACE2("catAttrs [] {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.catAttrs"));
-
- ASSERT_TRACE2("catAttrs \"foo\" {}",
- TypeError,
- hintfmt("value is %s while a list was expected", "a set"),
- hintfmt("while evaluating the second argument passed to builtins.catAttrs"));
-
- ASSERT_TRACE2("catAttrs \"foo\" [ 1 ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "an integer"),
- hintfmt("while evaluating an element in the list passed as second argument to builtins.catAttrs"));
-
- ASSERT_TRACE2("catAttrs \"foo\" [ { foo = 1; } 1 { bar = 5;} ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "an integer"),
- hintfmt("while evaluating an element in the list passed as second argument to builtins.catAttrs"));
-
- }
-
-
- TEST_F(ErrorTraceTest, functionArgs) {
- ASSERT_TRACE1("functionArgs {}",
- TypeError,
- hintfmt("'functionArgs' requires a function"));
-
- }
-
-
- TEST_F(ErrorTraceTest, mapAttrs) {
- ASSERT_TRACE2("mapAttrs [] []",
- TypeError,
- hintfmt("value is %s while a set was expected", "a list"),
- hintfmt("while evaluating the second argument passed to builtins.mapAttrs"));
-
- // XXX: defered
- // ASSERT_TRACE2("mapAttrs \"\" { foo.bar = 1; }",
- // TypeError,
- // hintfmt("attempt to call something which is not a function but %s", "a string"),
- // hintfmt("while evaluating the attribute 'foo'"));
-
- // ASSERT_TRACE2("mapAttrs (x: x + \"1\") { foo.bar = 1; }",
- // TypeError,
- // hintfmt("attempt to call something which is not a function but %s", "a string"),
- // hintfmt("while evaluating the attribute 'foo'"));
-
- // ASSERT_TRACE2("mapAttrs (x: y: x + 1) { foo.bar = 1; }",
- // TypeError,
- // hintfmt("cannot coerce %s to a string", "an integer"),
- // hintfmt("while evaluating a path segment"));
-
- }
-
-
- TEST_F(ErrorTraceTest, zipAttrsWith) {
- ASSERT_TRACE2("zipAttrsWith [] [ 1 ]",
- TypeError,
- hintfmt("value is %s while a function was expected", "a list"),
- hintfmt("while evaluating the first argument passed to builtins.zipAttrsWith"));
-
- ASSERT_TRACE2("zipAttrsWith (_: 1) [ 1 ]",
- TypeError,
- hintfmt("value is %s while a set was expected", "an integer"),
- hintfmt("while evaluating a value of the list passed as second argument to builtins.zipAttrsWith"));
-
- // XXX: How to properly tell that the fucntion takes two arguments ?
- // The same question also applies to sort, and maybe others.
- // Due to lazyness, we only create a thunk, and it fails later on.
- // ASSERT_TRACE2("zipAttrsWith (_: 1) [ { foo = 1; } ]",
- // TypeError,
- // hintfmt("attempt to call something which is not a function but %s", "an integer"),
- // hintfmt("while evaluating the attribute 'foo'"));
-
- // XXX: Also deferred deeply
- // ASSERT_TRACE2("zipAttrsWith (a: b: a + b) [ { foo = 1; } { foo = 2; } ]",
- // TypeError,
- // hintfmt("cannot coerce %s to a string", "a list"),
- // hintfmt("while evaluating a path segment"));
-
- }
-
-
- TEST_F(ErrorTraceTest, isList) {
- }
-
-
- TEST_F(ErrorTraceTest, elemAt) {
- ASSERT_TRACE2("elemAt \"foo\" (-1)",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.elemAt"));
-
- ASSERT_TRACE1("elemAt [] (-1)",
- Error,
- hintfmt("list index %d is out of bounds", -1));
-
- ASSERT_TRACE1("elemAt [\"foo\"] 3",
- Error,
- hintfmt("list index %d is out of bounds", 3));
-
- }
-
-
- TEST_F(ErrorTraceTest, head) {
- ASSERT_TRACE2("head 1",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.elemAt"));
-
- ASSERT_TRACE1("head []",
- Error,
- hintfmt("list index %d is out of bounds", 0));
-
- }
-
-
- TEST_F(ErrorTraceTest, tail) {
- ASSERT_TRACE2("tail 1",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.tail"));
-
- ASSERT_TRACE1("tail []",
- Error,
- hintfmt("'tail' called on an empty list"));
-
- }
-
-
- TEST_F(ErrorTraceTest, map) {
- ASSERT_TRACE2("map 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.map"));
-
- ASSERT_TRACE2("map 1 [ 1 ]",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.map"));
-
- }
-
-
- TEST_F(ErrorTraceTest, filter) {
- ASSERT_TRACE2("filter 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.filter"));
-
- ASSERT_TRACE2("filter 1 [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.filter"));
-
- ASSERT_TRACE2("filter (_: 5) [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the return value of the filtering function passed to builtins.filter"));
-
- }
-
-
- TEST_F(ErrorTraceTest, elem) {
- ASSERT_TRACE2("elem 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.elem"));
-
- }
-
-
- TEST_F(ErrorTraceTest, concatLists) {
- ASSERT_TRACE2("concatLists 1",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.concatLists"));
-
- ASSERT_TRACE2("concatLists [ 1 ]",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating a value of the list passed to builtins.concatLists"));
-
- ASSERT_TRACE2("concatLists [ [1] \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating a value of the list passed to builtins.concatLists"));
-
- }
-
-
- TEST_F(ErrorTraceTest, length) {
- ASSERT_TRACE2("length 1",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.length"));
-
- ASSERT_TRACE2("length \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the first argument passed to builtins.length"));
-
- }
-
-
- TEST_F(ErrorTraceTest, foldlPrime) {
- ASSERT_TRACE2("foldl' 1 \"foo\" true",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.foldlStrict"));
-
- ASSERT_TRACE2("foldl' (_: 1) \"foo\" true",
- TypeError,
- hintfmt("value is %s while a list was expected", "a Boolean"),
- hintfmt("while evaluating the third argument passed to builtins.foldlStrict"));
-
- ASSERT_TRACE1("foldl' (_: 1) \"foo\" [ true ]",
- TypeError,
- hintfmt("attempt to call something which is not a function but %s", "an integer"));
-
- ASSERT_TRACE2("foldl' (a: b: a && b) \"foo\" [ true ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "a string"),
- hintfmt("in the left operand of the AND (&&) operator"));
-
- }
-
-
- TEST_F(ErrorTraceTest, any) {
- ASSERT_TRACE2("any 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.any"));
-
- ASSERT_TRACE2("any (_: 1) \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.any"));
-
- ASSERT_TRACE2("any (_: 1) [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the return value of the function passed to builtins.any"));
-
- }
-
-
- TEST_F(ErrorTraceTest, all) {
- ASSERT_TRACE2("all 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.all"));
-
- ASSERT_TRACE2("all (_: 1) \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.all"));
-
- ASSERT_TRACE2("all (_: 1) [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the return value of the function passed to builtins.all"));
-
- }
-
-
- TEST_F(ErrorTraceTest, genList) {
- ASSERT_TRACE2("genList 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.genList"));
-
- ASSERT_TRACE2("genList 1 2",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.genList", "an integer"));
-
- // XXX: defered
- // ASSERT_TRACE2("genList (x: x + \"foo\") 2 #TODO",
- // TypeError,
- // hintfmt("cannot add %s to an integer", "a string"),
- // hintfmt("while evaluating anonymous lambda"));
-
- ASSERT_TRACE1("genList false (-3)",
- EvalError,
- hintfmt("cannot create list of size %d", -3));
-
- }
-
-
- TEST_F(ErrorTraceTest, sort) {
- ASSERT_TRACE2("sort 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.sort"));
-
- ASSERT_TRACE2("sort 1 [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.sort"));
-
- ASSERT_TRACE1("sort (_: 1) [ \"foo\" \"bar\" ]",
- TypeError,
- hintfmt("attempt to call something which is not a function but %s", "an integer"));
-
- ASSERT_TRACE2("sort (_: _: 1) [ \"foo\" \"bar\" ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the return value of the sorting function passed to builtins.sort"));
-
- // XXX: Trace too deep, need better asserts
- // ASSERT_TRACE1("sort (a: b: a <= b) [ \"foo\" {} ] # TODO",
- // TypeError,
- // hintfmt("cannot compare %s with %s", "a string", "a set"));
-
- // ASSERT_TRACE1("sort (a: b: a <= b) [ {} {} ] # TODO",
- // TypeError,
- // hintfmt("cannot compare %s with %s; values of that type are incomparable", "a set", "a set"));
-
- }
-
-
- TEST_F(ErrorTraceTest, partition) {
- ASSERT_TRACE2("partition 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.partition"));
-
- ASSERT_TRACE2("partition (_: 1) \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.partition"));
-
- ASSERT_TRACE2("partition (_: 1) [ \"foo\" ]",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the return value of the partition function passed to builtins.partition"));
-
- }
-
-
- TEST_F(ErrorTraceTest, groupBy) {
- ASSERT_TRACE2("groupBy 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.groupBy"));
-
- ASSERT_TRACE2("groupBy (_: 1) \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.groupBy"));
-
- ASSERT_TRACE2("groupBy (x: x) [ \"foo\" \"bar\" 1 ]",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the return value of the grouping function passed to builtins.groupBy"));
-
- }
-
-
- TEST_F(ErrorTraceTest, concatMap) {
- ASSERT_TRACE2("concatMap 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a function was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.concatMap"));
-
- ASSERT_TRACE2("concatMap (x: 1) \"foo\"",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the second argument passed to builtins.concatMap"));
-
- ASSERT_TRACE2("concatMap (x: 1) [ \"foo\" ] # TODO",
- TypeError,
- hintfmt("value is %s while a list was expected", "an integer"),
- hintfmt("while evaluating the return value of the function passed to buitlins.concatMap"));
-
- ASSERT_TRACE2("concatMap (x: \"foo\") [ 1 2 ] # TODO",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the return value of the function passed to buitlins.concatMap"));
-
- }
-
-
- TEST_F(ErrorTraceTest, add) {
- ASSERT_TRACE2("add \"foo\" 1",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the first argument of the addition"));
-
- ASSERT_TRACE2("add 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the second argument of the addition"));
-
- }
-
-
- TEST_F(ErrorTraceTest, sub) {
- ASSERT_TRACE2("sub \"foo\" 1",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the first argument of the subtraction"));
-
- ASSERT_TRACE2("sub 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the second argument of the subtraction"));
-
- }
-
-
- TEST_F(ErrorTraceTest, mul) {
- ASSERT_TRACE2("mul \"foo\" 1",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the first argument of the multiplication"));
-
- ASSERT_TRACE2("mul 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the second argument of the multiplication"));
-
- }
-
-
- TEST_F(ErrorTraceTest, div) {
- ASSERT_TRACE2("div \"foo\" 1 # TODO: an integer was expected -> a number",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the first operand of the division"));
-
- ASSERT_TRACE2("div 1 \"foo\"",
- TypeError,
- hintfmt("value is %s while a float was expected", "a string"),
- hintfmt("while evaluating the second operand of the division"));
-
- ASSERT_TRACE1("div \"foo\" 0",
- EvalError,
- hintfmt("division by zero"));
-
- }
-
-
- TEST_F(ErrorTraceTest, bitAnd) {
- ASSERT_TRACE2("bitAnd 1.1 2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the first argument passed to builtins.bitAnd"));
-
- ASSERT_TRACE2("bitAnd 1 2.2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the second argument passed to builtins.bitAnd"));
-
- }
-
-
- TEST_F(ErrorTraceTest, bitOr) {
- ASSERT_TRACE2("bitOr 1.1 2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the first argument passed to builtins.bitOr"));
-
- ASSERT_TRACE2("bitOr 1 2.2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the second argument passed to builtins.bitOr"));
-
- }
-
-
- TEST_F(ErrorTraceTest, bitXor) {
- ASSERT_TRACE2("bitXor 1.1 2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the first argument passed to builtins.bitXor"));
-
- ASSERT_TRACE2("bitXor 1 2.2",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a float"),
- hintfmt("while evaluating the second argument passed to builtins.bitXor"));
-
- }
-
-
- TEST_F(ErrorTraceTest, lessThan) {
- ASSERT_TRACE1("lessThan 1 \"foo\"",
- EvalError,
- hintfmt("cannot compare %s with %s", "an integer", "a string"));
-
- ASSERT_TRACE1("lessThan {} {}",
- EvalError,
- hintfmt("cannot compare %s with %s; values of that type are incomparable", "a set", "a set"));
-
- ASSERT_TRACE2("lessThan [ 1 2 ] [ \"foo\" ]",
- EvalError,
- hintfmt("cannot compare %s with %s", "an integer", "a string"),
- hintfmt("while comparing two list elements"));
-
- }
-
-
- TEST_F(ErrorTraceTest, toString) {
- ASSERT_TRACE2("toString { a = 1; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the first argument passed to builtins.toString"));
-
- }
-
-
- TEST_F(ErrorTraceTest, substring) {
- ASSERT_TRACE2("substring {} \"foo\" true",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a set"),
- hintfmt("while evaluating the first argument (the start offset) passed to builtins.substring"));
-
- ASSERT_TRACE2("substring 3 \"foo\" true",
- TypeError,
- hintfmt("value is %s while an integer was expected", "a string"),
- hintfmt("while evaluating the second argument (the substring length) passed to builtins.substring"));
-
- ASSERT_TRACE2("substring 0 3 {}",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the third argument (the string) passed to builtins.substring"));
-
- ASSERT_TRACE1("substring (-3) 3 \"sometext\"",
- EvalError,
- hintfmt("negative start position in 'substring'"));
-
- }
-
-
- TEST_F(ErrorTraceTest, stringLength) {
- ASSERT_TRACE2("stringLength {} # TODO: context is missing ???",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the argument passed to builtins.stringLength"));
-
- }
-
-
- TEST_F(ErrorTraceTest, hashString) {
- ASSERT_TRACE2("hashString 1 {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.hashString"));
-
- ASSERT_TRACE1("hashString \"foo\" \"content\"",
- UsageError,
- hintfmt("unknown hash algorithm '%s'", "foo"));
-
- ASSERT_TRACE2("hashString \"sha256\" {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a set"),
- hintfmt("while evaluating the second argument passed to builtins.hashString"));
-
- }
-
-
- TEST_F(ErrorTraceTest, match) {
- ASSERT_TRACE2("match 1 {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.match"));
-
- ASSERT_TRACE2("match \"foo\" {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a set"),
- hintfmt("while evaluating the second argument passed to builtins.match"));
-
- ASSERT_TRACE1("match \"(.*\" \"\"",
- EvalError,
- hintfmt("invalid regular expression '%s'", "(.*"));
-
- }
-
-
- TEST_F(ErrorTraceTest, split) {
- ASSERT_TRACE2("split 1 {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.split"));
-
- ASSERT_TRACE2("split \"foo\" {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a set"),
- hintfmt("while evaluating the second argument passed to builtins.split"));
-
- ASSERT_TRACE1("split \"f(o*o\" \"1foo2\"",
- EvalError,
- hintfmt("invalid regular expression '%s'", "f(o*o"));
-
- }
-
-
- TEST_F(ErrorTraceTest, concatStringsSep) {
- ASSERT_TRACE2("concatStringsSep 1 {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument (the separator string) passed to builtins.concatStringsSep"));
-
- ASSERT_TRACE2("concatStringsSep \"foo\" {}",
- TypeError,
- hintfmt("value is %s while a list was expected", "a set"),
- hintfmt("while evaluating the second argument (the list of strings to concat) passed to builtins.concatStringsSep"));
-
- ASSERT_TRACE2("concatStringsSep \"foo\" [ 1 2 {} ] # TODO: coerce to string is buggy",
- TypeError,
- hintfmt("cannot coerce %s to a string", "an integer"),
- hintfmt("while evaluating one element of the list of strings to concat passed to builtins.concatStringsSep"));
-
- }
-
-
- TEST_F(ErrorTraceTest, parseDrvName) {
- ASSERT_TRACE2("parseDrvName 1",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.parseDrvName"));
-
- }
-
-
- TEST_F(ErrorTraceTest, compareVersions) {
- ASSERT_TRACE2("compareVersions 1 {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.compareVersions"));
-
- ASSERT_TRACE2("compareVersions \"abd\" {}",
- TypeError,
- hintfmt("value is %s while a string was expected", "a set"),
- hintfmt("while evaluating the second argument passed to builtins.compareVersions"));
-
- }
-
-
- TEST_F(ErrorTraceTest, splitVersion) {
- ASSERT_TRACE2("splitVersion 1",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the first argument passed to builtins.splitVersion"));
-
- }
-
-
- TEST_F(ErrorTraceTest, traceVerbose) {
- }
-
-
- /* // Needs different ASSERTs
- TEST_F(ErrorTraceTest, derivationStrict) {
- ASSERT_TRACE2("derivationStrict \"\"",
- TypeError,
- hintfmt("value is %s while a set was expected", "a string"),
- hintfmt("while evaluating the argument passed to builtins.derivationStrict"));
-
- ASSERT_TRACE2("derivationStrict {}",
- TypeError,
- hintfmt("attribute '%s' missing", "name"),
- hintfmt("in the attrset passed as argument to builtins.derivationStrict"));
-
- ASSERT_TRACE2("derivationStrict { name = 1; }",
- TypeError,
- hintfmt("value is %s while a string was expected", "an integer"),
- hintfmt("while evaluating the `name` attribute passed to builtins.derivationStrict"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; }",
- TypeError,
- hintfmt("required attribute 'builder' missing"),
- hintfmt("while evaluating derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __structuredAttrs = 15; }",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the `__structuredAttrs` attribute passed to builtins.derivationStrict"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __ignoreNulls = 15; }",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "an integer"),
- hintfmt("while evaluating the `__ignoreNulls` attribute passed to builtins.derivationStrict"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = 15; }",
- TypeError,
- hintfmt("invalid value '15' for 'outputHashMode' attribute"),
- hintfmt("while evaluating the attribute 'outputHashMode' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = \"custom\"; }",
- TypeError,
- hintfmt("invalid value 'custom' for 'outputHashMode' attribute"),
- hintfmt("while evaluating the attribute 'outputHashMode' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = {}; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the attribute 'system' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = {}; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"drv\"; }",
- TypeError,
- hintfmt("invalid derivation output name 'drv'"),
- hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = []; }",
- TypeError,
- hintfmt("derivation cannot have an empty set of outputs"),
- hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"drv\" ]; }",
- TypeError,
- hintfmt("invalid derivation output name 'drv'"),
- hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"out\" \"out\" ]; }",
- TypeError,
- hintfmt("duplicate derivation output 'out'"),
- hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __contentAddressed = \"true\"; }",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "a string"),
- hintfmt("while evaluating the attribute '__contentAddressed' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "a string"),
- hintfmt("while evaluating the attribute '__impure' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
- TypeError,
- hintfmt("value is %s while a Boolean was expected", "a string"),
- hintfmt("while evaluating the attribute '__impure' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = \"foo\"; }",
- TypeError,
- hintfmt("value is %s while a list was expected", "a string"),
- hintfmt("while evaluating the attribute 'args' of derivation 'foo'"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ {} ]; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating an element of the argument list"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ \"a\" {} ]; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating an element of the argument list"));
-
- ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; FOO = {}; }",
- TypeError,
- hintfmt("cannot coerce %s to a string", "a set"),
- hintfmt("while evaluating the attribute 'FOO' of derivation 'foo'"));
-
- }
- */
-
-} /* namespace nix */
diff --git a/src/libexpr/tests/flakeref.cc b/src/libexpr/tests/flakeref.cc
deleted file mode 100644
index 2b7809b93..000000000
--- a/src/libexpr/tests/flakeref.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <gtest/gtest.h>
-
-#include "flake/flakeref.hh"
-
-namespace nix {
-
-/* ----------- tests for flake/flakeref.hh --------------------------------------------------*/
-
- /* ----------------------------------------------------------------------------
- * to_string
- * --------------------------------------------------------------------------*/
-
- TEST(to_string, doesntReencodeUrl) {
- auto s = "http://localhost:8181/test/+3d.tar.gz";
- auto flakeref = parseFlakeRef(s);
- auto parsed = flakeref.to_string();
- auto expected = "http://localhost:8181/test/%2B3d.tar.gz";
-
- ASSERT_EQ(parsed, expected);
- }
-
-}
diff --git a/src/libexpr/tests/json.cc b/src/libexpr/tests/json.cc
deleted file mode 100644
index 7586bdd9b..000000000
--- a/src/libexpr/tests/json.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "tests/libexpr.hh"
-#include "value-to-json.hh"
-
-namespace nix {
-// Testing the conversion to JSON
-
- class JSONValueTest : public LibExprTest {
- protected:
- std::string getJSONValue(Value& value) {
- std::stringstream ss;
- NixStringContext ps;
- printValueAsJSON(state, true, value, noPos, ss, ps);
- return ss.str();
- }
- };
-
- TEST_F(JSONValueTest, null) {
- Value v;
- v.mkNull();
- ASSERT_EQ(getJSONValue(v), "null");
- }
-
- TEST_F(JSONValueTest, BoolFalse) {
- Value v;
- v.mkBool(false);
- ASSERT_EQ(getJSONValue(v),"false");
- }
-
- TEST_F(JSONValueTest, BoolTrue) {
- Value v;
- v.mkBool(true);
- ASSERT_EQ(getJSONValue(v), "true");
- }
-
- TEST_F(JSONValueTest, IntPositive) {
- Value v;
- v.mkInt(100);
- ASSERT_EQ(getJSONValue(v), "100");
- }
-
- TEST_F(JSONValueTest, IntNegative) {
- Value v;
- v.mkInt(-100);
- ASSERT_EQ(getJSONValue(v), "-100");
- }
-
- TEST_F(JSONValueTest, String) {
- Value v;
- v.mkString("test");
- ASSERT_EQ(getJSONValue(v), "\"test\"");
- }
-
- TEST_F(JSONValueTest, StringQuotes) {
- Value v;
-
- v.mkString("test\"");
- ASSERT_EQ(getJSONValue(v), "\"test\\\"\"");
- }
-
- // The dummy store doesn't support writing files. Fails with this exception message:
- // C++ exception with description "error: operation 'addToStoreFromDump' is
- // not supported by store 'dummy'" thrown in the test body.
- TEST_F(JSONValueTest, DISABLED_Path) {
- Value v;
- v.mkPath("test");
- ASSERT_EQ(getJSONValue(v), "\"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x\"");
- }
-} /* namespace nix */
diff --git a/src/libexpr/tests/libexpr.hh b/src/libexpr/tests/libexpr.hh
deleted file mode 100644
index b8e65aafe..000000000
--- a/src/libexpr/tests/libexpr.hh
+++ /dev/null
@@ -1,140 +0,0 @@
-#pragma once
-///@file
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include "value.hh"
-#include "nixexpr.hh"
-#include "eval.hh"
-#include "eval-inline.hh"
-#include "store-api.hh"
-
-#include "tests/libstore.hh"
-
-namespace nix {
- class LibExprTest : public LibStoreTest {
- public:
- static void SetUpTestSuite() {
- LibStoreTest::SetUpTestSuite();
- initGC();
- }
-
- protected:
- LibExprTest()
- : LibStoreTest()
- , state({}, store)
- {
- }
- Value eval(std::string input, bool forceValue = true) {
- Value v;
- Expr * e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
- assert(e);
- state.eval(e, v);
- if (forceValue)
- state.forceValue(v, noPos);
- return v;
- }
-
- Symbol createSymbol(const char * value) {
- return state.symbols.create(value);
- }
-
- EvalState state;
- };
-
- MATCHER(IsListType, "") {
- return arg != nList;
- }
-
- MATCHER(IsList, "") {
- return arg.type() == nList;
- }
-
- MATCHER(IsString, "") {
- return arg.type() == nString;
- }
-
- MATCHER(IsNull, "") {
- return arg.type() == nNull;
- }
-
- MATCHER(IsThunk, "") {
- return arg.type() == nThunk;
- }
-
- MATCHER(IsAttrs, "") {
- return arg.type() == nAttrs;
- }
-
- MATCHER_P(IsStringEq, s, fmt("The string is equal to \"%1%\"", s)) {
- if (arg.type() != nString) {
- return false;
- }
- return std::string_view(arg.string.s) == s;
- }
-
- MATCHER_P(IsIntEq, v, fmt("The string is equal to \"%1%\"", v)) {
- if (arg.type() != nInt) {
- return false;
- }
- return arg.integer == v;
- }
-
- MATCHER_P(IsFloatEq, v, fmt("The float is equal to \"%1%\"", v)) {
- if (arg.type() != nFloat) {
- return false;
- }
- return arg.fpoint == v;
- }
-
- MATCHER(IsTrue, "") {
- if (arg.type() != nBool) {
- return false;
- }
- return arg.boolean == true;
- }
-
- MATCHER(IsFalse, "") {
- if (arg.type() != nBool) {
- return false;
- }
- return arg.boolean == false;
- }
-
- MATCHER_P(IsPathEq, p, fmt("Is a path equal to \"%1%\"", p)) {
- if (arg.type() != nPath) {
- *result_listener << "Expected a path got " << arg.type();
- return false;
- } else if (std::string_view(arg.string.s) != p) {
- *result_listener << "Expected a path that equals \"" << p << "\" but got: " << arg.string.s;
- return false;
- }
- return true;
- }
-
-
- MATCHER_P(IsListOfSize, n, fmt("Is a list of size [%1%]", n)) {
- if (arg.type() != nList) {
- *result_listener << "Expected list got " << arg.type();
- return false;
- } else if (arg.listSize() != (size_t)n) {
- *result_listener << "Expected as list of size " << n << " got " << arg.listSize();
- return false;
- }
- return true;
- }
-
- MATCHER_P(IsAttrsOfSize, n, fmt("Is a set of size [%1%]", n)) {
- if (arg.type() != nAttrs) {
- *result_listener << "Expected set got " << arg.type();
- return false;
- } else if (arg.attrs->size() != (size_t)n) {
- *result_listener << "Expected a set with " << n << " attributes but got " << arg.attrs->size();
- return false;
- }
- return true;
- }
-
-
-} /* namespace nix */
diff --git a/src/libexpr/tests/local.mk b/src/libexpr/tests/local.mk
deleted file mode 100644
index c56848a14..000000000
--- a/src/libexpr/tests/local.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-check: libexpr-tests_RUN
-
-programs += libexpr-tests
-
-libexpr-tests_NAME := libnixexpr-tests
-
-libexpr-tests_DIR := $(d)
-
-libexpr-tests_INSTALL_DIR :=
-
-libexpr-tests_SOURCES := \
- $(wildcard $(d)/*.cc) \
- $(wildcard $(d)/value/*.cc)
-
-libexpr-tests_CXXFLAGS += -I src/libexpr -I src/libutil -I src/libstore -I src/libexpr/tests -I src/libfetchers
-
-libexpr-tests_LIBS = libstore-tests libutils-tests libexpr libutil libstore libfetchers
-
-libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock
diff --git a/src/libexpr/tests/primops.cc b/src/libexpr/tests/primops.cc
deleted file mode 100644
index ce3b5d11f..000000000
--- a/src/libexpr/tests/primops.cc
+++ /dev/null
@@ -1,832 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "tests/libexpr.hh"
-
-namespace nix {
- class CaptureLogger : public Logger
- {
- std::ostringstream oss;
-
- public:
- CaptureLogger() {}
-
- std::string get() const {
- return oss.str();
- }
-
- void log(Verbosity lvl, std::string_view s) override {
- oss << s << std::endl;
- }
-
- void logEI(const ErrorInfo & ei) override {
- showErrorInfo(oss, ei, loggerSettings.showTrace.get());
- }
- };
-
- class CaptureLogging {
- Logger * oldLogger;
- std::unique_ptr<CaptureLogger> tempLogger;
- public:
- CaptureLogging() : tempLogger(std::make_unique<CaptureLogger>()) {
- oldLogger = logger;
- logger = tempLogger.get();
- }
-
- ~CaptureLogging() {
- logger = oldLogger;
- }
-
- std::string get() const {
- return tempLogger->get();
- }
- };
-
-
- // Testing eval of PrimOp's
- class PrimOpTest : public LibExprTest {};
-
-
- TEST_F(PrimOpTest, throw) {
- ASSERT_THROW(eval("throw \"foo\""), ThrownError);
- }
-
- TEST_F(PrimOpTest, abort) {
- ASSERT_THROW(eval("abort \"abort\""), Abort);
- }
-
- TEST_F(PrimOpTest, ceil) {
- auto v = eval("builtins.ceil 1.9");
- ASSERT_THAT(v, IsIntEq(2));
- }
-
- TEST_F(PrimOpTest, floor) {
- auto v = eval("builtins.floor 1.9");
- ASSERT_THAT(v, IsIntEq(1));
- }
-
- TEST_F(PrimOpTest, tryEvalFailure) {
- auto v = eval("builtins.tryEval (throw \"\")");
- ASSERT_THAT(v, IsAttrsOfSize(2));
- auto s = createSymbol("success");
- auto p = v.attrs->get(s);
- ASSERT_NE(p, nullptr);
- ASSERT_THAT(*p->value, IsFalse());
- }
-
- TEST_F(PrimOpTest, tryEvalSuccess) {
- auto v = eval("builtins.tryEval 123");
- ASSERT_THAT(v, IsAttrs());
- auto s = createSymbol("success");
- auto p = v.attrs->get(s);
- ASSERT_NE(p, nullptr);
- ASSERT_THAT(*p->value, IsTrue());
- s = createSymbol("value");
- p = v.attrs->get(s);
- ASSERT_NE(p, nullptr);
- ASSERT_THAT(*p->value, IsIntEq(123));
- }
-
- TEST_F(PrimOpTest, getEnv) {
- setenv("_NIX_UNIT_TEST_ENV_VALUE", "test value", 1);
- auto v = eval("builtins.getEnv \"_NIX_UNIT_TEST_ENV_VALUE\"");
- ASSERT_THAT(v, IsStringEq("test value"));
- }
-
- TEST_F(PrimOpTest, seq) {
- ASSERT_THROW(eval("let x = throw \"test\"; in builtins.seq x { }"), ThrownError);
- }
-
- TEST_F(PrimOpTest, seqNotDeep) {
- auto v = eval("let x = { z = throw \"test\"; }; in builtins.seq x { }");
- ASSERT_THAT(v, IsAttrs());
- }
-
- TEST_F(PrimOpTest, deepSeq) {
- ASSERT_THROW(eval("let x = { z = throw \"test\"; }; in builtins.deepSeq x { }"), ThrownError);
- }
-
- TEST_F(PrimOpTest, trace) {
- CaptureLogging l;
- auto v = eval("builtins.trace \"test string 123\" 123");
- ASSERT_THAT(v, IsIntEq(123));
- auto text = l.get();
- ASSERT_NE(text.find("test string 123"), std::string::npos);
- }
-
- TEST_F(PrimOpTest, placeholder) {
- auto v = eval("builtins.placeholder \"out\"");
- ASSERT_THAT(v, IsStringEq("/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"));
- }
-
- TEST_F(PrimOpTest, baseNameOf) {
- auto v = eval("builtins.baseNameOf /some/path");
- ASSERT_THAT(v, IsStringEq("path"));
- }
-
- TEST_F(PrimOpTest, dirOf) {
- auto v = eval("builtins.dirOf /some/path");
- ASSERT_THAT(v, IsPathEq("/some"));
- }
-
- TEST_F(PrimOpTest, attrValues) {
- auto v = eval("builtins.attrValues { x = \"foo\"; a = 1; }");
- ASSERT_THAT(v, IsListOfSize(2));
- ASSERT_THAT(*v.listElems()[0], IsIntEq(1));
- ASSERT_THAT(*v.listElems()[1], IsStringEq("foo"));
- }
-
- TEST_F(PrimOpTest, getAttr) {
- auto v = eval("builtins.getAttr \"x\" { x = \"foo\"; }");
- ASSERT_THAT(v, IsStringEq("foo"));
- }
-
- TEST_F(PrimOpTest, getAttrNotFound) {
- // FIXME: TypeError is really bad here, also the error wording is worse
- // than on Nix <=2.3
- ASSERT_THROW(eval("builtins.getAttr \"y\" { }"), TypeError);
- }
-
- TEST_F(PrimOpTest, unsafeGetAttrPos) {
- // The `y` attribute is at position
- const char* expr = "builtins.unsafeGetAttrPos \"y\" { y = \"x\"; }";
- auto v = eval(expr);
- ASSERT_THAT(v, IsNull());
- }
-
- TEST_F(PrimOpTest, hasAttr) {
- auto v = eval("builtins.hasAttr \"x\" { x = 1; }");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, hasAttrNotFound) {
- auto v = eval("builtins.hasAttr \"x\" { }");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, isAttrs) {
- auto v = eval("builtins.isAttrs {}");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, isAttrsFalse) {
- auto v = eval("builtins.isAttrs null");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, removeAttrs) {
- auto v = eval("builtins.removeAttrs { x = 1; } [\"x\"]");
- ASSERT_THAT(v, IsAttrsOfSize(0));
- }
-
- TEST_F(PrimOpTest, removeAttrsRetains) {
- auto v = eval("builtins.removeAttrs { x = 1; y = 2; } [\"x\"]");
- ASSERT_THAT(v, IsAttrsOfSize(1));
- ASSERT_NE(v.attrs->find(createSymbol("y")), nullptr);
- }
-
- TEST_F(PrimOpTest, listToAttrsEmptyList) {
- auto v = eval("builtins.listToAttrs []");
- ASSERT_THAT(v, IsAttrsOfSize(0));
- ASSERT_EQ(v.type(), nAttrs);
- ASSERT_EQ(v.attrs->size(), 0);
- }
-
- TEST_F(PrimOpTest, listToAttrsNotFieldName) {
- ASSERT_THROW(eval("builtins.listToAttrs [{}]"), Error);
- }
-
- TEST_F(PrimOpTest, listToAttrs) {
- auto v = eval("builtins.listToAttrs [ { name = \"key\"; value = 123; } ]");
- ASSERT_THAT(v, IsAttrsOfSize(1));
- auto key = v.attrs->find(createSymbol("key"));
- ASSERT_NE(key, nullptr);
- ASSERT_THAT(*key->value, IsIntEq(123));
- }
-
- TEST_F(PrimOpTest, intersectAttrs) {
- auto v = eval("builtins.intersectAttrs { a = 1; b = 2; } { b = 3; c = 4; }");
- ASSERT_THAT(v, IsAttrsOfSize(1));
- auto b = v.attrs->find(createSymbol("b"));
- ASSERT_NE(b, nullptr);
- ASSERT_THAT(*b->value, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, catAttrs) {
- auto v = eval("builtins.catAttrs \"a\" [{a = 1;} {b = 0;} {a = 2;}]");
- ASSERT_THAT(v, IsListOfSize(2));
- ASSERT_THAT(*v.listElems()[0], IsIntEq(1));
- ASSERT_THAT(*v.listElems()[1], IsIntEq(2));
- }
-
- TEST_F(PrimOpTest, functionArgs) {
- auto v = eval("builtins.functionArgs ({ x, y ? 123}: 1)");
- ASSERT_THAT(v, IsAttrsOfSize(2));
-
- auto x = v.attrs->find(createSymbol("x"));
- ASSERT_NE(x, nullptr);
- ASSERT_THAT(*x->value, IsFalse());
-
- auto y = v.attrs->find(createSymbol("y"));
- ASSERT_NE(y, nullptr);
- ASSERT_THAT(*y->value, IsTrue());
- }
-
- TEST_F(PrimOpTest, mapAttrs) {
- auto v = eval("builtins.mapAttrs (name: value: value * 10) { a = 1; b = 2; }");
- ASSERT_THAT(v, IsAttrsOfSize(2));
-
- auto a = v.attrs->find(createSymbol("a"));
- ASSERT_NE(a, nullptr);
- ASSERT_THAT(*a->value, IsThunk());
- state.forceValue(*a->value, noPos);
- ASSERT_THAT(*a->value, IsIntEq(10));
-
- auto b = v.attrs->find(createSymbol("b"));
- ASSERT_NE(b, nullptr);
- ASSERT_THAT(*b->value, IsThunk());
- state.forceValue(*b->value, noPos);
- ASSERT_THAT(*b->value, IsIntEq(20));
- }
-
- TEST_F(PrimOpTest, isList) {
- auto v = eval("builtins.isList []");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, isListFalse) {
- auto v = eval("builtins.isList null");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, elemtAt) {
- auto v = eval("builtins.elemAt [0 1 2 3] 3");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, elemtAtOutOfBounds) {
- ASSERT_THROW(eval("builtins.elemAt [0 1 2 3] 5"), Error);
- }
-
- TEST_F(PrimOpTest, head) {
- auto v = eval("builtins.head [ 3 2 1 0 ]");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, headEmpty) {
- ASSERT_THROW(eval("builtins.head [ ]"), Error);
- }
-
- TEST_F(PrimOpTest, headWrongType) {
- ASSERT_THROW(eval("builtins.head { }"), Error);
- }
-
- TEST_F(PrimOpTest, tail) {
- auto v = eval("builtins.tail [ 3 2 1 0 ]");
- ASSERT_THAT(v, IsListOfSize(3));
- for (const auto [n, elem] : enumerate(v.listItems()))
- ASSERT_THAT(*elem, IsIntEq(2 - static_cast<int>(n)));
- }
-
- TEST_F(PrimOpTest, tailEmpty) {
- ASSERT_THROW(eval("builtins.tail []"), Error);
- }
-
- TEST_F(PrimOpTest, map) {
- auto v = eval("map (x: \"foo\" + x) [ \"bar\" \"bla\" \"abc\" ]");
- ASSERT_THAT(v, IsListOfSize(3));
- auto elem = v.listElems()[0];
- ASSERT_THAT(*elem, IsThunk());
- state.forceValue(*elem, noPos);
- ASSERT_THAT(*elem, IsStringEq("foobar"));
-
- elem = v.listElems()[1];
- ASSERT_THAT(*elem, IsThunk());
- state.forceValue(*elem, noPos);
- ASSERT_THAT(*elem, IsStringEq("foobla"));
-
- elem = v.listElems()[2];
- ASSERT_THAT(*elem, IsThunk());
- state.forceValue(*elem, noPos);
- ASSERT_THAT(*elem, IsStringEq("fooabc"));
- }
-
- TEST_F(PrimOpTest, filter) {
- auto v = eval("builtins.filter (x: x == 2) [ 3 2 3 2 3 2 ]");
- ASSERT_THAT(v, IsListOfSize(3));
- for (const auto elem : v.listItems())
- ASSERT_THAT(*elem, IsIntEq(2));
- }
-
- TEST_F(PrimOpTest, elemTrue) {
- auto v = eval("builtins.elem 3 [ 1 2 3 4 5 ]");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, elemFalse) {
- auto v = eval("builtins.elem 6 [ 1 2 3 4 5 ]");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, concatLists) {
- auto v = eval("builtins.concatLists [[1 2] [3 4]]");
- ASSERT_THAT(v, IsListOfSize(4));
- for (const auto [i, elem] : enumerate(v.listItems()))
- ASSERT_THAT(*elem, IsIntEq(static_cast<int>(i)+1));
- }
-
- TEST_F(PrimOpTest, length) {
- auto v = eval("builtins.length [ 1 2 3 ]");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, foldStrict) {
- auto v = eval("builtins.foldl' (a: b: a + b) 0 [1 2 3]");
- ASSERT_THAT(v, IsIntEq(6));
- }
-
- TEST_F(PrimOpTest, anyTrue) {
- auto v = eval("builtins.any (x: x == 2) [ 1 2 3 ]");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, anyFalse) {
- auto v = eval("builtins.any (x: x == 5) [ 1 2 3 ]");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, allTrue) {
- auto v = eval("builtins.all (x: x > 0) [ 1 2 3 ]");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, allFalse) {
- auto v = eval("builtins.all (x: x <= 0) [ 1 2 3 ]");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, genList) {
- auto v = eval("builtins.genList (x: x + 1) 3");
- ASSERT_EQ(v.type(), nList);
- ASSERT_EQ(v.listSize(), 3);
- for (const auto [i, elem] : enumerate(v.listItems())) {
- ASSERT_THAT(*elem, IsThunk());
- state.forceValue(*elem, noPos);
- ASSERT_THAT(*elem, IsIntEq(static_cast<int>(i)+1));
- }
- }
-
- TEST_F(PrimOpTest, sortLessThan) {
- auto v = eval("builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]");
- ASSERT_EQ(v.type(), nList);
- ASSERT_EQ(v.listSize(), 6);
-
- const std::vector<int> numbers = { 42, 77, 147, 249, 483, 526 };
- for (const auto [n, elem] : enumerate(v.listItems()))
- ASSERT_THAT(*elem, IsIntEq(numbers[n]));
- }
-
- TEST_F(PrimOpTest, partition) {
- auto v = eval("builtins.partition (x: x > 10) [1 23 9 3 42]");
- ASSERT_THAT(v, IsAttrsOfSize(2));
-
- auto right = v.attrs->get(createSymbol("right"));
- ASSERT_NE(right, nullptr);
- ASSERT_THAT(*right->value, IsListOfSize(2));
- ASSERT_THAT(*right->value->listElems()[0], IsIntEq(23));
- ASSERT_THAT(*right->value->listElems()[1], IsIntEq(42));
-
- auto wrong = v.attrs->get(createSymbol("wrong"));
- ASSERT_NE(wrong, nullptr);
- ASSERT_EQ(wrong->value->type(), nList);
- ASSERT_EQ(wrong->value->listSize(), 3);
- ASSERT_THAT(*wrong->value, IsListOfSize(3));
- ASSERT_THAT(*wrong->value->listElems()[0], IsIntEq(1));
- ASSERT_THAT(*wrong->value->listElems()[1], IsIntEq(9));
- ASSERT_THAT(*wrong->value->listElems()[2], IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, concatMap) {
- auto v = eval("builtins.concatMap (x: x ++ [0]) [ [1 2] [3 4] ]");
- ASSERT_EQ(v.type(), nList);
- ASSERT_EQ(v.listSize(), 6);
-
- const std::vector<int> numbers = { 1, 2, 0, 3, 4, 0 };
- for (const auto [n, elem] : enumerate(v.listItems()))
- ASSERT_THAT(*elem, IsIntEq(numbers[n]));
- }
-
- TEST_F(PrimOpTest, addInt) {
- auto v = eval("builtins.add 3 5");
- ASSERT_THAT(v, IsIntEq(8));
- }
-
- TEST_F(PrimOpTest, addFloat) {
- auto v = eval("builtins.add 3.0 5.0");
- ASSERT_THAT(v, IsFloatEq(8.0));
- }
-
- TEST_F(PrimOpTest, addFloatToInt) {
- auto v = eval("builtins.add 3.0 5");
- ASSERT_THAT(v, IsFloatEq(8.0));
-
- v = eval("builtins.add 3 5.0");
- ASSERT_THAT(v, IsFloatEq(8.0));
- }
-
- TEST_F(PrimOpTest, subInt) {
- auto v = eval("builtins.sub 5 2");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, subFloat) {
- auto v = eval("builtins.sub 5.0 2.0");
- ASSERT_THAT(v, IsFloatEq(3.0));
- }
-
- TEST_F(PrimOpTest, subFloatFromInt) {
- auto v = eval("builtins.sub 5.0 2");
- ASSERT_THAT(v, IsFloatEq(3.0));
-
- v = eval("builtins.sub 4 2.0");
- ASSERT_THAT(v, IsFloatEq(2.0));
- }
-
- TEST_F(PrimOpTest, mulInt) {
- auto v = eval("builtins.mul 3 5");
- ASSERT_THAT(v, IsIntEq(15));
- }
-
- TEST_F(PrimOpTest, mulFloat) {
- auto v = eval("builtins.mul 3.0 5.0");
- ASSERT_THAT(v, IsFloatEq(15.0));
- }
-
- TEST_F(PrimOpTest, mulFloatMixed) {
- auto v = eval("builtins.mul 3 5.0");
- ASSERT_THAT(v, IsFloatEq(15.0));
-
- v = eval("builtins.mul 2.0 5");
- ASSERT_THAT(v, IsFloatEq(10.0));
- }
-
- TEST_F(PrimOpTest, divInt) {
- auto v = eval("builtins.div 5 (-1)");
- ASSERT_THAT(v, IsIntEq(-5));
- }
-
- TEST_F(PrimOpTest, divIntZero) {
- ASSERT_THROW(eval("builtins.div 5 0"), EvalError);
- }
-
- TEST_F(PrimOpTest, divFloat) {
- auto v = eval("builtins.div 5.0 (-1)");
- ASSERT_THAT(v, IsFloatEq(-5.0));
- }
-
- TEST_F(PrimOpTest, divFloatZero) {
- ASSERT_THROW(eval("builtins.div 5.0 0.0"), EvalError);
- }
-
- TEST_F(PrimOpTest, bitOr) {
- auto v = eval("builtins.bitOr 1 2");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(PrimOpTest, bitXor) {
- auto v = eval("builtins.bitXor 3 2");
- ASSERT_THAT(v, IsIntEq(1));
- }
-
- TEST_F(PrimOpTest, lessThanFalse) {
- auto v = eval("builtins.lessThan 3 1");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(PrimOpTest, lessThanTrue) {
- auto v = eval("builtins.lessThan 1 3");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(PrimOpTest, toStringAttrsThrows) {
- ASSERT_THROW(eval("builtins.toString {}"), EvalError);
- }
-
- TEST_F(PrimOpTest, toStringLambdaThrows) {
- ASSERT_THROW(eval("builtins.toString (x: x)"), EvalError);
- }
-
- class ToStringPrimOpTest :
- public PrimOpTest,
- public testing::WithParamInterface<std::tuple<std::string, std::string_view>>
- {};
-
- TEST_P(ToStringPrimOpTest, toString) {
- const auto [input, output] = GetParam();
- auto v = eval(input);
- ASSERT_THAT(v, IsStringEq(output));
- }
-
-#define CASE(input, output) (std::make_tuple(std::string_view("builtins.toString " input), std::string_view(output)))
- INSTANTIATE_TEST_SUITE_P(
- toString,
- ToStringPrimOpTest,
- testing::Values(
- CASE(R"("foo")", "foo"),
- CASE(R"(1)", "1"),
- CASE(R"([1 2 3])", "1 2 3"),
- CASE(R"(.123)", "0.123000"),
- CASE(R"(true)", "1"),
- CASE(R"(false)", ""),
- CASE(R"(null)", ""),
- CASE(R"({ v = "bar"; __toString = self: self.v; })", "bar"),
- CASE(R"({ v = "bar"; __toString = self: self.v; outPath = "foo"; })", "bar"),
- CASE(R"({ outPath = "foo"; })", "foo"),
- CASE(R"(./test)", "/test")
- )
- );
-#undef CASE
-
- TEST_F(PrimOpTest, substring){
- auto v = eval("builtins.substring 0 3 \"nixos\"");
- ASSERT_THAT(v, IsStringEq("nix"));
- }
-
- TEST_F(PrimOpTest, substringSmallerString){
- auto v = eval("builtins.substring 0 3 \"n\"");
- ASSERT_THAT(v, IsStringEq("n"));
- }
-
- TEST_F(PrimOpTest, substringEmptyString){
- auto v = eval("builtins.substring 1 3 \"\"");
- ASSERT_THAT(v, IsStringEq(""));
- }
-
- TEST_F(PrimOpTest, stringLength) {
- auto v = eval("builtins.stringLength \"123\"");
- ASSERT_THAT(v, IsIntEq(3));
- }
- TEST_F(PrimOpTest, hashStringMd5) {
- auto v = eval("builtins.hashString \"md5\" \"asdf\"");
- ASSERT_THAT(v, IsStringEq("912ec803b2ce49e4a541068d495ab570"));
- }
-
- TEST_F(PrimOpTest, hashStringSha1) {
- auto v = eval("builtins.hashString \"sha1\" \"asdf\"");
- ASSERT_THAT(v, IsStringEq("3da541559918a808c2402bba5012f6c60b27661c"));
- }
-
- TEST_F(PrimOpTest, hashStringSha256) {
- auto v = eval("builtins.hashString \"sha256\" \"asdf\"");
- ASSERT_THAT(v, IsStringEq("f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b"));
- }
-
- TEST_F(PrimOpTest, hashStringSha512) {
- auto v = eval("builtins.hashString \"sha512\" \"asdf\"");
- ASSERT_THAT(v, IsStringEq("401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429080fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1"));
- }
-
- TEST_F(PrimOpTest, hashStringInvalidHashType) {
- ASSERT_THROW(eval("builtins.hashString \"foobar\" \"asdf\""), Error);
- }
-
- TEST_F(PrimOpTest, nixPath) {
- auto v = eval("builtins.nixPath");
- ASSERT_EQ(v.type(), nList);
- // We can't test much more as currently the EvalSettings are a global
- // that we can't easily swap / replace
- }
-
- TEST_F(PrimOpTest, langVersion) {
- auto v = eval("builtins.langVersion");
- ASSERT_EQ(v.type(), nInt);
- }
-
- TEST_F(PrimOpTest, storeDir) {
- auto v = eval("builtins.storeDir");
- ASSERT_THAT(v, IsStringEq(settings.nixStore));
- }
-
- TEST_F(PrimOpTest, nixVersion) {
- auto v = eval("builtins.nixVersion");
- ASSERT_THAT(v, IsStringEq(nixVersion));
- }
-
- TEST_F(PrimOpTest, currentSystem) {
- auto v = eval("builtins.currentSystem");
- ASSERT_THAT(v, IsStringEq(settings.thisSystem.get()));
- }
-
- TEST_F(PrimOpTest, derivation) {
- auto v = eval("derivation");
- ASSERT_EQ(v.type(), nFunction);
- ASSERT_TRUE(v.isLambda());
- ASSERT_NE(v.lambda.fun, nullptr);
- ASSERT_TRUE(v.lambda.fun->hasFormals());
- }
-
- TEST_F(PrimOpTest, currentTime) {
- auto v = eval("builtins.currentTime");
- ASSERT_EQ(v.type(), nInt);
- ASSERT_TRUE(v.integer > 0);
- }
-
- TEST_F(PrimOpTest, splitVersion) {
- auto v = eval("builtins.splitVersion \"1.2.3git\"");
- ASSERT_THAT(v, IsListOfSize(4));
-
- const std::vector<std::string_view> strings = { "1", "2", "3", "git" };
- for (const auto [n, p] : enumerate(v.listItems()))
- ASSERT_THAT(*p, IsStringEq(strings[n]));
- }
-
- class CompareVersionsPrimOpTest :
- public PrimOpTest,
- public testing::WithParamInterface<std::tuple<std::string, const int>>
- {};
-
- TEST_P(CompareVersionsPrimOpTest, compareVersions) {
- auto [expression, expectation] = GetParam();
- auto v = eval(expression);
- ASSERT_THAT(v, IsIntEq(expectation));
- }
-
-#define CASE(a, b, expected) (std::make_tuple("builtins.compareVersions \"" #a "\" \"" #b "\"", expected))
- INSTANTIATE_TEST_SUITE_P(
- compareVersions,
- CompareVersionsPrimOpTest,
- testing::Values(
- // The first two are weird cases. Intuition tells they should
- // be the same but they aren't.
- CASE(1.0, 1.0.0, -1),
- CASE(1.0.0, 1.0, 1),
- // the following are from the nix-env manual:
- CASE(1.0, 2.3, -1),
- CASE(2.1, 2.3, -1),
- CASE(2.3, 2.3, 0),
- CASE(2.5, 2.3, 1),
- CASE(3.1, 2.3, 1),
- CASE(2.3.1, 2.3, 1),
- CASE(2.3.1, 2.3a, 1),
- CASE(2.3pre1, 2.3, -1),
- CASE(2.3pre3, 2.3pre12, -1),
- CASE(2.3a, 2.3c, -1),
- CASE(2.3pre1, 2.3c, -1),
- CASE(2.3pre1, 2.3q, -1)
- )
- );
-#undef CASE
-
-
- class ParseDrvNamePrimOpTest :
- public PrimOpTest,
- public testing::WithParamInterface<std::tuple<std::string, std::string_view, std::string_view>>
- {};
-
- TEST_P(ParseDrvNamePrimOpTest, parseDrvName) {
- auto [input, expectedName, expectedVersion] = GetParam();
- const auto expr = fmt("builtins.parseDrvName \"%1%\"", input);
- auto v = eval(expr);
- ASSERT_THAT(v, IsAttrsOfSize(2));
-
- auto name = v.attrs->find(createSymbol("name"));
- ASSERT_TRUE(name);
- ASSERT_THAT(*name->value, IsStringEq(expectedName));
-
- auto version = v.attrs->find(createSymbol("version"));
- ASSERT_TRUE(version);
- ASSERT_THAT(*version->value, IsStringEq(expectedVersion));
- }
-
- INSTANTIATE_TEST_SUITE_P(
- parseDrvName,
- ParseDrvNamePrimOpTest,
- testing::Values(
- std::make_tuple("nix-0.12pre12876", "nix", "0.12pre12876"),
- std::make_tuple("a-b-c-1234pre5+git", "a-b-c", "1234pre5+git")
- )
- );
-
- TEST_F(PrimOpTest, replaceStrings) {
- // FIXME: add a test that verifies the string context is as expected
- auto v = eval("builtins.replaceStrings [\"oo\" \"a\"] [\"a\" \"i\"] \"foobar\"");
- ASSERT_EQ(v.type(), nString);
- ASSERT_EQ(v.string.s, std::string_view("fabir"));
- }
-
- TEST_F(PrimOpTest, concatStringsSep) {
- // FIXME: add a test that verifies the string context is as expected
- auto v = eval("builtins.concatStringsSep \"%\" [\"foo\" \"bar\" \"baz\"]");
- ASSERT_EQ(v.type(), nString);
- ASSERT_EQ(std::string_view(v.string.s), "foo%bar%baz");
- }
-
- TEST_F(PrimOpTest, split1) {
- // v = [ "" [ "a" ] "c" ]
- auto v = eval("builtins.split \"(a)b\" \"abc\"");
- ASSERT_THAT(v, IsListOfSize(3));
-
- ASSERT_THAT(*v.listElems()[0], IsStringEq(""));
-
- ASSERT_THAT(*v.listElems()[1], IsListOfSize(1));
- ASSERT_THAT(*v.listElems()[1]->listElems()[0], IsStringEq("a"));
-
- ASSERT_THAT(*v.listElems()[2], IsStringEq("c"));
- }
-
- TEST_F(PrimOpTest, split2) {
- // v is expected to be a list [ "" [ "a" ] "b" [ "c"] "" ]
- auto v = eval("builtins.split \"([ac])\" \"abc\"");
- ASSERT_THAT(v, IsListOfSize(5));
-
- ASSERT_THAT(*v.listElems()[0], IsStringEq(""));
-
- ASSERT_THAT(*v.listElems()[1], IsListOfSize(1));
- ASSERT_THAT(*v.listElems()[1]->listElems()[0], IsStringEq("a"));
-
- ASSERT_THAT(*v.listElems()[2], IsStringEq("b"));
-
- ASSERT_THAT(*v.listElems()[3], IsListOfSize(1));
- ASSERT_THAT(*v.listElems()[3]->listElems()[0], IsStringEq("c"));
-
- ASSERT_THAT(*v.listElems()[4], IsStringEq(""));
- }
-
- TEST_F(PrimOpTest, split3) {
- auto v = eval("builtins.split \"(a)|(c)\" \"abc\"");
- ASSERT_THAT(v, IsListOfSize(5));
-
- // First list element
- ASSERT_THAT(*v.listElems()[0], IsStringEq(""));
-
- // 2nd list element is a list [ "" null ]
- ASSERT_THAT(*v.listElems()[1], IsListOfSize(2));
- ASSERT_THAT(*v.listElems()[1]->listElems()[0], IsStringEq("a"));
- ASSERT_THAT(*v.listElems()[1]->listElems()[1], IsNull());
-
- // 3rd element
- ASSERT_THAT(*v.listElems()[2], IsStringEq("b"));
-
- // 4th element is a list: [ null "c" ]
- ASSERT_THAT(*v.listElems()[3], IsListOfSize(2));
- ASSERT_THAT(*v.listElems()[3]->listElems()[0], IsNull());
- ASSERT_THAT(*v.listElems()[3]->listElems()[1], IsStringEq("c"));
-
- // 5th element is the empty string
- ASSERT_THAT(*v.listElems()[4], IsStringEq(""));
- }
-
- TEST_F(PrimOpTest, split4) {
- auto v = eval("builtins.split \"([[:upper:]]+)\" \" FOO \"");
- ASSERT_THAT(v, IsListOfSize(3));
- auto first = v.listElems()[0];
- auto second = v.listElems()[1];
- auto third = v.listElems()[2];
-
- ASSERT_THAT(*first, IsStringEq(" "));
-
- ASSERT_THAT(*second, IsListOfSize(1));
- ASSERT_THAT(*second->listElems()[0], IsStringEq("FOO"));
-
- ASSERT_THAT(*third, IsStringEq(" "));
- }
-
- TEST_F(PrimOpTest, match1) {
- auto v = eval("builtins.match \"ab\" \"abc\"");
- ASSERT_THAT(v, IsNull());
- }
-
- TEST_F(PrimOpTest, match2) {
- auto v = eval("builtins.match \"abc\" \"abc\"");
- ASSERT_THAT(v, IsListOfSize(0));
- }
-
- TEST_F(PrimOpTest, match3) {
- auto v = eval("builtins.match \"a(b)(c)\" \"abc\"");
- ASSERT_THAT(v, IsListOfSize(2));
- ASSERT_THAT(*v.listElems()[0], IsStringEq("b"));
- ASSERT_THAT(*v.listElems()[1], IsStringEq("c"));
- }
-
- TEST_F(PrimOpTest, match4) {
- auto v = eval("builtins.match \"[[:space:]]+([[:upper:]]+)[[:space:]]+\" \" FOO \"");
- ASSERT_THAT(v, IsListOfSize(1));
- ASSERT_THAT(*v.listElems()[0], IsStringEq("FOO"));
- }
-
- TEST_F(PrimOpTest, attrNames) {
- auto v = eval("builtins.attrNames { x = 1; y = 2; z = 3; a = 2; }");
- ASSERT_THAT(v, IsListOfSize(4));
-
- // ensure that the list is sorted
- const std::vector<std::string_view> expected { "a", "x", "y", "z" };
- for (const auto [n, elem] : enumerate(v.listItems()))
- ASSERT_THAT(*elem, IsStringEq(expected[n]));
- }
-
- TEST_F(PrimOpTest, genericClosure_not_strict) {
- // Operator should not be used when startSet is empty
- auto v = eval("builtins.genericClosure { startSet = []; }");
- ASSERT_THAT(v, IsListOfSize(0));
- }
-} /* namespace nix */
diff --git a/src/libexpr/tests/search-path.cc b/src/libexpr/tests/search-path.cc
deleted file mode 100644
index dbe7ab95f..000000000
--- a/src/libexpr/tests/search-path.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include "search-path.hh"
-
-namespace nix {
-
-TEST(SearchPathElem, parse_justPath) {
- ASSERT_EQ(
- SearchPath::Elem::parse("foo"),
- (SearchPath::Elem {
- .prefix = SearchPath::Prefix { .s = "" },
- .path = SearchPath::Path { .s = "foo" },
- }));
-}
-
-TEST(SearchPathElem, parse_emptyPrefix) {
- ASSERT_EQ(
- SearchPath::Elem::parse("=foo"),
- (SearchPath::Elem {
- .prefix = SearchPath::Prefix { .s = "" },
- .path = SearchPath::Path { .s = "foo" },
- }));
-}
-
-TEST(SearchPathElem, parse_oneEq) {
- ASSERT_EQ(
- SearchPath::Elem::parse("foo=bar"),
- (SearchPath::Elem {
- .prefix = SearchPath::Prefix { .s = "foo" },
- .path = SearchPath::Path { .s = "bar" },
- }));
-}
-
-TEST(SearchPathElem, parse_twoEqs) {
- ASSERT_EQ(
- SearchPath::Elem::parse("foo=bar=baz"),
- (SearchPath::Elem {
- .prefix = SearchPath::Prefix { .s = "foo" },
- .path = SearchPath::Path { .s = "bar=baz" },
- }));
-}
-
-
-TEST(SearchPathElem, suffixIfPotentialMatch_justPath) {
- SearchPath::Prefix prefix { .s = "" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("any/thing"), std::optional { "any/thing" });
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_misleadingPrefix1) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX"), std::nullopt);
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_misleadingPrefix2) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX/bar"), std::nullopt);
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_partialPrefix) {
- SearchPath::Prefix prefix { .s = "fooX" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::nullopt);
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_exactPrefix) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::optional { "" });
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_multiKey) {
- SearchPath::Prefix prefix { .s = "foo/bar" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "baz" });
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_trailingSlash) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/"), std::optional { "" });
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_trailingDoubleSlash) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo//"), std::optional { "/" });
-}
-
-TEST(SearchPathElem, suffixIfPotentialMatch_trailingPath) {
- SearchPath::Prefix prefix { .s = "foo" };
- ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "bar/baz" });
-}
-
-}
diff --git a/src/libexpr/tests/trivial.cc b/src/libexpr/tests/trivial.cc
deleted file mode 100644
index 171727ac7..000000000
--- a/src/libexpr/tests/trivial.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-#include "tests/libexpr.hh"
-
-namespace nix {
- // Testing of trivial expressions
- class TrivialExpressionTest : public LibExprTest {};
-
- TEST_F(TrivialExpressionTest, true) {
- auto v = eval("true");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(TrivialExpressionTest, false) {
- auto v = eval("false");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(TrivialExpressionTest, null) {
- auto v = eval("null");
- ASSERT_THAT(v, IsNull());
- }
-
- TEST_F(TrivialExpressionTest, 1) {
- auto v = eval("1");
- ASSERT_THAT(v, IsIntEq(1));
- }
-
- TEST_F(TrivialExpressionTest, 1plus1) {
- auto v = eval("1+1");
- ASSERT_THAT(v, IsIntEq(2));
- }
-
- TEST_F(TrivialExpressionTest, minus1) {
- auto v = eval("-1");
- ASSERT_THAT(v, IsIntEq(-1));
- }
-
- TEST_F(TrivialExpressionTest, 1minus1) {
- auto v = eval("1-1");
- ASSERT_THAT(v, IsIntEq(0));
- }
-
- TEST_F(TrivialExpressionTest, lambdaAdd) {
- auto v = eval("let add = a: b: a + b; in add 1 2");
- ASSERT_THAT(v, IsIntEq(3));
- }
-
- TEST_F(TrivialExpressionTest, list) {
- auto v = eval("[]");
- ASSERT_THAT(v, IsListOfSize(0));
- }
-
- TEST_F(TrivialExpressionTest, attrs) {
- auto v = eval("{}");
- ASSERT_THAT(v, IsAttrsOfSize(0));
- }
-
- TEST_F(TrivialExpressionTest, float) {
- auto v = eval("1.234");
- ASSERT_THAT(v, IsFloatEq(1.234));
- }
-
- TEST_F(TrivialExpressionTest, updateAttrs) {
- auto v = eval("{ a = 1; } // { b = 2; a = 3; }");
- ASSERT_THAT(v, IsAttrsOfSize(2));
- auto a = v.attrs->find(createSymbol("a"));
- ASSERT_NE(a, nullptr);
- ASSERT_THAT(*a->value, IsIntEq(3));
-
- auto b = v.attrs->find(createSymbol("b"));
- ASSERT_NE(b, nullptr);
- ASSERT_THAT(*b->value, IsIntEq(2));
- }
-
- TEST_F(TrivialExpressionTest, hasAttrOpFalse) {
- auto v = eval("{} ? a");
- ASSERT_THAT(v, IsFalse());
- }
-
- TEST_F(TrivialExpressionTest, hasAttrOpTrue) {
- auto v = eval("{ a = 123; } ? a");
- ASSERT_THAT(v, IsTrue());
- }
-
- TEST_F(TrivialExpressionTest, withFound) {
- auto v = eval("with { a = 23; }; a");
- ASSERT_THAT(v, IsIntEq(23));
- }
-
- TEST_F(TrivialExpressionTest, withNotFound) {
- ASSERT_THROW(eval("with {}; a"), Error);
- }
-
- TEST_F(TrivialExpressionTest, withOverride) {
- auto v = eval("with { a = 23; }; with { a = 42; }; a");
- ASSERT_THAT(v, IsIntEq(42));
- }
-
- TEST_F(TrivialExpressionTest, letOverWith) {
- auto v = eval("let a = 23; in with { a = 1; }; a");
- ASSERT_THAT(v, IsIntEq(23));
- }
-
- TEST_F(TrivialExpressionTest, multipleLet) {
- auto v = eval("let a = 23; in let a = 42; in a");
- ASSERT_THAT(v, IsIntEq(42));
- }
-
- TEST_F(TrivialExpressionTest, defaultFunctionArgs) {
- auto v = eval("({ a ? 123 }: a) {}");
- ASSERT_THAT(v, IsIntEq(123));
- }
-
- TEST_F(TrivialExpressionTest, defaultFunctionArgsOverride) {
- auto v = eval("({ a ? 123 }: a) { a = 5; }");
- ASSERT_THAT(v, IsIntEq(5));
- }
-
- TEST_F(TrivialExpressionTest, defaultFunctionArgsCaptureBack) {
- auto v = eval("({ a ? 123 }@args: args) {}");
- ASSERT_THAT(v, IsAttrsOfSize(0));
- }
-
- TEST_F(TrivialExpressionTest, defaultFunctionArgsCaptureFront) {
- auto v = eval("(args@{ a ? 123 }: args) {}");
- ASSERT_THAT(v, IsAttrsOfSize(0));
- }
-
- TEST_F(TrivialExpressionTest, assertThrows) {
- ASSERT_THROW(eval("let x = arg: assert arg == 1; 123; in x 2"), Error);
- }
-
- TEST_F(TrivialExpressionTest, assertPassed) {
- auto v = eval("let x = arg: assert arg == 1; 123; in x 1");
- ASSERT_THAT(v, IsIntEq(123));
- }
-
- class AttrSetMergeTrvialExpressionTest :
- public TrivialExpressionTest,
- public testing::WithParamInterface<const char*>
- {};
-
- TEST_P(AttrSetMergeTrvialExpressionTest, attrsetMergeLazy) {
- // Usually Nix rejects duplicate keys in an attrset but it does allow
- // so if it is an attribute set that contains disjoint sets of keys.
- // The below is equivalent to `{a.b = 1; a.c = 2; }`.
- // The attribute set `a` will be a Thunk at first as the attribuets
- // have to be merged (or otherwise computed) and that is done in a lazy
- // manner.
-
- auto expr = GetParam();
- auto v = eval(expr);
- ASSERT_THAT(v, IsAttrsOfSize(1));
-
- auto a = v.attrs->find(createSymbol("a"));
- ASSERT_NE(a, nullptr);
-
- ASSERT_THAT(*a->value, IsThunk());
- state.forceValue(*a->value, noPos);
-
- ASSERT_THAT(*a->value, IsAttrsOfSize(2));
-
- auto b = a->value->attrs->find(createSymbol("b"));
- ASSERT_NE(b, nullptr);
- ASSERT_THAT(*b->value, IsIntEq(1));
-
- auto c = a->value->attrs->find(createSymbol("c"));
- ASSERT_NE(c, nullptr);
- ASSERT_THAT(*c->value, IsIntEq(2));
- }
-
- INSTANTIATE_TEST_SUITE_P(
- attrsetMergeLazy,
- AttrSetMergeTrvialExpressionTest,
- testing::Values(
- "{ a.b = 1; a.c = 2; }",
- "{ a = { b = 1; }; a = { c = 2; }; }"
- )
- );
-
- TEST_F(TrivialExpressionTest, functor) {
- auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
- ASSERT_THAT(v, IsIntEq(15));
- }
-
- TEST_F(TrivialExpressionTest, bindOr) {
- auto v = eval("{ or = 1; }");
- ASSERT_THAT(v, IsAttrsOfSize(1));
- auto b = v.attrs->find(createSymbol("or"));
- ASSERT_NE(b, nullptr);
- ASSERT_THAT(*b->value, IsIntEq(1));
- }
-
- TEST_F(TrivialExpressionTest, orCantBeUsed) {
- ASSERT_THROW(eval("let or = 1; in or"), Error);
- }
-} /* namespace nix */
diff --git a/src/libexpr/tests/value/context.cc b/src/libexpr/tests/value/context.cc
deleted file mode 100644
index 92d4889ab..000000000
--- a/src/libexpr/tests/value/context.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-
-#include "tests/path.hh"
-#include "tests/libexpr.hh"
-#include "tests/value/context.hh"
-
-namespace nix {
-
-// Test a few cases of invalid string context elements.
-
-TEST(NixStringContextElemTest, empty_invalid) {
- EXPECT_THROW(
- NixStringContextElem::parse(""),
- BadNixStringContextElem);
-}
-
-TEST(NixStringContextElemTest, single_bang_invalid) {
- EXPECT_THROW(
- NixStringContextElem::parse("!"),
- BadNixStringContextElem);
-}
-
-TEST(NixStringContextElemTest, double_bang_invalid) {
- EXPECT_THROW(
- NixStringContextElem::parse("!!/"),
- BadStorePath);
-}
-
-TEST(NixStringContextElemTest, eq_slash_invalid) {
- EXPECT_THROW(
- NixStringContextElem::parse("=/"),
- BadStorePath);
-}
-
-TEST(NixStringContextElemTest, slash_invalid) {
- EXPECT_THROW(
- NixStringContextElem::parse("/"),
- BadStorePath);
-}
-
-/**
- * Round trip (string <-> data structure) test for
- * `NixStringContextElem::Opaque`.
- */
-TEST(NixStringContextElemTest, opaque) {
- std::string_view opaque = "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x";
- auto elem = NixStringContextElem::parse(opaque);
- auto * p = std::get_if<NixStringContextElem::Opaque>(&elem.raw);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->path, StorePath { opaque });
- ASSERT_EQ(elem.to_string(), opaque);
-}
-
-/**
- * Round trip (string <-> data structure) test for
- * `NixStringContextElem::DrvDeep`.
- */
-TEST(NixStringContextElemTest, drvDeep) {
- std::string_view drvDeep = "=g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv";
- auto elem = NixStringContextElem::parse(drvDeep);
- auto * p = std::get_if<NixStringContextElem::DrvDeep>(&elem.raw);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->drvPath, StorePath { drvDeep.substr(1) });
- ASSERT_EQ(elem.to_string(), drvDeep);
-}
-
-/**
- * Round trip (string <-> data structure) test for a simpler
- * `NixStringContextElem::Built`.
- */
-TEST(NixStringContextElemTest, built_opaque) {
- std::string_view built = "!foo!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv";
- auto elem = NixStringContextElem::parse(built);
- auto * p = std::get_if<NixStringContextElem::Built>(&elem.raw);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->output, "foo");
- ASSERT_EQ(*p->drvPath, ((SingleDerivedPath) SingleDerivedPath::Opaque {
- .path = StorePath { built.substr(5) },
- }));
- ASSERT_EQ(elem.to_string(), built);
-}
-
-/**
- * Round trip (string <-> data structure) test for a more complex,
- * inductive `NixStringContextElem::Built`.
- */
-TEST(NixStringContextElemTest, built_built) {
- /**
- * We set these in tests rather than the regular globals so we don't have
- * to worry about race conditions if the tests run concurrently.
- */
- ExperimentalFeatureSettings mockXpSettings;
- mockXpSettings.set("experimental-features", "dynamic-derivations ca-derivations");
-
- std::string_view built = "!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv";
- auto elem = NixStringContextElem::parse(built, mockXpSettings);
- auto * p = std::get_if<NixStringContextElem::Built>(&elem.raw);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->output, "foo");
- auto * drvPath = std::get_if<SingleDerivedPath::Built>(&*p->drvPath);
- ASSERT_TRUE(drvPath);
- ASSERT_EQ(drvPath->output, "bar");
- ASSERT_EQ(*drvPath->drvPath, ((SingleDerivedPath) SingleDerivedPath::Opaque {
- .path = StorePath { built.substr(9) },
- }));
- ASSERT_EQ(elem.to_string(), built);
-}
-
-/**
- * Without the right experimental features enabled, we cannot parse a
- * complex inductive string context element.
- */
-TEST(NixStringContextElemTest, built_built_xp) {
- ASSERT_THROW(
- NixStringContextElem::parse("!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv"), MissingExperimentalFeature);
-}
-
-}
-
-namespace rc {
-using namespace nix;
-
-Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
-{
- return gen::just(NixStringContextElem::DrvDeep {
- .drvPath = *gen::arbitrary<StorePath>(),
- });
-}
-
-Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
-{
- switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
- case 0:
- return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
- case 1:
- return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
- case 2:
- return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
- default:
- assert(false);
- }
-}
-
-}
-
-namespace nix {
-
-#ifndef COVERAGE
-
-RC_GTEST_PROP(
- NixStringContextElemTest,
- prop_round_rip,
- (const NixStringContextElem & o))
-{
- RC_ASSERT(o == NixStringContextElem::parse(o.to_string()));
-}
-
-#endif
-
-}
diff --git a/src/libexpr/tests/value/context.hh b/src/libexpr/tests/value/context.hh
deleted file mode 100644
index c0bc97ba3..000000000
--- a/src/libexpr/tests/value/context.hh
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-///@file
-
-#include <rapidcheck/gen/Arbitrary.h>
-
-#include <value/context.hh>
-
-namespace rc {
-using namespace nix;
-
-template<>
-struct Arbitrary<NixStringContextElem::Opaque> {
- static Gen<NixStringContextElem::Opaque> arbitrary();
-};
-
-template<>
-struct Arbitrary<NixStringContextElem::Built> {
- static Gen<NixStringContextElem::Built> arbitrary();
-};
-
-template<>
-struct Arbitrary<NixStringContextElem::DrvDeep> {
- static Gen<NixStringContextElem::DrvDeep> arbitrary();
-};
-
-template<>
-struct Arbitrary<NixStringContextElem> {
- static Gen<NixStringContextElem> arbitrary();
-};
-
-}
diff --git a/src/libexpr/tests/value/print.cc b/src/libexpr/tests/value/print.cc
deleted file mode 100644
index 5e96e12ec..000000000
--- a/src/libexpr/tests/value/print.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-#include "tests/libexpr.hh"
-
-#include "value.hh"
-
-namespace nix {
-
-using namespace testing;
-
-struct ValuePrintingTests : LibExprTest
-{
- template<class... A>
- void test(Value v, std::string_view expected, A... args)
- {
- std::stringstream out;
- v.print(state.symbols, out, args...);
- ASSERT_EQ(out.str(), expected);
- }
-};
-
-TEST_F(ValuePrintingTests, tInt)
-{
- Value vInt;
- vInt.mkInt(10);
- test(vInt, "10");
-}
-
-TEST_F(ValuePrintingTests, tBool)
-{
- Value vBool;
- vBool.mkBool(true);
- test(vBool, "true");
-}
-
-TEST_F(ValuePrintingTests, tString)
-{
- Value vString;
- vString.mkString("some-string");
- test(vString, "\"some-string\"");
-}
-
-TEST_F(ValuePrintingTests, tPath)
-{
- Value vPath;
- vPath.mkString("/foo");
- test(vPath, "\"/foo\"");
-}
-
-TEST_F(ValuePrintingTests, tNull)
-{
- Value vNull;
- vNull.mkNull();
- test(vNull, "null");
-}
-
-TEST_F(ValuePrintingTests, tAttrs)
-{
- Value vOne;
- vOne.mkInt(1);
-
- Value vTwo;
- vTwo.mkInt(2);
-
- BindingsBuilder builder(state, state.allocBindings(10));
- builder.insert(state.symbols.create("one"), &vOne);
- builder.insert(state.symbols.create("two"), &vTwo);
-
- Value vAttrs;
- vAttrs.mkAttrs(builder.finish());
-
- test(vAttrs, "{ one = 1; two = 2; }");
-}
-
-TEST_F(ValuePrintingTests, tList)
-{
- Value vOne;
- vOne.mkInt(1);
-
- Value vTwo;
- vTwo.mkInt(2);
-
- Value vList;
- state.mkList(vList, 5);
- vList.bigList.elems[0] = &vOne;
- vList.bigList.elems[1] = &vTwo;
- vList.bigList.size = 3;
-
- test(vList, "[ 1 2 (nullptr) ]");
-}
-
-TEST_F(ValuePrintingTests, vThunk)
-{
- Value vThunk;
- vThunk.mkThunk(nullptr, nullptr);
-
- test(vThunk, "<CODE>");
-}
-
-TEST_F(ValuePrintingTests, vApp)
-{
- Value vApp;
- vApp.mkApp(nullptr, nullptr);
-
- test(vApp, "<CODE>");
-}
-
-TEST_F(ValuePrintingTests, vLambda)
-{
- Value vLambda;
- vLambda.mkLambda(nullptr, nullptr);
-
- test(vLambda, "<LAMBDA>");
-}
-
-TEST_F(ValuePrintingTests, vPrimOp)
-{
- Value vPrimOp;
- vPrimOp.mkPrimOp(nullptr);
-
- test(vPrimOp, "<PRIMOP>");
-}
-
-TEST_F(ValuePrintingTests, vPrimOpApp)
-{
- Value vPrimOpApp;
- vPrimOpApp.mkPrimOpApp(nullptr, nullptr);
-
- test(vPrimOpApp, "<PRIMOP-APP>");
-}
-
-TEST_F(ValuePrintingTests, vExternal)
-{
- struct MyExternal : ExternalValueBase
- {
- public:
- std::string showType() const override
- {
- return "";
- }
- std::string typeOf() const override
- {
- return "";
- }
- virtual std::ostream & print(std::ostream & str) const override
- {
- str << "testing-external!";
- return str;
- }
- } myExternal;
- Value vExternal;
- vExternal.mkExternal(&myExternal);
-
- test(vExternal, "testing-external!");
-}
-
-TEST_F(ValuePrintingTests, vFloat)
-{
- Value vFloat;
- vFloat.mkFloat(2.0);
-
- test(vFloat, "2");
-}
-
-TEST_F(ValuePrintingTests, vBlackhole)
-{
- Value vBlackhole;
- vBlackhole.mkBlackhole();
- test(vBlackhole, "«potential infinite recursion»");
-}
-
-TEST_F(ValuePrintingTests, depthAttrs)
-{
- Value vOne;
- vOne.mkInt(1);
-
- Value vTwo;
- vTwo.mkInt(2);
-
- BindingsBuilder builder(state, state.allocBindings(10));
- builder.insert(state.symbols.create("one"), &vOne);
- builder.insert(state.symbols.create("two"), &vTwo);
-
- Value vAttrs;
- vAttrs.mkAttrs(builder.finish());
-
- BindingsBuilder builder2(state, state.allocBindings(10));
- builder2.insert(state.symbols.create("one"), &vOne);
- builder2.insert(state.symbols.create("two"), &vTwo);
- builder2.insert(state.symbols.create("nested"), &vAttrs);
-
- Value vNested;
- vNested.mkAttrs(builder2.finish());
-
- test(vNested, "{ nested = «too deep»; one = «too deep»; two = «too deep»; }", false, 1);
- test(vNested, "{ nested = { one = «too deep»; two = «too deep»; }; one = 1; two = 2; }", false, 2);
- test(vNested, "{ nested = { one = 1; two = 2; }; one = 1; two = 2; }", false, 3);
- test(vNested, "{ nested = { one = 1; two = 2; }; one = 1; two = 2; }", false, 4);
-}
-
-TEST_F(ValuePrintingTests, depthList)
-{
- Value vOne;
- vOne.mkInt(1);
-
- Value vTwo;
- vTwo.mkInt(2);
-
- BindingsBuilder builder(state, state.allocBindings(10));
- builder.insert(state.symbols.create("one"), &vOne);
- builder.insert(state.symbols.create("two"), &vTwo);
-
- Value vAttrs;
- vAttrs.mkAttrs(builder.finish());
-
- BindingsBuilder builder2(state, state.allocBindings(10));
- builder2.insert(state.symbols.create("one"), &vOne);
- builder2.insert(state.symbols.create("two"), &vTwo);
- builder2.insert(state.symbols.create("nested"), &vAttrs);
-
- Value vNested;
- vNested.mkAttrs(builder2.finish());
-
- Value vList;
- state.mkList(vList, 5);
- vList.bigList.elems[0] = &vOne;
- vList.bigList.elems[1] = &vTwo;
- vList.bigList.elems[2] = &vNested;
- vList.bigList.size = 3;
-
- test(vList, "[ «too deep» «too deep» «too deep» ]", false, 1);
- test(vList, "[ 1 2 { nested = «too deep»; one = «too deep»; two = «too deep»; } ]", false, 2);
- test(vList, "[ 1 2 { nested = { one = «too deep»; two = «too deep»; }; one = 1; two = 2; } ]", false, 3);
- test(vList, "[ 1 2 { nested = { one = 1; two = 2; }; one = 1; two = 2; } ]", false, 4);
- test(vList, "[ 1 2 { nested = { one = 1; two = 2; }; one = 1; two = 2; } ]", false, 5);
-}
-
-} // namespace nix