@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
22import { readFileSync } from "node:fs" ;
33import { fileURLToPath } from "node:url" ;
44import { dirname , resolve } from "node:path" ;
5- import { buildBwipOptions , getDisplaySize , getEanUpcLayout } from "./bwipHelpers" ;
5+ import { buildBwipOptions , getDisplaySize , getEanUpcLayout , parseZplCode128Escapes } from "./bwipHelpers" ;
66import type { LabelObject } from "../../registry" ;
77
88describe ( "getEanUpcLayout" , ( ) => {
@@ -217,3 +217,88 @@ describe("getDisplaySize coverage (ZPL-first policy)", () => {
217217 expect ( missing , `Missing explicit case for: ${ missing . join ( ", " ) } ` ) . toEqual ( [ ] ) ;
218218 } ) ;
219219} ) ;
220+
221+ describe ( "parseZplCode128Escapes" , ( ) => {
222+ it ( "returns null for plain ASCII (no escape sequences)" , ( ) => {
223+ expect ( parseZplCode128Escapes ( "ABC123" ) ) . toBeNull ( ) ;
224+ expect ( parseZplCode128Escapes ( "" ) ) . toBeNull ( ) ;
225+ } ) ;
226+
227+ it ( "translates >5 to FNC1" , ( ) => {
228+ expect ( parseZplCode128Escapes ( "AB>5CD" ) ) . toBe ( "AB^FNC1CD" ) ;
229+ } ) ;
230+
231+ it ( "translates >9 to FNC1 only at the start of the field (per ZPL spec)" , ( ) => {
232+ expect ( parseZplCode128Escapes ( ">91234" ) ) . toBe ( "^FNC11234" ) ;
233+ // Mid-string >9 is just a Code-C invocation; bwip auto-mode picks C
234+ // for the digit run, so we drop the escape entirely.
235+ expect ( parseZplCode128Escapes ( "A>9123" ) ) . toBe ( "A123" ) ;
236+ } ) ;
237+
238+ it ( "translates >6/>7/>8 to FNC2/FNC3/FNC4" , ( ) => {
239+ expect ( parseZplCode128Escapes ( "A>6B" ) ) . toBe ( "A^FNC2B" ) ;
240+ expect ( parseZplCode128Escapes ( "A>7B" ) ) . toBe ( "A^FNC3B" ) ;
241+ expect ( parseZplCode128Escapes ( "A>8B" ) ) . toBe ( "A^FNC4B" ) ;
242+ } ) ;
243+
244+ it ( "translates >0 to a literal `>`" , ( ) => {
245+ expect ( parseZplCode128Escapes ( "A>0B>5" ) ) . toBe ( "A>B^FNC1" ) ;
246+ } ) ;
247+
248+ it ( "drops >: and >; (subset switches — bwip auto-mode picks the subset)" , ( ) => {
249+ expect ( parseZplCode128Escapes ( "A>:B>;C>5" ) ) . toBe ( "ABC^FNC1" ) ;
250+ } ) ;
251+
252+ it ( "doubles literal `^` so bwip parsefnc does not treat it as an escape" , ( ) => {
253+ expect ( parseZplCode128Escapes ( "A^B>5" ) ) . toBe ( "A^^B^FNC1" ) ;
254+ } ) ;
255+
256+ it ( "leaves trailing `>` and unknown `>X` literal — matches firmware behaviour" , ( ) => {
257+ expect ( parseZplCode128Escapes ( "abc>" ) ) . toBeNull ( ) ;
258+ // `>z` is not a defined ZPL escape; Zebra treats it as literal `>z`.
259+ expect ( parseZplCode128Escapes ( "a>z>5" ) ) . toBe ( "a>z^FNC1" ) ;
260+ } ) ;
261+
262+ it ( "handles the reported case STRSTR>5… with auto Code-C compaction" , ( ) => {
263+ // Without translation: 21 raw Subset-B symbols.
264+ // After translation: bwip sees STRSTR + FNC1 + 16 digits, auto-switches
265+ // to Code C for the digit run → ~15 data symbols, matching firmware.
266+ expect ( parseZplCode128Escapes ( "STRSTR>52316094000242201" ) )
267+ . toBe ( "STRSTR^FNC12316094000242201" ) ;
268+ } ) ;
269+ } ) ;
270+
271+ describe ( "buildBwipOptions code128 escape handling" , ( ) => {
272+ const code128 = ( content : string ) : LabelObject =>
273+ ( {
274+ id : "1" ,
275+ type : "code128" ,
276+ x : 0 ,
277+ y : 0 ,
278+ rotation : 0 ,
279+ props : {
280+ content,
281+ height : 100 ,
282+ moduleWidth : 2 ,
283+ printInterpretation : false ,
284+ checkDigit : false ,
285+ rotation : "N" ,
286+ } ,
287+ } ) as LabelObject ;
288+
289+ it ( "uses raw Subset-B mode for plain ASCII content (existing behaviour)" , ( ) => {
290+ const opts = buildBwipOptions ( code128 ( "ABC123" ) , 1 , 8 ) ;
291+ expect ( opts ?. raw ) . toBe ( true ) ;
292+ expect ( opts ?. parsefnc ) . toBeUndefined ( ) ;
293+ expect ( typeof opts ?. text ) . toBe ( "string" ) ;
294+ expect ( ( opts ?. text as string ) . startsWith ( "^104" ) ) . toBe ( true ) ;
295+ } ) ;
296+
297+ it ( "switches to parsefnc auto-mode when ZPL escape sequences are present" , ( ) => {
298+ const opts = buildBwipOptions ( code128 ( "STRSTR>52316094000242201" ) , 1 , 8 ) ;
299+ expect ( opts ?. parsefnc ) . toBe ( true ) ;
300+ expect ( opts ?. raw ) . toBeUndefined ( ) ;
301+ expect ( opts ?. text ) . toBe ( "STRSTR^FNC12316094000242201" ) ;
302+ } ) ;
303+ } ) ;
304+
0 commit comments