Skip to content

Commit 63a0795

Browse files
Simple SyncUp tutorial fixes (#3141)
* Typo, heirarchy -> hierarchy * Typo: recursive -> recursively * Typo: comes -> combines * Typo: is -> to be * Typo: add -> we added * Typo: 3 -> 2 * Adding a note to avoid confusion * Add more detail to step * Remove stray whitespace causing a diff to incorrectly display * Removed step documentation for unused code * Typo: apart -> a part * Typo: reducer -> reducers * Add missing mock * Fix mainactor placement * Fix transcript param not compiling * Add durationPerAttendee to be usable * Undo a whitespace change * Delete commented-out code * Update Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/06-SyncUpDetail/EditingAndDeletingSyncUp.tutorial * Update Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/05-PersistingSyncUps/PersistingSyncUps.tutorial * Update Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/07-SyncUpDetailNavigation/MeetingNavigation-01-code-0003.swift --------- Co-authored-by: Stephen Celis <[email protected]>
1 parent 1d29522 commit 63a0795

28 files changed

+51
-148
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ func testFeature() {
680680
}
681681
```
682682

683-
However, if your test suite is apart of an app target, then the entry point of the app will execute
683+
However, if your test suite is a part of an app target, then the entry point of the app will execute
684684
and potentially cause an early access of `@Shared`, thus capturing a different default value than
685685
what is specified above. This quirk of tests in app targets is documented in
686686
<doc:Testing#Testing-gotchas> of the <doc:Testing> article, and a similar quirk exists for Xcode

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/02-ListsOfSyncUps/ListsOfSyncUps-01-code-0002.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ struct SyncUp: Equatable, Identifiable, Codable {
88
var meetings: [Meeting] = []
99
var theme: Theme = .bubblegum
1010
var title = ""
11+
12+
var durationPerAttendee: Duration {
13+
duration / attendees.count
14+
}
1115
}
1216

1317
struct Attendee: Equatable, Identifiable, Codable {

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/02-ListsOfSyncUps/ListsOfSyncUps-01-code-0003.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ struct SyncUp: Equatable, Identifiable, Codable {
99
var meetings: IdentifiedArrayOf<Meeting> = []
1010
var theme: Theme = .bubblegum
1111
var title = ""
12+
13+
var durationPerAttendee: Duration {
14+
duration / attendees.count
15+
}
1216
}
1317

1418
struct Attendee: Equatable, Identifiable, Codable {

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/02-ListsOfSyncUps/ListsOfSyncUps-01-code-0004.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ struct SyncUp: Equatable, Identifiable, Codable {
1010
var meetings: IdentifiedArrayOf<Meeting> = []
1111
var theme: Theme = .bubblegum
1212
var title = ""
13+
14+
var durationPerAttendee: Duration {
15+
duration / attendees.count
16+
}
1317
}
1418

1519
struct Attendee: Equatable, Identifiable, Codable {

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/02-ListsOfSyncUps/ListsOfSyncUps.tutorial

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -52,51 +52,7 @@
5252
[identified-array-gh]: http://github.com/pointfreeco/swift-identified-collections
5353

5454
@Code(name: "Models.swift", file: ListsOfSyncUps-01-code-0003.swift)
55-
}
56-
57-
<!--
58-
NB: Removing the Tagged discussion for now because it was too confusing for readers.
59-
60-
There's another improvement that can be made to our domain models, but this one is completely
61-
optional.
62-
63-
Right now all of the IDs of our models are `UUID`. This means it is technically possible to
64-
do something non-sensical like check if a `syncUp.id` is equal to an `attendee.id`. That is
65-
never a valid thing to do, and so it would be ideal if we could detect that at _compile time_,
66-
rather than runtime.
67-
68-
We can do this by leveraging one of our other libraries, [Tagged][tagged-gh]. This library
69-
does not automatically come with the Composable Architecture, and so you will need to add it,
70-
and these next steps are completely optional for the purpose of this tutorial.
71-
72-
[tagged-gh]: http://github.com/pointfreeco/swift-tagged
73-
74-
@Step {
75-
Add the `Tagged` library to your project by navigating to the build settings, and then to
76-
the package dependencies tab, and input the GitHub URL:
77-
[https://github.com/pointfreeco/swift-tagged](https://github.com/pointfreeco/swift-tagged).
78-
79-
@Image(source: syncups-02-package-dependencies-tagged.png)
80-
}
81-
82-
@Step {
83-
Go back to Models.swift, and import the `Tagged` library, and upgrade all usages of a plain
84-
`UUID` to be a tagged `UUID`.
85-
86-
> Note: The tag can even just be `Self`, but you can also have multiple tagged values in a
87-
> model by created dedicated tagged types. See the [Tagged repo][tag-collisions-gh] for more
88-
> information.
89-
90-
[tag-collisions-gh]: https://github.com/pointfreeco/swift-tagged#handling-tag-collisions
91-
92-
@Code(name: "Models.swift", file: ListsOfSyncUps-01-code-0004.swift)
93-
}
94-
> Important: To keep things simple for the rest of this tutorial we will _not_ assume that
95-
you have implemented the `Tagged` type into your domain. If you choose to use `Tagged` then
96-
you will need to do some extra work to construct tagged values that is not covered in
97-
the tutorial. For example, once we get to using dependencies to control UUIDs, you will need
98-
to write `Attendee.ID(uuid())` instead of just `uuid()`.
99-
-->
55+
}
10056
}
10157
}
10258

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/04-PresentingSyncUpForm/PresentingSyncUpForm.tutorial

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

8383
That is all it takes to integrate two features together using the tools from the
8484
Composable Architecture. Notice that we have not yet mentioned _how_ we want the
85-
`SyncUpFormView` is presented, _e.g._ as a sheet, popover, full-screen cover, or something
85+
`SyncUpFormView` to be presented, _e.g._ as a sheet, popover, full-screen cover, or something
8686
else? The reducer does not care about that detail. It only cares about the domain modeling of
8787
the optional feature. You do not need to decide the _type_ of navigation until you implement
8888
the view layer.

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/05-PersistingSyncUps/PersistingSyncUps.tutorial

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
Go back to the SyncUpsList.swift file, and start by applying the [`@Shared`](<doc:Shared>)
1717
property wrapper to the `syncUps` field.
1818

19+
> Note: Our changes will not compile right now, but they will soon.
20+
1921
@Code(name: "SyncUpsList.swift", file: PersistingSyncUps-01-code-0001.swift, previousFile: PersistingSyncUps-01-code-0001-previous.swift)
2022
}
2123

@@ -51,7 +53,7 @@
5153

5254
With that change the project should be compiling. It is worth noting that
5355
``ComposableArchitecture/PersistenceReaderKey/fileStorage(_:)`` only works with `Codable` data
54-
types, and earlier in the tutorial when add models to Models.swift we made them codable from
56+
types, and earlier in the tutorial when we added models to Models.swift we made them codable from
5557
the beginning.
5658

5759
To confirm that persistence works we need to run the app in the simulator, but we haven't done

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/06-SyncUpDetail/EditingAndDeletingSyncUp.tutorial

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155

156156
> Note: We are pre-emptively applying the `@CasePathable` macro to make it possible to write
157157
tests against these actions in a keypath-like syntax. The `@CasePathable` macro is
158-
automatically applied to `Action` enums inside reducers, but macros cannot recursive apply
158+
automatically applied to `Action` enums inside reducers, but macros cannot recursively apply
159159
themselves and so we must do it manually sometimes.
160160

161161
@Code(name: "SyncUpDetail.swift", file: EditingAndDeletingSyncUp-02-code-0001.swift, previousFile: EditingAndDeletingSyncUp-02-code-0001-previous.swift)
@@ -184,7 +184,8 @@
184184
}
185185

186186
@Step {
187-
Use the ``ComposableArchitecture/Reducer/ifLet(_:action:then:fileID:line:)-42kki`` operator
187+
Handle the `.alert` case in the reducer, and use the
188+
``ComposableArchitecture/Reducer/ifLet(_:action:then:fileID:line:)-42kki`` operator
188189
again to integrate the alert's logic into the `SyncUpDetail` reducer.
189190

190191
@Code(name: "SyncUpDetail.swift", file: EditingAndDeletingSyncUp-02-code-0004.swift)

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/06-SyncUpDetail/SyncUpDetail.tutorial

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
}
3838

3939
Next we add a case to the `Action` enum for each action the user can perform in the view.
40-
Currently there are 3 buttons, and so we will have an action for each.
40+
Currently there are 2 buttons, and so we will have an action for each.
4141

4242
@Step {
4343
Add an action for each of the buttons in the UI, including tapping the "Delete" button,

Sources/ComposableArchitecture/Documentation.docc/Tutorials/BuildingSyncUps/06-SyncUpDetail/TestingSyncUpDetail.tutorial

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@
4646

4747
@Step {
4848
Assert how the state changes after sending the action. In particular, the `syncUp` data
49-
inside the `edit` case of the destination should change. We can use the special
50-
``ComposableArchitecture/PresentationState/subscript(case:)-7uqte`` defined on
51-
`$destination` to modify the data in a particular case.
49+
inside the `edit` case of the destination should change.
5250

5351
Run the test suite again to confirm that everything still passes.
5452

@@ -71,79 +69,5 @@
7169
It is also possible to shorten this test quite a bit by using a non-exhaustive test store, as
7270
we did in <doc:PresentingSyncUpForm>, but we will leave that as an exercise for the reader.
7371
}
74-
}
75-
76-
<!--
77-
This is all old now that we are using @Shared and deleting directly in the reducer. We can
78-
either omit this or update it.
79-
80-
@Section(title: "Testing the delete flow") {
81-
@ContentAndMedia {
82-
Next we will test the flow of the user deleting the sync-up. This involves asserting that the
83-
confirmation alert shows, and emulating the user interacting with the alert.
84-
}
85-
86-
@Steps {
87-
@Step {
88-
Create a new test method for testing the delete user flow. Also create a
89-
``ComposableArchitecture/TestStore`` for the `SyncUpDetail` feature.
90-
91-
@Code(name: "SyncUpDetailTests.swift", file: TestingSyncUpDetail-02-code-0001.swift, previousFile: TestingSyncUpDetail-02-code-0001-previous.swift)
92-
}
93-
94-
@Step {
95-
Emulate the user tapping the "Delete" button and assert that the alert state is populated.
96-
97-
Run the test suite to confirm that it passes.
98-
99-
@Code(name: "SyncUpDetailTests.swift", file: TestingSyncUpDetail-02-code-0002.swift)
100-
}
101-
102-
@Step {
103-
Emulate the user confirming deletion of the sync-up by sending a deeply nested action to the
104-
`.destination`, when it is `.presented`, in the `.alert` case, and then finally the
105-
`.confirmButtonTapped` action. Also assert that the alert will be dismissed by setting the
106-
`destination` state to `nil`.
107-
108-
TODO: Make alert action case-pathable
109-
110-
@Code(name: "SyncUpDetailTests.swift", file: TestingSyncUpDetail-02-code-0003.swift)
111-
}
112-
113-
@Step {
114-
Run the test suite again to see that now it does _not_ pass. We have a test failure.
115-
116-
@Code(name: "SyncUpDetailTests.swift", file: TestingSyncUpDetail-02-code-0004.swift)
117-
}
118-
119-
This failure is happening because we are now making use effects that emit actions, and by
120-
default the ``ComposableArchitecture/TestStore`` forces us to assert on _everything_ happening
121-
in the feature. This is really great because it helps us catch potential problems when new
122-
logic and behavior is added to our features.
123-
124-
The failure is letting us know that the system received an action that we did not
125-
assert against. This is also a great failure to have because it forces us to prove that we
126-
know how effects execute and feed their data back in the system.
127-
128-
Let's fix this test failure by asserting on more of what is happening in the system.
129-
130-
@Step {
131-
Use the ``ComposableArchitecture/TestStore/receive(_:_:timeout:assert:file:line:)-dkei``
132-
method to assert that we expect to receive a delegate action to delete the sync-up.
133-
134-
Run the test suite to see that one of the previous two test failures has now been fixed.
135-
136-
> Note: We are using case key path composition in order to describe the deeply nested action
137-
> that is being received.
138-
139-
@Code(name: "SyncUpDetailTests.swift", file: TestingSyncUpDetail-02-code-0005.swift)
140-
}
141-
142-
Now that this test passes we have definitively proven that
143-
the `.deleteSyncUp` delegate action is sent when the user confirms deletion of the sync-up.
144-
That will communicate to the parent that it should finish deleting the sync-up _and_ it should
145-
dismiss the presented sheet.
146-
}
147-
}
148-
-->
72+
}
14973
}

0 commit comments

Comments
 (0)