mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 00:39:37 +01:00
264 lines
9.1 KiB
C++
264 lines
9.1 KiB
C++
#include <gtest/gtest.h>
|
|
#include <set>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "nix/fetchers/fetch-settings.hh"
|
|
#include "nix/flake/flakeref.hh"
|
|
#include "nix/fetchers/attrs.hh"
|
|
#include "nix/fetchers/fetchers.hh"
|
|
#include "nix/util/configuration.hh"
|
|
#include "nix/util/error.hh"
|
|
#include "nix/util/experimental-features.hh"
|
|
|
|
namespace nix {
|
|
|
|
/* ----------- tests for flake/flakeref.hh --------------------------------------------------*/
|
|
|
|
TEST(parseFlakeRef, path)
|
|
{
|
|
experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes);
|
|
|
|
fetchers::Settings fetchSettings;
|
|
|
|
{
|
|
auto s = "/foo/bar";
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar");
|
|
}
|
|
|
|
{
|
|
auto s = "/foo/bar?revCount=123&rev=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar?rev=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&revCount=123");
|
|
}
|
|
|
|
{
|
|
auto s = "/foo/bar?xyzzy=123";
|
|
EXPECT_THROW(parseFlakeRef(fetchSettings, s), Error);
|
|
}
|
|
|
|
{
|
|
auto s = "/foo/bar#bla";
|
|
EXPECT_THROW(parseFlakeRef(fetchSettings, s), Error);
|
|
}
|
|
|
|
{
|
|
auto s = "/foo/bar#bla";
|
|
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar");
|
|
ASSERT_EQ(fragment, "bla");
|
|
}
|
|
|
|
{
|
|
auto s = "/foo/bar?revCount=123#bla";
|
|
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar?revCount=123");
|
|
ASSERT_EQ(fragment, "bla");
|
|
}
|
|
|
|
{
|
|
auto s = "/foo bar/baz?dir=bla space";
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "path:/foo%20bar/baz?dir=bla%20space");
|
|
ASSERT_EQ(flakeref.toAttrs().at("dir"), fetchers::Attr("bla space"));
|
|
}
|
|
}
|
|
|
|
TEST(parseFlakeRef, GitArchiveInput)
|
|
{
|
|
experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes);
|
|
|
|
fetchers::Settings fetchSettings;
|
|
|
|
{
|
|
auto s = "github:foo/bar/branch%23"; // branch name with `#`
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "github:foo/bar/branch%23");
|
|
}
|
|
|
|
{
|
|
auto s = "github:foo/bar?ref=branch%23"; // branch name with `#`
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
ASSERT_EQ(flakeref.to_string(), "github:foo/bar/branch%23");
|
|
}
|
|
|
|
{
|
|
auto s = "github:foo/bar?ref=branch#\"name.with.dot\""; // unescaped quotes `"`
|
|
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
|
ASSERT_EQ(fragment, "\"name.with.dot\"");
|
|
ASSERT_EQ(flakeref.to_string(), "github:foo/bar/branch");
|
|
}
|
|
|
|
{
|
|
auto s = "github:foo/bar#\"name.with.dot\""; // unescaped quotes `"`
|
|
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
|
ASSERT_EQ(fragment, "\"name.with.dot\"");
|
|
ASSERT_EQ(flakeref.to_string(), "github:foo/bar");
|
|
}
|
|
}
|
|
|
|
struct InputFromURLTestCase
|
|
{
|
|
std::string url;
|
|
fetchers::Attrs attrs;
|
|
std::string description;
|
|
std::string expectedUrl = url;
|
|
};
|
|
|
|
class InputFromURLTest : public ::testing::WithParamInterface<InputFromURLTestCase>, public ::testing::Test
|
|
{};
|
|
|
|
TEST_P(InputFromURLTest, attrsAreCorrectAndRoundTrips)
|
|
{
|
|
experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes);
|
|
fetchers::Settings fetchSettings;
|
|
|
|
const auto & testCase = GetParam();
|
|
|
|
auto flakeref = parseFlakeRef(fetchSettings, testCase.url);
|
|
|
|
EXPECT_EQ(flakeref.toAttrs(), testCase.attrs);
|
|
EXPECT_EQ(flakeref.to_string(), testCase.expectedUrl);
|
|
|
|
auto input = fetchers::Input::fromURL(fetchSettings, flakeref.to_string());
|
|
|
|
EXPECT_EQ(input.toURLString(), testCase.expectedUrl);
|
|
EXPECT_EQ(input.toAttrs(), testCase.attrs);
|
|
|
|
// Round-trip check.
|
|
auto input2 = fetchers::Input::fromURL(fetchSettings, input.toURLString());
|
|
EXPECT_EQ(input, input2);
|
|
EXPECT_EQ(input.toURLString(), input2.toURLString());
|
|
}
|
|
|
|
using fetchers::Attr;
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
InputFromURL,
|
|
InputFromURLTest,
|
|
::testing::Values(
|
|
InputFromURLTestCase{
|
|
.url = "flake:nixpkgs",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
},
|
|
.description = "basic_indirect",
|
|
},
|
|
InputFromURLTestCase{
|
|
.url = "flake:nixpkgs/branch",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
},
|
|
.description = "basic_indirect_branch",
|
|
},
|
|
InputFromURLTestCase{
|
|
.url = "nixpkgs/branch",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
},
|
|
.description = "flake_id_ref_branch",
|
|
.expectedUrl = "flake:nixpkgs/branch",
|
|
},
|
|
InputFromURLTestCase{
|
|
.url = "nixpkgs/branch/2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
{"rev", Attr("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed")},
|
|
},
|
|
.description = "flake_id_ref_branch_trailing_slash",
|
|
.expectedUrl = "flake:nixpkgs/branch/2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
|
|
},
|
|
// The following tests are for back-compat with lax parsers in older versions
|
|
// that used `tokenizeString` for splitting path segments, which ignores empty
|
|
// strings.
|
|
InputFromURLTestCase{
|
|
.url = "nixpkgs/branch////",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
},
|
|
.description = "flake_id_ref_branch_ignore_empty_trailing_segments",
|
|
.expectedUrl = "flake:nixpkgs/branch",
|
|
},
|
|
InputFromURLTestCase{
|
|
.url = "nixpkgs/branch///2aae6c35c94fcfb415dbe95f408b9ce91ee846ed///",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
{"rev", Attr("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed")},
|
|
},
|
|
.description = "flake_id_ref_branch_ignore_empty_segments_ref_rev",
|
|
.expectedUrl = "flake:nixpkgs/branch/2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
|
|
},
|
|
InputFromURLTestCase{
|
|
// Note that this is different from above because the "flake id" shorthand
|
|
// doesn't allow this.
|
|
.url = "flake:/nixpkgs///branch////",
|
|
.attrs =
|
|
{
|
|
{"id", Attr("nixpkgs")},
|
|
{"type", Attr("indirect")},
|
|
{"ref", Attr("branch")},
|
|
},
|
|
.description = "indirect_branch_empty_segments_everywhere",
|
|
.expectedUrl = "flake:nixpkgs/branch",
|
|
},
|
|
InputFromURLTestCase{
|
|
// TODO: Technically this has an empty authority, but it's ignored
|
|
// for now. Yes, this is what all versions going back to at least
|
|
// 2.18 did and yes, this should not be allowed.
|
|
.url = "github://////owner%42/////repo%41///branch%43////",
|
|
.attrs =
|
|
{
|
|
{"type", Attr("github")},
|
|
{"owner", Attr("ownerB")},
|
|
{"repo", Attr("repoA")},
|
|
{"ref", Attr("branchC")},
|
|
},
|
|
.description = "github_ref_slashes_in_path_everywhere",
|
|
.expectedUrl = "github:ownerB/repoA/branchC",
|
|
},
|
|
InputFromURLTestCase{
|
|
// FIXME: Subgroups in gitlab URLs are busted. This double-encoding
|
|
// behavior exists since 2.18. See issue #9161 and PR #8845.
|
|
.url = "gitlab:/owner%252Fsubgroup/////repo%41///branch%43////",
|
|
.attrs =
|
|
{
|
|
{"type", Attr("gitlab")},
|
|
{"owner", Attr("owner%2Fsubgroup")},
|
|
{"repo", Attr("repoA")},
|
|
{"ref", Attr("branchC")},
|
|
},
|
|
.description = "gitlab_ref_slashes_in_path_everywhere_with_pct_encoding",
|
|
.expectedUrl = "gitlab:owner%252Fsubgroup/repoA/branchC",
|
|
}),
|
|
[](const ::testing::TestParamInfo<InputFromURLTestCase> & info) { return info.param.description; });
|
|
|
|
TEST(to_string, doesntReencodeUrl)
|
|
{
|
|
fetchers::Settings fetchSettings;
|
|
auto s = "http://localhost:8181/test/+3d.tar.gz";
|
|
auto flakeref = parseFlakeRef(fetchSettings, s);
|
|
auto unparsed = flakeref.to_string();
|
|
auto expected = "http://localhost:8181/test/%2B3d.tar.gz";
|
|
|
|
ASSERT_EQ(unparsed, expected);
|
|
}
|
|
|
|
} // namespace nix
|