Skip to content

Commit 073d24b

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-sharing-docs
2 parents a219f04 + 688802c commit 073d24b

32 files changed

+103
-48
lines changed

Examples/SyncUps/SyncUps/Dependencies/SpeechRecognizer.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,12 @@ extension SpeechClient: DependencyKey {
3333
}
3434

3535
static var previewValue: SpeechClient {
36-
let isRecording = LockIsolated(false)
37-
return Self(
36+
Self(
3837
authorizationStatus: { .authorized },
3938
requestAuthorization: { .authorized },
4039
startTask: { _ in
4140
AsyncThrowingStream { continuation in
4241
Task { @MainActor in
43-
isRecording.setValue(true)
4442
var finalText = """
4543
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \
4644
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
@@ -50,7 +48,7 @@ extension SpeechClient: DependencyKey {
5048
officia deserunt mollit anim id est laborum.
5149
"""
5250
var text = ""
53-
while isRecording.value {
51+
while !finalText.isEmpty {
5452
let word = finalText.prefix { $0 != " " }
5553
try await Task.sleep(for: .milliseconds(word.count * 50 + .random(in: 0...200)))
5654
finalText.removeFirst(word.count)

Sources/ComposableArchitecture/Documentation.docc/Articles/FAQ.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ However, one does not need to have any prior experience with these concepts. The
217217
[dependency-management-article]: <doc:DependencyManagement>
218218
[sharing-state-article]: <doc:SharingState>
219219
[navigation-article]: <doc:Navigation>
220-
[testing-article]: <doc:Testing>
220+
[testing-article]: <doc:TestingTCA>
221221
[migration-1.7-article]: <doc:MigratingTo1.7>
222222
[migration-1.10-article]: <doc:MigratingTo1.10>
223223
[sync-ups-tutorial]: <doc:BuildingSyncUps>

Sources/ComposableArchitecture/Documentation.docc/Articles/GettingStarted.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ doing much additional work.
252252

253253
## Testing your feature
254254

255-
> Note: For more in-depth information on testing, see the dedicated <doc:Testing>
255+
> Note: For more in-depth information on testing, see the dedicated <doc:TestingTCA>
256256
article.
257257

258258
To test use a `TestStore`, which can be created with the same information as the `Store`, but it
@@ -464,7 +464,7 @@ let store = TestStore(initialState: Feature.State()) {
464464

465465
That is the basics of building and testing a feature in the Composable Architecture. There are
466466
_a lot_ more things to be explored. Be sure to check out the <doc:MeetComposableArchitecture>
467-
tutorial, as well as dedicated articles on <doc:DependencyManagement>, <doc:Testing>,
467+
tutorial, as well as dedicated articles on <doc:DependencyManagement>, <doc:TestingTCA>,
468468
<doc:Navigation>, <doc:Performance>, and more. Also, the [Examples][examples] directory has
469469
a bunch of projects to explore to see more advanced usages.
470470

Sources/ComposableArchitecture/Documentation.docc/Articles/SharingState.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ Shared state behaves quite a bit different from the regular state held in Compos
485485
features. It is capable of being changed by any part of the application, not just when an action is
486486
sent to the store, and it has reference semantics rather than value semantics. Typically references
487487
cause serious problems with testing, especially exhaustive testing that the library prefers (see
488-
<doc:Testing>), because references cannot be copied and so one cannot inspect the changes
488+
<doc:TestingTCA>), because references cannot be copied and so one cannot inspect the changes
489489
before and after an action is sent.
490490

491491
For this reason, the `@Shared` property wrapper does extra work during testing to preserve a
@@ -691,11 +691,11 @@ func basics() {
691691
However, if your test suite is a part of an app target, then the entry point of the app will execute
692692
and potentially cause an early access of `@Shared`, thus capturing a different default value than
693693
what is specified above. This quirk of tests in app targets is documented in
694-
<doc:Testing#Testing-gotchas> of the <doc:Testing> article, and a similar quirk
694+
<doc:TestingTCA#Testing-gotchas> of the <doc:TestingTCA> article, and a similar quirk
695695
exists for Xcode previews and is discussed below in <doc:SharingState#Gotchas-of-Shared>.
696696

697697
The most robust workaround to this issue is to simply not execute your app's entry point when tests
698-
are running, which we detail in <doc:Testing#Testing-host-application>. This makes it so that you
698+
are running, which we detail in <doc:TestingTCA#Testing-host-application>. This makes it so that you
699699
are not accidentally execute network requests, tracking analytics, etc. while running tests.
700700

701701
You can also work around this issue by simply setting the shared state again after initializing
@@ -1050,3 +1050,62 @@ extension AppState: Codable {
10501050
}
10511051
}
10521052
```
1053+
1054+
#### Previews
1055+
1056+
When a preview is run in an app target, the entry point is also created. This means if your entry
1057+
point looks something like this:
1058+
1059+
```swift
1060+
@main
1061+
struct MainApp: App {
1062+
let store = Store()
1063+
1064+
var body: some Scene {
1065+
1066+
}
1067+
}
1068+
```
1069+
1070+
then a store will be created each time you run your preview. This can be problematic with `@Shared`
1071+
and persistence strategies because the first access of a `@Shared` property will use the default
1072+
value provided, and that will cause `@Shared`'s created later to ignore the default. That will mean
1073+
you cannot override shared state in previews.
1074+
1075+
The fix is to delay creation of the store until the entry point's `body` is executed. Further, it
1076+
can be a good idea to also not run the `body` when in tests because that can also interfere with
1077+
tests (as documented in <doc:TestingTCA#Testing-gotchas>). Here is one way this can be accomplished:
1078+
1079+
```swift
1080+
import ComposableArchitecture
1081+
import SwiftUI
1082+
1083+
@main
1084+
struct MainApp: App {
1085+
@MainActor
1086+
static let store = Store()
1087+
1088+
var body: some Scene {
1089+
WindowGroup {
1090+
if isTesting {
1091+
// NB: Don't run application in tests to avoid interference
1092+
// between the app and the test.
1093+
EmptyView()
1094+
} else {
1095+
AppView(store: Self.store)
1096+
}
1097+
}
1098+
}
1099+
}
1100+
```
1101+
1102+
Alternatively you can take an extra step to override shared state in your previews:
1103+
1104+
```swift
1105+
#Preview {
1106+
@Shared(.appStorage("isOn")) var isOn = true
1107+
isOn = true
1108+
}
1109+
```
1110+
1111+
The second assignment of `isOn` will guarantee that it holds a value of `true`.

Sources/ComposableArchitecture/Documentation.docc/Articles/StackBasedNavigation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ with the parent.
350350
## Testing
351351
352352
A huge benefit of using the tools of this library to model navigation stacks is that testing becomes
353-
quite easy. Further, using "non-exhaustive testing" (see <doc:Testing#Non-exhaustive-testing>) can
353+
quite easy. Further, using "non-exhaustive testing" (see <doc:TestingTCA#Non-exhaustive-testing>) can
354354
be very useful for testing navigation since you often only want to assert on a few high level
355355
details and not all state mutations and effects.
356356
@@ -537,11 +537,11 @@ other in a navigation stack.
537537
However, the more complex the features become, the more cumbersome testing their integration can be.
538538
By default, ``TestStore`` requires us to be exhaustive in our assertions. We must assert on how
539539
every piece of state changes, how every effect feeds data back into the system, and we must make
540-
sure that all effects finish by the end of the test (see <doc:Testing> for more info).
540+
sure that all effects finish by the end of the test (see <doc:TestingTCA> for more info).
541541

542542
But ``TestStore`` also supports a form of testing known as "non-exhaustive testing" that allows you
543543
to assert on only the parts of the features that you actually care about (see
544-
<doc:Testing#Non-exhaustive-testing> for more info).
544+
<doc:TestingTCA#Non-exhaustive-testing> for more info).
545545

546546
For example, if we turn off exhaustivity on the test store (see ``TestStore/exhaustivity``) then we
547547
can assert at a high level that when the increment button is tapped twice that eventually we receive
File renamed without changes.

Sources/ComposableArchitecture/Documentation.docc/Articles/TreeBasedNavigation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ the child domain without explicitly communicating with the parent.
512512
## Testing
513513
514514
A huge benefit of properly modeling your domains for navigation is that testing becomes quite easy.
515-
Further, using "non-exhaustive testing" (see <doc:Testing#Non-exhaustive-testing>) can be very
515+
Further, using "non-exhaustive testing" (see <doc:TestingTCA#Non-exhaustive-testing>) can be very
516516
useful for testing navigation since you often only want to assert on a few high level details and
517517
not all state mutations and effects.
518518
@@ -626,11 +626,11 @@ other.
626626
However, the more complex the features become, the more cumbersome testing their integration can be.
627627
By default, ``TestStore`` requires us to be exhaustive in our assertions. We must assert on how
628628
every piece of state changes, how every effect feeds data back into the system, and we must make
629-
sure that all effects finish by the end of the test (see <doc:Testing> for more info).
629+
sure that all effects finish by the end of the test (see <doc:TestingTCA> for more info).
630630

631631
But ``TestStore`` also supports a form of testing known as "non-exhaustive testing" that allows you
632632
to assert on only the parts of the features that you actually care about (see
633-
<doc:Testing#Non-exhaustive-testing> for more info).
633+
<doc:TestingTCA#Non-exhaustive-testing> for more info).
634634

635635
For example, if we turn off exhaustivity on the test store (see ``TestStore/exhaustivity``) then we
636636
can assert at a high level that when the increment button is tapped twice that eventually we receive

Sources/ComposableArchitecture/Documentation.docc/ComposableArchitecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ day-to-day when building applications, such as:
4949

5050
- <doc:GettingStarted>
5151
- <doc:DependencyManagement>
52-
- <doc:Testing>
52+
- <doc:TestingTCA>
5353
- <doc:Navigation>
5454
- <doc:SharingState>
5555
- <doc:Performance>
@@ -70,7 +70,7 @@ day-to-day when building applications, such as:
7070
### Testing
7171

7272
- ``TestStore``
73-
- <doc:Testing>
73+
- <doc:TestingTCA>
7474

7575
### Integrations
7676

Sources/ComposableArchitecture/Documentation.docc/Extensions/Deprecations/StoreDeprecations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ instead.
1515

1616
### UIKit integration
1717

18-
- ``ifLet(then:else:)``
18+
- ``Store/ifLet(then:else:)``

Sources/ComposableArchitecture/Documentation.docc/Extensions/Effect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
- ``cancellable(id:cancelInFlight:)``
1616
- ``cancel(id:)``
17-
- ``withTaskCancellation(id:cancelInFlight:operation:)``
17+
- ``ComposableArchitecture/withTaskCancellation(id:cancelInFlight:isolation:operation:)``
1818
- ``_Concurrency/Task/cancel(id:)``
1919

2020
### Composition

0 commit comments

Comments
 (0)