diff --git a/package.json b/package.json index 11b10b69f0..24d0f090db 100644 --- a/package.json +++ b/package.json @@ -38,13 +38,14 @@ }, "devDependencies": { "bindings": "^1.5.0", + "mocha": "^10.2.0", "nan": "^2.14.2", "require-inject": "^1.4.4", "standard": "^14.3.4", - "tap": "^12.7.0" + "tap": "^16.3.4" }, "scripts": { "lint": "standard */*.js test/**/*.js", - "test": "npm run lint && tap --timeout=600 test/test-*" + "test": "npm run lint && tap --no-coverage --timeout=600 test/tap-* && mocha --timeout=600000 test/mocha-*" } } diff --git a/test/mocha-addon.js b/test/mocha-addon.js new file mode 100644 index 0000000000..4833fa8b39 --- /dev/null +++ b/test/mocha-addon.js @@ -0,0 +1,144 @@ +'use strict' + +const { describe, it } = require('mocha') +const assert = require('assert') +const path = require('path') +const fs = require('graceful-fs') +const childProcess = require('child_process') +const os = require('os') +const addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') +const nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') +const execFileSync = childProcess.execFileSync || require('./process-exec-sync') +const execFile = childProcess.execFile + +function runHello (hostProcess) { + if (!hostProcess) { + hostProcess = process.execPath + } + var testCode = "console.log(require('hello_world').hello())" + return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString() +} + +function getEncoding () { + var code = 'import locale;print(locale.getdefaultlocale()[1])' + return execFileSync('python', ['-c', code]).toString().trim() +} + +function checkCharmapValid () { + var data + try { + data = execFileSync('python', ['fixtures/test-charmap.py'], + { cwd: __dirname }) + } catch (err) { + return false + } + var lines = data.toString().trim().split('\n') + return lines.pop() === 'True' +} + +describe('addon', () => { + it('build simple addon', function (done) { + // Set the loglevel otherwise the output disappears when run via 'npm test' + var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length - 1] + assert.strictEqual(err, null) + assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + assert.strictEqual(runHello().trim(), 'world') + done() + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') + }) + + it('build simple addon in path with non-ascii characters', function (done) { + if (!checkCharmapValid()) { + return this.skip('python console app can\'t encode non-ascii character.') + } + + var testDirNames = { + cp936: '文件夹', + cp1252: 'Latīna', + cp932: 'フォルダ' + } + // Select non-ascii characters by current encoding + var testDirName = testDirNames[getEncoding()] + // If encoding is UTF-8 or other then no need to test + if (!testDirName) { + return this.skip('no need to test') + } + + var data + var configPath = path.join(addonPath, 'build', 'config.gypi') + try { + data = fs.readFileSync(configPath, 'utf8') + } catch (err) { + assert.fail(err) + } + var config = JSON.parse(data.replace(/#.+\n/, '')) + var nodeDir = config.variables.nodedir + var testNodeDir = path.join(addonPath, testDirName) + // Create symbol link to path with non-ascii characters + try { + fs.symlinkSync(nodeDir, testNodeDir, 'dir') + } catch (err) { + switch (err.code) { + case 'EEXIST': break + case 'EPERM': + assert.fail(err, null, 'Please try to running console as an administrator') + break + default: + assert.fail(err) + } + } + + var cmd = [ + nodeGyp, + 'rebuild', + '-C', + addonPath, + '--loglevel=verbose', + '-nodedir=' + testNodeDir + ] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { + try { + fs.unlink(testNodeDir) + } catch (err) { + assert.fail(err) + } + + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length - 1] + assert.strictEqual(err, null) + assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + assert.strictEqual(runHello().trim(), 'world') + done() + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') + }) + + it('addon works with renamed host executable', function (done) { + // No `fs.copyFileSync` before node8. + if (process.version.substr(1).split('.')[0] < 8) { + return this.skip('skipping test for old node version') + } + + var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath)) + fs.copyFileSync(process.execPath, notNodePath) + + var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length - 1] + assert.strictEqual(err, null) + assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + assert.strictEqual(runHello(notNodePath).trim(), 'world') + fs.unlinkSync(notNodePath) + done() + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') + }) +}) diff --git a/test/test-configure-python.js b/test/tap-configure-python.js similarity index 100% rename from test/test-configure-python.js rename to test/tap-configure-python.js diff --git a/test/test-create-config-gypi.js b/test/tap-create-config-gypi.js similarity index 100% rename from test/test-create-config-gypi.js rename to test/tap-create-config-gypi.js diff --git a/test/test-download.js b/test/tap-download.js similarity index 100% rename from test/test-download.js rename to test/tap-download.js diff --git a/test/test-find-accessible-sync.js b/test/tap-find-accessible-sync.js similarity index 100% rename from test/test-find-accessible-sync.js rename to test/tap-find-accessible-sync.js diff --git a/test/test-find-node-directory.js b/test/tap-find-node-directory.js similarity index 100% rename from test/test-find-node-directory.js rename to test/tap-find-node-directory.js diff --git a/test/test-find-python.js b/test/tap-find-python.js similarity index 100% rename from test/test-find-python.js rename to test/tap-find-python.js diff --git a/test/test-find-visualstudio.js b/test/tap-find-visualstudio.js similarity index 100% rename from test/test-find-visualstudio.js rename to test/tap-find-visualstudio.js diff --git a/test/test-install.js b/test/tap-install.js similarity index 100% rename from test/test-install.js rename to test/tap-install.js diff --git a/test/test-options.js b/test/tap-options.js similarity index 100% rename from test/test-options.js rename to test/tap-options.js diff --git a/test/test-process-release.js b/test/tap-process-release.js similarity index 100% rename from test/test-process-release.js rename to test/tap-process-release.js diff --git a/test/test-addon.js b/test/test-addon.js deleted file mode 100644 index f79eff73c1..0000000000 --- a/test/test-addon.js +++ /dev/null @@ -1,150 +0,0 @@ -'use strict' - -const test = require('tap').test -const path = require('path') -const fs = require('graceful-fs') -const childProcess = require('child_process') -const os = require('os') -const addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') -const nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') -const execFileSync = childProcess.execFileSync || require('./process-exec-sync') -const execFile = childProcess.execFile - -function runHello (hostProcess) { - if (!hostProcess) { - hostProcess = process.execPath - } - var testCode = "console.log(require('hello_world').hello())" - return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString() -} - -function getEncoding () { - var code = 'import locale;print(locale.getdefaultlocale()[1])' - return execFileSync('python', ['-c', code]).toString().trim() -} - -function checkCharmapValid () { - var data - try { - data = execFileSync('python', ['fixtures/test-charmap.py'], - { cwd: __dirname }) - } catch (err) { - return false - } - var lines = data.toString().trim().split('\n') - return lines.pop() === 'True' -} - -test('build simple addon', function (t) { - t.plan(3) - - // Set the loglevel otherwise the output disappears when run via 'npm test' - var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello().trim(), 'world') - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -}) - -test('build simple addon in path with non-ascii characters', function (t) { - t.plan(1) - - if (!checkCharmapValid()) { - return t.skip('python console app can\'t encode non-ascii character.') - } - - var testDirNames = { - cp936: '文件夹', - cp1252: 'Latīna', - cp932: 'フォルダ' - } - // Select non-ascii characters by current encoding - var testDirName = testDirNames[getEncoding()] - // If encoding is UTF-8 or other then no need to test - if (!testDirName) { - return t.skip('no need to test') - } - - t.plan(3) - - var data - var configPath = path.join(addonPath, 'build', 'config.gypi') - try { - data = fs.readFileSync(configPath, 'utf8') - } catch (err) { - t.error(err) - return - } - var config = JSON.parse(data.replace(/#.+\n/, '')) - var nodeDir = config.variables.nodedir - var testNodeDir = path.join(addonPath, testDirName) - // Create symbol link to path with non-ascii characters - try { - fs.symlinkSync(nodeDir, testNodeDir, 'dir') - } catch (err) { - switch (err.code) { - case 'EEXIST': break - case 'EPERM': - t.error(err, 'Please try to running console as an administrator') - return - default: - t.error(err) - return - } - } - - var cmd = [ - nodeGyp, - 'rebuild', - '-C', - addonPath, - '--loglevel=verbose', - '-nodedir=' + testNodeDir - ] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - try { - fs.unlink(testNodeDir) - } catch (err) { - t.error(err) - } - - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello().trim(), 'world') - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -}) - -test('addon works with renamed host executable', function (t) { - // No `fs.copyFileSync` before node8. - if (process.version.substr(1).split('.')[0] < 8) { - t.skip('skipping test for old node version') - t.end() - return - } - - t.plan(3) - - var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath)) - fs.copyFileSync(process.execPath, notNodePath) - - var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello(notNodePath).trim(), 'world') - fs.unlinkSync(notNodePath) - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -})