Skip to content

Commit

Permalink
Test the builtins.parseFlakeRef primop
Browse files Browse the repository at this point in the history
Simple unit tests, but already catch half of the issue behind #6633 (comment)
  • Loading branch information
Théophane Hufschmitt committed Mar 1, 2024
1 parent bf48501 commit 84619c4
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/libexpr/flake/flakeref.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ FlakeRef parseFlakeRef(
{
auto [flakeRef, fragment] = parseFlakeRefWithFragment(url, baseDir, allowMissing, isFlake);
if (fragment != "")
throw Error("unexpected fragment '%s' in flake reference '%s'", fragment, url);
throw FlakeRefError("unexpected fragment '%s' in flake reference '%s'", fragment, url);
return flakeRef;
}

Expand Down Expand Up @@ -113,10 +113,10 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
found = true;
break;
} else if (pathExists(path + "/.git"))
throw Error("path '%s' is not part of a flake (neither it nor its parent directories contain a 'flake.nix' file)", path);
throw FlakeRefError("path '%s' is not part of a flake (neither it nor its parent directories contain a 'flake.nix' file)", path);
else {
if (lstat(path).st_dev != device)
throw Error("unable to find a flake before encountering filesystem boundary at '%s'", path);
throw FlakeRefError("unable to find a flake before encountering filesystem boundary at '%s'", path);
}
path = dirOf(path);
}
Expand Down Expand Up @@ -148,7 +148,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(

if (subdir != "") {
if (parsedURL.query.count("dir"))
throw Error("flake URL '%s' has an inconsistent 'dir' parameter", url);
throw FlakeRefError("flake URL '%s' has an inconsistent 'dir' parameter", url);
parsedURL.query.insert_or_assign("dir", subdir);
}

Expand Down
2 changes: 2 additions & 0 deletions src/libexpr/flake/flakeref.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Store;

typedef std::string FlakeId;

MakeError(FlakeRefError, Error);

/**
* A flake reference specifies how to fetch a flake or raw source
* (e.g. from a Git repository). It is created from a URL-like syntax
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "eval-settings.hh"
#include "memory-input-accessor.hh"
#include "flake/flakeref.hh"

#include "tests/libexpr.hh"

Expand Down Expand Up @@ -855,4 +856,35 @@ namespace nix {
auto v = eval("builtins.genericClosure { startSet = []; }");
ASSERT_THAT(v, IsListOfSize(0));
}

TEST_F(PrimOpTest, parseFlakeRef) {
auto getAttrStr = [&](Value attrSet, std::string attrName) -> Value * {
auto attr = attrSet.attrs->get(createSymbol(attrName.c_str()));
if (attr == nullptr) {
ADD_FAILURE();
return new Value(); // Just so that it doesn't crash
}
return attr->value;
};

// These two refs should be equivalent
auto ref1 = "/foo/bar?lastModified=5";
auto ref2 = "/foo/bar?lastModified=5#";

for (auto ref : std::vector<std::string>{ref1, ref2}) {
auto v = eval(fmt("builtins.parseFlakeRef \"%s\"", ref));
ASSERT_THAT(v, IsAttrsOfSize(3));

EXPECT_THAT(*getAttrStr(v, "type"), IsStringEq("path"));
EXPECT_THAT(*getAttrStr(v, "path"), IsStringEq("/foo/bar"));
EXPECT_THAT(*getAttrStr(v, "lastModified"), IsIntEq(5));
}
}
TEST_F(PrimOpTest, parseFlakeRefWithFragment) {
// Throws because `builtins.parseFlakeRef` doesn't accept a fragment
EXPECT_THROW(
eval("builtins.parseFlakeRef \"/foo/bar?lastModified=5#foo\""),
FlakeRefError
);
}
} /* namespace nix */

0 comments on commit 84619c4

Please sign in to comment.