1'use strict' 2 3const test = require('tap').test 4const path = require('path') 5const fs = require('graceful-fs') 6const childProcess = require('child_process') 7const os = require('os') 8const addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') 9const nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') 10const execFileSync = childProcess.execFileSync || require('./process-exec-sync') 11const execFile = childProcess.execFile 12 13function runHello (hostProcess) { 14 if (!hostProcess) { 15 hostProcess = process.execPath 16 } 17 var testCode = "console.log(require('hello_world').hello())" 18 return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString() 19} 20 21function getEncoding () { 22 var code = 'import locale;print(locale.getdefaultlocale()[1])' 23 return execFileSync('python', ['-c', code]).toString().trim() 24} 25 26function checkCharmapValid () { 27 var data 28 try { 29 data = execFileSync('python', ['fixtures/test-charmap.py'], 30 { cwd: __dirname }) 31 } catch (err) { 32 return false 33 } 34 var lines = data.toString().trim().split('\n') 35 return lines.pop() === 'True' 36} 37 38test('build simple addon', function (t) { 39 t.plan(3) 40 41 // Set the loglevel otherwise the output disappears when run via 'npm test' 42 var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] 43 var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { 44 var logLines = stderr.toString().trim().split(/\r?\n/) 45 var lastLine = logLines[logLines.length - 1] 46 t.strictEqual(err, null) 47 t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') 48 t.strictEqual(runHello().trim(), 'world') 49 }) 50 proc.stdout.setEncoding('utf-8') 51 proc.stderr.setEncoding('utf-8') 52}) 53 54test('build simple addon in path with non-ascii characters', function (t) { 55 t.plan(1) 56 57 if (!checkCharmapValid()) { 58 return t.skip('python console app can\'t encode non-ascii character.') 59 } 60 61 var testDirNames = { 62 cp936: '文件夹', 63 cp1252: 'Latīna', 64 cp932: 'フォルダ' 65 } 66 // Select non-ascii characters by current encoding 67 var testDirName = testDirNames[getEncoding()] 68 // If encoding is UTF-8 or other then no need to test 69 if (!testDirName) { 70 return t.skip('no need to test') 71 } 72 73 t.plan(3) 74 75 var data 76 var configPath = path.join(addonPath, 'build', 'config.gypi') 77 try { 78 data = fs.readFileSync(configPath, 'utf8') 79 } catch (err) { 80 t.error(err) 81 return 82 } 83 var config = JSON.parse(data.replace(/#.+\n/, '')) 84 var nodeDir = config.variables.nodedir 85 var testNodeDir = path.join(addonPath, testDirName) 86 // Create symbol link to path with non-ascii characters 87 try { 88 fs.symlinkSync(nodeDir, testNodeDir, 'dir') 89 } catch (err) { 90 switch (err.code) { 91 case 'EEXIST': break 92 case 'EPERM': 93 t.error(err, 'Please try to running console as an administrator') 94 return 95 default: 96 t.error(err) 97 return 98 } 99 } 100 101 var cmd = [ 102 nodeGyp, 103 'rebuild', 104 '-C', 105 addonPath, 106 '--loglevel=verbose', 107 '-nodedir=' + testNodeDir 108 ] 109 var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { 110 try { 111 fs.unlink(testNodeDir) 112 } catch (err) { 113 t.error(err) 114 } 115 116 var logLines = stderr.toString().trim().split(/\r?\n/) 117 var lastLine = logLines[logLines.length - 1] 118 t.strictEqual(err, null) 119 t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') 120 t.strictEqual(runHello().trim(), 'world') 121 }) 122 proc.stdout.setEncoding('utf-8') 123 proc.stderr.setEncoding('utf-8') 124}) 125 126test('addon works with renamed host executable', function (t) { 127 // No `fs.copyFileSync` before node8. 128 if (process.version.substr(1).split('.')[0] < 8) { 129 t.skip('skipping test for old node version') 130 t.end() 131 return 132 } 133 134 t.plan(3) 135 136 var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath)) 137 fs.copyFileSync(process.execPath, notNodePath) 138 139 var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] 140 var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { 141 var logLines = stderr.toString().trim().split(/\r?\n/) 142 var lastLine = logLines[logLines.length - 1] 143 t.strictEqual(err, null) 144 t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') 145 t.strictEqual(runHello(notNodePath).trim(), 'world') 146 fs.unlinkSync(notNodePath) 147 }) 148 proc.stdout.setEncoding('utf-8') 149 proc.stderr.setEncoding('utf-8') 150}) 151