81 lines
2.2 KiB
Swift
81 lines
2.2 KiB
Swift
//
|
|
// SwiftGenKit UnitTests
|
|
// Copyright © 2022 SwiftGen
|
|
// MIT Licence
|
|
//
|
|
|
|
import Difference
|
|
import Foundation
|
|
import PathKit
|
|
import Stencil
|
|
import SwiftGenKit
|
|
import XCTest
|
|
|
|
public func XCTAssertEqualDict(
|
|
_ received: [String: Any],
|
|
_ expected: [String: Any],
|
|
file: StaticString = #file,
|
|
line: UInt = #line
|
|
) {
|
|
for difference in diff(expected, received) where !difference.isEmpty {
|
|
XCTFail(difference, file: file, line: line)
|
|
}
|
|
}
|
|
|
|
// MARK: - Compare contexts
|
|
|
|
public func XCTDiffContexts(
|
|
_ received: [String: Any],
|
|
expected name: String,
|
|
sub directory: Fixtures.Directory,
|
|
file: StaticString = #file,
|
|
line: UInt = #line
|
|
) {
|
|
let fileName = "\(name).yaml"
|
|
|
|
if ProcessInfo().environment["GENERATE_CONTEXTS"] == "YES" {
|
|
store(context: received, directory: directory, fileName: fileName)
|
|
} else {
|
|
do {
|
|
let normalized = try yamlNormalize(received)
|
|
let expected = Fixtures.context(for: fileName, sub: directory)
|
|
|
|
for difference in diff(normalized, expected) where !difference.isEmpty {
|
|
XCTFail(difference, file: file, line: line)
|
|
}
|
|
} catch let error {
|
|
fatalError("Unable to compare contexts: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Recursive dig into the object to convert any "lazy" values into a context-compatible structure (Dict, Array, …)
|
|
private func normalize(_ object: Any) throws -> Any {
|
|
switch object {
|
|
case let array as [Any]:
|
|
return try array.compactMap(normalize)
|
|
case let dict as [String: Any]:
|
|
return try dict.compactMapValues(normalize)
|
|
case let value as LazyValueWrapper:
|
|
return try normalize(try value.resolve(.init()) ?? value)
|
|
default:
|
|
return object
|
|
}
|
|
}
|
|
|
|
/// Do a roundtrip to YAML, to avoid boolean/int differences
|
|
private func yamlNormalize(_ object: Any) throws -> Any {
|
|
try YAML.decode(string: YAML.encode(object: normalize(object))) ?? object
|
|
}
|
|
|
|
/// Write the given data to a context file
|
|
private func store(context: Any, directory: Fixtures.Directory, fileName: String) {
|
|
let path = Path(#filePath).parent() + "Fixtures/StencilContexts" + directory.rawValue + fileName
|
|
|
|
do {
|
|
try YAML.write(object: normalize(context), to: path)
|
|
} catch let error {
|
|
fatalError("Unable to write context file \(path): \(error)")
|
|
}
|
|
}
|