diff --git a/Sources/HTMLKit/Framework/Environment/Statements/BranchStatements.swift b/Sources/HTMLKit/Framework/Environment/Statements/BranchStatements.swift index 2ff9dbcc..34e7b7d9 100644 --- a/Sources/HTMLKit/Framework/Environment/Statements/BranchStatements.swift +++ b/Sources/HTMLKit/Framework/Environment/Statements/BranchStatements.swift @@ -9,24 +9,16 @@ /// The statement is for public struct IF: GlobalElement { - public enum IFPrerenderErrors: Error { - - case dynamiclyEvaluatedCondition - } - internal class Condition { internal let condition: Conditionable - internal var formula: Formula - - internal var view: AnyContent + internal var content: AnyContent internal init(condition: Conditionable) { self.condition = condition - self.view = "" - self.formula = Formula() + self.content = "" } } @@ -39,7 +31,7 @@ public struct IF: GlobalElement { public init(_ condition: Conditionable, @ContentBuilder content: () -> AnyContent) { let condition = Condition(condition: condition) - condition.view = content() + condition.content = content() self.conditions = [condition] } @@ -47,7 +39,7 @@ public struct IF: GlobalElement { public func elseIf(_ condition: Conditionable, @ContentBuilder content: () -> AnyContent) -> IF { let condition = Condition(condition: condition) - condition.view = content() + condition.content = content() return .init(conditions: conditions + [condition]) } @@ -55,7 +47,7 @@ public struct IF: GlobalElement { public func elseIf(isNil path: TemplateValue, @ContentBuilder content: () -> AnyContent) -> IF { let condition = Condition(condition: IsNullCondition(lhs: path)) - condition.view = content() + condition.content = content() return .init(conditions: conditions + [condition]) } @@ -63,7 +55,7 @@ public struct IF: GlobalElement { public func elseIf(isNotNil path: TemplateValue, @ContentBuilder content: () -> AnyContent) -> IF { let condition = Condition(condition: NotNullCondition(lhs: path)) - condition.view = content() + condition.content = content() return .init(conditions: conditions + [condition]) } @@ -71,7 +63,7 @@ public struct IF: GlobalElement { public func `else`(@ContentBuilder content: () -> AnyContent) -> IF { let condition = Condition(condition: AlwaysTrueCondition()) - condition.view = content() + condition.content = content() return .init(conditions: conditions + [condition]) } @@ -84,7 +76,7 @@ extension IF: AnyContent { IF(conditions: conditions.map { htmlCondition in let scriptCondition = IF.Condition(condition: htmlCondition.condition) - scriptCondition.view = htmlCondition.view.scripts + scriptCondition.content = htmlCondition.content.scripts return scriptCondition }) @@ -95,31 +87,22 @@ extension IF: AnyContent { var isStaticallyEvaluated = true for condition in conditions { - - condition.formula.calendar = formula.calendar - - condition.formula.timeZone = formula.timeZone do { guard isStaticallyEvaluated else { - throw IFPrerenderErrors.dynamiclyEvaluatedCondition + break } - let testContext = ContextManager(contexts: [:]) - - if try condition.condition.evaluate(with: testContext) { + if try condition.condition.evaluate(with: ContextManager(contexts: [:])) { - try condition.view.prerender(formula) + try condition.content.prerender(formula) - return // Returning as the first true condition should be the only one that is rendered + break } } catch { - isStaticallyEvaluated = false - - try condition.prerender(formula) } } @@ -144,11 +127,11 @@ extension IF: AnyContent { extension IF.Condition: AnyContent { public func prerender(_ formula: Formula) throws { - try view.prerender(formula) + try content.prerender(formula) } public func render(with manager: ContextManager) throws -> String { - return try formula.render(with: manager) + return try content.render(with: manager) } } diff --git a/Tests/HTMLKitTests/StatementsTests.swift b/Tests/HTMLKitTests/StatementsTests.swift index 129ae914..5f8b2e87 100644 --- a/Tests/HTMLKitTests/StatementsTests.swift +++ b/Tests/HTMLKitTests/StatementsTests.swift @@ -15,7 +15,7 @@ final class StatementsTests: XCTestCase { var renderer = Renderer() - func testIfStatement() throws { + func testIfStatementWithConstantValue() throws { let isValid: TemplateValue = .constant(true) @@ -40,7 +40,37 @@ final class StatementsTests: XCTestCase { ) } - func testElseStatement() throws { + func testIfStatementWithVariableValue() throws { + + struct TestContext { + var isValid: Bool + } + + @TemplateValue(TestContext.self) + var item + + let page = TestPage { + IF(item.isValid) { + Paragraph { + "true" + } + }.else { + Paragraph { + "false" + } + } + } + + try renderer.add(layout: page) + + XCTAssertEqual(try renderer.render(layout: TestPage.self, with: TestContext(isValid: true)), + """ +

true

+ """ + ) + } + + func testElseStatementWithConstantValue() throws { let isValid: TemplateValue = .constant(false) @@ -65,6 +95,36 @@ final class StatementsTests: XCTestCase { ) } + func testElseStatementWithVariableValue() throws { + + struct TestContext { + var isValid: Bool + } + + @TemplateValue(TestContext.self) + var item + + let page = TestPage { + IF(item.isValid) { + Paragraph { + "true" + } + }.else { + Paragraph { + "false" + } + } + } + + try renderer.add(layout: page) + + XCTAssertEqual(try renderer.render(layout: TestPage.self, with: TestContext(isValid: false)), + """ +

false

+ """ + ) + } + func testElseIfStatement() throws { let age: TemplateValue = .constant(16)