Warnings--

This commit is contained in:
David Jennes
2022-07-27 04:47:19 +02:00
parent e6ee27f64e
commit f32c772b99
39 changed files with 772 additions and 614 deletions

View File

@@ -4,35 +4,35 @@ import XCTest
final class ContextTests: XCTestCase {
func testContextSubscripting() {
describe("Context Subscripting") {
describe("Context Subscripting") { test in
var context = Context()
$0.before {
test.before {
context = Context(dictionary: ["name": "Kyle"])
}
$0.it("allows you to get a value via subscripting") {
test.it("allows you to get a value via subscripting") {
try expect(context["name"] as? String) == "Kyle"
}
$0.it("allows you to set a value via subscripting") {
test.it("allows you to set a value via subscripting") {
context["name"] = "Katie"
try expect(context["name"] as? String) == "Katie"
}
$0.it("allows you to remove a value via subscripting") {
test.it("allows you to remove a value via subscripting") {
context["name"] = nil
try expect(context["name"]).to.beNil()
}
$0.it("allows you to retrieve a value from a parent") {
test.it("allows you to retrieve a value from a parent") {
try context.push {
try expect(context["name"] as? String) == "Kyle"
}
}
$0.it("allows you to override a parent's value") {
test.it("allows you to override a parent's value") {
try context.push {
context["name"] = "Katie"
try expect(context["name"] as? String) == "Katie"
@@ -42,13 +42,13 @@ final class ContextTests: XCTestCase {
}
func testContextRestoration() {
describe("Context Restoration") {
describe("Context Restoration") { test in
var context = Context()
$0.before {
test.before {
context = Context(dictionary: ["name": "Kyle"])
}
$0.it("allows you to pop to restore previous state") {
test.it("allows you to pop to restore previous state") {
context.push {
context["name"] = "Katie"
}
@@ -56,7 +56,7 @@ final class ContextTests: XCTestCase {
try expect(context["name"] as? String) == "Kyle"
}
$0.it("allows you to remove a parent's value in a level") {
test.it("allows you to remove a parent's value in a level") {
try context.push {
context["name"] = nil
try expect(context["name"]).to.beNil()
@@ -65,7 +65,7 @@ final class ContextTests: XCTestCase {
try expect(context["name"] as? String) == "Kyle"
}
$0.it("allows you to push a dictionary and run a closure then restoring previous state") {
test.it("allows you to push a dictionary and run a closure then restoring previous state") {
var didRun = false
try context.push(dictionary: ["name": "Katie"]) {
@@ -77,7 +77,7 @@ final class ContextTests: XCTestCase {
try expect(context["name"] as? String) == "Kyle"
}
$0.it("allows you to flatten the context contents") {
test.it("allows you to flatten the context contents") {
try context.push(dictionary: ["test": "abc"]) {
let flattened = context.flatten()

View File

@@ -0,0 +1,125 @@
import PathKit
import Spectre
@testable import Stencil
import XCTest
final class EnvironmentBaseAndChildTemplateTests: XCTestCase {
private var environment = Environment(loader: ExampleLoader())
private var childTemplate: Template = ""
private var baseTemplate: Template = ""
override func setUp() {
super.setUp()
let path = Path(#file as String) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader)
childTemplate = ""
baseTemplate = ""
}
override func tearDown() {
super.tearDown()
}
func testSyntaxErrorInBaseTemplate() throws {
childTemplate = try environment.loadTemplate(name: "invalid-child-super.html")
baseTemplate = try environment.loadTemplate(name: "invalid-base.html")
try expectError(
reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
childToken: "extends \"invalid-base.html\"",
baseToken: "target|unknown"
)
}
func testRuntimeErrorInBaseTemplate() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
childTemplate = try environment.loadTemplate(name: "invalid-child-super.html")
baseTemplate = try environment.loadTemplate(name: "invalid-base.html")
try expectError(
reason: "filter error",
childToken: "extends \"invalid-base.html\"",
baseToken: "target|unknown"
)
}
func testSyntaxErrorInChildTemplate() throws {
childTemplate = Template(
templateString: """
{% extends "base.html" %}
{% block body %}Child {{ target|unknown }}{% endblock %}
""",
environment: environment,
name: nil
)
try expectError(
reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
childToken: "target|unknown",
baseToken: nil
)
}
func testRuntimeErrorInChildTemplate() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
childTemplate = Template(
templateString: """
{% extends "base.html" %}
{% block body %}Child {{ target|unknown }}{% endblock %}
""",
environment: environment,
name: nil
)
try expectError(
reason: "filter error",
childToken: "target|unknown",
baseToken: nil
)
}
private func expectError(
reason: String,
childToken: String,
baseToken: String?,
file: String = #file,
line: Int = #line,
function: String = #function
) throws {
var expectedError = expectedSyntaxError(token: childToken, template: childTemplate, description: reason)
if let baseToken = baseToken {
expectedError.stackTrace = [
expectedSyntaxError(
token: baseToken,
template: baseTemplate,
description: reason
).token
].compactMap { $0 }
}
let error = try expect(
self.environment.render(template: self.childTemplate, context: ["target": "World"]),
file: file,
line: line,
function: function
).toThrow() as TemplateSyntaxError
let reporter = SimpleErrorReporter()
try expect(
reporter.renderError(error),
file: file,
line: line,
function: function
) == reporter.renderError(expectedError)
}
}

View File

@@ -0,0 +1,88 @@
import PathKit
import Spectre
@testable import Stencil
import XCTest
final class EnvironmentIncludeTemplateTests: XCTestCase {
private var environment = Environment(loader: ExampleLoader())
private var template: Template = ""
private var includedTemplate: Template = ""
override func setUp() {
super.setUp()
let path = Path(#file as String) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader)
template = ""
includedTemplate = ""
}
override func tearDown() {
super.tearDown()
}
func testSyntaxError() throws {
template = Template(templateString: """
{% include "invalid-include.html" %}
""", environment: environment)
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
try expectError(
reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
token: #"include "invalid-include.html""#,
includedToken: "target|unknown"
)
}
func testRuntimeError() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
template = Template(templateString: """
{% include "invalid-include.html" %}
""", environment: environment)
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
try expectError(
reason: "filter error",
token: "include \"invalid-include.html\"",
includedToken: "target|unknown"
)
}
private func expectError(
reason: String,
token: String,
includedToken: String,
file: String = #file,
line: Int = #line,
function: String = #function
) throws {
var expectedError = expectedSyntaxError(token: token, template: template, description: reason)
expectedError.stackTrace = [
expectedSyntaxError(
token: includedToken,
template: includedTemplate,
description: reason
).token
].compactMap { $0 }
let error = try expect(
self.environment.render(template: self.template, context: ["target": "World"]),
file: file,
line: line,
function: function
).toThrow() as TemplateSyntaxError
let reporter = SimpleErrorReporter()
try expect(
reporter.renderError(error),
file: file,
line: line,
function: function
) == reporter.renderError(expectedError)
}
}

View File

@@ -4,8 +4,8 @@ import Spectre
import XCTest
final class EnvironmentTests: XCTestCase {
var environment = Environment(loader: ExampleLoader())
var template: Template = ""
private var environment = Environment(loader: ExampleLoader())
private var template: Template = ""
override func setUp() {
super.setUp()
@@ -26,6 +26,10 @@ final class EnvironmentTests: XCTestCase {
template = ""
}
override func tearDown() {
super.tearDown()
}
func testLoading() {
it("can load a template from a name") {
let template = try self.environment.loadTemplate(name: "example.html")
@@ -207,242 +211,11 @@ final class EnvironmentTests: XCTestCase {
}
}
final class EnvironmentIncludeTemplateTests: XCTestCase {
var environment = Environment(loader: ExampleLoader())
var template: Template = ""
var includedTemplate: Template = ""
override func setUp() {
super.setUp()
let path = Path(#file as String) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader)
template = ""
includedTemplate = ""
}
func testSyntaxError() throws {
template = Template(templateString: """
{% include "invalid-include.html" %}
""", environment: environment)
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
token: """
include "invalid-include.html"
""",
includedToken: "target|unknown")
}
func testRuntimeError() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
template = Template(templateString: """
{% include "invalid-include.html" %}
""", environment: environment)
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
try expectError(reason: "filter error",
token: "include \"invalid-include.html\"",
includedToken: "target|unknown")
}
private func expectError(
reason: String,
token: String,
includedToken: String,
file: String = #file,
line: Int = #line,
function: String = #function
) throws {
var expectedError = expectedSyntaxError(token: token, template: template, description: reason)
expectedError.stackTrace = [
expectedSyntaxError(
token: includedToken,
template: includedTemplate,
description: reason
).token
].compactMap { $0 }
let error = try expect(
self.environment.render(template: self.template, context: ["target": "World"]),
file: file,
line: line,
function: function
).toThrow() as TemplateSyntaxError
let reporter = SimpleErrorReporter()
try expect(
reporter.renderError(error),
file: file,
line: line,
function: function
) == reporter.renderError(expectedError)
}
}
final class EnvironmentBaseAndChildTemplateTests: XCTestCase {
var environment = Environment(loader: ExampleLoader())
var childTemplate: Template = ""
var baseTemplate: Template = ""
override func setUp() {
super.setUp()
let path = Path(#file as String) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader)
childTemplate = ""
baseTemplate = ""
}
func testSyntaxErrorInBaseTemplate() throws {
childTemplate = try environment.loadTemplate(name: "invalid-child-super.html")
baseTemplate = try environment.loadTemplate(name: "invalid-base.html")
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
childToken: "extends \"invalid-base.html\"",
baseToken: "target|unknown")
}
func testRuntimeErrorInBaseTemplate() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
childTemplate = try environment.loadTemplate(name: "invalid-child-super.html")
baseTemplate = try environment.loadTemplate(name: "invalid-base.html")
try expectError(reason: "filter error",
childToken: "extends \"invalid-base.html\"",
baseToken: "target|unknown")
}
func testSyntaxErrorInChildTemplate() throws {
childTemplate = Template(
templateString: """
{% extends "base.html" %}
{% block body %}Child {{ target|unknown }}{% endblock %}
""",
environment: environment,
name: nil
)
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
childToken: "target|unknown",
baseToken: nil)
}
func testRuntimeErrorInChildTemplate() throws {
let filterExtension = Extension()
filterExtension.registerFilter("unknown") { (_: Any?) in
throw TemplateSyntaxError("filter error")
}
environment.extensions += [filterExtension]
childTemplate = Template(
templateString: """
{% extends "base.html" %}
{% block body %}Child {{ target|unknown }}{% endblock %}
""",
environment: environment,
name: nil
)
try expectError(reason: "filter error",
childToken: "target|unknown",
baseToken: nil)
}
private func expectError(
reason: String,
childToken: String,
baseToken: String?,
file: String = #file,
line: Int = #line,
function: String = #function
) throws {
var expectedError = expectedSyntaxError(token: childToken, template: childTemplate, description: reason)
if let baseToken = baseToken {
expectedError.stackTrace = [
expectedSyntaxError(
token: baseToken,
template: baseTemplate,
description: reason
).token
].compactMap { $0 }
}
let error = try expect(
self.environment.render(template: self.childTemplate, context: ["target": "World"]),
file: file,
line: line,
function: function
).toThrow() as TemplateSyntaxError
let reporter = SimpleErrorReporter()
try expect(
reporter.renderError(error),
file: file,
line: line,
function: function
) == reporter.renderError(expectedError)
}
}
extension Expectation {
@discardableResult
func toThrow<T: Error>() throws -> T {
var thrownError: Error?
do {
_ = try expression()
} catch {
thrownError = error
}
if let thrownError = thrownError {
if let thrownError = thrownError as? T {
return thrownError
} else {
throw failure("\(thrownError) is not \(T.self)")
}
} else {
throw failure("expression did not throw an error")
}
}
}
extension XCTestCase {
func expectedSyntaxError(token: String, template: Template, description: String) -> TemplateSyntaxError {
guard let range = template.templateString.range(of: token) else {
fatalError("Can't find '\(token)' in '\(template)'")
}
let lexer = Lexer(templateString: template.templateString)
let location = lexer.rangeLocation(range)
let sourceMap = SourceMap(filename: template.name, location: location)
let token = Token.block(value: token, at: sourceMap)
return TemplateSyntaxError(reason: description, token: token, stackTrace: [])
}
}
private class ExampleLoader: Loader {
func loadTemplate(name: String, environment: Environment) throws -> Template {
if name == "example.html" {
return Template(templateString: "Hello World!", environment: environment, name: name)
}
throw TemplateDoesNotExist(templateNames: [name], loader: self)
}
}
// MARK: - Helpers
private class CustomTemplate: Template {
// swiftlint:disable discouraged_optional_collection
override func render(_ dictionary: [String: Any]? = nil) throws -> String {
return "here"
"here"
}
}

View File

@@ -3,7 +3,7 @@ import Spectre
import XCTest
final class ExpressionsTests: XCTestCase {
let parser = TokenParser(tokens: [], environment: Environment())
private let parser = TokenParser(tokens: [], environment: Environment())
private func makeExpression(_ components: [String]) -> Expression {
do {

View File

@@ -103,30 +103,30 @@ final class FilterTests: XCTestCase {
}
it("allows you to register a custom filter which accepts several arguments") {
let template = Template(templateString: """
{{ name|repeat:'value"1"',"value'2'",'(key, value)' }}
""")
let template = Template(templateString: """
{{ name|repeat:'value"1"',"value'2'",'(key, value)' }}
""")
let repeatExtension = Extension()
repeatExtension.registerFilter("repeat") { value, arguments in
guard let value = value else { return nil }
let args = arguments.compactMap { $0 }
return "\(value) \(value) with args 0: \(args[0]), 1: \(args[1]), 2: \(args[2])"
}
let repeatExtension = Extension()
repeatExtension.registerFilter("repeat") { value, arguments in
guard let value = value else { return nil }
let args = arguments.compactMap { $0 }
return "\(value) \(value) with args 0: \(args[0]), 1: \(args[1]), 2: \(args[2])"
}
let result = try template.render(Context(
dictionary: context,
environment: Environment(extensions: [repeatExtension])
))
try expect(result) == """
Kyle Kyle with args 0: value"1", 1: value'2', 2: (key, value)
"""
let result = try template.render(Context(
dictionary: context,
environment: Environment(extensions: [repeatExtension])
))
try expect(result) == """
Kyle Kyle with args 0: value"1", 1: value'2', 2: (key, value)
"""
}
it("allows whitespace in expression") {
let template = Template(templateString: """
{{ value | join : ", " }}
""")
{{ value | join : ", " }}
""")
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
try expect(result) == "One, Two"
}
@@ -363,10 +363,12 @@ final class FilterTests: XCTestCase {
Two
"""
]))
// swiftlint:disable indentation_width
try expect(result) == """
One
Two
"""
// swiftlint:enable indentation_width
}
func testIndentNotEmptyLines() throws {
@@ -383,6 +385,7 @@ final class FilterTests: XCTestCase {
"""
]))
// swiftlint:disable indentation_width
try expect(result) == """
One
@@ -391,6 +394,7 @@ final class FilterTests: XCTestCase {
"""
// swiftlint:enable indentation_width
}
func testDynamicFilters() throws {

View File

@@ -23,9 +23,9 @@ final class FilterTagTests: XCTestCase {
it("can render filters with arguments") {
let ext = Extension()
ext.registerFilter("split") {
guard let value = $0 as? String,
let argument = $1.first as? String else { return $0 }
ext.registerFilter("split") { value, args in
guard let value = value as? String,
let argument = args.first as? String else { return value }
return value.components(separatedBy: argument)
}
let env = Environment(extensions: [ext])
@@ -37,11 +37,11 @@ final class FilterTagTests: XCTestCase {
it("can render filters with quote as an argument") {
let ext = Extension()
ext.registerFilter("replace") {
guard let value = $0 as? String,
$1.count == 2,
let search = $1.first as? String,
let replacement = $1.last as? String else { return $0 }
ext.registerFilter("replace") { value, args in
guard let value = value as? String,
args.count == 2,
let search = args.first as? String,
let replacement = args.last as? String else { return value }
return value.replacingOccurrences(of: search, with: replacement)
}
let env = Environment(extensions: [ext])

View File

@@ -3,9 +3,10 @@ import Spectre
import XCTest
final class ForNodeTests: XCTestCase {
let context = Context(dictionary: [
private let context = Context(dictionary: [
"items": [1, 2, 3],
"anyItems": [1, 2, 3] as [Any],
// swiftlint:disable:next legacy_objc_type
"nsItems": NSArray(array: [1, 2, 3]),
"emptyItems": [Int](),
"dict": [
@@ -313,6 +314,8 @@ final class ForNodeTests: XCTestCase {
}
}
// MARK: - Helpers
private struct MyStruct {
let string: String
let number: Int

View File

@@ -0,0 +1,63 @@
import PathKit
import Spectre
@testable import Stencil
import XCTest
extension Expectation {
@discardableResult
func toThrow<T: Error>() throws -> T {
var thrownError: Error?
do {
_ = try expression()
} catch {
thrownError = error
}
if let thrownError = thrownError {
if let thrownError = thrownError as? T {
return thrownError
} else {
throw failure("\(thrownError) is not \(T.self)")
}
} else {
throw failure("expression did not throw an error")
}
}
}
extension XCTestCase {
func expectedSyntaxError(token: String, template: Template, description: String) -> TemplateSyntaxError {
guard let range = template.templateString.range(of: token) else {
fatalError("Can't find '\(token)' in '\(template)'")
}
let lexer = Lexer(templateString: template.templateString)
let location = lexer.rangeLocation(range)
let sourceMap = SourceMap(filename: template.name, location: location)
let token = Token.block(value: token, at: sourceMap)
return TemplateSyntaxError(reason: description, token: token, stackTrace: [])
}
}
// MARK: - Test Types
class ExampleLoader: Loader {
func loadTemplate(name: String, environment: Environment) throws -> Template {
if name == "example.html" {
return Template(templateString: "Hello World!", environment: environment, name: name)
}
throw TemplateDoesNotExist(templateNames: [name], loader: self)
}
}
class ErrorNode: NodeType {
let token: Token?
init(token: Token? = nil) {
self.token = token
}
func render(_ context: Context) throws -> String {
throw TemplateSyntaxError("Custom Error")
}
}

View File

@@ -2,10 +2,6 @@ import Spectre
@testable import Stencil
import XCTest
private struct SomeType {
let value: String? = nil
}
final class IfNodeTests: XCTestCase {
func testParseIf() {
it("can parse an if block") {
@@ -286,3 +282,9 @@ final class IfNodeTests: XCTestCase {
try expect(renderNodes(nodes, Context(dictionary: ["value": 4]))) == "false"
}
}
// MARK: - Helpers
private struct SomeType {
let value: String? = nil
}

View File

@@ -4,9 +4,9 @@ import Spectre
import XCTest
final class IncludeTests: XCTestCase {
let path = Path(#file as String) + ".." + "fixtures"
lazy var loader = FileSystemLoader(paths: [path])
lazy var environment = Environment(loader: loader)
private let path = Path(#file as String) + ".." + "fixtures"
private lazy var loader = FileSystemLoader(paths: [path])
private lazy var environment = Environment(loader: loader)
func testParsing() {
it("throws an error when no template is given") {

View File

@@ -4,9 +4,9 @@ import Stencil
import XCTest
final class InheritanceTests: XCTestCase {
let path = Path(#file as String) + ".." + "fixtures"
lazy var loader = FileSystemLoader(paths: [path])
lazy var environment = Environment(loader: loader)
private let path = Path(#file as String) + ".." + "fixtures"
private lazy var loader = FileSystemLoader(paths: [path])
private lazy var environment = Environment(loader: loader)
func testInheritance() {
it("can inherit from another template") {

View File

@@ -82,6 +82,7 @@ final class LexerTests: XCTestCase {
}
func testNewlines() throws {
// swiftlint:disable indentation_width
let templateString = """
My name is {%
if name
@@ -92,6 +93,7 @@ final class LexerTests: XCTestCase {
}}{%
endif %}.
"""
// swiftlint:enable indentation_width
let lexer = Lexer(templateString: templateString)
let tokens = lexer.tokenize()

View File

@@ -32,7 +32,7 @@ final class TemplateLoaderTests: XCTestCase {
func testDictionaryLoader() {
let loader = DictionaryLoader(templates: [
"index.html": "Hello World"
"index.html": "Hello World"
])
let environment = Environment(loader: loader)

View File

@@ -2,19 +2,8 @@ import Spectre
@testable import Stencil
import XCTest
class ErrorNode: NodeType {
let token: Token?
init(token: Token? = nil) {
self.token = token
}
func render(_ context: Context) throws -> String {
throw TemplateSyntaxError("Custom Error")
}
}
final class NodeTests: XCTestCase {
let context = Context(dictionary: [
private let context = Context(dictionary: [
"name": "Kyle",
"age": 27,
"items": [1, 2, 3]

View File

@@ -5,9 +5,9 @@ import XCTest
final class NowNodeTests: XCTestCase {
func testParsing() {
it("parses default format without any now arguments") {
#if os(Linux)
#if os(Linux)
throw skip()
#else
#else
let tokens: [Token] = [ .block(value: "now", at: .unknown) ]
let parser = TokenParser(tokens: tokens, environment: Environment())
@@ -15,36 +15,36 @@ final class NowNodeTests: XCTestCase {
let node = nodes.first as? NowNode
try expect(nodes.count) == 1
try expect(node?.format.variable) == "\"yyyy-MM-dd 'at' HH:mm\""
#endif
#endif
}
it("parses now with a format") {
#if os(Linux)
#if os(Linux)
throw skip()
#else
#else
let tokens: [Token] = [ .block(value: "now \"HH:mm\"", at: .unknown) ]
let parser = TokenParser(tokens: tokens, environment: Environment())
let nodes = try parser.parse()
let node = nodes.first as? NowNode
try expect(nodes.count) == 1
try expect(node?.format.variable) == "\"HH:mm\""
#endif
#endif
}
}
func testRendering() {
it("renders the date") {
#if os(Linux)
#if os(Linux)
throw skip()
#else
#else
let node = NowNode(format: Variable("\"yyyy-MM-dd\""))
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let date = formatter.string(from: NSDate() as Date)
let date = formatter.string(from: Date())
try expect(try node.render(Context())) == date
#endif
#endif
}
}
}

View File

@@ -57,8 +57,8 @@ final class TokenParserTests: XCTestCase {
try expect(try parser.parse()).toThrow(TemplateSyntaxError(
reason: "Unknown template tag 'unknown'",
token: tokens.first)
)
token: tokens.first
))
}
}
}

View File

@@ -2,20 +2,8 @@ import Spectre
import Stencil
import XCTest
private struct CustomNode: NodeType {
let token: Token?
func render(_ context: Context) throws -> String {
return "Hello World"
}
}
private struct Article {
let title: String
let author: String
}
final class StencilTests: XCTestCase {
lazy var environment: Environment = {
private lazy var environment: Environment = {
let exampleExtension = Extension()
exampleExtension.registerSimpleTag("simpletag") { _ in
"Hello World"
@@ -32,7 +20,7 @@ final class StencilTests: XCTestCase {
There are {{ articles.count }} articles.
{% for article in articles %}\
- {{ article.title }} by {{ article.author }}.
- {{ article.title }} by {{ article.author }}.
{% endfor %}
"""
@@ -49,8 +37,8 @@ final class StencilTests: XCTestCase {
try expect(result) == """
There are 2 articles.
- Migrating from OCUnit to XCTest by Kyle Fuller.
- Memory Management with ARC by Kyle Fuller.
- Migrating from OCUnit to XCTest by Kyle Fuller.
- Memory Management with ARC by Kyle Fuller.
"""
}
@@ -66,3 +54,17 @@ final class StencilTests: XCTestCase {
}
}
}
// MARK: - Helpers
private struct CustomNode: NodeType {
let token: Token?
func render(_ context: Context) throws -> String {
"Hello World"
}
}
private struct Article {
let title: String
let author: String
}

View File

@@ -11,9 +11,9 @@ final class TemplateTests: XCTestCase {
}
it("can render a template from a string literal") {
let template: Template = "Hello World"
let result = try template.render([ "name": "Kyle" ])
try expect(result) == "Hello World"
let template: Template = "Hello World"
let result = try template.render([ "name": "Kyle" ])
try expect(result) == "Hello World"
}
}
}

View File

@@ -2,47 +2,8 @@ import Spectre
@testable import Stencil
import XCTest
#if os(OSX)
@objc
class Superclass: NSObject {
@objc let name = "Foo"
}
@objc
class Object: Superclass {
@objc let title = "Hello World"
}
#endif
private struct Person {
let name: String
}
private struct Article {
let author: Person
}
private class WebSite {
let url: String = "blog.com"
}
private class Blog: WebSite {
let articles: [Article] = [Article(author: Person(name: "Kyle"))]
let featuring: Article? = Article(author: Person(name: "Jhon"))
}
@dynamicMemberLookup
private struct DynamicStruct: DynamicMemberLookup {
subscript(dynamicMember member: String) -> Any? {
member == "test" ? "this is a dynamic response" : nil
}
}
private enum DynamicEnum: String, DynamicMemberLookup {
case someValue = "this is raw value"
}
final class VariableTests: XCTestCase {
let context: Context = {
private let context: Context = {
let ext = Extension()
ext.registerFilter("incr") { arg in
(arg.flatMap { toNumber(value: $0) } ?? 0) + 1
@@ -66,9 +27,9 @@ final class VariableTests: XCTestCase {
"struct": DynamicStruct()
]
], environment: environment)
#if os(OSX)
#if os(OSX)
context["object"] = Object()
#endif
#endif
return context
}()
@@ -145,9 +106,9 @@ final class VariableTests: XCTestCase {
let result = try variable.resolve(self.context) as? String
try expect(result) == "Katie"
let variable1 = Variable("contacts.1")
let result1 = try variable1.resolve(self.context) as? String
try expect(result1) == "Carlton"
let variable1 = Variable("contacts.1")
let result1 = try variable1.resolve(self.context) as? String
try expect(result1) == "Carlton"
}
it("can resolve an item from an array via unknown index") {
@@ -214,7 +175,7 @@ final class VariableTests: XCTestCase {
}
func testKVO() {
#if os(OSX)
#if os(OSX)
it("can resolve a value via KVO") {
let variable = Variable("object.title")
let result = try variable.resolve(self.context) as? String
@@ -232,7 +193,7 @@ final class VariableTests: XCTestCase {
let result = try variable.resolve(self.context) as? String
try expect(result).to.beNil()
}
#endif
#endif
}
func testTuple() {
@@ -285,7 +246,7 @@ final class VariableTests: XCTestCase {
}
}
#if os(OSX)
#if os(OSX)
it("can resolve a subscript via KVO") {
try self.context.push(dictionary: ["property": "name"]) {
let variable = Variable("object[property]")
@@ -293,7 +254,7 @@ final class VariableTests: XCTestCase {
try expect(result) == "Foo"
}
}
#endif
#endif
it("can resolve an optional subscript via reflection") {
try self.context.push(dictionary: ["property": "featuring"]) {
@@ -394,3 +355,44 @@ final class VariableTests: XCTestCase {
}
}
}
// MARK: - Helpers
#if os(OSX)
@objc
class Superclass: NSObject {
@objc let name = "Foo"
}
@objc
class Object: Superclass {
@objc let title = "Hello World"
}
#endif
private struct Person {
let name: String
}
private struct Article {
let author: Person
}
private class WebSite {
let url: String = "blog.com"
}
private class Blog: WebSite {
let articles: [Article] = [Article(author: Person(name: "Kyle"))]
let featuring: Article? = Article(author: Person(name: "Jhon"))
}
@dynamicMemberLookup
private struct DynamicStruct: DynamicMemberLookup {
subscript(dynamicMember member: String) -> Any? {
member == "test" ? "this is a dynamic response" : nil
}
}
private enum DynamicEnum: String, DynamicMemberLookup {
case someValue = "this is raw value"
}