#![allow(clippy::needless_update)]
use df_ls_core::{Reference, ReferenceTo};
use df_ls_debug_structure::*;
use df_ls_diagnostics::lsp_types::*;
use df_ls_lexical_analysis::test_utils::LexerTestBuilder;
use df_ls_syntax_analysis::test_utils::SyntaxTestBuilder;
#[test]
fn message_token_not_expected() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[TEST]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "".to_owned(), token_structure: vec![],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 1,
character: 12,
},
end: Position {
line: 1,
character: 18,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("token_not_expected".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected a different token.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_token_is_missing() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:TYPE1]
[ITEM:DOG]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "".to_owned(), token_structure: vec![],
})
.add_test_syntax_diagnostics(vec![
Diagnostic {
range: Range {
start: Position {
line: 2,
character: 12,
},
end: Position {
line: 2,
character: 22,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("token_is_missing".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Suggest adding one of following tokens here: `TYPE1`.".to_owned(),
..Default::default()
},
Diagnostic {
range: Range {
start: Position {
line: 2,
character: 12,
},
end: Position {
line: 2,
character: 22,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("token_not_expected".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected a different token.".to_owned(),
..Default::default()
},
])
.run_test();
}
#[test]
fn message_invalid_second_par_type() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:T]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 1,
character: 18,
},
end: Position {
line: 1,
character: 19,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("invalid_second_par_type".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "`T` is not a valid type in `MAIN`, valid types are \
`TYPE1`, `TYPE2`, `TYPE3`, `TYPE4`, `PROFESSION`, `DEBUG`."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_unknown_token() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:TYPE1]
[TYPE1:DOG]
[TEST]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
type_1: vec![Type1Token {
reference: Some(Reference("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 12,
},
end: Position {
line: 3,
character: 18,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("unknown_token".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Unrecognized token `TEST`.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_wrong_arg_number_to_many() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:TYPE1]
[TYPE1:DOG]
[ITEM:REF:::]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
type_1: vec![Type1Token {
reference: Some(Reference("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 12,
},
end: Position {
line: 3,
character: 25,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("wrong_arg_number".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected 1 arguments, found 4.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_wrong_arg_number_to_few() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:TYPE1]
[TYPE1:DOG]
[ITEM]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
type_1: vec![Type1Token {
reference: Some(Reference("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 12,
},
end: Position {
line: 3,
character: 18,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("wrong_arg_number".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected at least 1 arguments, found 0.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_wrong_arg_type() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:TYPE1]
[TYPE1:DOG]
[ITEM:5]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
type_1: vec![Type1Token {
reference: Some(Reference("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 18,
},
end: Position {
line: 3,
character: 19,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("wrong_arg_type".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected Reference, found Integer.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_wrong_enum_value() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[GENDER:NOT]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 24,
},
end: Position {
line: 3,
character: 27,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("wrong_enum_value".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "The value `NOT` is not allowed in this enum. Allowed value are: `MALE`, `FEMALE`, `OTHER`.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_too_large_int() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[DIFFICULTY:60000]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 28,
},
end: Position {
line: 3,
character: 33,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("too_large_int".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "This parameter does not accept values larger than 255.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_too_small_int() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[DIFFICULTY:-200]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 28,
},
end: Position {
line: 3,
character: 32,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("too_small_int".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "This parameter does not accept values smaller than 0.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
#[ignore = "This error can not happen because of lexer"]
fn message_char_wrong_quote() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[SYMBOL:'a!]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 16,
},
end: Position {
line: 3,
character: 19,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("char_wrong_quote".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected `'`(single quote) but found something `!`.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
#[ignore = "This error can not happen because of lexer"]
fn message_char_expected_more_chars() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[SYMBOL:']",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 16,
},
end: Position {
line: 3,
character: 17,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String(
"char_expected_more_chars".to_owned(),
)),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected `'a'`(1 character in single quote) but found only 1 character."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
#[ignore = "This error can not happen because of lexer"]
fn message_expected_integer() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[DIFFICULTY:12.5]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 20,
},
end: Position {
line: 3,
character: 24,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("expected_integer".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected an Integer, but found `12.5`. \
Could not covert this to an Integer: Not an Integer."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_duplicate_token_warn() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[DIFFICULTY:12]
[DIFFICULTY:35]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
difficulty: Some(12),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 4,
character: 16,
},
end: Position {
line: 4,
character: 31,
},
},
severity: Some(DiagnosticSeverity::WARNING),
code: Some(NumberOrString::String("duplicate_token_warn".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Duplicate token: `DIFFICULTY` already exists in this `PROFESSION`.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_duplicate_token_error() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[DIFFICULTY_HARD:12]
[DIFFICULTY_HARD:35]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
difficulty_hard: Some(12),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 4,
character: 16,
},
end: Position {
line: 4,
character: 36,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("duplicate_token_error".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Duplicate token: `DIFFICULTY_HARD` already exists in this `PROFESSION`."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_reference_is_string() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:Dog]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("Dog".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 2,
character: 24,
},
end: Position {
line: 2,
character: 27,
},
},
severity: Some(DiagnosticSeverity::WARNING),
code: Some(NumberOrString::String("reference_is_string".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected `Reference` but found `String`. Make sure to only use UPPERCASE, numbers and `_`."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_string_is_reference() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[ARG:CPU]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
argument: Some(("CPU".to_owned(), None)),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 17,
},
end: Position {
line: 3,
character: 20,
},
},
severity: Some(DiagnosticSeverity::WARNING),
code: Some(NumberOrString::String("string_is_reference".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Expected `String` but found `Reference`. \
If possible, try to use at least 1 lowercase character, space, \
or special character like `.` or `,` or `!`."
.to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_alias() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[JOB:DRINKING]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
name: vec![Reference("DRINKING".to_owned())],
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![Diagnostic {
range: Range {
start: Position {
line: 3,
character: 17,
},
end: Position {
line: 3,
character: 20,
},
},
severity: Some(DiagnosticSeverity::WARNING),
code: Some(NumberOrString::String("alias".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "The token `JOB` is an alias, please use `NAME`.".to_owned(),
..Default::default()
}])
.run_test();
}
#[test]
fn message_unchecked_code() {
SyntaxTestBuilder::from_lexer_test_builder(
LexerTestBuilder::test_source(
"h
[MAIN:PROFESSION]
[PROFESSION:DOG]
[TTTTTTT]
[TEST]",
)
.add_test_lexer_diagnostics_codes(vec![])
.add_test_lexer_diagnostics_ranges(vec![]),
)
.add_test_structure(DebugRaw {
header: "h".to_owned(),
token_structure: vec![MainToken {
professions: vec![ProfessionToken {
reference: Some(ReferenceTo::new("DOG".to_owned())),
..Default::default()
}],
..Default::default()
}],
})
.add_test_syntax_diagnostics(vec![
Diagnostic {
range: Range {
start: Position {
line: 3,
character: 16,
},
end: Position {
line: 3,
character: 25,
},
},
severity: Some(DiagnosticSeverity::ERROR),
code: Some(NumberOrString::String("unknown_token".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "Unrecognized token `TTTTTTT`.".to_owned(),
..Default::default()
},
Diagnostic {
range: Range {
start: Position {
line: 3,
character: 25,
},
end: Position {
line: 4,
character: 18,
},
},
severity: Some(DiagnosticSeverity::WARNING),
code: Some(NumberOrString::String("unchecked_code".to_owned())),
source: Some("DF RAW Language Server".to_owned()),
message: "This code could not be checked because of previous error.".to_owned(),
..Default::default()
},
])
.run_test();
}