You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test-find-python.js 6.1KB

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