• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2
3delete process.env.PYTHON
4
5const { describe, it } = require('mocha')
6const assert = require('assert')
7const findPython = require('../lib/find-python')
8const execFile = require('child_process').execFile
9const PythonFinder = findPython.test.PythonFinder
10
11require('npmlog').level = 'warn'
12
13describe('find-python', function () {
14  it('find python', function () {
15    findPython.test.findPython(null, function (err, found) {
16      assert.strictEqual(err, null)
17      var proc = execFile(found, ['-V'], function (err, stdout, stderr) {
18        assert.strictEqual(err, null)
19        assert.ok(/Python 3/.test(stdout))
20        assert.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  it('find python - python', function () {
56    var f = new TestPythonFinder('python', done)
57    f.execFile = function (program, args, opts, cb) {
58      f.execFile = function (program, args, opts, cb) {
59        poison(f, 'execFile')
60        assert.strictEqual(program, '/path/python')
61        assert.ok(/sys\.version_info/.test(args[1]))
62        cb(null, '3.9.1')
63      }
64      assert.strictEqual(program,
65        process.platform === 'win32' ? '"python"' : 'python')
66      assert.ok(/sys\.executable/.test(args[1]))
67      cb(null, '/path/python')
68    }
69    f.findPython()
70
71    function done (err, python) {
72      assert.strictEqual(err, null)
73      assert.strictEqual(python, '/path/python')
74    }
75  })
76
77  it('find python - python too old', function () {
78    var f = new TestPythonFinder(null, done)
79    f.execFile = function (program, args, opts, cb) {
80      if (/sys\.executable/.test(args[args.length - 1])) {
81        cb(null, '/path/python')
82      } else if (/sys\.version_info/.test(args[args.length - 1])) {
83        cb(null, '2.3.4')
84      } else {
85        assert.fail()
86      }
87    }
88    f.findPython()
89
90    function done (err) {
91      assert.ok(/Could not find any Python/.test(err))
92      assert.ok(/not supported/i.test(f.errorLog))
93    }
94  })
95
96  it('find python - no python', function () {
97    var f = new TestPythonFinder(null, done)
98    f.execFile = function (program, args, opts, cb) {
99      if (/sys\.executable/.test(args[args.length - 1])) {
100        cb(new Error('not found'))
101      } else if (/sys\.version_info/.test(args[args.length - 1])) {
102        cb(new Error('not a Python executable'))
103      } else {
104        assert.fail()
105      }
106    }
107    f.findPython()
108
109    function done (err) {
110      assert.ok(/Could not find any Python/.test(err))
111      assert.ok(/not in PATH/.test(f.errorLog))
112    }
113  })
114
115  it('find python - no python2, no python, unix', function () {
116    var f = new TestPythonFinder(null, done)
117    f.checkPyLauncher = assert.fail
118    f.win = false
119
120    f.execFile = function (program, args, opts, cb) {
121      if (/sys\.executable/.test(args[args.length - 1])) {
122        cb(new Error('not found'))
123      } else {
124        assert.fail()
125      }
126    }
127    f.findPython()
128
129    function done (err) {
130      assert.ok(/Could not find any Python/.test(err))
131      assert.ok(/not in PATH/.test(f.errorLog))
132    }
133  })
134
135  it('find python - no python, use python launcher', function () {
136    var f = new TestPythonFinder(null, done)
137    f.win = true
138
139    f.execFile = function (program, args, opts, cb) {
140      if (program === 'py.exe') {
141        assert.notStrictEqual(args.indexOf('-3'), -1)
142        assert.notStrictEqual(args.indexOf('-c'), -1)
143        return cb(null, 'Z:\\snake.exe')
144      }
145      if (/sys\.executable/.test(args[args.length - 1])) {
146        cb(new Error('not found'))
147      } else if (f.winDefaultLocations.includes(program)) {
148        cb(new Error('not found'))
149      } else if (/sys\.version_info/.test(args[args.length - 1])) {
150        if (program === 'Z:\\snake.exe') {
151          cb(null, '3.9.0')
152        } else {
153          assert.fail()
154        }
155      } else {
156        assert.fail()
157      }
158    }
159    f.findPython()
160
161    function done (err, python) {
162      assert.strictEqual(err, null)
163      assert.strictEqual(python, 'Z:\\snake.exe')
164    }
165  })
166
167  it('find python - no python, no python launcher, good guess', function () {
168    var f = new TestPythonFinder(null, done)
169    f.win = true
170    const expectedProgram = f.winDefaultLocations[0]
171
172    f.execFile = function (program, args, opts, cb) {
173      if (program === 'py.exe') {
174        return cb(new Error('not found'))
175      }
176      if (/sys\.executable/.test(args[args.length - 1])) {
177        cb(new Error('not found'))
178      } else if (program === expectedProgram &&
179                 /sys\.version_info/.test(args[args.length - 1])) {
180        cb(null, '3.7.3')
181      } else {
182        assert.fail()
183      }
184    }
185    f.findPython()
186
187    function done (err, python) {
188      assert.strictEqual(err, null)
189      assert.ok(python === expectedProgram)
190    }
191  })
192
193  it('find python - no python, no python launcher, bad guess', function () {
194    var f = new TestPythonFinder(null, done)
195    f.win = true
196
197    f.execFile = function (program, args, opts, cb) {
198      if (/sys\.executable/.test(args[args.length - 1])) {
199        cb(new Error('not found'))
200      } else if (/sys\.version_info/.test(args[args.length - 1])) {
201        cb(new Error('not a Python executable'))
202      } else {
203        assert.fail()
204      }
205    }
206    f.findPython()
207
208    function done (err) {
209      assert.ok(/Could not find any Python/.test(err))
210      assert.ok(/not in PATH/.test(f.errorLog))
211    }
212  })
213})
214