Files
swift-composable-architectu…/Examples/Todos/TodosTests/TodosTests.swift
Stephen Celis 85417e000e Update documentation and examples to use Swift Testing (#3413)
* Testing: Case Studies

* Testing: Search

* Testing: Speech Recognition

* Testing: SyncUps

* Project Settings

* Testing: TicTacToe

* Testing: Todos

* Testing: Voice Memos

* Update tutorials/docs

* fix

* Fixes

* wip

* Update ci.yml

* Update ci.yml

* Update ci.yml

* wip

* wip

* Quiet

* fix

* wip

* wip

* flaky

* wip

* wip

* fix
2024-10-02 16:28:33 -07:00

356 lines
7.0 KiB
Swift

import ComposableArchitecture
import Foundation
import Testing
@testable import Todos
@MainActor
struct TodosTests {
let clock = TestClock()
@Test
func add() async {
let store = TestStore(initialState: Todos.State()) {
Todos()
} withDependencies: {
$0.uuid = .incrementing
}
await store.send(.addTodoButtonTapped) {
$0.todos.insert(
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
at: 0
)
}
await store.send(.addTodoButtonTapped) {
$0.todos = [
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
]
}
}
@Test
func edit() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
)
]
)
let store = TestStore(initialState: state) {
Todos()
}
await store.send(\.todos[id: UUID(0)].binding.description, "Learn Composable Architecture") {
$0.todos[id: UUID(0)]?.description = "Learn Composable Architecture"
}
}
@Test
func complete() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
]
)
let store = TestStore(initialState: state) {
Todos()
} withDependencies: {
$0.continuousClock = clock
}
await store.send(\.todos[id: UUID(0)].binding.isComplete, true) {
$0.todos[id: UUID(0)]?.isComplete = true
}
await clock.advance(by: .seconds(1))
await store.receive(\.sortCompletedTodos) {
$0.todos = [
$0.todos[1],
$0.todos[0],
]
}
}
@Test
func completionDebounce() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
]
)
let store = TestStore(initialState: state) {
Todos()
} withDependencies: {
$0.continuousClock = clock
}
await store.send(\.todos[id: UUID(0)].binding.isComplete, true) {
$0.todos[id: UUID(0)]?.isComplete = true
}
await clock.advance(by: .milliseconds(500))
await store.send(\.todos[id: UUID(0)].binding.isComplete, false) {
$0.todos[id: UUID(0)]?.isComplete = false
}
await clock.advance(by: .seconds(1))
await store.receive(\.sortCompletedTodos)
}
@Test
func clearCompleted() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: true
),
]
)
let store = TestStore(initialState: state) {
Todos()
}
await store.send(.clearCompletedButtonTapped) {
$0.todos = [
$0.todos[0]
]
}
}
@Test
func delete() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
Todo.State(
description: "",
id: UUID(2),
isComplete: false
),
]
)
let store = TestStore(initialState: state) {
Todos()
}
await store.send(.delete([1])) {
$0.todos = [
$0.todos[0],
$0.todos[2],
]
}
}
@Test
func filteredDelete() async {
let state = Todos.State(
filter: .completed,
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
Todo.State(
description: "",
id: UUID(2),
isComplete: true
),
]
)
let store = TestStore(initialState: state) {
Todos()
}
await store.send(.delete([0])) {
$0.todos = [
$0.todos[0],
$0.todos[1],
]
}
}
@Test
func editModeMove() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
Todo.State(
description: "",
id: UUID(2),
isComplete: false
),
]
)
let store = TestStore(initialState: state) {
Todos()
} withDependencies: {
$0.continuousClock = clock
}
await store.send(\.binding.editMode, .active) {
$0.editMode = .active
}
await store.send(.move([0], 2)) {
$0.todos = [
$0.todos[1],
$0.todos[0],
$0.todos[2],
]
}
await clock.advance(by: .milliseconds(100))
await store.receive(\.sortCompletedTodos)
}
@Test
func filteredEditModeMove() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: false
),
Todo.State(
description: "",
id: UUID(2),
isComplete: true
),
Todo.State(
description: "",
id: UUID(3),
isComplete: true
),
]
)
let store = TestStore(initialState: state) {
Todos()
} withDependencies: {
$0.continuousClock = clock
$0.uuid = .incrementing
}
await store.send(\.binding.editMode, .active) {
$0.editMode = .active
}
await store.send(\.binding.filter, .completed) {
$0.filter = .completed
}
await store.send(.move([0], 2)) {
$0.todos = [
$0.todos[0],
$0.todos[1],
$0.todos[3],
$0.todos[2],
]
}
await clock.advance(by: .milliseconds(100))
await store.receive(\.sortCompletedTodos)
}
@Test
func filteredEdit() async {
let state = Todos.State(
todos: [
Todo.State(
description: "",
id: UUID(0),
isComplete: false
),
Todo.State(
description: "",
id: UUID(1),
isComplete: true
),
]
)
let store = TestStore(initialState: state) {
Todos()
}
await store.send(\.binding.filter, .completed) {
$0.filter = .completed
}
await store.send(\.todos[id: UUID(1)].binding.description, "Did this already") {
$0.todos[id: UUID(1)]?.description = "Did this already"
}
}
}