Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration from tap to mocha #2851

Merged
merged 2 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
},
"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"
"standard": "^14.3.4"
},
"scripts": {
"lint": "standard */*.js test/**/*.js",
"test": "npm run lint && tap --timeout=1200 test/test-*"
"test": "npm run lint && mocha --reporter=test/reporter.js test/test-download.js test/test-*"
}
}
75 changes: 75 additions & 0 deletions test/reporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const Mocha = require('mocha')

class Reporter {
constructor (runner) {
this.failedTests = []

runner.on(Mocha.Runner.constants.EVENT_RUN_BEGIN, () => {
console.log('Starting tests')
})

runner.on(Mocha.Runner.constants.EVENT_RUN_END, () => {
console.log('Tests finished')
console.log()
console.log('****************')
console.log('* TESTS REPORT *')
console.log('****************')
console.log()
console.log(`Executed ${runner.stats.suites} suites with ${runner.stats.tests} tests in ${runner.stats.duration} ms`)
console.log(` Passed: ${runner.stats.passes}`)
console.log(` Skipped: ${runner.stats.pending}`)
console.log(` Failed: ${runner.stats.failures}`)
if (this.failedTests.length > 0) {
console.log()
console.log(' Failed test details')
this.failedTests.forEach((failedTest, index) => {
console.log()
console.log(` ${index + 1}.'${failedTest.test.fullTitle()}'`)
console.log(` Name: ${failedTest.error.name}`)
console.log(` Message: ${failedTest.error.message}`)
console.log(` Code: ${failedTest.error.code}`)
console.log(` Stack: ${failedTest.error.stack}`)
})
}
console.log()
})

runner.on(Mocha.Runner.constants.EVENT_SUITE_BEGIN, (suite) => {
if (suite.root) {
return
}
console.log(`Starting suite '${suite.title}'`)
})

runner.on(Mocha.Runner.constants.EVENT_SUITE_END, (suite) => {
if (suite.root) {
return
}
console.log(`Suite '${suite.title}' finished`)
console.log()
})

runner.on(Mocha.Runner.constants.EVENT_TEST_BEGIN, (test) => {
console.log(`Starting test '${test.title}'`)
})

runner.on(Mocha.Runner.constants.EVENT_TEST_PASS, (test) => {
console.log(`Test '${test.title}' passed in ${test.duration} ms`)
})

runner.on(Mocha.Runner.constants.EVENT_TEST_PENDING, (test) => {
console.log(`Test '${test.title}' skipped in ${test.duration} ms`)
})

runner.on(Mocha.Runner.constants.EVENT_TEST_FAIL, (test, error) => {
this.failedTests.push({ test, error })
console.log(`Test '${test.title}' failed in ${test.duration} ms with ${error}`)
})

runner.on(Mocha.Runner.constants.EVENT_TEST_END, (test) => {
console.log()
})
}
}

module.exports = Reporter
200 changes: 101 additions & 99 deletions test/test-addon.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const test = require('tap').test
const { describe, it } = require('mocha')
const assert = require('assert')
const path = require('path')
const fs = require('graceful-fs')
const childProcess = require('child_process')
Expand Down Expand Up @@ -35,116 +36,117 @@ function checkCharmapValid () {
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')
describe('addon', function () {
this.timeout(300000)

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')
})
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.')
}
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 t.skip('no need to test')
}
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')
}

t.plan(3)
this.timeout(300000)

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 data
var configPath = path.join(addonPath, 'build', 'config.gypi')
try {
data = fs.readFileSync(configPath, 'utf8')
} catch (err) {
assert.fail(err)
return
}
}

var cmd = [
nodeGyp,
'rebuild',
'-C',
addonPath,
'--loglevel=verbose',
'-nodedir=' + testNodeDir
]
var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
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.unlink(testNodeDir)
fs.symlinkSync(nodeDir, testNodeDir, 'dir')
} catch (err) {
t.error(err)
switch (err.code) {
case 'EEXIST': break
case 'EPERM':
assert.fail(err, null, 'Please try to running console as an administrator')
return
default:
assert.fail(err)
return
}
}

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')
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')
})
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)
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 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)
this.timeout(300000)

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')
})
proc.stdout.setEncoding('utf-8')
proc.stderr.setEncoding('utf-8')
})
Loading