From 232beb2b841f20fef86cfb08f89b2362af06f55a Mon Sep 17 00:00:00 2001 From: Colin Campbell Date: Mon, 29 May 2023 17:56:37 -0500 Subject: [PATCH 1/3] Break apart tests. --- .../LaTeXSwiftUITests/LaTeXSwiftUITests.swift | 192 ---------------- Tests/LaTeXSwiftUITests/ParserTests.swift | 206 ++++++++++++++++++ 2 files changed, 206 insertions(+), 192 deletions(-) create mode 100644 Tests/LaTeXSwiftUITests/ParserTests.swift diff --git a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift b/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift index 8341b24..d475763 100644 --- a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift +++ b/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift @@ -4,198 +4,6 @@ import XCTest final class LaTeXSwiftUITests: XCTestCase { - func assertComponent(_ components: [Component], _ index: Int, _ text: String, _ type: Component.ComponentType, file: StaticString = #file, line: UInt = #line) { - guard index < components.count else { - XCTFail() - return - } - XCTAssertEqual(components[index], Component(text: text, type: type)) - } - - func testParseEmpty() { - let input = "" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 0) - } - - func testParseTextOnly() { - let input = "Hello, World!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - XCTAssertEqual(components[0].text, input) - } - - func testParseDollarOnly() { - let input = "$\\TeX$" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, "\\TeX", .inlineEquation) - } - - func testParseDollarOnly_Normal() { - let input = "Hello, $\\TeX$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 3) - assertComponent(components, 0, "Hello, ", .text) - assertComponent(components, 1, "\\TeX", .inlineEquation) - assertComponent(components, 2, "!", .text) - } - - func testParseDollarOnly_LeftEscaped() { - let input = "Hello, \\$\\TeX$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseDollarOnly_RightEscaped() { - let input = "Hello, $\\TeX\\$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseDoubleDollarOnly() { - let input = "$$\\TeX$$" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, "\\TeX", .texEquation) - } - - func testParseDoubleDollarOnly_Normal() { - let input = "Hello, $$\\TeX$$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 3) - assertComponent(components, 0, "Hello, ", .text) - assertComponent(components, 1, "\\TeX", .texEquation) - assertComponent(components, 2, "!", .text) - } - - func testParseDoubleDollarOnly_LeftEscaped() { - let input = "Hello, \\$$\\TeX$$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseDoubleDollarOnly_RightEscaped() { - let input = "Hello, $$\\TeX\\$$!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBracketsOnly() { - let input = "\\[\\TeX\\]" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, "\\TeX", .blockEquation) - } - - func testParseBracketsOnly_Normal() { - let input = "Hello, \\[\\TeX\\]!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 3) - assertComponent(components, 0, "Hello, ", .text) - assertComponent(components, 1, "\\TeX", .blockEquation) - assertComponent(components, 2, "!", .text) - } - - func testParseBracketsOnly_LeftEscaped() { - let input = "Hello, \\\\[\\TeX\\]!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBracketsOnly_RightEscaped() { - let input = "Hello, \\[\\TeX\\\\]!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBracketsOnly_LineBreak() { - let input = "Hello, \\[\\TeX\n\\\\]!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndOnly() { - let input = "\\begin{equation}\\TeX\\end{equation}" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, "\\TeX", .namedEquation) - } - - func testParseBeginEndOnly_Normal() { - let input = "Hello, \\begin{equation}\\TeX\\end{equation}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 3) - assertComponent(components, 0, "Hello, ", .text) - assertComponent(components, 1, "\\TeX", .namedEquation) - assertComponent(components, 2, "!", .text) - } - - func testParseBeginEndOnly_LeftEscaped() { - let input = "Hello, \\\\begin{equation}\\TeX\\end{equation}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndOnly_RightEscaped() { - let input = "Hello, \\begin{equation}\\TeX\\\\end{equation}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndOnly_LineBreak() { - let input = "Hello, \\begin{equation}\\TeX\n\\\\end{equation}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndStarOnly() { - let input = "\\begin{equation*}\\TeX\\end{equation*}" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, "\\TeX", .namedNoNumberEquation) - } - - func testParseBeginEndStarOnly_Normal() { - let input = "Hello, \\begin{equation*}\\TeX\\end{equation*}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 3) - assertComponent(components, 0, "Hello, ", .text) - assertComponent(components, 1, "\\TeX", .namedNoNumberEquation) - assertComponent(components, 2, "!", .text) - } - - func testParseBeginEndStarOnly_LeftEscaped() { - let input = "Hello, \\\\begin{equation*}\\TeX\\end{equation*}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndStarOnly_RightEscaped() { - let input = "Hello, \\begin{equation*}\\TeX\\\\end{equation*}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testParseBeginEndStarOnly_LineBreak() { - let input = "Hello, \\begin{equation*}\\TeX\n\\\\end{equation*}!" - let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - func testSVGGeometry_parseAlignment() { let input = "\"vertical-align: -1.602ex;\"" let value = SVGGeometry.parseAlignment(from: input) diff --git a/Tests/LaTeXSwiftUITests/ParserTests.swift b/Tests/LaTeXSwiftUITests/ParserTests.swift new file mode 100644 index 0000000..d40ad99 --- /dev/null +++ b/Tests/LaTeXSwiftUITests/ParserTests.swift @@ -0,0 +1,206 @@ +// +// ParserTests.swift +// +// +// Created by Colin Campbell on 5/29/23. +// + +import MathJaxSwift +import XCTest +@testable import LaTeXSwiftUI + +final class ParserTests: XCTestCase { + + func assertComponent(_ components: [Component], _ index: Int, _ text: String, _ type: Component.ComponentType, file: StaticString = #file, line: UInt = #line) { + guard index < components.count else { + XCTFail() + return + } + XCTAssertEqual(components[index], Component(text: text, type: type)) + } + + func testParseEmpty() { + let input = "" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 0) + } + + func testParseTextOnly() { + let input = "Hello, World!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + XCTAssertEqual(components[0].text, input) + } + + func testParseDollarOnly() { + let input = "$\\TeX$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, "\\TeX", .inlineEquation) + } + + func testParseDollarOnly_Normal() { + let input = "Hello, $\\TeX$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 0, "Hello, ", .text) + assertComponent(components, 1, "\\TeX", .inlineEquation) + assertComponent(components, 2, "!", .text) + } + + func testParseDollarOnly_LeftEscaped() { + let input = "Hello, \\$\\TeX$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseDollarOnly_RightEscaped() { + let input = "Hello, $\\TeX\\$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseDoubleDollarOnly() { + let input = "$$\\TeX$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, "\\TeX", .texEquation) + } + + func testParseDoubleDollarOnly_Normal() { + let input = "Hello, $$\\TeX$$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 0, "Hello, ", .text) + assertComponent(components, 1, "\\TeX", .texEquation) + assertComponent(components, 2, "!", .text) + } + + func testParseDoubleDollarOnly_LeftEscaped() { + let input = "Hello, \\$$\\TeX$$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseDoubleDollarOnly_RightEscaped() { + let input = "Hello, $$\\TeX\\$$!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBracketsOnly() { + let input = "\\[\\TeX\\]" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, "\\TeX", .blockEquation) + } + + func testParseBracketsOnly_Normal() { + let input = "Hello, \\[\\TeX\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 0, "Hello, ", .text) + assertComponent(components, 1, "\\TeX", .blockEquation) + assertComponent(components, 2, "!", .text) + } + + func testParseBracketsOnly_LeftEscaped() { + let input = "Hello, \\\\[\\TeX\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBracketsOnly_RightEscaped() { + let input = "Hello, \\[\\TeX\\\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBracketsOnly_LineBreak() { + let input = "Hello, \\[\\TeX\n\\\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndOnly() { + let input = "\\begin{equation}\\TeX\\end{equation}" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, "\\TeX", .namedEquation) + } + + func testParseBeginEndOnly_Normal() { + let input = "Hello, \\begin{equation}\\TeX\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 0, "Hello, ", .text) + assertComponent(components, 1, "\\TeX", .namedEquation) + assertComponent(components, 2, "!", .text) + } + + func testParseBeginEndOnly_LeftEscaped() { + let input = "Hello, \\\\begin{equation}\\TeX\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndOnly_RightEscaped() { + let input = "Hello, \\begin{equation}\\TeX\\\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndOnly_LineBreak() { + let input = "Hello, \\begin{equation}\\TeX\n\\\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndStarOnly() { + let input = "\\begin{equation*}\\TeX\\end{equation*}" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, "\\TeX", .namedNoNumberEquation) + } + + func testParseBeginEndStarOnly_Normal() { + let input = "Hello, \\begin{equation*}\\TeX\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 0, "Hello, ", .text) + assertComponent(components, 1, "\\TeX", .namedNoNumberEquation) + assertComponent(components, 2, "!", .text) + } + + func testParseBeginEndStarOnly_LeftEscaped() { + let input = "Hello, \\\\begin{equation*}\\TeX\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndStarOnly_RightEscaped() { + let input = "Hello, \\begin{equation*}\\TeX\\\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + + func testParseBeginEndStarOnly_LineBreak() { + let input = "Hello, \\begin{equation*}\\TeX\n\\\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, input, .text) + } + +} From 48012d27cd6b400be760032a9b7a4d31988d308b Mon Sep 17 00:00:00 2001 From: Colin Campbell Date: Mon, 29 May 2023 17:57:05 -0500 Subject: [PATCH 2/3] Fix missing import. --- Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift b/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift index 27a4b08..78d7860 100644 --- a/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift +++ b/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift @@ -24,6 +24,7 @@ // import Foundation +import CoreGraphics extension CGRect: Hashable { From 45ccfcf293aba98215bb3021e961a7d1073e7396 Mon Sep 17 00:00:00 2001 From: Colin Campbell Date: Mon, 29 May 2023 18:30:30 -0500 Subject: [PATCH 3/3] Fix parsing block equations with leading/trailing newlines and update tests. --- Sources/LaTeXSwiftUI/Models/Parser.swift | 8 +- ...SwiftUITests.swift => GeometryTests.swift} | 2 +- Tests/LaTeXSwiftUITests/ParserTests.swift | 99 ++++++++++++++++--- 3 files changed, 92 insertions(+), 17 deletions(-) rename Tests/LaTeXSwiftUITests/{LaTeXSwiftUITests.swift => GeometryTests.swift} (98%) diff --git a/Sources/LaTeXSwiftUI/Models/Parser.swift b/Sources/LaTeXSwiftUI/Models/Parser.swift index 78c400a..9661e87 100644 --- a/Sources/LaTeXSwiftUI/Models/Parser.swift +++ b/Sources/LaTeXSwiftUI/Models/Parser.swift @@ -49,28 +49,28 @@ internal struct Parser { /// An TeX-style block equation component. static let tex = EquationComponent( - regex: #/\$\$(.*?)\$\$/#, + regex: #/\$\$\s*(.*?)\s*\$\$/#, terminatingRegex: #/\$\$/#, equation: .texEquation, supportsRecursion: false) /// A block equation. static let block = EquationComponent( - regex: #/\\\[(.*?)\\\]/#, + regex: #/\\\[\s*(.*?)\s*\\\]/#, terminatingRegex: #/\\\]/#, equation: .blockEquation, supportsRecursion: false) /// A named equation component. static let named = EquationComponent( - regex: #/\\begin{equation}(.*?)\\end{equation}/#, + regex: #/\\begin{equation}\s*(.*?)\s*\\end{equation}/#, terminatingRegex: #/\\end{equation}/#, equation: .namedEquation, supportsRecursion: true) /// A named no number equation component. static let namedNoNumber = EquationComponent( - regex: #/\\begin{equation\*}(.*?)\\end{equation\*}/#, + regex: #/\\begin{equation\*}\s*(.*?)\s*\\end{equation\*}/#, terminatingRegex: #/\\end{equation\*}/#, equation: .namedNoNumberEquation, supportsRecursion: true) diff --git a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift b/Tests/LaTeXSwiftUITests/GeometryTests.swift similarity index 98% rename from Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift rename to Tests/LaTeXSwiftUITests/GeometryTests.swift index d475763..8de22a0 100644 --- a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift +++ b/Tests/LaTeXSwiftUITests/GeometryTests.swift @@ -2,7 +2,7 @@ import MathJaxSwift import XCTest @testable import LaTeXSwiftUI -final class LaTeXSwiftUITests: XCTestCase { +final class GeometryTests: XCTestCase { func testSVGGeometry_parseAlignment() { let input = "\"vertical-align: -1.602ex;\"" diff --git a/Tests/LaTeXSwiftUITests/ParserTests.swift b/Tests/LaTeXSwiftUITests/ParserTests.swift index d40ad99..cc227e9 100644 --- a/Tests/LaTeXSwiftUITests/ParserTests.swift +++ b/Tests/LaTeXSwiftUITests/ParserTests.swift @@ -92,6 +92,30 @@ final class ParserTests: XCTestCase { assertComponent(components, 0, input, .text) } + func testParseDoubleDollarOnly_LeadingLineBreak() { + let equation = "\nf(x)=5x+2" + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + + func testParseDoubleDollarOnly_TrailingLineBreak() { + let equation = "f(x)=5x+2\n" + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + + func testParseDoubleDollarOnly_Whitespace() { + let equation = " \nf(x)=5x+2\n " + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + func testParseBracketsOnly() { let input = "\\[\\TeX\\]" let components = Parser.parse(input) @@ -122,11 +146,28 @@ final class ParserTests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBracketsOnly_LineBreak() { - let input = "Hello, \\[\\TeX\n\\\\]!" + func testParseBracketsOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\[\(equation)\\]!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) + } + + func testParseBracketsOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\[\(equation)\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) + } + + func testParseBracketsOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\[\(equation)\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) } func testParseBeginEndOnly() { @@ -159,11 +200,28 @@ final class ParserTests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBeginEndOnly_LineBreak() { - let input = "Hello, \\begin{equation}\\TeX\n\\\\end{equation}!" + func testParseBeginEndOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) + } + + func testParseBeginEndOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) + } + + func testParseBeginEndOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) } func testParseBeginEndStarOnly() { @@ -196,11 +254,28 @@ final class ParserTests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBeginEndStarOnly_LineBreak() { - let input = "Hello, \\begin{equation*}\\TeX\n\\\\end{equation*}!" + func testParseBeginEndStarOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) + } + + func testParseBeginEndStarOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) + } + + func testParseBeginEndStarOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) } }