forked from lix-project/lix
Improve tests for OutputsSpec
This commit is contained in:
parent
5ba6e5d0d9
commit
0faf5326bd
|
@ -40,22 +40,33 @@ std::optional<OutputsSpec> OutputsSpec::parseOpt(std::string_view s)
|
||||||
|
|
||||||
OutputsSpec OutputsSpec::parse(std::string_view s)
|
OutputsSpec OutputsSpec::parse(std::string_view s)
|
||||||
{
|
{
|
||||||
std::optional spec = OutputsSpec::parseOpt(s);
|
std::optional spec = parseOpt(s);
|
||||||
if (!spec)
|
if (!spec)
|
||||||
throw Error("Invalid outputs specifier: '%s'", s);
|
throw Error("Invalid outputs specifier: '%s'", s);
|
||||||
return *spec;
|
return *spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::string_view, ExtendedOutputsSpec> ExtendedOutputsSpec::parse(std::string_view s)
|
std::optional<std::pair<std::string_view, ExtendedOutputsSpec>> ExtendedOutputsSpec::parseOpt(std::string_view s)
|
||||||
{
|
{
|
||||||
auto found = s.rfind('^');
|
auto found = s.rfind('^');
|
||||||
|
|
||||||
if (found == std::string::npos)
|
if (found == std::string::npos)
|
||||||
return { s, ExtendedOutputsSpec::Default {} };
|
return std::pair { s, ExtendedOutputsSpec::Default {} };
|
||||||
|
|
||||||
auto spec = OutputsSpec::parse(s.substr(found + 1));
|
auto specOpt = OutputsSpec::parseOpt(s.substr(found + 1));
|
||||||
return { s.substr(0, found), ExtendedOutputsSpec::Explicit { spec } };
|
if (!specOpt)
|
||||||
|
return std::nullopt;
|
||||||
|
return std::pair { s.substr(0, found), ExtendedOutputsSpec::Explicit { *std::move(specOpt) } };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<std::string_view, ExtendedOutputsSpec> ExtendedOutputsSpec::parse(std::string_view s)
|
||||||
|
{
|
||||||
|
std::optional spec = parseOpt(s);
|
||||||
|
if (!spec)
|
||||||
|
throw Error("Invalid extended outputs specifier: '%s'", s);
|
||||||
|
return *spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@ struct OutputNames : std::set<std::string> {
|
||||||
OutputNames() = delete;
|
OutputNames() = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AllOutputs {
|
struct AllOutputs : std::monostate { };
|
||||||
bool operator < (const AllOutputs & _) const { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::variant<AllOutputs, OutputNames> _OutputsSpecRaw;
|
typedef std::variant<AllOutputs, OutputNames> _OutputsSpecRaw;
|
||||||
|
|
||||||
|
@ -64,9 +62,7 @@ struct OutputsSpec : _OutputsSpecRaw {
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DefaultOutputs {
|
struct DefaultOutputs : std::monostate { };
|
||||||
bool operator < (const DefaultOutputs & _) const { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::variant<DefaultOutputs, OutputsSpec> _ExtendedOutputsSpecRaw;
|
typedef std::variant<DefaultOutputs, OutputsSpec> _ExtendedOutputsSpecRaw;
|
||||||
|
|
||||||
|
@ -84,6 +80,7 @@ struct ExtendedOutputsSpec : _ExtendedOutputsSpecRaw {
|
||||||
/* Parse a string of the form 'prefix^output1,...outputN' or
|
/* Parse a string of the form 'prefix^output1,...outputN' or
|
||||||
'prefix^*', returning the prefix and the extended outputs spec. */
|
'prefix^*', returning the prefix and the extended outputs spec. */
|
||||||
static std::pair<std::string_view, ExtendedOutputsSpec> parse(std::string_view s);
|
static std::pair<std::string_view, ExtendedOutputsSpec> parse(std::string_view s);
|
||||||
|
static std::optional<std::pair<std::string_view, ExtendedOutputsSpec>> parseOpt(std::string_view s);
|
||||||
|
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,63 +4,96 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
TEST(OutputsSpec_parse, basic)
|
#define TEST_DONT_PARSE(NAME, STR) \
|
||||||
{
|
TEST(OutputsSpec, bad_ ## NAME) { \
|
||||||
{
|
std::optional OutputsSpecOpt = \
|
||||||
auto outputsSpec = OutputsSpec::parse("*");
|
OutputsSpec::parseOpt(STR); \
|
||||||
ASSERT_TRUE(std::get_if<OutputsSpec::All>(&outputsSpec));
|
ASSERT_FALSE(OutputsSpecOpt); \
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST_DONT_PARSE(empty, "")
|
||||||
auto outputsSpec = OutputsSpec::parse("out");
|
TEST_DONT_PARSE(garbage, "&*()")
|
||||||
ASSERT_TRUE(std::get<OutputsSpec::Names>(outputsSpec) == OutputsSpec::Names({"out"}));
|
TEST_DONT_PARSE(double_star, "**")
|
||||||
|
TEST_DONT_PARSE(star_first, "*,foo")
|
||||||
|
TEST_DONT_PARSE(star_second, "foo,*")
|
||||||
|
|
||||||
|
#undef TEST_DONT_PARSE
|
||||||
|
|
||||||
|
TEST(OutputsSpec, all) {
|
||||||
|
std::string_view str = "*";
|
||||||
|
OutputsSpec expected = OutputsSpec::All { };
|
||||||
|
ASSERT_EQ(OutputsSpec::parse(str), expected);
|
||||||
|
ASSERT_EQ(expected.to_string(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(OutputsSpec, names_out) {
|
||||||
auto outputsSpec = OutputsSpec::parse("out,bin");
|
std::string_view str = "out";
|
||||||
ASSERT_TRUE(std::get<OutputsSpec::Names>(outputsSpec) == OutputsSpec::Names({"out", "bin"}));
|
OutputsSpec expected = OutputsSpec::Names { "out" };
|
||||||
|
ASSERT_EQ(OutputsSpec::parse(str), expected);
|
||||||
|
ASSERT_EQ(expected.to_string(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(OutputsSpec, names_out_bin) {
|
||||||
std::optional outputsSpecOpt = OutputsSpec::parseOpt("&*()");
|
OutputsSpec expected = OutputsSpec::Names { "out", "bin" };
|
||||||
ASSERT_FALSE(outputsSpecOpt);
|
ASSERT_EQ(OutputsSpec::parse("out,bin"), expected);
|
||||||
}
|
// N.B. This normalization is OK.
|
||||||
|
ASSERT_EQ(expected.to_string(), "bin,out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(ExtendedOutputsSpec_parse, basic)
|
#define TEST_DONT_PARSE(NAME, STR) \
|
||||||
{
|
TEST(ExtendedOutputsSpec, bad_ ## NAME) { \
|
||||||
{
|
std::optional extendedOutputsSpecOpt = \
|
||||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo");
|
ExtendedOutputsSpec::parseOpt(STR); \
|
||||||
|
ASSERT_FALSE(extendedOutputsSpecOpt); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_DONT_PARSE(carot_empty, "^")
|
||||||
|
TEST_DONT_PARSE(prefix_carot_empty, "foo^")
|
||||||
|
|
||||||
|
#undef TEST_DONT_PARSE
|
||||||
|
|
||||||
|
TEST(ExtendedOutputsSpec, defeault) {
|
||||||
|
std::string_view str = "foo";
|
||||||
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
||||||
ASSERT_EQ(prefix, "foo");
|
ASSERT_EQ(prefix, "foo");
|
||||||
ASSERT_TRUE(std::get_if<ExtendedOutputsSpec::Default>(&extendedOutputsSpec));
|
ExtendedOutputsSpec expected = ExtendedOutputsSpec::Default { };
|
||||||
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
||||||
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(ExtendedOutputsSpec, all) {
|
||||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^*");
|
std::string_view str = "foo^*";
|
||||||
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
||||||
ASSERT_EQ(prefix, "foo");
|
ASSERT_EQ(prefix, "foo");
|
||||||
auto * explicit_p = std::get_if<ExtendedOutputsSpec::Explicit>(&extendedOutputsSpec);
|
ExtendedOutputsSpec expected = OutputsSpec::All { };
|
||||||
ASSERT_TRUE(explicit_p);
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
||||||
ASSERT_TRUE(std::get_if<OutputsSpec::All>(explicit_p));
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(ExtendedOutputsSpec, out) {
|
||||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^out");
|
std::string_view str = "foo^out";
|
||||||
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
||||||
ASSERT_EQ(prefix, "foo");
|
ASSERT_EQ(prefix, "foo");
|
||||||
ASSERT_TRUE(std::get<OutputsSpec::Names>(std::get<ExtendedOutputsSpec::Explicit>(extendedOutputsSpec)) == OutputsSpec::Names({"out"}));
|
ExtendedOutputsSpec expected = OutputsSpec::Names { "out" };
|
||||||
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
||||||
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(ExtendedOutputsSpec, out_bin) {
|
||||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^out,bin");
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^out,bin");
|
||||||
ASSERT_EQ(prefix, "foo");
|
ASSERT_EQ(prefix, "foo");
|
||||||
ASSERT_TRUE(std::get<OutputsSpec::Names>(std::get<ExtendedOutputsSpec::Explicit>(extendedOutputsSpec)) == OutputsSpec::Names({"out", "bin"}));
|
ExtendedOutputsSpec expected = OutputsSpec::Names { "out", "bin" };
|
||||||
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
||||||
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), "foo^bin,out");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
TEST(ExtendedOutputsSpec, many_carrot) {
|
||||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^bar^out,bin");
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^bar^out,bin");
|
||||||
ASSERT_EQ(prefix, "foo^bar");
|
ASSERT_EQ(prefix, "foo^bar");
|
||||||
ASSERT_TRUE(std::get<OutputsSpec::Names>(std::get<ExtendedOutputsSpec::Explicit>(extendedOutputsSpec)) == OutputsSpec::Names({"out", "bin"}));
|
ExtendedOutputsSpec expected = OutputsSpec::Names { "out", "bin" };
|
||||||
}
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
||||||
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), "foo^bar^bin,out");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue