Skip to content

Commit 7dc11e4

Browse files
committed
test: verify gs1 composite references
1 parent 275356d commit 7dc11e4

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

tests/gs1-composite-core.test.mjs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import assert from 'node:assert/strict'
2+
import { createHash } from 'node:crypto'
3+
import test from 'node:test'
4+
5+
import {
6+
compactGs1Composite,
7+
getGs1CompositeBitCapacities,
8+
parseGs1Elements,
9+
} from '../libs/GS1CompositeCompaction.js'
10+
import {
11+
GS1_CC_A_VARIANTS,
12+
Gs1CompositeCore,
13+
} from '../libs/GS1CompositeCore.js'
14+
15+
const REFERENCE_FIXTURES = [
16+
['(01)09521234543213(3103)000123', 'a', 2, '14f78ac1a04a6317dcaedbf3039f1eece74584447654c53572c8ab0bd1cfc8c0'],
17+
['(01)09521234543213(3103)000123', 'b', 2, 'cd87a5481a31592ebaa644c288f69e320a24a07d9a6463294a817a4d85387cc1'],
18+
['(01)09521234543213(3103)000123', 'c', 4, '737d5d1ea6e33a4fabbf4503651d23e9024c10520d8365a5941113601aee71cb'],
19+
['(21)A12345678', 'a', 2, '4158ad3a653e87747b05908194ab83e684ce718545fffc63b2f5fa47f4e94748'],
20+
['(21)A12345678', 'b', 2, '2fa4bb2d4336640a1ade3482c5be92af6be8d968dc1be79fa157f3a477ee440b'],
21+
['(21)A12345678', 'c', 4, '61498268b13ab20ef1651f16993c2444dc08271d398873cb1c7a1d537fe41292'],
22+
['(99)1234-abcd', 'a', 2, '18b26e18282a316a07c385ba36dc1fc404bbc2ea6c1507133f70d1d1b2fec151'],
23+
['(99)1234-abcd', 'b', 2, '44bcc2b11de93544150ebb5ade8bf3202749cfdf73dbf0017dd35443a495dd87'],
24+
['(99)1234-abcd', 'c', 4, '26a5e63c398fd0824c64b8b778094233dd89c67091bf2d51d75618bbf1fb8697'],
25+
['(235)5vBZIF%!', 'a', 2, 'cf8b26892ce989777c5c0ce0cfc3c5de62b39a41a490003da129719b212db49e'],
26+
['(235)5vBZIF%!', 'b', 2, 'f8715958dca527167594d3132772c182e7247e1eb5897d2aa339a26eaf672f89'],
27+
['(235)5vBZIF%!', 'c', 4, 'f5ac9597940f7ece34b728e335ddf8510380d4f03afbdf0479b9a038702936f9'],
28+
['(01)09521234543213(3103)000123', 'a', 3, '6d7d3c42f77241b125e1e06063129474fd27e95223fdbffa3b3ccafff28af2dd'],
29+
['(01)09521234543213(3103)000123', 'a', 4, '6a29ed5b9ce82d8cd96c780ae5408a56caac3325194420252a7a77ce363d4d0e'],
30+
['(01)09521234543213(3103)000123', 'b', 3, '18ce8a12cf42d3acc19bdb35cd7dbae39a6fb55aed5242dae15951aff561e1b2'],
31+
['(01)09521234543213(3103)000123', 'b', 4, '78214ff7215ea8e728050d2e8ab6170bb592e32a1c4e6e32e3c553c7e53a92b1'],
32+
]
33+
34+
function fingerprint(modules) {
35+
const bits = modules.map((row) => row.map(Number).join('')).join('')
36+
return createHash('sha256').update(bits).digest('hex')
37+
}
38+
39+
function assertBooleanMatrix(result) {
40+
assert.equal(result.modules.length, result.rows)
41+
assert.ok(result.modules.every((row) => (
42+
row.length === result.columns && row.every((module) => typeof module === 'boolean')
43+
)))
44+
}
45+
46+
test('publishes all 17 standardized CC-A layouts', () => {
47+
assert.equal(GS1_CC_A_VARIANTS.length, 17)
48+
assert.deepEqual(
49+
GS1_CC_A_VARIANTS.map((variant) => variant.id),
50+
[
51+
'A-2x5', 'A-2x6', 'A-2x7', 'A-2x8', 'A-2x9', 'A-2x10', 'A-2x12',
52+
'A-3x4', 'A-3x5', 'A-3x6', 'A-3x7', 'A-3x8',
53+
'A-4x3', 'A-4x4', 'A-4x5', 'A-4x6', 'A-4x7',
54+
],
55+
)
56+
assert.equal(GS1_CC_A_VARIANTS.find((variant) => variant.id === 'A-3x4').moduleColumns, 72)
57+
})
58+
59+
test('parses bracketed GS1 data and inserts separators after variable fields', () => {
60+
const elements = parseGs1Elements('(01)09521234543213(10)ABC123(17)300101')
61+
assert.deepEqual(elements.map(({ ai, value, separator }) => ({ ai, value, separator })), [
62+
{ ai: '01', value: '09521234543213', separator: false },
63+
{ ai: '10', value: 'ABC123', separator: true },
64+
{ ai: '17', value: '300101', separator: false },
65+
])
66+
67+
const raw = parseGs1Elements(`0109521234543213\x1d10ABC123`)
68+
assert.equal(raw.length, 2)
69+
assert.equal(raw[0].separator, true)
70+
})
71+
72+
test('selects exact CC-A and CC-B bit capacities', () => {
73+
assert.deepEqual(getGs1CompositeBitCapacities('a', 2), [59, 78, 88, 108, 118, 138, 167])
74+
assert.deepEqual(getGs1CompositeBitCapacities('b', 4), [56, 96, 152, 208, 264, 352, 496, 672, 840, 1016, 1184])
75+
assert.equal(compactGs1Composite('(01)09521234543213', { version: 'a', columns: 2 }).bitCapacity, 59)
76+
})
77+
78+
test('matches independent BWIPP module references for CC-A, CC-B and CC-C', () => {
79+
for (const [data, version, columns, expected] of REFERENCE_FIXTURES) {
80+
const result = new Gs1CompositeCore(data, { version, columns }).generate()
81+
assertBooleanMatrix(result)
82+
assert.equal(fingerprint(result.modules), expected, `${version}/${columns}: ${data}`)
83+
}
84+
})
85+
86+
test('shares PDF417 codeword, error-correction and layout machinery', () => {
87+
const a = new Gs1CompositeCore('(01)09521234543213', { version: 'a' }).generate()
88+
const b = new Gs1CompositeCore('(01)09521234543213', { version: 'b' }).generate()
89+
const c = new Gs1CompositeCore('(01)09521234543213', { version: 'c', columns: 4 }).generate()
90+
91+
assert.equal(a.version, 'CC-A')
92+
assert.equal(a.dataCodewords.length + a.errorCodewords.length, a.dataColumns * a.rows)
93+
assert.equal(b.version, 'CC-B')
94+
assert.equal(b.dataCodewords[0], 920)
95+
assert.equal(c.version, 'CC-C')
96+
assert.equal(c.dataCodewords[1], 920)
97+
assert.equal(c.dataCodewords[0], c.dataCodewords.length)
98+
})
99+
100+
test('supports large CC-C payloads and deterministic repeated generation', () => {
101+
const data = `(99)${'A'.repeat(500)}`
102+
const core = new Gs1CompositeCore(data, { version: 'c', columns: 6 })
103+
const first = core.generate()
104+
const second = core.generate()
105+
assert.equal(first.variant, 'C-12x30-ecl4')
106+
assert.deepEqual(second.codewords, first.codewords)
107+
assert.deepEqual(second.modules, first.modules)
108+
})
109+
110+
test('validates versions, columns, syntax, characters and capacity', () => {
111+
assert.throws(() => new Gs1CompositeCore('(01)123', { version: 'x' }).generate(), /version/)
112+
assert.throws(() => new Gs1CompositeCore('(01)123', { version: 'a', columns: 1 }).generate(), /2 to 4/)
113+
assert.throws(() => new Gs1CompositeCore('(01)', { version: 'a' }).generate(), /has no value/)
114+
assert.throws(() => new Gs1CompositeCore('(99)€', { version: 'a' }).generate(), /capacity/)
115+
assert.throws(
116+
() => new Gs1CompositeCore(`(99)${'A'.repeat(200)}`, { version: 'b', columns: 4 }).generate(),
117+
/capacity/,
118+
)
119+
})

0 commit comments

Comments
 (0)