fix: fixed tests and added 5 new ones
This commit is contained in:
@@ -42,51 +42,102 @@ import Testing
|
|||||||
#expect(tokens == [.recipe("build"), .command("swift build")])
|
#expect(tokens == [.recipe("build"), .command("swift build")])
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Parser
|
@Test func lexer_unrecognized_line_produces_error_token() {
|
||||||
|
let tokens = Lexer().tokenize("???bad line")
|
||||||
@Test func parser_single_recipe_with_command() {
|
#expect(tokens == [.error(line: "???bad line")])
|
||||||
let tokens: [Token] = [.recipe("build"), .command("swift build")]
|
|
||||||
let ast = Parser().parse(tokens)
|
|
||||||
#expect(ast != nil)
|
|
||||||
#expect(ast?.rules["build"]?.commands == ["swift build"])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func parser_recipe_with_dependency() {
|
@Test func lexer_multiple_errors_in_multiline() {
|
||||||
|
let input = """
|
||||||
|
build:
|
||||||
|
???bad
|
||||||
|
!!!also bad
|
||||||
|
"""
|
||||||
|
let tokens = Lexer().tokenize(input)
|
||||||
|
#expect(tokens.contains(.error(line: "???bad")))
|
||||||
|
#expect(tokens.contains(.error(line: "!!!also bad")))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Parser
|
||||||
|
|
||||||
|
@Test func parser_single_recipe_with_command() throws {
|
||||||
|
let tokens: [Token] = [.recipe("build"), .command("swift build")]
|
||||||
|
let ast = try Parser().parse(tokens).get()
|
||||||
|
#expect(ast.rules["build"]?.commands == ["swift build"])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parser_recipe_with_dependency() throws {
|
||||||
let tokens: [Token] = [
|
let tokens: [Token] = [
|
||||||
.recipe("test"), .dependency("build"),
|
.recipe("test"), .dependency("build"),
|
||||||
.command("swift test")
|
.command("swift test")
|
||||||
]
|
]
|
||||||
let ast = Parser().parse(tokens)
|
let ast = try Parser().parse(tokens).get()
|
||||||
#expect(ast?.rules["test"]?.dependencies == ["build"])
|
#expect(ast.rules["test"]?.dependencies == ["build"])
|
||||||
#expect(ast?.rules["test"]?.commands == ["swift test"])
|
#expect(ast.rules["test"]?.commands == ["swift test"])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func parser_variable_is_stored() {
|
@Test func parser_variable_is_stored() throws {
|
||||||
let tokens: [Token] = [.variable(name: "CC", value: "clang")]
|
let tokens: [Token] = [.variable(name: "CC", value: "clang")]
|
||||||
let ast = Parser().parse(tokens)
|
let ast = try Parser().parse(tokens).get()
|
||||||
#expect(ast?.vars["CC"] == "clang")
|
#expect(ast.vars["CC"] == "clang")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func parser_multiple_recipes() {
|
@Test func parser_multiple_recipes() throws {
|
||||||
let tokens: [Token] = [
|
let tokens: [Token] = [
|
||||||
.recipe("build"), .command("swift build"),
|
.recipe("build"), .command("swift build"),
|
||||||
.newline,
|
.newline,
|
||||||
.recipe("test"), .command("swift test"),
|
.recipe("test"), .command("swift test"),
|
||||||
]
|
]
|
||||||
let ast = Parser().parse(tokens)
|
let ast = try Parser().parse(tokens).get()
|
||||||
#expect(ast?.rules["build"]?.commands == ["swift build"])
|
#expect(ast.rules["build"]?.commands == ["swift build"])
|
||||||
#expect(ast?.rules["test"]?.commands == ["swift test"])
|
#expect(ast.rules["test"]?.commands == ["swift test"])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func parser_variable_before_recipe_flushes_context() {
|
@Test func parser_variable_before_recipe_flushes_context() throws {
|
||||||
// A variable declaration after a recipe must flush the current recipe first.
|
|
||||||
let tokens: [Token] = [
|
let tokens: [Token] = [
|
||||||
.recipe("build"), .command("swift build"),
|
.recipe("build"), .command("swift build"),
|
||||||
.variable(name: "X", value: "1"),
|
.variable(name: "X", value: "1"),
|
||||||
]
|
]
|
||||||
let ast = Parser().parse(tokens)
|
let ast = try Parser().parse(tokens).get()
|
||||||
#expect(ast?.rules["build"]?.commands == ["swift build"])
|
#expect(ast.rules["build"]?.commands == ["swift build"])
|
||||||
#expect(ast?.vars["X"] == "1")
|
#expect(ast.vars["X"] == "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Parser error handling
|
||||||
|
|
||||||
|
@Test func parser_single_error_token_returns_failure() {
|
||||||
|
let tokens: [Token] = [.error(line: "???bad")]
|
||||||
|
let result = Parser().parse(tokens)
|
||||||
|
guard case .failure(let err) = result else {
|
||||||
|
Issue.record("expected failure, got success")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#expect(err.errorLines == ["???bad"])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parser_multiple_error_tokens_collected() {
|
||||||
|
let tokens: [Token] = [
|
||||||
|
.error(line: "???bad"),
|
||||||
|
.recipe("build"), .command("swift build"),
|
||||||
|
.error(line: "!!!also bad"),
|
||||||
|
]
|
||||||
|
let result = Parser().parse(tokens)
|
||||||
|
guard case .failure(let err) = result else {
|
||||||
|
Issue.record("expected failure, got success")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#expect(err.errorLines.count == 2)
|
||||||
|
#expect(err.errorLines.contains("???bad"))
|
||||||
|
#expect(err.errorLines.contains("!!!also bad"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parser_no_error_tokens_returns_success() {
|
||||||
|
let tokens: [Token] = [.recipe("build"), .command("swift build")]
|
||||||
|
let result = Parser().parse(tokens)
|
||||||
|
guard case .success = result else {
|
||||||
|
Issue.record("expected success, got failure")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Variable resolution
|
// MARK: - Variable resolution
|
||||||
|
|||||||
Reference in New Issue
Block a user