From 6be7a382fb6faea5bc971987df10f66ebff8f596 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 12 Mar 2021 10:14:17 +0000 Subject: [PATCH] Added error tests --- .../HummingbirdMustache/Template+Parser.swift | 36 +++++++++++------- Sources/HummingbirdMustache/Template.swift | 6 --- .../TemplateParserTests.swift | 38 +++++++++++++++++++ 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/Sources/HummingbirdMustache/Template+Parser.swift b/Sources/HummingbirdMustache/Template+Parser.swift index 9aa2938..8e714b0 100644 --- a/Sources/HummingbirdMustache/Template+Parser.swift +++ b/Sources/HummingbirdMustache/Template+Parser.swift @@ -1,5 +1,11 @@ extension HBMustacheTemplate { + enum Error: Swift.Error { + case sectionCloseNameIncorrect + case unfinishedName + case expectedSectionEnd + } + static func parse(_ string: String) throws -> [Token] { var parser = HBParser(string) return try parse(&parser, sectionName: nil) @@ -9,14 +15,16 @@ extension HBMustacheTemplate { var tokens: [Token] = [] while !parser.reachedEnd() { let text = try parser.read(untilString: "{{", throwOnOverflow: false, skipToEnd: true) - tokens.append(.text(text.string)) + if text.count > 0 { + tokens.append(.text(text.string)) + } if parser.reachedEnd() { break } switch parser.current() { case "#": parser.unsafeAdvance() - let name = try parseSectionName(&parser) + let name = try parseName(&parser) if parser.current() == "\n" { parser.unsafeAdvance() } @@ -25,7 +33,7 @@ extension HBMustacheTemplate { case "^": parser.unsafeAdvance() - let name = try parseSectionName(&parser) + let name = try parseName(&parser) if parser.current() == "\n" { parser.unsafeAdvance() } @@ -34,9 +42,9 @@ extension HBMustacheTemplate { case "/": parser.unsafeAdvance() - let name = try parseSectionName(&parser) + let name = try parseName(&parser) guard name == sectionName else { - throw HBMustacheError.sectionCloseNameIncorrect + throw Error.sectionCloseNameIncorrect } if parser.current() == "\n" { parser.unsafeAdvance() @@ -45,40 +53,40 @@ extension HBMustacheTemplate { case "{": parser.unsafeAdvance() - let name = try parseSectionName(&parser) - guard try parser.read("}") else { throw HBMustacheError.unfinishedSectionName } + let name = try parseName(&parser) + guard try parser.read("}") else { throw Error.unfinishedName } tokens.append(.unescapedVariable(name)) case "!": parser.unsafeAdvance() - _ = try parseSection(&parser) + _ = try parseComment(&parser) case ">": parser.unsafeAdvance() - let name = try parseSectionName(&parser) + let name = try parseName(&parser) tokens.append(.partial(name)) default: - let name = try parseSectionName(&parser) + let name = try parseName(&parser) tokens.append(.variable(name)) } } // should never get here if reading section guard sectionName == nil else { - throw HBMustacheError.expectedSectionEnd + throw Error.expectedSectionEnd } return tokens } - static func parseSectionName(_ parser: inout HBParser) throws -> String { + static func parseName(_ parser: inout HBParser) throws -> String { parser.read(while: \.isWhitespace) let text = parser.read(while: sectionNameChars ) parser.read(while: \.isWhitespace) - guard try parser.read("}"), try parser.read("}") else { throw HBMustacheError.unfinishedSectionName } + guard try parser.read("}"), try parser.read("}") else { throw Error.unfinishedName } return text.string } - static func parseSection(_ parser: inout HBParser) throws -> String { + static func parseComment(_ parser: inout HBParser) throws -> String { let text = try parser.read(untilString: "}}", throwOnOverflow: true, skipToEnd: true) return text.string } diff --git a/Sources/HummingbirdMustache/Template.swift b/Sources/HummingbirdMustache/Template.swift index d0609d6..027ce67 100644 --- a/Sources/HummingbirdMustache/Template.swift +++ b/Sources/HummingbirdMustache/Template.swift @@ -1,10 +1,4 @@ -enum HBMustacheError: Error { - case sectionCloseNameIncorrect - case unfinishedSectionName - case expectedSectionEnd -} - public class HBMustacheTemplate { public init(string: String) throws { self.tokens = try Self.parse(string) diff --git a/Tests/HummingbirdMustacheTests/TemplateParserTests.swift b/Tests/HummingbirdMustacheTests/TemplateParserTests.swift index c36daee..a762d0d 100644 --- a/Tests/HummingbirdMustacheTests/TemplateParserTests.swift +++ b/Tests/HummingbirdMustacheTests/TemplateParserTests.swift @@ -26,6 +26,44 @@ final class TemplateParserTests: XCTestCase { let template = try HBMustacheTemplate(string: "test {{!section}}") XCTAssertEqual(template.tokens, [.text("test ")]) } + + func testWhitespace() throws { + let template = try HBMustacheTemplate(string: "{{ section }}") + XCTAssertEqual(template.tokens, [.variable("section")]) + } + + func testSectionEndError() throws { + XCTAssertThrowsError(_ = try HBMustacheTemplate(string: "test {{#section}}")) { error in + switch error { + case HBMustacheTemplate.Error.expectedSectionEnd: + break + default: + XCTFail("\(error)") + } + } + } + + func testSectionCloseNameIncorrectError() throws { + XCTAssertThrowsError(_ = try HBMustacheTemplate(string: "test {{#section}}{{/error}}")) { error in + switch error { + case HBMustacheTemplate.Error.sectionCloseNameIncorrect: + break + default: + XCTFail("\(error)") + } + } + } + + func testUnmatchedNameError() throws { + XCTAssertThrowsError(_ = try HBMustacheTemplate(string: "test {{section#}}")) { error in + switch error { + case HBMustacheTemplate.Error.unfinishedName: + break + default: + XCTFail("\(error)") + } + } + } } extension HBMustacheTemplate: Equatable {