Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ref-Cycle flaky tests fix #36

Merged
merged 4 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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