167 lines
4.5 KiB
Swift
167 lines
4.5 KiB
Swift
//
|
|
// Stencil
|
|
// Copyright © 2022 Stencil
|
|
// MIT Licence
|
|
//
|
|
|
|
import Spectre
|
|
@testable import Stencil
|
|
import XCTest
|
|
|
|
final class ContextTests: XCTestCase {
|
|
func testContextSubscripting() {
|
|
describe("Context Subscripting") { test in
|
|
var context = Context()
|
|
test.before {
|
|
context = Context(dictionary: ["name": "Kyle"])
|
|
}
|
|
|
|
test.it("allows you to get a value via subscripting") {
|
|
try expect(context["name"] as? String) == "Kyle"
|
|
}
|
|
|
|
test.it("allows you to set a value via subscripting") {
|
|
context["name"] = "Katie"
|
|
|
|
try expect(context["name"] as? String) == "Katie"
|
|
}
|
|
|
|
test.it("allows you to remove a value via subscripting") {
|
|
context["name"] = nil
|
|
|
|
try expect(context["name"]).to.beNil()
|
|
}
|
|
|
|
test.it("allows you to retrieve a value from a parent") {
|
|
try context.push {
|
|
try expect(context["name"] as? String) == "Kyle"
|
|
}
|
|
}
|
|
|
|
test.it("allows you to override a parent's value") {
|
|
try context.push {
|
|
context["name"] = "Katie"
|
|
try expect(context["name"] as? String) == "Katie"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testContextRestoration() {
|
|
describe("Context Restoration") { test in
|
|
var context = Context()
|
|
test.before {
|
|
context = Context(dictionary: ["name": "Kyle"])
|
|
}
|
|
|
|
test.it("allows you to pop to restore previous state") {
|
|
context.push {
|
|
context["name"] = "Katie"
|
|
}
|
|
|
|
try expect(context["name"] as? String) == "Kyle"
|
|
}
|
|
|
|
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()
|
|
}
|
|
|
|
try expect(context["name"] as? String) == "Kyle"
|
|
}
|
|
|
|
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"]) {
|
|
didRun = true
|
|
try expect(context["name"] as? String) == "Katie"
|
|
}
|
|
|
|
try expect(didRun).to.beTrue()
|
|
try expect(context["name"] as? String) == "Kyle"
|
|
}
|
|
|
|
test.it("allows you to flatten the context contents") {
|
|
try context.push(dictionary: ["test": "abc"]) {
|
|
let flattened = context.flatten()
|
|
|
|
try expect(flattened.count) == 2
|
|
try expect(flattened["name"] as? String) == "Kyle"
|
|
try expect(flattened["test"] as? String) == "abc"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testContextLazyEvaluation() {
|
|
let ticker = Ticker()
|
|
var context = Context()
|
|
var wrapper = LazyValueWrapper("")
|
|
|
|
describe("Lazy evaluation") { test in
|
|
test.before {
|
|
ticker.count = 0
|
|
wrapper = LazyValueWrapper(ticker.tick())
|
|
context = Context(dictionary: ["name": wrapper])
|
|
}
|
|
|
|
test.it("Evaluates lazy data") {
|
|
let template = Template(templateString: "{{ name }}")
|
|
let result = try template.render(context)
|
|
try expect(result) == "Kyle"
|
|
try expect(ticker.count) == 1
|
|
}
|
|
|
|
test.it("Evaluates lazy only once") {
|
|
let template = Template(templateString: "{{ name }}{{ name }}")
|
|
let result = try template.render(context)
|
|
try expect(result) == "KyleKyle"
|
|
try expect(ticker.count) == 1
|
|
}
|
|
|
|
test.it("Does not evaluate lazy data when not used") {
|
|
let template = Template(templateString: "{{ 'Katie' }}")
|
|
let result = try template.render(context)
|
|
try expect(result) == "Katie"
|
|
try expect(ticker.count) == 0
|
|
}
|
|
}
|
|
}
|
|
|
|
func testContextLazyAccessTypes() {
|
|
it("Supports evaluation via context reference") {
|
|
let context = Context(dictionary: ["name": "Kyle"])
|
|
context["alias"] = LazyValueWrapper { $0["name"] ?? "" }
|
|
let template = Template(templateString: "{{ alias }}")
|
|
|
|
try context.push(dictionary: ["name": "Katie"]) {
|
|
let result = try template.render(context)
|
|
try expect(result) == "Katie"
|
|
}
|
|
}
|
|
|
|
it("Supports evaluation via context copy") {
|
|
let context = Context(dictionary: ["name": "Kyle"])
|
|
context["alias"] = LazyValueWrapper(copying: context) { $0["name"] ?? "" }
|
|
let template = Template(templateString: "{{ alias }}")
|
|
|
|
try context.push(dictionary: ["name": "Katie"]) {
|
|
let result = try template.render(context)
|
|
try expect(result) == "Kyle"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
private final class Ticker {
|
|
var count: Int = 0
|
|
func tick() -> String {
|
|
count += 1
|
|
return "Kyle"
|
|
}
|
|
}
|