diff --git a/src/engine/ExportQueryExecutionTrees.cpp b/src/engine/ExportQueryExecutionTrees.cpp index eb25b7e6e..676e8814b 100644 --- a/src/engine/ExportQueryExecutionTrees.cpp +++ b/src/engine/ExportQueryExecutionTrees.cpp @@ -12,11 +12,13 @@ #include "util/ConstexprUtils.h" #include "util/http/MediaTypes.h" -bool getResultForAsk(const std::shared_ptr& res) { - if (res->isFullyMaterialized()) { - return !res->idTable().empty(); +// Return true iff the `result` is nonempty. +bool getResultForAsk(const std::shared_ptr& result) { + if (result->isFullyMaterialized()) { + return !result->idTable().empty(); } else { - return std::ranges::any_of(res->idTables(), std::not_fn(&IdTable::empty)); + return std::ranges::any_of(result->idTables(), + std::not_fn(&IdTable::empty)); } } @@ -52,6 +54,7 @@ ad_utility::streams::stream_generator computeResultForAsk( j["head"] = nlohmann::json::object_t{}; j["boolean"] = result; co_yield j.dump(); + break; } default: throw std::runtime_error{ @@ -835,7 +838,7 @@ ExportQueryExecutionTrees::computeResultAsQLeverJSON( jsonPrefix["selected"] = std::vector{"?subject", "?predicate", "?object"}; } else { - // TODO Assert that this is an ASK clause. + AD_CORRECTNESS_CHECK(query.hasAskClause()); jsonPrefix["selected"] = std::vector{"?result"}; } diff --git a/test/ExportQueryExecutionTreesTest.cpp b/test/ExportQueryExecutionTreesTest.cpp index 96a0a3b7c..81408161f 100644 --- a/test/ExportQueryExecutionTreesTest.cpp +++ b/test/ExportQueryExecutionTreesTest.cpp @@ -89,6 +89,8 @@ struct TestCaseSelectQuery { std::string resultXml; }; +// A test case that tests the correct execution and exporting of an ASK query +// in various formats. struct TestCaseAskQuery { std::string kg; // The knowledge graph (TURTLE) std::string query; // The query (SPARQL) @@ -100,15 +102,6 @@ struct TestCaseAskQuery { std::string resultXml; }; -// TODO setup one test case for the ASK -> true and one for the ASK -> -// false case and use them for unit testing. -/* -TestCaseAskQuery askResultTrue() { - TestCaseAskQuery testCase; - testCase.resultQLeverJSON = nlohmann::json::parse("[]"); -} - */ - struct TestCaseConstructQuery { std::string kg; // The knowledge graph (TURTLE) std::string query; // The query (SPARQL) @@ -176,7 +169,7 @@ void runConstructQueryTestCase( void runAskQueryTestCase( const TestCaseAskQuery& testCase, ad_utility::source_location l = ad_utility::source_location::current()) { - auto trace = generateLocationTrace(l, "runConstructQueryTestCase"); + auto trace = generateLocationTrace(l, "runAskQueryTestCase"); using enum ad_utility::MediaType; // TODO match the exception EXPECT_ANY_THROW(runQueryStreamableResult(testCase.kg, testCase.query, tsv)); @@ -1222,6 +1215,40 @@ TEST(ExportQueryExecutionTrees, CornerCases) { ::testing::ContainsRegex("should be unreachable")); } +// Test the correct exporting of ASK queries. +TEST(ExportQueryExecutionTrees, AskQuery) { + auto askResultTrue = []() { + TestCaseAskQuery testCase; + testCase.query = "ASK { BIND (3 as ?x) FILTER (?x > 0)}"; + testCase.resultQLeverJSON = nlohmann::json{std::vector{ + "\"true\"^^"}}; + testCase.resultSparqlJSON = + nlohmann::json::parse(R"({"head":{ }, "boolean" : true})"); + testCase.resultXml = + "\n\n \n " + "true\n"; + + return testCase; + }; + + auto askResultFalse = []() { + TestCaseAskQuery testCase; + testCase.query = "ASK { BIND (3 as ?x) FILTER (?x < 0)}"; + testCase.resultQLeverJSON = nlohmann::json{std::vector{ + "\"false\"^^"}}; + testCase.resultSparqlJSON = + nlohmann::json::parse(R"({"head":{ }, "boolean" : false})"); + testCase.resultXml = + "\n\n \n " + "false\n"; + return testCase; + }; + runAskQueryTestCase(askResultTrue()); + runAskQueryTestCase(askResultFalse()); +} + using enum ad_utility::MediaType; // ____________________________________________________________________________