Skip to content

Commit

Permalink
feat: Report describe/it inside XCTestCases using XCTest (#32)
Browse files Browse the repository at this point in the history
Closes #2
  • Loading branch information
kylef authored Feb 6, 2018
1 parent af4c327 commit a116c2c
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 23 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

## Master

### Breaking

- Using Spectre in Xcode has be re-hauled, there are now `describe` and `it`
methods on `XCTestCase` which can be used. When used, these tests will be ran
directly and reported as XCTest failures and therefore shown in Xcode and
Xcode sidebar as XCTest failures.

Use of the global test context, i.e, global `describe` and `it` is no longer
permitted when using Spectre with XCTest.

### Enhancements

- Unhandled errors will now be reported from the invoked cases source map.
Expand Down
9 changes: 7 additions & 2 deletions Sources/Spectre/Global.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import Darwin


let globalContext: GlobalContext = {
#if os(macOS)
if getenv("XCTestConfigurationFilePath") != nil {
fatalError("Use of global context is not permitted when running inside XCTest")
}
#endif
atexit { run() }
return GlobalContext()
}()

public func describe(_ name: String, closure: (ContextType) -> Void) {
public func describe(_ name: String, _ closure: (ContextType) -> Void) {
globalContext.describe(name, closure: closure)
}

public func it(_ name: String, closure: @escaping () throws -> Void) {
public func it(_ name: String, _ closure: @escaping () throws -> Void) {
globalContext.it(name, closure: closure)
}

Expand Down
38 changes: 38 additions & 0 deletions Sources/Spectre/XCTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#if os(macOS)
import XCTest


extension XCTestCase {
public func describe(_ name: String, _ closure: (ContextType) -> Void) {
let context = Context(name: name)
closure(context)
context.run(reporter: XcodeReporter(testCase: self))
}

public func it(_ name: String, closure: @escaping () throws -> Void) {
let `case` = Case(name: name, closure: closure)
`case`.run(reporter: XcodeReporter(testCase: self))
}
}


class XcodeReporter: ContextReporter {
let testCase: XCTestCase

init(testCase: XCTestCase) {
self.testCase = testCase
}

func report(_ name: String, closure: (ContextReporter) -> Void) {
closure(self)
}

func addSuccess(_ name: String) {}

func addDisabled(_ name: String) {}

func addFailure(_ name: String, failure: FailureType) {
testCase.recordFailure(withDescription: "\(name): \(failure.reason)", inFile: failure.file, atLine: failure.line, expected: false)
}
}
#endif
5 changes: 3 additions & 2 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Spectre
import SpectreTests

testExpectation()
testFailure()
describe("Expectation", testExpectation)
describe("Failure", testFailure)
5 changes: 1 addition & 4 deletions Tests/SpectreTests/ExpectationSpec.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import Spectre


public func testExpectation() {
describe("Expectation") {
public let testExpectation: ((ContextType) -> Void) = {
$0.it("can be created from a value") {
let expectation = expect("value")
let value = try expectation.expression()
Expand Down Expand Up @@ -192,4 +190,3 @@ public func testExpectation() {
}
}
}
}
25 changes: 12 additions & 13 deletions Tests/SpectreTests/FailureSpec.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import Spectre

public func testFailure() {
describe("Failure") {
$0.it("throws an error") {
var didFail = false
public let testFailure: ((ContextType) -> Void) = {
$0.it("throws an error") {

do {
throw failure("it's broken")
} catch {
didFail = true
}
var didFail = false

if !didFail {
// We cannot trust fail inside fails tests.
fatalError("Test failed")
}
do {
throw failure("it's broken")
} catch {
didFail = true
}

if !didFail {
// We cannot trust fail inside fails tests.
fatalError("Test failed")
}
}
}
5 changes: 3 additions & 2 deletions Tests/SpectreTests/XCTest.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import XCTest
import Spectre

class SpectreTests: XCTestCase {
func testSpectre() {
testFailure()
testExpectation()
describe("Failure", testFailure)
describe("Expectation", testExpectation)
}
}

0 comments on commit a116c2c

Please sign in to comment.