Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 34 additions & 103 deletions Tests/XcodeTemplateGeneratorLibraryTests/StencilRendererTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,102 +7,45 @@

import Nimble
import SnapshotTesting
import XcodeTemplateGeneratorLibrary
@testable import XcodeTemplateGeneratorLibrary
import XCTest

final class StencilRendererTests: XCTestCase, TestFactories {

func testRenderNode() throws {
let context: NodeContext = givenNodeContext()
let templates: [String: String] = try StencilRenderer().renderNode(context: context, kind: .uiKit)
expect(templates.keys.sorted()) == [
"Analytics",
"Builder",
"Context",
"Flow",
"ViewController",
"Worker"
]
assertSnapshot(matching: templates["Analytics"]!,
as: .lines,
named: "Analytics")
assertSnapshot(matching: templates["Builder"]!,
as: .lines,
named: "Builder")
assertSnapshot(matching: templates["Context"]!,
as: .lines,
named: "Context")
assertSnapshot(matching: templates["Flow"]!,
as: .lines,
named: "Flow")
assertSnapshot(matching: templates["ViewController"]!,
as: .lines,
named: "ViewController")
assertSnapshot(matching: templates["Worker"]!,
as: .lines,
named: "Worker")
}

func testRenderNodeSwiftUI() throws {
let context: NodeContext = givenNodeContext()
let templates: [String: String] = try StencilRenderer().renderNode(context: context, kind: .swiftUI)
expect(templates.keys.sorted()) == [
"Analytics",
"Builder",
"Context",
"Flow",
"ViewController",
"Worker"
]
assertSnapshot(matching: templates["Analytics"]!,
as: .lines,
named: "Analytics")
assertSnapshot(matching: templates["Builder"]!,
as: .lines,
named: "Builder")
assertSnapshot(matching: templates["Context"]!,
as: .lines,
named: "Context")
assertSnapshot(matching: templates["Flow"]!,
as: .lines,
named: "Flow")
assertSnapshot(matching: templates["ViewController"]!,
as: .lines,
named: "ViewController")
assertSnapshot(matching: templates["Worker"]!,
as: .lines,
named: "Worker")
try UIFramework.Kind.allCases.forEach { kind in
let context: NodeContext = givenNodeContext()
let templates: [String: String] = try StencilRenderer().renderNode(context: context, kind: kind)
expect(templates.keys.sorted()) == [
"Analytics",
"Builder",
"Context",
"Flow",
"ViewController",
"Worker"
]
templates.forEach { name, template in
assertSnapshot(matching: template, as: .lines, named: "\(name)-\(kind.rawValue)")
}
}
}

func testRenderNodeRoot() throws {
let context: NodeRootContext = givenNodeRootContext()
let templates: [String: String] = try StencilRenderer().renderNodeRoot(context: context, kind: .uiKit)
expect(templates.keys.sorted()) == [
"Analytics",
"Builder",
"Context",
"Flow",
"ViewController",
"Worker"
]
assertSnapshot(matching: templates["Analytics"]!,
as: .lines,
named: "Analytics")
assertSnapshot(matching: templates["Builder"]!,
as: .lines,
named: "Builder")
assertSnapshot(matching: templates["Context"]!,
as: .lines,
named: "Context")
assertSnapshot(matching: templates["Flow"]!,
as: .lines,
named: "Flow")
assertSnapshot(matching: templates["ViewController"]!,
as: .lines,
named: "ViewController")
assertSnapshot(matching: templates["Worker"]!,
as: .lines,
named: "Worker")
try UIFramework.Kind.allCases.forEach { kind in
let context: NodeRootContext = givenNodeRootContext()
let templates: [String: String] = try StencilRenderer().renderNodeRoot(context: context, kind: kind)
expect(templates.keys.sorted()) == [
"Analytics",
"Builder",
"Context",
"Flow",
"ViewController",
"Worker"
]
templates.forEach { name, template in
assertSnapshot(matching: template, as: .lines, named: "\(name)-\(kind.rawValue)")
}
}
}

func testRenderNodeViewInjected() throws {
Expand All @@ -115,21 +58,9 @@ final class StencilRendererTests: XCTestCase, TestFactories {
"Flow",
"Worker"
]
assertSnapshot(matching: templates["Analytics"]!,
as: .lines,
named: "Analytics")
assertSnapshot(matching: templates["Builder"]!,
as: .lines,
named: "Builder")
assertSnapshot(matching: templates["Context"]!,
as: .lines,
named: "Context")
assertSnapshot(matching: templates["Flow"]!,
as: .lines,
named: "Flow")
assertSnapshot(matching: templates["Worker"]!,
as: .lines,
named: "Worker")
templates.forEach { name, template in
assertSnapshot(matching: template, as: .lines, named: name)
}
}

func testRenderPlugin() throws {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<fileHeader>

import <workerImports>

/*
INSTRUCTIONS:

Option 1
========
Conform an existing analytics tracker (or client), that is defined outside of the Node, to the
<nodeName>Analytics protocol.

This option is preferred.

When using this option, delete the class defined in this file (below).

Option 2
========
Inject an existing analytics tracker (or client), that is defined outside of the Node, into the
class defined in this file (below).

Only use this option if option 1 is not possible, for example, when the class defined in this
file (below) is needed to store state (not recommended).

When using this option, inject the tracker (or client) via a protocol. The protocol for the
injected tracker (or client) can either be an existing one defined outside of the Node or
can be a new one added to this file.
*/

/**
PURPOSE:
The interface for analytics tracked by this Node.

Whether using option 1 or 2, add requirements to this protocol to provide analytics tracking
methods for this Node.
*/
internal protocol <nodeName>Analytics: AnyObject {}

/**
PURPOSE:
The implementations of the protocol methods for analytics tracked by this Node.

If using option 1, add implementations for the methods defined in the protocol that are not
implemented by the conforming tracker (or client).

If using option 2, delete this extension.
*/
internal extension <nodeName>Analytics {}

/**
PURPOSE:
Custom analytics implementation for this Node, to be used ONLY when storing state is unavoidable.

If using option 1, delete this class and extension below.
*/
internal final class <nodeName>AnalyticsImp {}

extension <nodeName>AnalyticsImp: <nodeName>Analytics {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<fileHeader>

import <workerImports>

/*
INSTRUCTIONS:

Option 1
========
Conform an existing analytics tracker (or client), that is defined outside of the Node, to the
<nodeName>Analytics protocol.

This option is preferred.

When using this option, delete the class defined in this file (below).

Option 2
========
Inject an existing analytics tracker (or client), that is defined outside of the Node, into the
class defined in this file (below).

Only use this option if option 1 is not possible, for example, when the class defined in this
file (below) is needed to store state (not recommended).

When using this option, inject the tracker (or client) via a protocol. The protocol for the
injected tracker (or client) can either be an existing one defined outside of the Node or
can be a new one added to this file.
*/

/**
PURPOSE:
The interface for analytics tracked by this Node.

Whether using option 1 or 2, add requirements to this protocol to provide analytics tracking
methods for this Node.
*/
internal protocol <nodeName>Analytics: AnyObject {}

/**
PURPOSE:
The implementations of the protocol methods for analytics tracked by this Node.

If using option 1, add implementations for the methods defined in the protocol that are not
implemented by the conforming tracker (or client).

If using option 2, delete this extension.
*/
internal extension <nodeName>Analytics {}

/**
PURPOSE:
Custom analytics implementation for this Node, to be used ONLY when storing state is unavoidable.

If using option 1, delete this class and extension below.
*/
internal final class <nodeName>AnalyticsImp {}

extension <nodeName>AnalyticsImp: <nodeName>Analytics {}
Loading