| 1 | 'use strict'
|
|---|
| 2 |
|
|---|
| 3 | delete process.env.PYTHON
|
|---|
| 4 |
|
|---|
| 5 | const test = require('tap').test
|
|---|
| 6 | const findPython = require('../lib/find-python')
|
|---|
| 7 | const execFile = require('child_process').execFile
|
|---|
| 8 | const PythonFinder = findPython.test.PythonFinder
|
|---|
| 9 |
|
|---|
| 10 | require('npmlog').level = 'warn'
|
|---|
| 11 |
|
|---|
| 12 | test('find python', function (t) {
|
|---|
| 13 | t.plan(4)
|
|---|
| 14 |
|
|---|
| 15 | findPython.test.findPython(null, function (err, found) {
|
|---|
| 16 | t.strictEqual(err, null)
|
|---|
| 17 | var proc = execFile(found, ['-V'], function (err, stdout, stderr) {
|
|---|
| 18 | t.strictEqual(err, null)
|
|---|
| 19 | t.ok(/Python 3/.test(stdout))
|
|---|
| 20 | t.strictEqual(stderr, '')
|
|---|
| 21 | })
|
|---|
| 22 | proc.stdout.setEncoding('utf-8')
|
|---|
| 23 | proc.stderr.setEncoding('utf-8')
|
|---|
| 24 | })
|
|---|
| 25 | })
|
|---|
| 26 |
|
|---|
| 27 | function poison (object, property) {
|
|---|
| 28 | function fail () {
|
|---|
| 29 | console.error(Error(`Property ${property} should not have been accessed.`))
|
|---|
| 30 | process.abort()
|
|---|
| 31 | }
|
|---|
| 32 | var descriptor = {
|
|---|
| 33 | configurable: false,
|
|---|
| 34 | enumerable: false,
|
|---|
| 35 | get: fail,
|
|---|
| 36 | set: fail
|
|---|
| 37 | }
|
|---|
| 38 | Object.defineProperty(object, property, descriptor)
|
|---|
| 39 | }
|
|---|
| 40 |
|
|---|
| 41 | function TestPythonFinder () {
|
|---|
| 42 | PythonFinder.apply(this, arguments)
|
|---|
| 43 | }
|
|---|
| 44 | TestPythonFinder.prototype = Object.create(PythonFinder.prototype)
|
|---|
| 45 | // Silence npmlog - remove for debugging
|
|---|
| 46 | TestPythonFinder.prototype.log = {
|
|---|
| 47 | silly: () => {},
|
|---|
| 48 | verbose: () => {},
|
|---|
| 49 | info: () => {},
|
|---|
| 50 | warn: () => {},
|
|---|
| 51 | error: () => {}
|
|---|
| 52 | }
|
|---|
| 53 | delete TestPythonFinder.prototype.env.NODE_GYP_FORCE_PYTHON
|
|---|
| 54 |
|
|---|
| 55 | test('find python - python', function (t) {
|
|---|
| 56 | t.plan(6)
|
|---|
| 57 |
|
|---|
| 58 | var f = new TestPythonFinder('python', done)
|
|---|
| 59 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 60 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 61 | poison(f, 'execFile')
|
|---|
| 62 | t.strictEqual(program, '/path/python')
|
|---|
| 63 | t.ok(/sys\.version_info/.test(args[1]))
|
|---|
| 64 | cb(null, '3.9.1')
|
|---|
| 65 | }
|
|---|
| 66 | t.strictEqual(program,
|
|---|
| 67 | process.platform === 'win32' ? '"python"' : 'python')
|
|---|
| 68 | t.ok(/sys\.executable/.test(args[1]))
|
|---|
| 69 | cb(null, '/path/python')
|
|---|
| 70 | }
|
|---|
| 71 | f.findPython()
|
|---|
| 72 |
|
|---|
| 73 | function done (err, python) {
|
|---|
| 74 | t.strictEqual(err, null)
|
|---|
| 75 | t.strictEqual(python, '/path/python')
|
|---|
| 76 | }
|
|---|
| 77 | })
|
|---|
| 78 |
|
|---|
| 79 | test('find python - python too old', function (t) {
|
|---|
| 80 | t.plan(2)
|
|---|
| 81 |
|
|---|
| 82 | var f = new TestPythonFinder(null, done)
|
|---|
| 83 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 84 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 85 | cb(null, '/path/python')
|
|---|
| 86 | } else if (/sys\.version_info/.test(args[args.length - 1])) {
|
|---|
| 87 | cb(null, '2.3.4')
|
|---|
| 88 | } else {
|
|---|
| 89 | t.fail()
|
|---|
| 90 | }
|
|---|
| 91 | }
|
|---|
| 92 | f.findPython()
|
|---|
| 93 |
|
|---|
| 94 | function done (err) {
|
|---|
| 95 | t.ok(/Could not find any Python/.test(err))
|
|---|
| 96 | t.ok(/not supported/i.test(f.errorLog))
|
|---|
| 97 | }
|
|---|
| 98 | })
|
|---|
| 99 |
|
|---|
| 100 | test('find python - no python', function (t) {
|
|---|
| 101 | t.plan(2)
|
|---|
| 102 |
|
|---|
| 103 | var f = new TestPythonFinder(null, done)
|
|---|
| 104 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 105 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 106 | cb(new Error('not found'))
|
|---|
| 107 | } else if (/sys\.version_info/.test(args[args.length - 1])) {
|
|---|
| 108 | cb(new Error('not a Python executable'))
|
|---|
| 109 | } else {
|
|---|
| 110 | t.fail()
|
|---|
| 111 | }
|
|---|
| 112 | }
|
|---|
| 113 | f.findPython()
|
|---|
| 114 |
|
|---|
| 115 | function done (err) {
|
|---|
| 116 | t.ok(/Could not find any Python/.test(err))
|
|---|
| 117 | t.ok(/not in PATH/.test(f.errorLog))
|
|---|
| 118 | }
|
|---|
| 119 | })
|
|---|
| 120 |
|
|---|
| 121 | test('find python - no python2, no python, unix', function (t) {
|
|---|
| 122 | t.plan(2)
|
|---|
| 123 |
|
|---|
| 124 | var f = new TestPythonFinder(null, done)
|
|---|
| 125 | f.checkPyLauncher = t.fail
|
|---|
| 126 | f.win = false
|
|---|
| 127 |
|
|---|
| 128 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 129 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 130 | cb(new Error('not found'))
|
|---|
| 131 | } else {
|
|---|
| 132 | t.fail()
|
|---|
| 133 | }
|
|---|
| 134 | }
|
|---|
| 135 | f.findPython()
|
|---|
| 136 |
|
|---|
| 137 | function done (err) {
|
|---|
| 138 | t.ok(/Could not find any Python/.test(err))
|
|---|
| 139 | t.ok(/not in PATH/.test(f.errorLog))
|
|---|
| 140 | }
|
|---|
| 141 | })
|
|---|
| 142 |
|
|---|
| 143 | test('find python - no python, use python launcher', function (t) {
|
|---|
| 144 | t.plan(4)
|
|---|
| 145 |
|
|---|
| 146 | var f = new TestPythonFinder(null, done)
|
|---|
| 147 | f.win = true
|
|---|
| 148 |
|
|---|
| 149 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 150 | if (program === 'py.exe') {
|
|---|
| 151 | t.notEqual(args.indexOf('-3'), -1)
|
|---|
| 152 | t.notEqual(args.indexOf('-c'), -1)
|
|---|
| 153 | return cb(null, 'Z:\\snake.exe')
|
|---|
| 154 | }
|
|---|
| 155 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 156 | cb(new Error('not found'))
|
|---|
| 157 | } else if (f.winDefaultLocations.includes(program)) {
|
|---|
| 158 | cb(new Error('not found'))
|
|---|
| 159 | } else if (/sys\.version_info/.test(args[args.length - 1])) {
|
|---|
| 160 | if (program === 'Z:\\snake.exe') {
|
|---|
| 161 | cb(null, '3.9.0')
|
|---|
| 162 | } else {
|
|---|
| 163 | t.fail()
|
|---|
| 164 | }
|
|---|
| 165 | } else {
|
|---|
| 166 | t.fail()
|
|---|
| 167 | }
|
|---|
| 168 | }
|
|---|
| 169 | f.findPython()
|
|---|
| 170 |
|
|---|
| 171 | function done (err, python) {
|
|---|
| 172 | t.strictEqual(err, null)
|
|---|
| 173 | t.strictEqual(python, 'Z:\\snake.exe')
|
|---|
| 174 | }
|
|---|
| 175 | })
|
|---|
| 176 |
|
|---|
| 177 | test('find python - no python, no python launcher, good guess', function (t) {
|
|---|
| 178 | t.plan(2)
|
|---|
| 179 |
|
|---|
| 180 | var f = new TestPythonFinder(null, done)
|
|---|
| 181 | f.win = true
|
|---|
| 182 | const expectedProgram = f.winDefaultLocations[0]
|
|---|
| 183 |
|
|---|
| 184 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 185 | if (program === 'py.exe') {
|
|---|
| 186 | return cb(new Error('not found'))
|
|---|
| 187 | }
|
|---|
| 188 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 189 | cb(new Error('not found'))
|
|---|
| 190 | } else if (program === expectedProgram &&
|
|---|
| 191 | /sys\.version_info/.test(args[args.length - 1])) {
|
|---|
| 192 | cb(null, '3.7.3')
|
|---|
| 193 | } else {
|
|---|
| 194 | t.fail()
|
|---|
| 195 | }
|
|---|
| 196 | }
|
|---|
| 197 | f.findPython()
|
|---|
| 198 |
|
|---|
| 199 | function done (err, python) {
|
|---|
| 200 | t.strictEqual(err, null)
|
|---|
| 201 | t.ok(python === expectedProgram)
|
|---|
| 202 | }
|
|---|
| 203 | })
|
|---|
| 204 |
|
|---|
| 205 | test('find python - no python, no python launcher, bad guess', function (t) {
|
|---|
| 206 | t.plan(2)
|
|---|
| 207 |
|
|---|
| 208 | var f = new TestPythonFinder(null, done)
|
|---|
| 209 | f.win = true
|
|---|
| 210 |
|
|---|
| 211 | f.execFile = function (program, args, opts, cb) {
|
|---|
| 212 | if (/sys\.executable/.test(args[args.length - 1])) {
|
|---|
| 213 | cb(new Error('not found'))
|
|---|
| 214 | } else if (/sys\.version_info/.test(args[args.length - 1])) {
|
|---|
| 215 | cb(new Error('not a Python executable'))
|
|---|
| 216 | } else {
|
|---|
| 217 | t.fail()
|
|---|
| 218 | }
|
|---|
| 219 | }
|
|---|
| 220 | f.findPython()
|
|---|
| 221 |
|
|---|
| 222 | function done (err) {
|
|---|
| 223 | t.ok(/Could not find any Python/.test(err))
|
|---|
| 224 | t.ok(/not in PATH/.test(f.errorLog))
|
|---|
| 225 | }
|
|---|
| 226 | })
|
|---|