use crate::tests::utils;
use crate::token::GraphQLTokenKind;
use crate::GraphQLTokenStream;
#[test]
fn test_peek_without_consuming() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let first_peek = stream.peek().map(|t| t.kind.clone());
let second_peek = stream.peek().map(|t| t.kind.clone());
assert_eq!(first_peek, second_peek);
assert!(
matches!(first_peek, Some(GraphQLTokenKind::Name(ref name)) if name == "type")
);
let consumed = stream.consume().map(|t| t.kind.clone());
assert_eq!(first_peek, consumed);
}
#[test]
fn test_consume_advances_token() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let first = stream.consume().map(|t| t.kind.clone());
assert!(matches!(first, Some(GraphQLTokenKind::Name(name)) if name == "type"));
let second = stream.peek().map(|t| t.kind.clone());
assert!(matches!(second, Some(GraphQLTokenKind::Name(name)) if name == "Query"));
}
#[test]
fn test_peek_nth_lookahead() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_token(GraphQLTokenKind::CurlyBraceOpen),
utils::mock_name_token("field"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let token_0 = stream.peek_nth(0).map(|t| t.kind.clone());
let token_1 = stream.peek_nth(1).map(|t| t.kind.clone());
let token_2 = stream.peek_nth(2).map(|t| t.kind.clone());
assert!(
matches!(token_0, Some(GraphQLTokenKind::Name(ref name)) if name == "type")
);
assert!(
matches!(token_1, Some(GraphQLTokenKind::Name(ref name)) if name == "Query")
);
assert!(matches!(token_2, Some(GraphQLTokenKind::CurlyBraceOpen)));
stream.consume();
let new_token_0 = stream.peek_nth(0).map(|t| t.kind.clone());
assert_eq!(token_1, new_token_0);
}
#[test]
fn test_peek_nth_beyond_end() {
let tokens = vec![utils::mock_name_token("type"), utils::mock_eof_token()];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let result = stream.peek_nth(100);
assert!(result.is_none());
}
#[test]
fn test_peek_nth_zero_equals_peek() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let peek_result = stream.peek().map(|t| t.kind.clone());
let peek_nth_result = stream.peek_nth(0).map(|t| t.kind.clone());
assert_eq!(peek_result, peek_nth_result);
}
#[test]
fn test_is_at_end() {
let tokens = vec![utils::mock_name_token("type"), utils::mock_eof_token()];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
assert!(!stream.is_at_end());
stream.consume(); assert!(stream.is_at_end()); }
#[test]
fn test_is_at_end_empty_stream() {
let tokens = vec![];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
assert!(stream.is_at_end());
}
#[test]
fn test_consume_at_end_returns_none() {
let tokens = vec![utils::mock_name_token("type")];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
assert!(stream.consume().is_some()); assert!(stream.consume().is_none()); }
#[test]
fn test_mixed_peek_and_consume() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
let peeked = stream.peek_nth(1).map(|t| t.kind.clone());
stream.consume();
let now_first = stream.peek().map(|t| t.kind.clone());
assert_eq!(peeked, now_first);
}
#[test]
fn test_buffer_order_after_lookahead() {
let tokens = vec![
utils::mock_name_token("type"),
utils::mock_name_token("Query"),
utils::mock_token(GraphQLTokenKind::CurlyBraceOpen),
utils::mock_name_token("field"),
utils::mock_eof_token(),
];
let mut stream = GraphQLTokenStream::new(utils::MockTokenSource::new(tokens));
stream.peek_nth(3);
let mut consumed: Vec<GraphQLTokenKind> = Vec::new();
for _ in 0..4 {
if let Some(token) = stream.consume() {
consumed.push(token.kind.clone());
}
}
assert!(matches!(consumed[0], GraphQLTokenKind::Name(ref n) if n == "type"));
assert!(matches!(consumed[1], GraphQLTokenKind::Name(ref n) if n == "Query"));
assert!(matches!(consumed[2], GraphQLTokenKind::CurlyBraceOpen));
assert!(matches!(consumed[3], GraphQLTokenKind::Name(ref n) if n == "field"));
}
#[test]
fn test_consume_bounds_memory() {
let token_count = 10_000;
let tokens = (0..token_count)
.map(|i| utils::mock_name_token(&format!("token{i}")))
.chain(std::iter::once(utils::mock_eof_token()))
.collect();
let mut stream = GraphQLTokenStream::new(
utils::MockTokenSource::new(tokens),
);
let mut consumed_count: u16 = 0;
while stream.consume().is_some() {
consumed_count += 1;
assert!(stream.current_buffer_len() <= 1);
}
assert_eq!(consumed_count, token_count + 1);
assert_eq!(stream.current_buffer_len(), 0);
}