From 34cbdad1e92c6d6db39a40c88cb74b109065d152 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Thu, 19 Mar 2020 14:00:39 +0100 Subject: [PATCH 01/23] Leaf 4 support --- Package.swift | 10 ++-- Package@swift-4.swift | 19 ------- Sources/LeafMarkdown/Tag.swift | 42 ++++++-------- Tests/LeafMarkdownTests/LeafTests.swift | 74 ++++++++++++++----------- 4 files changed, 66 insertions(+), 79 deletions(-) delete mode 100644 Package@swift-4.swift diff --git a/Package.swift b/Package.swift index 603aa39..d01e9ca 100644 --- a/Package.swift +++ b/Package.swift @@ -4,16 +4,18 @@ import PackageDescription let package = Package( name: "LeafMarkdown", + platforms: [ + .macOS(.v10_15) + ], products: [ .library(name: "LeafMarkdown", targets: ["LeafMarkdown"]), ], dependencies: [ - .package(url: "https://github.com/vapor/template-kit.git", from: "1.4.0"), .package(url: "https://github.com/vapor-community/markdown.git", from: "0.6.1"), - .package(url: "https://github.com/vapor/leaf.git", from: "3.0.0"), + .package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0"), ], targets: [ - .target(name: "LeafMarkdown", dependencies: ["TemplateKit", "SwiftMarkdown"]), - .testTarget(name: "LeafMarkdownTests", dependencies: ["LeafMarkdown", "Leaf"]), + .target(name: "LeafMarkdown", dependencies: ["LeafKit", "SwiftMarkdown"]), + .testTarget(name: "LeafMarkdownTests", dependencies: ["LeafMarkdown", "LeafKit"]), ] ) diff --git a/Package@swift-4.swift b/Package@swift-4.swift deleted file mode 100644 index 0553068..0000000 --- a/Package@swift-4.swift +++ /dev/null @@ -1,19 +0,0 @@ -// swift-tools-version:4.0 - -import PackageDescription - -let package = Package( - name: "LeafMarkdown", - products: [ - .library(name: "LeafMarkdown", targets: ["LeafMarkdown"]), - ], - dependencies: [ - .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"), - .package(url: "https://github.com/vapor/leaf.git", from: "3.0.0"), - .package(url: "https://github.com/vapor-community/markdown.git", .upToNextMajor(from: "0.4.0")), - ], - targets: [ - .target(name: "LeafMarkdown", dependencies: ["Vapor", "Leaf", "SwiftMarkdown"]), - .testTarget(name: "LeafMarkdownTests", dependencies: ["LeafMarkdown"]), - ] -) diff --git a/Sources/LeafMarkdown/Tag.swift b/Sources/LeafMarkdown/Tag.swift index 6c4b736..593ae78 100644 --- a/Sources/LeafMarkdown/Tag.swift +++ b/Sources/LeafMarkdown/Tag.swift @@ -1,42 +1,34 @@ -import TemplateKit +import LeafKit import SwiftMarkdown -public final class Markdown: TagRenderer { - +public struct Markdown: LeafTag { public enum Error: Swift.Error { - case invalidArgument(TemplateData?) + case invalidArgument(LeafData?) } - - public let name = "markdown" - + private let options: MarkdownOptions? - + public init(options: MarkdownOptions? = nil) { self.options = options } - - public func render(tag: TagContext) throws -> Future { - + + public func render(_ ctx: LeafContext) throws -> LeafData { var markdown = "" - - if let markdownArgument = tag.parameters.first, !markdownArgument.isNull { + + if let markdownArgument = ctx.parameters.first, !markdownArgument.isNull { guard let markdownArgumentValue = markdownArgument.string else { - throw Error.invalidArgument(tag.parameters.first) + throw Error.invalidArgument(ctx.parameters.first) } markdown = markdownArgumentValue } - let markdownHTML: String = try { - if let options = options { - return try markdownToHTML(markdown, options: options) - } else { - return try markdownToHTML(markdown) - } - }() - - return Future.map(on: tag) { - .string(markdownHTML) + let markdownHTML: String + if let options = options { + markdownHTML = try markdownToHTML(markdown, options: options) + } else { + markdownHTML = try markdownToHTML(markdown) } - } + return .string(markdownHTML) + } } diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index f1e83fb..f61d6e7 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -1,73 +1,85 @@ import XCTest -@testable import Leaf +@testable import LeafKit import LeafMarkdown -class LeafTests: XCTestCase { - +class MarkdownTests: XCTestCase { // MARK: - Properties var renderer: LeafRenderer! - let template = "#markdown(data)" + var template: ResolvedDocument! // MARK: - Overrides override func setUp() { - let queue = EmbeddedEventLoop() - let container = BasicContainer(config: .init(), environment: .testing, services: .init(), on: queue) - let tag = Markdown() - var leafTagConfig = LeafTagConfig.default() - leafTagConfig.use(tag, as: tag.name) - self.renderer = LeafRenderer(config: LeafConfig(tags: leafTagConfig, viewsDir: "", shouldCache: false), using: container) + let loop = EmbeddedEventLoop() + let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) + var tags = defaultTags + tags["markdown"] = Markdown() + self.renderer = LeafRenderer( + configuration: config, + tags: tags, + files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), + eventLoop: loop + ) + + do { + var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)") + let tokens = try lexer.lex() + var parser = LeafParser(name: "markdowntest", tokens: tokens) + let syntax = try parser.parse() + let unresolved = UnresolvedDocument(name: "markdowntest", raw: syntax) + let resolver = ExtendResolver(document: unresolved, dependencies: []) + template = try resolver.resolve(rootDirectory: config.rootDirectory) + } catch { + XCTFail() + } } // MARK: - Tests func testRunTag() throws { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" - let data = TemplateData.dictionary(["data": .string(inputMarkdown)]) let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let result = try renderer.render(template: template.data(using: .utf8)!, data).wait() - let resultString = String(data: result.data, encoding: .utf8)! + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) } func testNilParameterDoesNotCrashLeaf() throws { - let data = TemplateData.dictionary(["data": .null]) let expectedHtml = "" - - let result = try renderer.render(template: template.data(using: .utf8)!, data).wait() - let resultString = String(data: result.data, encoding: .utf8)! + let result = try renderer.render(template, context: ["data": .null]) + let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) } func testStripHtml() throws { let inputMarkdown = "
" - let data = TemplateData.dictionary(["data": .string(inputMarkdown)]) let expectedHtml = "\n" - let result = try renderer.render(template: template.data(using: .utf8)!, data).wait() - let resultString = String(data: result.data, encoding: .utf8)! + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) } func testDoNotStripHtml() throws { - - let queue = EmbeddedEventLoop() - let container = BasicContainer(config: .init(), environment: .testing, services: .init(), on: queue) - let tag = Markdown(options: [.unsafe]) - var leafTagConfig = LeafTagConfig.default() - leafTagConfig.use(tag, as: tag.name) - let renderer = LeafRenderer(config: LeafConfig(tags: leafTagConfig, viewsDir: "", shouldCache: false), - using: container) + let loop = EmbeddedEventLoop() + let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) + var tags = defaultTags + tags["markdown"] = Markdown(options: []) + let renderer = LeafRenderer( + configuration: config, + tags: tags, + files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), + eventLoop: loop + ) let inputMarkdown = "
" - let data = TemplateData.dictionary(["data": .string(inputMarkdown)]) let expectedHtml = "
\n" - let result = try renderer.render(template: template.data(using: .utf8)!, data).wait() - let resultString = String(data: result.data, encoding: .utf8)! + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) } } From a580588346e1760e635a28be456fe49f374c9adb Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Mon, 23 Mar 2020 09:48:34 +0100 Subject: [PATCH 02/23] Update CI script to trigger for pull requests --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4eaaf58..2384b32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,11 @@ name: CI on: -- push + push: + branches: + - master + pull_request: + branches: + - master jobs: xenial: container: From 388a6d73fdacc6ae88692d170ff74797a010c85e Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 10:24:53 +0100 Subject: [PATCH 03/23] Trigger alwys --- .github/workflows/ci.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2384b32..eeceb55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,7 @@ name: CI on: - push: - branches: - - master - pull_request: - branches: - - master + push + pull_request jobs: xenial: container: From 3fa3f2829a47f72b1ea90a5e8abd0b5caa0a4007 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 10:25:53 +0100 Subject: [PATCH 04/23] Trigger on master push only --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eeceb55..96d5f83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,9 @@ name: CI on: - push - pull_request + push: + branches: + - master + pull_request: jobs: xenial: container: From 0742d0a2be68863b0010b47a0a29103cfe70906f Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 12:12:39 +0100 Subject: [PATCH 05/23] Fix failing test --- Tests/LeafMarkdownTests/LeafTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index f61d6e7..49dcc66 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -67,7 +67,7 @@ class MarkdownTests: XCTestCase { let loop = EmbeddedEventLoop() let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) var tags = defaultTags - tags["markdown"] = Markdown(options: []) + tags["markdown"] = Markdown(options: [.init(rawValue: 1 << 17)]) let renderer = LeafRenderer( configuration: config, tags: tags, From 85eb183a517c7b3b3c1b73ade504401843d26d00 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 14:23:29 +0100 Subject: [PATCH 06/23] Update the manifest to swift 5.2 format --- Package.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index d01e9ca..a2a3a13 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.1 +// swift-tools-version:5.2 import PackageDescription @@ -15,7 +15,13 @@ let package = Package( .package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0"), ], targets: [ - .target(name: "LeafMarkdown", dependencies: ["LeafKit", "SwiftMarkdown"]), - .testTarget(name: "LeafMarkdownTests", dependencies: ["LeafMarkdown", "LeafKit"]), + .target(name: "LeafMarkdown", dependencies: [ + .product(name: "LeafKit", package: "leaf-kit"), + .product(name: "SwiftMarkdown", package: "markdown"), + ]), + .testTarget(name: "LeafMarkdownTests", dependencies: [ + .target(name: "LeafMarkdown"), + .product(name: "LeafKit", package: "leaf-kit"), + ]), ] ) From 8e691aa6deb6b55a03578ebd1442f678405b8ed2 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 14:25:20 +0100 Subject: [PATCH 07/23] Update the CI to swift 5.2 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96d5f83..3c87fcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,14 +7,14 @@ on: jobs: xenial: container: - image: vapor/swift:5.1-xenial + image: vapor/swift:5.2-xenial runs-on: ubuntu-latest steps: - uses: actions/checkout@master - run: swift test --enable-test-discovery --enable-code-coverage bionic: container: - image: vapor/swift:5.1-bionic + image: vapor/swift:5.2-bionic runs-on: ubuntu-latest steps: - uses: actions/checkout@master From 8a757cf5424c28ee9df35482c73abe82867f66a5 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 14:27:32 +0100 Subject: [PATCH 08/23] Try the method that I thought would be correct, but apparantly changed --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index a2a3a13..9227297 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( targets: [ .target(name: "LeafMarkdown", dependencies: [ .product(name: "LeafKit", package: "leaf-kit"), - .product(name: "SwiftMarkdown", package: "markdown"), + .product(name: "SwiftMarkdown", package: "SwiftMarkdown"), ]), .testTarget(name: "LeafMarkdownTests", dependencies: [ .target(name: "LeafMarkdown"), From 1b4e3cb4e530c2d1365d6de19a307f81e1a5ff59 Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Wed, 25 Mar 2020 14:29:16 +0100 Subject: [PATCH 09/23] Revert "Try the method that I thought would be correct, but apparantly changed" This reverts commit 6efaba2629da7ed24c286942b499366271dc3171. --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 9227297..a2a3a13 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( targets: [ .target(name: "LeafMarkdown", dependencies: [ .product(name: "LeafKit", package: "leaf-kit"), - .product(name: "SwiftMarkdown", package: "SwiftMarkdown"), + .product(name: "SwiftMarkdown", package: "markdown"), ]), .testTarget(name: "LeafMarkdownTests", dependencies: [ .target(name: "LeafMarkdown"), From 75c328af0e0d07630da2e328097fa632f1254bc9 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 25 Mar 2020 13:51:58 +0000 Subject: [PATCH 10/23] Fix code coverage --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c87fcd..86bcb16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Setup container for codecov upload run: apt-get update && apt-get install curl - name: Process coverage file - run: llvm-cov show .build/x86_64-unknown-linux/debug/LeafMarkdownPackageTests.xctest -instr-profile=.build/x86_64-unknown-linux/debug/codecov/default.profdata > coverage.txt + run: llvm-cov show .build/x86_64-unknown-linux-gnu/debug/LeafMarkdownPackageTests.xctest -instr-profile=.build/debug/codecov/default.profdata > coverage.txt - name: Upload code coverage uses: codecov/codecov-action@v1 with: From c717d699641940b418033f72883b31e4620a9b1e Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 25 Mar 2020 13:55:17 +0000 Subject: [PATCH 11/23] Only run code coverage on our files --- .codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.codecov.yml b/.codecov.yml index f9f4b3c..fea7da7 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,3 +2,4 @@ coverage: range: "0...100" ignore: - "Tests/" + - ".build/" From c9e21916befb34898fa512fd6d31586551b4740f Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Thu, 26 Mar 2020 13:46:45 +0100 Subject: [PATCH 12/23] Add failure test --- Package.swift | 2 +- Tests/LeafMarkdownTests/LeafTests.swift | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index a2a3a13..9227297 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( targets: [ .target(name: "LeafMarkdown", dependencies: [ .product(name: "LeafKit", package: "leaf-kit"), - .product(name: "SwiftMarkdown", package: "markdown"), + .product(name: "SwiftMarkdown", package: "SwiftMarkdown"), ]), .testTarget(name: "LeafMarkdownTests", dependencies: [ .target(name: "LeafMarkdown"), diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index 49dcc66..ed7719b 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -60,14 +60,18 @@ class MarkdownTests: XCTestCase { let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) + } + func testRejectBadData() throws { + let data = LeafData.lazy { .null } + XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) } func testDoNotStripHtml() throws { let loop = EmbeddedEventLoop() let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) var tags = defaultTags - tags["markdown"] = Markdown(options: [.init(rawValue: 1 << 17)]) + tags["markdown"] = Markdown(options: [.unsafe]) let renderer = LeafRenderer( configuration: config, tags: tags, From f74578c100427bbeb5867b869d7c0a107a61d132 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 2 Nov 2020 14:52:04 +0000 Subject: [PATCH 13/23] Update Tag to Tau release --- Sources/LeafMarkdown/Tag.swift | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/Sources/LeafMarkdown/Tag.swift b/Sources/LeafMarkdown/Tag.swift index 593ae78..827a5c5 100644 --- a/Sources/LeafMarkdown/Tag.swift +++ b/Sources/LeafMarkdown/Tag.swift @@ -1,32 +1,35 @@ import LeafKit import SwiftMarkdown -public struct Markdown: LeafTag { - public enum Error: Swift.Error { - case invalidArgument(LeafData?) - } +public struct Markdown: LeafFunction, StringReturn, Invariant { private let options: MarkdownOptions? public init(options: MarkdownOptions? = nil) { self.options = options } - - public func render(_ ctx: LeafContext) throws -> LeafData { + + public static let callSignature: [LeafCallParameter] = [.string] + + public func evaluate(_ params: LeafCallValues) -> LeafData { var markdown = "" - - if let markdownArgument = ctx.parameters.first, !markdownArgument.isNull { - guard let markdownArgumentValue = markdownArgument.string else { - throw Error.invalidArgument(ctx.parameters.first) + + if params.count > 0 { + guard let markdownArgumentValue = params[0].string else { + return .error("Failed to get markdown from parameter") } markdown = markdownArgumentValue } let markdownHTML: String - if let options = options { - markdownHTML = try markdownToHTML(markdown, options: options) - } else { - markdownHTML = try markdownToHTML(markdown) + do { + if let options = options { + markdownHTML = try markdownToHTML(markdown, options: options) + } else { + markdownHTML = try markdownToHTML(markdown) + } + } catch { + return .error("Failed to convert markdown string to HTML - \(error)") } return .string(markdownHTML) From ddcb7bc2ad3adf53b658b7aeab8bddbd60b85a9b Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 2 Nov 2020 15:16:49 +0000 Subject: [PATCH 14/23] Get first test passing again --- Tests/LeafMarkdownTests/LeafTests.swift | 124 +++++++++--------- .../LeafMarkdownTests/StubbedLeafSource.swift | 16 +++ 2 files changed, 76 insertions(+), 64 deletions(-) create mode 100644 Tests/LeafMarkdownTests/StubbedLeafSource.swift diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index ed7719b..0625e49 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -6,33 +6,22 @@ class MarkdownTests: XCTestCase { // MARK: - Properties var renderer: LeafRenderer! - var template: ResolvedDocument! + var eventLoop: EventLoop! +// var template: ResolvedDocument! + let templateString = "#markdown(data)" + let template = "template" // MARK: - Overrides - override func setUp() { - let loop = EmbeddedEventLoop() - let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) - var tags = defaultTags - tags["markdown"] = Markdown() - self.renderer = LeafRenderer( - configuration: config, - tags: tags, - files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), - eventLoop: loop - ) - - do { - var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)") - let tokens = try lexer.lex() - var parser = LeafParser(name: "markdowntest", tokens: tokens) - let syntax = try parser.parse() - let unresolved = UnresolvedDocument(name: "markdowntest", raw: syntax) - let resolver = ExtendResolver(document: unresolved, dependencies: []) - template = try resolver.resolve(rootDirectory: config.rootDirectory) - } catch { - XCTFail() - } + eventLoop = EmbeddedEventLoop() + + let leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) + LeafConfiguration.entities.use(Markdown(), asFunction: "markdown") + self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) + } + + override func tearDownWithError() throws { + try eventLoop.syncShutdownGracefully() } // MARK: - Tests @@ -41,49 +30,56 @@ class MarkdownTests: XCTestCase { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) - } - - func testNilParameterDoesNotCrashLeaf() throws { - let expectedHtml = "" - let result = try renderer.render(template, context: ["data": .null]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) - } - - func testStripHtml() throws { - let inputMarkdown = "
" - let expectedHtml = "\n" - - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) + let resultString = try getRenderedString(input: inputMarkdown) XCTAssertEqual(resultString, expectedHtml) } - func testRejectBadData() throws { - let data = LeafData.lazy { .null } - XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) - } - - func testDoNotStripHtml() throws { - let loop = EmbeddedEventLoop() - let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) - var tags = defaultTags - tags["markdown"] = Markdown(options: [.unsafe]) - let renderer = LeafRenderer( - configuration: config, - tags: tags, - files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), - eventLoop: loop - ) - - let inputMarkdown = "
" - let expectedHtml = "
\n" +// func testNilParameterDoesNotCrashLeaf() throws { +// let expectedHtml = "" +// let result = try renderer.render(template, context: ["data": .null]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testStripHtml() throws { +// let inputMarkdown = "
" +// let expectedHtml = "\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testRejectBadData() throws { +// let data = LeafData.lazy { .null } +// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) +// } +// +// func testDoNotStripHtml() throws { +// let loop = EmbeddedEventLoop() +// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) +// var tags = defaultTags +// tags["markdown"] = Markdown(options: [.unsafe]) +// let renderer = LeafRenderer( +// configuration: config, +// tags: tags, +// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), +// eventLoop: loop +// ) +// +// let inputMarkdown = "
" +// let expectedHtml = "
\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) + private func getRenderedString(input: String) throws -> String { + let result = try renderer.render(template: template, context: ["data": .string(input)]).wait() + let resultString = String(decoding: result.readableBytesView, as: UTF8.self) + return resultString } } + +struct LeafMarkdownTestError: Error {} diff --git a/Tests/LeafMarkdownTests/StubbedLeafSource.swift b/Tests/LeafMarkdownTests/StubbedLeafSource.swift new file mode 100644 index 0000000..8e10094 --- /dev/null +++ b/Tests/LeafMarkdownTests/StubbedLeafSource.swift @@ -0,0 +1,16 @@ +import LeafKit + +struct StubbedLeafSource: LeafSource { + + let templateName: String + let templateContents: String + + func file(template: String, escape: Bool, on eventLoop: EventLoop) -> EventLoopFuture { + if template == templateName { + let byteBuffer = ByteBuffer(string: templateContents) + return eventLoop.makeSucceededFuture(byteBuffer) + } else { + return eventLoop.makeFailedFuture(LeafMarkdownTestError()) + } + } +} From db42ef3918c020a658bcf894b495fe0f7c646bbe Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 2 Nov 2020 15:29:17 +0000 Subject: [PATCH 15/23] Get the tests working --- Tests/LeafMarkdownTests/LeafTests.swift | 76 ++++++++++--------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index 0625e49..d52e5d9 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -7,15 +7,17 @@ class MarkdownTests: XCTestCase { var renderer: LeafRenderer! var eventLoop: EventLoop! -// var template: ResolvedDocument! + var leafSource: StubbedLeafSource! let templateString = "#markdown(data)" let template = "template" // MARK: - Overrides override func setUp() { eventLoop = EmbeddedEventLoop() + LeafConfiguration.started = false + LeafConfiguration.entities = .leaf4Core - let leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) + leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) LeafConfiguration.entities.use(Markdown(), asFunction: "markdown") self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) } @@ -30,53 +32,37 @@ class MarkdownTests: XCTestCase { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let resultString = try getRenderedString(input: inputMarkdown) + let resultString = try getRenderedString(input: .string(inputMarkdown)) XCTAssertEqual(resultString, expectedHtml) } -// func testNilParameterDoesNotCrashLeaf() throws { -// let expectedHtml = "" -// let result = try renderer.render(template, context: ["data": .null]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testStripHtml() throws { -// let inputMarkdown = "
" -// let expectedHtml = "\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testRejectBadData() throws { -// let data = LeafData.lazy { .null } -// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) -// } -// -// func testDoNotStripHtml() throws { -// let loop = EmbeddedEventLoop() -// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) -// var tags = defaultTags -// tags["markdown"] = Markdown(options: [.unsafe]) -// let renderer = LeafRenderer( -// configuration: config, -// tags: tags, -// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), -// eventLoop: loop -// ) -// -// let inputMarkdown = "
" -// let expectedHtml = "
\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } + func testStripHtml() throws { + let inputMarkdown = "
" + let expectedHtml = "\n" - private func getRenderedString(input: String) throws -> String { - let result = try renderer.render(template: template, context: ["data": .string(input)]).wait() + let resultString = try getRenderedString(input: .string(inputMarkdown)) + XCTAssertEqual(resultString, expectedHtml) + } + + func testRejectBadData() throws { + XCTAssertThrowsError(try getRenderedString(input: .init(nilLiteral: ()))) + } + + func testDoNotStripHtml() throws { + LeafConfiguration.started = false + LeafConfiguration.entities = .leaf4Core + LeafConfiguration.entities.use(Markdown(options: .unsafe), asFunction: "markdown") + self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) + + let inputMarkdown = "
" + let expectedHtml = "
\n" + + let resultString = try getRenderedString(input: .string(inputMarkdown)) + XCTAssertEqual(resultString, expectedHtml) + } + + private func getRenderedString(input: LeafData) throws -> String { + let result = try renderer.render(template: template, context: ["data": input]).wait() let resultString = String(decoding: result.readableBytesView, as: UTF8.self) return resultString } From 2e88ad66f918615e9d923af8c1ee7d18a31a225d Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 08:18:35 +0000 Subject: [PATCH 16/23] Update manifest for Leaf release --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 9227297..e0a8237 100644 --- a/Package.swift +++ b/Package.swift @@ -11,7 +11,7 @@ let package = Package( .library(name: "LeafMarkdown", targets: ["LeafMarkdown"]), ], dependencies: [ - .package(url: "https://github.com/vapor-community/markdown.git", from: "0.6.1"), + .package(name: "SwiftMarkdown", url: "https://github.com/vapor-community/markdown.git", from: "0.6.1"), .package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0"), ], targets: [ From b3bf6b844953bc521992304e912de8321c97ca01 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 08:18:58 +0000 Subject: [PATCH 17/23] Fix CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86bcb16..abc30db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Run Bionic Tests run: swift test --enable-test-discovery --enable-code-coverage - name: Setup container for codecov upload - run: apt-get update && apt-get install curl + run: apt-get update && apt-get install -y curl - name: Process coverage file run: llvm-cov show .build/x86_64-unknown-linux-gnu/debug/LeafMarkdownPackageTests.xctest -instr-profile=.build/debug/codecov/default.profdata > coverage.txt - name: Upload code coverage From a55f93747cc7dd1fab666a04ed571bcd2c856401 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 08:21:21 +0000 Subject: [PATCH 18/23] Revert "Get the tests working" This reverts commit dd33180fc4dedaad29dd10f39274466a32f674f3. --- Tests/LeafMarkdownTests/LeafTests.swift | 76 +++++++++++++++---------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index d52e5d9..0625e49 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -7,17 +7,15 @@ class MarkdownTests: XCTestCase { var renderer: LeafRenderer! var eventLoop: EventLoop! - var leafSource: StubbedLeafSource! +// var template: ResolvedDocument! let templateString = "#markdown(data)" let template = "template" // MARK: - Overrides override func setUp() { eventLoop = EmbeddedEventLoop() - LeafConfiguration.started = false - LeafConfiguration.entities = .leaf4Core - leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) + let leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) LeafConfiguration.entities.use(Markdown(), asFunction: "markdown") self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) } @@ -32,37 +30,53 @@ class MarkdownTests: XCTestCase { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let resultString = try getRenderedString(input: .string(inputMarkdown)) + let resultString = try getRenderedString(input: inputMarkdown) XCTAssertEqual(resultString, expectedHtml) } - func testStripHtml() throws { - let inputMarkdown = "
" - let expectedHtml = "\n" +// func testNilParameterDoesNotCrashLeaf() throws { +// let expectedHtml = "" +// let result = try renderer.render(template, context: ["data": .null]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testStripHtml() throws { +// let inputMarkdown = "
" +// let expectedHtml = "\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testRejectBadData() throws { +// let data = LeafData.lazy { .null } +// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) +// } +// +// func testDoNotStripHtml() throws { +// let loop = EmbeddedEventLoop() +// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) +// var tags = defaultTags +// tags["markdown"] = Markdown(options: [.unsafe]) +// let renderer = LeafRenderer( +// configuration: config, +// tags: tags, +// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), +// eventLoop: loop +// ) +// +// let inputMarkdown = "
" +// let expectedHtml = "
\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } - let resultString = try getRenderedString(input: .string(inputMarkdown)) - XCTAssertEqual(resultString, expectedHtml) - } - - func testRejectBadData() throws { - XCTAssertThrowsError(try getRenderedString(input: .init(nilLiteral: ()))) - } - - func testDoNotStripHtml() throws { - LeafConfiguration.started = false - LeafConfiguration.entities = .leaf4Core - LeafConfiguration.entities.use(Markdown(options: .unsafe), asFunction: "markdown") - self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) - - let inputMarkdown = "
" - let expectedHtml = "
\n" - - let resultString = try getRenderedString(input: .string(inputMarkdown)) - XCTAssertEqual(resultString, expectedHtml) - } - - private func getRenderedString(input: LeafData) throws -> String { - let result = try renderer.render(template: template, context: ["data": input]).wait() + private func getRenderedString(input: String) throws -> String { + let result = try renderer.render(template: template, context: ["data": .string(input)]).wait() let resultString = String(decoding: result.readableBytesView, as: UTF8.self) return resultString } From 748addb6fececa3631909ef6480742762d0926d1 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 08:21:26 +0000 Subject: [PATCH 19/23] Revert "Get first test passing again" This reverts commit 7f064ea6547a21f3814217a2c49a832265784fa5. --- Tests/LeafMarkdownTests/LeafTests.swift | 124 +++++++++--------- .../LeafMarkdownTests/StubbedLeafSource.swift | 16 --- 2 files changed, 64 insertions(+), 76 deletions(-) delete mode 100644 Tests/LeafMarkdownTests/StubbedLeafSource.swift diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index 0625e49..ed7719b 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -6,22 +6,33 @@ class MarkdownTests: XCTestCase { // MARK: - Properties var renderer: LeafRenderer! - var eventLoop: EventLoop! -// var template: ResolvedDocument! - let templateString = "#markdown(data)" - let template = "template" + var template: ResolvedDocument! // MARK: - Overrides + override func setUp() { - eventLoop = EmbeddedEventLoop() - - let leafSource = StubbedLeafSource(templateName: template, templateContents: templateString) - LeafConfiguration.entities.use(Markdown(), asFunction: "markdown") - self.renderer = LeafRenderer(cache: DefaultLeafCache(), sources: .singleSource(leafSource), eventLoop: eventLoop) - } - - override func tearDownWithError() throws { - try eventLoop.syncShutdownGracefully() + let loop = EmbeddedEventLoop() + let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) + var tags = defaultTags + tags["markdown"] = Markdown() + self.renderer = LeafRenderer( + configuration: config, + tags: tags, + files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), + eventLoop: loop + ) + + do { + var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)") + let tokens = try lexer.lex() + var parser = LeafParser(name: "markdowntest", tokens: tokens) + let syntax = try parser.parse() + let unresolved = UnresolvedDocument(name: "markdowntest", raw: syntax) + let resolver = ExtendResolver(document: unresolved, dependencies: []) + template = try resolver.resolve(rootDirectory: config.rootDirectory) + } catch { + XCTFail() + } } // MARK: - Tests @@ -30,56 +41,49 @@ class MarkdownTests: XCTestCase { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let resultString = try getRenderedString(input: inputMarkdown) + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) + XCTAssertEqual(resultString, expectedHtml) + } + + func testNilParameterDoesNotCrashLeaf() throws { + let expectedHtml = "" + let result = try renderer.render(template, context: ["data": .null]) + let resultString = result.getString(at: 0, length: result.readableBytes) + XCTAssertEqual(resultString, expectedHtml) + } + + func testStripHtml() throws { + let inputMarkdown = "
" + let expectedHtml = "\n" + + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) XCTAssertEqual(resultString, expectedHtml) } -// func testNilParameterDoesNotCrashLeaf() throws { -// let expectedHtml = "" -// let result = try renderer.render(template, context: ["data": .null]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testStripHtml() throws { -// let inputMarkdown = "
" -// let expectedHtml = "\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testRejectBadData() throws { -// let data = LeafData.lazy { .null } -// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) -// } -// -// func testDoNotStripHtml() throws { -// let loop = EmbeddedEventLoop() -// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) -// var tags = defaultTags -// tags["markdown"] = Markdown(options: [.unsafe]) -// let renderer = LeafRenderer( -// configuration: config, -// tags: tags, -// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), -// eventLoop: loop -// ) -// -// let inputMarkdown = "
" -// let expectedHtml = "
\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } + func testRejectBadData() throws { + let data = LeafData.lazy { .null } + XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) + } + + func testDoNotStripHtml() throws { + let loop = EmbeddedEventLoop() + let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) + var tags = defaultTags + tags["markdown"] = Markdown(options: [.unsafe]) + let renderer = LeafRenderer( + configuration: config, + tags: tags, + files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), + eventLoop: loop + ) + + let inputMarkdown = "
" + let expectedHtml = "
\n" - private func getRenderedString(input: String) throws -> String { - let result = try renderer.render(template: template, context: ["data": .string(input)]).wait() - let resultString = String(decoding: result.readableBytesView, as: UTF8.self) - return resultString + let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) + let resultString = result.getString(at: 0, length: result.readableBytes) + XCTAssertEqual(resultString, expectedHtml) } } - -struct LeafMarkdownTestError: Error {} diff --git a/Tests/LeafMarkdownTests/StubbedLeafSource.swift b/Tests/LeafMarkdownTests/StubbedLeafSource.swift deleted file mode 100644 index 8e10094..0000000 --- a/Tests/LeafMarkdownTests/StubbedLeafSource.swift +++ /dev/null @@ -1,16 +0,0 @@ -import LeafKit - -struct StubbedLeafSource: LeafSource { - - let templateName: String - let templateContents: String - - func file(template: String, escape: Bool, on eventLoop: EventLoop) -> EventLoopFuture { - if template == templateName { - let byteBuffer = ByteBuffer(string: templateContents) - return eventLoop.makeSucceededFuture(byteBuffer) - } else { - return eventLoop.makeFailedFuture(LeafMarkdownTestError()) - } - } -} From fb5e063d59a1ac4bd7d69e4f6c3a46a49764a6a3 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 08:21:31 +0000 Subject: [PATCH 20/23] Revert "Update Tag to Tau release" This reverts commit 1caeb64383a680f8d74753bf295e32d14c7012f5. --- Sources/LeafMarkdown/Tag.swift | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/Sources/LeafMarkdown/Tag.swift b/Sources/LeafMarkdown/Tag.swift index 827a5c5..593ae78 100644 --- a/Sources/LeafMarkdown/Tag.swift +++ b/Sources/LeafMarkdown/Tag.swift @@ -1,35 +1,32 @@ import LeafKit import SwiftMarkdown -public struct Markdown: LeafFunction, StringReturn, Invariant { +public struct Markdown: LeafTag { + public enum Error: Swift.Error { + case invalidArgument(LeafData?) + } private let options: MarkdownOptions? public init(options: MarkdownOptions? = nil) { self.options = options } - - public static let callSignature: [LeafCallParameter] = [.string] - - public func evaluate(_ params: LeafCallValues) -> LeafData { + + public func render(_ ctx: LeafContext) throws -> LeafData { var markdown = "" - - if params.count > 0 { - guard let markdownArgumentValue = params[0].string else { - return .error("Failed to get markdown from parameter") + + if let markdownArgument = ctx.parameters.first, !markdownArgument.isNull { + guard let markdownArgumentValue = markdownArgument.string else { + throw Error.invalidArgument(ctx.parameters.first) } markdown = markdownArgumentValue } let markdownHTML: String - do { - if let options = options { - markdownHTML = try markdownToHTML(markdown, options: options) - } else { - markdownHTML = try markdownToHTML(markdown) - } - } catch { - return .error("Failed to convert markdown string to HTML - \(error)") + if let options = options { + markdownHTML = try markdownToHTML(markdown, options: options) + } else { + markdownHTML = try markdownToHTML(markdown) } return .string(markdownHTML) From b8c7a4f187c0cab5d5b8c778950b9dd5d8397efe Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 09:59:38 +0000 Subject: [PATCH 21/23] Get first test working with release of LeafKit --- Sources/LeafMarkdown/Tag.swift | 2 +- Tests/LeafMarkdownTests/LeafTests.swift | 127 ++++++++++++------------ 2 files changed, 63 insertions(+), 66 deletions(-) diff --git a/Sources/LeafMarkdown/Tag.swift b/Sources/LeafMarkdown/Tag.swift index 593ae78..45ff2de 100644 --- a/Sources/LeafMarkdown/Tag.swift +++ b/Sources/LeafMarkdown/Tag.swift @@ -15,7 +15,7 @@ public struct Markdown: LeafTag { public func render(_ ctx: LeafContext) throws -> LeafData { var markdown = "" - if let markdownArgument = ctx.parameters.first, !markdownArgument.isNull { + if let markdownArgument = ctx.parameters.first, !markdownArgument.isNil { guard let markdownArgumentValue = markdownArgument.string else { throw Error.invalidArgument(ctx.parameters.first) } diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index ed7719b..a61e4df 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -1,38 +1,34 @@ import XCTest @testable import LeafKit import LeafMarkdown +import NIO class MarkdownTests: XCTestCase { // MARK: - Properties var renderer: LeafRenderer! - var template: ResolvedDocument! + var ast: [Syntax]! + var markdownTag: Markdown! // MARK: - Overrides - override func setUp() { - let loop = EmbeddedEventLoop() - let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) - var tags = defaultTags - tags["markdown"] = Markdown() - self.renderer = LeafRenderer( - configuration: config, - tags: tags, - files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), - eventLoop: loop + override func setUpWithError() throws { + var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)") + let tokens = try lexer.lex() + var parser = LeafParser(name: "markdowntest", tokens: tokens) + ast = try parser.parse() + markdownTag = Markdown() + } + + // MARK: - Helper + func render(context: [String: LeafData]) throws -> String { + var serializer = LeafSerializer( + ast: ast, + context: context, + tags: ["markdown": markdownTag] ) - - do { - var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)") - let tokens = try lexer.lex() - var parser = LeafParser(name: "markdowntest", tokens: tokens) - let syntax = try parser.parse() - let unresolved = UnresolvedDocument(name: "markdowntest", raw: syntax) - let resolver = ExtendResolver(document: unresolved, dependencies: []) - template = try resolver.resolve(rootDirectory: config.rootDirectory) - } catch { - XCTFail() - } + let view = try serializer.serialize() + return view.getString(at: view.readerIndex, length: view.readableBytes) ?? "" } // MARK: - Tests @@ -41,49 +37,50 @@ class MarkdownTests: XCTestCase { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) - } - - func testNilParameterDoesNotCrashLeaf() throws { - let expectedHtml = "" - let result = try renderer.render(template, context: ["data": .null]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) - } - - func testStripHtml() throws { - let inputMarkdown = "
" - let expectedHtml = "\n" - - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) +// let result = try renderer.render(path: template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) + let resultString = try render(context: ["data": .string(inputMarkdown)]) XCTAssertEqual(resultString, expectedHtml) } - func testRejectBadData() throws { - let data = LeafData.lazy { .null } - XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) - } - - func testDoNotStripHtml() throws { - let loop = EmbeddedEventLoop() - let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) - var tags = defaultTags - tags["markdown"] = Markdown(options: [.unsafe]) - let renderer = LeafRenderer( - configuration: config, - tags: tags, - files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), - eventLoop: loop - ) - - let inputMarkdown = "
" - let expectedHtml = "
\n" - - let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) - let resultString = result.getString(at: 0, length: result.readableBytes) - XCTAssertEqual(resultString, expectedHtml) - } +// func testNilParameterDoesNotCrashLeaf() throws { +// let expectedHtml = "" +// let result = try renderer.render(path: template, context: ["data": .nil]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testStripHtml() throws { +// let inputMarkdown = "
" +// let expectedHtml = "\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } +// +// func testRejectBadData() throws { +// let data = LeafData.lazy { .null } +// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) +// } +// +// func testDoNotStripHtml() throws { +// let loop = EmbeddedEventLoop() +// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) +// var tags = defaultTags +// tags["markdown"] = Markdown(options: [.unsafe]) +// let renderer = LeafRenderer( +// configuration: config, +// tags: tags, +// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), +// eventLoop: loop +// ) +// +// let inputMarkdown = "
" +// let expectedHtml = "
\n" +// +// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) +// let resultString = result.getString(at: 0, length: result.readableBytes) +// XCTAssertEqual(resultString, expectedHtml) +// } } From 435f06663522d93b46ce32606a2fafc73cee5338 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 10:05:19 +0000 Subject: [PATCH 22/23] Bring back all the tests --- Tests/LeafMarkdownTests/LeafTests.swift | 68 ++++++++++--------------- 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/Tests/LeafMarkdownTests/LeafTests.swift b/Tests/LeafMarkdownTests/LeafTests.swift index a61e4df..302563d 100644 --- a/Tests/LeafMarkdownTests/LeafTests.swift +++ b/Tests/LeafMarkdownTests/LeafTests.swift @@ -36,51 +36,35 @@ class MarkdownTests: XCTestCase { func testRunTag() throws { let inputMarkdown = "# This is a test\n\nWe have some text in a tag" let expectedHtml = "

This is a test

\n

We have some text in a tag

\n" + let resultString = try render(context: ["data": .string(inputMarkdown)]) + XCTAssertEqual(resultString, expectedHtml) + } + + func testNilParameterDoesNotCrashLeaf() throws { + let expectedHtml = "" + let resultString = try render(context: ["data": .trueNil]) + XCTAssertEqual(resultString, expectedHtml) + } + + func testStripHtml() throws { + let inputMarkdown = "
" + let expectedHtml = "\n" -// let result = try renderer.render(path: template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) let resultString = try render(context: ["data": .string(inputMarkdown)]) XCTAssertEqual(resultString, expectedHtml) } -// func testNilParameterDoesNotCrashLeaf() throws { -// let expectedHtml = "" -// let result = try renderer.render(path: template, context: ["data": .nil]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testStripHtml() throws { -// let inputMarkdown = "
" -// let expectedHtml = "\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } -// -// func testRejectBadData() throws { -// let data = LeafData.lazy { .null } -// XCTAssertThrowsError(try renderer.render(template, context: ["data": data])) -// } -// -// func testDoNotStripHtml() throws { -// let loop = EmbeddedEventLoop() -// let config = LeafConfiguration(rootDirectory: Process().currentDirectoryPath) -// var tags = defaultTags -// tags["markdown"] = Markdown(options: [.unsafe]) -// let renderer = LeafRenderer( -// configuration: config, -// tags: tags, -// files: NIOLeafFiles(fileio: .init(threadPool: .init(numberOfThreads: 1))), -// eventLoop: loop -// ) -// -// let inputMarkdown = "
" -// let expectedHtml = "
\n" -// -// let result = try renderer.render(template, context: ["data": .string(inputMarkdown)]) -// let resultString = result.getString(at: 0, length: result.readableBytes) -// XCTAssertEqual(resultString, expectedHtml) -// } + func testRejectBadData() throws { + XCTAssertThrowsError(try render(context: ["data": .dictionary(["something": .string("somethingelese")])])) + } + + func testDoNotStripHtml() throws { + markdownTag = Markdown(options: [.unsafe]) + + let inputMarkdown = "
" + let expectedHtml = "
\n" + + let resultString = try render(context: ["data": .string(inputMarkdown)]) + XCTAssertEqual(resultString, expectedHtml) + } } From c94b50726cf705c03e5fbb3aeed5241249a169d6 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 17 Nov 2020 10:10:40 +0000 Subject: [PATCH 23/23] Update the README --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f416aa9..f74b79f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Leaf Markdown -[![Language](https://img.shields.io/badge/Swift-5.1-brightgreen.svg)](http://swift.org) -[![Build Status](https://github.com/vapor-community/leaf-markdown/workflows/CI/badge.svg?branch=master)](https://github.com/vapor-community/leaf-markdown/actions) -[![codecov](https://codecov.io/gh/vapor-community/leaf-markdown/branch/master/graph/badge.svg)](https://codecov.io/gh/vapor-community/leaf-markdown) -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/vapor-community/leaf-markdown/master/LICENSE) +[![Language](https://img.shields.io/badge/Swift-5.2-brightgreen.svg)](http://swift.org) +[![Build Status](https://github.com/vapor-community/leaf-markdown/workflows/CI/badge.svg?branch=main)](https://github.com/vapor-community/leaf-markdown/actions) +[![codecov](https://codecov.io/gh/vapor-community/leaf-markdown/branch/main/graph/badge.svg)](https://codecov.io/gh/vapor-community/leaf-markdown) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/vapor-community/leaf-markdown/main/LICENSE) -A Markdown renderer for Vapor and Leaf. This uses the [Vapor Markdown](https://github.com/vapor/markdown) package to wrap [cmark](https://github.com/jgm/cmark) (though a [fork](https://github.com/brokenhandsio/cmark-gfm) is used to make it work with Swift PM), so it understands [Common Mark](http://commonmark.org). A quick reference guide for Common Mark can be found [here](http://commonmark.org/help/). It also supports [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/). +A Markdown renderer for Vapor and Leaf. This uses the [Vapor Markdown](https://github.com/vapor/markdown) package to wrap [cmark](https://github.com/github/cmark-gfm) (though a [fork](https://github.com/brokenhandsio/cmark-gfm) is used to make it work with Swift PM), so it understands [Common Mark](http://commonmark.org). A quick reference guide for Common Mark can be found [here](http://commonmark.org/help/). It also supports [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/). ## Usage @@ -32,21 +32,29 @@ Add Leaf Markdown as a dependency in your `Package.swift` file: ```swift dependencies: [ ..., - .package(url: "https://github.com/vapor-community/leaf-markdown.git", .upToNextMajor(from: "2.0.0")) + .package(name: "LeafMarkdown", url: "https://github.com/vapor-community/leaf-markdown.git", .upToNextMajor(from: "3.0.0")), ] ``` +Then add the dependency to your target: + +```swift +.target( + name: "App", + dependencies: [ + // ... + "LeafMarkdown" + ], + // ... +) +``` + ### Register with Leaf -To add the tag to Leaf, add it to your `LeafTagConfig`: +Register the tag with Leaf so Leaf knows about it: ```swift -try services.register(LeafProvider()) -var tags = LeafTagConfig.default() -tags.use(Markdown(), as: "markdown") -services.register(tags) +app.leaf.tags["markdown"] = Markdown() ``` -**Note:** it's important that you register the `LeafProvider` first otherwise this will override your `LeafTagConfig`. - Don't forget to import LeafMarkdown in the file you register the tag with `import LeafMarkdown`.