ariadna 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ariadna.gemspec +0 -1
- data/data/agents/ariadna-codebase-mapper.md +34 -722
- data/data/agents/ariadna-debugger.md +44 -1139
- data/data/agents/ariadna-executor.md +75 -396
- data/data/agents/ariadna-planner.md +78 -1215
- data/data/agents/ariadna-roadmapper.md +55 -582
- data/data/agents/ariadna-verifier.md +60 -702
- data/data/ariadna/templates/config.json +8 -33
- data/data/ariadna/workflows/debug.md +28 -0
- data/data/ariadna/workflows/execute-phase.md +31 -513
- data/data/ariadna/workflows/map-codebase.md +20 -319
- data/data/ariadna/workflows/new-milestone.md +20 -365
- data/data/ariadna/workflows/new-project.md +19 -880
- data/data/ariadna/workflows/plan-phase.md +24 -443
- data/data/ariadna/workflows/progress.md +20 -376
- data/data/ariadna/workflows/quick.md +19 -221
- data/data/ariadna/workflows/roadmap-ops.md +28 -0
- data/data/ariadna/workflows/verify-work.md +23 -560
- data/data/commands/ariadna/add-phase.md +11 -22
- data/data/commands/ariadna/debug.md +11 -143
- data/data/commands/ariadna/execute-phase.md +12 -30
- data/data/commands/ariadna/insert-phase.md +7 -14
- data/data/commands/ariadna/map-codebase.md +16 -49
- data/data/commands/ariadna/new-milestone.md +12 -25
- data/data/commands/ariadna/new-project.md +22 -26
- data/data/commands/ariadna/plan-phase.md +13 -22
- data/data/commands/ariadna/progress.md +16 -6
- data/data/commands/ariadna/quick.md +9 -11
- data/data/commands/ariadna/remove-phase.md +9 -12
- data/data/commands/ariadna/verify-work.md +14 -19
- data/data/skills/rails-backend/API.md +138 -0
- data/data/skills/rails-backend/CONTROLLERS.md +154 -0
- data/data/skills/rails-backend/JOBS.md +132 -0
- data/data/skills/rails-backend/MODELS.md +213 -0
- data/data/skills/rails-backend/SKILL.md +169 -0
- data/data/skills/rails-frontend/ASSETS.md +154 -0
- data/data/skills/rails-frontend/COMPONENTS.md +253 -0
- data/data/skills/rails-frontend/SKILL.md +187 -0
- data/data/skills/rails-frontend/VIEWS.md +168 -0
- data/data/skills/rails-performance/PROFILING.md +106 -0
- data/data/skills/rails-performance/SKILL.md +217 -0
- data/data/skills/rails-security/AUDIT.md +118 -0
- data/data/skills/rails-security/SKILL.md +422 -0
- data/data/skills/rails-testing/FIXTURES.md +78 -0
- data/data/skills/rails-testing/SKILL.md +160 -0
- data/data/skills/rails-testing/SYSTEM-TESTS.md +73 -0
- data/lib/ariadna/installer.rb +11 -15
- data/lib/ariadna/tools/cli.rb +0 -12
- data/lib/ariadna/tools/config_manager.rb +10 -72
- data/lib/ariadna/tools/frontmatter.rb +23 -1
- data/lib/ariadna/tools/init.rb +201 -401
- data/lib/ariadna/tools/model_profiles.rb +6 -14
- data/lib/ariadna/tools/phase_manager.rb +1 -10
- data/lib/ariadna/tools/state_manager.rb +170 -451
- data/lib/ariadna/tools/template_filler.rb +4 -12
- data/lib/ariadna/tools/verification.rb +21 -399
- data/lib/ariadna/uninstaller.rb +9 -0
- data/lib/ariadna/version.rb +1 -1
- metadata +20 -91
- data/data/agents/ariadna-backend-executor.md +0 -261
- data/data/agents/ariadna-frontend-executor.md +0 -259
- data/data/agents/ariadna-integration-checker.md +0 -418
- data/data/agents/ariadna-phase-researcher.md +0 -469
- data/data/agents/ariadna-plan-checker.md +0 -622
- data/data/agents/ariadna-project-researcher.md +0 -618
- data/data/agents/ariadna-research-synthesizer.md +0 -236
- data/data/agents/ariadna-test-executor.md +0 -266
- data/data/ariadna/references/checkpoints.md +0 -772
- data/data/ariadna/references/continuation-format.md +0 -249
- data/data/ariadna/references/decimal-phase-calculation.md +0 -65
- data/data/ariadna/references/git-integration.md +0 -248
- data/data/ariadna/references/git-planning-commit.md +0 -38
- data/data/ariadna/references/model-profile-resolution.md +0 -32
- data/data/ariadna/references/model-profiles.md +0 -73
- data/data/ariadna/references/phase-argument-parsing.md +0 -61
- data/data/ariadna/references/planning-config.md +0 -194
- data/data/ariadna/references/questioning.md +0 -153
- data/data/ariadna/references/rails-conventions.md +0 -416
- data/data/ariadna/references/tdd.md +0 -267
- data/data/ariadna/references/ui-brand.md +0 -160
- data/data/ariadna/references/verification-patterns.md +0 -853
- data/data/ariadna/templates/codebase/architecture.md +0 -481
- data/data/ariadna/templates/codebase/concerns.md +0 -380
- data/data/ariadna/templates/codebase/conventions.md +0 -434
- data/data/ariadna/templates/codebase/integrations.md +0 -328
- data/data/ariadna/templates/codebase/stack.md +0 -189
- data/data/ariadna/templates/codebase/structure.md +0 -418
- data/data/ariadna/templates/codebase/testing.md +0 -606
- data/data/ariadna/templates/context.md +0 -283
- data/data/ariadna/templates/continue-here.md +0 -78
- data/data/ariadna/templates/debug-subagent-prompt.md +0 -91
- data/data/ariadna/templates/phase-prompt.md +0 -609
- data/data/ariadna/templates/planner-subagent-prompt.md +0 -117
- data/data/ariadna/templates/research-project/ARCHITECTURE.md +0 -439
- data/data/ariadna/templates/research-project/FEATURES.md +0 -168
- data/data/ariadna/templates/research-project/PITFALLS.md +0 -406
- data/data/ariadna/templates/research-project/STACK.md +0 -251
- data/data/ariadna/templates/research-project/SUMMARY.md +0 -247
- data/data/ariadna/templates/state.md +0 -176
- data/data/ariadna/templates/summary-complex.md +0 -59
- data/data/ariadna/templates/summary-minimal.md +0 -41
- data/data/ariadna/templates/summary-standard.md +0 -48
- data/data/ariadna/templates/user-setup.md +0 -310
- data/data/ariadna/workflows/add-phase.md +0 -111
- data/data/ariadna/workflows/add-todo.md +0 -157
- data/data/ariadna/workflows/audit-milestone.md +0 -241
- data/data/ariadna/workflows/check-todos.md +0 -176
- data/data/ariadna/workflows/complete-milestone.md +0 -644
- data/data/ariadna/workflows/diagnose-issues.md +0 -219
- data/data/ariadna/workflows/discovery-phase.md +0 -289
- data/data/ariadna/workflows/discuss-phase.md +0 -408
- data/data/ariadna/workflows/execute-plan.md +0 -448
- data/data/ariadna/workflows/help.md +0 -470
- data/data/ariadna/workflows/insert-phase.md +0 -129
- data/data/ariadna/workflows/list-phase-assumptions.md +0 -178
- data/data/ariadna/workflows/pause-work.md +0 -122
- data/data/ariadna/workflows/plan-milestone-gaps.md +0 -256
- data/data/ariadna/workflows/remove-phase.md +0 -154
- data/data/ariadna/workflows/research-phase.md +0 -74
- data/data/ariadna/workflows/resume-project.md +0 -306
- data/data/ariadna/workflows/set-profile.md +0 -80
- data/data/ariadna/workflows/settings.md +0 -145
- data/data/ariadna/workflows/transition.md +0 -493
- data/data/ariadna/workflows/update.md +0 -212
- data/data/ariadna/workflows/verify-phase.md +0 -226
- data/data/commands/ariadna/add-todo.md +0 -42
- data/data/commands/ariadna/audit-milestone.md +0 -42
- data/data/commands/ariadna/check-todos.md +0 -41
- data/data/commands/ariadna/complete-milestone.md +0 -136
- data/data/commands/ariadna/discuss-phase.md +0 -86
- data/data/commands/ariadna/help.md +0 -22
- data/data/commands/ariadna/list-phase-assumptions.md +0 -50
- data/data/commands/ariadna/pause-work.md +0 -35
- data/data/commands/ariadna/plan-milestone-gaps.md +0 -40
- data/data/commands/ariadna/reapply-patches.md +0 -110
- data/data/commands/ariadna/research-phase.md +0 -187
- data/data/commands/ariadna/resume-work.md +0 -40
- data/data/commands/ariadna/set-profile.md +0 -34
- data/data/commands/ariadna/settings.md +0 -36
- data/data/commands/ariadna/update.md +0 -37
- data/data/guides/backend.md +0 -3069
- data/data/guides/frontend.md +0 -1479
- data/data/guides/performance.md +0 -1193
- data/data/guides/security.md +0 -1522
- data/data/guides/style-guide.md +0 -1091
- data/data/guides/testing.md +0 -504
- data/data/templates.md +0 -94
data/data/guides/testing.md
DELETED
|
@@ -1,504 +0,0 @@
|
|
|
1
|
-
# Testing Patterns & Practices
|
|
2
|
-
|
|
3
|
-
**A Guide to Testing Rails Applications with Minitest**
|
|
4
|
-
|
|
5
|
-
This guide consolidates all testing patterns and practices used across the application. It covers setup conventions, model testing, controller testing, job testing, and common gotchas.
|
|
6
|
-
|
|
7
|
-
**Related guides:**
|
|
8
|
-
- [Backend Patterns](backend.md) — Architecture, models, controllers, jobs, style guide
|
|
9
|
-
- [Frontend Patterns](frontend.md) — Presenter pattern (includes presenter testing examples)
|
|
10
|
-
- [Security Guide](security.md) — Agent-oriented security checklist for code review
|
|
11
|
-
|
|
12
|
-
## Table of Contents
|
|
13
|
-
|
|
14
|
-
- [1. Testing Philosophy](#1-testing-philosophy)
|
|
15
|
-
- [2. Model Testing Patterns](#2-model-testing-patterns)
|
|
16
|
-
- [2.1 Current Context Setup](#21-current-context-setup)
|
|
17
|
-
- [2.2 Testing State Changes](#22-testing-state-changes)
|
|
18
|
-
- [2.3 Testing Event Creation](#23-testing-event-creation)
|
|
19
|
-
- [2.4 Testing Scopes](#24-testing-scopes)
|
|
20
|
-
- [3. Controller Testing Patterns](#3-controller-testing-patterns)
|
|
21
|
-
- [4. Job Testing Patterns](#4-job-testing-patterns)
|
|
22
|
-
- [4.1 Testing Synchronous Logic](#41-testing-synchronous-logic)
|
|
23
|
-
- [4.2 Testing Async Wrappers](#42-testing-async-wrappers)
|
|
24
|
-
- [4.3 Multi-Tenancy in Job Tests](#43-multi-tenancy-in-job-tests)
|
|
25
|
-
- [5. Presenter Testing Patterns](#5-presenter-testing-patterns)
|
|
26
|
-
- [6. Recipe Test Steps](#6-recipe-test-steps)
|
|
27
|
-
- [6.1 Recipe: Testing New Card States](#recipe-testing-new-card-states)
|
|
28
|
-
- [6.2 Recipe: Testing Event Creation](#recipe-testing-event-creation)
|
|
29
|
-
- [6.3 Recipe: Testing Background Jobs](#recipe-testing-background-jobs)
|
|
30
|
-
- [7. Common Testing Gotchas](#7-common-testing-gotchas)
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
# 1. Testing Philosophy
|
|
35
|
-
|
|
36
|
-
The application uses **Minitest** (Rails default) with **fixtures** for test data. Key principles:
|
|
37
|
-
|
|
38
|
-
- **Test at the model level first** — Business logic lives in models, so that's where tests provide the most value
|
|
39
|
-
- **Use fixtures, not factories** — YAML fixtures provide deterministic, fast test data
|
|
40
|
-
- **Always set `Current.session`** — Lambda defaults and multi-tenancy depend on it
|
|
41
|
-
- **Test behavior, not implementation** — Assert on outcomes, not internal method calls
|
|
42
|
-
- **Use `assert_difference` for state changes** — Verify record counts change as expected
|
|
43
|
-
|
|
44
|
-
### Test File Organization
|
|
45
|
-
|
|
46
|
-
Tests mirror the `app/` directory structure:
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
test/
|
|
50
|
-
models/
|
|
51
|
-
card/
|
|
52
|
-
archivable_test.rb # Tests for Card::Archivable concern
|
|
53
|
-
closeable_test.rb # Tests for Card::Closeable concern
|
|
54
|
-
card_test.rb # Tests for Card model
|
|
55
|
-
controllers/
|
|
56
|
-
cards/
|
|
57
|
-
closures_controller_test.rb
|
|
58
|
-
jobs/
|
|
59
|
-
notify_recipients_job_test.rb
|
|
60
|
-
fixtures/
|
|
61
|
-
cards.yml
|
|
62
|
-
sessions.yml
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Standard Test Structure
|
|
66
|
-
|
|
67
|
-
```ruby
|
|
68
|
-
require "test_helper"
|
|
69
|
-
|
|
70
|
-
class Card::CloseableTest < ActiveSupport::TestCase
|
|
71
|
-
setup do
|
|
72
|
-
Current.session = sessions(:david) # Always set Current context
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
test "descriptive name of what is being tested" do
|
|
76
|
-
# Arrange
|
|
77
|
-
card = cards(:logo)
|
|
78
|
-
|
|
79
|
-
# Act & Assert
|
|
80
|
-
assert_difference -> { Closure.count }, +1 do
|
|
81
|
-
card.close
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
assert card.closed?
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
# 2. Model Testing Patterns
|
|
92
|
-
|
|
93
|
-
## 2.1 Current Context Setup
|
|
94
|
-
|
|
95
|
-
Every model test that creates records or uses `Current.user`/`Current.account` must set up the Current context:
|
|
96
|
-
|
|
97
|
-
```ruby
|
|
98
|
-
setup do
|
|
99
|
-
Current.session = sessions(:david) # Sets up user and account context
|
|
100
|
-
end
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**The cascade**: Setting `Current.session` automatically:
|
|
104
|
-
1. Extracts the `identity` from the session
|
|
105
|
-
2. Finds the `user` for that identity in the current `account`
|
|
106
|
-
|
|
107
|
-
This is required because:
|
|
108
|
-
- Lambda defaults like `default: -> { Current.user }` need it
|
|
109
|
-
- Multi-tenancy scoping depends on `Current.account`
|
|
110
|
-
- Event tracking uses `Current.user` as default creator
|
|
111
|
-
|
|
112
|
-
## 2.2 Testing State Changes
|
|
113
|
-
|
|
114
|
-
Use `assert_difference` to verify records are created or destroyed:
|
|
115
|
-
|
|
116
|
-
```ruby
|
|
117
|
-
test "close creates closure record and event" do
|
|
118
|
-
card = cards(:logo)
|
|
119
|
-
|
|
120
|
-
assert_difference -> { Closure.count }, +1 do
|
|
121
|
-
assert_difference -> { Event.count }, +1 do
|
|
122
|
-
card.close
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
assert card.closed?
|
|
127
|
-
assert_equal "card_closed", Event.last.action
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
test "reopen removes closure record" do
|
|
131
|
-
card = cards(:logo)
|
|
132
|
-
card.close
|
|
133
|
-
|
|
134
|
-
assert_difference -> { Closure.count }, -1 do
|
|
135
|
-
card.reopen
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
assert card.open?
|
|
139
|
-
end
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
**Pattern**: Nest `assert_difference` blocks when multiple record types change together.
|
|
143
|
-
|
|
144
|
-
## 2.3 Testing Event Creation
|
|
145
|
-
|
|
146
|
-
When testing actions that track events, verify both the event count and event attributes:
|
|
147
|
-
|
|
148
|
-
```ruby
|
|
149
|
-
test "archiving creates event with correct attributes" do
|
|
150
|
-
card = cards(:logo)
|
|
151
|
-
|
|
152
|
-
assert_difference -> { Event.count }, +1 do
|
|
153
|
-
card.archive
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
event = Event.last
|
|
157
|
-
assert_equal "card_archived", event.action
|
|
158
|
-
assert_equal card, event.eventable
|
|
159
|
-
assert_equal Current.user, event.creator
|
|
160
|
-
end
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
For events with particulars:
|
|
164
|
-
|
|
165
|
-
```ruby
|
|
166
|
-
test "moving boards creates event with particulars" do
|
|
167
|
-
card = cards(:logo)
|
|
168
|
-
old_board = card.board
|
|
169
|
-
new_board = boards(:other)
|
|
170
|
-
|
|
171
|
-
assert_difference -> { Event.count }, +1 do
|
|
172
|
-
card.move_to(new_board)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
event = Event.last
|
|
176
|
-
assert_equal "card_board_changed", event.action
|
|
177
|
-
assert_equal old_board.name, event.particulars["old_board"]
|
|
178
|
-
assert_equal new_board.name, event.particulars["new_board"]
|
|
179
|
-
end
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## 2.4 Testing Scopes
|
|
183
|
-
|
|
184
|
-
Test scopes by creating records in the expected state and asserting membership:
|
|
185
|
-
|
|
186
|
-
```ruby
|
|
187
|
-
test "archived scope returns only archived cards" do
|
|
188
|
-
card = cards(:logo)
|
|
189
|
-
card.archive
|
|
190
|
-
|
|
191
|
-
assert_includes Card.archived, card
|
|
192
|
-
assert_not_includes Card.unarchived, card
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
test "open scope excludes closed cards" do
|
|
196
|
-
card = cards(:logo)
|
|
197
|
-
card.close
|
|
198
|
-
|
|
199
|
-
assert_not_includes Card.open, card
|
|
200
|
-
assert_includes Card.closed, card
|
|
201
|
-
end
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
# 3. Controller Testing Patterns
|
|
207
|
-
|
|
208
|
-
Controller tests verify that the controller correctly delegates to the model and renders the right response:
|
|
209
|
-
|
|
210
|
-
```ruby
|
|
211
|
-
require "test_helper"
|
|
212
|
-
|
|
213
|
-
class Cards::ClosuresControllerTest < ActionDispatch::IntegrationTest
|
|
214
|
-
setup do
|
|
215
|
-
Current.session = sessions(:david)
|
|
216
|
-
@card = cards(:logo)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
test "create closes the card" do
|
|
220
|
-
post card_closure_path(@card.number)
|
|
221
|
-
|
|
222
|
-
assert @card.reload.closed?
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
test "destroy reopens the card" do
|
|
226
|
-
@card.close
|
|
227
|
-
|
|
228
|
-
delete card_closure_path(@card.number)
|
|
229
|
-
|
|
230
|
-
assert @card.reload.open?
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
**Key points:**
|
|
236
|
-
- Use RESTful route helpers matching the resource nesting pattern
|
|
237
|
-
- Assert on the model state after the request, not on internal calls
|
|
238
|
-
- The `setup` block sets `Current.session` for authentication context
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
# 4. Job Testing Patterns
|
|
243
|
-
|
|
244
|
-
## 4.1 Testing Synchronous Logic
|
|
245
|
-
|
|
246
|
-
Test the synchronous version of the method directly — this tests the actual business logic without job infrastructure:
|
|
247
|
-
|
|
248
|
-
```ruby
|
|
249
|
-
test "notify_recipients sends to watchers" do
|
|
250
|
-
comment = comments(:first)
|
|
251
|
-
|
|
252
|
-
comment.notify_recipients
|
|
253
|
-
|
|
254
|
-
assert_equal 2, Notification.count
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
test "process_data updates records" do
|
|
258
|
-
record = some_model(:example)
|
|
259
|
-
|
|
260
|
-
record.process_data
|
|
261
|
-
|
|
262
|
-
assert record.processed?
|
|
263
|
-
end
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
## 4.2 Testing Async Wrappers
|
|
267
|
-
|
|
268
|
-
Test that the async wrapper correctly enqueues the job:
|
|
269
|
-
|
|
270
|
-
```ruby
|
|
271
|
-
test "notify_recipients_later enqueues job" do
|
|
272
|
-
assert_enqueued_with(job: NotifyRecipientsJob) do
|
|
273
|
-
comment.save!
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
test "process_data_later enqueues job with correct args" do
|
|
278
|
-
assert_enqueued_with(job: ProcessDataJob, args: [record]) do
|
|
279
|
-
record.process_data_later
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**Pattern**: Test synchronous logic and async enqueuing separately. This gives you:
|
|
285
|
-
- Fast, focused tests for business logic (via synchronous method)
|
|
286
|
-
- Integration tests for job enqueuing (via async wrapper)
|
|
287
|
-
|
|
288
|
-
## 4.3 Multi-Tenancy in Job Tests
|
|
289
|
-
|
|
290
|
-
The multi-tenancy job extension automatically captures and restores `Current.account`. Tests work naturally when you set `Current.session`:
|
|
291
|
-
|
|
292
|
-
```ruby
|
|
293
|
-
setup do
|
|
294
|
-
Current.session = sessions(:david) # Sets Current.account
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
test "job processes in correct account" do
|
|
298
|
-
perform_enqueued_jobs do
|
|
299
|
-
comment.notify_recipients_later
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
# Job ran with correct Current.account
|
|
303
|
-
assert_equal 2, Current.account.notifications.count
|
|
304
|
-
end
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
**You don't need to manually pass account to jobs in tests** — it's captured automatically, just like in production.
|
|
308
|
-
|
|
309
|
-
---
|
|
310
|
-
|
|
311
|
-
# 5. Presenter Testing Patterns
|
|
312
|
-
|
|
313
|
-
Presenter tests live alongside their presenters in the test directory. For detailed presenter testing examples, see [Frontend Patterns — Testing Presenters](frontend.md#18-testing-presenters).
|
|
314
|
-
|
|
315
|
-
Key patterns:
|
|
316
|
-
- Test presenters like any Ruby class
|
|
317
|
-
- Set `Current.session` in setup for context
|
|
318
|
-
- Test boolean display methods (`show_tags?`, `expanded?`)
|
|
319
|
-
- Test cache key uniqueness for different states
|
|
320
|
-
- For HTML-generating presenters, test both `to_html` and `to_plain_text` outputs
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
# 6. Recipe Test Steps
|
|
325
|
-
|
|
326
|
-
These test examples correspond to the recipes in [Backend Patterns — Common Tasks & Recipes](backend.md#part-6-common-tasks--recipes).
|
|
327
|
-
|
|
328
|
-
## Recipe: Testing New Card States
|
|
329
|
-
|
|
330
|
-
Complete test for the "Adding a New State to Cards" recipe (see [Backend Patterns — Recipe 6.1](backend.md#61-recipe-adding-a-new-state-to-cards)):
|
|
331
|
-
|
|
332
|
-
```ruby
|
|
333
|
-
# test/models/card/archivable_test.rb
|
|
334
|
-
require "test_helper"
|
|
335
|
-
|
|
336
|
-
class Card::ArchivableTest < ActiveSupport::TestCase
|
|
337
|
-
setup do
|
|
338
|
-
Current.session = sessions(:david)
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
test "archive creates archive record and event" do
|
|
342
|
-
card = cards(:logo)
|
|
343
|
-
|
|
344
|
-
assert_difference -> { Card::Archive.count }, +1 do
|
|
345
|
-
assert_difference -> { Event.count }, +1 do
|
|
346
|
-
card.archive
|
|
347
|
-
end
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
assert card.archived?
|
|
351
|
-
assert_equal "card_archived", Event.last.action
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
test "unarchive removes archive record" do
|
|
355
|
-
card = cards(:logo)
|
|
356
|
-
card.archive
|
|
357
|
-
|
|
358
|
-
assert_difference -> { Card::Archive.count }, -1 do
|
|
359
|
-
card.unarchive
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
assert card.unarchived?
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
test "archived scope" do
|
|
366
|
-
card = cards(:logo)
|
|
367
|
-
card.archive
|
|
368
|
-
|
|
369
|
-
assert_includes Card.archived, card
|
|
370
|
-
assert_not_includes Card.unarchived, card
|
|
371
|
-
end
|
|
372
|
-
end
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
## Recipe: Testing Event Creation
|
|
376
|
-
|
|
377
|
-
Complete test for the "Adding Event Tracking" recipe (see [Backend Patterns — Recipe 6.2](backend.md#62-recipe-adding-event-tracking)):
|
|
378
|
-
|
|
379
|
-
```ruby
|
|
380
|
-
test "moving boards creates event with particulars" do
|
|
381
|
-
card = cards(:logo)
|
|
382
|
-
old_board = card.board
|
|
383
|
-
new_board = boards(:other)
|
|
384
|
-
|
|
385
|
-
assert_difference -> { Event.count }, +1 do
|
|
386
|
-
card.move_to(new_board)
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
event = Event.last
|
|
390
|
-
assert_equal "card_board_changed", event.action
|
|
391
|
-
assert_equal old_board.name, event.particulars["old_board"]
|
|
392
|
-
assert_equal new_board.name, event.particulars["new_board"]
|
|
393
|
-
end
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
## Recipe: Testing Background Jobs
|
|
397
|
-
|
|
398
|
-
Complete tests for the "Creating Background Jobs" recipe (see [Backend Patterns — Recipe 6.3](backend.md#63-recipe-creating-background-jobs)):
|
|
399
|
-
|
|
400
|
-
```ruby
|
|
401
|
-
# Test synchronous logic
|
|
402
|
-
test "process_data updates records" do
|
|
403
|
-
record.process_data
|
|
404
|
-
assert record.processed?
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
# Test async wrapper
|
|
408
|
-
test "process_data_later enqueues job" do
|
|
409
|
-
assert_enqueued_with(job: ProcessDataJob, args: [record]) do
|
|
410
|
-
record.process_data_later
|
|
411
|
-
end
|
|
412
|
-
end
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
---
|
|
416
|
-
|
|
417
|
-
# 7. Common Testing Gotchas
|
|
418
|
-
|
|
419
|
-
### 1. Forgetting Current.session in Model Tests
|
|
420
|
-
|
|
421
|
-
**Problem:**
|
|
422
|
-
|
|
423
|
-
```ruby
|
|
424
|
-
test "creating card" do
|
|
425
|
-
card = Card.create!(board: boards(:writebook), title: "Test")
|
|
426
|
-
# Error: Current.user is nil!
|
|
427
|
-
end
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
**Solution:**
|
|
431
|
-
|
|
432
|
-
```ruby
|
|
433
|
-
test "creating card" do
|
|
434
|
-
Current.session = sessions(:david) # ← Add this!
|
|
435
|
-
card = Card.create!(board: boards(:writebook), title: "Test")
|
|
436
|
-
end
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
**Why:** Lambda defaults like `default: -> { Current.user }` need `Current.session` set. This is the most common test failure for new developers. Always include it in your `setup` block:
|
|
440
|
-
|
|
441
|
-
```ruby
|
|
442
|
-
setup do
|
|
443
|
-
Current.session = sessions(:david)
|
|
444
|
-
end
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### 2. Testing Events Without Checking Attributes
|
|
448
|
-
|
|
449
|
-
**Problem:**
|
|
450
|
-
|
|
451
|
-
```ruby
|
|
452
|
-
test "closing creates event" do
|
|
453
|
-
assert_difference -> { Event.count }, +1 do
|
|
454
|
-
card.close
|
|
455
|
-
end
|
|
456
|
-
# Only checks count, not that the right event was created
|
|
457
|
-
end
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
**Solution:**
|
|
461
|
-
|
|
462
|
-
```ruby
|
|
463
|
-
test "closing creates event" do
|
|
464
|
-
assert_difference -> { Event.count }, +1 do
|
|
465
|
-
card.close
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
event = Event.last
|
|
469
|
-
assert_equal "card_closed", event.action
|
|
470
|
-
assert_equal card, event.eventable
|
|
471
|
-
end
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
Always verify event attributes after checking the count.
|
|
475
|
-
|
|
476
|
-
### 3. Not Using assert_difference for State Changes
|
|
477
|
-
|
|
478
|
-
**Problem:**
|
|
479
|
-
|
|
480
|
-
```ruby
|
|
481
|
-
test "archive creates record" do
|
|
482
|
-
card.archive
|
|
483
|
-
assert card.archived? # Passes, but doesn't verify a record was created
|
|
484
|
-
end
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
**Solution:**
|
|
488
|
-
|
|
489
|
-
```ruby
|
|
490
|
-
test "archive creates record" do
|
|
491
|
-
assert_difference -> { Card::Archive.count }, +1 do
|
|
492
|
-
card.archive
|
|
493
|
-
end
|
|
494
|
-
assert card.archived?
|
|
495
|
-
end
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
`assert_difference` catches bugs where the boolean check passes for the wrong reason.
|
|
499
|
-
|
|
500
|
-
---
|
|
501
|
-
|
|
502
|
-
**Document Version**: 1.0
|
|
503
|
-
**Last Updated**: 2026-02-15
|
|
504
|
-
**Maintainer**: Development Team
|
data/data/templates.md
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# Plan: Make Codebase Templates Rails-Focused
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
The templates in `data/ariadna/templates/codebase/` are used by Ariadna's codebase mapping agents to generate `.ariadna_planning/codebase/` documents when analyzing a Rails project. Currently, all templates except `architecture.md` are generic/framework-agnostic with JavaScript/TypeScript examples (Next.js, Vitest, npm, etc.). Since Ariadna is targeting Ruby on Rails applications, these templates should use Rails-specific terminology, examples, tools, and patterns.
|
|
6
|
-
|
|
7
|
-
`architecture.md` has already been updated and serves as the reference for style and approach.
|
|
8
|
-
|
|
9
|
-
## Approach
|
|
10
|
-
|
|
11
|
-
Launch **6 parallel agents** (one per file), each tasked with rewriting a single template to be Rails-focused. Each agent will:
|
|
12
|
-
1. Read `data/guides/backend.md` and `data/guides/testing.md` for Rails patterns context
|
|
13
|
-
2. Read the already-updated `architecture.md` as a style reference
|
|
14
|
-
3. Read its assigned template file
|
|
15
|
-
4. Rewrite the template with Rails-specific content
|
|
16
|
-
|
|
17
|
-
## Files to Update
|
|
18
|
-
|
|
19
|
-
### 1. `concerns.md` — Codebase Concerns
|
|
20
|
-
- Replace JS/Next.js examples with Rails examples:
|
|
21
|
-
- **Tech Debt**: N+1 queries, raw SQL instead of scopes, business logic in controllers, missing concern extraction
|
|
22
|
-
- **Known Bugs**: ActiveRecord callback ordering, race conditions in background jobs, stale Current context
|
|
23
|
-
- **Security**: Mass assignment, missing authorization checks, unscoped queries leaking tenant data
|
|
24
|
-
- **Performance**: N+1 queries, missing database indexes, heavy callbacks, unoptimized eager loading
|
|
25
|
-
- **Fragile Areas**: Complex concern chains, callback ordering, multi-tenancy scoping
|
|
26
|
-
- **Dependencies at Risk**: Outdated gems, deprecated Rails APIs
|
|
27
|
-
- **Test Coverage Gaps**: Missing model concern tests, controller integration tests
|
|
28
|
-
- Update guidelines to reference Rails file paths (`app/models/`, `app/controllers/`, etc.)
|
|
29
|
-
|
|
30
|
-
### 2. `conventions.md` — Coding Conventions
|
|
31
|
-
- Replace JS/TS conventions with Ruby/Rails conventions:
|
|
32
|
-
- **Naming**: snake_case methods/variables, PascalCase classes/modules, SCREAMING_SNAKE constants, `?` for booleans, `!` for bang methods
|
|
33
|
-
- **Code Style**: RuboCop config, `frozen_string_literal: true`, double quotes, 120 char line length, 2-space indentation
|
|
34
|
-
- **Require/Include Organization**: Ruby require patterns, concern includes, module nesting
|
|
35
|
-
- **Error Handling**: `rescue` patterns, custom error classes, `rescue_from` in controllers
|
|
36
|
-
- **Logging**: `Rails.logger`, tagged logging
|
|
37
|
-
- **Comments**: `# frozen_string_literal: true`, YARD docs (if used), TODO patterns
|
|
38
|
-
- **Method Design**: Ruby method conventions, keyword arguments, method visibility (public/private)
|
|
39
|
-
- **Module Design**: Concern patterns, module nesting, `ActiveSupport::Concern`
|
|
40
|
-
- Reference patterns from the Fizzy guide (intention-revealing APIs, imperative verbs for actions, boolean pairs)
|
|
41
|
-
|
|
42
|
-
### 3. `integrations.md` — External Integrations
|
|
43
|
-
- Replace JS/Supabase/Vercel examples with Rails ecosystem:
|
|
44
|
-
- **Payment**: Stripe via `stripe` gem
|
|
45
|
-
- **Email**: ActionMailer with SMTP/Postmark/SendGrid
|
|
46
|
-
- **Databases**: SQLite (Rails default) or PostgreSQL via ActiveRecord, `database.yml`
|
|
47
|
-
- **File Storage**: ActiveStorage with S3/GCS/local disk
|
|
48
|
-
- **Caching**: Solid Cache/Redis via `Rails.cache`
|
|
49
|
-
- **Auth**: Rails authentication generator, OmniAuth
|
|
50
|
-
- **Monitoring**: Sentry/Honeybadger via gems
|
|
51
|
-
- **CI/CD**: GitHub Actions, Kamal/Docker deployment
|
|
52
|
-
- **Background Jobs**: Solid Queue/Sidekiq/GoodJob
|
|
53
|
-
- **Webhooks**: Rails controller endpoints with signature verification
|
|
54
|
-
|
|
55
|
-
### 4. `stack.md` — Technology Stack
|
|
56
|
-
- Replace Node.js/TypeScript/npm examples with:
|
|
57
|
-
- **Languages**: Ruby (version from `.ruby-version`), JavaScript/CSS for assets
|
|
58
|
-
- **Runtime**: Ruby + Bundler, `.ruby-version`
|
|
59
|
-
- **Frameworks**: Rails (version), Minitest (recommended)/RSpec, Hotwire/Turbo/Stimulus
|
|
60
|
-
- **Key Dependencies**: Key gems (solid_queue, solid_cache, etc.)
|
|
61
|
-
- **Configuration**: `database.yml`, `credentials.yml.enc`, `config/environments/`
|
|
62
|
-
- **Build**: Asset pipeline (Propshaft/Sprockets), importmap/esbuild/vite
|
|
63
|
-
- **Platform**: Kamal, Docker, Heroku, etc.
|
|
64
|
-
|
|
65
|
-
### 5. `structure.md` — Codebase Structure
|
|
66
|
-
- Replace JS project structure with Rails directory layout:
|
|
67
|
-
- Standard Rails directories: `app/`, `config/`, `db/`, `lib/`, `test/`, `public/`, `bin/`
|
|
68
|
-
- `app/` subdirectories: `models/`, `controllers/`, `views/`, `jobs/`, `mailers/`, `helpers/`
|
|
69
|
-
- Model-specific concern directories: `app/models/card/`, `app/models/board/`
|
|
70
|
-
- Config files: `routes.rb`, `database.yml`, `application.rb`, initializers
|
|
71
|
-
- Where to add new code: new model → `app/models/`, new concern → `app/models/concerns/` or `app/models/{model}/`, new controller → `app/controllers/`, etc.
|
|
72
|
-
- Special directories: `db/migrate/`, `tmp/`, `log/`, `storage/`
|
|
73
|
-
- Naming: snake_case for everything, `_test.rb` suffix, `_controller.rb` suffix
|
|
74
|
-
|
|
75
|
-
### 6. `testing.md` — Testing Patterns
|
|
76
|
-
- Remove the JS/Vitest primary example entirely, keep only Rails content
|
|
77
|
-
- Make Rails/Minitest the primary template (not a secondary example):
|
|
78
|
-
- **Framework**: Minitest (Rails default), `test_helper.rb`
|
|
79
|
-
- **Organization**: `test/` mirroring `app/`, fixtures in `test/fixtures/`
|
|
80
|
-
- **Structure**: `ActiveSupport::TestCase`, `setup` blocks, `test "description"` blocks
|
|
81
|
-
- **Mocking**: `Minitest::Mock`, `stub`, `travel_to` for time
|
|
82
|
-
- **Fixtures**: YAML fixtures (Rails default), fixture accessor methods
|
|
83
|
-
- **Test Types**: Model tests, controller tests, integration tests, system tests (Capybara)
|
|
84
|
-
- **Patterns**: `assert_difference`, `assert_changes`, `assert_no_difference`, Current context setup
|
|
85
|
-
- **Coverage**: SimpleCov
|
|
86
|
-
- Reference patterns from Fizzy guide (fixture-based testing, Current.session setup, event assertion patterns)
|
|
87
|
-
|
|
88
|
-
## Verification
|
|
89
|
-
|
|
90
|
-
After all 6 agents complete:
|
|
91
|
-
1. Read each updated file to confirm Rails-specific content
|
|
92
|
-
2. Verify no JS/TS/Node.js references remain in templates or examples
|
|
93
|
-
3. Verify consistency with the already-updated `architecture.md` style
|
|
94
|
-
4. Run `bundle exec rubocop` to verify no gem code was affected
|