diff options
author | Julian Andres Klode <jak@debian.org> | 2020-02-03 13:26:41 +0000 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2020-02-03 13:26:41 +0000 |
commit | 3ee6fdc08a91ef65e5a69f8857de3bf86a8fe1ad (patch) | |
tree | d7f2bed62c67b05e01095865056634db0f9b6be7 /test | |
parent | efc52f1fc9acb6ec815f695506bc8d5045c76834 (diff) | |
parent | 404771d0ec11f26a0b631018719e2918a049455b (diff) |
Merge branch 'pu/short-patterns' into 'master'
Implement short patterns
See merge request apt-team/apt!100
Diffstat (limited to 'test')
-rw-r--r-- | test/libapt/pattern_test.cc | 139 |
1 files changed, 133 insertions, 6 deletions
diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc index de2fbceb9..bfcaf2093 100644 --- a/test/libapt/pattern_test.cc +++ b/test/libapt/pattern_test.cc @@ -14,21 +14,53 @@ using namespace APT::Internal; +#define EXPECT_EXCEPTION(exp, exc, msg) \ + caught = false; \ + try \ + { \ + exp; \ + } \ + catch (exc & e) \ + { \ + caught = true; \ + EXPECT_TRUE(e.message.find(msg) != std::string::npos) << msg << " not in " << e.message; \ + }; \ + EXPECT_TRUE(caught) << #exp "should have thrown an exception" + +TEST(TreeParserTest, ParseInvalid) +{ + bool caught = false; + + // Not a valid pattern: Reject + EXPECT_EXCEPTION(PatternTreeParser("?").parse(), PatternTreeParser::Error, "Pattern must have a term"); + EXPECT_EXCEPTION(PatternTreeParser("?AB?").parse(), PatternTreeParser::Error, "Pattern must have a term"); + EXPECT_EXCEPTION(PatternTreeParser("~").parse(), PatternTreeParser::Error, "Unknown short pattern"); + + // Not a pattern at all: Report nullptr + EXPECT_EQ(PatternTreeParser("A?").parse(), nullptr); +} + TEST(TreeParserTest, ParseWord) { - auto node = PatternTreeParser("word").parseTop(); - auto wordNode = dynamic_cast<PatternTreeParser::WordNode *>(node.get()); + auto node = PatternTreeParser("?word(word)").parseTop(); + auto patternNode = dynamic_cast<PatternTreeParser::PatternNode *>(node.get()); - EXPECT_EQ(node.get(), wordNode); + ASSERT_EQ(patternNode->arguments.size(), 1u); + auto wordNode = dynamic_cast<PatternTreeParser::WordNode *>(patternNode->arguments[0].get()); + + EXPECT_EQ(patternNode->arguments[0].get(), wordNode); EXPECT_EQ(wordNode->word, "word"); } TEST(TreeParserTest, ParseQuotedWord) { - auto node = PatternTreeParser("\"a word\"").parseTop(); - auto wordNode = dynamic_cast<PatternTreeParser::WordNode *>(node.get()); + auto node = PatternTreeParser("?word(\"a word\")").parseTop(); + auto patternNode = dynamic_cast<PatternTreeParser::PatternNode *>(node.get()); - EXPECT_EQ(node.get(), wordNode); + ASSERT_EQ(patternNode->arguments.size(), 1u); + auto wordNode = dynamic_cast<PatternTreeParser::WordNode *>(patternNode->arguments[0].get()); + + EXPECT_EQ(patternNode->arguments[0].get(), wordNode); EXPECT_EQ(wordNode->word, "a word"); } @@ -93,3 +125,98 @@ TEST(TreeParserTest, ParseWithManyArgsWithSpacesWithTrailingComma) EXPECT_EQ(patternNode->term, "?hello"); EXPECT_EQ(2u, patternNode->arguments.size()); } + +// Helper +static bool samePattern(const std::unique_ptr<PatternTreeParser::Node> &a, const std::unique_ptr<PatternTreeParser::Node> &b) +{ + auto pa = dynamic_cast<const PatternTreeParser::PatternNode *>(a.get()); + auto pb = dynamic_cast<const PatternTreeParser::PatternNode *>(b.get()); + + if (pa && pb) + { + if (pa->term != pb->term || pa->haveArgumentList != pb->haveArgumentList || pa->arguments.size() != pb->arguments.size()) + return false; + + for (size_t i = 0; i < pa->arguments.size(); i++) + { + if (!samePattern(pa->arguments[i], pb->arguments[i])) + return false; + } + return true; + } + + auto wa = dynamic_cast<const PatternTreeParser::WordNode *>(a.get()); + auto wb = dynamic_cast<const PatternTreeParser::WordNode *>(b.get()); + if (wa && wb) + return wa->word == wb->word && wa->quoted == wb->quoted; + + return false; +} + +#define EXPECT_PATTERN_EQ(shrt, lng) \ + EXPECT_TRUE(samePattern(PatternTreeParser(shrt).parseTop(), PatternTreeParser(lng).parseTop())) +#define EXPECT_PATTERN_EQ_ATOMIC(shrt, lng) \ + EXPECT_TRUE(PatternTreeParser(shrt).parseTop()); \ + caught = false; \ + try \ + { \ + PatternTreeParser(shrt "XXX").parseTop(); \ + } \ + catch (PatternTreeParser::Error & e) \ + { \ + caught = true; \ + }; \ + EXPECT_TRUE(caught) << shrt "XXX should have thrown an exception"; \ + EXPECT_PATTERN_EQ(shrt, lng) + +TEST(TreeParserTest, ParseShortPattern) +{ + bool caught; + EXPECT_PATTERN_EQ("~ramd64", "?architecture(amd64)"); + EXPECT_PATTERN_EQ("~AanArchive", "?archive(anArchive)"); + EXPECT_PATTERN_EQ_ATOMIC("~M", "?automatic"); + EXPECT_PATTERN_EQ_ATOMIC("~b", "?broken"); + EXPECT_PATTERN_EQ_ATOMIC("~c", "?config-files"); + EXPECT_PATTERN_EQ_ATOMIC("~E", "?essential"); + EXPECT_PATTERN_EQ_ATOMIC("~F", "?false"); + EXPECT_PATTERN_EQ_ATOMIC("~g", "?garbage"); + EXPECT_PATTERN_EQ_ATOMIC("~i", "?installed"); + EXPECT_PATTERN_EQ("~napt", "?name(apt)"); + EXPECT_PATTERN_EQ_ATOMIC("~o", "?obsolete"); + EXPECT_PATTERN_EQ("~Obar", "?origin(bar)"); + EXPECT_PATTERN_EQ("~sfoo", "?section(foo)"); + EXPECT_PATTERN_EQ("~esourcename", "?source-package(sourcename)"); + EXPECT_PATTERN_EQ_ATOMIC("~T", "?true"); + EXPECT_PATTERN_EQ_ATOMIC("~U", "?upgradable"); + EXPECT_PATTERN_EQ("~Vverstr", "?version(verstr)"); + EXPECT_PATTERN_EQ_ATOMIC("~v", "?virtual"); + EXPECT_PATTERN_EQ("!?foo", "?not(?foo)"); + + caught = false; + try + { + PatternTreeParser("!x").parseTop(); + } + catch (PatternTreeParser::Error &e) + { + caught = true; + }; + EXPECT_TRUE(caught) << "!X should have thrown an exception"; + + EXPECT_PATTERN_EQ("?a?b", "?and(?a, ?b)"); + EXPECT_PATTERN_EQ("~T~F", "?and(?true, ?false)"); + EXPECT_PATTERN_EQ("~T ~F", "?and(?true, ?false)"); + EXPECT_PATTERN_EQ("~T !~F", "?and(?true, ?not(?false))"); + EXPECT_PATTERN_EQ("!~F ~T", "?and(?not(?false), ?true)"); + EXPECT_PATTERN_EQ("!~F~T", "?and(?not(?false), ?true)"); + + EXPECT_PATTERN_EQ("!~F~T | ~T", "?or(?and(?not(?false), ?true), ?true)"); + EXPECT_PATTERN_EQ("~ramd64|~rall", "?or(?architecture(amd64), ?architecture(all))"); + EXPECT_PATTERN_EQ("~ramd64 | ~rall", "?or(?architecture(amd64), ?architecture(all))"); + EXPECT_PATTERN_EQ("~ramd64?name(foo)", "?and(?architecture(amd64), ?name(foo))"); + + EXPECT_PATTERN_EQ("(?A|?B)?C", "?and(?or(?A, ?B), ?C)"); + EXPECT_PATTERN_EQ("?A|?B?C", "?or(?A, ?and(?B, ?C))"); + EXPECT_PATTERN_EQ("?A|(?B?C)", "?or(?A, ?and(?B, ?C))"); + EXPECT_PATTERN_EQ("(?B?C)|?A", "?or(?and(?B, ?C), ?A)"); +} |