test(import): a folder of only header-only files kept no record and refuses (improvise-8jk6.6)

After merging PR #314, a header-only file's seeded File proposal means the
category check alone no longer refuses an import that kept no record.
nothing_to_import does, and this pins it. The docs now name from_merge
(switched to from_csv in the merge) among the CSV entry points.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Claude (agent-headless-import)
2026-09-24 22:12:02 -07:00
committed by Edward Langley
parent 9b8b061a93
commit efaa505059
3 changed files with 34 additions and 3 deletions
+13 -3
View File
@@ -670,8 +670,10 @@ This is not caution for its own sake. When the parser first changed, eleven
tests in four files failed. Every one handed parser output to
`ImportPipeline::new`, the JSON constructor, which would read every column as
text and propose `Revenue` as a Category. Production had the same shape at all
three CSV entry points: `main.rs`'s single file and merge, and
`ImportJsonHeadless`. Now that mistake does not compile. Two holes remain, and
three CSV entry points: `main.rs`'s single file, `ImportPipeline::from_merge`
(the merge path, from PR #314), and `ImportJsonHeadless`. `from_merge` merged
in with `Self::new` and now calls `Self::from_csv`. Now that mistake does not
compile. Two holes remain, and
both take a deliberate step. `ImportPipeline::records` is still a public
`Vec<Value>`, and a test helper once copied it out of a CSV pipeline into a
JSON one. And `CsvRecords` derefs to a slice that `.to_vec()` will copy.
@@ -708,6 +710,14 @@ records were skipped as not JSON objects`, or `the source has no records`. The
wizard asks it first on `ReviewProposals`, where another array path can still
be chosen.
One case meets PR #314's "a header-only file is still a file". A folder whose
CSVs are **all** header-only has no records, only sources. Built from
`from_merge`'s seeded proposals alone, it would save `File` items, empty
columns and one empty records view per file. It is refused here, because it
kept no record. A header-only file *beside* files with rows is unaffected,
since some record was kept. Whether an all-header-only folder should instead
save its structure is a question for the user on the PR.
**A partial skip stays a warning.** Some records kept and some skipped still
builds, exits 0, and warns with a count: `Skipped 1 of 3 records that were not
JSON objects`. The argument: a non-object in an array of records is not a
@@ -717,7 +727,7 @@ trailing `null` or a stray scalar in a hand-edited file. Every record that
Making it fatal would fail every import that carries one stray element.
Making it a distinct non-zero exit that still writes gives a contract where
`import … && next` stops even though the file was written. That is a question
for the user (PR #TBD), and `an_import_that_skips_some_records_warns_with_a_count_and_still_writes`
put to the user on the PR that fixed 8jk6.6, and `an_import_that_skips_some_records_warns_with_a_count_and_still_writes`
pins the current answer so that changing it is a decision.
### A folder of CSVs is one sparse model, with a view per file (improvise-lpzu)
+11
View File
@@ -1894,3 +1894,14 @@ improvise-8jk6.12 (4). A `region` of `" "` is kept as a record with no
predates this PR (improvise-ych), but the sparse-record rule now rests on it:
without it the value becomes an item named `" "`. Rival F4 (the reviewer's
fault) fails it.
### a_folder_of_only_header_only_files_keeps_no_record_and_refuses
improvise-8jk6.6 meeting PR #314's rule that a header-only file is still a
file. Written after merging `main` at `c91cc055`, where the two rules first
met. The file seeds give the pipeline a `File` Category proposal even with no
records. So without `nothing_to_import` the build succeeds and saves `File`
items and empty views: the category check alone cannot refuse. The `setup`
assertion proves that seeded proposal exists, so the test is not passing only
because there was no category. **R7**, the check removed from the build, fails
it. Whether this case should refuse is put to the user on the PR.