summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2020-02-03 13:26:41 +0000
committerJulian Andres Klode <jak@debian.org>2020-02-03 13:26:41 +0000
commit3ee6fdc08a91ef65e5a69f8857de3bf86a8fe1ad (patch)
treed7f2bed62c67b05e01095865056634db0f9b6be7 /test
parentefc52f1fc9acb6ec815f695506bc8d5045c76834 (diff)
parent404771d0ec11f26a0b631018719e2918a049455b (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.cc139
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)");
+}