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

Block strings are parsed like non-block strings #609

Closed
SimonSapin opened this issue Aug 3, 2023 · 0 comments · Fixed by #633
Closed

Block strings are parsed like non-block strings #609

SimonSapin opened this issue Aug 3, 2023 · 0 comments · Fixed by #633
Assignees
Labels
apollo-parser bug Something isn't working

Comments

@SimonSapin
Copy link
Contributor

Description

Both in the lexer and in the impl From<&'_ ast::StringValue> for String conversion, block strings and "normal" string literals are treated the same except for the number of double-quote delimiters. Block strings should accept different escape sequences (only \"""), remove leading/trailing empty lines, and remove common indent.

https://spec.graphql.org/October2021/#sec-String-Value.Semantics

Steps to reproduce

crates/apollo-parser/src/ast/node_ext.rs

#[cfg(test)]
mod tests {
    use crate::ast;
    use crate::Parser;

    #[test]
    fn test_block_string_1() {
        let input = r#"
            query ($arg: Int!) {
                field(
                    block_string: """
                          other\n\"""

                        \"text\" 
                    """
                )
            }
        "#;
        let values = extract_argument_values(input);
        let ast::Value::StringValue(block_string) = &values[0] else { panic!() };

        // Removed: common indent of non-empty lines, leading/trailing empty lines,
        // but not trailing space of a non-empty line
        // Unescaped: `\"""` only
        assert_eq!(
            String::try_from(block_string).as_deref(),
            Ok(r#"  other\n"""

\"text\" "#)
        );
    }

    #[test]
    fn test_block_string_2() {
        let input = r#"
            query ($arg: Int!) {
                field(
                    block_string: """\""""""
                )
            }
        "#;
        let values = extract_argument_values(input);
        let ast::Value::StringValue(block_string) = &values[0] else { panic!() };
        assert_eq!(String::try_from(block_string).as_deref(), Ok(r#"""""#));
    }

    fn extract_argument_values(input: &str) -> Vec<ast::Value> {
        let ast = Parser::new(input).parse();
        assert_eq!(ast.errors().as_slice(), []);
        let ast::Definition::OperationDefinition(operation) = ast
            .document()
            .definitions()
            .next()
            .unwrap()
        else { panic!("expected an operation") };
        let ast::Selection::Field(field) = operation
            .selection_set()
            .unwrap()
            .selections()
            .next()
            .unwrap()
        else { panic!("expected a field") };
        field
            .arguments()
            .unwrap()
            .arguments()
            .map(|arg| arg.value().unwrap())
            .collect()
    }
}

Expected result

Tests pass

Actual result

---- ast::node_ext::tests::test_block_string_2 stdout ----
thread 'ast::node_ext::tests::test_block_string_2' panicked at 'assertion failed: `(left == right)`
  left: `[ERROR@142:142 "expected R_PAREN, got EOF" EOF, ERROR@142:142 "expected R_CURLY, got EOF" EOF]`,
 right: `[]`', crates/apollo-parser/src/ast/node_ext.rs:333:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- ast::node_ext::tests::test_block_string_1 stdout ----
thread 'ast::node_ext::tests::test_block_string_1' panicked at 'assertion failed: `(left == right)`
  left: `Ok("\n                          other\n\"\"\"\n\n                        \"text\" \n                    ")`,
 right: `Ok("  other\\n\"\"\"\n\n\\\"text\\\" ")`', crates/apollo-parser/src/ast/node_ext.rs:309:9

Environment

  • apollo-rs crate: apollo-parser
  • Crate version: current main, 126816f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apollo-parser bug Something isn't working
Projects
None yet
2 participants