Skip to content

Commit 6b4f822

Browse files
committed
test: enable t.Parallel() across non-timer unit tests
Adds t.Parallel() to 46 unit tests across 6 test files (types, validation, builder, hierarchy, snapshot, reflect). These cover pure machine construction and snapshot logic — no timer, lock, or event-store state, so parallelism is safe. Race-clean under go test -race. Skipped (intentionally sequential — shared timer / actor / lock / event-store state would race under parallel execution): delayed_test.go (already migrated to FakeClock), actor_test.go, invoke_test.go, persist_test.go, distributed_test.go, plugin_test.go, snapshot_actor_test.go, performance_bench_test.go. Source: quality review — t.Parallel sweep was top-3 leverage move. This is the safe subset; remaining files need lock/event-store isolation per package before they can parallelize.
1 parent 856247f commit 6b4f822

6 files changed

Lines changed: 46 additions & 0 deletions

File tree

builder_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type testContext struct {
1111
}
1212

1313
func TestMachineBuilder_Basic(t *testing.T) {
14+
t.Parallel()
1415
machine, err := NewMachine[testContext]("trafficLight").
1516
WithInitial("green").
1617
State("green").Done().
@@ -27,6 +28,7 @@ func TestMachineBuilder_Basic(t *testing.T) {
2728
}
2829

2930
func TestMachineBuilder_WithContext(t *testing.T) {
31+
t.Parallel()
3032
ctx := testContext{Count: 42}
3133
machine, err := NewMachine[testContext]("test").
3234
WithInitial("idle").
@@ -42,6 +44,7 @@ func TestMachineBuilder_WithContext(t *testing.T) {
4244
}
4345

4446
func TestMachineBuilder_WithStates(t *testing.T) {
47+
t.Parallel()
4548
machine, err := NewMachine[testContext]("trafficLight").
4649
WithInitial("green").
4750
State("green").
@@ -80,6 +83,7 @@ func TestMachineBuilder_WithStates(t *testing.T) {
8083
}
8184

8285
func TestMachineBuilder_FinalState(t *testing.T) {
86+
t.Parallel()
8387
machine, err := NewMachine[testContext]("workflow").
8488
WithInitial("active").
8589
State("active").
@@ -99,6 +103,7 @@ func TestMachineBuilder_FinalState(t *testing.T) {
99103
}
100104

101105
func TestMachineBuilder_WithActions(t *testing.T) {
106+
t.Parallel()
102107
actionCalled := false
103108
action := func(ctx *testContext, e Event) {
104109
actionCalled = true
@@ -151,6 +156,7 @@ func TestMachineBuilder_WithActions(t *testing.T) {
151156
}
152157

153158
func TestMachineBuilder_WithGuards(t *testing.T) {
159+
t.Parallel()
154160
guard := func(ctx testContext, e Event) bool {
155161
return ctx.Count > 0
156162
}
@@ -189,6 +195,7 @@ func TestMachineBuilder_WithGuards(t *testing.T) {
189195
}
190196

191197
func TestMachineBuilder_MultipleTransitions(t *testing.T) {
198+
t.Parallel()
192199
machine, err := NewMachine[testContext]("test").
193200
WithInitial("idle").
194201
State("idle").

hierarchy_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
// TestHierarchical_BuildNestedStates tests building a machine with nested states
88
func TestHierarchical_BuildNestedStates(t *testing.T) {
9+
t.Parallel()
910
// Structure:
1011
// active (compound)
1112
// ├── idle (atomic)
@@ -61,6 +62,7 @@ func TestHierarchical_BuildNestedStates(t *testing.T) {
6162

6263
// TestHierarchical_StartEntersLeaf tests that Start() enters the initial leaf state
6364
func TestHierarchical_StartEntersLeaf(t *testing.T) {
65+
t.Parallel()
6466
machine, err := NewMachine[struct{}]("test").
6567
WithInitial("active").
6668
State("active").
@@ -84,6 +86,7 @@ func TestHierarchical_StartEntersLeaf(t *testing.T) {
8486

8587
// TestHierarchical_StartEntersDeepLeaf tests entering a deeply nested initial leaf
8688
func TestHierarchical_StartEntersDeepLeaf(t *testing.T) {
89+
t.Parallel()
8790
machine, err := NewMachine[struct{}]("test").
8891
WithInitial("level1").
8992
State("level1").
@@ -108,6 +111,7 @@ func TestHierarchical_StartEntersDeepLeaf(t *testing.T) {
108111

109112
// TestHierarchical_MatchesAncestors tests that Matches() returns true for ancestors
110113
func TestHierarchical_MatchesAncestors(t *testing.T) {
114+
t.Parallel()
111115
machine, err := NewMachine[struct{}]("test").
112116
WithInitial("active").
113117
State("active").
@@ -146,6 +150,7 @@ func TestHierarchical_MatchesAncestors(t *testing.T) {
146150

147151
// TestHierarchical_TransitionWithinCompound tests transitions between siblings
148152
func TestHierarchical_TransitionWithinCompound(t *testing.T) {
153+
t.Parallel()
149154
machine, err := NewMachine[struct{}]("test").
150155
WithInitial("active").
151156
State("active").
@@ -184,6 +189,7 @@ func TestHierarchical_TransitionWithinCompound(t *testing.T) {
184189

185190
// TestHierarchical_TransitionToCompoundEntersLeaf tests that transitioning to a compound state enters its initial leaf
186191
func TestHierarchical_TransitionToCompoundEntersLeaf(t *testing.T) {
192+
t.Parallel()
187193
machine, err := NewMachine[struct{}]("test").
188194
WithInitial("idle").
189195
State("idle").
@@ -230,6 +236,7 @@ type orderContext struct {
230236

231237
// TestHierarchical_EntryExitOrder tests that entry/exit actions are called in correct order
232238
func TestHierarchical_EntryExitOrder(t *testing.T) {
239+
t.Parallel()
233240
machine, err := NewMachine[orderContext]("test").
234241
WithInitial("idle").
235242
WithContext(orderContext{}).
@@ -333,6 +340,7 @@ func TestHierarchical_EntryExitOrder(t *testing.T) {
333340

334341
// TestHierarchical_EventBubblesUp tests that events bubble up to parent states
335342
func TestHierarchical_EventBubblesUp(t *testing.T) {
343+
t.Parallel()
336344
machine, err := NewMachine[struct{}]("test").
337345
WithInitial("active").
338346
State("active").
@@ -375,6 +383,7 @@ func TestHierarchical_EventBubblesUp(t *testing.T) {
375383

376384
// TestHierarchical_ChildTransitionTakesPriority tests that child state transitions take priority over parent
377385
func TestHierarchical_ChildTransitionTakesPriority(t *testing.T) {
386+
t.Parallel()
378387
handled := ""
379388

380389
machine, err := NewMachine[struct{}]("test").
@@ -411,6 +420,7 @@ func TestHierarchical_ChildTransitionTakesPriority(t *testing.T) {
411420

412421
// TestHierarchical_TransitionToSibling tests transitions between siblings in a compound state
413422
func TestHierarchical_TransitionToSibling(t *testing.T) {
423+
t.Parallel()
414424
machine, err := NewMachine[orderContext]("test").
415425
WithInitial("active").
416426
WithContext(orderContext{}).

reflect_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type SimpleReflectMachine struct {
1717
}
1818

1919
func TestFromStruct_Simple(t *testing.T) {
20+
t.Parallel()
2021
registry := NewActionRegistry[ReflectTestContext]()
2122

2223
machine, err := FromStruct[SimpleReflectMachine, ReflectTestContext](registry)
@@ -63,6 +64,7 @@ type ActionReflectMachine struct {
6364
}
6465

6566
func TestFromStruct_WithActions(t *testing.T) {
67+
t.Parallel()
6668
enterIdleCalled := false
6769
exitIdleCalled := false
6870
enterRunningCalled := false
@@ -123,6 +125,7 @@ type GuardReflectMachine struct {
123125
}
124126

125127
func TestFromStruct_WithGuards(t *testing.T) {
128+
t.Parallel()
126129
canStart := false
127130

128131
registry := NewActionRegistry[ReflectTestContext]().
@@ -166,6 +169,7 @@ type FinalReflectMachine struct {
166169
}
167170

168171
func TestFromStruct_WithFinalState(t *testing.T) {
172+
t.Parallel()
169173
registry := NewActionRegistry[ReflectTestContext]()
170174

171175
machine, err := FromStruct[FinalReflectMachine, ReflectTestContext](registry)
@@ -216,6 +220,7 @@ type HierarchicalReflectMachine struct {
216220
}
217221

218222
func TestFromStruct_Hierarchical(t *testing.T) {
223+
t.Parallel()
219224
registry := NewActionRegistry[ReflectTestContext]()
220225

221226
machine, err := FromStruct[HierarchicalReflectMachine, ReflectTestContext](registry)
@@ -279,6 +284,7 @@ type ContextReflectMachine struct {
279284
}
280285

281286
func TestFromStructWithContext(t *testing.T) {
287+
t.Parallel()
282288
registry := NewActionRegistry[ReflectTestContext]().
283289
WithAction("incrementCount", func(ctx *ReflectTestContext, e Event) {
284290
ctx.Count++
@@ -311,6 +317,7 @@ func TestFromStructWithContext(t *testing.T) {
311317

312318
// Test parity with fluent builder
313319
func TestFromStruct_ParityWithBuilder(t *testing.T) {
320+
t.Parallel()
314321
// Build with fluent API
315322
builderMachine, err := NewMachine[ReflectTestContext]("traffic").
316323
WithInitial("green").
@@ -388,6 +395,7 @@ type InvalidMachine struct {
388395
}
389396

390397
func TestFromStruct_ValidationError(t *testing.T) {
398+
t.Parallel()
391399
registry := NewActionRegistry[ReflectTestContext]()
392400

393401
_, err := FromStruct[InvalidMachine, ReflectTestContext](registry)
@@ -403,6 +411,7 @@ type MissingActionMachine struct {
403411
}
404412

405413
func TestFromStruct_MissingAction(t *testing.T) {
414+
t.Parallel()
406415
registry := NewActionRegistry[ReflectTestContext]()
407416

408417
_, err := FromStruct[MissingActionMachine, ReflectTestContext](registry)
@@ -419,6 +428,7 @@ type MissingGuardMachine struct {
419428
}
420429

421430
func TestFromStruct_MissingGuard(t *testing.T) {
431+
t.Parallel()
422432
registry := NewActionRegistry[ReflectTestContext]()
423433

424434
_, err := FromStruct[MissingGuardMachine, ReflectTestContext](registry)

snapshot_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type snapshotContext struct {
1313
}
1414

1515
func TestSnapshot_Simple(t *testing.T) {
16+
t.Parallel()
1617
machine, err := NewMachine[snapshotContext]("test").
1718
WithInitial("idle").
1819
WithContext(snapshotContext{Count: 0, Name: "initial"}).
@@ -53,6 +54,7 @@ func TestSnapshot_Simple(t *testing.T) {
5354
}
5455

5556
func TestSnapshot_Restore(t *testing.T) {
57+
t.Parallel()
5658
machine, _ := NewMachine[snapshotContext]("test").
5759
WithInitial("idle").
5860
WithContext(snapshotContext{Count: 0}).
@@ -95,6 +97,7 @@ func TestSnapshot_Restore(t *testing.T) {
9597
}
9698

9799
func TestSnapshot_RestoreWithHistory(t *testing.T) {
100+
t.Parallel()
98101
machine, _ := NewMachine[struct{}]("player").
99102
WithInitial("playing").
100103
State("playing").
@@ -134,6 +137,7 @@ func TestSnapshot_RestoreWithHistory(t *testing.T) {
134137
}
135138

136139
func TestSnapshot_RestoreWithParallel(t *testing.T) {
140+
t.Parallel()
137141
machine, err := NewMachine[struct{}]("editor").
138142
WithInitial("active").
139143
State("active").Parallel().
@@ -191,6 +195,7 @@ func TestSnapshot_RestoreWithParallel(t *testing.T) {
191195
}
192196

193197
func TestSnapshot_RestoreMachineMismatch(t *testing.T) {
198+
t.Parallel()
194199
machine1, _ := NewMachine[struct{}]("machine1").
195200
WithInitial("idle").
196201
State("idle").Done().
@@ -222,6 +227,7 @@ func TestSnapshot_RestoreMachineMismatch(t *testing.T) {
222227
}
223228

224229
func TestSnapshot_RestoreInvalidState(t *testing.T) {
230+
t.Parallel()
225231
machine, _ := NewMachine[struct{}]("test").
226232
WithInitial("idle").
227233
State("idle").Done().
@@ -251,6 +257,7 @@ func TestSnapshot_RestoreInvalidState(t *testing.T) {
251257
}
252258

253259
func TestSnapshot_JSONSerialization(t *testing.T) {
260+
t.Parallel()
254261
machine, _ := NewMachine[snapshotContext]("test").
255262
WithInitial("idle").
256263
WithContext(snapshotContext{Count: 42, Name: "test"}).
@@ -290,6 +297,7 @@ func TestSnapshot_JSONSerialization(t *testing.T) {
290297
}
291298

292299
func TestSnapshot_RestoreWithDelayedTransition(t *testing.T) {
300+
t.Parallel()
293301
machine, _ := NewMachine[struct{}]("test").
294302
WithInitial("waiting").
295303
State("waiting").
@@ -324,6 +332,7 @@ func TestSnapshot_RestoreWithDelayedTransition(t *testing.T) {
324332
}
325333

326334
func TestSnapshot_RestoreCancelsExistingTimers(t *testing.T) {
335+
t.Parallel()
327336
machine, _ := NewMachine[struct{}]("test").
328337
WithInitial("state1").
329338
State("state1").
@@ -364,6 +373,7 @@ func TestSnapshot_RestoreCancelsExistingTimers(t *testing.T) {
364373
}
365374

366375
func TestRestoreError_Error(t *testing.T) {
376+
t.Parallel()
367377
err := &RestoreError{
368378
Code: "TEST_CODE",
369379
Message: "test message",

types_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package statekit
33
import "testing"
44

55
func TestState_Matches(t *testing.T) {
6+
t.Parallel()
67
state := State[struct{}]{
78
Value: "green",
89
}
@@ -17,6 +18,7 @@ func TestState_Matches(t *testing.T) {
1718
}
1819

1920
func TestStateType_ReExports(t *testing.T) {
21+
t.Parallel()
2022
// Verify constants are properly re-exported
2123
if StateTypeAtomic.String() != "atomic" {
2224
t.Errorf("expected 'atomic', got %v", StateTypeAtomic.String())
@@ -30,6 +32,7 @@ func TestStateType_ReExports(t *testing.T) {
3032
}
3133

3234
func TestEvent_Creation(t *testing.T) {
35+
t.Parallel()
3336
event := Event{
3437
Type: "TIMER",
3538
Payload: map[string]int{"count": 1},

validation_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
)
99

1010
func TestBuild_Validation_MissingInitial(t *testing.T) {
11+
t.Parallel()
1112
_, err := NewMachine[struct{}]("test").
1213
State("idle").Done().
1314
Build()
@@ -27,6 +28,7 @@ func TestBuild_Validation_MissingInitial(t *testing.T) {
2728
}
2829

2930
func TestBuild_Validation_InitialNotFound(t *testing.T) {
31+
t.Parallel()
3032
_, err := NewMachine[struct{}]("test").
3133
WithInitial("nonexistent").
3234
State("idle").Done().
@@ -47,6 +49,7 @@ func TestBuild_Validation_InitialNotFound(t *testing.T) {
4749
}
4850

4951
func TestBuild_Validation_InvalidTransitionTarget(t *testing.T) {
52+
t.Parallel()
5053
_, err := NewMachine[struct{}]("test").
5154
WithInitial("idle").
5255
State("idle").
@@ -69,6 +72,7 @@ func TestBuild_Validation_InvalidTransitionTarget(t *testing.T) {
6972
}
7073

7174
func TestBuild_Validation_MissingAction(t *testing.T) {
75+
t.Parallel()
7276
_, err := NewMachine[struct{}]("test").
7377
WithInitial("idle").
7478
State("idle").
@@ -91,6 +95,7 @@ func TestBuild_Validation_MissingAction(t *testing.T) {
9195
}
9296

9397
func TestBuild_Validation_MissingGuard(t *testing.T) {
98+
t.Parallel()
9499
_, err := NewMachine[struct{}]("test").
95100
WithInitial("idle").
96101
State("idle").
@@ -114,6 +119,7 @@ func TestBuild_Validation_MissingGuard(t *testing.T) {
114119
}
115120

116121
func TestBuild_Validation_ErrorMessage(t *testing.T) {
122+
t.Parallel()
117123
_, err := NewMachine[struct{}]("test").
118124
WithInitial("nonexistent").
119125
State("idle").Done().

0 commit comments

Comments
 (0)