@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.
@@ -0,0 +1,133 @@
1
+ param(
2
+ [string]$FixturesDir = "tmp/validation-docx"
3
+ )
4
+
5
+ # Differential validation against desktop Microsoft Word (the authoritative
6
+ # OOXML consumer). For each generated fixture, Word itself accepts all
7
+ # revisions and then rejects all revisions, and the resulting document text
8
+ # is compared to the expected outcomes recorded at generation time. This
9
+ # makes Word an independent oracle for the redline engine instead of
10
+ # verifying the library against its own accept/reject transforms.
11
+ #
12
+ # Usage:
13
+ # node scripts/export-validation-fixtures.mjs
14
+ # npm run smoke:word:diff
15
+
16
+ $ErrorActionPreference = 'Stop'
17
+
18
+ function Get-NormalizedText([string]$text) {
19
+ if ($null -eq $text) { return '' }
20
+ $text = $text -replace [string][char]7, ' ' # table cell markers
21
+ return ($text -replace '\s+', ' ').Trim()
22
+ }
23
+
24
+ $resolvedDir = Resolve-Path -LiteralPath $FixturesDir -ErrorAction SilentlyContinue
25
+ if (-not $resolvedDir) {
26
+ Write-Error "Fixtures directory '$FixturesDir' not found. Run: node scripts/export-validation-fixtures.mjs"
27
+ exit 1
28
+ }
29
+
30
+ $expectations = Get-ChildItem -LiteralPath $resolvedDir -Filter '*.expected.json' | Sort-Object Name
31
+ if ($expectations.Count -eq 0) {
32
+ Write-Error "No *.expected.json fixtures in '$resolvedDir'. Run: node scripts/export-validation-fixtures.mjs"
33
+ exit 1
34
+ }
35
+
36
+ $word = $null
37
+ $failures = 0
38
+ $results = @()
39
+
40
+ function Open-FixtureDocument($word, [string]$path) {
41
+ # Single-argument Open: Windows PowerShell 5.1 COM binding rejects the
42
+ # long optional-parameter signature. Defaults leave the document
43
+ # writable, which accept/reject requires; nothing is ever saved.
44
+ return $word.Documents.Open($path)
45
+ }
46
+
47
+ try {
48
+ $word = New-Object -ComObject Word.Application
49
+ $word.Visible = $false
50
+ $word.DisplayAlerts = 0 # wdAlertsNone
51
+
52
+ foreach ($expectationFile in $expectations) {
53
+ $name = $expectationFile.BaseName -replace '\.expected$', ''
54
+ $docxPath = Join-Path $resolvedDir "$name.docx"
55
+ if (-not (Test-Path -LiteralPath $docxPath)) {
56
+ Write-Warning "SKIP ${name}: no matching .docx"
57
+ continue
58
+ }
59
+
60
+ # -Encoding UTF8 is required: Windows PowerShell 5.1 otherwise reads
61
+ # BOM-less UTF-8 sidecars as ANSI and garbles non-ASCII expectations.
62
+ $expected = Get-Content -LiteralPath $expectationFile.FullName -Raw -Encoding UTF8 | ConvertFrom-Json
63
+ $expectedAccepted = Get-NormalizedText $expected.expectedAcceptedText
64
+ $expectedRejected = Get-NormalizedText $expected.expectedRejectedText
65
+ $caseFailed = $false
66
+ $document = $null
67
+
68
+ # Phase 1: open cleanly, revisions present, accept-all matches intent.
69
+ try {
70
+ $document = Open-FixtureDocument $word ([string]$docxPath)
71
+ $revisionCount = $document.Revisions.Count
72
+ if ($revisionCount -lt 1) {
73
+ Write-Output "FAIL ${name}: Word sees no tracked revisions"
74
+ $caseFailed = $true
75
+ }
76
+ else {
77
+ $document.AcceptAllRevisions()
78
+ $acceptedText = Get-NormalizedText $document.Content.Text
79
+ if ($acceptedText -ne $expectedAccepted) {
80
+ Write-Output "FAIL ${name}: accept-all mismatch"
81
+ Write-Output " expected: $expectedAccepted"
82
+ Write-Output " actual: $acceptedText"
83
+ $caseFailed = $true
84
+ }
85
+ }
86
+ }
87
+ catch {
88
+ Write-Output "FAIL ${name}: Word could not open/accept: $($_.Exception.Message)"
89
+ $caseFailed = $true
90
+ }
91
+ finally {
92
+ if ($null -ne $document) { $document.Close(0) | Out-Null; $document = $null }
93
+ }
94
+
95
+ # Phase 2: fresh open, reject-all restores the original text.
96
+ if (-not $caseFailed) {
97
+ try {
98
+ $document = Open-FixtureDocument $word ([string]$docxPath)
99
+ $document.RejectAllRevisions()
100
+ $rejectedText = Get-NormalizedText $document.Content.Text
101
+ if ($rejectedText -ne $expectedRejected) {
102
+ Write-Output "FAIL ${name}: reject-all mismatch"
103
+ Write-Output " expected: $expectedRejected"
104
+ Write-Output " actual: $rejectedText"
105
+ $caseFailed = $true
106
+ }
107
+ }
108
+ catch {
109
+ Write-Output "FAIL ${name}: Word could not open/reject: $($_.Exception.Message)"
110
+ $caseFailed = $true
111
+ }
112
+ finally {
113
+ if ($null -ne $document) { $document.Close(0) | Out-Null; $document = $null }
114
+ }
115
+ }
116
+
117
+ if ($caseFailed) {
118
+ $failures++
119
+ $results += "FAIL $name"
120
+ }
121
+ else {
122
+ Write-Output "PASS ${name} (revisions: $revisionCount)"
123
+ $results += "PASS $name"
124
+ }
125
+ }
126
+ }
127
+ finally {
128
+ if ($null -ne $word) { $word.Quit() | Out-Null }
129
+ }
130
+
131
+ Write-Output ""
132
+ Write-Output "Word differential: $($results.Count - $failures)/$($results.Count) fixtures passed."
133
+ if ($failures -gt 0) { exit 1 }