Skip to content

Instantly share code, notes, and snippets.

@FranDepascuali
Last active August 22, 2020 12:57
Show Gist options
  • Save FranDepascuali/d5aef2566a052235eb7c649e7830e2e6 to your computer and use it in GitHub Desktop.
Save FranDepascuali/d5aef2566a052235eb7c649e7830e2e6 to your computer and use it in GitHub Desktop.
A sample for testing memory leaks
// Adapted from https://www.avanderlee.com/swift/memory-leaks-unit-tests/
// --------------> Usage <-------------------
XCTAssertDeallocation(of: {
MyViewController(...)
})
// With some setup:
XCTAssertDeallocation(of: { () -> MyViewController in
let myViewController = MyViewController(...)
// call any function
return myViewController
})
// Can also be used with other types, not only view controller.
// --------------> Implementation <-------------------
import Foundation
import XCTest
@testable import Oasis
public func XCTAssertDeallocation<T: AnyObject>(
of buildElement: () -> T,
file: StaticString = #file,
line: UInt = #line) {
weak var weakReference: T?
autoreleasepool {
let element = buildElement()
weakReference = element
// If it's a UIViewController, we need to trigger viewDidLoad.
if let viewController = element as? UIViewController {
_ = viewController.view
}
}
XCTWait(for: weakReference == nil, timeout: 3.0, description: "Memory leak in \(T.self)", file: file, line: line)
}
/// Checks for the callback to be the expected value within the given timeout.
///
/// - Parameters:
/// - condition: The condition to check for.
/// - timeout: The timeout in which the callback should return true.
/// - description: A string to display in the test log for this expectation, to help diagnose failures.
func XCTWait(
for condition: @autoclosure @escaping () -> Bool,
timeout: TimeInterval, description: String,
file: StaticString = #file,
line: UInt = #line) {
let end = Date().addingTimeInterval(timeout)
var value: Bool = false
let closure: () -> Void = {
value = condition()
}
while !value && 0 < end.timeIntervalSinceNow {
if RunLoop.current.run(mode: RunLoop.Mode.default, before: Date(timeIntervalSinceNow: 0.002)) {
Thread.sleep(forTimeInterval: 0.002)
}
closure()
}
closure()
XCTAssertTrue(value, "➡️? Timed out waiting for condition to be true: \"\(description)\"", file: file, line: line)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment