use crate::token::GraphQLTriviaToken;
use crate::token::StrGraphQLTokenSource;
use crate::token::StrGraphQLTokenSourceConfig;
struct TriviaCounts {
comments: usize,
commas: usize,
whitespace: usize,
}
fn count_trivia_by_kind(
tokens: &[crate::token::GraphQLToken<'_>],
) -> TriviaCounts {
let mut counts = TriviaCounts {
comments: 0,
commas: 0,
whitespace: 0,
};
for token in tokens {
for trivia in &token.preceding_trivia {
match trivia {
GraphQLTriviaToken::Comment { .. } => counts.comments += 1,
GraphQLTriviaToken::Comma { .. } => counts.commas += 1,
GraphQLTriviaToken::Whitespace { .. } => {
counts.whitespace += 1;
},
}
}
}
counts
}
#[test]
fn default_config_retains_all_trivia() {
let source = "# comment\na, b";
let tokens: Vec<_> = StrGraphQLTokenSource::new(source).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 1, "expected 1 comment");
assert_eq!(counts.commas, 1, "expected 1 comma");
assert_eq!(counts.whitespace, 2, "expected 2 whitespace runs");
}
#[test]
fn no_trivia_config_discards_all_trivia() {
let source = "# comment\na, b";
let config = StrGraphQLTokenSourceConfig::no_trivia();
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 0, "no_trivia should discard comments");
assert_eq!(counts.commas, 0, "no_trivia should discard commas");
assert_eq!(counts.whitespace, 0, "no_trivia should discard whitespace");
}
#[test]
fn retain_comments_false_discards_comments() {
let source = "# comment\na, b";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
..Default::default()
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 0, "comments should be discarded");
assert_eq!(counts.commas, 1, "commas should still be retained");
assert_eq!(counts.whitespace, 2, "whitespace should still be retained");
}
#[test]
fn retain_comments_true_preserves_comments() {
let source = "# hello\nfield";
let config = StrGraphQLTokenSourceConfig {
retain_comments: true,
retain_commas: false,
retain_whitespace: false,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 1, "should have exactly 1 comment trivia");
assert_eq!(counts.commas, 0);
assert_eq!(counts.whitespace, 0);
assert!(matches!(
&tokens[0].preceding_trivia[0],
GraphQLTriviaToken::Comment { value, .. } if value == " hello"
));
}
#[test]
fn retain_commas_false_discards_commas() {
let source = "# comment\na, b";
let config = StrGraphQLTokenSourceConfig {
retain_commas: false,
..Default::default()
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 1, "comments should still be retained");
assert_eq!(counts.commas, 0, "commas should be discarded");
assert_eq!(counts.whitespace, 2, "whitespace should still be retained");
}
#[test]
fn retain_commas_true_preserves_commas() {
let source = "a,b";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
retain_commas: true,
retain_whitespace: false,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 0);
assert_eq!(counts.commas, 1, "should have exactly 1 comma trivia");
assert_eq!(counts.whitespace, 0);
assert!(matches!(
&tokens[1].preceding_trivia[0],
GraphQLTriviaToken::Comma { .. }
));
}
#[test]
fn retain_whitespace_false_discards_whitespace() {
let source = "# comment\na, b";
let config = StrGraphQLTokenSourceConfig {
retain_whitespace: false,
..Default::default()
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
let counts = count_trivia_by_kind(&tokens);
assert_eq!(counts.comments, 1, "comments should still be retained");
assert_eq!(counts.commas, 1, "commas should still be retained");
assert_eq!(counts.whitespace, 0, "whitespace should be discarded");
}
#[test]
fn retain_whitespace_true_preserves_whitespace_runs() {
let source = " a b";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
retain_commas: false,
retain_whitespace: true,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
assert_eq!(tokens[0].preceding_trivia.len(), 1);
assert!(matches!(
&tokens[0].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == " "
));
assert_eq!(tokens[1].preceding_trivia.len(), 1);
assert!(matches!(
&tokens[1].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == " "
));
}
#[test]
fn whitespace_captures_newlines() {
let source = "a\n\nb";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
retain_commas: false,
retain_whitespace: true,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
assert_eq!(tokens[1].preceding_trivia.len(), 1);
assert!(matches!(
&tokens[1].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == "\n\n"
));
}
#[test]
fn whitespace_captures_tabs() {
let source = "\t\ta";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
retain_commas: false,
retain_whitespace: true,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
assert_eq!(tokens[0].preceding_trivia.len(), 1);
assert!(matches!(
&tokens[0].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == "\t\t"
));
}
#[test]
fn whitespace_captures_mixed_run() {
let source = " \t\n a";
let config = StrGraphQLTokenSourceConfig {
retain_comments: false,
retain_commas: false,
retain_whitespace: true,
};
let tokens: Vec<_> =
StrGraphQLTokenSource::with_config(source, config).collect();
assert_eq!(tokens[0].preceding_trivia.len(), 1);
assert!(matches!(
&tokens[0].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == " \t\n "
));
}
#[test]
fn interleaved_trivia_ordering() {
let source = " # comment\n a, b";
let tokens: Vec<_> = StrGraphQLTokenSource::new(source).collect();
assert_eq!(
tokens[0].preceding_trivia.len(), 3,
"trivia on 'a': {:?}", tokens[0].preceding_trivia,
);
assert!(matches!(
&tokens[0].preceding_trivia[0],
GraphQLTriviaToken::Whitespace { value, .. } if value == " "
));
assert!(matches!(
&tokens[0].preceding_trivia[1],
GraphQLTriviaToken::Comment { value, .. } if value == " comment"
));
assert!(matches!(
&tokens[0].preceding_trivia[2],
GraphQLTriviaToken::Whitespace { value, .. } if value == "\n "
));
assert_eq!(
tokens[1].preceding_trivia.len(), 2,
"trivia on 'b': {:?}", tokens[1].preceding_trivia,
);
assert!(matches!(
&tokens[1].preceding_trivia[0],
GraphQLTriviaToken::Comma { .. }
));
assert!(matches!(
&tokens[1].preceding_trivia[1],
GraphQLTriviaToken::Whitespace { value, .. } if value == " "
));
}