'use strict'; const test = require('node:test'); const H = require('./public-cli-helper.cjs'); function rawAction(nodes) { return ` ${nodes} `; } test('public expand/build preserves an edited supported pushfloat without integer truncation', () => { const work = H.testCase('pushfloat'); const source = H.expanded(work, rawAction('')); H.assert.match(source.xml, /pushfloat 85\.25/); const edited = source.xml.replace('pushfloat 85.25', 'pushfloat 24.5'); H.assert.notEqual(edited, source.xml); const rebuilt = H.build(work, edited); H.succeeded(rebuilt.result); H.assert.equal(Number(H.element(rebuilt.raw, 'float', 'action', 180).val), 24.5); }); test('public expand/build distinguishes a numeric-looking quoted string from an integer pool value', () => { const work = H.testCase('quoted-numeric'); const source = H.expanded(work, rawAction(` `)); H.assert.match(source.xml, /pushconst "007"/); H.assert.match(source.xml, /pushconst 7(?:\s|<)/); const rebuilt = H.build(work, source.xml); H.succeeded(rebuilt.result); H.assert.equal(H.element(rebuilt.raw, 'constant', 'str', '007').str, '007'); H.assert.equal(H.element(rebuilt.raw, 'constant', 'num', '7').num, '7'); // This .const was generated by production build(), not by the fake converter. const table = H.fs.readFileSync(rebuilt.output.replace(/\.apt$/, '.const')); H.assert.equal(table.readUInt32LE(0x18), 2); const values = []; for (let i = 0; i < 2; i++) { const offset = 0x20 + i * 8; const type = table.readUInt32LE(offset); const value = table.readUInt32LE(offset + 4); values.push(type === 1 ? { type: 'string', value: table.subarray(value, table.indexOf(0, value)).toString('ascii') } : { type: 'integer', value }); } H.assert.deepEqual(values, [{ type: 'string', value: '007' }, { type: 'integer', value: 7 }]); }); test('public pushdata build retains quoted "007" and integer 7 as data nodes and correctly typed CONST values', () => { const work = H.testCase('pushdata-types'); const source = H.expanded(work, rawAction(` `)); H.assert.match(source.xml, /pushdata "007", 7/); const rebuilt = H.build(work, source.xml); H.succeeded(rebuilt.result); const body = rebuilt.raw.match(/]*>([\s\S]*?)<\/pushdata>/); H.assert.ok(body); const children = Array.from(body[1].matchAll(/<(data|constant)\b[^>]*>/g), match => ({ tag: match[1], attrs: H.attributes(match[0]) })); H.assert.equal(children.length, 2); H.assert.deepEqual(children.map(child => child.tag), ['data', 'data'], 'xml2apt expects data children; constant children previously crashed the native converter'); H.assert.equal(children[0].attrs.str, '007'); H.assert.equal(children[0].attrs.num, undefined); H.assert.equal(Number(children[1].attrs.num), 7); H.assert.equal(children[1].attrs.str, undefined); const records = H.constRecords(rebuilt.output); H.assert.deepEqual(records.map(record => ({ type: record.type, value: record.value })), [{ type: 1, value: '007' }, { type: 7, value: 7 }]); H.assert.equal(Number(children[0].attrs.val), 0); H.assert.equal(Number(children[1].attrs.val), 1); });