Skip to content

Commit abd82f2

Browse files
authored
Mark ModifiedAtom Scoped if the base atom is Scoped (#137)
* Mark ModifiedAtom Scoped if the base atom is Scoped * Fix compiler crash
1 parent cfc3924 commit abd82f2

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

Sources/Atoms/Core/Atom/ModifiedAtom.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,10 @@ extension ModifiedAtom: AsyncAtom where Node: AsyncAtom, Modifier: AsyncAtomModi
5858
modifier.refreshProducer(atom: atom)
5959
}
6060
}
61+
62+
extension ModifiedAtom: Scoped where Node: Scoped {
63+
/// A scope ID which is to find a matching scope.
64+
public var scopeID: Node.ScopeID {
65+
atom.scopeID
66+
}
67+
}

Tests/AtomsTests/Attribute/ScopedTests.swift

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,33 @@ final class ScopedTests: XCTestCase {
3838
overrides: [:]
3939
)
4040
let atom = ScopedAtom(scopeID: DefaultScopeID(), value: 0)
41-
let atomScope1Key = AtomKey(atom, scopeKey: scope1Key)
42-
let atomScope2Key = AtomKey(atom, scopeKey: scope2Key)
41+
let scoped1AtomKey = AtomKey(atom, scopeKey: scope1Key)
42+
let scoped2AtomKey = AtomKey(atom, scopeKey: scope2Key)
4343

4444
XCTAssertEqual(
4545
scoped1Context.watch(atom, subscriber: subscriber, subscription: Subscription()),
4646
0
4747
)
4848
XCTAssertEqual(
49-
store.state.caches[atomScope1Key] as? AtomCache<ScopedAtom<DefaultScopeID, Int>>,
49+
store.state.caches[scoped1AtomKey] as? AtomCache<ScopedAtom<DefaultScopeID, Int>>,
5050
AtomCache(atom: atom, value: 0)
5151
)
52-
XCTAssertNil(store.state.caches[atomScope2Key])
52+
XCTAssertNil(store.state.caches[scoped2AtomKey])
5353

5454
scoped1Context.unwatch(atom, subscriber: subscriber)
55-
XCTAssertNil(store.state.caches[atomScope1Key])
55+
XCTAssertNil(store.state.caches[scoped1AtomKey])
5656

5757
XCTAssertEqual(
5858
scoped2Context.watch(atom, subscriber: subscriber, subscription: Subscription()),
5959
0
6060
)
6161
XCTAssertEqual(
62-
store.state.caches[atomScope2Key] as? AtomCache<ScopedAtom<DefaultScopeID, Int>>,
62+
store.state.caches[scoped2AtomKey] as? AtomCache<ScopedAtom<DefaultScopeID, Int>>,
6363
AtomCache(atom: atom, value: 0)
6464
)
6565

6666
scoped2Context.unwatch(atom, subscriber: subscriber)
67-
XCTAssertNil(store.state.caches[atomScope2Key])
67+
XCTAssertNil(store.state.caches[scoped2AtomKey])
6868
}
6969

7070
XCTContext.runActivity(named: "Should be scoped in particular scope") { _ in
@@ -84,21 +84,68 @@ final class ScopedTests: XCTestCase {
8484
overrides: [:]
8585
)
8686
let atom = ScopedAtom(scopeID: scopeID, value: 0)
87-
let atomScope1Key = AtomKey(atom, scopeKey: scope1Key)
88-
let atomScope2Key = AtomKey(atom, scopeKey: scope2Key)
87+
let scoped1AtomKey = AtomKey(atom, scopeKey: scope1Key)
88+
let scoped2AtomKey = AtomKey(atom, scopeKey: scope2Key)
8989

9090
XCTAssertEqual(
9191
scoped2Context.watch(atom, subscriber: subscriber, subscription: Subscription()),
9292
0
9393
)
9494
XCTAssertEqual(
95-
store.state.caches[atomScope1Key] as? AtomCache<ScopedAtom<String, Int>>,
95+
store.state.caches[scoped1AtomKey] as? AtomCache<ScopedAtom<String, Int>>,
9696
AtomCache(atom: atom, value: 0)
9797
)
98-
XCTAssertNil(store.state.caches[atomScope2Key])
98+
XCTAssertNil(store.state.caches[scoped2AtomKey])
9999

100100
scoped2Context.unwatch(atom, subscriber: subscriber)
101-
XCTAssertNil(store.state.caches[atomScope1Key])
101+
XCTAssertNil(store.state.caches[scoped1AtomKey])
102+
}
103+
104+
XCTContext.runActivity(named: "Modified atoms should also be scoped") { _ in
105+
let store = AtomStore()
106+
let context = StoreContext(store: store)
107+
let scopeID = "Scope 1"
108+
let scoped1Context = context.scoped(
109+
scopeKey: scope1Key,
110+
scopeID: ScopeID(scopeID),
111+
observers: [],
112+
overrides: [:]
113+
)
114+
let scoped2Context = scoped1Context.scoped(
115+
scopeKey: scope2Key,
116+
scopeID: ScopeID(DefaultScopeID()),
117+
observers: [],
118+
overrides: [:]
119+
)
120+
let baseAtom = ScopedAtom(scopeID: scopeID, value: 0)
121+
let atom = baseAtom.changes
122+
let baseAtomKey = AtomKey(baseAtom, scopeKey: nil)
123+
let atomKey = AtomKey(atom, scopeKey: nil)
124+
let scoped1BaseAtomKey = AtomKey(baseAtom, scopeKey: scope1Key)
125+
let scoped1AtomKey = AtomKey(atom, scopeKey: scope1Key)
126+
let scoped2BaseAtomKey = AtomKey(baseAtom, scopeKey: scope2Key)
127+
let scoped2AtomKey = AtomKey(atom, scopeKey: scope2Key)
128+
129+
XCTAssertEqual(
130+
scoped2Context.watch(atom, subscriber: subscriber, subscription: Subscription()),
131+
0
132+
)
133+
XCTAssertEqual(
134+
(store.state.caches[scoped1BaseAtomKey] as? AtomCache<ScopedAtom<String, Int>>)?.value,
135+
0
136+
)
137+
XCTAssertEqual(
138+
(store.state.caches[scoped1AtomKey] as? AtomCache<ModifiedAtom<ScopedAtom<String, Int>, ChangesModifier<Int>>>)?.value,
139+
0
140+
)
141+
XCTAssertNil(store.state.caches[scoped2BaseAtomKey])
142+
XCTAssertNil(store.state.caches[scoped2AtomKey])
143+
XCTAssertNil(store.state.caches[baseAtomKey])
144+
XCTAssertNil(store.state.caches[atomKey])
145+
146+
scoped2Context.unwatch(atom, subscriber: subscriber)
147+
XCTAssertNil(store.state.caches[scoped1BaseAtomKey])
148+
XCTAssertNil(store.state.caches[scoped1AtomKey])
102149
}
103150
}
104151
}

0 commit comments

Comments
 (0)