@ansonlai/docx-redline-js 0.1.6 → 0.2.1

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.
@@ -1,48 +1,104 @@
1
1
  # Validation
2
2
 
3
3
  This package works on OOXML strings and intentionally leaves `.docx` zip
4
- packaging to consumers. Release validation should therefore check both XML
5
- invariants and at least one real OOXML consumer.
4
+ packaging to consumers (release *tooling* assembles minimal `.docx` fixtures
5
+ with a script-local zip writer; the published library still has no zip
6
+ dependency).
6
7
 
7
- ## Automated Checks
8
+ The test suite verifies the accept/reject round-trip invariant using the
9
+ library's own transforms. Because a shared misconception between the
10
+ generator and the resolver would pass those tests silently, release
11
+ validation adds **independent oracles**: Microsoft Word, LibreOffice, and
12
+ the ECMA-376 schemas.
8
13
 
9
- Run:
14
+ ## Automated Checks (every `npm test`)
10
15
 
11
16
  ```bash
12
- npm test
17
+ npm test # includes tests/roundtrip_fuzz_tests.mjs (seeded, deterministic)
13
18
  npm run test:isolation
14
19
  npm run check:types
15
20
  ```
16
21
 
17
- ## Export Fixture Parts
22
+ The fuzz harness generates random paragraph structures and edits, then
23
+ asserts the round-trip invariant plus `validateRedlineOoxml` on each case.
24
+ Tune or reproduce with:
18
25
 
19
- Run:
26
+ ```bash
27
+ FUZZ_SEED=<seed> FUZZ_ITERATIONS=<n> node tests/roundtrip_fuzz_tests.mjs
28
+ ```
29
+
30
+ A failing case prints its exact reproduction command.
31
+
32
+ ## Runtime Guardrail
33
+
34
+ `validateRedlineOoxml(oxml)` (exported from `index.js`) runs the structural
35
+ invariants at runtime and returns `{ valid, issues }`. Downstream packagers
36
+ should call it before writing engine output into `word/document.xml`.
37
+
38
+ ## Export Fixtures
20
39
 
21
40
  ```bash
22
41
  node scripts/export-validation-fixtures.mjs
23
42
  ```
24
43
 
25
- The script writes generated `word/document.xml` payloads to
26
- `tmp/validation-docx/`. If a case emits numbering XML, it writes that alongside
27
- the document XML. The script does not create full `.docx` files because the
28
- library intentionally avoids a zip dependency.
44
+ Writes to `tmp/validation-docx/`, per case:
29
45
 
30
- ## Manual Consumer Checks
46
+ - `<name>.document.xml` generated `word/document.xml` payload
47
+ - `<name>.docx` — minimal assembled package
48
+ - `<name>.expected.json` — expected accept-all / reject-all plain text,
49
+ derived from edit *intent* (not from this library's transforms), so
50
+ external consumers act as independent oracles
31
51
 
32
- To inspect in Microsoft Word or LibreOffice:
52
+ ## Word Differential Check (Windows, desktop Word)
33
53
 
34
- 1. Start from a minimal valid `.docx` package.
35
- 2. Replace `word/document.xml` with one generated `*.document.xml` fixture.
36
- 3. Add matching `word/numbering.xml` when present.
37
- 4. Open the document and confirm the file opens without repair prompts and the
38
- expected tracked changes are visible.
54
+ ```bash
55
+ node scripts/export-validation-fixtures.mjs
56
+ npm run smoke:word:diff
57
+ ```
39
58
 
40
- On Windows with desktop Word installed, the optional COM smoke script described
41
- in the improvement plan can be used to open a completed `.docx` and count
42
- revisions.
59
+ For each fixture, desktop Word opens the `.docx`, confirms revisions are
60
+ visible, runs **AcceptAllRevisions**, and compares the document text to the
61
+ expected modified text; then reopens and runs **RejectAllRevisions** and
62
+ compares to the original text. This is the strongest check available: Word
63
+ itself resolves the revisions this library generated.
43
64
 
44
- With LibreOffice installed, a quick parser check is:
65
+ The older `npm run smoke:word -- path/to/file.docx` open-only smoke check
66
+ remains available for ad-hoc files.
67
+
68
+ ## Schema Validation (ECMA-376 transitional XSD)
45
69
 
46
70
  ```bash
47
- soffice --headless --convert-to pdf path/to/fixtures/*.docx
71
+ node scripts/export-validation-fixtures.mjs
72
+ bash scripts/validate-fixtures-xsd.sh
48
73
  ```
74
+
75
+ Downloads (and caches in `.cache/ooxml-schemas/`) the transitional
76
+ wordprocessingml schemas from ECMA-376 Part 4, patches the `xml:` namespace
77
+ import to resolve offline, and validates every `*.document.xml` fixture with
78
+ `xmllint`. Requires `curl`, `unzip`, and `xmllint` (`libxml2-utils` on
79
+ Debian/Ubuntu; available on Windows via conda/msys).
80
+
81
+ ## LibreOffice Consumer Check
82
+
83
+ ```bash
84
+ cd tmp/validation-docx
85
+ soffice --headless --convert-to pdf --outdir converted *.docx
86
+ ```
87
+
88
+ A second independent OOXML consumer parsing the fixtures without error.
89
+
90
+ ## Continuous Validation
91
+
92
+ `.github/workflows/validation.yml` runs nightly (and on demand via
93
+ `workflow_dispatch`):
94
+
95
+ 1. **xsd-schema** — exports fixtures and validates them against the
96
+ ECMA-376 transitional `wml.xsd`.
97
+ 2. **libreoffice** — exports fixtures and converts them with headless
98
+ LibreOffice.
99
+ 3. **fuzz-extended** — 20,000 fuzz round-trip cases with a date-derived
100
+ seed, so every night explores new inputs. A failure log includes the
101
+ exact `FUZZ_SEED` reproduction command.
102
+
103
+ The Word differential check stays manual because it requires desktop Word;
104
+ run it before tagging a release.