Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement tests for construct query parsing #540

Merged
merged 27 commits into from
Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ffc44b1
Bump googletest and allow use of gmock
RobinTF Jan 13, 2022
6f0ed16
Implement some initial tests
RobinTF Jan 13, 2022
3217352
Formatting
RobinTF Jan 13, 2022
02619fe
Fix compile errors
RobinTF Jan 13, 2022
394da1c
Use ::testing::ElementsAre to group matchers
RobinTF Jan 14, 2022
d7a0938
Refactor classes to provide direct access to members
RobinTF Jan 14, 2022
d24d62f
Tidy up metaprogramming
RobinTF Jan 14, 2022
fef8e0c
Add tests for collections and graphTerm
RobinTF Jan 16, 2022
4c9e03f
Enhance test tooling and introduce blanknode tests
RobinTF Jan 17, 2022
d630975
Enhance metaprogramming
RobinTF Jan 18, 2022
b32bd40
Implement parsing tests
RobinTF Jan 18, 2022
8437248
Add basic unit tests for data type parsing
RobinTF Jan 23, 2022
463828c
Implement tests for Literal, Iri and BlankNode types
RobinTF Jan 23, 2022
c58af5f
Add final tests for variables
RobinTF Jan 23, 2022
153a863
Prefer using directives for commonly used gmock matchers
RobinTF Jan 23, 2022
1745a55
Rename generated() -> isGenerated()
RobinTF Jan 24, 2022
c3e18cf
Extract common concept
RobinTF Jan 24, 2022
5e0b030
Tidy up test syntax
RobinTF Jan 24, 2022
9519935
Adjust documentation
RobinTF Jan 24, 2022
780e1d1
Remove references
RobinTF Jan 24, 2022
5c1db18
Move metaprogramming templates to type_traits
RobinTF Jan 24, 2022
5dbca1c
Use different variables for more robust tests
RobinTF Jan 24, 2022
bac72dc
Merge remote-tracking branch 'ad-freiburg/master' into construct-tests
RobinTF Jan 24, 2022
bdd1054
Fix formatting
RobinTF Jan 24, 2022
98fee12
Introduce ad_utillity namespace for Concept
RobinTF Jan 25, 2022
2ed3300
Add documentation
RobinTF Jan 25, 2022
1ca1de0
Fix formatting
RobinTF Jan 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")

################################
# GTEST
# GTEST AND GMOCK
################################
add_subdirectory(third_party/googletest/googletest EXCLUDE_FROM_ALL)
add_subdirectory(third_party/googletest EXCLUDE_FROM_ALL)
include_directories(third_party/googletest/googletest/include)
include_directories(third_party/googletest/googlemock/include)

################################
# NLOHNMANN-JSON
Expand Down
2 changes: 1 addition & 1 deletion src/parser/SparqlParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void SparqlParser::parseQuery(ParsedQuery* query, QueryType queryType) {
for (const auto& triple : constructClause) {
for (const auto& varOrTerm : triple) {
if (auto variable = std::get_if<Variable>(&varOrTerm)) {
const auto& var = variable->getName();
const auto& var = variable->name();
if (std::find(query->_groupByVariables.begin(),
query->_groupByVariables.end(),
var) == query->_groupByVariables.end()) {
Expand Down
15 changes: 14 additions & 1 deletion src/parser/data/BlankNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@ class BlankNode {

public:
BlankNode(bool generated, std::string label)
: _generated{generated}, _label{std::move(label)} {}
: _generated{generated}, _label{std::move(label)} {
// roughly check allowed characters as blank node labels.
// Weaker than the SPARQL grammar, but good
// enough so that it will likely never be an issue
AD_CHECK(ctre::match<"\\w(?:(?:\\w|-|\\.)*\\w)?">(_label));
}

// ___________________________________________________________________________
// Used for testing
[[nodiscard]] bool isGenerated() const { return _generated; }

// ___________________________________________________________________________
// Used for testing
[[nodiscard]] const std::string& label() const { return _label; }

// ___________________________________________________________________________
[[nodiscard]] std::optional<std::string> evaluate(
Expand Down
9 changes: 6 additions & 3 deletions src/parser/data/Iri.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ class Iri {

public:
explicit Iri(std::string str) : _string{std::move(str)} {
AD_CHECK(ctre::match<
"(?:@[a-zA-Z]+(?:-(?:[a-zA-Z]|\\d)+)*@)?(?:<.+>|[^:]+:[^:]+)">(
_string));
AD_CHECK(ctre::match<"(?:@[a-zA-Z]+(?:-(?:[a-zA-Z]|\\d)+)*@)?"
"<[^<>\"{}|^\\\\`\\0- ]*>">(_string));
}

// ___________________________________________________________________________
// Used for testing
[[nodiscard]] const std::string& iri() const { return _string; }

// ___________________________________________________________________________
[[nodiscard]] std::optional<std::string> evaluate(
[[maybe_unused]] const Context& context,
Expand Down
23 changes: 20 additions & 3 deletions src/parser/data/Literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,36 @@
#include <sstream>
#include <string>

#include "../../util/Concepts.h"

class Literal {
std::string _stringRepresentation;

template <typename T>
template <Streamable T>
static std::string toString(const T& t) {
std::ostringstream stream;
stream << t;
return stream.str();
}

static std::string toString(bool boolean) {
return boolean ? "true" : "false";
}

public:
explicit Literal(auto&& t)
: _stringRepresentation(toString(std::forward<decltype(t)>(t))) {}
template <Streamable T>
explicit Literal(T&& t)
: _stringRepresentation(toString(std::forward<T>(t))) {}

static_assert(!Streamable<Literal>,
"If Literal satisfies the Streamable concept, copy and move "
"constructors are hidden, leading to unexpected behaviour");

// ___________________________________________________________________________
// Used for testing
[[nodiscard]] const std::string& literal() const {
return _stringRepresentation;
}

RobinTF marked this conversation as resolved.
Show resolved Hide resolved
// ___________________________________________________________________________
[[nodiscard]] std::optional<std::string> evaluate(
Expand Down
14 changes: 6 additions & 8 deletions src/parser/data/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ class Variable {

public:
explicit Variable(std::string name) : _name{std::move(name)} {
// Verify variable name is not empty
AD_CHECK(_name.length() > 1);
// verify variable name starts with ? or $ and continues without any
// special characters. This is weaker than the SPARQL grammar,
// but it is close enough so that it will likely never cause issues.
AD_CHECK(ctre::match<"[$?]\\w+">(_name));
// normalise notation for consistency
if (_name[0] == '$') {
_name[0] = '?';
}
// variables have to start with ?
AD_CHECK(_name[0] == '?');
_name[0] = '?';
}

// ___________________________________________________________________________
Expand Down Expand Up @@ -77,5 +75,5 @@ class Variable {
[[nodiscard]] std::string toSparql() const { return _name; }

// ___________________________________________________________________________
[[nodiscard]] const std::string& getName() const { return _name; }
[[nodiscard]] const std::string& name() const { return _name; }
};
16 changes: 16 additions & 0 deletions src/util/Concepts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2022, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Robin Textor-Falconi (textorr@informatik.uni-freiburg.de)

#pragma once

#include <sstream>

/**
* A concept to ensure objects can be formatted by std::ostream.
* @tparam T The Type to be formatted
*/
template <typename T>
concept Streamable = requires(T x, std::ostream& os) {
os << x;
};
21 changes: 18 additions & 3 deletions src/util/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ struct TupleToVariantImpl<std::tuple<Ts...>> {
using type = std::variant<Ts...>;
};

template <typename, typename... Ts>
struct LastT : LastT<Ts...> {};

template <typename T>
struct LastT<T> : public std::type_identity<T> {};

template <typename T, typename...>
struct FirstWrapper : public std::type_identity<T> {};

} // namespace detail

/// isInstantiation<SomeTemplate, SomeType> is true iff `SomeType` is an
Expand Down Expand Up @@ -97,9 +106,9 @@ constexpr static bool isTypeContainedIn<T, std::variant<Ts...>> = (... || isSimi
template <typename T, typename... Ts>
constexpr static bool isTypeContainedIn<T, std::pair<Ts...>> = (... || isSimilar<T, Ts>);

/// A templated bool that is always false, independent of the template parameter
/// T.
template <typename T>
/// A templated bool that is always false,
/// independent of the template parameter.
template <typename>
constexpr static bool alwaysFalse = false;

/// From the type Tuple (std::tuple<A, B, C....>) creates the type
Expand Down Expand Up @@ -159,4 +168,10 @@ auto applyFunctionToEachElementOfTuple(Function&& f, Tuple&& tuple) {
return std::apply(transformer, std::forward<Tuple>(tuple));
}

template <typename... Ts>
using Last = typename detail::LastT<Ts...>::type;

template <typename... Ts>
using First = typename detail::FirstWrapper<Ts...>::type;

} // namespace ad_utility
10 changes: 1 addition & 9 deletions src/util/streamable_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,12 @@

// Coroutines are still experimental in clang libcpp, therefore
// adapt the appropriate namespaces using the convenience header.
#include "./Concepts.h"
#include "./Coroutines.h"
#include "./ostringstream.h"

namespace ad_utility::stream_generator {

/**
* A concept to ensure objects can be formatted by std::ostream.
* @tparam T The Type to be formatted
*/
template <typename T>
concept Streamable = requires(T x, std::ostream& os) {
os << x;
};

template <size_t MIN_BUFFER_SIZE>
class basic_stream_generator;

Expand Down
6 changes: 5 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ target_link_libraries(SortPerformanceEstimatorTest gtest_main SortPerformanceEst
#add_test(SortPerformanceEstimatorTest SortPerformanceEstimatorTest)

add_executable(SparqlAntlrParserTest SparqlAntlrParserTest.cpp)
target_link_libraries(SparqlAntlrParserTest gtest_main parser sparqlExpressions ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(SparqlAntlrParserTest gmock_main parser sparqlExpressions ${CMAKE_THREAD_LIBS_INIT})
add_test(SparqlAntlrParserTest SparqlAntlrParserTest)

add_executable(SerializerTest SerializerTest.cpp)
Expand Down Expand Up @@ -220,3 +220,7 @@ add_test(RdfEscapingTest RdfEscapingTest)
add_executable(CompactStringVectorTest CompactStringVectorTest.cpp)
target_link_libraries(CompactStringVectorTest gtest_main ${CMAKE_THREAD_LIBS_INIT})
add_test(CompactStringVectorTest CompactStringVectorTest)

add_executable(SparqlDataTypesTest SparqlDataTypesTest.cpp)
target_link_libraries(SparqlDataTypesTest gmock_main engine ${CMAKE_THREAD_LIBS_INIT})
add_test(SparqlDataTypesTest SparqlDataTypesTest)