mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 14:52:55 +00:00
2625e9fb0a
When reviewing old PRs, I found that #9997 adds some code to ensure one particular assert is always present. But, removing asserts isn't something we do in our own release builds either in the flake here or in nixpkgs, and is plainly a bad idea that increases support burden, especially if other distros make bad choices of build flags in their Nix packaging. For context, the assert macro in the C standard is defined to do nothing if NDEBUG is set. There is no way in our build system to set -DNDEBUG without manually adding it to CFLAGS, so this is simply a configuration we do not use. Let's ban it at compile time. I put this preprocessor directive in src/libutil.cc because it is not obvious where else to put it, and it seems like the most logical file since you are not getting a usable nix without it.
213 lines
7.2 KiB
C++
213 lines
7.2 KiB
C++
#include "tests/outputs-spec.hh"
|
|
|
|
#include <nlohmann/json.hpp>
|
|
#include <gtest/gtest.h>
|
|
#include <rapidcheck/gtest.h>
|
|
|
|
namespace nix {
|
|
|
|
TEST(OutputsSpec, no_empty_names) {
|
|
ASSERT_DEATH(OutputsSpec::Names { std::set<std::string> { } }, "");
|
|
}
|
|
|
|
#define TEST_DONT_PARSE(NAME, STR) \
|
|
TEST(OutputsSpec, bad_ ## NAME) { \
|
|
std::optional OutputsSpecOpt = \
|
|
OutputsSpec::parseOpt(STR); \
|
|
ASSERT_FALSE(OutputsSpecOpt); \
|
|
}
|
|
|
|
TEST_DONT_PARSE(empty, "")
|
|
TEST_DONT_PARSE(garbage, "&*()")
|
|
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) {
|
|
std::string_view str = "out";
|
|
OutputsSpec expected = OutputsSpec::Names { "out" };
|
|
ASSERT_EQ(OutputsSpec::parse(str), expected);
|
|
ASSERT_EQ(expected.to_string(), str);
|
|
}
|
|
|
|
TEST(OutputsSpec, names_underscore) {
|
|
std::string_view str = "a_b";
|
|
OutputsSpec expected = OutputsSpec::Names { "a_b" };
|
|
ASSERT_EQ(OutputsSpec::parse(str), expected);
|
|
ASSERT_EQ(expected.to_string(), str);
|
|
}
|
|
|
|
TEST(OutputsSpec, names_numberic) {
|
|
std::string_view str = "01";
|
|
OutputsSpec expected = OutputsSpec::Names { "01" };
|
|
ASSERT_EQ(OutputsSpec::parse(str), expected);
|
|
ASSERT_EQ(expected.to_string(), str);
|
|
}
|
|
|
|
TEST(OutputsSpec, names_out_bin) {
|
|
OutputsSpec expected = OutputsSpec::Names { "out", "bin" };
|
|
ASSERT_EQ(OutputsSpec::parse("out,bin"), expected);
|
|
// N.B. This normalization is OK.
|
|
ASSERT_EQ(expected.to_string(), "bin,out");
|
|
}
|
|
|
|
#define TEST_SUBSET(X, THIS, THAT) \
|
|
X((OutputsSpec { THIS }).isSubsetOf(THAT));
|
|
|
|
TEST(OutputsSpec, subsets_all_all) {
|
|
TEST_SUBSET(ASSERT_TRUE, OutputsSpec::All { }, OutputsSpec::All { });
|
|
}
|
|
|
|
TEST(OutputsSpec, subsets_names_all) {
|
|
TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, OutputsSpec::All { });
|
|
}
|
|
|
|
TEST(OutputsSpec, subsets_names_names_eq) {
|
|
TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, OutputsSpec::Names { "a" });
|
|
}
|
|
|
|
TEST(OutputsSpec, subsets_names_names_noneq) {
|
|
TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, (OutputsSpec::Names { "a", "b" }));
|
|
}
|
|
|
|
TEST(OutputsSpec, not_subsets_all_names) {
|
|
TEST_SUBSET(ASSERT_FALSE, OutputsSpec::All { }, OutputsSpec::Names { "a" });
|
|
}
|
|
|
|
TEST(OutputsSpec, not_subsets_names_names) {
|
|
TEST_SUBSET(ASSERT_FALSE, (OutputsSpec::Names { "a", "b" }), (OutputsSpec::Names { "a" }));
|
|
}
|
|
|
|
#undef TEST_SUBSET
|
|
|
|
#define TEST_UNION(RES, THIS, THAT) \
|
|
ASSERT_EQ(OutputsSpec { RES }, (OutputsSpec { THIS }).union_(THAT));
|
|
|
|
TEST(OutputsSpec, union_all_all) {
|
|
TEST_UNION(OutputsSpec::All { }, OutputsSpec::All { }, OutputsSpec::All { });
|
|
}
|
|
|
|
TEST(OutputsSpec, union_all_names) {
|
|
TEST_UNION(OutputsSpec::All { }, OutputsSpec::All { }, OutputsSpec::Names { "a" });
|
|
}
|
|
|
|
TEST(OutputsSpec, union_names_all) {
|
|
TEST_UNION(OutputsSpec::All { }, OutputsSpec::Names { "a" }, OutputsSpec::All { });
|
|
}
|
|
|
|
TEST(OutputsSpec, union_names_names) {
|
|
TEST_UNION((OutputsSpec::Names { "a", "b" }), OutputsSpec::Names { "a" }, OutputsSpec::Names { "b" });
|
|
}
|
|
|
|
#undef TEST_UNION
|
|
|
|
#define TEST_DONT_PARSE(NAME, STR) \
|
|
TEST(ExtendedOutputsSpec, bad_ ## NAME) { \
|
|
std::optional extendedOutputsSpecOpt = \
|
|
ExtendedOutputsSpec::parseOpt(STR); \
|
|
ASSERT_FALSE(extendedOutputsSpecOpt); \
|
|
}
|
|
|
|
TEST_DONT_PARSE(carot_empty, "^")
|
|
TEST_DONT_PARSE(prefix_carot_empty, "foo^")
|
|
TEST_DONT_PARSE(garbage, "^&*()")
|
|
TEST_DONT_PARSE(double_star, "^**")
|
|
TEST_DONT_PARSE(star_first, "^*,foo")
|
|
TEST_DONT_PARSE(star_second, "^foo,*")
|
|
|
|
#undef TEST_DONT_PARSE
|
|
|
|
TEST(ExtendedOutputsSpec, defeault) {
|
|
std::string_view str = "foo";
|
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
|
ASSERT_EQ(prefix, "foo");
|
|
ExtendedOutputsSpec expected = ExtendedOutputsSpec::Default { };
|
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
|
|
}
|
|
|
|
TEST(ExtendedOutputsSpec, all) {
|
|
std::string_view str = "foo^*";
|
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
|
ASSERT_EQ(prefix, "foo");
|
|
ExtendedOutputsSpec expected = OutputsSpec::All { };
|
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
|
|
}
|
|
|
|
TEST(ExtendedOutputsSpec, out) {
|
|
std::string_view str = "foo^out";
|
|
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
|
|
ASSERT_EQ(prefix, "foo");
|
|
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");
|
|
ASSERT_EQ(prefix, "foo");
|
|
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");
|
|
ASSERT_EQ(prefix, "foo^bar");
|
|
ExtendedOutputsSpec expected = OutputsSpec::Names { "out", "bin" };
|
|
ASSERT_EQ(extendedOutputsSpec, expected);
|
|
ASSERT_EQ(std::string { prefix } + expected.to_string(), "foo^bar^bin,out");
|
|
}
|
|
|
|
|
|
#define TEST_JSON(TYPE, NAME, STR, VAL) \
|
|
\
|
|
TEST(TYPE, NAME ## _to_json) { \
|
|
using nlohmann::literals::operator "" _json; \
|
|
ASSERT_EQ( \
|
|
STR ## _json, \
|
|
((nlohmann::json) TYPE { VAL })); \
|
|
} \
|
|
\
|
|
TEST(TYPE, NAME ## _from_json) { \
|
|
using nlohmann::literals::operator "" _json; \
|
|
ASSERT_EQ( \
|
|
TYPE { VAL }, \
|
|
(STR ## _json).get<TYPE>()); \
|
|
}
|
|
|
|
TEST_JSON(OutputsSpec, all, R"(["*"])", OutputsSpec::All { })
|
|
TEST_JSON(OutputsSpec, name, R"(["a"])", OutputsSpec::Names { "a" })
|
|
TEST_JSON(OutputsSpec, names, R"(["a","b"])", (OutputsSpec::Names { "a", "b" }))
|
|
|
|
TEST_JSON(ExtendedOutputsSpec, def, R"(null)", ExtendedOutputsSpec::Default { })
|
|
TEST_JSON(ExtendedOutputsSpec, all, R"(["*"])", ExtendedOutputsSpec::Explicit { OutputsSpec::All { } })
|
|
TEST_JSON(ExtendedOutputsSpec, name, R"(["a"])", ExtendedOutputsSpec::Explicit { OutputsSpec::Names { "a" } })
|
|
TEST_JSON(ExtendedOutputsSpec, names, R"(["a","b"])", (ExtendedOutputsSpec::Explicit { OutputsSpec::Names { "a", "b" } }))
|
|
|
|
#undef TEST_JSON
|
|
|
|
#ifndef COVERAGE
|
|
|
|
RC_GTEST_PROP(
|
|
OutputsSpec,
|
|
prop_round_rip,
|
|
(const OutputsSpec & o))
|
|
{
|
|
RC_ASSERT(o == OutputsSpec::parse(o.to_string()));
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|