Update to Spectre 0.9.0 (#247)
* update to Spectre 0.9.0 * fix variable spec tests * fix flatMap warning * updated CHANGELOG
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,5 @@
|
||||
.conche/
|
||||
.build/
|
||||
Packages/
|
||||
Package.resolved
|
||||
Package.pins
|
||||
*.xcodeproj
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
- Now you can conditionally render variables with `{{ variable if condition }}`, which is a shorthand for `{% if condition %}{{ variable }}{% endif %}`. You can also use `else` like `{{ variable1 if condition else variable2 }}`, which is a shorthand for `{% if condition %}{{ variable1 }}{% else %}{{ variable2 }}{% endif %}`
|
||||
[Ilya Puchka](https://github.com/ilyapuchka)
|
||||
[#243](https://github.com/stencilproject/Stencil/pull/243)
|
||||
|
||||
- Now you can access string characters by index or get string length the same was as if it was an array, i.e. `{{ 'string'.first }}`, `{{ 'string'.last }}`, `{{ 'string'.1 }}`, `{{ 'string'.count }}`.
|
||||
[Ilya Puchka](https://github.com/ilyapuchka)
|
||||
[#245](https://github.com/stencilproject/Stencil/pull/245)
|
||||
@@ -35,6 +34,9 @@
|
||||
- Updated the codebase to use Swift 4 features.
|
||||
[David Jennes](https://github.com/djbe)
|
||||
[#239](https://github.com/stencilproject/Stencil/pull/239)
|
||||
- Update to Spectre 0.9.0.
|
||||
[Ilya Puchka](https://github.com/ilyapuchka)
|
||||
[#247](https://github.com/stencilproject/Stencil/pull/247)
|
||||
|
||||
|
||||
## 0.12.1
|
||||
|
||||
25
Package.resolved
Normal file
25
Package.resolved
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "PathKit",
|
||||
"repositoryURL": "https://github.com/kylef/PathKit.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "e2f5be30e4c8f531c9c1e8765aa7b71c0a45d7a0",
|
||||
"version": "0.9.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Spectre",
|
||||
"repositoryURL": "https://github.com/kylef/Spectre.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
|
||||
"version": "0.9.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
@@ -8,7 +8,7 @@ let package = Package(
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/kylef/PathKit.git", from: "0.9.0"),
|
||||
.package(url: "https://github.com/kylef/Spectre.git", from: "0.8.0"),
|
||||
.package(url: "https://github.com/kylef/Spectre.git", from: "0.9.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Stencil", dependencies: [
|
||||
|
||||
@@ -118,7 +118,7 @@ final class IfExpressionParser {
|
||||
private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws {
|
||||
var parsedComponents = Set<Int>()
|
||||
var bracketsBalance = 0
|
||||
self.tokens = try zip(components.indices, components).flatMap { (index, component) in
|
||||
self.tokens = try zip(components.indices, components).compactMap { (index, component) in
|
||||
guard !parsedComponents.contains(index) else { return nil }
|
||||
|
||||
if component == "(" {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import XCTest
|
||||
|
||||
import StencilTests
|
||||
|
||||
stencilTests()
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += StencilTests.__allTests()
|
||||
|
||||
XCTMain(tests)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testContext() {
|
||||
class ContextTests: XCTestCase {
|
||||
|
||||
func testContext() {
|
||||
describe("Context") {
|
||||
var context: Context!
|
||||
|
||||
@@ -78,4 +81,5 @@ func testContext() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
import PathKit
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testEnvironment() {
|
||||
class EnvironmentTests: XCTestCase {
|
||||
func testEnvironment() {
|
||||
describe("Environment") {
|
||||
var environment: Environment!
|
||||
var template: Template!
|
||||
@@ -329,6 +330,7 @@ func testEnvironment() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Expectation {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testExpressions() {
|
||||
class ExpressionsTests: XCTestCase {
|
||||
func testExpressions() {
|
||||
describe("Expression") {
|
||||
let parser = TokenParser(tokens: [], environment: Environment())
|
||||
|
||||
@@ -341,4 +342,5 @@ func testExpressions() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testFilter() {
|
||||
class FilterTests: XCTestCase {
|
||||
func testFilter() {
|
||||
describe("template filters") {
|
||||
let context: [String: Any] = ["name": "Kyle"]
|
||||
|
||||
@@ -367,4 +368,5 @@ func testFilter() {
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
import Stencil
|
||||
|
||||
|
||||
func testFilterTag() {
|
||||
class FilterTagTests: XCTestCase {
|
||||
func testFilterTag() {
|
||||
describe("Filter Tag") {
|
||||
$0.it("allows you to use a filter") {
|
||||
let template = Template(templateString: "{% filter uppercase %}Test{% endfilter %}")
|
||||
@@ -46,4 +47,5 @@ func testFilterTag() {
|
||||
try expect(result) == "1,2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
import Foundation
|
||||
|
||||
|
||||
func testForNode() {
|
||||
class ForNodeTests: XCTestCase {
|
||||
func testForNode() {
|
||||
describe("ForNode") {
|
||||
let context = Context(dictionary: [
|
||||
"items": [1, 2, 3],
|
||||
@@ -346,6 +347,7 @@ func testForNode() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct Article {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testIfNode() {
|
||||
class IfNodeTests: XCTestCase {
|
||||
func testIfNode() {
|
||||
describe("IfNode") {
|
||||
$0.describe("parsing") {
|
||||
$0.it("can parse an if block") {
|
||||
@@ -284,4 +285,5 @@ func testIfNode() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
import PathKit
|
||||
|
||||
|
||||
func testInclude() {
|
||||
class IncludeTests: XCTestCase {
|
||||
func testInclude() {
|
||||
describe("Include") {
|
||||
let path = Path(#file) + ".." + "fixtures"
|
||||
let loader = FileSystemLoader(paths: [path])
|
||||
@@ -67,4 +68,5 @@ func testInclude() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
import Stencil
|
||||
import PathKit
|
||||
|
||||
|
||||
func testInheritence() {
|
||||
class InheritenceTests: XCTestCase {
|
||||
func testInheritence() {
|
||||
describe("Inheritence") {
|
||||
let path = Path(#file) + ".." + "fixtures"
|
||||
let loader = FileSystemLoader(paths: [path])
|
||||
@@ -33,4 +34,5 @@ func testInheritence() {
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testLexer() {
|
||||
class LexerTests: XCTestCase {
|
||||
func testLexer() {
|
||||
describe("Lexer") {
|
||||
$0.it("can tokenize text") {
|
||||
let lexer = Lexer(templateString: "Hello World")
|
||||
@@ -92,4 +93,5 @@ func testLexer() {
|
||||
try expect(tokens[4]) == Token.text(value: ".", at: SourceMap(location: lexer.rangeLocation(templateString.range(of: ".")!)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
import Stencil
|
||||
import PathKit
|
||||
|
||||
|
||||
func testTemplateLoader() {
|
||||
class TemplateLoaderTests: XCTestCase {
|
||||
func testTemplateLoader() {
|
||||
describe("FileSystemLoader") {
|
||||
let path = Path(#file) + ".." + "fixtures"
|
||||
let loader = FileSystemLoader(paths: [path])
|
||||
@@ -52,4 +53,5 @@ func testTemplateLoader() {
|
||||
_ = try environment.loadTemplate(names: ["unknown.html", "index.html"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
class ErrorNode : NodeType {
|
||||
let token: Token?
|
||||
init(token: Token? = nil) {
|
||||
@@ -13,8 +13,8 @@ class ErrorNode : NodeType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testNode() {
|
||||
class NodeTests: XCTestCase {
|
||||
func testNode() {
|
||||
describe("Node") {
|
||||
let context = Context(dictionary: [
|
||||
"name": "Kyle",
|
||||
@@ -62,4 +62,5 @@ func testNode() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import XCTest
|
||||
import Foundation
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testNowNode() {
|
||||
#if !os(Linux)
|
||||
class NowNodeTests: XCTestCase {
|
||||
func testNowNode() {
|
||||
#if !os(Linux)
|
||||
describe("NowNode") {
|
||||
$0.describe("parsing") {
|
||||
$0.it("parses default format without any now arguments") {
|
||||
@@ -39,5 +41,6 @@ func testNowNode() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testTokenParser() {
|
||||
class TokenParserTests: XCTestCase {
|
||||
func testTokenParser() {
|
||||
describe("TokenParser") {
|
||||
$0.it("can parse a text token") {
|
||||
let parser = TokenParser(tokens: [
|
||||
@@ -58,4 +59,5 @@ func testTokenParser() {
|
||||
try expect(try parser.parse()).toThrow(TemplateSyntaxError(reason: "Unknown template tag 'unknown'", token: tokens.first))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
import Stencil
|
||||
|
||||
|
||||
fileprivate struct CustomNode : NodeType {
|
||||
let token: Token?
|
||||
func render(_ context:Context) throws -> String {
|
||||
@@ -9,14 +9,13 @@ fileprivate struct CustomNode : NodeType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate struct Article {
|
||||
let title: String
|
||||
let author: String
|
||||
}
|
||||
|
||||
|
||||
func testStencil() {
|
||||
class StencilTests: XCTestCase {
|
||||
func testStencil() {
|
||||
describe("Stencil") {
|
||||
let exampleExtension = Extension()
|
||||
|
||||
@@ -69,4 +68,5 @@ func testStencil() {
|
||||
try expect(result) == "Hello World"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testTemplate() {
|
||||
class TemplateTests: XCTestCase {
|
||||
func testTemplate() {
|
||||
describe("Template") {
|
||||
$0.it("can render a template from a string") {
|
||||
let template = Template(templateString: "Hello World")
|
||||
@@ -17,4 +18,5 @@ func testTemplate() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import XCTest
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
|
||||
|
||||
func testToken() {
|
||||
class TokenTests: XCTestCase {
|
||||
func testToken() {
|
||||
describe("Token") {
|
||||
$0.it("can split the contents into components") {
|
||||
let token = Token.text(value: "hello world", at: .unknown)
|
||||
@@ -31,4 +32,5 @@ func testToken() {
|
||||
try expect(components[1]) == "\"kyle fuller\""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import XCTest
|
||||
import Foundation
|
||||
import Spectre
|
||||
@testable import Stencil
|
||||
@@ -29,7 +30,8 @@ fileprivate class Blog: WebSite {
|
||||
let featuring: Article? = Article(author: Person(name: "Jhon"))
|
||||
}
|
||||
|
||||
func testVariable() {
|
||||
class VariableTests: XCTestCase {
|
||||
func testVariable() {
|
||||
describe("Variable") {
|
||||
let context = Context(dictionary: [
|
||||
"name": "Kyle",
|
||||
@@ -44,9 +46,9 @@ func testVariable() {
|
||||
"tuple": (one: 1, two: 2)
|
||||
])
|
||||
|
||||
#if os(OSX)
|
||||
#if os(OSX)
|
||||
context["object"] = Object()
|
||||
#endif
|
||||
#endif
|
||||
context["blog"] = Blog()
|
||||
|
||||
$0.it("can resolve a string literal with double quotes") {
|
||||
@@ -186,7 +188,7 @@ func testVariable() {
|
||||
try expect(result) == "Kyle"
|
||||
}
|
||||
|
||||
#if os(OSX)
|
||||
#if os(OSX)
|
||||
$0.it("can resolve a value via KVO") {
|
||||
let variable = Variable("object.title")
|
||||
let result = try variable.resolve(context) as? String
|
||||
@@ -204,7 +206,7 @@ func testVariable() {
|
||||
let result = try variable.resolve(context) as? String
|
||||
try expect(result).to.beNil()
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
$0.it("can resolve a value via reflection") {
|
||||
let variable = Variable("blog.articles.0.author.name")
|
||||
@@ -270,7 +272,7 @@ func testVariable() {
|
||||
}
|
||||
}
|
||||
|
||||
#if os(OSX)
|
||||
#if os(OSX)
|
||||
$0.it("can resolve a subscript via KVO") {
|
||||
try context.push(dictionary: ["property": "name"]) {
|
||||
let variable = Variable("object[property]")
|
||||
@@ -278,7 +280,7 @@ func testVariable() {
|
||||
try expect(result) == "Foo"
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
$0.it("can resolve an optional subscript via reflection") {
|
||||
try context.push(dictionary: ["property": "featuring"]) {
|
||||
@@ -406,4 +408,5 @@ func testVariable() {
|
||||
try expect(template.render(Context(dictionary: ["variable": "a"]))).toThrow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import XCTest
|
||||
|
||||
|
||||
public func stencilTests() {
|
||||
testContext()
|
||||
testFilter()
|
||||
testLexer()
|
||||
testToken()
|
||||
testTokenParser()
|
||||
testTemplateLoader()
|
||||
testTemplate()
|
||||
testVariable()
|
||||
testNode()
|
||||
testForNode()
|
||||
testExpressions()
|
||||
testIfNode()
|
||||
testNowNode()
|
||||
testInclude()
|
||||
testInheritence()
|
||||
testFilterTag()
|
||||
testEnvironment()
|
||||
testStencil()
|
||||
}
|
||||
|
||||
|
||||
class StencilTests: XCTestCase {
|
||||
func testRunStencilTests() {
|
||||
stencilTests()
|
||||
}
|
||||
}
|
||||
134
Tests/StencilTests/XCTestManifests.swift
Normal file
134
Tests/StencilTests/XCTestManifests.swift
Normal file
@@ -0,0 +1,134 @@
|
||||
import XCTest
|
||||
|
||||
extension ContextTests {
|
||||
static let __allTests = [
|
||||
("testContext", testContext),
|
||||
]
|
||||
}
|
||||
|
||||
extension EnvironmentTests {
|
||||
static let __allTests = [
|
||||
("testEnvironment", testEnvironment),
|
||||
]
|
||||
}
|
||||
|
||||
extension ExpressionsTests {
|
||||
static let __allTests = [
|
||||
("testExpressions", testExpressions),
|
||||
]
|
||||
}
|
||||
|
||||
extension FilterTagTests {
|
||||
static let __allTests = [
|
||||
("testFilterTag", testFilterTag),
|
||||
]
|
||||
}
|
||||
|
||||
extension FilterTests {
|
||||
static let __allTests = [
|
||||
("testFilter", testFilter),
|
||||
]
|
||||
}
|
||||
|
||||
extension ForNodeTests {
|
||||
static let __allTests = [
|
||||
("testForNode", testForNode),
|
||||
]
|
||||
}
|
||||
|
||||
extension IfNodeTests {
|
||||
static let __allTests = [
|
||||
("testIfNode", testIfNode),
|
||||
]
|
||||
}
|
||||
|
||||
extension IncludeTests {
|
||||
static let __allTests = [
|
||||
("testInclude", testInclude),
|
||||
]
|
||||
}
|
||||
|
||||
extension InheritenceTests {
|
||||
static let __allTests = [
|
||||
("testInheritence", testInheritence),
|
||||
]
|
||||
}
|
||||
|
||||
extension LexerTests {
|
||||
static let __allTests = [
|
||||
("testLexer", testLexer),
|
||||
]
|
||||
}
|
||||
|
||||
extension NodeTests {
|
||||
static let __allTests = [
|
||||
("testNode", testNode),
|
||||
]
|
||||
}
|
||||
|
||||
extension NowNodeTests {
|
||||
static let __allTests = [
|
||||
("testNowNode", testNowNode),
|
||||
]
|
||||
}
|
||||
|
||||
extension StencilTests {
|
||||
static let __allTests = [
|
||||
("testStencil", testStencil),
|
||||
]
|
||||
}
|
||||
|
||||
extension TemplateLoaderTests {
|
||||
static let __allTests = [
|
||||
("testTemplateLoader", testTemplateLoader),
|
||||
]
|
||||
}
|
||||
|
||||
extension TemplateTests {
|
||||
static let __allTests = [
|
||||
("testTemplate", testTemplate),
|
||||
]
|
||||
}
|
||||
|
||||
extension TokenParserTests {
|
||||
static let __allTests = [
|
||||
("testTokenParser", testTokenParser),
|
||||
]
|
||||
}
|
||||
|
||||
extension TokenTests {
|
||||
static let __allTests = [
|
||||
("testToken", testToken),
|
||||
]
|
||||
}
|
||||
|
||||
extension VariableTests {
|
||||
static let __allTests = [
|
||||
("testVariable", testVariable),
|
||||
]
|
||||
}
|
||||
|
||||
#if !os(macOS)
|
||||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(ContextTests.__allTests),
|
||||
testCase(EnvironmentTests.__allTests),
|
||||
testCase(ExpressionsTests.__allTests),
|
||||
testCase(FilterTagTests.__allTests),
|
||||
testCase(FilterTests.__allTests),
|
||||
testCase(ForNodeTests.__allTests),
|
||||
testCase(IfNodeTests.__allTests),
|
||||
testCase(IncludeTests.__allTests),
|
||||
testCase(InheritenceTests.__allTests),
|
||||
testCase(LexerTests.__allTests),
|
||||
testCase(NodeTests.__allTests),
|
||||
testCase(NowNodeTests.__allTests),
|
||||
testCase(StencilTests.__allTests),
|
||||
testCase(TemplateLoaderTests.__allTests),
|
||||
testCase(TemplateTests.__allTests),
|
||||
testCase(TokenParserTests.__allTests),
|
||||
testCase(TokenTests.__allTests),
|
||||
testCase(VariableTests.__allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user