diff --git a/Tests/PoieticCoreTests/Design/DesignTests.swift b/Tests/PoieticCoreTests/Design/DesignTests.swift index a29533e5..34efc723 100644 --- a/Tests/PoieticCoreTests/Design/DesignTests.swift +++ b/Tests/PoieticCoreTests/Design/DesignTests.swift @@ -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) diff --git a/Tests/PoieticCoreTests/Expression/ExpressionParserTests.swift b/Tests/PoieticCoreTests/Expression/ExpressionParserTests.swift index ea3db19f..8e44a672 100644 --- a/Tests/PoieticCoreTests/Expression/ExpressionParserTests.swift +++ b/Tests/PoieticCoreTests/Expression/ExpressionParserTests.swift @@ -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) } } diff --git a/Tests/PoieticCoreTests/Expression/FunctionTests.swift b/Tests/PoieticCoreTests/Expression/FunctionTests.swift index 3e3a3838..4c4857db 100644 --- a/Tests/PoieticCoreTests/Expression/FunctionTests.swift +++ b/Tests/PoieticCoreTests/Expression/FunctionTests.swift @@ -5,64 +5,57 @@ // 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)), @@ -70,15 +63,14 @@ final class SignatureTests: XCTestCase { 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)), @@ -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) } } diff --git a/Tests/PoieticCoreTests/Expression/LexerTests.swift b/Tests/PoieticCoreTests/Expression/LexerTests.swift index cbf5667f..09592cd5 100644 --- a/Tests/PoieticCoreTests/Expression/LexerTests.swift +++ b/Tests/PoieticCoreTests/Expression/LexerTests.swift @@ -1,247 +1,244 @@ // -// File.swift -// +// LexerTests.swift +// // // Created by Stefan Urbanek on 01/07/2022. // -import XCTest +import Testing @testable import PoieticCore -final class LexerTests: XCTestCase { - func testAcceptFunction() throws { - // TODO: This is a scanner test. (originally it was in the lexer) +@Suite struct LexerTests { + @Test func acceptFunction() throws { let lexer = ExpressionLexer(string: " ") - XCTAssertNotNil(lexer.scanner.currentChar) - XCTAssertTrue(lexer.scanner.scan(\.isWhitespace)) - XCTAssertNil(lexer.scanner.currentChar) - XCTAssertTrue(lexer.scanner.atEnd) + #expect(lexer.scanner.currentChar != nil) + // Swift Testing macro expansion is complaining about having \.isWhitespace within #expect + let flag = lexer.scanner.scan(\.isWhitespace) + #expect(flag) + #expect(lexer.scanner.currentChar == nil) + #expect(lexer.scanner.atEnd) } - func testEmpty() throws { + @Test func emptyString() throws { var lexer = ExpressionLexer(string: "") - XCTAssertTrue(lexer.atEnd) - XCTAssertEqual(lexer.next().type, ExpressionTokenType.empty) - XCTAssertEqual(lexer.next().type, ExpressionTokenType.empty) + #expect(lexer.atEnd) + #expect(lexer.next().type == .empty) + #expect(lexer.next().type == .empty) } - func testSpace() throws { + @Test func spaceOnly() throws { var lexer = ExpressionLexer(string: " ") - XCTAssertFalse(lexer.atEnd) - XCTAssertEqual(lexer.next().type, ExpressionTokenType.empty) - XCTAssertTrue(lexer.atEnd) + #expect(!lexer.atEnd) + #expect(lexer.next().type == .empty) + #expect(lexer.atEnd) } - // func testUnexpected() throws { - // var lexer = ExpressionLexer(string: "$") - // let token = lexer.next() - // - // XCTAssertEqual(token.type, ExpressionTokenType.error(.unexpectedCharacter)) - // XCTAssertEqual(token.text, "$") - // } - + // MARK: Numbers - func testInteger() throws { + @Test func integerToken() throws { var lexer = ExpressionLexer(string: "1234") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "1234") + + #expect(token.type == .int) + #expect(token.text == "1234") } - func testThousandsSeparator() throws { + @Test func thousandsSeparator() throws { var lexer = ExpressionLexer(string: "123_456_789") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "123_456_789") + + #expect(token.type == .int) + #expect(token.text == "123_456_789") } - func testMultipleInts() throws { + @Test func multipleInts() throws { var lexer = ExpressionLexer(string: "1 22 333 ") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "1") + + #expect(token.type == .int) + #expect(token.text == "1") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "22") + #expect(token.type == .int) + #expect(token.text == "22") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "333") + #expect(token.type == .int) + #expect(token.text == "333") } - func testInvalidInteger() throws { + @Test func invalidInteger() throws { var lexer = ExpressionLexer(string: "1234x") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.error(.invalidCharacterInNumber)) - XCTAssertEqual(token.text, "1234x") + #expect(token.type == .error(.invalidCharacterInNumber)) + #expect(token.text == "1234x") } - func testFloat() throws { + @Test func floatTokens() throws { var lexer = ExpressionLexer(string: "10.20 10e20 10.20e30 10.20e-30") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.double) - XCTAssertEqual(token.text, "10.20") + #expect(token.type == .double) + #expect(token.text == "10.20") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.double) - XCTAssertEqual(token.text, "10e20") + #expect(token.type == .double) + #expect(token.text == "10e20") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.double) - XCTAssertEqual(token.text, "10.20e30") + #expect(token.type == .double) + #expect(token.text == "10.20e30") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.double) - XCTAssertEqual(token.text, "10.20e-30") + #expect(token.type == .double) + #expect(token.text == "10.20e-30") } - func testInvalidFloat() throws { + @Test func invalidFloat() throws { var lexer = ExpressionLexer(string: "1. 2.x 3ex") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.error(.numberExpected)) - XCTAssertEqual(token.text, "1. ") + #expect(token.type == .error(.numberExpected)) + #expect(token.text == "1. ") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.error(.numberExpected)) - XCTAssertEqual(token.text, "2.x") + #expect(token.type == .error(.numberExpected)) + #expect(token.text == "2.x") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.error(.numberExpected)) - XCTAssertEqual(token.text, "3ex") + #expect(token.type == .error(.numberExpected)) + #expect(token.text == "3ex") } - func testIdentifier() throws { + @Test func identifierToken() throws { var lexer = ExpressionLexer(string: "an_identifier_1") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.identifier) - XCTAssertEqual(token.text, "an_identifier_1") + #expect(token.type == .identifier) + #expect(token.text == "an_identifier_1") } // MARK: Punctuation and operators - func testPunctuation() throws { + @Test func punctuationToken() throws { var lexer = ExpressionLexer(string: "( , )") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.leftParen) - XCTAssertEqual(token.text, "(") + #expect(token.type == .leftParen) + #expect(token.text == "(") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.comma) - XCTAssertEqual(token.text, ",") + #expect(token.type == .comma) + #expect(token.text == ",") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.rightParen) - XCTAssertEqual(token.text, ")") + #expect(token.type == .rightParen) + #expect(token.text == ")") } - func testOperator() throws { + @Test func operatorToken() throws { var lexer = ExpressionLexer(string: "+ - * / %") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "+") + #expect(token.type == .operator) + #expect(token.text == "+") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "-") + #expect(token.type == .operator) + #expect(token.text == "-") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "*") + #expect(token.type == .operator) + #expect(token.text == "*") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "/") + #expect(token.type == .operator) + #expect(token.text == "/") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "%") + #expect(token.type == .operator) + #expect(token.text == "%") } - func testComparisonOperator() throws { + @Test func comparisonOperator() throws { var lexer = ExpressionLexer(string: "> >= < <= == != !") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, ">") + #expect(token.type == .operator) + #expect(token.text == ">") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, ">=") + #expect(token.type == .operator) + #expect(token.text == ">=") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "<") + #expect(token.type == .operator) + #expect(token.text == "<") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "<=") + #expect(token.type == .operator) + #expect(token.text == "<=") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "==") + #expect(token.type == .operator) + #expect(token.text == "==") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "!=") + #expect(token.type == .operator) + #expect(token.text == "!=") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "!") + #expect(token.type == .operator) + #expect(token.text == "!") } - func testMinusAsOperator() throws { + @Test func minusAsOperator() throws { var lexer = ExpressionLexer(string: "1-2") var token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "1") + #expect(token.type == .int) + #expect(token.text == "1") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.operator) - XCTAssertEqual(token.text, "-") + #expect(token.type == .operator) + #expect(token.text == "-") token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.int) - XCTAssertEqual(token.text, "2") + #expect(token.type == .int) + #expect(token.text == "2") } // MARK: Trivia - func testEmptyTrivia() throws { + @Test func emptyTrivia() throws { var lexer = ExpressionLexer(string: " ") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.empty) - XCTAssertEqual(token.text, "") - XCTAssertEqual(token.fullText, " ") + #expect(token.type == .empty) + #expect(token.text == "") + #expect(token.fullText == " ") } - func testTrailingTrivia() throws { + @Test func trailingTrivia() throws { var lexer = ExpressionLexer(string: "thing ") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.identifier) - XCTAssertEqual(token.text, "thing") - XCTAssertEqual(token.trailingTrivia, " ") + #expect(token.type == .identifier) + #expect(token.text == "thing") + #expect(token.trailingTrivia == " ") } - func testTrailingTriviaComment() throws { + @Test func trailingTriviaComment() throws { var lexer = ExpressionLexer(string: "thing # This\nThat") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.identifier) - XCTAssertEqual(token.text, "thing") - XCTAssertEqual(token.trailingTrivia, " # This") + #expect(token.type == .identifier) + #expect(token.text == "thing") + #expect(token.trailingTrivia == " # This") } - func testLeadingTriviaComment() throws { + @Test func leadingTriviaComment() throws { var lexer = ExpressionLexer(string: "# Comment\nthing") let token = lexer.next() - XCTAssertEqual(token.type, ExpressionTokenType.identifier) - XCTAssertEqual(token.text, "thing") - XCTAssertEqual(token.leadingTrivia, "# Comment\n") + #expect(token.type == .identifier) + #expect(token.text == "thing") + #expect(token.leadingTrivia == "# Comment\n") } } diff --git a/Tests/PoieticCoreTests/Foreign/CSVReaderTests.swift b/Tests/PoieticCoreTests/Foreign/CSVReaderTests.swift index e33665c2..0dba2666 100644 --- a/Tests/PoieticCoreTests/Foreign/CSVReaderTests.swift +++ b/Tests/PoieticCoreTests/Foreign/CSVReaderTests.swift @@ -4,152 +4,93 @@ // Created by Stefan Urbanek on 2021/8/31. // -import XCTest +import Testing @testable import PoieticCore -final class CSVReaderTests: XCTestCase { - func testEmptyReader() throws { - var reader:CSVReader - var token: CSVReader.Token - - reader = CSVReader("") - token = reader.nextToken() - - XCTAssertEqual(token, .empty) +@Suite struct CSVReaderTests { + @Test func testEmptyReader() throws { + let reader = CSVReader("") + #expect(reader.nextToken() == .empty) } - func testWhitespaceRows() throws { - var reader:CSVReader - var token: CSVReader.Token - - reader = CSVReader(" ") - token = reader.nextToken() - XCTAssertEqual(token, .value(" ")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) - - reader = CSVReader("\n") - token = reader.nextToken() - XCTAssertEqual(token, .recordSeparator) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + @Test func testWhitespaceRows() throws { + let reader = CSVReader(" ") + #expect(reader.nextToken() == .value(" ")) + #expect(reader.nextToken() == .empty) + + let reader2 = CSVReader("\n") + #expect(reader2.nextToken() == .recordSeparator) + #expect(reader2.nextToken() == .empty) } - func testRowTokens() throws { - var reader:CSVReader - var token: CSVReader.Token - - reader = CSVReader("one,two,three") - token = reader.nextToken() - XCTAssertEqual(token, .value("one")) - token = reader.nextToken() - XCTAssertEqual(token, .fieldSeparator) - token = reader.nextToken() - XCTAssertEqual(token, .value("two")) - token = reader.nextToken() - XCTAssertEqual(token, .fieldSeparator) - token = reader.nextToken() - XCTAssertEqual(token, .value("three")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + @Test func testRowTokens() throws { + let reader = CSVReader("one,two,three") + + #expect(reader.nextToken() == .value("one")) + #expect(reader.nextToken() == .fieldSeparator) + #expect(reader.nextToken() == .value("two")) + #expect(reader.nextToken() == .fieldSeparator) + #expect(reader.nextToken() == .value("three")) + #expect(reader.nextToken() == .empty) } - func testCustomDelimiters() throws { + @Test func testCustomDelimiters() throws { let reader = CSVReader("1@2|10@20", - options: CSVOptions(fieldDelimiter:"@", - recordDelimiter:"|")) + options: CSVOptions(fieldDelimiter:"@", recordDelimiter:"|")) - let row1 = reader.next() - XCTAssertEqual(row1, ["1", "2"]) - - let row2 = reader.next() - XCTAssertEqual(row2, ["10", "20"]) + #expect(reader.next() == ["1", "2"]) + #expect(reader.next() == ["10", "20"]) } - func testQuote() throws { - var reader:CSVReader - var token: CSVReader.Token - - reader = CSVReader("\"quoted\"") - token = reader.nextToken() - XCTAssertEqual(token, .value("quoted")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) - - reader = CSVReader("\"quoted,comma\"") - token = reader.nextToken() - XCTAssertEqual(token, .value("quoted,comma")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) - - reader = CSVReader("\"quoted\nnewline\"") - token = reader.nextToken() - XCTAssertEqual(token, .value("quoted\nnewline")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + @Test func testQuote() throws { + let reader = CSVReader("\"quoted\"") + #expect(reader.nextToken() == .value("quoted")) + #expect(reader.nextToken() == .empty) + + let reader2 = CSVReader("\"quoted,comma\"") + #expect(reader2.nextToken() == .value("quoted,comma")) + #expect(reader2.nextToken() == .empty) + + let reader3 = CSVReader("\"quoted\nnewline\"") + #expect(reader3.nextToken() == .value("quoted\nnewline")) + #expect(reader3.nextToken() == .empty) } - func testQuoteEscape() throws { - var reader:CSVReader - var token: CSVReader.Token - - reader = CSVReader("\"\"\"\"") - token = reader.nextToken() - XCTAssertEqual(token, .value("\"")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + + @Test func testQuoteEscape() throws { + let reader = CSVReader("\"\"\"\"") + #expect(reader.nextToken() == .value("\"")) + #expect(reader.nextToken() == .empty) } - func testWeirdQuote() throws { - var reader:CSVReader - var token: CSVReader.Token - + + @Test func testWeirdQuote() throws { // The following behavior was observed with Numbers and with MS Word - // This is broken but should be parsed into a signle quote value - reader = CSVReader("\"\"\"") - token = reader.nextToken() - XCTAssertEqual(token, .value("\"")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + + let reader = CSVReader("\"\"\"") + #expect(reader.nextToken() == .value("\"")) + #expect(reader.nextToken() == .empty) // This is broken but should be parsed into a signle quote value - reader = CSVReader("\"quoted\" value") - token = reader.nextToken() - XCTAssertEqual(token, .value("quoted value")) - token = reader.nextToken() - XCTAssertEqual(token, .empty) + let reader2 = CSVReader("\"quoted\" value") + #expect(reader2.nextToken() == .value("quoted value")) + #expect(reader2.nextToken() == .empty) } - func testRow() throws { - var reader: CSVReader - var row: [String]? - - reader = CSVReader("one,two,three") - row = reader.next() - - XCTAssertEqual(row, ["one", "two", "three"]) - XCTAssertNil(reader.next()) + @Test func testRow() throws { + let reader = CSVReader("one,two,three") + #expect(reader.next() == ["one", "two", "three"]) + #expect(reader.next() == nil) } - func testQuotedRow() throws { - var reader: CSVReader - var row: [String]? - - reader = CSVReader("one,\"quoted value\",three") - row = reader.next() - - XCTAssertEqual(row, ["one", "quoted value", "three"]) + @Test func testQuotedRow() throws { + let reader = CSVReader("one,\"quoted value\",three") + #expect(reader.next() == ["one", "quoted value", "three"]) } - func testMultipleRows() throws { - var reader: CSVReader - var row: [String]? - - reader = CSVReader("11,12,13\n21,22,23\n31,32,33") - row = reader.next() - XCTAssertEqual(row, ["11", "12", "13"]) - row = reader.next() - XCTAssertEqual(row, ["21", "22", "23"]) - row = reader.next() - XCTAssertEqual(row, ["31", "32", "33"]) - } + @Test func testMultipleRows() throws { + let reader = CSVReader("11,12,13\n21,22,23\n31,32,33") + #expect(reader.next() == ["11", "12", "13"]) + #expect(reader.next() == ["21", "22", "23"]) + #expect(reader.next() == ["31", "32", "33"]) + } } diff --git a/Tests/PoieticCoreTests/Foreign/CSVWriterTests.swift b/Tests/PoieticCoreTests/Foreign/CSVWriterTests.swift index dae42286..ee78e4e7 100644 --- a/Tests/PoieticCoreTests/Foreign/CSVWriterTests.swift +++ b/Tests/PoieticCoreTests/Foreign/CSVWriterTests.swift @@ -1,27 +1,27 @@ // -// File.swift -// +// CSVWriterTests.swift +// // // Created by Stefan Urbanek on 12/09/2023. // -import XCTest +import Testing @testable import PoieticCore -final class CSVFormatterTests: XCTestCase { - func testQuoteEmpty() throws { +@Suite struct CSVFormatterTests { + @Test func testQuoteEmpty() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.quote(""), "") + #expect(formatter.quote("") == "") } - func testQuoteNotNeeded() throws { + @Test func testQuoteNotNeeded() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.quote("10"), "10") - XCTAssertEqual(formatter.quote("abc"), "abc") - XCTAssertEqual(formatter.quote("one two"), "one two") - XCTAssertEqual(formatter.quote("-"), "-") - XCTAssertEqual(formatter.quote(" "), " ") + #expect(formatter.quote("10") == "10") + #expect(formatter.quote("abc") == "abc") + #expect(formatter.quote("one two") == "one two") + #expect(formatter.quote("-") == "-") + #expect(formatter.quote(" ") == " ") } - func testQuoteQuote() throws { + @Test func testQuoteQuote() throws { let formatter = CSVFormatter() // Single quote yields four: // @@ -31,27 +31,26 @@ final class CSVFormatterTests: XCTestCase { // opening --^^ ^ // | | // escaping---+ +---- closing - XCTAssertEqual(formatter.quote("\""), "\"\"\"\"") - XCTAssertEqual(formatter.quote("middle\"quote"), "\"middle\"\"quote\"") - XCTAssertEqual(formatter.quote("\n"), "\"\n\"") + #expect(formatter.quote("\"") == "\"\"\"\"") + #expect(formatter.quote("middle\"quote") == "\"middle\"\"quote\"") + #expect(formatter.quote("\n") == "\"\n\"") } - func testQuoteSeparators() throws { + @Test func testQuoteSeparators() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.quote("one,two"), "\"one,two\"") - XCTAssertEqual(formatter.quote("new\nline"), "\"new\nline\"") + #expect(formatter.quote("one,two") == "\"one,two\"") + #expect(formatter.quote("new\nline") == "\"new\nline\"") } - func testFormatRowEmpty() throws { + @Test func testFormatRowEmpty() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.format([]), "") + #expect(formatter.format([]) == "") } - func testFormatRow() throws { + @Test func testFormatRow() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.format(["one","two"]), "one,two") + #expect(formatter.format(["one","two"]) == "one,two") } - func testFormatRowQuote() throws { + @Test func testFormatRowQuote() throws { let formatter = CSVFormatter() - XCTAssertEqual(formatter.format(["one,two","three"]), - "\"one,two\",three") + #expect(formatter.format(["one,two","three"]) == "\"one,two\",three") } }