Update from Hummingbird Project Template (#58)
* Update from hummingbird-project-template 572d468b2cabeca286314c5a35196bd42445c8ef * run swift-format * Remove .swiftformat --------- Co-authored-by: adam-fowler <adam-fowler@users.noreply.github.com> Co-authored-by: Adam Fowler <adamfowler71@gmail.com>
This commit is contained in:
committed by
GitHub
parent
8c5c8ead74
commit
ec4ef9aa04
6
.github/workflows/validate.yml
vendored
6
.github/workflows/validate.yml
vendored
@@ -8,16 +8,12 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
validate:
|
validate:
|
||||||
runs-on: macOS-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Install Dependencies
|
|
||||||
run: |
|
|
||||||
brew install mint
|
|
||||||
mint install NickLockwood/SwiftFormat@0.53.10 --no-link
|
|
||||||
- name: run script
|
- name: run script
|
||||||
run: ./scripts/validate.sh
|
run: ./scripts/validate.sh
|
||||||
|
|||||||
63
.swift-format
Normal file
63
.swift-format
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"version" : 1,
|
||||||
|
"indentation" : {
|
||||||
|
"spaces" : 4
|
||||||
|
},
|
||||||
|
"tabWidth" : 4,
|
||||||
|
"fileScopedDeclarationPrivacy" : {
|
||||||
|
"accessLevel" : "private"
|
||||||
|
},
|
||||||
|
"spacesAroundRangeFormationOperators" : false,
|
||||||
|
"indentConditionalCompilationBlocks" : false,
|
||||||
|
"indentSwitchCaseLabels" : false,
|
||||||
|
"lineBreakAroundMultilineExpressionChainComponents" : false,
|
||||||
|
"lineBreakBeforeControlFlowKeywords" : false,
|
||||||
|
"lineBreakBeforeEachArgument" : true,
|
||||||
|
"lineBreakBeforeEachGenericRequirement" : true,
|
||||||
|
"lineLength" : 150,
|
||||||
|
"maximumBlankLines" : 1,
|
||||||
|
"respectsExistingLineBreaks" : true,
|
||||||
|
"prioritizeKeepingFunctionOutputTogether" : true,
|
||||||
|
"multiElementCollectionTrailingCommas" : true,
|
||||||
|
"rules" : {
|
||||||
|
"AllPublicDeclarationsHaveDocumentation" : false,
|
||||||
|
"AlwaysUseLiteralForEmptyCollectionInit" : false,
|
||||||
|
"AlwaysUseLowerCamelCase" : false,
|
||||||
|
"AmbiguousTrailingClosureOverload" : true,
|
||||||
|
"BeginDocumentationCommentWithOneLineSummary" : false,
|
||||||
|
"DoNotUseSemicolons" : true,
|
||||||
|
"DontRepeatTypeInStaticProperties" : true,
|
||||||
|
"FileScopedDeclarationPrivacy" : true,
|
||||||
|
"FullyIndirectEnum" : true,
|
||||||
|
"GroupNumericLiterals" : true,
|
||||||
|
"IdentifiersMustBeASCII" : true,
|
||||||
|
"NeverForceUnwrap" : false,
|
||||||
|
"NeverUseForceTry" : false,
|
||||||
|
"NeverUseImplicitlyUnwrappedOptionals" : false,
|
||||||
|
"NoAccessLevelOnExtensionDeclaration" : true,
|
||||||
|
"NoAssignmentInExpressions" : true,
|
||||||
|
"NoBlockComments" : true,
|
||||||
|
"NoCasesWithOnlyFallthrough" : true,
|
||||||
|
"NoEmptyTrailingClosureParentheses" : true,
|
||||||
|
"NoLabelsInCasePatterns" : true,
|
||||||
|
"NoLeadingUnderscores" : false,
|
||||||
|
"NoParensAroundConditions" : true,
|
||||||
|
"NoVoidReturnOnFunctionSignature" : true,
|
||||||
|
"OmitExplicitReturns" : true,
|
||||||
|
"OneCasePerLine" : true,
|
||||||
|
"OneVariableDeclarationPerLine" : true,
|
||||||
|
"OnlyOneTrailingClosureArgument" : true,
|
||||||
|
"OrderedImports" : true,
|
||||||
|
"ReplaceForEachWithForLoop" : true,
|
||||||
|
"ReturnVoidInsteadOfEmptyTuple" : true,
|
||||||
|
"UseEarlyExits" : false,
|
||||||
|
"UseExplicitNilCheckInConditions" : false,
|
||||||
|
"UseLetInEveryBoundCaseVariable" : false,
|
||||||
|
"UseShorthandTypeNames" : true,
|
||||||
|
"UseSingleLinePropertyGetter" : false,
|
||||||
|
"UseSynthesizedInitializer" : false,
|
||||||
|
"UseTripleSlashForDocumentationComments" : true,
|
||||||
|
"UseWhereClausesInForLoops" : false,
|
||||||
|
"ValidateDocumentationComments" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
26
.swiftformat
26
.swiftformat
@@ -1,26 +0,0 @@
|
|||||||
# Minimum swiftformat version
|
|
||||||
--minversion 0.53.10
|
|
||||||
|
|
||||||
# Swift version
|
|
||||||
--swiftversion 5.9
|
|
||||||
|
|
||||||
# file options
|
|
||||||
--exclude .build
|
|
||||||
|
|
||||||
# rules
|
|
||||||
--disable redundantReturn, extensionAccessControl, typeSugar, conditionalAssignment, preferForLoop, redundantInternal, redundantStaticSelf
|
|
||||||
|
|
||||||
# format options
|
|
||||||
--ifdef no-indent
|
|
||||||
--nospaceoperators ...,..<
|
|
||||||
--patternlet inline
|
|
||||||
--self insert
|
|
||||||
--stripunusedargs unnamed-only
|
|
||||||
|
|
||||||
#--maxwidth 150
|
|
||||||
--wraparguments before-first
|
|
||||||
--wrapparameters before-first
|
|
||||||
--wrapcollections before-first
|
|
||||||
|
|
||||||
#file header
|
|
||||||
# --header "//===----------------------------------------------------------------------===//\n//\n// This source file is part of the Hummingbird server framework project\n//\n// Copyright (c) {created.year}-{year} the Hummingbird authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//"
|
|
||||||
@@ -28,4 +28,4 @@ The main development branch of the repository is `main`.
|
|||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
We use Nick Lockwood's SwiftFormat for formatting code. PRs will not be accepted if they haven't be formatted. The current version of SwiftFormat we are using is v0.53.10.
|
We use Apple's swift-format for formatting code. PRs will not be accepted if they haven't be formatted.
|
||||||
@@ -7,7 +7,7 @@ let package = Package(
|
|||||||
name: "swift-mustache",
|
name: "swift-mustache",
|
||||||
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6)],
|
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6)],
|
||||||
products: [
|
products: [
|
||||||
.library(name: "Mustache", targets: ["Mustache"]),
|
.library(name: "Mustache", targets: ["Mustache"])
|
||||||
],
|
],
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
targets: [
|
targets: [
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ public protocol MustacheContentType: Sendable {
|
|||||||
/// Text content type where no character is escaped
|
/// Text content type where no character is escaped
|
||||||
struct TextContentType: MustacheContentType {
|
struct TextContentType: MustacheContentType {
|
||||||
func escapeText(_ text: String) -> String {
|
func escapeText(_ text: String) -> String {
|
||||||
return text
|
text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HTML content where text is escaped for HTML output
|
/// HTML content where text is escaped for HTML output
|
||||||
struct HTMLContentType: MustacheContentType {
|
struct HTMLContentType: MustacheContentType {
|
||||||
func escapeText(_ text: String) -> String {
|
func escapeText(_ text: String) -> String {
|
||||||
return text.htmlEscape()
|
text.htmlEscape()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ struct HTMLContentType: MustacheContentType {
|
|||||||
/// with `MustacheContentTypes.register`.
|
/// with `MustacheContentTypes.register`.
|
||||||
public enum MustacheContentTypes {
|
public enum MustacheContentTypes {
|
||||||
static func get(_ name: String) -> MustacheContentType? {
|
static func get(_ name: String) -> MustacheContentType? {
|
||||||
return self.types[name]
|
self.types[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register new content type
|
/// Register new content type
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ struct MustacheContext {
|
|||||||
|
|
||||||
/// return context with sequence info and sequence element added to stack
|
/// return context with sequence info and sequence element added to stack
|
||||||
func withContentType(_ contentType: MustacheContentType) -> MustacheContext {
|
func withContentType(_ contentType: MustacheContentType) -> MustacheContext {
|
||||||
return .init(
|
.init(
|
||||||
stack: self.stack,
|
stack: self.stack,
|
||||||
sequenceContext: self.sequenceContext,
|
sequenceContext: self.sequenceContext,
|
||||||
indentation: self.indentation,
|
indentation: self.indentation,
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ public struct MustacheLambda {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal func callAsFunction(_ s: String) -> Any? {
|
internal func callAsFunction(_ s: String) -> Any? {
|
||||||
return self.callback(s)
|
self.callback(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ public protocol MustacheParent {
|
|||||||
/// Extend dictionary where the key is a string so that it uses the key values to access
|
/// Extend dictionary where the key is a string so that it uses the key values to access
|
||||||
/// it values
|
/// it values
|
||||||
extension Dictionary: MustacheParent where Key == String {
|
extension Dictionary: MustacheParent where Key == String {
|
||||||
public func child(named: String) -> Any? { return self[named] }
|
public func child(named: String) -> Any? { self[named] }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ struct Parser {
|
|||||||
self.position = string.startIndex
|
self.position = string.startIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer: String { return self._storage.buffer }
|
var buffer: String { self._storage.buffer }
|
||||||
private(set) var position: String.Index
|
private(set) var position: String.Index
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,10 @@ extension Parser {
|
|||||||
/// - Returns: If current character was the one we expected
|
/// - Returns: If current character was the one we expected
|
||||||
mutating func read(_ char: Character) throws -> Bool {
|
mutating func read(_ char: Character) throws -> Bool {
|
||||||
let c = try character()
|
let c = try character()
|
||||||
guard c == char else { unsafeRetreat(); return false }
|
guard c == char else {
|
||||||
|
unsafeRetreat()
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +87,10 @@ extension Parser {
|
|||||||
/// - Returns: If current character is in character set
|
/// - Returns: If current character is in character set
|
||||||
mutating func read(_ characterSet: Set<Character>) throws -> Bool {
|
mutating func read(_ characterSet: Set<Character>) throws -> Bool {
|
||||||
let c = try character()
|
let c = try character()
|
||||||
guard characterSet.contains(c) else { unsafeRetreat(); return false }
|
guard characterSet.contains(c) else {
|
||||||
|
unsafeRetreat()
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,13 +292,13 @@ extension Parser {
|
|||||||
/// Return whether we have reached the end of the buffer
|
/// Return whether we have reached the end of the buffer
|
||||||
/// - Returns: Have we reached the end
|
/// - Returns: Have we reached the end
|
||||||
func reachedEnd() -> Bool {
|
func reachedEnd() -> Bool {
|
||||||
return self.position == self.buffer.endIndex
|
self.position == self.buffer.endIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return whether we are at the start of the buffer
|
/// Return whether we are at the start of the buffer
|
||||||
/// - Returns: Are we are the start
|
/// - Returns: Are we are the start
|
||||||
func atStart() -> Bool {
|
func atStart() -> Bool {
|
||||||
return self.position == self.buffer.startIndex
|
self.position == self.buffer.startIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +384,7 @@ extension Parser {
|
|||||||
// unsafe versions without checks
|
// unsafe versions without checks
|
||||||
extension Parser {
|
extension Parser {
|
||||||
func unsafeCurrent() -> Character {
|
func unsafeCurrent() -> Character {
|
||||||
return self.buffer[self.position]
|
self.buffer[self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeAdvance() {
|
mutating func unsafeAdvance() {
|
||||||
|
|||||||
@@ -327,7 +327,8 @@ extension MustacheTemplate {
|
|||||||
}
|
}
|
||||||
if self.isStandalone(&parser, state: state) {
|
if self.isStandalone(&parser, state: state) {
|
||||||
setNewLine = true
|
setNewLine = true
|
||||||
} else if whiteSpaceBefore.count > 0 {}
|
} else if whiteSpaceBefore.count > 0 {
|
||||||
|
}
|
||||||
let sectionTemplate = try parse(&parser, state: state.withSectionName(name, newLine: setNewLine))
|
let sectionTemplate = try parse(&parser, state: state.withSectionName(name, newLine: setNewLine))
|
||||||
tokens.append(.blockExpansion(name: name, default: sectionTemplate, indentation: String(whiteSpaceBefore)))
|
tokens.append(.blockExpansion(name: name, default: sectionTemplate, indentation: String(whiteSpaceBefore)))
|
||||||
whiteSpaceBefore = ""
|
whiteSpaceBefore = ""
|
||||||
@@ -512,7 +513,7 @@ extension MustacheTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func isStandalone(_ parser: inout Parser, state: ParserState) -> Bool {
|
static func isStandalone(_ parser: inout Parser, state: ParserState) -> Bool {
|
||||||
return state.newLine && self.hasLineFinished(&parser)
|
state.newLine && self.hasLineFinished(&parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let sectionNameCharsWithoutBrackets = Set<Character>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_?*")
|
private static let sectionNameCharsWithoutBrackets = Set<Character>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_?*")
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ public protocol MustacheTransformable {
|
|||||||
func transform(_ name: String) -> Any?
|
func transform(_ name: String) -> Any?
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension StringProtocol {
|
extension StringProtocol {
|
||||||
/// Transform String/Substring
|
/// Transform String/Substring
|
||||||
///
|
///
|
||||||
/// Transforms available are `capitalized`, `lowercased`, `uppercased` and `reversed`
|
/// Transforms available are `capitalized`, `lowercased`, `uppercased` and `reversed`
|
||||||
/// - Parameter name: transform name
|
/// - Parameter name: transform name
|
||||||
/// - Returns: Result
|
/// - Returns: Result
|
||||||
func transform(_ name: String) -> Any? {
|
public func transform(_ name: String) -> Any? {
|
||||||
switch name {
|
switch name {
|
||||||
case "empty":
|
case "empty":
|
||||||
return isEmpty
|
return isEmpty
|
||||||
@@ -209,13 +209,13 @@ extension Dictionary: ComparableSequence where Key: Comparable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension FixedWidthInteger {
|
extension FixedWidthInteger {
|
||||||
/// Transform FixedWidthInteger
|
/// Transform FixedWidthInteger
|
||||||
///
|
///
|
||||||
/// Transforms available are `plusone`, `minusone`, `odd`, `even`
|
/// Transforms available are `plusone`, `minusone`, `odd`, `even`
|
||||||
/// - Parameter name: transform name
|
/// - Parameter name: transform name
|
||||||
/// - Returns: Result
|
/// - Returns: Result
|
||||||
func transform(_ name: String) -> Any? {
|
public func transform(_ name: String) -> Any? {
|
||||||
switch name {
|
switch name {
|
||||||
case "equalzero":
|
case "equalzero":
|
||||||
return self == 0
|
return self == 0
|
||||||
|
|||||||
@@ -17,11 +17,15 @@ import XCTest
|
|||||||
|
|
||||||
final class ErrorTests: XCTestCase {
|
final class ErrorTests: XCTestCase {
|
||||||
func testSectionCloseNameIncorrect() {
|
func testSectionCloseNameIncorrect() {
|
||||||
XCTAssertThrowsError(try MustacheTemplate(string: """
|
XCTAssertThrowsError(
|
||||||
|
try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#test}}
|
{{#test}}
|
||||||
{{.}}
|
{{.}}
|
||||||
{{/test2}}
|
{{/test2}}
|
||||||
""")) { error in
|
"""
|
||||||
|
)
|
||||||
|
) { error in
|
||||||
switch error {
|
switch error {
|
||||||
case let error as MustacheTemplate.ParserError:
|
case let error as MustacheTemplate.ParserError:
|
||||||
XCTAssertEqual(error.error as? MustacheTemplate.Error, .sectionCloseNameIncorrect)
|
XCTAssertEqual(error.error as? MustacheTemplate.Error, .sectionCloseNameIncorrect)
|
||||||
@@ -36,11 +40,15 @@ final class ErrorTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testUnfinishedName() {
|
func testUnfinishedName() {
|
||||||
XCTAssertThrowsError(try MustacheTemplate(string: """
|
XCTAssertThrowsError(
|
||||||
|
try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#test}}
|
{{#test}}
|
||||||
{{name}
|
{{name}
|
||||||
{{/test2}}
|
{{/test2}}
|
||||||
""")) { error in
|
"""
|
||||||
|
)
|
||||||
|
) { error in
|
||||||
switch error {
|
switch error {
|
||||||
case let error as MustacheTemplate.ParserError:
|
case let error as MustacheTemplate.ParserError:
|
||||||
XCTAssertEqual(error.error as? MustacheTemplate.Error, .unfinishedName)
|
XCTAssertEqual(error.error as? MustacheTemplate.Error, .unfinishedName)
|
||||||
@@ -55,10 +63,14 @@ final class ErrorTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testExpectedSectionEnd() {
|
func testExpectedSectionEnd() {
|
||||||
XCTAssertThrowsError(try MustacheTemplate(string: """
|
XCTAssertThrowsError(
|
||||||
|
try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#test}}
|
{{#test}}
|
||||||
{{.}}
|
{{.}}
|
||||||
""")) { error in
|
"""
|
||||||
|
)
|
||||||
|
) { error in
|
||||||
switch error {
|
switch error {
|
||||||
case let error as MustacheTemplate.ParserError:
|
case let error as MustacheTemplate.ParserError:
|
||||||
XCTAssertEqual(error.error as? MustacheTemplate.Error, .expectedSectionEnd)
|
XCTAssertEqual(error.error as? MustacheTemplate.Error, .expectedSectionEnd)
|
||||||
@@ -73,11 +85,15 @@ final class ErrorTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testInvalidSetDelimiter() {
|
func testInvalidSetDelimiter() {
|
||||||
XCTAssertThrowsError(try MustacheTemplate(string: """
|
XCTAssertThrowsError(
|
||||||
|
try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{=<% %>=}}
|
{{=<% %>=}}
|
||||||
<%.%>
|
<%.%>
|
||||||
<%={{}}=%>
|
<%={{}}=%>
|
||||||
""")) { error in
|
"""
|
||||||
|
)
|
||||||
|
) { error in
|
||||||
switch error {
|
switch error {
|
||||||
case let error as MustacheTemplate.ParserError:
|
case let error as MustacheTemplate.ParserError:
|
||||||
XCTAssertEqual(error.error as? MustacheTemplate.Error, .invalidSetDelimiter)
|
XCTAssertEqual(error.error as? MustacheTemplate.Error, .invalidSetDelimiter)
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@testable import Mustache
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
|
@testable import Mustache
|
||||||
|
|
||||||
final class LibraryTests: XCTestCase {
|
final class LibraryTests: XCTestCase {
|
||||||
func testDirectoryLoad() async throws {
|
func testDirectoryLoad() async throws {
|
||||||
let fs = FileManager()
|
let fs = FileManager()
|
||||||
@@ -54,11 +55,13 @@ final class LibraryTests: XCTestCase {
|
|||||||
let mustache = Data("<test>{{#value}}<value>{{.}}</value>{{/value}}</test>".utf8)
|
let mustache = Data("<test>{{#value}}<value>{{.}}</value>{{/value}}</test>".utf8)
|
||||||
try mustache.write(to: URL(fileURLWithPath: "templates/test.mustache"))
|
try mustache.write(to: URL(fileURLWithPath: "templates/test.mustache"))
|
||||||
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/test.mustache")) }
|
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/test.mustache")) }
|
||||||
let mustache2 = Data("""
|
let mustache2 = Data(
|
||||||
|
"""
|
||||||
{{#test}}
|
{{#test}}
|
||||||
{{{name}}
|
{{{name}}
|
||||||
{{/test2}}
|
{{/test2}}
|
||||||
""".utf8)
|
""".utf8
|
||||||
|
)
|
||||||
try mustache2.write(to: URL(fileURLWithPath: "templates/error.mustache"))
|
try mustache2.write(to: URL(fileURLWithPath: "templates/error.mustache"))
|
||||||
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/error.mustache")) }
|
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/error.mustache")) }
|
||||||
|
|
||||||
|
|||||||
@@ -12,46 +12,57 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@testable import Mustache
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
|
@testable import Mustache
|
||||||
|
|
||||||
final class PartialTests: XCTestCase {
|
final class PartialTests: XCTestCase {
|
||||||
/// Testing partials
|
/// Testing partials
|
||||||
func testMustacheManualExample9() throws {
|
func testMustacheManualExample9() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
{{#names}}
|
{{#names}}
|
||||||
{{> user}}
|
{{> user}}
|
||||||
{{/names}}
|
{{/names}}
|
||||||
""")
|
"""
|
||||||
let template2 = try MustacheTemplate(string: """
|
)
|
||||||
|
let template2 = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<strong>{{.}}</strong>
|
<strong>{{.}}</strong>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let library = MustacheLibrary(templates: ["base": template, "user": template2])
|
let library = MustacheLibrary(templates: ["base": template, "user": template2])
|
||||||
|
|
||||||
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
|
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
|
||||||
XCTAssertEqual(library.render(object, withTemplate: "base"), """
|
XCTAssertEqual(
|
||||||
|
library.render(object, withTemplate: "base"),
|
||||||
|
"""
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
<strong>john</strong>
|
<strong>john</strong>
|
||||||
<strong>adam</strong>
|
<strong>adam</strong>
|
||||||
<strong>claire</strong>
|
<strong>claire</strong>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test where last line of partial generates no content. It should not add a
|
/// Test where last line of partial generates no content. It should not add a
|
||||||
/// tab either
|
/// tab either
|
||||||
func testPartialEmptyLineTabbing() throws {
|
func testPartialEmptyLineTabbing() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
{{#names}}
|
{{#names}}
|
||||||
{{> user}}
|
{{> user}}
|
||||||
{{/names}}
|
{{/names}}
|
||||||
Text after
|
Text after
|
||||||
|
|
||||||
""")
|
"""
|
||||||
let template2 = try MustacheTemplate(string: """
|
)
|
||||||
|
let template2 = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{^empty(.)}}
|
{{^empty(.)}}
|
||||||
<strong>{{.}}</strong>
|
<strong>{{.}}</strong>
|
||||||
{{/empty(.)}}
|
{{/empty(.)}}
|
||||||
@@ -59,73 +70,98 @@ final class PartialTests: XCTestCase {
|
|||||||
<strong>empty</strong>
|
<strong>empty</strong>
|
||||||
{{/empty(.)}}
|
{{/empty(.)}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
var library = MustacheLibrary()
|
var library = MustacheLibrary()
|
||||||
library.register(template, named: "base")
|
library.register(template, named: "base")
|
||||||
library.register(template2, named: "user")
|
library.register(template2, named: "user")
|
||||||
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
|
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
|
||||||
XCTAssertEqual(library.render(object, withTemplate: "base"), """
|
XCTAssertEqual(
|
||||||
|
library.render(object, withTemplate: "base"),
|
||||||
|
"""
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
<strong>john</strong>
|
<strong>john</strong>
|
||||||
<strong>adam</strong>
|
<strong>adam</strong>
|
||||||
<strong>claire</strong>
|
<strong>claire</strong>
|
||||||
Text after
|
Text after
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTrailingNewLines() throws {
|
func testTrailingNewLines() throws {
|
||||||
let template1 = try MustacheTemplate(string: """
|
let template1 = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{> withNewLine }}
|
{{> withNewLine }}
|
||||||
>> {{> withNewLine }}
|
>> {{> withNewLine }}
|
||||||
[ {{> withNewLine }} ]
|
[ {{> withNewLine }} ]
|
||||||
""")
|
"""
|
||||||
let template2 = try MustacheTemplate(string: """
|
)
|
||||||
|
let template2 = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{> withoutNewLine }}
|
{{> withoutNewLine }}
|
||||||
>> {{> withoutNewLine }}
|
>> {{> withoutNewLine }}
|
||||||
[ {{> withoutNewLine }} ]
|
[ {{> withoutNewLine }} ]
|
||||||
""")
|
"""
|
||||||
let withNewLine = try MustacheTemplate(string: """
|
)
|
||||||
|
let withNewLine = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#things}}{{.}}, {{/things}}
|
{{#things}}{{.}}, {{/things}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let withoutNewLine = try MustacheTemplate(string: "{{#things}}{{.}}, {{/things}}")
|
let withoutNewLine = try MustacheTemplate(string: "{{#things}}{{.}}, {{/things}}")
|
||||||
let library = MustacheLibrary(templates: ["base1": template1, "base2": template2, "withNewLine": withNewLine, "withoutNewLine": withoutNewLine])
|
let library = MustacheLibrary(templates: [
|
||||||
|
"base1": template1, "base2": template2, "withNewLine": withNewLine, "withoutNewLine": withoutNewLine,
|
||||||
|
])
|
||||||
let object = ["things": [1, 2, 3, 4, 5]]
|
let object = ["things": [1, 2, 3, 4, 5]]
|
||||||
XCTAssertEqual(library.render(object, withTemplate: "base1"), """
|
XCTAssertEqual(
|
||||||
|
library.render(object, withTemplate: "base1"),
|
||||||
|
"""
|
||||||
1, 2, 3, 4, 5,
|
1, 2, 3, 4, 5,
|
||||||
>> 1, 2, 3, 4, 5,
|
>> 1, 2, 3, 4, 5,
|
||||||
|
|
||||||
[ 1, 2, 3, 4, 5,
|
[ 1, 2, 3, 4, 5,
|
||||||
]
|
]
|
||||||
""")
|
"""
|
||||||
XCTAssertEqual(library.render(object, withTemplate: "base2"), """
|
)
|
||||||
|
XCTAssertEqual(
|
||||||
|
library.render(object, withTemplate: "base2"),
|
||||||
|
"""
|
||||||
1, 2, 3, 4, 5, >> 1, 2, 3, 4, 5,
|
1, 2, 3, 4, 5, >> 1, 2, 3, 4, 5,
|
||||||
[ 1, 2, 3, 4, 5, ]
|
[ 1, 2, 3, 4, 5, ]
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Testing dynamic partials
|
/// Testing dynamic partials
|
||||||
func testDynamicPartials() throws {
|
func testDynamicPartials() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
{{partial}}
|
{{partial}}
|
||||||
""")
|
"""
|
||||||
let template2 = try MustacheTemplate(string: """
|
)
|
||||||
|
let template2 = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#names}}
|
{{#names}}
|
||||||
<strong>{{.}}</strong>
|
<strong>{{.}}</strong>
|
||||||
{{/names}}
|
{{/names}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let library = MustacheLibrary(templates: ["base": template])
|
let library = MustacheLibrary(templates: ["base": template])
|
||||||
|
|
||||||
let object: [String: Any] = ["names": ["john", "adam", "claire"], "partial": template2]
|
let object: [String: Any] = ["names": ["john", "adam", "claire"], "partial": template2]
|
||||||
XCTAssertEqual(library.render(object, withTemplate: "base"), """
|
XCTAssertEqual(
|
||||||
|
library.render(object, withTemplate: "base"),
|
||||||
|
"""
|
||||||
<h2>Names</h2>
|
<h2>Names</h2>
|
||||||
<strong>john</strong>
|
<strong>john</strong>
|
||||||
<strong>adam</strong>
|
<strong>adam</strong>
|
||||||
<strong>claire</strong>
|
<strong>claire</strong>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test inheritance
|
/// test inheritance
|
||||||
@@ -163,7 +199,9 @@ final class PartialTests: XCTestCase {
|
|||||||
""",
|
""",
|
||||||
named: "mypage"
|
named: "mypage"
|
||||||
)
|
)
|
||||||
XCTAssertEqual(library.render({}, withTemplate: "mypage")!, """
|
XCTAssertEqual(
|
||||||
|
library.render({}, withTemplate: "mypage")!,
|
||||||
|
"""
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>My page title</title>
|
<title>My page title</title>
|
||||||
@@ -171,7 +209,8 @@ final class PartialTests: XCTestCase {
|
|||||||
<h1>Hello world</h1>
|
<h1>Hello world</h1>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInheritanceIndentation() throws {
|
func testInheritanceIndentation() throws {
|
||||||
@@ -194,11 +233,14 @@ final class PartialTests: XCTestCase {
|
|||||||
""",
|
""",
|
||||||
named: "template"
|
named: "template"
|
||||||
)
|
)
|
||||||
XCTAssertEqual(library.render({}, withTemplate: "template"), """
|
XCTAssertEqual(
|
||||||
|
library.render({}, withTemplate: "template"),
|
||||||
|
"""
|
||||||
Hi,
|
Hi,
|
||||||
one
|
one
|
||||||
two
|
two
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ extension AnyDecodable {
|
|||||||
self.init(dictionary.mapValues { $0.value })
|
self.init(dictionary.mapValues { $0.value })
|
||||||
} else {
|
} else {
|
||||||
throw DecodingError.dataCorruptedError(
|
throw DecodingError.dataCorruptedError(
|
||||||
in: container, debugDescription: "AnyDecodable value cannot be decoded"
|
in: container,
|
||||||
|
debugDescription: "AnyDecodable value cannot be decoded"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +103,8 @@ final class MustacheSpecTests: XCTestCase {
|
|||||||
\(result ?? "nil")
|
\(result ?? "nil")
|
||||||
expected:
|
expected:
|
||||||
\(test.expected)
|
\(test.expected)
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +115,8 @@ final class MustacheSpecTests: XCTestCase {
|
|||||||
|
|
||||||
func testSpec(name: String, ignoring: [String] = []) async throws {
|
func testSpec(name: String, ignoring: [String] = []) async throws {
|
||||||
let url = URL(
|
let url = URL(
|
||||||
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json")!
|
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json"
|
||||||
|
)!
|
||||||
try await testSpec(url: url, ignoring: ignoring)
|
try await testSpec(url: url, ignoring: ignoring)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +138,8 @@ final class MustacheSpecTests: XCTestCase {
|
|||||||
|
|
||||||
func testSpec(name: String, only: [String]) async throws {
|
func testSpec(name: String, only: [String]) async throws {
|
||||||
let url = URL(
|
let url = URL(
|
||||||
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json")!
|
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json"
|
||||||
|
)!
|
||||||
try await testSpec(url: url, only: only)
|
try await testSpec(url: url, only: only)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +165,12 @@ final class MustacheSpecTests: XCTestCase {
|
|||||||
"Interpolation": MustacheLambda { "world" },
|
"Interpolation": MustacheLambda { "world" },
|
||||||
"Interpolation - Expansion": MustacheLambda { "{{planet}}" },
|
"Interpolation - Expansion": MustacheLambda { "{{planet}}" },
|
||||||
"Interpolation - Alternate Delimiters": MustacheLambda { "|planet| => {{planet}}" },
|
"Interpolation - Alternate Delimiters": MustacheLambda { "|planet| => {{planet}}" },
|
||||||
"Interpolation - Multiple Calls": MustacheLambda { return MustacheLambda { g += 1; return g }},
|
"Interpolation - Multiple Calls": MustacheLambda {
|
||||||
|
return MustacheLambda {
|
||||||
|
g += 1
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
},
|
||||||
"Escaping": MustacheLambda { ">" },
|
"Escaping": MustacheLambda { ">" },
|
||||||
"Section": MustacheLambda { text in text == "{{x}}" ? "yes" : "no" },
|
"Section": MustacheLambda { text in text == "{{x}}" ? "yes" : "no" },
|
||||||
"Section - Expansion": MustacheLambda { text in text + "{{planet}}" + text },
|
"Section - Expansion": MustacheLambda { text in text + "{{planet}}" + text },
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@testable import Mustache
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
|
@testable import Mustache
|
||||||
|
|
||||||
final class TemplateParserTests: XCTestCase {
|
final class TemplateParserTests: XCTestCase {
|
||||||
func testText() throws {
|
func testText() throws {
|
||||||
let template = try MustacheTemplate(string: "test template")
|
let template = try MustacheTemplate(string: "test template")
|
||||||
|
|||||||
@@ -141,81 +141,103 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
|
|
||||||
/// variables
|
/// variables
|
||||||
func testMustacheManualVariables() throws {
|
func testMustacheManualVariables() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
Hello {{name}}
|
Hello {{name}}
|
||||||
You have just won {{value}} dollars!
|
You have just won {{value}} dollars!
|
||||||
{{#in_ca}}
|
{{#in_ca}}
|
||||||
Well, {{taxed_value}} dollars, after taxes.
|
Well, {{taxed_value}} dollars, after taxes.
|
||||||
{{/in_ca}}
|
{{/in_ca}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["name": "Chris", "value": 10000, "taxed_value": 10000 - (10000 * 0.4), "in_ca": true]
|
let object: [String: Any] = ["name": "Chris", "value": 10000, "taxed_value": 10000 - (10000 * 0.4), "in_ca": true]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
Hello Chris
|
Hello Chris
|
||||||
You have just won 10000 dollars!
|
You have just won 10000 dollars!
|
||||||
Well, 6000.0 dollars, after taxes.
|
Well, 6000.0 dollars, after taxes.
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test escaped and unescaped text
|
/// test escaped and unescaped text
|
||||||
func testMustacheManualEscapedText() throws {
|
func testMustacheManualEscapedText() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
*{{name}}
|
*{{name}}
|
||||||
*{{age}}
|
*{{age}}
|
||||||
*{{company}}
|
*{{company}}
|
||||||
*{{{company}}}
|
*{{{company}}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["name": "Chris", "company": "<b>GitHub</b>"]
|
let object: [String: Any] = ["name": "Chris", "company": "<b>GitHub</b>"]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
*Chris
|
*Chris
|
||||||
*
|
*
|
||||||
*<b>GitHub</b>
|
*<b>GitHub</b>
|
||||||
*<b>GitHub</b>
|
*<b>GitHub</b>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test dotted names
|
/// test dotted names
|
||||||
func test_MustacheManualDottedNames() throws {
|
func test_MustacheManualDottedNames() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
* {{client.name}}
|
* {{client.name}}
|
||||||
* {{age}}
|
* {{age}}
|
||||||
* {{client.company.name}}
|
* {{client.company.name}}
|
||||||
* {{{company.name}}}
|
* {{{company.name}}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = [
|
let object: [String: Any] = [
|
||||||
"client": (
|
"client": (
|
||||||
name: "Chris & Friends",
|
name: "Chris & Friends",
|
||||||
age: 50
|
age: 50
|
||||||
),
|
),
|
||||||
"company": [
|
"company": [
|
||||||
"name": "<b>GitHub</b>",
|
"name": "<b>GitHub</b>"
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
* Chris & Friends
|
* Chris & Friends
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* <b>GitHub</b>
|
* <b>GitHub</b>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test implicit operator
|
/// test implicit operator
|
||||||
func testMustacheManualImplicitOperator() throws {
|
func testMustacheManualImplicitOperator() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
* {{.}}
|
* {{.}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object = "Hello!"
|
let object = "Hello!"
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
* Hello!
|
* Hello!
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test lambda
|
/// test lambda
|
||||||
func test_MustacheManualLambda() throws {
|
func test_MustacheManualLambda() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
* {{time.hour}}
|
* {{time.hour}}
|
||||||
* {{today}}
|
* {{today}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = [
|
let object: [String: Any] = [
|
||||||
"year": 1970,
|
"year": 1970,
|
||||||
"month": 1,
|
"month": 1,
|
||||||
@@ -231,113 +253,151 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
return "{{year}}-{{month}}-{{day}}"
|
return "{{year}}-{{month}}-{{day}}"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
* 0
|
* 0
|
||||||
* 1970-1-1
|
* 1970-1-1
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test boolean
|
/// test boolean
|
||||||
func testMustacheManualSectionFalse() throws {
|
func testMustacheManualSectionFalse() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
Shown.
|
Shown.
|
||||||
{{#person}}
|
{{#person}}
|
||||||
Never shown!
|
Never shown!
|
||||||
{{/person}}
|
{{/person}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["person": false]
|
let object: [String: Any] = ["person": false]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
Shown.
|
Shown.
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test non-empty lists
|
/// test non-empty lists
|
||||||
func testMustacheManualSectionList() throws {
|
func testMustacheManualSectionList() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{name}}</b>
|
<b>{{name}}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>resque</b>
|
<b>resque</b>
|
||||||
<b>hub</b>
|
<b>hub</b>
|
||||||
<b>rip</b>
|
<b>rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test non-empty lists
|
/// test non-empty lists
|
||||||
func testMustacheManualSectionList2() throws {
|
func testMustacheManualSectionList2() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{.}}</b>
|
<b>{{.}}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
|
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>resque</b>
|
<b>resque</b>
|
||||||
<b>hub</b>
|
<b>hub</b>
|
||||||
<b>rip</b>
|
<b>rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test lambdas
|
/// test lambdas
|
||||||
func testMustacheManualSectionLambda() throws {
|
func testMustacheManualSectionLambda() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#wrapped}}{{name}} is awesome.{{/wrapped}}
|
{{#wrapped}}{{name}} is awesome.{{/wrapped}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
func wrapped(_ s: String) -> Any? {
|
func wrapped(_ s: String) -> Any? {
|
||||||
return "<b>\(s)</b>"
|
"<b>\(s)</b>"
|
||||||
}
|
}
|
||||||
let object: [String: Any] = ["name": "Willy", "wrapped": MustacheLambda(wrapped)]
|
let object: [String: Any] = ["name": "Willy", "wrapped": MustacheLambda(wrapped)]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>Willy is awesome.</b>
|
<b>Willy is awesome.</b>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test setting context object
|
/// test setting context object
|
||||||
func testMustacheManualContextObject() throws {
|
func testMustacheManualContextObject() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#person?}}
|
{{#person?}}
|
||||||
Hi {{name}}!
|
Hi {{name}}!
|
||||||
{{/person?}}
|
{{/person?}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["person?": ["name": "Jon"]]
|
let object: [String: Any] = ["person?": ["name": "Jon"]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
Hi Jon!
|
Hi Jon!
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test inverted sections
|
/// test inverted sections
|
||||||
func testMustacheManualInvertedSection() throws {
|
func testMustacheManualInvertedSection() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{name}}</b>
|
<b>{{name}}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
{{^repo}}
|
{{^repo}}
|
||||||
No repos :(
|
No repos :(
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": []]
|
let object: [String: Any] = ["repo": []]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
No repos :(
|
No repos :(
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test comments
|
/// test comments
|
||||||
func testMustacheManualComment() throws {
|
func testMustacheManualComment() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<h1>Today{{! ignore me }}.</h1>
|
<h1>Today{{! ignore me }}.</h1>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": []]
|
let object: [String: Any] = ["repo": []]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<h1>Today.</h1>
|
<h1>Today.</h1>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// test dynamic names
|
/// test dynamic names
|
||||||
@@ -357,18 +417,23 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
|
|
||||||
/// test block with defaults
|
/// test block with defaults
|
||||||
func testMustacheManualBlocksWithDefaults() throws {
|
func testMustacheManualBlocksWithDefaults() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
<h1>{{$title}}The News of Today{{/title}}</h1>
|
<h1>{{$title}}The News of Today{{/title}}</h1>
|
||||||
{{$body}}
|
{{$body}}
|
||||||
<p>Nothing special happened.</p>
|
<p>Nothing special happened.</p>
|
||||||
{{/body}}
|
{{/body}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
XCTAssertEqual(template.render([]), """
|
)
|
||||||
|
XCTAssertEqual(
|
||||||
|
template.render([]),
|
||||||
|
"""
|
||||||
<h1>The News of Today</h1>
|
<h1>The News of Today</h1>
|
||||||
<p>Nothing special happened.</p>
|
<p>Nothing special happened.</p>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMustacheManualParents() throws {
|
func testMustacheManualParents() throws {
|
||||||
@@ -405,7 +470,7 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
"headlines": [
|
"headlines": [
|
||||||
"A pug's handler grew mustaches.",
|
"A pug's handler grew mustaches.",
|
||||||
"What an exciting day!",
|
"What an exciting day!",
|
||||||
],
|
]
|
||||||
]
|
]
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
library.render(object, withTemplate: "main"),
|
library.render(object, withTemplate: "main"),
|
||||||
@@ -474,11 +539,13 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPerformance() throws {
|
func testPerformance() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{name}}</b>
|
<b>{{name}}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
let date = Date()
|
let date = Date()
|
||||||
for _ in 1...10000 {
|
for _ in 1...10000 {
|
||||||
|
|||||||
@@ -17,177 +17,233 @@ import XCTest
|
|||||||
|
|
||||||
final class TransformTests: XCTestCase {
|
final class TransformTests: XCTestCase {
|
||||||
func testLowercased() throws {
|
func testLowercased() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{ lowercased(name) }}
|
{{ lowercased(name) }}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["name": "Test"]
|
let object: [String: Any] = ["name": "Test"]
|
||||||
XCTAssertEqual(template.render(object), "test")
|
XCTAssertEqual(template.render(object), "test")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUppercased() throws {
|
func testUppercased() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{ uppercased(name) }}
|
{{ uppercased(name) }}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["name": "Test"]
|
let object: [String: Any] = ["name": "Test"]
|
||||||
XCTAssertEqual(template.render(object), "TEST")
|
XCTAssertEqual(template.render(object), "TEST")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testNewline() throws {
|
func testNewline() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{name}}</b>
|
<b>{{name}}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>resque</b>
|
<b>resque</b>
|
||||||
<b>hub</b>
|
<b>hub</b>
|
||||||
<b>rip</b>
|
<b>rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFirstLast() throws {
|
func testFirstLast() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{#first()}}first: {{/first()}}{{#last()}}last: {{/last()}}{{ name }}</b>
|
<b>{{#first()}}first: {{/first()}}{{#last()}}last: {{/last()}}{{ name }}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>first: resque</b>
|
<b>first: resque</b>
|
||||||
<b>hub</b>
|
<b>hub</b>
|
||||||
<b>last: rip</b>
|
<b>last: rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIndex() throws {
|
func testIndex() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{#index()}}{{plusone(.)}}{{/index()}}) {{ name }}</b>
|
<b>{{#index()}}{{plusone(.)}}{{/index()}}) {{ name }}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>1) resque</b>
|
<b>1) resque</b>
|
||||||
<b>2) hub</b>
|
<b>2) hub</b>
|
||||||
<b>3) rip</b>
|
<b>3) rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDoubleSequenceTransformWorks() throws {
|
func testDoubleSequenceTransformWorks() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
{{count(reversed(numbers))}}
|
{{count(reversed(numbers))}}
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": ["numbers": [1, 2, 3]]]
|
let object: [String: Any] = ["repo": ["numbers": [1, 2, 3]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
3
|
3
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMultipleTransformWorks() throws {
|
func testMultipleTransformWorks() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
{{minusone(plusone(last(reversed(numbers))))}}
|
{{minusone(plusone(last(reversed(numbers))))}}
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": ["numbers": [5, 4, 3]]]
|
let object: [String: Any] = ["repo": ["numbers": [5, 4, 3]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
5
|
5
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testNestedTransformWorks() throws {
|
func testNestedTransformWorks() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
{{#uppercased(string)}}{{reversed(.)}}{{/uppercased(string)}}
|
{{#uppercased(string)}}{{reversed(.)}}{{/uppercased(string)}}
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": ["string": "a123a"]]
|
let object: [String: Any] = ["repo": ["string": "a123a"]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
A321A
|
A321A
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEvenOdd() throws {
|
func testEvenOdd() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{index()}}) {{#even()}}even {{/even()}}{{#odd()}}odd {{/odd()}}{{ name }}</b>
|
<b>{{index()}}) {{#even()}}even {{/even()}}{{#odd()}}odd {{/odd()}}{{ name }}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>0) even resque</b>
|
<b>0) even resque</b>
|
||||||
<b>1) odd hub</b>
|
<b>1) odd hub</b>
|
||||||
<b>2) even rip</b>
|
<b>2) even rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testReversed() throws {
|
func testReversed() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#reversed(repo)}}
|
{{#reversed(repo)}}
|
||||||
<b>{{ name }}</b>
|
<b>{{ name }}</b>
|
||||||
{{/reversed(repo)}}
|
{{/reversed(repo)}}
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>rip</b>
|
<b>rip</b>
|
||||||
<b>hub</b>
|
<b>hub</b>
|
||||||
<b>resque</b>
|
<b>resque</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testArrayIndex() throws {
|
func testArrayIndex() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#repo}}
|
{{#repo}}
|
||||||
<b>{{ index() }}) {{ name }}</b>
|
<b>{{ index() }}) {{ name }}</b>
|
||||||
{{/repo}}
|
{{/repo}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>0) resque</b>
|
<b>0) resque</b>
|
||||||
<b>1) hub</b>
|
<b>1) hub</b>
|
||||||
<b>2) rip</b>
|
<b>2) rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testArraySorted() throws {
|
func testArraySorted() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#sorted(repo)}}
|
{{#sorted(repo)}}
|
||||||
<b>{{ index() }}) {{ . }}</b>
|
<b>{{ index() }}) {{ . }}</b>
|
||||||
{{/sorted(repo)}}
|
{{/sorted(repo)}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
|
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
|
||||||
XCTAssertEqual(template.render(object), """
|
XCTAssertEqual(
|
||||||
|
template.render(object),
|
||||||
|
"""
|
||||||
<b>0) hub</b>
|
<b>0) hub</b>
|
||||||
<b>1) resque</b>
|
<b>1) resque</b>
|
||||||
<b>2) rip</b>
|
<b>2) rip</b>
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDictionaryEmpty() throws {
|
func testDictionaryEmpty() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#empty(array)}}Array{{/empty(array)}}{{#empty(dictionary)}}Dictionary{{/empty(dictionary)}}
|
{{#empty(array)}}Array{{/empty(array)}}{{#empty(dictionary)}}Dictionary{{/empty(dictionary)}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["array": [], "dictionary": [:]]
|
let object: [String: Any] = ["array": [], "dictionary": [:]]
|
||||||
XCTAssertEqual(template.render(object), "ArrayDictionary")
|
XCTAssertEqual(template.render(object), "ArrayDictionary")
|
||||||
}
|
}
|
||||||
@@ -199,18 +255,22 @@ final class TransformTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testDictionaryEnumerated() throws {
|
func testDictionaryEnumerated() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#enumerated(.)}}<b>{{ key }} = {{ value }}</b>{{/enumerated(.)}}
|
{{#enumerated(.)}}<b>{{ key }} = {{ value }}</b>{{/enumerated(.)}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["one": 1, "two": 2]
|
let object: [String: Any] = ["one": 1, "two": 2]
|
||||||
let result = template.render(object)
|
let result = template.render(object)
|
||||||
XCTAssertTrue(result == "<b>one = 1</b><b>two = 2</b>" || result == "<b>two = 2</b><b>one = 1</b>")
|
XCTAssertTrue(result == "<b>one = 1</b><b>two = 2</b>" || result == "<b>two = 2</b><b>one = 1</b>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDictionarySortedByKey() throws {
|
func testDictionarySortedByKey() throws {
|
||||||
let template = try MustacheTemplate(string: """
|
let template = try MustacheTemplate(
|
||||||
|
string: """
|
||||||
{{#sorted(.)}}<b>{{ key }} = {{ value }}</b>{{/sorted(.)}}
|
{{#sorted(.)}}<b>{{ key }} = {{ value }}</b>{{/sorted(.)}}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
let object: [String: Any] = ["one": 1, "two": 2, "three": 3]
|
let object: [String: Any] = ["one": 1, "two": 2, "three": 3]
|
||||||
let result = template.render(object)
|
let result = template.render(object)
|
||||||
XCTAssertEqual(result, "<b>one = 1</b><b>three = 3</b><b>two = 2</b>")
|
XCTAssertEqual(result, "<b>one = 1</b><b>three = 3</b><b>two = 2</b>")
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ SWIFT_FORMAT_VERSION=0.53.10
|
|||||||
set -eu
|
set -eu
|
||||||
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
which swiftformat > /dev/null 2>&1 || (echo "swiftformat not installed. You can install it using 'brew install swiftformat'" ; exit -1)
|
|
||||||
|
|
||||||
function replace_acceptable_years() {
|
function replace_acceptable_years() {
|
||||||
# this needs to replace all acceptable forms with 'YEARS'
|
# this needs to replace all acceptable forms with 'YEARS'
|
||||||
sed -e 's/20[12][0-9]-20[12][0-9]/YEARS/' -e 's/20[12][0-9]/YEARS/' -e '/^#!/ d'
|
sed -e 's/20[12][0-9]-20[12][0-9]/YEARS/' -e 's/20[12][0-9]/YEARS/' -e '/^#!/ d'
|
||||||
@@ -40,13 +38,9 @@ function replace_acceptable_years() {
|
|||||||
|
|
||||||
printf "=> Checking format... "
|
printf "=> Checking format... "
|
||||||
FIRST_OUT="$(git status --porcelain)"
|
FIRST_OUT="$(git status --porcelain)"
|
||||||
if [[ -n "${CI-""}" ]]; then
|
git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place
|
||||||
printf "(using v$(mint run NickLockwood/SwiftFormat@"$SWIFT_FORMAT_VERSION" --version)) "
|
git diff --exit-code '*.swift'
|
||||||
mint run NickLockwood/SwiftFormat@"$SWIFT_FORMAT_VERSION" . > /dev/null 2>&1
|
|
||||||
else
|
|
||||||
printf "(using v$(swiftformat --version)) "
|
|
||||||
swiftformat . > /dev/null 2>&1
|
|
||||||
fi
|
|
||||||
SECOND_OUT="$(git status --porcelain)"
|
SECOND_OUT="$(git status --porcelain)"
|
||||||
if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
|
if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
|
||||||
printf "\033[0;31mformatting issues!\033[0m\n"
|
printf "\033[0;31mformatting issues!\033[0m\n"
|
||||||
@@ -55,10 +49,11 @@ if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
|
|||||||
else
|
else
|
||||||
printf "\033[0;32mokay.\033[0m\n"
|
printf "\033[0;32mokay.\033[0m\n"
|
||||||
fi
|
fi
|
||||||
exit
|
|
||||||
printf "=> Checking license headers... "
|
printf "=> Checking license headers... "
|
||||||
tmp=$(mktemp /tmp/.soto-core-sanity_XXXXXX)
|
tmp=$(mktemp /tmp/.soto-core-sanity_XXXXXX)
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
for language in swift-or-c; do
|
for language in swift-or-c; do
|
||||||
declare -a matching_files
|
declare -a matching_files
|
||||||
declare -a exceptions
|
declare -a exceptions
|
||||||
@@ -66,18 +61,18 @@ for language in swift-or-c; do
|
|||||||
matching_files=( -name '*' )
|
matching_files=( -name '*' )
|
||||||
case "$language" in
|
case "$language" in
|
||||||
swift-or-c)
|
swift-or-c)
|
||||||
exceptions=( -path '*Sources/INIParser/*' -o -path '*Sources/CSotoExpat/*' -o -path '*Benchmark/.build/*' -o -name Package.swift)
|
exceptions=( -path '*/Benchmarks/.build/*' -o -name Package.swift)
|
||||||
matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' )
|
matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' )
|
||||||
cat > "$tmp" <<"EOF"
|
cat > "$tmp" <<"EOF"
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This source file is part of the Hummingbird open source project
|
// This source file is part of the Hummingbird server framework project
|
||||||
//
|
//
|
||||||
// Copyright (c) YEARS the Hummingbird authors
|
// Copyright (c) YEARS the Hummingbird authors
|
||||||
// Licensed under Apache License v2.0
|
// Licensed under Apache License v2.0
|
||||||
//
|
//
|
||||||
// See LICENSE.txt for license information
|
// See LICENSE.txt for license information
|
||||||
// See CONTRIBUTORS.txt for the list of Hummingbird authors
|
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@@ -89,13 +84,13 @@ EOF
|
|||||||
cat > "$tmp" <<"EOF"
|
cat > "$tmp" <<"EOF"
|
||||||
##===----------------------------------------------------------------------===##
|
##===----------------------------------------------------------------------===##
|
||||||
##
|
##
|
||||||
## This source file is part of the Hummingbird open source project
|
## This source file is part of the Hummingbird server framework project
|
||||||
##
|
##
|
||||||
## Copyright (c) YEARS the Hummingbird authors
|
## Copyright (c) YEARS the Hummingbird authors
|
||||||
## Licensed under Apache License v2.0
|
## Licensed under Apache License v2.0
|
||||||
##
|
##
|
||||||
## See LICENSE.txt for license information
|
## See LICENSE.txt for license information
|
||||||
## See CONTRIBUTORS.txt for the list of Hummingbird authors
|
## See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
|
||||||
##
|
##
|
||||||
## SPDX-License-Identifier: Apache-2.0
|
## SPDX-License-Identifier: Apache-2.0
|
||||||
##
|
##
|
||||||
|
|||||||
Reference in New Issue
Block a user