Runtime warnings are not test helpers that should propagate XCTest
failures to the original file/line, so we should always omit that
information. This leads to better test failures that show up alongside
the test, not buried in application code.
* Pass state to `SwitchStore.init` view builder
Rather than rely on many, many overloads of `SwitchStore.init` to
strictly accept only `CaseLet`s and an optional, final `Default` view,
let's introduce a single initializer without constraints that is passed
the current state whenever the case changes. This state can be switched
on and route to the appropriate view via `CaseLet`.
The pros:
* We get exhaustive switching at compile time.
* We get more flexibility in the view layer. Previously, any
customization needed to be pushed into the `CaseLet` builder, but
now `CaseLet` can freely apply view modifiers.
* We can deprecate and eventually remove the many, many initializer
overloads, and hopefully slim down binary size in the process, and
improve view builder compile times when dealing with `SwitchStore`.
We can also deprecate and eventually remove `Default`.
The cons:
* It's slightly more verbose and repetitive. You have a `SwitchStore`
and then a `switch` inside it with many `case`s with `CaseLet`s
inside them, and the `case .screen:` is followed by
`CaseLet(/State.screen, ...)`.
* One is free to extract the state's associated value(s) and use it to
render a view, but this view will be inert and will not re-render if
the value it depends on changes in the store. This can lead to some
surprises, but we can document against the pattern, and maybe in the
future we can use something like macros to prevent this from being
possible.
* You can still get things wrong if you're not careful: there's
nothing enforcing that the `case` you switch on is the same case you
send to `CaseLet`, so `case .screenA: CaseLet(/State.screenB, ...)`
is possible. While unlikely, it's still a copy-paste error in
waiting.
* wip
* wip
* wip
* Bump
* fix test
* clean up
* clean up
* clean up
* wip
---------
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* Don't disable `_printChanges()` in tests
It can be handy to have this logging during a test, so let's not go out of our way to suppress it.
* Update DebugReducer.swift
We are looking to deprecate TCA's dependence on Combine, _e.g._ the
direct conformance of `Effect` to `Publisher`, as well as many
Combine-centric APIs, but that doesn't mean we want to eliminate support
for using Combine with TCA. Our current advice given by our soft
deprecations is to iterate over `publisher.values`, but this is
unavailable in iOS 13 and 14, so let's introduce a dedicated bridging
mechanism, instead.
* Rollback to a top level `Send`
* Rename `EffectSend` as `Send`
* Add a `Sendable` typealias to `ReducerProtocol`
* Revert "Add a `Sendable` typealias to `ReducerProtocol`"
This reverts commit d808d3c916.
---------
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
* Make the new XCTModify play nicely with non-exhaustive testing.
* wip
* Update Tests/ComposableArchitectureTests/TestStoreNonExhaustiveTests.swift
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
---------
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
* Warn if send called after effect completes
When an Effect.run is converted into a publisher, we already end up discarding `send`s sent after returning. Similarly, `*Task.finish()` will fail to track send()s after other in-flight effects complete. This is effectively UB so let's warn about it.
* Fix tests
* we don't need to print TestAction yet
* Tweak messaging and tests.
* fix tests
* wip
* fix tests part 2
* fix tests part 3
* Wrap testCancellation test in _withMainSerialExecutor
* Update Publisher.swift
---------
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
Co-authored-by: Stephen Celis <stephen.celis@gmail.com>
* Improve expected action test store failure message
We currently interpolate the action directly, which prints in a pretty
crude format that becomes almost incomprehensible for deeply nested
actions (common in "integration" tests). So let's leverage Custom Dump
instead!
* Bump
* Make Store.filter internal
We're seeing that `@_spi` can still come up in autocomplete. Now Xcode
surfaces internal stuff too occasionally, but maybe this will suppress
it a bit.
* wip
* fix
* `IfLetStore`: ignore view store binding writes to `nil` state
* swift-format
* wip
* add test for filter
---------
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* Add note to reducer protocol dependency section
The discussion #1870 noted that our migration guide could include more
of a breadcrumb that migrating to the Dependencies library isn't a
simple matter of changing every environment property to a `@Dependency`
property.
* wip
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* Add `Effect.send`
With the `Effect<Action, Failure>` -> `Effect<Action>` migration,
`Effect.init(value:)` and `Effect.init(error:)` no longer make sense. We
will be retiring the latter some time in the future, so let's also get a
head start and rename the former to `Effect.send`.
For now it will call `Effect.init(value:)` under the hood, but in the
future we will want a non-Combine-driven way of running synchronous
effects.
* format fix
* wip
* fix
* wip
* wip