Repository: apollographql/apollo-rs
Pull request #134 (2021-12-08 16:30:34)

fix(apollo-parser): error when selection set is empty in operation definition
An operation definition [must have a selection set with selections](https://spec.graphql.org/October2021/#OperationDefinition), so this query `query {}` should also come with an error. This fix ensures we have this error.


Patch:
diff --git a/crates/apollo-parser/src/parser/grammar/selection.rs b/crates/apollo-parser/src/parser/grammar/selection.rs
index d3548d2..8808ae2 100644
--- a/crates/apollo-parser/src/parser/grammar/selection.rs
+++ b/crates/apollo-parser/src/parser/grammar/selection.rs
@@ -23,6 +23,8 @@ pub(crate) fn selection_set(p: &mut Parser) {
 ///     FragmentSpread
 ///     InlineFragment
 pub(crate) fn selection(p: &mut Parser) {
+    let mut has_selection = false;
+
     while let Some(node) = p.peek() {
         match node {
             T![...] => {
@@ -31,6 +33,7 @@ pub(crate) fn selection(p: &mut Parser) {
                         "on" | "{" => fragment::inline_fragment(p),
                         _ => fragment::fragment_spread(p),
                     }
+                    has_selection = true;
                 } else {
                     p.err("expected an Inline Fragment or a Fragment Spread");
                 }
@@ -40,8 +43,14 @@ pub(crate) fn selection(p: &mut Parser) {
             }
             TokenKind::Name => {
                 field::field(p);
+                has_selection = true;
+            }
+            _ => {
+                if !has_selection {
+                    p.err("exepcted at least one Selection in Selection Set");
+                }
+                break;
             }
-            _ => break,
         }
     }
 }
@@ -189,4 +198,17 @@ query GraphQuery($graph_id: ID!, $variant: String) {
             matching == a.len() && matching == b.len()
         }
     }
+
+    #[test]
+    fn it_errors_when_selection_set_is_empty() {
+        let schema = r#"
+        query($foo: Int) {}
+        "#;
+        let parser = Parser::new(schema);
+
+        let ast = parser.parse();
+
+        assert_eq!(ast.errors().len(), 1);
+        assert_eq!(ast.document().definitions().into_iter().count(), 1);
+    }
 }


Test patch:
diff --git a/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.graphql b/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.graphql
new file mode 100644
index 0000000..c7d2a3a
--- /dev/null
+++ b/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.graphql
@@ -0,0 +1,1 @@
+query {}
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.txt b/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.txt
new file mode 100644
index 0000000..d26a698
--- /dev/null
+++ b/crates/apollo-parser/test_data/parser/err/0029_operation_definition_with_empty_selection_set.txt
@@ -0,0 +1,9 @@
+- DOCUMENT@0..8
+    - OPERATION_DEFINITION@0..8
+        - OPERATION_TYPE@0..6
+            - query_KW@0..5 "query"
+            - WHITESPACE@5..6 " "
+        - SELECTION_SET@6..8
+            - L_CURLY@6..7 "{"
+            - R_CURLY@7..8 "}"
+- ERROR@7:8 "exepcted at least one Selection in Selection Set" }