test-find-python.js 5.6 KB

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