Skip to content

Commit

Permalink
More tests rewrite to Swift Testing
Browse files Browse the repository at this point in the history
- Rewrote: Expression parser, function, lexer, CSV reader/writer
  • Loading branch information
Stiivi committed Nov 14, 2024
1 parent fe7b20a commit 69f29db
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 412 deletions.
13 changes: 5 additions & 8 deletions Tests/PoieticCoreTests/Design/DesignTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,11 @@ import Testing
#expect {
try design.accept(frame)
} throws: {
guard let error = $0 as? FrameConstraintError else {
Issue.record("Error is not a FrameConstraintError")
return false
}
guard let violation = error.violations.first else {
Issue.record("No constraint violation found")
return false
}
let error = try #require($0 as? FrameConstraintError,
"Error is not a FrameConstraintError")
let violation = try #require(error.violations.first,
"No constraint violation found")

return error.violations.count == 1
&& violation.objects.count == 2
&& violation.objects.contains(a.id)
Expand Down
157 changes: 63 additions & 94 deletions Tests/PoieticCoreTests/Expression/ExpressionParserTests.swift
Original file line number Diff line number Diff line change
@@ -1,176 +1,145 @@
//
// File.swift
//
// ExpressionParserTests.swift
//
//
// Created by Stefan Urbanek on 28/05/2022.
//

import XCTest
import Testing
@testable import PoieticCore


final class ExpressionParserTests: XCTestCase {
func testEmpty() {
@Suite struct ExpressionParserTests {
@Test func empty() {
let parser = ExpressionParser(string: "")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}
}

func testUnexpected() throws {
@Test func unexpectedToken() throws {
let parser = ExpressionParser(string: "$")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}

let parser2 = ExpressionParser(string: "1 1")
#expect(throws: ExpressionSyntaxError.unexpectedToken) {
try parser2.parse()
}
}

func testBinary() {
let expr = UnboundExpression.binary(
"+",
.variable("a"),
.value(1)
)
XCTAssertEqual(try ExpressionParser(string: "a + 1").parse(), expr)
XCTAssertEqual(try ExpressionParser(string: "a+1").parse(), expr)
@Test func parseBinary() throws {
let expr = UnboundExpression.binary( "+", .variable("a"), .value(1) )
#expect(try ExpressionParser(string: "a + 1").parse() == expr)
#expect(try ExpressionParser(string: "a+1").parse() == expr)
}

func testBinaryComparison() {
let expr = UnboundExpression.binary(
"<=",
.value(1),
.value(2)
)
XCTAssertEqual(try ExpressionParser(string: "1 <= 2").parse(), expr)
XCTAssertEqual(try ExpressionParser(string: "1<=2").parse(), expr)
@Test func binaryComparison() throws {
let expr = UnboundExpression.binary( "<=", .value(1), .value(2) )
#expect(try ExpressionParser(string: "1 <= 2").parse() == expr)
#expect(try ExpressionParser(string: "1<=2").parse() == expr)
}

func testFactorAndTermRepetition() {
@Test func factorAndTermRepetition() throws {
let expr = UnboundExpression.binary(
"*",
.binary(
"*",
.variable("a"),
.variable("b")
),
.binary( "*", .variable("a"), .variable("b") ),
.variable("c")
)
XCTAssertEqual(try ExpressionParser(string: "a * b * c").parse(), expr)
#expect(try ExpressionParser(string: "a * b * c").parse() == expr)

let expr2 = UnboundExpression.binary(
"+",
.binary(
"+",
.variable("a"),
.variable("b")
),
.binary( "+", .variable("a"), .variable("b") ),
.variable("c")
)
XCTAssertEqual(try ExpressionParser(string: "a + b + c").parse(), expr2)
#expect(try ExpressionParser(string: "a + b + c").parse() == expr2)
}

func testPrecedence() {
@Test func precedence() throws {
let expr = UnboundExpression.binary(
"+",
.variable("a"),
.binary(
"*",
.variable("b"),
.variable("c")
)
.binary( "*", .variable("b"), .variable("c") )
)
XCTAssertEqual(try ExpressionParser(string: "a + b * c").parse(), expr)
XCTAssertEqual(try ExpressionParser(string: "a + (b * c)").parse(), expr)
#expect(try ExpressionParser(string: "a + b * c").parse() == expr)
#expect(try ExpressionParser(string: "a + (b * c)").parse() == expr)

let expr2 = UnboundExpression.binary(
"+",
.binary(
"*",
.variable("a"),
.variable("b")
),
.binary( "*", .variable("a"), .variable("b") ),
.variable("c")
)
XCTAssertEqual(try ExpressionParser(string: "a * b + c").parse(), expr2)
XCTAssertEqual(try ExpressionParser(string: "(a * b) + c").parse(), expr2)
#expect(try ExpressionParser(string: "a * b + c").parse() == expr2)
#expect(try ExpressionParser(string: "(a * b) + c").parse() == expr2)
}

func testUnary() {
@Test func unaryExpression() throws {
let expr = UnboundExpression.unary("-", .variable("x"))
XCTAssertEqual(try ExpressionParser(string: "-x").parse(), expr)
#expect(try ExpressionParser(string: "-x").parse() == expr)

let expr2 = UnboundExpression.binary(
"-",
.variable("x"),
.unary(
"-",
.variable("y")
)
.unary( "-", .variable("y") )
)
XCTAssertEqual(try ExpressionParser(string: "x - -y").parse(), expr2)
#expect(try ExpressionParser(string: "x - -y").parse() == expr2)
}
func testFunction() {
@Test func functionCall() throws {
let expr = UnboundExpression.function("fun", [.variable("x")])
XCTAssertEqual(try ExpressionParser(string: "fun(x)").parse(), expr)
#expect(try ExpressionParser(string: "fun(x)").parse() == expr)

let expr2 = UnboundExpression.function("fun", [.variable("x"), .variable("y")])
XCTAssertEqual(try ExpressionParser(string: "fun(x,y)").parse(), expr2)
#expect(try ExpressionParser(string: "fun(x,y)").parse() == expr2)

}

func testErrorMissingParenthesis() throws {
@Test func errorMissingParenthesis() throws {
let parser = ExpressionParser(string: "(")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}
}
func testErrorMissingParenthesisFunctionCall() throws {
@Test func errorMissingParenthesisFunctionCall() throws {
let parser = ExpressionParser(string: "func(1,2,3")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.missingRightParenthesis)
#expect(throws: ExpressionSyntaxError.missingRightParenthesis) {
try parser.parse()
}
}

func testUnaryExpressionExpected() throws {
@Test func unaryExpressionExpected() throws {
let parser = ExpressionParser(string: "1 + -")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}

let parser2 = ExpressionParser(string: "-")
XCTAssertThrowsError(try parser2.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser2.parse()
}
}

func testFactorUnaryExpressionExpected() throws {
@Test func factorUnaryExpressionExpected() throws {
let parser = ExpressionParser(string: "1 *")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}
}

func testTermExpressionExpected() throws {
@Test func termExpressionExpected() throws {
let parser = ExpressionParser(string: "1 +")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.expressionExpected)
#expect(throws: ExpressionSyntaxError.expressionExpected) {
try parser.parse()
}
}

func testUnexpectedToken() throws {
let parser = ExpressionParser(string: "1 1")
XCTAssertThrowsError(try parser.parse()) {
XCTAssertEqual($0 as! ExpressionSyntaxError, ExpressionSyntaxError.unexpectedToken)
}
}

func testFullText() throws {
@Test func fullText() throws {
// All-in-one, but works. Split this when nodes start mis-behaving.
let text = " - ( a + b ) * f( c, d, 100_000\n)"
let parser = ExpressionParser(string: text)
guard let result = try parser.expression() else {
XCTFail("Expected valid expression to be parsed")
return
}
XCTAssertEqual(text, result.fullText)
let result = try #require(try parser.expression(),
"Expected valid expression to be parsed")
#expect(text == result.fullText)
}
}
77 changes: 34 additions & 43 deletions Tests/PoieticCoreTests/Expression/FunctionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,80 +5,72 @@
// Created by Stefan Urbanek on 05/07/2023.
//

import XCTest
import Testing
@testable import PoieticCore


final class SignatureTests: XCTestCase {
func testSignatureEmpty() throws {
@Suite struct SignatureTests {
@Test func emptySignature() throws {
let signature = Signature(returns: .bool)

XCTAssertFalse(signature.isVariadic)
XCTAssertEqual(signature.validate(), .ok)
#expect(!signature.isVariadic)
#expect(signature.validate() == .ok)
}

func testPositional() throws {
@Test func positional() throws {
let signature = Signature([
FunctionArgument("a", type: .concrete(.int)),
FunctionArgument("b", type: .concrete(.int)),
FunctionArgument("c", type: .concrete(.int)),
],returns: .int)

XCTAssertEqual(signature.validate([.int, .int, .int]), .ok)
XCTAssertEqual(signature.validate([.int, .int, .ints]),
.typeMismatch([2]))
XCTAssertEqual(signature.validate([.point, .bools, .strings]),
.typeMismatch([0, 1, 2]))

XCTAssertEqual(signature.validate([]), .invalidNumberOfArguments)
XCTAssertEqual(signature.validate([.int, .int, .int, .int]), .invalidNumberOfArguments)
#expect(signature.validate([.int, .int, .int]) == .ok)
#expect(signature.validate([.int, .int, .ints]) == .typeMismatch([2]))
#expect(signature.validate([.point, .bools, .strings]) == .typeMismatch([0, 1, 2]))
#expect(signature.validate([]) == .invalidNumberOfArguments)
#expect(signature.validate([.int, .int, .int, .int]) == .invalidNumberOfArguments)
}

func testVariadic() throws {
@Test func variadic() throws {
let signature = Signature(
variadic: FunctionArgument("things", type: .concrete(.int)),
returns: .int
)
XCTAssertTrue(signature.isVariadic)

XCTAssertEqual(signature.validate([.int]), .ok)
XCTAssertEqual(signature.validate([.int, .int, .int]), .ok)
XCTAssertEqual(signature.validate([]), .invalidNumberOfArguments)
XCTAssertEqual(signature.validate([.int, .int, .point]),
.typeMismatch([2]))
XCTAssertEqual(signature.validate([.point, .point, .point]),
.typeMismatch([0, 1, 2]))
#expect(signature.isVariadic)
#expect(signature.validate([.int]) == .ok)
#expect(signature.validate([.int, .int, .int]) == .ok)
#expect(signature.validate([]) == .invalidNumberOfArguments)
#expect(signature.validate([.int, .int, .point]) == .typeMismatch([2]))
#expect(signature.validate([.point, .point, .point]) == .typeMismatch([0, 1, 2]))
}

func testVariadicAtLeastOne() throws {
@Test func variadicAtLeastOne() throws {
let signature = Signature(
variadic: FunctionArgument("values", type: .concrete(.int)),
returns: .int
)
XCTAssertTrue(signature.isVariadic)

XCTAssertEqual(signature.validate([.int]), .ok)
XCTAssertEqual(signature.validate([.int, .int, .int]), .ok)
XCTAssertEqual(signature.validate([]), .invalidNumberOfArguments)
#expect(signature.isVariadic)
#expect(signature.validate([.int]) == .ok)
#expect(signature.validate([.int, .int, .int]) == .ok)
#expect(signature.validate([]) == .invalidNumberOfArguments)
}

func testVariadicAtLeastOneAndPositional() throws {
@Test func variadicAtLeastOneAndPositional() throws {
let signature = Signature(
[
FunctionArgument("a", type: .concrete(.int)),
],
variadic: FunctionArgument("values", type: .concrete(.int)),
returns: .int
)
XCTAssertTrue(signature.isVariadic)

XCTAssertEqual(signature.validate([.int]), .invalidNumberOfArguments)
XCTAssertEqual(signature.validate([.int, .int]), .ok)
XCTAssertEqual(signature.validate([.int, .int, .int]), .ok)
XCTAssertEqual(signature.validate([]), .invalidNumberOfArguments)
#expect(signature.isVariadic)
#expect(signature.validate([.int]) == .invalidNumberOfArguments)
#expect(signature.validate([.int, .int]) == .ok)
#expect(signature.validate([.int, .int, .int]) == .ok)
#expect(signature.validate([]) == .invalidNumberOfArguments)
}

func testVariadicAndPositional() throws {
@Test func variadicAndPositional() throws {
let signature = Signature(
[
FunctionArgument("a", type: .concrete(.int)),
Expand All @@ -88,10 +80,9 @@ final class SignatureTests: XCTestCase {
variadic: FunctionArgument("things", type: .concrete(.int)),
returns: .int
)
XCTAssertTrue(signature.isVariadic)

XCTAssertEqual(signature.validate([.int]), .invalidNumberOfArguments)
XCTAssertEqual(signature.validate([.int, .int, .int]), .invalidNumberOfArguments)
XCTAssertEqual(signature.validate([.int, .int, .int, .int]), .ok)
#expect(signature.isVariadic)
#expect(signature.validate([.int]) == .invalidNumberOfArguments)
#expect(signature.validate([.int, .int, .int]) == .invalidNumberOfArguments)
#expect(signature.validate([.int, .int, .int, .int]) == .ok)
}
}
Loading

0 comments on commit 69f29db

Please sign in to comment.