Skip to content

Commit 86cf243

Browse files
committed
feat: Add tests for ThreadSafeArray, ThreadSafeDictionary, and Registry
1 parent bf02f2f commit 86cf243

4 files changed

Lines changed: 328 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import XCTest
2+
@testable import DesignAlgorithmsKit
3+
4+
final class GenericRegistryTests: XCTestCase {
5+
6+
func testRegistration() {
7+
let registry = Registry<String, Int>()
8+
9+
registry.register(1, for: "one")
10+
XCTAssertEqual(registry.get("one"), 1)
11+
12+
registry.register(2, for: "two")
13+
XCTAssertEqual(registry.get("two"), 2)
14+
}
15+
16+
func testOverwrite() {
17+
let registry = Registry<String, Int>()
18+
19+
registry.register(1, for: "key")
20+
XCTAssertEqual(registry.get("key"), 1)
21+
22+
registry.register(2, for: "key")
23+
XCTAssertEqual(registry.get("key"), 2)
24+
}
25+
26+
func testRemoval() {
27+
let registry = Registry<String, Int>()
28+
registry.register(1, for: "one")
29+
30+
registry.unregister("one")
31+
XCTAssertNil(registry.get("one"))
32+
33+
registry.register(2, for: "two")
34+
registry.removeAll()
35+
XCTAssertNil(registry.get("two"))
36+
}
37+
38+
func testAll() {
39+
let registry = Registry<String, Int>()
40+
registry.register(1, for: "one")
41+
registry.register(2, for: "two")
42+
43+
let allValues = registry.all()
44+
XCTAssertEqual(allValues.count, 2)
45+
XCTAssertTrue(allValues.contains(1))
46+
XCTAssertTrue(allValues.contains(2))
47+
}
48+
49+
func testConcurrency() {
50+
let registry = Registry<Int, Int>()
51+
let iterations = 1000
52+
let expectation = self.expectation(description: "Concurrent registry access")
53+
expectation.expectedFulfillmentCount = iterations
54+
55+
DispatchQueue.concurrentPerform(iterations: iterations) { i in
56+
registry.register(i, for: i)
57+
expectation.fulfill()
58+
}
59+
60+
waitForExpectations(timeout: 5.0)
61+
62+
// Count via iteration or if there is a count property (Registry usually doesn't expose count directly but has all().count)
63+
XCTAssertEqual(registry.all().count, iterations)
64+
65+
// Verify random element
66+
XCTAssertEqual(registry.get(500), 500)
67+
}
68+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import XCTest
2+
@testable import DesignAlgorithmsKit
3+
4+
final class ThreadSafeArrayTests: XCTestCase {
5+
6+
func testInitialization() {
7+
let array = ThreadSafeArray<Int>()
8+
XCTAssertTrue(array.isEmpty)
9+
XCTAssertEqual(array.count, 0)
10+
11+
let arrayWithItems = ThreadSafeArray([1, 2, 3])
12+
XCTAssertFalse(arrayWithItems.isEmpty)
13+
XCTAssertEqual(arrayWithItems.count, 3)
14+
}
15+
16+
func testAppend() {
17+
let array = ThreadSafeArray<Int>()
18+
array.append(1)
19+
XCTAssertEqual(array.count, 1)
20+
XCTAssertEqual(array[0], 1)
21+
22+
array.append(contentsOf: [2, 3])
23+
XCTAssertEqual(array.count, 3)
24+
XCTAssertEqual(array.allElements, [1, 2, 3])
25+
}
26+
27+
func testRemove() {
28+
let array = ThreadSafeArray([1, 2, 3])
29+
30+
let removed = array.remove(at: 1)
31+
XCTAssertEqual(removed, 2)
32+
XCTAssertEqual(array.count, 2)
33+
XCTAssertEqual(array.allElements, [1, 3])
34+
35+
array.removeAll()
36+
XCTAssertTrue(array.isEmpty)
37+
}
38+
39+
func testSubscript() {
40+
let array = ThreadSafeArray([1, 2, 3])
41+
XCTAssertEqual(array[0], 1)
42+
43+
array[0] = 10
44+
XCTAssertEqual(array[0], 10)
45+
}
46+
47+
func testFunctionalMethods() {
48+
let array = ThreadSafeArray([1, 2, 3, 4, 5])
49+
50+
// Map
51+
let stringArray = array.map { String($0) }
52+
XCTAssertEqual(stringArray, ["1", "2", "3", "4", "5"])
53+
54+
// Filter
55+
let evenArray = array.filter { $0 % 2 == 0 }
56+
XCTAssertEqual(evenArray, [2, 4])
57+
58+
// CompactMap
59+
let optionalArray = ThreadSafeArray(["1", "2", "NaN", "4"])
60+
let numbers = optionalArray.compactMap { Int($0) }
61+
XCTAssertEqual(numbers, [1, 2, 4])
62+
63+
// First(where:)
64+
let firstEven = array.first { $0 % 2 == 0 }
65+
XCTAssertEqual(firstEven, 2)
66+
67+
// Contains(where:)
68+
XCTAssertTrue(array.contains { $0 == 3 })
69+
XCTAssertFalse(array.contains { $0 == 6 })
70+
}
71+
72+
func testConcurrency() {
73+
let array = ThreadSafeArray<Int>()
74+
let iterations = 1000
75+
let expectation = self.expectation(description: "Concurrent append")
76+
expectation.expectedFulfillmentCount = iterations
77+
78+
DispatchQueue.concurrentPerform(iterations: iterations) { i in
79+
array.append(i)
80+
expectation.fulfill()
81+
}
82+
83+
waitForExpectations(timeout: 5.0)
84+
85+
// Should have all elements
86+
XCTAssertEqual(array.count, iterations)
87+
88+
// Count should match manual counting via read
89+
let count = array.read { $0.count }
90+
XCTAssertEqual(count, iterations)
91+
}
92+
93+
func testReadWriteBlock() {
94+
let array = ThreadSafeArray([1, 2, 3])
95+
96+
// Write block
97+
array.write { elements in
98+
elements.append(4)
99+
}
100+
101+
XCTAssertEqual(array.count, 4)
102+
103+
// Read block
104+
let sum = array.read { elements in
105+
return elements.reduce(0, +)
106+
}
107+
108+
XCTAssertEqual(sum, 10)
109+
}
110+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import XCTest
2+
@testable import DesignAlgorithmsKit
3+
4+
final class ThreadSafeDictionaryTests: XCTestCase {
5+
6+
func testInitialization() {
7+
let dict = ThreadSafeDictionary<String, Int>()
8+
XCTAssertTrue(dict.isEmpty)
9+
XCTAssertEqual(dict.count, 0)
10+
11+
let dictWithItems = ThreadSafeDictionary(["a": 1, "b": 2])
12+
XCTAssertFalse(dictWithItems.isEmpty)
13+
XCTAssertEqual(dictWithItems.count, 2)
14+
}
15+
16+
func testSubscript() {
17+
let dict = ThreadSafeDictionary<String, Int>()
18+
19+
// Write
20+
dict["a"] = 1
21+
XCTAssertEqual(dict["a"], 1)
22+
XCTAssertEqual(dict.count, 1)
23+
24+
// Update
25+
dict["a"] = 2
26+
XCTAssertEqual(dict["a"], 2)
27+
28+
// Remove via subscript
29+
dict["a"] = nil
30+
XCTAssertNil(dict["a"])
31+
XCTAssertTrue(dict.isEmpty)
32+
}
33+
34+
func testDefaultSubscript() {
35+
let dict = ThreadSafeDictionary<String, Int>()
36+
37+
// Read with default
38+
XCTAssertEqual(dict["a", default: 0], 0)
39+
40+
// Write with default (modify)
41+
dict["a", default: 0] += 1
42+
XCTAssertEqual(dict["a"], 1)
43+
}
44+
45+
func testUpdateValue() {
46+
let dict = ThreadSafeDictionary<String, Int>()
47+
48+
// Insert new
49+
let oldVal1 = dict.updateValue(1, forKey: "a")
50+
XCTAssertNil(oldVal1)
51+
XCTAssertEqual(dict["a"], 1)
52+
53+
// Update existing
54+
let oldVal2 = dict.updateValue(2, forKey: "a")
55+
XCTAssertEqual(oldVal2, 1)
56+
XCTAssertEqual(dict["a"], 2)
57+
}
58+
59+
func testRemoveValue() {
60+
let dict = ThreadSafeDictionary(["a": 1])
61+
62+
let removed = dict.removeValue(forKey: "a")
63+
XCTAssertEqual(removed, 1)
64+
XCTAssertTrue(dict.isEmpty)
65+
66+
let notFound = dict.removeValue(forKey: "b")
67+
XCTAssertNil(notFound)
68+
}
69+
70+
func testProperties() {
71+
let dict = ThreadSafeDictionary(["a": 1, "b": 2])
72+
73+
XCTAssertEqual(dict.all.count, 2)
74+
XCTAssertEqual(dict.keys.sorted(), ["a", "b"])
75+
XCTAssertEqual(dict.values.sorted(), [1, 2])
76+
77+
dict.removeAll()
78+
XCTAssertTrue(dict.isEmpty)
79+
}
80+
81+
func testConcurrency() {
82+
let dict = ThreadSafeDictionary<Int, Int>()
83+
let iterations = 1000
84+
let expectation = self.expectation(description: "Concurrent dictionary access")
85+
expectation.expectedFulfillmentCount = iterations
86+
87+
DispatchQueue.concurrentPerform(iterations: iterations) { i in
88+
dict[i] = i
89+
expectation.fulfill()
90+
}
91+
92+
waitForExpectations(timeout: 5.0)
93+
94+
XCTAssertEqual(dict.count, iterations)
95+
}
96+
97+
func testReadWriteBlock() {
98+
let dict = ThreadSafeDictionary(["a": 1, "b": 2])
99+
100+
// Write block
101+
dict.write { items in
102+
items["c"] = 3
103+
}
104+
105+
XCTAssertEqual(dict.count, 3)
106+
107+
// Read block
108+
let keys = dict.read { Array($0.keys).sorted() }
109+
XCTAssertEqual(keys, ["a", "b", "c"])
110+
}
111+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import XCTest
2+
@testable import DesignAlgorithmsKit
3+
4+
final class ThreadSafeTests: XCTestCase {
5+
6+
func testInitialization() {
7+
let safeInt = ThreadSafe(0)
8+
XCTAssertEqual(safeInt.read { $0 }, 0)
9+
}
10+
11+
func testReadWrite() {
12+
let safeInt = ThreadSafe(0)
13+
14+
// Write
15+
safeInt.write { $0 = 10 }
16+
17+
// Read
18+
let val = safeInt.read { $0 }
19+
XCTAssertEqual(val, 10)
20+
}
21+
22+
func testConcurrency() {
23+
let safeCounter = ThreadSafe(0)
24+
let iterations = 1000
25+
let expectation = self.expectation(description: "Concurrent increment")
26+
expectation.expectedFulfillmentCount = iterations
27+
28+
DispatchQueue.concurrentPerform(iterations: iterations) { i in
29+
safeCounter.write { $0 += 1 }
30+
expectation.fulfill()
31+
}
32+
33+
waitForExpectations(timeout: 5.0)
34+
35+
XCTAssertEqual(safeCounter.read { $0 }, iterations)
36+
}
37+
38+
39+
}

0 commit comments

Comments
 (0)