use crate::ast;
use crate::tests::utils::parse_executable;
use crate::token::GraphQLTriviaToken;
#[test]
fn trivia_whitespace_between_tokens() {
let source = "query { field }";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
let ss_syntax = op.selection_set.syntax.as_ref().unwrap();
let open_brace = &ss_syntax.braces.open;
let has_ws = open_brace.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { value, .. } if value == " ")
});
assert!(has_ws, "Open brace should have double-space whitespace trivia");
if let ast::Selection::Field(field) = &op.selection_set.selections[0] {
let name_syntax = field.name.syntax.as_ref().unwrap();
let has_ws = name_syntax.token.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { value, .. } if value == " ")
});
assert!(
has_ws,
"Field name token should have double-space whitespace trivia",
);
} else {
panic!("Expected a Field selection");
}
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_newlines() {
let source = "query {\n field\n}";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
if let ast::Selection::Field(field) = &op.selection_set.selections[0] {
let name_syntax = field.name.syntax.as_ref().unwrap();
let has_newline_ws = name_syntax.token.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { value, .. } if value == "\n ")
});
assert!(
has_newline_ws,
"Field name token should have \"\\n \" whitespace trivia",
);
} else {
panic!("Expected a Field selection");
}
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_comment_captured() {
let source = "# comment\nquery { f }";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
let op_syntax = op.syntax.as_ref().unwrap();
let kw = op_syntax.operation_keyword.as_ref().unwrap();
let has_comment = kw.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Comment { value, .. } if value == " comment")
});
assert!(
has_comment,
"query keyword should have Comment trivia with value \" comment\"",
);
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_comma_captured() {
let source = "{ a, b }";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
assert_eq!(op.selection_set.selections.len(), 2);
if let ast::Selection::Field(field_b) = &op.selection_set.selections[1] {
assert_eq!(field_b.name.value, "b");
let name_syntax = field_b.name.syntax.as_ref().unwrap();
let has_comma = name_syntax.token.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Comma { .. })
});
assert!(has_comma, "Field 'b' name token should have Comma trivia");
} else {
panic!("Expected a Field selection");
}
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_leading_whitespace() {
let source = " query { f }";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
let op_syntax = op.syntax.as_ref().unwrap();
let kw = op_syntax.operation_keyword.as_ref().unwrap();
let has_leading_ws = kw.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { value, .. } if value == " ")
});
assert!(
has_leading_ws,
"query keyword should have leading whitespace trivia",
);
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_trailing_in_document() {
let source = "query { f }\n ";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
let doc_syntax = doc.syntax.as_ref().unwrap();
let has_trailing_ws = doc_syntax.trailing_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { value, .. } if value == "\n ")
});
assert!(
has_trailing_ws,
"Document trailing trivia should contain \"\\n \" Whitespace",
);
}
#[test]
fn trivia_no_whitespace_adjacent_tokens() {
let source = "{f}";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
if let ast::Selection::Field(field) = &op.selection_set.selections[0] {
let name_syntax = field.name.syntax.as_ref().unwrap();
let has_ws = name_syntax.token.preceding_trivia.iter().any(|t| {
matches!(t, GraphQLTriviaToken::Whitespace { .. })
});
assert!(
!has_ws,
"Field name should have no Whitespace trivia when adjacent to brace",
);
} else {
panic!("Expected a Field selection");
}
} else {
panic!("Expected an OperationDefinition");
}
}
#[test]
fn trivia_span_matches_source_slice() {
let source = "query { f }";
let result = parse_executable(source);
assert!(!result.has_errors());
let (doc, _) = result.into_valid().unwrap();
if let ast::Definition::OperationDefinition(op) = &doc.definitions[0] {
let ss_syntax = op.selection_set.syntax.as_ref().unwrap();
let open_brace = &ss_syntax.braces.open;
for trivia in open_brace.preceding_trivia.iter() {
if let GraphQLTriviaToken::Whitespace { value, span } = trivia {
let start = span.start as usize;
let end = span.end as usize;
let source_slice = &source[start..end];
assert_eq!(
source_slice, value,
"Trivia span byte range should match the trivia value in the source",
);
return;
}
}
panic!("Expected to find Whitespace trivia on the open brace token");
} else {
panic!("Expected an OperationDefinition");
}
}