@@ -14,45 +14,59 @@ final class SingletonTests: XCTestCase {
1414
1515 func testThreadSafeSingletonSingleInstance( ) {
1616 // Given - Using a unique class name to avoid static storage conflicts
17- class UniqueTestSingleton1 : ThreadSafeSingleton {
17+ // Each test method needs a completely unique singleton class
18+ // The base class uses shared Static storage, so we need to ensure
19+ // each test class is truly isolated
20+ class IsolatedSingletonTest1 : ThreadSafeSingleton {
1821 var value : String = " initial "
1922
2023 private override init ( ) {
2124 super. init ( )
2225 }
2326
2427 override class func createShared( ) -> Self {
25- // Use a unique static storage per class
26- struct StaticStorage {
27- static var instance : UniqueTestSingleton1 ?
28+ // Use class-specific static storage that's truly isolated
29+ // This struct is unique to this specific class type
30+ struct IsolatedStorage {
31+ static var instance : IsolatedSingletonTest1 ?
2832 }
29- if StaticStorage . instance == nil {
30- StaticStorage . instance = UniqueTestSingleton1 ( )
33+ if IsolatedStorage . instance == nil {
34+ IsolatedStorage . instance = IsolatedSingletonTest1 ( )
3135 }
32- return StaticStorage . instance! as! Self
36+ return IsolatedStorage . instance! as! Self
3337 }
3438 }
3539
36- // When
37- let instance1 = UniqueTestSingleton1 . shared
38- let instance2 = UniqueTestSingleton1 . shared
40+ // When - Access shared instance multiple times
41+ let instance1 = IsolatedSingletonTest1 . shared
42+ let instance2 = IsolatedSingletonTest1 . shared
3943
40- // Then
44+ // Then - Should return the same instance
4145 XCTAssertTrue ( instance1 === instance2, " Should return the same instance " )
4246 XCTAssertEqual ( instance1. value, " initial " )
47+
48+ // Verify it's the same object identity
49+ instance1. value = " modified "
50+ XCTAssertEqual ( instance2. value, " modified " , " Both references should point to same instance " )
4351 }
4452
4553 func testThreadSafeSingletonThreadSafety( ) {
46- // Given
47- class TestSingleton : ThreadSafeSingleton {
54+ // Given - Use unique class name to avoid conflicts
55+ class ThreadSafetyTestSingleton : ThreadSafeSingleton {
4856 var counter : Int = 0
4957
5058 private override init ( ) {
5159 super. init ( )
5260 }
5361
5462 override class func createShared( ) -> Self {
55- return TestSingleton ( ) as! Self
63+ struct StaticStorage {
64+ static var instance : ThreadSafetyTestSingleton ?
65+ }
66+ if StaticStorage . instance == nil {
67+ StaticStorage . instance = ThreadSafetyTestSingleton ( )
68+ }
69+ return StaticStorage . instance! as! Self
5670 }
5771
5872 func increment( ) {
@@ -66,7 +80,7 @@ final class SingletonTests: XCTestCase {
6680
6781 for _ in 0 ..< 10 {
6882 DispatchQueue . global ( ) . async {
69- let instance = TestSingleton . shared
83+ let instance = ThreadSafetyTestSingleton . shared
7084 instance. increment ( )
7185 expectation. fulfill ( )
7286 }
@@ -75,88 +89,112 @@ final class SingletonTests: XCTestCase {
7589 waitForExpectations ( timeout: 2.0 )
7690
7791 // Then - Should still be the same instance
78- let instance1 = TestSingleton . shared
79- let instance2 = TestSingleton . shared
92+ let instance1 = ThreadSafetyTestSingleton . shared
93+ let instance2 = ThreadSafetyTestSingleton . shared
8094 XCTAssertTrue ( instance1 === instance2, " Should return the same instance across threads " )
8195 }
8296
8397 func testThreadSafeSingletonState( ) {
84- // Given
85- class TestSingleton : ThreadSafeSingleton {
98+ // Given - Use unique class name to avoid conflicts
99+ class StateTestSingleton : ThreadSafeSingleton {
86100 var state : String = " initial "
87101
88102 private override init ( ) {
89103 super. init ( )
90104 }
91105
92106 override class func createShared( ) -> Self {
93- return TestSingleton ( ) as! Self
107+ struct StaticStorage {
108+ static var instance : StateTestSingleton ?
109+ }
110+ if StaticStorage . instance == nil {
111+ StaticStorage . instance = StateTestSingleton ( )
112+ }
113+ return StaticStorage . instance! as! Self
94114 }
95115 }
96116
97117 // When
98- let instance = TestSingleton . shared
118+ let instance = StateTestSingleton . shared
99119 instance. state = " modified "
100120
101121 // Then
102- let instance2 = TestSingleton . shared
122+ let instance2 = StateTestSingleton . shared
103123 XCTAssertEqual ( instance2. state, " modified " , " State should persist across accesses " )
104124 }
105125
106126 func testThreadSafeSingletonSubclass( ) {
107- // Given
108- class BaseSingleton : ThreadSafeSingleton {
127+ // Given - Use unique class names to avoid conflicts
128+ class SubclassTestBaseSingleton : ThreadSafeSingleton {
109129 var baseValue : String = " base "
110130
111131 private override init ( ) {
112132 super. init ( )
113133 }
114134
115135 override class func createShared( ) -> Self {
116- return BaseSingleton ( ) as! Self
136+ struct StaticStorage {
137+ static var instance : SubclassTestBaseSingleton ?
138+ }
139+ if StaticStorage . instance == nil {
140+ StaticStorage . instance = SubclassTestBaseSingleton ( )
141+ }
142+ return StaticStorage . instance! as! Self
117143 }
118144 }
119145
120- class DerivedSingleton : ThreadSafeSingleton {
146+ class SubclassTestDerivedSingleton : ThreadSafeSingleton {
121147 var derivedValue : String = " derived "
122148
123149 private override init ( ) {
124150 super. init ( )
125151 }
126152
127153 override class func createShared( ) -> Self {
128- return DerivedSingleton ( ) as! Self
154+ struct StaticStorage {
155+ static var instance : SubclassTestDerivedSingleton ?
156+ }
157+ if StaticStorage . instance == nil {
158+ StaticStorage . instance = SubclassTestDerivedSingleton ( )
159+ }
160+ return StaticStorage . instance! as! Self
129161 }
130162 }
131163
132164 // When
133- let base = BaseSingleton . shared
134- let derived = DerivedSingleton . shared
165+ let base = SubclassTestBaseSingleton . shared
166+ let derived = SubclassTestDerivedSingleton . shared
135167
136168 // Then
137169 XCTAssertNotNil ( base)
138170 XCTAssertNotNil ( derived)
139- XCTAssertTrue ( type ( of: base) == BaseSingleton . self)
140- XCTAssertTrue ( type ( of: derived) == DerivedSingleton . self)
171+ XCTAssertTrue ( type ( of: base) == SubclassTestBaseSingleton . self)
172+ XCTAssertTrue ( type ( of: derived) == SubclassTestDerivedSingleton . self)
141173 }
142174
143175 // MARK: - Singleton Protocol Tests
144176
145177 func testSingletonProtocol( ) {
146- // Given
147- class ProtocolSingleton : ThreadSafeSingleton , Singleton {
178+ // Given - Use unique class name to avoid conflicts
179+ class ProtocolTestSingleton : ThreadSafeSingleton , Singleton {
148180 private override init ( ) {
149181 super. init ( )
150182 }
151183
152184 override class func createShared( ) -> Self {
153- return ProtocolSingleton ( ) as! Self
185+ struct StaticStorage {
186+ static var instance : ProtocolTestSingleton ?
187+ }
188+ if StaticStorage . instance == nil {
189+ StaticStorage . instance = ProtocolTestSingleton ( )
190+ }
191+ return StaticStorage . instance! as! Self
154192 }
155193 }
156194
157195 // When
158- let instance1 = ProtocolSingleton . shared
159- let instance2 = ProtocolSingleton . shared
196+ let instance1 = ProtocolTestSingleton . shared
197+ let instance2 = ProtocolTestSingleton . shared
160198
161199 // Then
162200 XCTAssertTrue ( instance1 === instance2, " Should conform to Singleton protocol " )
0 commit comments