33const tap = require ( 'tap' )
44const { test } = tap
55const findPython = require ( '../lib/find-python' )
6- const execFile = require ( 'child_process' ) . execFile
6+ const cp = require ( 'child_process' )
77const PythonFinder = findPython . test . PythonFinder
8-
8+ const util = require ( 'util' )
9+ const path = require ( 'path' )
910const npmlog = require ( 'npmlog' )
11+ const fs = require ( 'fs' )
1012npmlog . level = 'silent'
1113
1214// what final error message displayed in terminal should contain
@@ -123,7 +125,7 @@ test('find-python', { buffered: true }, (t) => {
123125 `mustn't produce any errors if execFile doesn't produced error. ${ err } `
124126 )
125127 } else {
126- t . strictEqual ( path , testString )
128+ t . equal ( path , testString )
127129 t . end ( )
128130 }
129131 } )
@@ -161,9 +163,9 @@ test('find-python', { buffered: true }, (t) => {
161163
162164 t . test ( 'no python, unix' , ( t ) => {
163165 const pythonFinderInstance = new PythonFinder ( null , ( err , path ) => {
164- t . false ( path )
166+ t . notOk ( path )
165167
166- t . true ( err )
168+ t . ok ( err )
167169 t . ok ( err . message . includes ( finalErrorMessage ) )
168170 t . end ( )
169171 } )
@@ -180,9 +182,9 @@ test('find-python', { buffered: true }, (t) => {
180182
181183 t . test ( 'no python, use python launcher' , ( t ) => {
182184 const pythonFinderInstance = new PythonFinder ( null , ( err , path ) => {
183- t . strictEqual ( err , null )
185+ t . equal ( err , null )
184186
185- t . strictEqual ( path , testString )
187+ t . equal ( path , testString )
186188
187189 t . end ( )
188190 } )
@@ -200,8 +202,8 @@ test('find-python', { buffered: true }, (t) => {
200202 'no python, no python launcher, checking win default locations' ,
201203 ( t ) => {
202204 const pythonFinderInstance = new PythonFinder ( null , ( err , path ) => {
203- t . strictEqual ( err , null )
204- t . true ( pythonFinderInstance . winDefaultLocations . includes ( path ) )
205+ t . equal ( err , null )
206+ t . ok ( pythonFinderInstance . winDefaultLocations . includes ( path ) )
205207 t . end ( )
206208 } )
207209
@@ -216,9 +218,9 @@ test('find-python', { buffered: true }, (t) => {
216218
217219 t . test ( 'python is setted from config' , ( t ) => {
218220 const pythonFinderInstance = new PythonFinder ( testString , ( err , path ) => {
219- t . strictEqual ( err , null )
221+ t . equal ( err , null )
220222
221- t . strictEqual ( path , testString )
223+ t . equal ( path , testString )
222224
223225 t . end ( )
224226 } )
@@ -232,24 +234,97 @@ test('find-python', { buffered: true }, (t) => {
232234 t . end ( )
233235 } )
234236
235- // TODO: make symlink to python with utf-8 chars
236- t . test ( 'real testing (trying to find real python exec)' , ( t ) => {
237- const pythonFinderInstance = new PythonFinder ( null , ( err , path ) => {
238- t . strictEqual ( err , null )
237+ // DONE: make symlink to python with utf-8 chars
238+ t . test ( 'real testing' , async ( t ) => {
239+ const paths = {
240+ python : '' ,
241+ pythonDir : '' ,
242+ testDir : '' ,
243+ baseDir : __dirname
244+ }
239245
240- execFile ( path , [ '-V' ] , ( err , stdout , stderr ) => {
241- t . false ( err )
242- console . log ( 'stdout:' + stdout )
243- console . log ( 'stderr:' + stderr )
246+ const execFile = util . promisify ( cp . execFile )
244247
245- t . ok ( stdout . includes ( 'Python 3' ) )
246- t . strictEqual ( stderr , '' )
248+ // a bit tricky way to make PythonFinder promisified
249+ function promisifyPythonFinder ( config ) {
250+ let pythonFinderInstance
247251
248- t . end ( )
252+ const result = new Promise ( ( resolve , reject ) => {
253+ pythonFinderInstance = new PythonFinder ( config , ( err , path ) => {
254+ if ( err ) {
255+ reject ( err )
256+ } else {
257+ resolve ( path )
258+ }
259+ } )
249260 } )
261+
262+ return { pythonFinderInstance, result }
263+ }
264+
265+ async function testPythonPath ( t , pythonPath ) {
266+ try {
267+ const { stderr, stdout } = await execFile ( pythonPath , [ '-V' ] )
268+
269+ console . log ( 'stdout:' , stdout )
270+ console . log ( 'stderr:' , stderr )
271+
272+ if ( t . ok ( stdout . includes ( 'Python 3' ) , 'is it python with major version 3' ) &&
273+ t . equal ( stderr , '' , 'is stderr empty' ) ) {
274+ return true
275+ }
276+
277+ return false
278+ } catch ( err ) {
279+ t . equal ( err , null , 'is error null' )
280+ return false
281+ }
282+ }
283+
284+ // await is needed because test func is async
285+ await t . test ( 'trying to find real python exec' , async ( t ) => {
286+ const { pythonFinderInstance, result } = promisifyPythonFinder ( null )
287+
288+ try {
289+ pythonFinderInstance . findPython ( )
290+
291+ const pythonPath = await result
292+
293+ if ( t . ok ( await testPythonPath ( t , pythonPath ) , 'is path valid' ) ) {
294+ // stdout contain output of "python -V" command, not python path
295+ // using found path as trusted
296+ paths . python = pythonPath
297+ paths . pythonDir = path . join ( paths . python , '../' )
298+ }
299+ } catch ( err ) {
300+ t . notOk ( err , 'are we having error' )
301+ }
302+
303+ t . end ( )
250304 } )
251305
252- pythonFinderInstance . findPython ( )
306+ await t . test ( `test with path contain "${ testString } "` , async ( t ) => {
307+ // making fixture
308+ paths . testDir = fs . mkdtempSync ( path . resolve ( paths . baseDir , 'node_modules' , 'pythonFindTestFolder-' ) )
309+
310+ // using "junction" to avoid permission error
311+ fs . symlinkSync ( paths . pythonDir , path . resolve ( paths . testDir , testString ) , 'junction' )
312+
313+ const { pythonFinderInstance, result } = promisifyPythonFinder ( path . resolve ( paths . testDir , 'python' ) )
314+
315+ pythonFinderInstance . findPython ( )
316+
317+ const pythonPath = await result
318+
319+ t . ok ( await testPythonPath ( t , pythonPath ) , 'is path valid' )
320+
321+ t . end ( )
322+ } )
323+
324+ // remove fixture
325+ fs . rmSync ( paths . testDir , { recursive : true } )
326+
327+ t . end ( )
253328 } )
254329
255330 t . end ( )
0 commit comments