test-find-python.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. 'use strict'
  2. var test = require('tape')
  3. var path = require('path')
  4. var configure = require('../lib/configure')
  5. var execFile = require('child_process').execFile
  6. var PythonFinder = configure.test.PythonFinder
  7. test('find python', function (t) {
  8. t.plan(4)
  9. configure.test.findPython('python', function (err, found) {
  10. t.strictEqual(err, null)
  11. var proc = execFile(found, ['-V'], function (err, stdout, stderr) {
  12. t.strictEqual(err, null)
  13. t.strictEqual(stdout, '')
  14. t.ok(/Python 2/.test(stderr))
  15. })
  16. proc.stdout.setEncoding('utf-8')
  17. proc.stderr.setEncoding('utf-8')
  18. })
  19. })
  20. function poison(object, property) {
  21. function fail() {
  22. throw new Error('Property ' + property + ' should not have been accessed.')
  23. }
  24. var descriptor = {
  25. configurable: true,
  26. enumerable: false,
  27. writable: true,
  28. getter: fail,
  29. setter: fail,
  30. }
  31. Object.defineProperty(object, property, descriptor)
  32. }
  33. // Work around a v0.10.x CI issue where path.resolve() on UNIX systems prefixes
  34. // Windows paths with the current working directory. v0.12 and up are free of
  35. // this issue because they use path.win32.resolve() which does the right thing.
  36. var resolve = path.win32 && path.win32.resolve || function() {
  37. function rstrip(s) { return s.replace(/\\+$/, '') }
  38. return [].slice.call(arguments).map(rstrip).join('\\')
  39. }
  40. function TestPythonFinder() { PythonFinder.apply(this, arguments) }
  41. TestPythonFinder.prototype = Object.create(PythonFinder.prototype)
  42. poison(TestPythonFinder.prototype, 'env')
  43. poison(TestPythonFinder.prototype, 'execFile')
  44. poison(TestPythonFinder.prototype, 'resolve')
  45. poison(TestPythonFinder.prototype, 'stat')
  46. poison(TestPythonFinder.prototype, 'which')
  47. poison(TestPythonFinder.prototype, 'win')
  48. test('find python - python', function (t) {
  49. t.plan(5)
  50. var f = new TestPythonFinder('python', done)
  51. f.which = function(program, cb) {
  52. t.strictEqual(program, 'python')
  53. cb(null, program)
  54. }
  55. f.execFile = function(program, args, opts, cb) {
  56. t.strictEqual(program, 'python')
  57. t.ok(/import platform/.test(args[1]))
  58. cb(null, '2.7.0')
  59. }
  60. f.checkPython()
  61. function done(err, python) {
  62. t.strictEqual(err, null)
  63. t.strictEqual(python, 'python')
  64. }
  65. })
  66. test('find python - python too old', function (t) {
  67. t.plan(4)
  68. var f = new TestPythonFinder('python', done)
  69. f.which = function(program, cb) {
  70. t.strictEqual(program, 'python')
  71. cb(null, program)
  72. }
  73. f.execFile = function(program, args, opts, cb) {
  74. t.strictEqual(program, 'python')
  75. t.ok(/import platform/.test(args[1]))
  76. cb(null, '2.3.4')
  77. }
  78. f.checkPython()
  79. function done(err, python) {
  80. t.ok(/is not supported by gyp/.test(err))
  81. }
  82. })
  83. test('find python - python too new', function (t) {
  84. t.plan(4)
  85. var f = new TestPythonFinder('python', done)
  86. f.which = function(program, cb) {
  87. t.strictEqual(program, 'python')
  88. cb(null, program)
  89. }
  90. f.execFile = function(program, args, opts, cb) {
  91. t.strictEqual(program, 'python')
  92. t.ok(/import platform/.test(args[1]))
  93. cb(null, '3.0.0')
  94. }
  95. f.checkPython()
  96. function done(err, python) {
  97. t.ok(/is not supported by gyp/.test(err))
  98. }
  99. })
  100. test('find python - no python', function (t) {
  101. t.plan(2)
  102. var f = new TestPythonFinder('python', done)
  103. f.which = function(program, cb) {
  104. t.strictEqual(program, 'python')
  105. cb(new Error('not found'))
  106. }
  107. f.checkPython()
  108. function done(err, python) {
  109. t.ok(/Can't find Python executable/.test(err))
  110. }
  111. })
  112. test('find python - no python2', function (t) {
  113. t.plan(6)
  114. var f = new TestPythonFinder('python2', done)
  115. f.which = function(program, cb) {
  116. f.which = function(program, cb) {
  117. t.strictEqual(program, 'python')
  118. cb(null, program)
  119. }
  120. t.strictEqual(program, 'python2')
  121. cb(new Error('not found'))
  122. }
  123. f.execFile = function(program, args, opts, cb) {
  124. t.strictEqual(program, 'python')
  125. t.ok(/import platform/.test(args[1]))
  126. cb(null, '2.7.0')
  127. }
  128. f.checkPython()
  129. function done(err, python) {
  130. t.strictEqual(err, null)
  131. t.strictEqual(python, 'python')
  132. }
  133. })
  134. test('find python - no python2, no python, unix', function (t) {
  135. t.plan(3)
  136. var f = new TestPythonFinder('python2', done)
  137. poison(f, 'checkPythonLauncher')
  138. f.win = false
  139. f.which = function(program, cb) {
  140. f.which = function(program, cb) {
  141. t.strictEqual(program, 'python')
  142. cb(new Error('not found'))
  143. }
  144. t.strictEqual(program, 'python2')
  145. cb(new Error('not found'))
  146. }
  147. f.checkPython()
  148. function done(err, python) {
  149. t.ok(/Can't find Python executable/.test(err))
  150. }
  151. })
  152. test('find python - no python, use python launcher', function (t) {
  153. t.plan(8)
  154. var f = new TestPythonFinder('python', done)
  155. f.env = {}
  156. f.win = true
  157. f.which = function(program, cb) {
  158. t.strictEqual(program, 'python')
  159. cb(new Error('not found'))
  160. }
  161. f.execFile = function(program, args, opts, cb) {
  162. f.execFile = function(program, args, opts, cb) {
  163. t.strictEqual(program, 'Z:\\snake.exe')
  164. t.ok(/import platform/.test(args[1]))
  165. cb(null, '2.7.0')
  166. }
  167. t.strictEqual(program, 'py.exe')
  168. t.notEqual(args.indexOf('-2'), -1)
  169. t.notEqual(args.indexOf('-c'), -1)
  170. cb(null, 'Z:\\snake.exe')
  171. }
  172. f.checkPython()
  173. function done(err, python) {
  174. t.strictEqual(err, null)
  175. t.strictEqual(python, 'Z:\\snake.exe')
  176. }
  177. })
  178. test('find python - python 3, use python launcher', function (t) {
  179. t.plan(10)
  180. var f = new TestPythonFinder('python', done)
  181. f.env = {}
  182. f.win = true
  183. f.which = function(program, cb) {
  184. t.strictEqual(program, 'python')
  185. cb(null, program)
  186. }
  187. f.execFile = function(program, args, opts, cb) {
  188. f.execFile = function(program, args, opts, cb) {
  189. f.execFile = function(program, args, opts, cb) {
  190. t.strictEqual(program, 'Z:\\snake.exe')
  191. t.ok(/import platform/.test(args[1]))
  192. cb(null, '2.7.0')
  193. }
  194. t.strictEqual(program, 'py.exe')
  195. t.notEqual(args.indexOf('-2'), -1)
  196. t.notEqual(args.indexOf('-c'), -1)
  197. cb(null, 'Z:\\snake.exe')
  198. }
  199. t.strictEqual(program, 'python')
  200. t.ok(/import platform/.test(args[1]))
  201. cb(null, '3.0.0')
  202. }
  203. f.checkPython()
  204. function done(err, python) {
  205. t.strictEqual(err, null)
  206. t.strictEqual(python, 'Z:\\snake.exe')
  207. }
  208. })
  209. test('find python - python 3, use python launcher, python 2 too old',
  210. function (t) {
  211. t.plan(9)
  212. var f = new TestPythonFinder('python', done)
  213. f.checkedPythonLauncher = false
  214. f.env = {}
  215. f.win = true
  216. f.which = function(program, cb) {
  217. t.strictEqual(program, 'python')
  218. cb(null, program)
  219. }
  220. f.execFile = function(program, args, opts, cb) {
  221. f.execFile = function(program, args, opts, cb) {
  222. f.execFile = function(program, args, opts, cb) {
  223. t.strictEqual(program, 'Z:\\snake.exe')
  224. t.ok(/import platform/.test(args[1]))
  225. cb(null, '2.3.4')
  226. }
  227. t.strictEqual(program, 'py.exe')
  228. t.notEqual(args.indexOf('-2'), -1)
  229. t.notEqual(args.indexOf('-c'), -1)
  230. cb(null, 'Z:\\snake.exe')
  231. }
  232. t.strictEqual(program, 'python')
  233. t.ok(/import platform/.test(args[1]))
  234. cb(null, '3.0.0')
  235. }
  236. f.checkPython()
  237. function done(err, python) {
  238. t.ok(/is not supported by gyp/.test(err))
  239. }
  240. })
  241. test('find python - no python, no python launcher, good guess', function (t) {
  242. t.plan(6)
  243. var re = /C:[\\\/]Python27[\\\/]python[.]exe/
  244. var f = new TestPythonFinder('python', done)
  245. f.env = {}
  246. f.win = true
  247. f.which = function(program, cb) {
  248. t.strictEqual(program, 'python')
  249. cb(new Error('not found'))
  250. }
  251. f.execFile = function(program, args, opts, cb) {
  252. f.execFile = function(program, args, opts, cb) {
  253. t.ok(re.test(program))
  254. t.ok(/import platform/.test(args[1]))
  255. cb(null, '2.7.0')
  256. }
  257. t.strictEqual(program, 'py.exe')
  258. cb(new Error('not found'))
  259. }
  260. f.resolve = resolve
  261. f.stat = function(path, cb) {
  262. t.ok(re.test(path))
  263. cb(null, {})
  264. }
  265. f.checkPython()
  266. function done(err, python) {
  267. t.ok(re.test(python))
  268. }
  269. })
  270. test('find python - no python, no python launcher, bad guess', function (t) {
  271. t.plan(4)
  272. var f = new TestPythonFinder('python', done)
  273. f.env = { SystemDrive: 'Z:\\' }
  274. f.win = true
  275. f.which = function(program, cb) {
  276. t.strictEqual(program, 'python')
  277. cb(new Error('not found'))
  278. }
  279. f.execFile = function(program, args, opts, cb) {
  280. t.strictEqual(program, 'py.exe')
  281. cb(new Error('not found'))
  282. }
  283. f.resolve = resolve
  284. f.stat = function(path, cb) {
  285. t.ok(/Z:[\\\/]Python27[\\\/]python.exe/.test(path))
  286. var err = new Error('not found')
  287. err.code = 'ENOENT'
  288. cb(err)
  289. }
  290. f.checkPython()
  291. function done(err, python) {
  292. t.ok(/Can't find Python executable/.test(err))
  293. }
  294. })