appydave-tools 0.76.2 → 0.76.3
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/CHANGELOG.md +12 -0
- data/docs/planning/final-test-gaps/AGENTS.md +333 -0
- data/docs/planning/final-test-gaps/IMPLEMENTATION_PLAN.md +29 -0
- data/docs/planning/test-coverage-gaps/assessment.md +75 -0
- data/lib/appydave/tools/version.rb +1 -1
- data/package.json +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d2b65bd11cb0b4e0a0c9b1718a9ebb262ad6c998167bfdc8f533ddca754ee850
|
|
4
|
+
data.tar.gz: e45a7a56eb7f77249911ea874037c002829cfcca1f8f5cfd8553b60d12e88898
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: feb57bd1aca715ae2b6b3a587e762e024457b4d14f1172069d1afd19e953c6c432567d9c76c819543f740acb757c53bb36fa7bc839e4e7c8706f13435e94bfb0
|
|
7
|
+
data.tar.gz: eba77632d7dad881243726e122d8da5546040910b2851c36a9b751d7310da9ca3d1a4279571baa31b908bb1ff398436253bed4f7e52907adeeb6e4cfe1b1f69a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.76.2](https://github.com/appydave/appydave-tools/compare/v0.76.1...v0.76.2) (2026-03-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add dedicated specs for Jump Commands layer ([8eec40c](https://github.com/appydave/appydave-tools/commit/8eec40cb60b08b1ca7901f288cff8c9a70783fe2))
|
|
7
|
+
* add determine_range edge cases and fix stale comment ([6e97390](https://github.com/appydave/appydave-tools/commit/6e97390e135ac452a364bfac45fcbc4679b5a26d))
|
|
8
|
+
* add functional CLI tests for -i -e -f -o flags to gpt_context cli_spec ([feed9c7](https://github.com/appydave/appydave-tools/commit/feed9c70abfbec83c6bdb0fcba45fce0ec528657))
|
|
9
|
+
* fix no-args cli spec assertion to avoid false positive on Linux clipboard error ([a50b68e](https://github.com/appydave/appydave-tools/commit/a50b68ea57e2d989b35da2c5f1172181cf825438))
|
|
10
|
+
* fix no-args clipboard assertion to avoid false failure from clipboard gem warning on Linux CI ([197b9de](https://github.com/appydave/appydave-tools/commit/197b9dea84fc12c14b03c39333593f430542228a))
|
|
11
|
+
* strengthen gpt_context no-args spec to verify collection does not proceed ([972d617](https://github.com/appydave/appydave-tools/commit/972d617b2241326a6b4beca53d520ebcb1051530))
|
|
12
|
+
|
|
1
13
|
## [0.76.1](https://github.com/appydave/appydave-tools/compare/v0.76.0...v0.76.1) (2026-03-19)
|
|
2
14
|
|
|
3
15
|
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# AGENTS.md — final-test-gaps
|
|
2
|
+
|
|
3
|
+
> Inherited from test-coverage-gaps AGENTS.md. Self-contained.
|
|
4
|
+
> Last updated: 2026-03-19
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Overview
|
|
9
|
+
|
|
10
|
+
**What:** Ruby gem providing CLI productivity tools for AppyDave's YouTube content creation workflow.
|
|
11
|
+
**Stack:** Ruby 3.4.2, Bundler 2.6.2, RSpec, RuboCop, semantic-release CI/CD.
|
|
12
|
+
**This campaign:** Test-only gap closure. No lib/ production code changes.
|
|
13
|
+
**Commits:** Always use `kfix` — never `git commit`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Build & Run Commands
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
eval "$(rbenv init -)"
|
|
21
|
+
|
|
22
|
+
RUBYOPT="-W0" bundle exec rspec # All tests
|
|
23
|
+
bundle exec rspec spec/appydave/tools/gpt_context/file_collector_spec.rb
|
|
24
|
+
bundle exec rspec spec/appydave/tools/gpt_context/cli_spec.rb
|
|
25
|
+
bundle exec rspec spec/appydave/tools/jump/commands/add_spec.rb
|
|
26
|
+
bundle exec rspec spec/appydave/tools/jump/commands/update_spec.rb
|
|
27
|
+
bundle exec rubocop --format clang
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Baseline:** 817 examples, 0 failures, 85.61% line coverage
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Directory Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
lib/appydave/tools/gpt_context/
|
|
38
|
+
file_collector.rb READ ONLY — formats: content, tree, json, aider
|
|
39
|
+
options.rb READ ONLY — Struct with: include_patterns, exclude_patterns,
|
|
40
|
+
format, line_limit, debug, output_target,
|
|
41
|
+
working_directory, prompt (all keyword_init)
|
|
42
|
+
|
|
43
|
+
spec/appydave/tools/gpt_context/
|
|
44
|
+
file_collector_spec.rb ADD json format, aider format, error path tests
|
|
45
|
+
cli_spec.rb ADD body content assertions to -i and -e describe blocks
|
|
46
|
+
|
|
47
|
+
spec/appydave/tools/jump/commands/
|
|
48
|
+
add_spec.rb ADD location data integrity assertions (path, jump, tags, description)
|
|
49
|
+
update_spec.rb ADD field isolation assertions (non-updated fields unchanged)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Work Unit Details
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### fix-b023 — file_collector_spec: json, aider, error paths
|
|
59
|
+
|
|
60
|
+
**Read first:** `lib/appydave/tools/gpt_context/file_collector.rb` and
|
|
61
|
+
`spec/appydave/tools/gpt_context/file_collector_spec.rb`
|
|
62
|
+
|
|
63
|
+
**What `build_json` produces:**
|
|
64
|
+
```ruby
|
|
65
|
+
{
|
|
66
|
+
'tree' => {}, # nested hash matching tree structure
|
|
67
|
+
'content' => [ # array of hashes, one per file
|
|
68
|
+
{ 'file' => 'path/to/file.txt', 'content' => '...' }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
Returns `JSON.pretty_generate(json_output)` — a valid JSON string.
|
|
73
|
+
|
|
74
|
+
**What `build_aider` produces:**
|
|
75
|
+
- With `prompt` set: `aider --message "my prompt" path/to/file1.rb path/to/file2.rb`
|
|
76
|
+
- Without `prompt` (nil): returns `''`
|
|
77
|
+
|
|
78
|
+
**Add these describe blocks to file_collector_spec.rb:**
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
describe '#build with json format' do
|
|
82
|
+
let(:format) { 'json' }
|
|
83
|
+
let(:include_patterns) { ['**/*.txt'] }
|
|
84
|
+
let(:exclude_patterns) { [] }
|
|
85
|
+
|
|
86
|
+
it 'returns valid JSON' do
|
|
87
|
+
result = subject.build
|
|
88
|
+
expect { JSON.parse(result) }.not_to raise_error
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'includes a tree key in the JSON output' do
|
|
92
|
+
result = JSON.parse(subject.build)
|
|
93
|
+
expect(result).to have_key('tree')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'includes a content key in the JSON output' do
|
|
97
|
+
result = JSON.parse(subject.build)
|
|
98
|
+
expect(result).to have_key('content')
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'includes file paths and content in the content array' do
|
|
102
|
+
result = JSON.parse(subject.build)
|
|
103
|
+
files = result['content'].map { |f| f['file'] }
|
|
104
|
+
expect(files).to include('included/file1.txt')
|
|
105
|
+
|
|
106
|
+
entry = result['content'].find { |f| f['file'] == 'included/file1.txt' }
|
|
107
|
+
expect(entry['content']).to include('File 1 content')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'excludes files matching exclude patterns from content' do
|
|
111
|
+
result = JSON.parse(subject.build)
|
|
112
|
+
files = result['content'].map { |f| f['file'] }
|
|
113
|
+
expect(files).not_to include('excluded/excluded_file.txt')
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe '#build with aider format' do
|
|
118
|
+
let(:format) { 'aider' }
|
|
119
|
+
let(:include_patterns) { ['**/*.txt'] }
|
|
120
|
+
let(:exclude_patterns) { [] }
|
|
121
|
+
|
|
122
|
+
context 'when prompt is set' do
|
|
123
|
+
let(:options) do
|
|
124
|
+
Appydave::Tools::GptContext::Options.new(
|
|
125
|
+
include_patterns: include_patterns,
|
|
126
|
+
exclude_patterns: exclude_patterns,
|
|
127
|
+
format: format,
|
|
128
|
+
line_limit: nil,
|
|
129
|
+
working_directory: temp_dir,
|
|
130
|
+
prompt: 'fix the bug'
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'returns an aider command string' do
|
|
135
|
+
expect(subject.build).to start_with('aider --message')
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'includes the prompt in the command' do
|
|
139
|
+
expect(subject.build).to include('fix the bug')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'includes collected file paths in the command' do
|
|
143
|
+
result = subject.build
|
|
144
|
+
expect(result).to include('included/file1.txt')
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context 'when prompt is not set' do
|
|
149
|
+
it 'returns an empty string' do
|
|
150
|
+
expect(subject.build).to eq('')
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe '#build with nonexistent working directory' do
|
|
156
|
+
let(:options) do
|
|
157
|
+
Appydave::Tools::GptContext::Options.new(
|
|
158
|
+
include_patterns: ['**/*.txt'],
|
|
159
|
+
exclude_patterns: [],
|
|
160
|
+
format: 'content',
|
|
161
|
+
line_limit: nil,
|
|
162
|
+
working_directory: '/tmp/does-not-exist-12345'
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'returns empty string without raising an error' do
|
|
167
|
+
expect { subject.build }.not_to raise_error
|
|
168
|
+
expect(subject.build).to eq('')
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Note:** The existing `before` block creates files under `temp_dir`. The aider context with `prompt` needs its own `let(:options)` that overrides the parent — this is fine in RSpec because the inner let shadows the outer.
|
|
174
|
+
|
|
175
|
+
**Commit:** `kfix "add json, aider, and error path tests to file_collector_spec"`
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### fix-b028 — cli_spec: add file body content assertions to -i and -e tests
|
|
180
|
+
|
|
181
|
+
**Read first:** `spec/appydave/tools/gpt_context/cli_spec.rb`
|
|
182
|
+
|
|
183
|
+
**The gap:** `-i` tests write known content to temp files but only assert on `# file: test.rb` headers. File body content (`# test content`, `# ruby file`) is never asserted. File truncation or body corruption would pass silently.
|
|
184
|
+
|
|
185
|
+
**Find the `-i include pattern` describe block (lines 43-68). Add body assertions to each existing `it` block:**
|
|
186
|
+
|
|
187
|
+
In the first `-i` example (`'collects files matching the include pattern'`):
|
|
188
|
+
```ruby
|
|
189
|
+
# After the existing assertion, add:
|
|
190
|
+
expect(File.read(outfile)).to include('# test content')
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
In the second `-i` example (`'does not include files that do not match the pattern'`):
|
|
194
|
+
```ruby
|
|
195
|
+
# The file 'test.rb' has content '# ruby file'
|
|
196
|
+
# After the existing assertions, add:
|
|
197
|
+
expect(content).to include('# ruby file')
|
|
198
|
+
expect(content).not_to include('# markdown file')
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Find the `-e exclude pattern` describe block (lines 70-95). Add body assertions:**
|
|
202
|
+
|
|
203
|
+
In the first `-e` example (`'excludes files matching the exclude pattern'`):
|
|
204
|
+
```ruby
|
|
205
|
+
# 'keep.rb' has content '# keep'
|
|
206
|
+
# After existing assertions, add:
|
|
207
|
+
expect(content).to include('# keep')
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
In the second `-e` example (`'keeps all files when exclude pattern matches nothing'`):
|
|
211
|
+
```ruby
|
|
212
|
+
# 'keep.rb' has content '# keep'
|
|
213
|
+
# After existing assertion, add:
|
|
214
|
+
expect(File.read(outfile)).to include('# keep')
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Do NOT modify the `-f`, `-o`, or `no arguments` describe blocks** — those are not in scope.
|
|
218
|
+
|
|
219
|
+
**Commit:** `kfix "add file body content assertions to cli_spec -i and -e tests"`
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
### fix-b029 — add_spec: validate all returned location data fields
|
|
224
|
+
|
|
225
|
+
**Read first:** `spec/appydave/tools/jump/commands/add_spec.rb`
|
|
226
|
+
|
|
227
|
+
**The gap:** The `'returns the created location data'` example (lines 35-41) only asserts `result[:location][:key]`. The path, jump, tags, description are never verified — data corruption or field mapping bugs would pass silently.
|
|
228
|
+
|
|
229
|
+
**Add a new `it` block** in the `'with valid attributes and existing path'` context, immediately after the existing `'returns the created location data'` block:
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
it 'returns location data matching all input attrs' do
|
|
233
|
+
cmd = described_class.new(config, valid_attrs, path_validator: path_validator)
|
|
234
|
+
result = cmd.run
|
|
235
|
+
|
|
236
|
+
location = result[:location]
|
|
237
|
+
expect(location[:key]).to eq('new-project')
|
|
238
|
+
expect(location[:path]).to eq('~/dev/new-project')
|
|
239
|
+
expect(location[:jump]).to eq('jnew')
|
|
240
|
+
expect(location[:tags]).to eq(%w[ruby])
|
|
241
|
+
expect(location[:description]).to eq('A new project')
|
|
242
|
+
end
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Do NOT modify the existing `'returns the created location data'` example** — add alongside it.
|
|
246
|
+
|
|
247
|
+
**Commit:** `kfix "add data integrity assertions to add_spec returned location data"`
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
### fix-b030 — update_spec: verify non-updated fields remain unchanged
|
|
252
|
+
|
|
253
|
+
**Read first:** `spec/appydave/tools/jump/commands/update_spec.rb`
|
|
254
|
+
**Also read:** `spec/support/jump_test_locations.rb` to get the exact field values for `JumpTestLocations.ad_tools` and `JumpTestLocations.flivideo`
|
|
255
|
+
|
|
256
|
+
**Gap 1:** `'leaves unmodified locations intact'` (lines 48-53) only checks `config.key_exists?('flivideo')`. The flivideo record's fields (path, jump, tags, description) could be corrupted and the test would still pass.
|
|
257
|
+
|
|
258
|
+
**Gap 2:** When updating `ad-tools` description, the key/path/jump/tags of the `ad-tools` record itself are never verified to be unchanged.
|
|
259
|
+
|
|
260
|
+
**Add two new `it` blocks** in the `'when location exists and update is valid'` context:
|
|
261
|
+
|
|
262
|
+
```ruby
|
|
263
|
+
it 'does not modify non-updated fields on the updated record' do
|
|
264
|
+
original = config.find('ad-tools')
|
|
265
|
+
original_path = original.path
|
|
266
|
+
original_jump = original.jump
|
|
267
|
+
original_tags = original.tags
|
|
268
|
+
|
|
269
|
+
cmd = described_class.new(config, 'ad-tools', { description: 'Changed' }, path_validator: path_validator)
|
|
270
|
+
cmd.run
|
|
271
|
+
|
|
272
|
+
updated = config.find('ad-tools')
|
|
273
|
+
expect(updated.path).to eq(original_path)
|
|
274
|
+
expect(updated.jump).to eq(original_jump)
|
|
275
|
+
expect(updated.tags).to eq(original_tags)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'does not modify the sibling record fields' do
|
|
279
|
+
original_flivideo = config.find('flivideo')
|
|
280
|
+
original_path = original_flivideo.path
|
|
281
|
+
original_jump = original_flivideo.jump
|
|
282
|
+
|
|
283
|
+
cmd = described_class.new(config, 'ad-tools', { description: 'Changed' }, path_validator: path_validator)
|
|
284
|
+
cmd.run
|
|
285
|
+
|
|
286
|
+
flivideo = config.find('flivideo')
|
|
287
|
+
expect(flivideo.path).to eq(original_path)
|
|
288
|
+
expect(flivideo.jump).to eq(original_jump)
|
|
289
|
+
end
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Do NOT modify existing examples** — add alongside them.
|
|
293
|
+
|
|
294
|
+
**Note:** Read jump_test_locations.rb to understand what fields `JumpTestLocations.flivideo` has before assuming field names.
|
|
295
|
+
|
|
296
|
+
**Commit:** `kfix "add field isolation assertions to update_spec non-updated fields"`
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Success Criteria
|
|
301
|
+
|
|
302
|
+
- [ ] `RUBYOPT="-W0" bundle exec rspec` — 817+ examples, 0 failures
|
|
303
|
+
- [ ] `bundle exec rubocop --format clang` — 0 offenses
|
|
304
|
+
- [ ] Line coverage stays ≥ 85.61%
|
|
305
|
+
- [ ] All new `it` blocks use descriptive behaviour names
|
|
306
|
+
- [ ] No `require 'spec_helper'` added (auto-required)
|
|
307
|
+
- [ ] All new spec files start with `# frozen_string_literal: true` (if any new files created)
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Anti-Patterns to Avoid
|
|
312
|
+
|
|
313
|
+
- ❌ Do NOT use `$?` — use `$CHILD_STATUS` (rubocop Style/SpecialGlobalVars)
|
|
314
|
+
- ❌ Do NOT modify existing passing examples — add new ones alongside
|
|
315
|
+
- ❌ Do NOT require spec_helper explicitly
|
|
316
|
+
- ❌ Do NOT change production lib/ code
|
|
317
|
+
- ❌ Do NOT use multiple separate `before` blocks on the same context — rubocop RSpec/ScatteredSetup; merge into one
|
|
318
|
+
- ❌ Do NOT assume field names on JumpTestLocations — read the file first
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Learnings (inherited from test-coverage-gaps)
|
|
323
|
+
|
|
324
|
+
- **`$CHILD_STATUS` not `$?`** — rubocop Special/GlobalVars cop
|
|
325
|
+
- **`exit` with no code exits 0** — specs asserting no-args exit should expect 0
|
|
326
|
+
- **`options.format` defaults to `'tree,content'`** — never nil
|
|
327
|
+
- **Grep full codebase before writing scope** — actual files may differ from brief
|
|
328
|
+
- **ENV stubbing:** `allow(ENV).to receive(:[]).and_call_original` then targeted override — no climate_control gem
|
|
329
|
+
- **Merge `before` blocks** — multiple separate `before` blocks on same context trigger RSpec/ScatteredSetup
|
|
330
|
+
- **`options.prompt` defaults to nil** — aider format returns `''` when prompt is nil
|
|
331
|
+
- **Parallel wave had zero merge conflicts across 5 agents** — all different files
|
|
332
|
+
- **B023 `build_json`:** returns `JSON.pretty_generate` — must `JSON.parse(result)` before asserting on keys
|
|
333
|
+
- **B028 body assertions:** file content is written in Dir.mktmpdir blocks; check the `File.write` call to know what body text to assert
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# IMPLEMENTATION_PLAN.md — final-test-gaps
|
|
2
|
+
|
|
3
|
+
**Goal**: Close remaining test quality gaps surfaced by the test-quality-audit: file_collector json/aider/error paths, cli_spec body assertions, add_spec data integrity, update_spec field isolation
|
|
4
|
+
**Started**: 2026-03-19
|
|
5
|
+
**Target**: All 4 work units complete; 817+ examples passing; rubocop clean; no regressions; regression catch rate meaningfully above 55%
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
- Total: 4 | Complete: 0 | In Progress: 4 | Pending: 0 | Failed: 0
|
|
9
|
+
|
|
10
|
+
## Pending
|
|
11
|
+
|
|
12
|
+
## In Progress
|
|
13
|
+
- [~] fix-b023 — file_collector_spec: add json format, aider format, and error path tests
|
|
14
|
+
- [~] fix-b028 — cli_spec: add file body content assertions to -i and -e tests
|
|
15
|
+
- [~] fix-b029 — add_spec: validate ALL returned location data fields match input attrs (path, jump, tags, description)
|
|
16
|
+
- [~] fix-b030 — update_spec: verify non-updated fields are unchanged on both updated record and sibling records
|
|
17
|
+
|
|
18
|
+
## Complete
|
|
19
|
+
|
|
20
|
+
## Failed / Needs Retry
|
|
21
|
+
|
|
22
|
+
## Notes & Decisions
|
|
23
|
+
- All 4 work units are independent — parallel wave
|
|
24
|
+
- Test-only campaign: no lib/ production code changes
|
|
25
|
+
- B019 and B015 already fixed in prior commits — closed without campaign
|
|
26
|
+
- B028 scope: -i tests check `# file: test.rb` header but not body; -e tests same gap. Add body content assertions only (do NOT rewrite existing assertions)
|
|
27
|
+
- B029 scope: "returns the created location data" test at line 35-41 of add_spec.rb — extend it to assert path/jump/tags/description. Add as a new 'it' block rather than modifying existing example.
|
|
28
|
+
- B030 scope: two gaps — (1) updated record: non-updated fields stay the same; (2) sibling record: not just key_exists? but fields are identical
|
|
29
|
+
- B023 scope: Options struct has :prompt field (keyword_init). Aider tests need `prompt: 'my prompt'` in options.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Assessment: test-coverage-gaps
|
|
2
|
+
|
|
3
|
+
**Campaign**: test-coverage-gaps
|
|
4
|
+
**Date**: 2026-03-19 → 2026-03-19
|
|
5
|
+
**Results**: 5 complete, 0 failed
|
|
6
|
+
**Version shipped**: v0.76.2
|
|
7
|
+
**Quality audit**: code-quality-audit + test-quality-audit run post-campaign
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Results Summary
|
|
12
|
+
|
|
13
|
+
| Work Unit | Examples Added | Notes |
|
|
14
|
+
|-----------|---------------|-------|
|
|
15
|
+
| fix-b024-ssl-tests | +6 | configure_ssl_options protected in s3_operations + share_operations |
|
|
16
|
+
| fix-b022-cli-tests | +10 | -i/-e/-f/-o functional tests with real file I/O |
|
|
17
|
+
| fix-b026-b025 | +6 + comment | b00/b9/a40 edge cases; stale comment fixed |
|
|
18
|
+
| fix-b027-noargs | +1 | No-file-collection assertion added |
|
|
19
|
+
| fix-b018-jump | +36 | Remove/Add/Update fully covered + fixed clipboard assertion |
|
|
20
|
+
|
|
21
|
+
**759 → 817 examples (+58). 85.0% → 85.61% coverage.**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What Worked Well
|
|
26
|
+
|
|
27
|
+
- **36 Jump Commands specs landed cleanly.** The accumulated AGENTS.md (JumpTestLocations, `with jump filesystem` context, TestPathValidator) meant agents could write correct specs without scaffolding guidance.
|
|
28
|
+
- **B018 agent fixed the B027 clipboard CI failure.** Unblocked itself and the other agents.
|
|
29
|
+
- **ENV stubbing pattern worked without climate_control.** `allow(ENV).to receive(:[]).and_call_original` + targeted override — captured in AGENTS.md.
|
|
30
|
+
- **Parallel wave had zero merge conflicts.** 5 agents, all different files, clean.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What Didn't Work
|
|
35
|
+
|
|
36
|
+
**Test quality is C overall (test audit finding).**
|
|
37
|
+
|
|
38
|
+
Specific gaps the audit surfaced:
|
|
39
|
+
- **cli_spec.rb (-i/-o tests):** Assert `# file:` header present but never check file body content. File truncation or body corruption would not be caught.
|
|
40
|
+
- **add_spec.rb:** After a successful add, only checks `key_exists?` — never validates returned location data matches input attrs (key, path, jump, tags).
|
|
41
|
+
- **update_spec.rb:** Tests verify the updated field changed but never verify other fields were NOT changed.
|
|
42
|
+
- **s3_operations_spec.rb:** Some output format checks use soft regex.
|
|
43
|
+
|
|
44
|
+
Regression catch rate: ~55%. Would catch code path breaks and guard logic. Would miss data integrity and content corruption.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Key Learnings — Application
|
|
49
|
+
|
|
50
|
+
- **B015 is already fixed.** BACKLOG.md lists B015 as pending but file_collector.rb already uses block form `FileUtils.cd(@working_directory) { build_formats }` from commit 13d5f87. Close it.
|
|
51
|
+
- **`allow(ENV).to receive(:[]).and_call_original`** is the correct ENV stub pattern when climate_control is absent. Must call `and_call_original` first, then override specific key.
|
|
52
|
+
- **Merge `before` blocks** to avoid `RSpec/ScatteredSetup` — multiple separate `before` blocks on same context trigger the cop.
|
|
53
|
+
- **Jump Commands layer is now tested.** base.rb/generate.rb/validate.rb already had specs; Remove/Add/Update are now covered.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## New Backlog Items from Quality Audit
|
|
58
|
+
|
|
59
|
+
- **B028** — Tests: cli_spec.rb add file body content assertions to -i/-o tests | Priority: medium
|
|
60
|
+
- **B029** — Tests: add_spec.rb validate returned location data matches input attrs exactly | Priority: medium
|
|
61
|
+
- **B030** — Tests: update_spec.rb verify non-updated fields remain unchanged | Priority: low
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Suggestions for Next Campaign
|
|
66
|
+
|
|
67
|
+
**B015 should be closed immediately** — the fix is already in the code. Update BACKLOG.md, don't plan a campaign for it.
|
|
68
|
+
|
|
69
|
+
Next meaningful work:
|
|
70
|
+
1. **B023** — file_collector_spec: JSON, aider, error paths (last test-coverage gap)
|
|
71
|
+
2. **B028** — cli_spec file body assertions (from this audit)
|
|
72
|
+
3. **B029** — add_spec data integrity assertions
|
|
73
|
+
4. These are small — could bundle into one campaign with B030
|
|
74
|
+
|
|
75
|
+
Or pivot to **architectural** items (B011 — extract VatCLI, B020 — split S3Operations) which are larger but unblock performance work (B007/B008).
|
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appydave-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.76.
|
|
4
|
+
version: 0.76.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cruwys
|
|
@@ -300,12 +300,15 @@ files:
|
|
|
300
300
|
- docs/planning/bugfix-and-security/AGENTS.md
|
|
301
301
|
- docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md
|
|
302
302
|
- docs/planning/bugfix-and-security/assessment.md
|
|
303
|
+
- docs/planning/final-test-gaps/AGENTS.md
|
|
304
|
+
- docs/planning/final-test-gaps/IMPLEMENTATION_PLAN.md
|
|
303
305
|
- docs/planning/fr2-gpt-context-help/AGENTS.md
|
|
304
306
|
- docs/planning/fr2-gpt-context-help/IMPLEMENTATION_PLAN.md
|
|
305
307
|
- docs/planning/fr2-gpt-context-help/assessment.md
|
|
306
308
|
- docs/planning/next-round-brief.md
|
|
307
309
|
- docs/planning/test-coverage-gaps/AGENTS.md
|
|
308
310
|
- docs/planning/test-coverage-gaps/IMPLEMENTATION_PLAN.md
|
|
311
|
+
- docs/planning/test-coverage-gaps/assessment.md
|
|
309
312
|
- docs/specs/fr-002-gpt-context-help-system.md
|
|
310
313
|
- docs/specs/fr-003-jump-location-tool.md
|
|
311
314
|
- docs/specs/zsh-history-tool.md
|