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:
Ilya Puchka
2018-09-23 03:46:27 +03:00
committed by GitHub
parent d238c25eef
commit f7bda226e8
26 changed files with 2386 additions and 2214 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.conche/ .conche/
.build/ .build/
Packages/ Packages/
Package.resolved
Package.pins Package.pins
*.xcodeproj *.xcodeproj

View File

@@ -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 %}` - 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) [Ilya Puchka](https://github.com/ilyapuchka)
[#243](https://github.com/stencilproject/Stencil/pull/243) [#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 }}`. - 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) [Ilya Puchka](https://github.com/ilyapuchka)
[#245](https://github.com/stencilproject/Stencil/pull/245) [#245](https://github.com/stencilproject/Stencil/pull/245)
@@ -35,6 +34,9 @@
- Updated the codebase to use Swift 4 features. - Updated the codebase to use Swift 4 features.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#239](https://github.com/stencilproject/Stencil/pull/239) [#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 ## 0.12.1

25
Package.resolved Normal file
View 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
}

View File

@@ -8,7 +8,7 @@ let package = Package(
], ],
dependencies: [ dependencies: [
.package(url: "https://github.com/kylef/PathKit.git", from: "0.9.0"), .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: [ targets: [
.target(name: "Stencil", dependencies: [ .target(name: "Stencil", dependencies: [

View File

@@ -118,7 +118,7 @@ final class IfExpressionParser {
private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws { private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws {
var parsedComponents = Set<Int>() var parsedComponents = Set<Int>()
var bracketsBalance = 0 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 } guard !parsedComponents.contains(index) else { return nil }
if component == "(" { if component == "(" {

View File

@@ -1,3 +1,8 @@
import XCTest
import StencilTests import StencilTests
stencilTests() var tests = [XCTestCaseEntry]()
tests += StencilTests.__allTests()
XCTMain(tests)

View File

@@ -1,8 +1,11 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
func testContext() { class ContextTests: XCTestCase {
func testContext() {
describe("Context") { describe("Context") {
var context: Context! var context: Context!
@@ -78,4 +81,5 @@ func testContext() {
} }
} }
} }
}
} }

View File

@@ -1,9 +1,10 @@
import XCTest
import Spectre import Spectre
import PathKit import PathKit
@testable import Stencil @testable import Stencil
class EnvironmentTests: XCTestCase {
func testEnvironment() { func testEnvironment() {
describe("Environment") { describe("Environment") {
var environment: Environment! var environment: Environment!
var template: Template! var template: Template!
@@ -329,6 +330,7 @@ func testEnvironment() {
} }
} }
}
} }
extension Expectation { extension Expectation {

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class ExpressionsTests: XCTestCase {
func testExpressions() { func testExpressions() {
describe("Expression") { describe("Expression") {
let parser = TokenParser(tokens: [], environment: Environment()) let parser = TokenParser(tokens: [], environment: Environment())
@@ -341,4 +342,5 @@ func testExpressions() {
} }
} }
} }
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class FilterTests: XCTestCase {
func testFilter() { func testFilter() {
describe("template filters") { describe("template filters") {
let context: [String: Any] = ["name": "Kyle"] let context: [String: Any] = ["name": "Kyle"]
@@ -367,4 +368,5 @@ func testFilter() {
""" """
} }
} }
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
import Stencil import Stencil
class FilterTagTests: XCTestCase {
func testFilterTag() { func testFilterTag() {
describe("Filter Tag") { describe("Filter Tag") {
$0.it("allows you to use a filter") { $0.it("allows you to use a filter") {
let template = Template(templateString: "{% filter uppercase %}Test{% endfilter %}") let template = Template(templateString: "{% filter uppercase %}Test{% endfilter %}")
@@ -46,4 +47,5 @@ func testFilterTag() {
try expect(result) == "1,2" try expect(result) == "1,2"
} }
} }
}
} }

View File

@@ -1,9 +1,10 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import Foundation import Foundation
class ForNodeTests: XCTestCase {
func testForNode() { func testForNode() {
describe("ForNode") { describe("ForNode") {
let context = Context(dictionary: [ let context = Context(dictionary: [
"items": [1, 2, 3], "items": [1, 2, 3],
@@ -346,6 +347,7 @@ func testForNode() {
} }
}
} }
fileprivate struct Article { fileprivate struct Article {

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class IfNodeTests: XCTestCase {
func testIfNode() { func testIfNode() {
describe("IfNode") { describe("IfNode") {
$0.describe("parsing") { $0.describe("parsing") {
$0.it("can parse an if block") { $0.it("can parse an if block") {
@@ -284,4 +285,5 @@ func testIfNode() {
} }
} }
}
} }

View File

@@ -1,9 +1,10 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import PathKit import PathKit
class IncludeTests: XCTestCase {
func testInclude() { func testInclude() {
describe("Include") { describe("Include") {
let path = Path(#file) + ".." + "fixtures" let path = Path(#file) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
@@ -67,4 +68,5 @@ func testInclude() {
} }
} }
} }
}
} }

View File

@@ -1,9 +1,10 @@
import XCTest
import Spectre import Spectre
import Stencil import Stencil
import PathKit import PathKit
class InheritenceTests: XCTestCase {
func testInheritence() { func testInheritence() {
describe("Inheritence") { describe("Inheritence") {
let path = Path(#file) + ".." + "fixtures" let path = Path(#file) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
@@ -33,4 +34,5 @@ func testInheritence() {
""" """
} }
} }
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class LexerTests: XCTestCase {
func testLexer() { func testLexer() {
describe("Lexer") { describe("Lexer") {
$0.it("can tokenize text") { $0.it("can tokenize text") {
let lexer = Lexer(templateString: "Hello World") 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: ".")!))) try expect(tokens[4]) == Token.text(value: ".", at: SourceMap(location: lexer.rangeLocation(templateString.range(of: ".")!)))
} }
} }
}
} }

View File

@@ -1,9 +1,10 @@
import XCTest
import Spectre import Spectre
import Stencil import Stencil
import PathKit import PathKit
class TemplateLoaderTests: XCTestCase {
func testTemplateLoader() { func testTemplateLoader() {
describe("FileSystemLoader") { describe("FileSystemLoader") {
let path = Path(#file) + ".." + "fixtures" let path = Path(#file) + ".." + "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
@@ -52,4 +53,5 @@ func testTemplateLoader() {
_ = try environment.loadTemplate(names: ["unknown.html", "index.html"]) _ = try environment.loadTemplate(names: ["unknown.html", "index.html"])
} }
} }
}
} }

View File

@@ -1,7 +1,7 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class ErrorNode : NodeType { class ErrorNode : NodeType {
let token: Token? let token: Token?
init(token: Token? = nil) { init(token: Token? = nil) {
@@ -13,8 +13,8 @@ class ErrorNode : NodeType {
} }
} }
class NodeTests: XCTestCase {
func testNode() { func testNode() {
describe("Node") { describe("Node") {
let context = Context(dictionary: [ let context = Context(dictionary: [
"name": "Kyle", "name": "Kyle",
@@ -62,4 +62,5 @@ func testNode() {
} }
} }
} }
}
} }

View File

@@ -1,10 +1,12 @@
import XCTest
import Foundation import Foundation
import Spectre import Spectre
@testable import Stencil @testable import Stencil
func testNowNode() { class NowNodeTests: XCTestCase {
#if !os(Linux) func testNowNode() {
#if !os(Linux)
describe("NowNode") { describe("NowNode") {
$0.describe("parsing") { $0.describe("parsing") {
$0.it("parses default format without any now arguments") { $0.it("parses default format without any now arguments") {
@@ -39,5 +41,6 @@ func testNowNode() {
} }
} }
} }
#endif #endif
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class TokenParserTests: XCTestCase {
func testTokenParser() { func testTokenParser() {
describe("TokenParser") { describe("TokenParser") {
$0.it("can parse a text token") { $0.it("can parse a text token") {
let parser = TokenParser(tokens: [ 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)) try expect(try parser.parse()).toThrow(TemplateSyntaxError(reason: "Unknown template tag 'unknown'", token: tokens.first))
} }
} }
}
} }

View File

@@ -1,7 +1,7 @@
import XCTest
import Spectre import Spectre
import Stencil import Stencil
fileprivate struct CustomNode : NodeType { fileprivate struct CustomNode : NodeType {
let token: Token? let token: Token?
func render(_ context:Context) throws -> String { func render(_ context:Context) throws -> String {
@@ -9,14 +9,13 @@ fileprivate struct CustomNode : NodeType {
} }
} }
fileprivate struct Article { fileprivate struct Article {
let title: String let title: String
let author: String let author: String
} }
class StencilTests: XCTestCase {
func testStencil() { func testStencil() {
describe("Stencil") { describe("Stencil") {
let exampleExtension = Extension() let exampleExtension = Extension()
@@ -69,4 +68,5 @@ func testStencil() {
try expect(result) == "Hello World" try expect(result) == "Hello World"
} }
} }
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class TemplateTests: XCTestCase {
func testTemplate() { func testTemplate() {
describe("Template") { describe("Template") {
$0.it("can render a template from a string") { $0.it("can render a template from a string") {
let template = Template(templateString: "Hello World") let template = Template(templateString: "Hello World")
@@ -17,4 +18,5 @@ func testTemplate() {
} }
} }
}
} }

View File

@@ -1,8 +1,9 @@
import XCTest
import Spectre import Spectre
@testable import Stencil @testable import Stencil
class TokenTests: XCTestCase {
func testToken() { func testToken() {
describe("Token") { describe("Token") {
$0.it("can split the contents into components") { $0.it("can split the contents into components") {
let token = Token.text(value: "hello world", at: .unknown) let token = Token.text(value: "hello world", at: .unknown)
@@ -31,4 +32,5 @@ func testToken() {
try expect(components[1]) == "\"kyle fuller\"" try expect(components[1]) == "\"kyle fuller\""
} }
} }
}
} }

View File

@@ -1,3 +1,4 @@
import XCTest
import Foundation import Foundation
import Spectre import Spectre
@testable import Stencil @testable import Stencil
@@ -29,7 +30,8 @@ fileprivate class Blog: WebSite {
let featuring: Article? = Article(author: Person(name: "Jhon")) let featuring: Article? = Article(author: Person(name: "Jhon"))
} }
func testVariable() { class VariableTests: XCTestCase {
func testVariable() {
describe("Variable") { describe("Variable") {
let context = Context(dictionary: [ let context = Context(dictionary: [
"name": "Kyle", "name": "Kyle",
@@ -44,9 +46,9 @@ func testVariable() {
"tuple": (one: 1, two: 2) "tuple": (one: 1, two: 2)
]) ])
#if os(OSX) #if os(OSX)
context["object"] = Object() context["object"] = Object()
#endif #endif
context["blog"] = Blog() context["blog"] = Blog()
$0.it("can resolve a string literal with double quotes") { $0.it("can resolve a string literal with double quotes") {
@@ -186,7 +188,7 @@ func testVariable() {
try expect(result) == "Kyle" try expect(result) == "Kyle"
} }
#if os(OSX) #if os(OSX)
$0.it("can resolve a value via KVO") { $0.it("can resolve a value via KVO") {
let variable = Variable("object.title") let variable = Variable("object.title")
let result = try variable.resolve(context) as? String let result = try variable.resolve(context) as? String
@@ -204,7 +206,7 @@ func testVariable() {
let result = try variable.resolve(context) as? String let result = try variable.resolve(context) as? String
try expect(result).to.beNil() try expect(result).to.beNil()
} }
#endif #endif
$0.it("can resolve a value via reflection") { $0.it("can resolve a value via reflection") {
let variable = Variable("blog.articles.0.author.name") 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") { $0.it("can resolve a subscript via KVO") {
try context.push(dictionary: ["property": "name"]) { try context.push(dictionary: ["property": "name"]) {
let variable = Variable("object[property]") let variable = Variable("object[property]")
@@ -278,7 +280,7 @@ func testVariable() {
try expect(result) == "Foo" try expect(result) == "Foo"
} }
} }
#endif #endif
$0.it("can resolve an optional subscript via reflection") { $0.it("can resolve an optional subscript via reflection") {
try context.push(dictionary: ["property": "featuring"]) { try context.push(dictionary: ["property": "featuring"]) {
@@ -406,4 +408,5 @@ func testVariable() {
try expect(template.render(Context(dictionary: ["variable": "a"]))).toThrow() try expect(template.render(Context(dictionary: ["variable": "a"]))).toThrow()
} }
} }
}
} }

View File

@@ -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()
}
}

View 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