Skip to content

Instantly share code, notes, and snippets.

@junebash
Created July 29, 2020 23:45
Show Gist options
  • Save junebash/6da6efdd3a1bd9e62a994ef72bdcea67 to your computer and use it in GitHub Desktop.
Save junebash/6da6efdd3a1bd9e62a994ef72bdcea67 to your computer and use it in GitHub Desktop.
struct CodeChallengeTestCases<Input, Output> {
var title: String?
var expected: KeyValuePairs<Input, Output>
var solution: (Input) -> Output
init(
title: String? = nil,
expected: KeyValuePairs<Input, Output> = [:],
solution: @escaping (Input) -> Output)
{
self.title = title
self.expected = expected
self.solution = solution
}
}
extension CodeChallengeTestCases {
struct Failure {
let input: Input
let expectedOutput: Output
let actualOutput: Output
func print() {
Swift.print("Input: \t\(input)\n"
+ "Expected: \t\(expectedOutput)\n"
+ "Actual output:\t\(actualOutput)"
)
}
}
var isEmpty: Bool { expected.isEmpty }
func evaluate(_ outputEqualsExpected: (Output, Output) -> Bool) -> [Failure] {
expected.compactMap { ioPair -> Failure? in
let o = output(for: ioPair.key)
let e = ioPair.value
if outputEqualsExpected(o, e) {
return nil
} else {
return Failure(input: ioPair.key, expectedOutput: e, actualOutput: o)
}
}
}
func printFailures(_ outputEqualsExpected: (Output, Output) -> Bool) {
printFailures(evaluate(outputEqualsExpected))
}
func printFailures(_ failures: [Failure]) {
let titleText = title ?? "\(Input.self) -> \(Output.self)"
if failures.isEmpty {
print("All tests passed for '\(titleText)'!\n")
return
}
print("Tests failed for '\(titleText)':")
for f in failures {
printEvaluation(for: f.input,
expected: f.expectedOutput,
actual: f.actualOutput)
}
print("\n----------------\n")
}
func printEvaluations() {
expected.forEach { ioPair in
printEvaluation(for: ioPair.key,
expected: ioPair.value,
actual: solution(ioPair.key))
}
}
}
extension CodeChallengeTestCases where Output: Equatable {
func evaluate() -> [Failure] {
evaluate { $0 == $1 }
}
func printFailures() {
printFailures { $0 == $1 }
}
}
extension CodeChallengeTestCases {
private func output(for input: Input) -> Output {
solution(input)
}
private func printEvaluation(
for input: Input,
expected: Output,
actual: Output)
{
print("Input: \t\(input)\n"
+ "Expected: \t\(expected)\n"
+ "Actual output:\t\(actual)"
)
}
}
extension Array {
func print<I, O>() where Element == CodeChallengeTestCases<I, O>.Failure {
let titleText = "\(I.self) -> \(O.self)"
if self.isEmpty {
Swift.print("All tests passed for '\(titleText)'!\n")
return
}
Swift.print("Tests failed for '\(titleText)':")
self.forEach { $0.print() }
Swift.print("\n----------------\n")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment