sqruff_lib_core/parser/segments/
test_functions.rs

1use std::ops::Range;
2
3use super::{ErasedSegment, SegmentBuilder, Tables};
4use crate::dialects::Dialect;
5use crate::dialects::syntax::SyntaxKind;
6use crate::helpers::Config;
7use crate::parser::lexer::Lexer;
8use crate::parser::markers::PositionMarker;
9use crate::templaters::TemplatedFile;
10
11pub fn bracket_segments() -> Vec<ErasedSegment> {
12    generate_test_segments_func(vec![
13        "bar", " \t ", "(", "foo", "    ", ")", "baar", " \t ", "foo",
14    ])
15}
16
17pub fn lex(dialect: &Dialect, string: &str) -> Vec<ErasedSegment> {
18    let lexer = Lexer::new(dialect.lexer_matchers());
19    let tables = Tables::default();
20    let (segments, errors) = lexer.lex(&tables, string);
21    assert_eq!(errors, &[]);
22    segments
23}
24
25/// Roughly generate test segments.
26///
27/// This is a factory function so that it works as a fixture,
28/// but when actually used, this will return the inner function
29/// which is what you actually need.
30pub fn generate_test_segments_func(elems: Vec<&str>) -> Vec<ErasedSegment> {
31    // Placeholder: assuming TemplatedFile, PositionMarker, and other structures
32    // are defined elsewhere in the codebase.
33    let raw_file = elems.concat();
34
35    let templated_file: TemplatedFile = raw_file.into();
36    let mut idx = 0;
37    let mut buff: Vec<ErasedSegment> = Vec::new();
38
39    for elem in elems {
40        if elem == "<indent>" {
41            buff.push(SegmentBuilder::token(0, "", SyntaxKind::Indent).finish());
42            continue;
43        } else if elem == "<dedent>" {
44            buff.push(SegmentBuilder::token(0, "", SyntaxKind::Dedent).finish());
45            continue;
46        }
47
48        let position_marker = PositionMarker::new(
49            idx..idx + elem.len(),
50            idx..idx + elem.len(),
51            templated_file.clone(),
52            None,
53            None,
54        );
55
56        let tables = Tables::default();
57
58        let seg = if elem.chars().all(|c| c == ' ' || c == '\t') {
59            SegmentBuilder::whitespace(tables.next_id(), elem).config(|this| {
60                this.get_mut()
61                    .set_position_marker(position_marker.clone().into())
62            })
63        } else if elem.chars().all(|c| c == '\n') {
64            SegmentBuilder::newline(tables.next_id(), elem)
65        } else if elem == "(" || elem == ")" {
66            SegmentBuilder::token(tables.next_id(), elem, SyntaxKind::RawComparisonOperator)
67                .with_position(position_marker)
68                .finish()
69        } else if elem.starts_with("--") {
70            SegmentBuilder::token(0, elem, SyntaxKind::InlineComment)
71                .with_position(position_marker)
72                .finish()
73        } else if elem.starts_with('\"') {
74            SegmentBuilder::token(0, elem, SyntaxKind::DoubleQuote)
75                .with_position(position_marker)
76                .finish()
77        } else if elem.starts_with('\'') {
78            SegmentBuilder::token(0, elem, SyntaxKind::SingleQuote)
79                .with_position(position_marker)
80                .finish()
81        } else {
82            SegmentBuilder::token(0, elem, SyntaxKind::RawComparisonOperator)
83                .with_position(position_marker)
84                .finish()
85        };
86
87        buff.push(seg);
88        idx += elem.len();
89    }
90
91    buff
92}
93
94/// Construct a list of raw segments as a fixture.
95pub fn raw_segments() -> Vec<ErasedSegment> {
96    generate_test_segments_func(["foobar", ".barfoo"].to_vec())
97}
98
99pub fn raw_seg() -> ErasedSegment {
100    raw_segments()[0].clone()
101}
102
103pub fn test_segments() -> Vec<ErasedSegment> {
104    generate_test_segments_func(vec!["bar", " \t ", "foo", "baar", " \t "])
105}
106
107pub fn make_result_tuple(
108    result_slice: Option<Range<usize>>,
109    matcher_keywords: &[&str],
110    test_segments: &[ErasedSegment],
111) -> Vec<ErasedSegment> {
112    // Make a comparison tuple for test matching.
113    // No result slice means no match.
114    match result_slice {
115        None => vec![],
116        Some(slice) => test_segments[slice]
117            .iter()
118            .map(|elem| {
119                let raw = elem.raw();
120                if matcher_keywords.contains(&raw.as_str()) {
121                    SegmentBuilder::keyword(0, raw).config(|this| {
122                        this.get_mut()
123                            .set_position_marker(Some(elem.get_position_marker().unwrap().clone()))
124                    })
125                } else {
126                    elem.clone()
127                }
128            })
129            .collect(),
130    }
131}