Added error tests
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
|
|
||||||
extension HBMustacheTemplate {
|
extension HBMustacheTemplate {
|
||||||
|
enum Error: Swift.Error {
|
||||||
|
case sectionCloseNameIncorrect
|
||||||
|
case unfinishedName
|
||||||
|
case expectedSectionEnd
|
||||||
|
}
|
||||||
|
|
||||||
static func parse(_ string: String) throws -> [Token] {
|
static func parse(_ string: String) throws -> [Token] {
|
||||||
var parser = HBParser(string)
|
var parser = HBParser(string)
|
||||||
return try parse(&parser, sectionName: nil)
|
return try parse(&parser, sectionName: nil)
|
||||||
@@ -9,14 +15,16 @@ extension HBMustacheTemplate {
|
|||||||
var tokens: [Token] = []
|
var tokens: [Token] = []
|
||||||
while !parser.reachedEnd() {
|
while !parser.reachedEnd() {
|
||||||
let text = try parser.read(untilString: "{{", throwOnOverflow: false, skipToEnd: true)
|
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() {
|
if parser.reachedEnd() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch parser.current() {
|
switch parser.current() {
|
||||||
case "#":
|
case "#":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
if parser.current() == "\n" {
|
if parser.current() == "\n" {
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
}
|
}
|
||||||
@@ -25,7 +33,7 @@ extension HBMustacheTemplate {
|
|||||||
|
|
||||||
case "^":
|
case "^":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
if parser.current() == "\n" {
|
if parser.current() == "\n" {
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
}
|
}
|
||||||
@@ -34,9 +42,9 @@ extension HBMustacheTemplate {
|
|||||||
|
|
||||||
case "/":
|
case "/":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
guard name == sectionName else {
|
guard name == sectionName else {
|
||||||
throw HBMustacheError.sectionCloseNameIncorrect
|
throw Error.sectionCloseNameIncorrect
|
||||||
}
|
}
|
||||||
if parser.current() == "\n" {
|
if parser.current() == "\n" {
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
@@ -45,40 +53,40 @@ extension HBMustacheTemplate {
|
|||||||
|
|
||||||
case "{":
|
case "{":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
guard try parser.read("}") else { throw HBMustacheError.unfinishedSectionName }
|
guard try parser.read("}") else { throw Error.unfinishedName }
|
||||||
tokens.append(.unescapedVariable(name))
|
tokens.append(.unescapedVariable(name))
|
||||||
|
|
||||||
case "!":
|
case "!":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
_ = try parseSection(&parser)
|
_ = try parseComment(&parser)
|
||||||
|
|
||||||
case ">":
|
case ">":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
tokens.append(.partial(name))
|
tokens.append(.partial(name))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseName(&parser)
|
||||||
tokens.append(.variable(name))
|
tokens.append(.variable(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// should never get here if reading section
|
// should never get here if reading section
|
||||||
guard sectionName == nil else {
|
guard sectionName == nil else {
|
||||||
throw HBMustacheError.expectedSectionEnd
|
throw Error.expectedSectionEnd
|
||||||
}
|
}
|
||||||
return tokens
|
return tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
static func parseSectionName(_ parser: inout HBParser) throws -> String {
|
static func parseName(_ parser: inout HBParser) throws -> String {
|
||||||
parser.read(while: \.isWhitespace)
|
parser.read(while: \.isWhitespace)
|
||||||
let text = parser.read(while: sectionNameChars )
|
let text = parser.read(while: sectionNameChars )
|
||||||
parser.read(while: \.isWhitespace)
|
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
|
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)
|
let text = try parser.read(untilString: "}}", throwOnOverflow: true, skipToEnd: true)
|
||||||
return text.string
|
return text.string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
|
|
||||||
enum HBMustacheError: Error {
|
|
||||||
case sectionCloseNameIncorrect
|
|
||||||
case unfinishedSectionName
|
|
||||||
case expectedSectionEnd
|
|
||||||
}
|
|
||||||
|
|
||||||
public class HBMustacheTemplate {
|
public class HBMustacheTemplate {
|
||||||
public init(string: String) throws {
|
public init(string: String) throws {
|
||||||
self.tokens = try Self.parse(string)
|
self.tokens = try Self.parse(string)
|
||||||
|
|||||||
@@ -26,6 +26,44 @@ final class TemplateParserTests: XCTestCase {
|
|||||||
let template = try HBMustacheTemplate(string: "test {{!section}}")
|
let template = try HBMustacheTemplate(string: "test {{!section}}")
|
||||||
XCTAssertEqual(template.tokens, [.text("test ")])
|
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 {
|
extension HBMustacheTemplate: Equatable {
|
||||||
|
|||||||
Reference in New Issue
Block a user