Skip to content

Commit

Permalink
Ref-Cycle flaky tests fix (#36)
Browse files Browse the repository at this point in the history
* moved to test utils

* added assert deallocation test extension

* fixed test

* updated all ref cycle tests
  • Loading branch information
KazaiMazai authored Aug 26, 2024
1 parent a68d3e0 commit 3fa8b78
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,17 @@ final class RootStoreRefCyclesTests: XCTestCase {
let timeout: TimeInterval = 3

func test_WhenGetStore_ThenNoStrongRefToRootStore() {
weak var rootStore: RootStore<TestState, Action>?
var store: Store<TestState, Action>?

autoreleasepool {
let strongRootStore = RootStore<TestState, Action>(
assertDeallocated {
let rootStore = RootStore<TestState, Action>(
initialState: TestState(currentIndex: 1)) { state, action in

state.reduce(action: action)
}

store = strongRootStore.store()
rootStore = strongRootStore
store = rootStore.store()
return rootStore as AnyObject
}

XCTAssertNil(rootStore)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,66 +19,54 @@ final class StoreNodeChildStoreRefCyclesTests: XCTestCase {
)

func test_WhenStore_ThenWeakRefToChildStoreCreated() {
weak var weakChildStore: ChildStore?
var store: Store<StateComposition, Action>?

autoreleasepool {
let strongChildStore = rootStore.createChildStore(
assertDeallocated {
let strongChildStore = self.rootStore.createChildStore(
initialState: ChildTestState(currentIndex: 0),
stateMapping: { state, childState in
StateComposition(state: state, childState: childState)
},
qos: .userInitiated,
reducer: { state, action in state.reduce(action: action) }
)

weakChildStore = strongChildStore

store = strongChildStore.weakRefStore()
return strongChildStore as AnyObject
}

XCTAssertNil(weakChildStore)
}

func test_WhenStoreObject_ThenStrongRefToChildStoreCreated() {
weak var weakChildStore: ChildStore?
var referencedStore: StateStore<StateComposition, Action>?

autoreleasepool {
let strongChildStore = rootStore.createChildStore(
assertNotDeallocated {
let strongChildStore = self.rootStore.createChildStore(
initialState: ChildTestState(currentIndex: 0),
stateMapping: { state, childState in
StateComposition(state: state, childState: childState)
},
qos: .userInitiated,
reducer: { state, action in state.reduce(action: action) }
)

weakChildStore = strongChildStore

referencedStore = strongChildStore.stateStore()
return strongChildStore as AnyObject
}

XCTAssertNotNil(weakChildStore)
}

func test_WhenStoreObjectReleased_ThenChildStoreIsReleased() {
weak var weakChildStore: ChildStore?
var referencedStore: StateStore<StateComposition, Action>?

autoreleasepool {
let strongChildStore = rootStore.createChildStore(
assertDeallocated {
var referencedStore: StateStore<StateComposition, Action>?
let strongChildStore = self.rootStore.createChildStore(
initialState: ChildTestState(currentIndex: 0),
stateMapping: { state, childState in
StateComposition(state: state, childState: childState)
},
qos: .userInitiated,
reducer: { state, action in state.reduce(action: action) }
)

weakChildStore = strongChildStore

referencedStore = strongChildStore.stateStore()
return strongChildStore as AnyObject
}

referencedStore = nil
XCTAssertNil(weakChildStore)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,15 @@ final class StoreNodeChildStoreObserverRefCycleTests: XCTestCase {
)

func test_WhenStrongRefToStoreAndObserverLive_ThenReferencCycleIsCreated() {
weak var weakRefObject: ReferenceTypeState?

autoreleasepool {

assertNotDeallocated {
let object = ReferenceTypeState()
let store = rootStore.createChildStore(
let store = self.rootStore.createChildStore(
initialState: object,
stateMapping: { state, childState in childState },
qos: .userInitiated,
reducer: { state, action in state.reduce(action) }
)

weakRefObject = object

let referencedStore = store.stateStore()

Expand All @@ -39,60 +36,42 @@ final class StoreNodeChildStoreObserverRefCycleTests: XCTestCase {
}

referencedStore.subscribe(observer: observer)
return object as AnyObject
}

XCTAssertNotNil(weakRefObject)
}

func test_WhenStrongRefToStoreAndObserverDead_ThenStoreIsReleased() {
weak var weakRefObject: ReferenceTypeState?

let asyncExpectation = expectation(description: "Observer state handler")

autoreleasepool {
assertDeallocated {
let object = ReferenceTypeState()
let store = rootStore.createChildStore(
let store = self.rootStore.createChildStore(
initialState: object,
stateMapping: { state, childState in childState },
qos: .userInitiated,
reducer: { state, action in state.reduce(action) }
)

weakRefObject = object

let referencedStore = store.stateStore()

let observer = Observer<ReferenceTypeState> { _, complete in
referencedStore.dispatch(UpdateIndex(index: 1))
complete(.dead)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
asyncExpectation.fulfill()
}
}

referencedStore.subscribe(observer: observer)
}

waitForExpectations(timeout: timeout) { _ in
XCTAssertNil(weakRefObject)
return object as AnyObject
}
}

func test_WhenWeakStoreAndObserverLive_ThenStoreIsReleased() {
weak var weakRefObject: ReferenceTypeState?

autoreleasepool {
assertDeallocated {
let object = ReferenceTypeState()
let store = rootStore.createChildStore(
let store = self.rootStore.createChildStore(
initialState: object,
stateMapping: { state, childState in childState },
qos: .userInitiated,
reducer: { state, action in state.reduce(action) }
)

weakRefObject = object


let weakRefStore = store.weakRefStore()

let observer = Observer<ReferenceTypeState> { _, complete in
Expand All @@ -101,8 +80,7 @@ final class StoreNodeChildStoreObserverRefCycleTests: XCTestCase {
}

store.subscribe(observer: observer)
return object as AnyObject
}

XCTAssertNil(weakRefObject)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,47 @@ import XCTest
final class StoreNodeRootStoreRefCyclesTests: XCTestCase {

func test_WhenWeakRefStore_ThenWeakRefToRootCreated() {
weak var weakRootStore: RootStoreNode<TestState, Action>?
var store: Store<TestState, Action>?

autoreleasepool {
assertDeallocated {
let rootStore = RootStoreNode<TestState, Action>.initRootStore(
initialState: TestState(currentIndex: 1)) { state, action in

state.reduce(action: action)
}

weakRootStore = rootStore
store = rootStore.weakRefStore()
return rootStore as AnyObject
}

XCTAssertNil(weakRootStore)
}

func test_WhenStoreExists_ThenStrongRefToRootCreated() {
weak var weakRootStore: RootStoreNode<TestState, Action>?
var store: StateStore<TestState, Action>?

autoreleasepool {
assertNotDeallocated {
let rootStore = RootStoreNode<TestState, Action>.initRootStore(
initialState: TestState(currentIndex: 1)) { state, action in

state.reduce(action: action)
}

weakRootStore = rootStore
store = rootStore.stateStore()
return rootStore as AnyObject
}

XCTAssertNotNil(weakRootStore)
}

func test_WhenStoreRemoved_ThenRootStoreIsReleased() {
weak var weakRootStore: RootStoreNode<TestState, Action>?
var store: StateStore<TestState, Action>?

autoreleasepool {
assertDeallocated {
var store: StateStore<TestState, Action>?
let rootStore = RootStoreNode<TestState, Action>.initRootStore(
initialState: TestState(currentIndex: 1)) { state, action in

state.reduce(action: action)
}

weakRootStore = rootStore
store = rootStore.stateStore()
store = nil
return rootStore as AnyObject
}

XCTAssertNotNil(weakRootStore)
store = nil
XCTAssertNil(weakRootStore)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,45 @@ final class ChildStorePresenterRefCycleTests: XCTestCase {

func test_WhenStrongRefToVC_ThenStrongRefToChildStoreState() {
var strongViewController: StubViewController?
weak var weakRefObject: ReferenceTypeState?

autoreleasepool {
assertNotDeallocated {
let object = ReferenceTypeState()

let store = factory.childStore(
let store = self.factory.childStore(
initialState: object,
reducer: { state, action in state.reduce(action) }
)

weakRefObject = object


let viewController = StubViewController()

viewController.with(store: store,
props: { _, _ in .init(title: "") }
)
viewController.viewDidLoad()
strongViewController = viewController
return object as AnyObject
}

XCTAssertNotNil(weakRefObject)
}

func test_WhenNoStrongRefToVC_ThenChildStoreStateIsReleased() {
weak var weakRefObject: ReferenceTypeState?
weak var weakViewController: StubViewController?

autoreleasepool {
assertDeallocated {
let object = ReferenceTypeState()

let store = factory.childStore(
let store = self.factory.childStore(
initialState: object,
reducer: { state, action in state.reduce(action) }
)

weakRefObject = object

let viewController = StubViewController()

viewController.with(store: store,
props: { _, _ in .init(title: "") }
)
viewController.viewDidLoad()

weakViewController = viewController
return object as AnyObject
}

XCTAssertNil(weakRefObject)
}
}
Loading

0 comments on commit 3fa8b78

Please sign in to comment.