diff --git a/package.json b/package.json index c552d25..2db7458 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "droidnet-command-library", - "version": "2.1.0", + "version": "2.1.1", "description": "Schema-driven encoder/decoder and visual composer for building serial commands to control a vibrant community of Astromech droid components. Anyone can add their board by editing a JSON library — no code changes required.", "license": "MPL-2.0", "keywords": [ diff --git a/src/droidnet-command-library.js b/src/droidnet-command-library.js index a583b48..126ec65 100644 --- a/src/droidnet-command-library.js +++ b/src/droidnet-command-library.js @@ -230,7 +230,9 @@ .sort((a, b) => b.length - a.length); // longest-first so multi-char codes win return '(' + codes.join('|') + ')'; } - return '(\\d+)'; + // Allow an optional leading '-' so int params with a negative range + // (e.g. a rotary speed of -80) re-parse to a structured step, not a raw one. + return '(-?\\d+)'; }); return { re: new RegExp('^' + pattern + '$'), groups }; } diff --git a/test/web.test.js b/test/web.test.js index 02c624d..372886f 100644 --- a/test/web.test.js +++ b/test/web.test.js @@ -64,3 +64,27 @@ describe('hosted site — reference data contract', () => { expect(bad).toEqual([]); }); }); + +describe('engine — negative-range int params round-trip (regression)', () => { + let cb; + beforeEach(() => { + cb = loadEngine(); + const { manifest, boards } = readCatalog(); + cb.loadLibrary(boards.map(b => JSON.parse(JSON.stringify(b))), { libraryVersion: manifest.libraryVersion }); + }); + + // A non-enum int param whose range allows negatives (uppity.rotary.spin min -100, + // uppity.rotary.rel min -180). The matcher must accept a leading '-' so a pasted / + // reloaded value re-parses to a structured, editable step instead of a raw step. + test("match() accepts a leading '-' for int params", () => { + const spin = cb.match(':PR-80'); + expect(spin).toBeTruthy(); + expect(spin.commandId).toBe('uppity.rotary.spin'); + expect(spin.params.speed).toBe('-80'); + + const rel = cb.match(':PD-90'); + expect(rel).toBeTruthy(); + expect(rel.commandId).toBe('uppity.rotary.rel'); + expect(rel.params.degrees).toBe('-90'); + }); +});