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

Test for parse(unparse(parse()) is identity #129

Merged
merged 4 commits into from
Dec 11, 2022

Conversation

alamb
Copy link
Contributor

@alamb alamb commented Dec 10, 2022

Follow on to #127

Here is a proposed method for testing that parsing the results of unparsing are the same records.

@@ -137,6 +137,35 @@ pub enum Record {
Injected(Injected),
}

/// Newtype that allows comparing a RegEx
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not a super fan of this, but I can't think of any better way to implement PartialEq in a more maintainable way.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That seems to have worked well 👍

/// Replaces the actual filename in all Records with
/// "__FILENAME__" so different files with the same contents can
/// compare equal
fn normalize_filename(records: Vec<Record>) -> Vec<Record> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am also not a super fan of this patter either, but it is what I can come up with

Copy link
Member

Choose a reason for hiding this comment

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

What about using derivative crate to ignore a field when comparing? https://mcarton.github.io/rust-derivative/latest/cmp.html#ignoring-a-field

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll give it a try 👍

@alamb alamb force-pushed the alamb/test_reparse branch from 1a66f68 to b5d6008 Compare December 10, 2022 21:11
@alamb
Copy link
Contributor Author

alamb commented Dec 10, 2022

@xxchan if you are OK with this approach, I'll add tests for the other example files as a follow on PR

@@ -679,6 +712,34 @@ mod tests {
UsefulDiffDisplay(&changeset),
output_contents,
);

Copy link
Member

Choose a reason for hiding this comment

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

IMHO if unparse(parse()) is identity (i.e., the above assert passed), then parse(unparse(parse())) isn't necessary. Should we remove the assert above? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 I really like it :) But I can remove it if you prefer

Copy link
Member

@xxchan xxchan Dec 10, 2022

Choose a reason for hiding this comment

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

I don't dislike it, but I proposed parse(unparse(parse())) just becasue parse_roundtrip can fail in such cases.

        // Technically this will not always be the same due to some whitespace normalization
        //
        // query   III
        // select * from foo;
        // ----
        // 1 2
        //
        // Will print out collaposting the spaces between `query`
        //
        // query III
        // select * from foo;
        // ----
        // 1 2

If we don't care or test that case, I think we don't even need to test parse(unparse(parse())) at all. The old one is enough.. 🤪 How do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For my usecase downstream apache/datafusion#4570, just need the parse(unparse(parse())) guarantee.

I don't really need the parse_roundtrip guarantee. It would be nice if the results of printing a Record will look pretty close to its input so that the "test script completion mode" is minimally disruptive to the rest of the records

Thus I think I will try add specific tests for reprinting certain records and change the tests for parsing the example files to ensure that the files survive roundtrip

@alamb alamb force-pushed the alamb/test_reparse branch from 8fae6dc to 968de75 Compare December 11, 2022 10:16
@@ -10,6 +10,7 @@ description = "Sqllogictest parser and runner."

[dependencies]
async-trait = "0.1"
derivative = "2.2.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use derivative as suggested by @xxchan

@@ -81,6 +81,7 @@ pub enum Record {
conditions: Vec<Condition>,
/// The SQL command is expected to fail with an error messages that matches the given
/// regex. If the regex is an empty string, any error message is accepted.
#[derivative(PartialEq(compare_with = "cmp_regex"))]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 much nicer

parse_roundtrip("../examples/validator/validator.slt")
}

/// Verifies Display impl is consistent with parsing by ensuring
Copy link
Contributor Author

@alamb alamb Dec 11, 2022

Choose a reason for hiding this comment

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

Removed the "display roundtrip check" (I will try and propose a more specific test in a follow on PR)

@xxchan xxchan merged commit 46752d1 into risinglightdb:main Dec 11, 2022
@alamb alamb deleted the alamb/test_reparse branch December 12, 2022 21:51
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.

2 participants