diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 2a3d621..9e0fe2f 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -40,9 +40,12 @@ jobs: run: npm ci - name: 'Test' - run: | - npm test -- --reporter json --reporter-options output=${{ runner.temp }}/report-${{ matrix.os }}.json - cat ${{ runner.temp }}/report-${{ matrix.os }}.json | jq + run: npm test -- --reporter json --reporter-options output=${{ runner.temp }}/report-${{ matrix.os }}.json + + - name: 'Print Tests' + # run this step even if previous step failed + if: (success() || failure()) + run: cat ${{ runner.temp }}/report-${{ matrix.os }}.json | jq - name: 'Publish Tests' uses: 'dorny/test-reporter@v1' diff --git a/package.json b/package.json index 6e296dc..9e0c1a6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "dist/index.js", "scripts": { "build": "ncc build -o dist src/index.js", - "test": "mocha --reporter spec --timeout 5000" + "test": "mocha --reporter spec --timeout 5000 test/**.spec.js" }, "repository": { "type": "git", diff --git a/test/bootstrap.js b/test/bootstrap.js new file mode 100644 index 0000000..7ef5d42 --- /dev/null +++ b/test/bootstrap.js @@ -0,0 +1,18 @@ +'use strict'; + +// Convert all of the arguments into environment variables to get +// around hyphenated names being problematic on non-windows platforms. +const args = process.argv.splice(2); +for (let i = 0; i < args.length; i += 2) { + const key = args[i]; + const value = args[i + 1]; + if (!value) { + console.warn('missing arg value for', key); + continue; + } + + console.log('assigning arg to env', key, value); + process.env[key] = value; +} + +require('../dist'); diff --git a/test/e2e.spec.js b/test/e2e.spec.js new file mode 100644 index 0000000..d75bfb7 --- /dev/null +++ b/test/e2e.spec.js @@ -0,0 +1,117 @@ +'use strict'; + +const assert = require('assert'); +const { exec } = require('child_process'); +const { access, unlink } = require('fs/promises'); +const path = require('path'); + +const exists = async (path) => { + try { + await access(path); + return true; + } + catch { + return false; + } +}; + +/** + * @param {string} path + */ +const unlinkIfExistsAsync = async (path) => { + if (await exists(path)) { + unlink(path); + } +}; + +describe('e2e', () => { + before(async () => { + const promises = ['./basic.exe', './with-plugins.exe'] + .map(unlinkIfExistsAsync); + + await Promise.all(promises); + }); + + /** + * @typedef {{ + * customArguments?: string, + * additionalPluginPaths?: string[], + * scriptFile?: string, + * }} RunOptions + * @param {RunOptions} options + */ + const run = async (options = {}) => { + const { + customArguments, + additionalPluginPaths, + scriptFile + } = options; + + const args = []; + const env = { + ...process.env, + debug: 'true', + }; + if (customArguments) { + args.push('INPUT_ARGUMENTS', customArguments); + } + if (additionalPluginPaths && additionalPluginPaths.length) { + args.push('INPUT_ADDITIONAL-PLUGIN-PATHS', additionalPluginPaths.join('\n')); + } + if (scriptFile) { + args.push('INPUT_SCRIPT-FILE', scriptFile); + } + + // Call bootstrap.js do avoid a problem where hyphenated environment + // variables are unable to be assigned on non-windows platforms. + const programPath = require.resolve('./bootstrap'); + const testDir = path.dirname(programPath); + const cwd = path.join(testDir, '../'); + const promise = new Promise((resolve, reject) => { + exec(`node ${programPath} ${args.join(' ')}`, { + env, + cwd, + }, (error, stdout, stderr) => { + console.log('cwd', cwd); + console.log('stdout', stdout); + console.log('stderr', stderr); + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + + await promise; + }; + + /** + * @param {string} script + * @param {(options: RunOptions) => void} fn + */ + const test = (script, fn) => { + it(`should create installer for ${script}.nsi`, async () => { + const options = { + scriptFile: `./test/${script}.nsi` + }; + if (fn) { + fn(options); + } + + await run(options); + + const actual = await exists(`./test/${script}.exe`); + + assert( + actual, + `Installer \`./test/${script}.exe\` should exist` + ); + }); + }; + + test('basic'); + test('with-plugins', options => options.additionalPluginPaths = [ + './test/EnVar' + ]); +});