#![cfg(debug_assertions)]
mod test_structure;
mod test_tree_structure;
use crate::TokenDeserialize;
use df_ls_diagnostics::{lsp_types::Diagnostic, DiagnosticsInfo, Range};
use df_ls_lexical_analysis::{
test_utils::{
test_diagnostics, test_diagnostics_codes, test_diagnostics_ranges, LexerTestBuilder,
},
Tree,
};
use std::{fmt::Debug, rc::Rc};
pub use test_tree_structure::skip_comment;
pub struct SyntaxTestBuilder<S: TokenDeserialize + Debug + PartialEq> {
lexer_test_builder: Option<LexerTestBuilder>,
structure: Option<S>,
syntax_diagnostics: Option<Vec<Diagnostic>>,
syntax_diagnostics_codes: Option<Vec<String>>,
syntax_diagnostics_ranges: Option<Vec<Range>>,
}
impl<S: TokenDeserialize + Debug + PartialEq> SyntaxTestBuilder<S> {
#[must_use = "Don't forget to call `.run_test()`"]
pub fn from_lexer_test_builder(lexer_test_builder: LexerTestBuilder) -> Self {
Self {
lexer_test_builder: Some(lexer_test_builder),
structure: None,
syntax_diagnostics: None,
syntax_diagnostics_codes: None,
syntax_diagnostics_ranges: None,
}
}
pub fn run_test(self) {
self.run_test_with_result();
}
pub fn run_test_with_result(mut self) -> (Rc<Tree>, S, String) {
let lexer_test_builder = self
.lexer_test_builder
.expect("LexerTestBuilder was already used.");
self.lexer_test_builder = None;
let (tree, source) = lexer_test_builder.run_test_with_result();
let (given_structure, diagnostic_info_syntax): (S, _) =
crate::do_syntax_analysis(&tree, &source);
self.run_test_with_custom_data(&given_structure, diagnostic_info_syntax);
(tree, given_structure, source)
}
pub fn run_test_with_custom_data(
&self,
given_structure: &S,
diagnostic_info_syntax: DiagnosticsInfo,
) {
if let Some(structure) = &self.structure {
test_structure::test_structure(structure, given_structure);
}
if let Some(syntax_diagnostics) = &self.syntax_diagnostics {
test_diagnostics::test_diagnostics(syntax_diagnostics, &diagnostic_info_syntax);
}
if let Some(syntax_diagnostics_codes) = &self.syntax_diagnostics_codes {
test_diagnostics_codes::test_diagnostics_codes(
syntax_diagnostics_codes,
&diagnostic_info_syntax,
);
}
if let Some(syntax_diagnostics_ranges) = &self.syntax_diagnostics_ranges {
test_diagnostics_ranges::test_diagnostics_ranges(
syntax_diagnostics_ranges,
&diagnostic_info_syntax,
);
}
}
#[must_use = "Don't forget to call `.run_test_with_custom_data()`"]
pub fn run_lexer_test_builder(mut self) -> (Self, Rc<Tree>, String) {
let lexer_test_builder = self
.lexer_test_builder
.expect("LexerTestBuilder was already used.");
self.lexer_test_builder = None;
let (tree, source) = lexer_test_builder.run_test_with_result();
(self, tree, source)
}
#[must_use = "Don't forget to call `.run_test()`"]
pub fn add_test_structure(mut self, structure: S) -> Self {
self.structure = Some(structure);
self
}
#[must_use = "Don't forget to call `.run_test()`"]
pub fn add_test_syntax_diagnostics(mut self, diagnostics: Vec<Diagnostic>) -> Self {
self.syntax_diagnostics = Some(diagnostics);
self
}
#[must_use = "Don't forget to call `.run_test()`"]
pub fn add_test_syntax_diagnostics_codes(mut self, diagnostics_codes: Vec<&str>) -> Self {
self.syntax_diagnostics_codes = Some(
diagnostics_codes
.into_iter()
.map(|s| s.to_owned())
.collect(),
);
self
}
#[must_use = "Don't forget to call `.run_test()`"]
pub fn add_test_syntax_diagnostics_ranges(mut self, diagnostics_ranges: Vec<Range>) -> Self {
self.syntax_diagnostics_ranges = Some(diagnostics_ranges);
self
}
}