UNPKG

codeschmiede-toolkit

Version:

A/B Test Development Toolkit

170 lines (137 loc) 5.14 kB
'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); const os = require('os'); const path = require('path'); const { spawnSync } = require('child_process'); const { transformSource, processFile } = require('../lib/inline-html.cjs'); function evaluateValue(source) { const fn = new Function(`${source}; return value;`); return fn(); } test('transforms mixed static and interpolated multiline template strings', () => { const source = [ 'const value = 5;', 'const markup = `<div>', ' <h1>Test Value</h1>', ' <p>${value}</p>', '</div>`;', ].join('\n'); const expected = [ 'const value = 5;', 'const markup = \'<div>\' +', ' \'<h1>Test Value</h1>\' +', ' `<p>${value}</p>` +', ' \'</div>\';', ].join('\n'); assert.equal(transformSource(source), expected); }); test('keeps multiple interpolations on the same line intact', () => { const source = [ 'const value = 5;', 'const markup = `<p>${value}-${value + 1}</p>', ' <span>Static</span>`;', ].join('\n'); const expected = [ 'const value = 5;', 'const markup = `<p>${value}-${value + 1}</p>` +', ' \'<span>Static</span>\';', ].join('\n'); assert.equal(transformSource(source), expected); }); test('does not transform single-line template strings', () => { const source = 'const value = `<div>${count}</div>`;'; assert.equal(transformSource(source), source); }); test('removes only empty boundary lines and keeps inner blank lines', () => { const source = [ 'const value = `', '', ' <div>', '', ' <span>Value</span>', ' </div>', '', '`;', ].join('\n'); const expected = [ 'const value = \'<div>\' +', ' \'\' +', ' \'<span>Value</span>\' +', ' \'</div>\';', ].join('\n'); assert.equal(transformSource(source), expected); }); test('preserves runtime content for quotes, backticks and backslashes', () => { const source = [ 'const quote = "It\\\'s";', 'const tick = "tick";', 'const value = `<div class="${quote}">', 'Backslash \\\\ and \\`${tick}\\`', '</div>`;', ].join('\n'); const transformed = transformSource(source); assert.notEqual(transformed, source); assert.equal( evaluateValue(transformed), '<div class="It\'s">Backslash \\ and `tick`</div>' ); }); test('does not transform tagged template strings', () => { const source = [ 'const value = html`', ' <div>${count}</div>', '`;', ].join('\n'); assert.equal(transformSource(source), source); }); test('does not rewrite files when nothing changed', () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'inlinehtml-unchanged-')); const filePath = path.join(tempDir, 'example.js'); const source = 'const value = `<div>${count}</div>`;'; fs.writeFileSync(filePath, source, 'utf8'); const unchangedDate = new Date('2020-01-01T00:00:00.000Z'); fs.utimesSync(filePath, unchangedDate, unchangedDate); const beforeStat = fs.statSync(filePath); const result = processFile(filePath); const afterStat = fs.statSync(filePath); assert.equal(result.status, 'unchanged'); assert.equal(afterStat.mtimeMs, beforeStat.mtimeMs); assert.equal(fs.readFileSync(filePath, 'utf8'), source); }); test('reports parse errors and leaves the file untouched', () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'inlinehtml-error-')); const filePath = path.join(tempDir, 'broken.js'); const source = 'const value = `unterminated;\n'; fs.writeFileSync(filePath, source, 'utf8'); const result = processFile(filePath); assert.equal(result.status, 'error'); assert.match(result.error.message, /Unterminated template/i); assert.equal(fs.readFileSync(filePath, 'utf8'), source); }); test('cli rewrites files in place and becomes a no-op on the second run', () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'inlinehtml-cli-')); const srcDir = path.join(tempDir, 'src'); const filePath = path.join(srcDir, 'variation-01.js'); fs.mkdirSync(srcDir); fs.writeFileSync(filePath, [ 'const value = 5;', 'const markup = `<div>', ' <p>${value}</p>', '</div>`;', ].join('\n'), 'utf8'); const cliPath = path.resolve(__dirname, '../bin/inlinehtml.cjs'); const firstRun = spawnSync(process.execPath, [cliPath], { cwd: tempDir, encoding: 'utf8', }); assert.equal(firstRun.status, 0, firstRun.stderr); assert.match(firstRun.stdout, /updated src[\\/]+variation-01\.js/); const secondRun = spawnSync(process.execPath, [cliPath], { cwd: tempDir, encoding: 'utf8', }); assert.equal(secondRun.status, 0, secondRun.stderr); assert.match(secondRun.stdout, /unchanged src[\\/]+variation-01\.js/); });