Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kibotu committed Jul 1, 2024
1 parent 5860cd2 commit 844956c
Showing 1 changed file with 186 additions and 6 deletions.
192 changes: 186 additions & 6 deletions Tests/KhanTests/KhanTests.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,192 @@
import XCTest
@testable import Khan

final class KhanTests: XCTestCase {
func testExample() throws {
// XCTest Documentation
// https://developer.apple.com/documentation/xctest
class KhanTests: XCTestCase {

// Defining Test Cases and Test Methods
// https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
// MARK: - Circular Dependency Tests

func testCircularDependencyDetection() {
class A: Initializer {
static var dependencies: [Initializer.Type] = [B.self]
static func embark() async throws {}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = [A.self]
static func embark() async throws {}
}

XCTAssertThrowsError(try Khan(initializers: [A.self, B.self])) { error in
XCTAssertTrue(error.localizedDescription.contains("CyclicDependencyError"))
}
}

func testComplexCircularDependencyDetection() {
class A: Initializer {
static var dependencies: [Initializer.Type] = [B.self]
static func embark() async throws {}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = [C.self]
static func embark() async throws {}
}

class C: Initializer {
static var dependencies: [Initializer.Type] = [A.self]
static func embark() async throws {}
}

XCTAssertThrowsError(try Khan(initializers: [A.self, B.self, C.self])) { error in
XCTAssertTrue(error.localizedDescription.contains("CyclicDependencyError"))
}
}

// MARK: - Thread Safety Tests

func testConcurrentInitialization() async throws {
class A: Initializer {
static var dependencies: [Initializer.Type] = []
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = []
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

let khan = try Khan(initializers: [A.self, B.self])

let expectation = XCTestExpectation(description: "Concurrent initialization")

Task {
try await khan.conquer()
expectation.fulfill()
}

await fulfillment(of: [expectation], timeout: 0.3)
}

// MARK: - Deadlock Tests

func testNoDeadlockWithComplexDependencies() async throws {
class A: Initializer {
static var dependencies: [Initializer.Type] = [B.self, C.self]
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = [D.self]
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

class C: Initializer {
static var dependencies: [Initializer.Type] = [D.self]
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

class D: Initializer {
static var dependencies: [Initializer.Type] = []
static func embark() async throws {
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 second
}
}

let khan = try Khan(initializers: [A.self, B.self, C.self, D.self])

let expectation = XCTestExpectation(description: "Complex initialization without deadlock")

Task {
try await khan.conquer()
expectation.fulfill()
}

await fulfillment(of: [expectation], timeout: 0.5)
}

// MARK: - Dependency Order Tests

func testCorrectDependencyOrder() async throws {
class TestTracker {
static var initializationOrder: [String] = []
}

class A: Initializer {
static var dependencies: [Initializer.Type] = [B.self]
static func embark() async throws {
TestTracker.initializationOrder.append("A")
}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = [C.self]
static func embark() async throws {
TestTracker.initializationOrder.append("B")
}
}

class C: Initializer {
static var dependencies: [Initializer.Type] = []
static func embark() async throws {
TestTracker.initializationOrder.append("C")
}
}

let khan = try Khan(initializers: [A.self, B.self, C.self])
try await khan.conquer()

XCTAssertEqual(TestTracker.initializationOrder, ["C", "B", "A"])
}

func testCorrectDependencyOrderWithMultipleDependencies() async throws {
class TestTracker {
static var initializationOrder: [String] = []
}

class A: Initializer {
static var dependencies: [Initializer.Type] = [B.self, C.self]
static func embark() async throws {
TestTracker.initializationOrder.append("A")
}
}

class B: Initializer {
static var dependencies: [Initializer.Type] = [D.self]
static func embark() async throws {
TestTracker.initializationOrder.append("B")
}
}

class C: Initializer {
static var dependencies: [Initializer.Type] = [D.self]
static func embark() async throws {
TestTracker.initializationOrder.append("C")
}
}

class D: Initializer {
static var dependencies: [Initializer.Type] = []
static func embark() async throws {
TestTracker.initializationOrder.append("D")
}
}

let khan = try Khan(initializers: [A.self, B.self, C.self, D.self])
try await khan.conquer()

XCTAssertEqual(TestTracker.initializationOrder.first, "D")
XCTAssertEqual(TestTracker.initializationOrder.last, "A")
XCTAssertTrue(TestTracker.initializationOrder.firstIndex(of: "B")! < TestTracker.initializationOrder.firstIndex(of: "A")!)
XCTAssertTrue(TestTracker.initializationOrder.firstIndex(of: "C")! < TestTracker.initializationOrder.firstIndex(of: "A")!)
}
}

0 comments on commit 844956c

Please sign in to comment.