Replace raw UTF8 parser with String parser (#6)

* Replace UTF8 parser with String based one

* swift format

* Add parsing errors that include context about where error is

* Remove old error tests
This commit is contained in:
Adam Fowler
2021-03-18 17:26:42 +00:00
committed by GitHub
parent a602593b5d
commit 05740bd7bc
8 changed files with 421 additions and 622 deletions

View File

@@ -0,0 +1,79 @@
import HummingbirdMustache
import XCTest
final class ErrorTests: XCTestCase {
func testSectionCloseNameIncorrect() {
XCTAssertThrowsError(try HBMustacheTemplate(string: """
{{#test}}
{{.}}
{{/test2}}
""")) { error in
switch error {
case let error as HBMustacheTemplate.ParserError:
XCTAssertEqual(error.error as? HBMustacheTemplate.Error, .sectionCloseNameIncorrect)
XCTAssertEqual(error.context.line, "{{/test2}}")
XCTAssertEqual(error.context.lineNumber, 3)
XCTAssertEqual(error.context.columnNumber, 4)
default:
XCTFail("\(error)")
}
}
}
func testUnfinishedName() {
XCTAssertThrowsError(try HBMustacheTemplate(string: """
{{#test}}
{{name}
{{/test2}}
""")) { error in
switch error {
case let error as HBMustacheTemplate.ParserError:
XCTAssertEqual(error.error as? HBMustacheTemplate.Error, .unfinishedName)
XCTAssertEqual(error.context.line, "{{name}")
XCTAssertEqual(error.context.lineNumber, 2)
XCTAssertEqual(error.context.columnNumber, 7)
default:
XCTFail("\(error)")
}
}
}
func testExpectedSectionEnd() {
XCTAssertThrowsError(try HBMustacheTemplate(string: """
{{#test}}
{{.}}
""")) { error in
switch error {
case let error as HBMustacheTemplate.ParserError:
XCTAssertEqual(error.error as? HBMustacheTemplate.Error, .expectedSectionEnd)
XCTAssertEqual(error.context.line, "{{.}}")
XCTAssertEqual(error.context.lineNumber, 2)
XCTAssertEqual(error.context.columnNumber, 6)
default:
XCTFail("\(error)")
}
}
}
func testInvalidSetDelimiter() {
XCTAssertThrowsError(try HBMustacheTemplate(string: """
{{=<% %>=}}
<%.%>
<%={{}}=%>
""")) { error in
switch error {
case let error as HBMustacheTemplate.ParserError:
XCTAssertEqual(error.error as? HBMustacheTemplate.Error, .invalidSetDelimiter)
XCTAssertEqual(error.context.line, "<%={{}}=%>")
XCTAssertEqual(error.context.lineNumber, 3)
XCTAssertEqual(error.context.columnNumber, 4)
default:
XCTFail("\(error)")
}
}
}
}

View File

@@ -5,14 +5,40 @@ final class LibraryTests: XCTestCase {
func testDirectoryLoad() throws {
let fs = FileManager()
try? fs.createDirectory(atPath: "templates", withIntermediateDirectories: false)
let mustache = "<test>{{#value}}<value>{{.}}</value>{{/value}}</test>"
let data = Data(mustache.utf8)
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates")) }
try data.write(to: URL(fileURLWithPath: "templates/test.mustache"))
let mustache = Data("<test>{{#value}}<value>{{.}}</value>{{/value}}</test>".utf8)
try mustache.write(to: URL(fileURLWithPath: "templates/test.mustache"))
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/test.mustache")) }
let library = try HBMustacheLibrary(directory: "./templates")
let object = ["value": ["value1", "value2"]]
XCTAssertEqual(library.render(object, withTemplate: "test"), "<test><value>value1</value><value>value2</value></test>")
}
func testLibraryParserError() throws {
let fs = FileManager()
try? fs.createDirectory(atPath: "templates", withIntermediateDirectories: false)
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates")) }
let mustache = Data("<test>{{#value}}<value>{{.}}</value>{{/value}}</test>".utf8)
try mustache.write(to: URL(fileURLWithPath: "templates/test.mustache"))
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/test.mustache")) }
let mustache2 = Data("""
{{#test}}
{{{name}}
{{/test2}}
""".utf8)
try mustache2.write(to: URL(fileURLWithPath: "templates/error.mustache"))
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/error.mustache")) }
XCTAssertThrowsError(try HBMustacheLibrary(directory: "./templates")) { error in
guard let parserError = error as? HBMustacheLibrary.ParserError else {
XCTFail("\(error)")
return
}
XCTAssertEqual(parserError.filename, "error.mustache")
XCTAssertEqual(parserError.context.line, "{{{name}}")
XCTAssertEqual(parserError.context.lineNumber, 2)
XCTAssertEqual(parserError.context.columnNumber, 10)
}
}
}

View File

@@ -128,6 +128,12 @@ final class MethodTests: XCTestCase {
""")
}
func testListOutput() throws {
let object = [1, 2, 3, 4]
let template = try HBMustacheTemplate(string: "{{#.}}{{.}}{{^last()}}, {{/last()}}{{/.}}")
XCTAssertEqual(template.render(object), "1, 2, 3, 4")
}
func testDictionaryEnumerated() throws {
let template = try HBMustacheTemplate(string: """
{{#enumerated(.)}}<b>{{ key }} = {{ value }}</b>{{/enumerated(.)}}

View File

@@ -31,39 +31,6 @@ final class TemplateParserTests: XCTestCase {
let template = try HBMustacheTemplate(string: "{{ section }}")
XCTAssertEqual(template.tokens, [.variable(name: "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 {