mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 10:23:02 -07:00
This commit is contained in:
parent
6823d54c1e
commit
276873f0bd
2 changed files with 112 additions and 17 deletions
|
|
@ -65,7 +65,7 @@ RegexMatcherString <- ('\\/' / !'/' .)+
|
||||||
FlexStringValue <- CompactStringSet / String / [(] StringList [)]
|
FlexStringValue <- CompactStringSet / String / [(] StringList [)]
|
||||||
CompactStringSet <- StringListString ([,+] StringListString)+
|
CompactStringSet <- StringListString ([,+] StringListString)+
|
||||||
|
|
||||||
SetExpression <- NumericOperator ws? String
|
SetExpression <- <NumericOperator> ws? String
|
||||||
|
|
||||||
NumericExpression <- NumericOperator ws? NumericValue
|
NumericExpression <- NumericOperator ws? NumericValue
|
||||||
NumericOperator <- [=:] / <[><!][=]?>
|
NumericOperator <- [=:] / <[><!][=]?>
|
||||||
|
|
@ -114,16 +114,8 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto matcher = std::any_cast<NumberMatcher>(sv[0]);
|
auto matcher = std::any_cast<Filter>(sv[0]);
|
||||||
return [=](const CardData &x) -> bool {
|
return matcher;
|
||||||
const auto &sets = x->getSets().values();
|
|
||||||
auto matchesSet = [&](const PrintingInfo &printing) {
|
|
||||||
return printing.getSet()->getEnabled() && matcher(printing.getSet()->getReleaseDate().toJulianDay());
|
|
||||||
};
|
|
||||||
return std::any_of(sets.begin(), sets.end(), [&](const auto &printings) {
|
|
||||||
return std::any_of(printings.begin(), printings.end(), matchesSet);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
search["Rarity"] = [](const peg::SemanticValues &sv) -> QString {
|
search["Rarity"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
switch (tolower(std::string(sv.sv())[0])) {
|
switch (tolower(std::string(sv.sv())[0])) {
|
||||||
|
|
@ -300,17 +292,57 @@ static void setupParserRules()
|
||||||
return [=](int s) { return comparer(s, arg); };
|
return [=](int s) { return comparer(s, arg); };
|
||||||
};
|
};
|
||||||
|
|
||||||
search["SetExpression"] = [](const peg::SemanticValues &sv) -> NumberMatcher {
|
search["SetExpression"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
const auto comparer = std::any_cast<NumberComparer>(sv[0]);
|
const auto comparer = std::any_cast<NumberComparer>(sv[0]);
|
||||||
const auto setCode = std::any_cast<QString>(sv[1]);
|
const auto setCode = std::any_cast<QString>(sv[1]);
|
||||||
|
const auto operatorText = QString::fromStdString(std::string(sv.token(0)));
|
||||||
|
|
||||||
|
auto printingsOf = [](const CardData &x) {
|
||||||
|
QList<PrintingInfo> printings;
|
||||||
|
for (const auto &printingsPerSet : x->getSets()) {
|
||||||
|
printings.append(printingsPerSet);
|
||||||
|
}
|
||||||
|
return printings;
|
||||||
|
};
|
||||||
|
auto isExactSet = [setCode](const PrintingInfo &printing) {
|
||||||
|
return printing.getSet()->getEnabled() &&
|
||||||
|
printing.getSet()->getShortName().compare(setCode, Qt::CaseInsensitive) == 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (operatorText == ":" || operatorText == "=") {
|
||||||
|
return [=](const CardData &x) {
|
||||||
|
const auto printings = printingsOf(x);
|
||||||
|
return std::any_of(printings.begin(), printings.end(), isExactSet);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (operatorText == "!" || operatorText == "!=") {
|
||||||
|
return [=](const CardData &x) {
|
||||||
|
const auto printings = printingsOf(x);
|
||||||
|
return std::none_of(printings.begin(), printings.end(), isExactSet);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const auto allSets = CardDatabaseManager::getInstance()->getSetList();
|
const auto allSets = CardDatabaseManager::getInstance()->getSetList();
|
||||||
for (auto &set : allSets) {
|
int releaseDate = 0;
|
||||||
if (set->getShortName() == setCode) {
|
bool setFound = false;
|
||||||
const int releaseDate = set->getReleaseDate().toJulianDay();
|
for (const auto &set : allSets) {
|
||||||
return [=](int s) { return comparer(s, releaseDate); };
|
if (set->getShortName().compare(setCode, Qt::CaseInsensitive) == 0) {
|
||||||
|
releaseDate = set->getReleaseDate().toJulianDay();
|
||||||
|
setFound = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [](int) { return false; };
|
if (!setFound) {
|
||||||
|
return [](const CardData &) { return false; };
|
||||||
|
}
|
||||||
|
auto matchesReleaseDate = [comparer, releaseDate](const PrintingInfo &printing) {
|
||||||
|
return printing.getSet()->getEnabled() &&
|
||||||
|
comparer(printing.getSet()->getReleaseDate().toJulianDay(), releaseDate);
|
||||||
|
};
|
||||||
|
return [=](const CardData &x) {
|
||||||
|
const auto printings = printingsOf(x);
|
||||||
|
return std::any_of(printings.begin(), printings.end(), matchesReleaseDate);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
search["NormalMatcher"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
search["NormalMatcher"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#include "test_card_database_path_provider.h"
|
#include "test_card_database_path_provider.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include <libcockatrice/card/card_info.h>
|
||||||
|
#include <libcockatrice/card/printing/printing_info.h>
|
||||||
#include <libcockatrice/filters/filter_string.h>
|
#include <libcockatrice/filters/filter_string.h>
|
||||||
#include <libcockatrice/interfaces/noop_card_preference_provider.h>
|
#include <libcockatrice/interfaces/noop_card_preference_provider.h>
|
||||||
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
||||||
|
|
@ -71,10 +73,71 @@ QUERY(Color2, cat, "c:gw", true)
|
||||||
QUERY(Color3, cat, "c!g", true)
|
QUERY(Color3, cat, "c!g", true)
|
||||||
QUERY(Color4, cat, "c!gw", false)
|
QUERY(Color4, cat, "c!gw", false)
|
||||||
|
|
||||||
|
QUERY(SetCodeCaseInsensitive1, cat, "set:cat", true)
|
||||||
|
QUERY(SetCodeCaseInsensitive2, cat, "set:CAT", true)
|
||||||
|
QUERY(SetCodeCaseInsensitive3, cat, "set:CAt", true)
|
||||||
|
QUERY(SetCodeShortForm, cat, "e:cat", true)
|
||||||
|
QUERY(SetCodeWrongSet, cat, "set:who", false)
|
||||||
|
QUERY(SetCodeWrongSet2, doctor, "set:cat", false)
|
||||||
|
|
||||||
QUERY(BracketNextToUnquotedString, cat, "(o:woof OR o:meow)", true)
|
QUERY(BracketNextToUnquotedString, cat, "(o:woof OR o:meow)", true)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
class SetQuery : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
// EOE and EOC share a release date, like a set and its Commander counterpart.
|
||||||
|
const QDate sharedReleaseDate(2026, 3, 13);
|
||||||
|
mainSet = CardSet::newInstance(&controller, "EOE", "Edge of Eternities", "expansion", sharedReleaseDate,
|
||||||
|
CardSet::PriorityPrimary);
|
||||||
|
commanderSet = CardSet::newInstance(&controller, "EOC", "Edge of Eternities Commander", "commander",
|
||||||
|
sharedReleaseDate, CardSet::PrioritySecondary);
|
||||||
|
|
||||||
|
inBothSets = newCardWithPrintings({{"EOE", mainSet}, {"EOC", commanderSet}});
|
||||||
|
onlyInCommanderSet = newCardWithPrintings({{"EOC", commanderSet}});
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr newCardWithPrintings(const QList<QPair<QString, CardSetPtr>> &printings)
|
||||||
|
{
|
||||||
|
SetToPrintingsMap setsInfo;
|
||||||
|
for (const auto &printing : printings) {
|
||||||
|
setsInfo[printing.first].append(PrintingInfo(printing.second));
|
||||||
|
}
|
||||||
|
return CardInfo::newInstance("Test Card", "", false, {}, {}, {}, setsInfo, CardInfo::UiAttributes());
|
||||||
|
}
|
||||||
|
|
||||||
|
NoopCardSetPriorityController controller;
|
||||||
|
CardSetPtr mainSet;
|
||||||
|
CardSetPtr commanderSet;
|
||||||
|
CardInfoPtr inBothSets;
|
||||||
|
CardInfoPtr onlyInCommanderSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(SetQuery, ExactMatchSeparatesSameDaySets)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(FilterString("set:EOE").check(inBothSets));
|
||||||
|
EXPECT_TRUE(FilterString("e:EOE").check(inBothSets));
|
||||||
|
EXPECT_TRUE(FilterString("set:EOC").check(inBothSets));
|
||||||
|
EXPECT_FALSE(FilterString("set:EOE").check(onlyInCommanderSet));
|
||||||
|
EXPECT_TRUE(FilterString("set:EOC").check(onlyInCommanderSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SetQuery, ExactMatchIsCaseInsensitive)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(FilterString("set:eoe").check(inBothSets));
|
||||||
|
EXPECT_TRUE(FilterString("set:EoE").check(inBothSets));
|
||||||
|
EXPECT_FALSE(FilterString("set:eoe").check(onlyInCommanderSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SetQuery, NotEqualsMatchesPrintingsOutsideTheSet)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(FilterString("set!EOE").check(inBothSets));
|
||||||
|
EXPECT_TRUE(FilterString("set!EOE").check(onlyInCommanderSet));
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue