Skip to content

Commit

Permalink
Test isolation fixes (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyMDev authored and gh-action-runner committed Oct 30, 2023
1 parent 6e55764 commit d7fa344
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 164 deletions.
60 changes: 42 additions & 18 deletions Tests/ApolloCodegenInternalTestHelpers/MockFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,33 @@ public class MockApolloFileManager: ApolloFileManager {
}
}

/// If `true` then all called closures must be mocked otherwise the call will fail. When `false` any called closure
/// that is not mocked will fall through to `super`. As a byproduct of `false`, all mocked closures must be called otherwise
/// the test will fail.
/// If `true` then any function on the file manager called that is not mocked will
/// result in a test failure. If `false`, any called closure that is not mocked will fall
/// through to `super`. Defaults to `true`.
var strict: Bool { _base.strict }

/// If `true` all mocked closures must be called otherwise the test
/// will fail. Defaults to `true`.
var requireAllClosuresCalled: Bool { _base.requireAllClosuresCalled }

var _base: MockFileManager { unsafeDowncast(base, to: MockFileManager.self) }

/// Designated initializer.
///
/// - Parameters:
/// - strict: If `true` then all called closures must be mocked otherwise the call will fail.
/// When `false` any called closure that is not mocked will fall through to `super`. As a
/// byproduct of `false`, all mocked closures must be called otherwise the test will fail.
public init(strict: Bool = true) {
super.init(base: MockFileManager(strict: strict))
/// - strict: If `true` then any function on the file manager called that is not mocked will
/// result in a test failure. If `false`, any called closure that is not mocked will fall
/// through to `super`. Defaults to `true`.
/// - requireAllClosuresCalled: If `true` all mocked closures must be called otherwise the test
/// will fail. Defaults to `true`.
public init(
strict: Bool = true,
requireAllClosuresCalled: Bool = true
) {
super.init(base: MockFileManager(
strict: strict,
requireAllClosuresCalled: requireAllClosuresCalled
))
}

/// Provide a mock closure for the `FileManager` function.
Expand All @@ -58,39 +71,50 @@ public class MockApolloFileManager: ApolloFileManager {

class MockFileManager: FileManager {

private let lock = NSLock()

fileprivate var closures: [String: Closure] = [:]
fileprivate var closuresToBeCalled: Set<String> = []

/// If `true` then all called closures must be mocked otherwise the call will fail. When `false` any called closure
/// that is not mocked will fall through to `super`. As a byproduct of `false`, all mocked closures must be called otherwise
/// the test will fail.
let strict: Bool

fileprivate init(strict: Bool = true) {
let requireAllClosuresCalled: Bool

fileprivate init(
strict: Bool = true,
requireAllClosuresCalled: Bool = true
) {
self.strict = strict
self.requireAllClosuresCalled = requireAllClosuresCalled
}

deinit {
if strict == false && allClosuresCalled == false {
XCTFail("Non-strict mode requires that all mocked closures are called! Check \(closuresToBeCalled) in your MockFileManager instance.")
if requireAllClosuresCalled && !allClosuresCalled {
XCTFail("`requireAllClosuresCalled` is `true`, but not all mocked closures are called! Check \(closuresToBeCalled) in your MockFileManager instance.")
}
}

/// Provide a mock closure for the `FileManager` function.
///
/// - Parameter closure: The mocked function closure.
fileprivate func mock(closure: Closure) {
closures[closure.description] = closure
closuresToBeCalled.insert(closure.description)
lock.withLock {
closures[closure.description] = closure
closuresToBeCalled.insert(closure.description)
}
}

fileprivate func didCall(closure: Closure) {
closuresToBeCalled.remove(closure.description)
lock.withLock {
_ = closuresToBeCalled.remove(closure.description)
}
}

/// Check whether all mocked closures were called during the lifetime of an instance.
fileprivate var allClosuresCalled: Bool {
return closuresToBeCalled.isEmpty
return lock.withLock {
return closuresToBeCalled.isEmpty
}
}

// MARK: FileManager overrides
Expand Down
Loading

0 comments on commit d7fa344

Please sign in to comment.