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

Refactor the unit tests for the SPARQL ANTLR parser #767

Merged
merged 27 commits into from
Sep 7, 2022

Conversation

Qup42
Copy link
Member

@Qup42 Qup42 commented Aug 28, 2022

The tests themselves are the same regarding content. The've just been changed to use the new parsing functions and Matchers.

Many matchers are now only combinations of other matchers. This has the benefit that the failure messages are much more usefull. Sometimes it wasn't possible to model the matcher as a combination of other matchers (e.g. IsSelect). I have started to provide manual failure messages in these cases.

Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, this is a great step towards simplifying the testing and for us as a group to further understand Googletest.

When you have read all the stuff I wrote, maybe we can discuss some of it in person!

test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
@@ -263,50 +290,87 @@ MATCHER_P(GroupByVariablesMatch, vars, "") {
[](auto& var, auto& var1) { return var.name() == var1; });
}

MATCHER_P2(IsValues, vars, values, "") {
auto IsValues = [](const vector<string>& vars,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some matchers above this one that are still MATCHER_P... .
Can you refactor all of them to lambdas?
As I understand it, the "base cases" all need to be builtin, non-macro matchers like testing::Field or testing::Property.

I know that this (like all of them) would incur some visual overhead, but we would be much cleaner and much easier to reason about for future refactorings.

Copy link
Member Author

@Qup42 Qup42 Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have currently refactored almost all Matchers to lambdas that are possible to refactor with my current knowledge. The problems are

  • some matchers use unwrapVariant which a custom behaviour and is not available as matcher.
  • std::equal in GroupByVariablesMatch but i think this one can just be a simple Eq matcher if the argument is set as vector<Variable> in the lambda
  • IsSelect and IsSolutionModifier are is very complex
  • IsGraphPattern should be possible to refactor with my new matcher.

test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
@Qup42
Copy link
Member Author

Qup42 commented Sep 2, 2022

A meeting also seems sensible to me. I was able to write a Matcher that takes variadic matchers and can then match a vector in the meantime. The matchers are tested one to one to the vectors elements. So 1st matcher on 1st vector elements, 2nd matcher on 2nd element, ... This would make it possible to express the GraphPattern Matcher as a lambda. It should also enable us to get rid of expectCompleteArrayParse which is the same pattern.

@Qup42
Copy link
Member Author

Qup42 commented Sep 3, 2022

It seems that clang13 does not support the features required for the usage of std::source_location: llvm/llvm-project#48230

Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really coming forward.
I think we are at the point where the tests are nice when you read the test failure,
But the actual source code can be further simplified.
I think there are some aspects that we can discuss.

test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Show resolved Hide resolved
test/SparqlAntlrParserTest.cpp Outdated Show resolved Hide resolved
@Qup42 Qup42 marked this pull request as ready for review September 5, 2022 20:02
Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice, we are almost there.
mostly just very small stuff, and one suggestion whcih we can maybe discuss in person.

src/util/SourceLocation.h Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
Comment on lines 111 to 120
expectNumericLiteral("3.0", NumericLiteralFP(3.0));
expectNumericLiteral("3.0e2", NumericLiteralFP(300.0));
expectNumericLiteral("3.0e-2", NumericLiteralFP(0.030));
expectNumericLiteral("3", NumericLiteralWhole(3ll));
expectNumericLiteral("-3.0", NumericLiteralFP(-3.0));
expectNumericLiteral("-3", NumericLiteralWhole(-3ll));
expectNumericLiteral("+3", NumericLiteralWhole(3ll));
expectNumericLiteral("+3.02", NumericLiteralFP(3.02));
expectNumericLiteral("+3.1234e12", NumericLiteralFP(3123400000000.0));
expectNumericLiteral(".234", NumericLiteralFP(0.234));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant those when you wanted to pass a matcher to the ExpectCompleteParse, s.t. this can become
expectFloat("3.0", 3.0) and expectInt(+3, 3ll).
Maybe have a look on whether this can be done easily, and contact me if there's trouble.

test/SparqlParserTest.cpp Outdated Show resolved Hide resolved
Comment on lines 112 to 118
expectNumericLiteral("3.0", m::NumericLiteralFP(3.0));
expectNumericLiteral("3.0e2", m::NumericLiteralFP(300.0));
expectNumericLiteral("3.0e-2", m::NumericLiteralFP(0.030));
expectNumericLiteral("3", m::NumericLiteralWhole(3ll));
expectNumericLiteral("-3.0", m::NumericLiteralFP(-3.0));
expectNumericLiteral("-3", m::NumericLiteralWhole(-3ll));
expectNumericLiteral("+3", m::NumericLiteralWhole(3ll));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were talking about making the EQ default matcher configurabel, s.t we can easily make this

auto expectFloat = exepectCompleteParse<&parseNumericLiteral, m::NumericLiteralFP>{};
expectFloat("3.0", 3.0)

Maybe we can talk about this in a meeting how it can be done, you basically need to make the Value a template that
requires that it is a valid argument to the DefaultMatcher.

Qup42 and others added 2 commits September 6, 2022 15:14
Co-authored-by: joka921 <joka921@users.noreply.github.com>
return blankNode->isGenerated() == generated && blankNode->label() == label;
private:
static std::string GetTypeName() {
return testing::internal::GetTypeName<ad_utility::Last<Ts...>>();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also an internal gtest function. But getting a type as a string in c++ seems to non trivial. testing::internal::GetTypeName<...>() does somewhat lowlevel stuff. I don't whether it is worth reimplementing the functionality to get rid of this.

Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok,
The very last and very simple suggestions before I will definitely merge this.

Please note, that we now use clang-format-14 for formatting, but this should make no difference for this code.

src/util/SourceLocation.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
test/SparqlAntlrParserTestHelpers.h Outdated Show resolved Hide resolved
Qup42 and others added 2 commits September 7, 2022 11:17
Co-authored-by: joka921 <joka921@users.noreply.github.com>
Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much!
This was a lot of work, but helps a great deal for cleaner testing now, as well as in the future!

@joka921 joka921 changed the title Cleanup ANTLR Tests Refactor the unit tests for the SPARQL ANTLR parser Sep 7, 2022
@joka921 joka921 merged commit f89cedb into ad-freiburg:master Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants