Skip to content

Commit

Permalink
Add support for optional values
Browse files Browse the repository at this point in the history
Also adds support for customising the separator used when generating the test name.
  • Loading branch information
cameroncooke committed Jan 6, 2023
1 parent 7a24179 commit 3110804
Show file tree
Hide file tree
Showing 32 changed files with 2,619 additions and 176 deletions.
35 changes: 35 additions & 0 deletions Sources/ParameterizedTesting/ParameterizedTestCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// ParameterizedTestCase.swift
// Copyright © 2023 Cameron Cooke. All rights reserved.
//

import Foundation
import XCTest

open class ParameterizedTestCase: XCTestCase {

// MARK: - Open -

open class var testNameFieldSeparator: String {
"_"
}

// MARK: - Internal -

private var storage: [String: Any] = [:]

func setValue<T>(_ value: T, forKey key: String) {
storage[key] = value
}

func getValue<T>(forKey key: String) -> T? {
return storage[key] as? T
}

static func testName(for values: [Any]) -> String {
values
.map { String(describing: $0) }
.joined(separator: testNameFieldSeparator)
.lowercased()
}
}
29 changes: 20 additions & 9 deletions Sources/ParameterizedTesting/ParameterizedTestsCase1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import XCTest

open class ParameterizedTestCase1<IN1, OUT>: XCTestCase {
open class ParameterizedTestCase1<IN1, OUT>: ParameterizedTestCase {
// MARK: - Open -

open override class var defaultTestSuite: XCTestSuite {
Expand All @@ -20,8 +20,14 @@ open class ParameterizedTestCase1<IN1, OUT>: XCTestCase {
nil
}

open class func testName(_ value1: IN1) -> String {
"\(value1)".lowercased()
open class func testName(
_ value1: IN1
) -> String {
testName(
for: [
value1,
]
)
}

open func testAllCombinations(_ value1: IN1, _ expectedResult: OUT?) {
Expand All @@ -31,11 +37,11 @@ open class ParameterizedTestCase1<IN1, OUT>: XCTestCase {
// MARK: - Internal -

func getValue1() -> IN1? {
getValue(forKey: &ParameterizedTestCaseKey.value1)
getValue(forKey: ParameterizedTestCaseKey.value1)
}

func getExpectedValue() -> OUT? {
getValue(forKey: &ParameterizedTestCaseKey.expectedValue)
getValue(forKey: ParameterizedTestCaseKey.expectedValue)
}

@objc
Expand Down Expand Up @@ -64,16 +70,21 @@ open class ParameterizedTestCase1<IN1, OUT>: XCTestCase {

let selector = ParameterizedTestCase1.registerTestMethod(
name: testName(value1),
testMethod: #selector(self.internalHandler)
testMethod: #selector(self.internalHandler),
separator: testNameFieldSeparator
)

let test = subclassType.init(selector: selector)
test.setValue(value: value1, forKey: &ParameterizedTestCaseKey.value1)
let testCase = subclassType.init(selector: selector)
guard let test = testCase as? ParameterizedTestCase else {
fatalError("Unable to instantiate XCTestCase")
}

test.setValue(value1, forKey: ParameterizedTestCaseKey.value1)

if let expectedValues {
if expectedValues.count == totalCombinations {
let expectedValue = expectedValues[counter]
test.setValue(value: expectedValue, forKey: &ParameterizedTestCaseKey.expectedValue)
test.setValue(expectedValue, forKey: ParameterizedTestCaseKey.expectedValue)

} else {
preconditionFailure(
Expand Down
30 changes: 20 additions & 10 deletions Sources/ParameterizedTesting/ParameterizedTestsCase2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import XCTest

open class ParameterizedTestCase2<IN1, IN2, OUT>: XCTestCase {
open class ParameterizedTestCase2<IN1, IN2, OUT>: ParameterizedTestCase {
// MARK: - Open -

open override class var defaultTestSuite: XCTestSuite {
Expand All @@ -24,7 +24,12 @@ open class ParameterizedTestCase2<IN1, IN2, OUT>: XCTestCase {
_ value1: IN1,
_ value2: IN2
) -> String {
"\(value1)_\(value2)".lowercased()
testName(
for: [
value1,
value2
]
)
}

open func testAllCombinations(_ value1: IN1, _ value2: IN2, _ expectedResult: OUT?) {
Expand All @@ -34,15 +39,15 @@ open class ParameterizedTestCase2<IN1, IN2, OUT>: XCTestCase {
// MARK: - Internal -

func getValue1() -> IN1? {
getValue(forKey: &ParameterizedTestCaseKey.value1)
getValue(forKey: ParameterizedTestCaseKey.value1)
}

func getValue2() -> IN2? {
getValue(forKey: &ParameterizedTestCaseKey.value2)
getValue(forKey: ParameterizedTestCaseKey.value2)
}

func getExpectedValue() -> OUT? {
getValue(forKey: &ParameterizedTestCaseKey.expectedValue)
getValue(forKey: ParameterizedTestCaseKey.expectedValue)
}

@objc
Expand Down Expand Up @@ -72,17 +77,22 @@ open class ParameterizedTestCase2<IN1, IN2, OUT>: XCTestCase {

let selector = ParameterizedTestCase2.registerTestMethod(
name: testName(value1, value2),
testMethod: #selector(self.internalHandler)
testMethod: #selector(self.internalHandler),
separator: testNameFieldSeparator
)

let test = subclassType.init(selector: selector)
test.setValue(value: value1, forKey: &ParameterizedTestCaseKey.value1)
test.setValue(value: value2, forKey: &ParameterizedTestCaseKey.value2)
let testCase = subclassType.init(selector: selector)
guard let test = testCase as? ParameterizedTestCase else {
fatalError("Unable to instantiate XCTestCase")
}

test.setValue(value1, forKey: ParameterizedTestCaseKey.value1)
test.setValue(value2, forKey: ParameterizedTestCaseKey.value2)

if let expectedValues {
if expectedValues.count == totalCombinations {
let expectedValue = expectedValues[counter]
test.setValue(value: expectedValue, forKey: &ParameterizedTestCaseKey.expectedValue)
test.setValue(expectedValue, forKey: ParameterizedTestCaseKey.expectedValue)

} else {
preconditionFailure(
Expand Down
35 changes: 23 additions & 12 deletions Sources/ParameterizedTesting/ParameterizedTestsCase3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import XCTest

open class ParameterizedTestCase3<IN1, IN2, IN3, OUT>: XCTestCase {
open class ParameterizedTestCase3<IN1, IN2, IN3, OUT>: ParameterizedTestCase {
// MARK: - Open -

open override class var defaultTestSuite: XCTestSuite {
Expand All @@ -25,7 +25,13 @@ open class ParameterizedTestCase3<IN1, IN2, IN3, OUT>: XCTestCase {
_ value2: IN2,
_ value3: IN3
) -> String {
"\(value1)_\(value2)_\(value3)".lowercased()
testName(
for: [
value1,
value2,
value3
]
)
}

open func testAllCombinations(_ value1: IN1, _ value2: IN2, _ value3: IN3, _ expectedResult: OUT?) {
Expand All @@ -35,19 +41,19 @@ open class ParameterizedTestCase3<IN1, IN2, IN3, OUT>: XCTestCase {
// MARK: - Internal -

func getValue1() -> IN1? {
getValue(forKey: &ParameterizedTestCaseKey.value1)
getValue(forKey: ParameterizedTestCaseKey.value1)
}

func getValue2() -> IN2? {
getValue(forKey: &ParameterizedTestCaseKey.value2)
getValue(forKey: ParameterizedTestCaseKey.value2)
}

func getValue3() -> IN3? {
getValue(forKey: &ParameterizedTestCaseKey.value3)
getValue(forKey: ParameterizedTestCaseKey.value3)
}

func getExpectedValue() -> OUT? {
getValue(forKey: &ParameterizedTestCaseKey.expectedValue)
getValue(forKey: ParameterizedTestCaseKey.expectedValue)
}

@objc
Expand Down Expand Up @@ -78,18 +84,23 @@ open class ParameterizedTestCase3<IN1, IN2, IN3, OUT>: XCTestCase {

let selector = ParameterizedTestCase3.registerTestMethod(
name: testName(value1, value2, value3),
testMethod: #selector(self.internalHandler)
testMethod: #selector(self.internalHandler),
separator: testNameFieldSeparator
)

let test = subclassType.init(selector: selector)
test.setValue(value: value1, forKey: &ParameterizedTestCaseKey.value1)
test.setValue(value: value2, forKey: &ParameterizedTestCaseKey.value2)
test.setValue(value: value3, forKey: &ParameterizedTestCaseKey.value3)
let testCase = subclassType.init(selector: selector)
guard let test = testCase as? ParameterizedTestCase else {
fatalError("Unable to instantiate XCTestCase")
}

test.setValue(value1, forKey: ParameterizedTestCaseKey.value1)
test.setValue(value2, forKey: ParameterizedTestCaseKey.value2)
test.setValue(value3, forKey: ParameterizedTestCaseKey.value3)

if let expectedValues {
if expectedValues.count == totalCombinations {
let expectedValue = expectedValues[counter]
test.setValue(value: expectedValue, forKey: &ParameterizedTestCaseKey.expectedValue)
test.setValue(expectedValue, forKey: ParameterizedTestCaseKey.expectedValue)

} else {
preconditionFailure(
Expand Down
40 changes: 26 additions & 14 deletions Sources/ParameterizedTesting/ParameterizedTestsCase4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import XCTest

open class ParameterizedTestCase4<IN1, IN2, IN3, IN4, OUT>: XCTestCase {
open class ParameterizedTestCase4<IN1, IN2, IN3, IN4, OUT>: ParameterizedTestCase {
// MARK: - Open -

open override class var defaultTestSuite: XCTestSuite {
Expand All @@ -26,7 +26,14 @@ open class ParameterizedTestCase4<IN1, IN2, IN3, IN4, OUT>: XCTestCase {
_ value3: IN3,
_ value4: IN4
) -> String {
"\(value1)_\(value2)_\(value3)_\(value4)".lowercased()
testName(
for: [
value1,
value2,
value3,
value4
]
)
}

open func testAllCombinations(
Expand All @@ -42,23 +49,23 @@ open class ParameterizedTestCase4<IN1, IN2, IN3, IN4, OUT>: XCTestCase {
// MARK: - Internal -

func getValue1() -> IN1? {
getValue(forKey: &ParameterizedTestCaseKey.value1)
getValue(forKey: ParameterizedTestCaseKey.value1)
}

func getValue2() -> IN2? {
getValue(forKey: &ParameterizedTestCaseKey.value2)
getValue(forKey: ParameterizedTestCaseKey.value2)
}

func getValue3() -> IN3? {
getValue(forKey: &ParameterizedTestCaseKey.value3)
getValue(forKey: ParameterizedTestCaseKey.value3)
}

func getValue4() -> IN4? {
getValue(forKey: &ParameterizedTestCaseKey.value4)
getValue(forKey: ParameterizedTestCaseKey.value4)
}

func getExpectedValue() -> OUT? {
getValue(forKey: &ParameterizedTestCaseKey.expectedValue)
getValue(forKey: ParameterizedTestCaseKey.expectedValue)
}

@objc
Expand Down Expand Up @@ -91,19 +98,24 @@ open class ParameterizedTestCase4<IN1, IN2, IN3, IN4, OUT>: XCTestCase {

let selector = ParameterizedTestCase4.registerTestMethod(
name: testName(value1, value2, value3, value4),
testMethod: #selector(self.internalHandler)
testMethod: #selector(self.internalHandler),
separator: testNameFieldSeparator
)

let test = subclassType.init(selector: selector)
test.setValue(value: value1, forKey: &ParameterizedTestCaseKey.value1)
test.setValue(value: value2, forKey: &ParameterizedTestCaseKey.value2)
test.setValue(value: value3, forKey: &ParameterizedTestCaseKey.value3)
test.setValue(value: value4, forKey: &ParameterizedTestCaseKey.value4)
let testCase = subclassType.init(selector: selector)
guard let test = testCase as? ParameterizedTestCase else {
fatalError("Unable to instantiate XCTestCase")
}

test.setValue(value1, forKey: ParameterizedTestCaseKey.value1)
test.setValue(value2, forKey: ParameterizedTestCaseKey.value2)
test.setValue(value3, forKey: ParameterizedTestCaseKey.value3)
test.setValue(value4, forKey: ParameterizedTestCaseKey.value4)

if let expectedValues {
if expectedValues.count == totalCombinations {
let expectedValue = expectedValues[counter]
test.setValue(value: expectedValue, forKey: &ParameterizedTestCaseKey.expectedValue)
test.setValue(expectedValue, forKey: ParameterizedTestCaseKey.expectedValue)

} else {
preconditionFailure(
Expand Down
Loading

0 comments on commit 3110804

Please sign in to comment.