• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2
3const test = require('tap').test
4const fs = require('fs')
5const path = require('path')
6const findVisualStudio = require('../lib/find-visualstudio')
7const VisualStudioFinder = findVisualStudio.test.VisualStudioFinder
8
9const semverV1 = { major: 1, minor: 0, patch: 0 }
10
11delete process.env.VCINSTALLDIR
12
13function poison (object, property) {
14  function fail () {
15    console.error(Error(`Property ${property} should not have been accessed.`))
16    process.abort()
17  }
18  var descriptor = {
19    configurable: false,
20    enumerable: false,
21    get: fail,
22    set: fail
23  }
24  Object.defineProperty(object, property, descriptor)
25}
26
27function TestVisualStudioFinder () { VisualStudioFinder.apply(this, arguments) }
28TestVisualStudioFinder.prototype = Object.create(VisualStudioFinder.prototype)
29// Silence npmlog - remove for debugging
30TestVisualStudioFinder.prototype.log = {
31  silly: () => {},
32  verbose: () => {},
33  info: () => {},
34  warn: () => {},
35  error: () => {}
36}
37
38test('VS2013', function (t) {
39  t.plan(4)
40
41  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
42    t.strictEqual(err, null)
43    t.deepEqual(info, {
44      msBuild: 'C:\\MSBuild12\\MSBuild.exe',
45      path: 'C:\\VS2013',
46      sdk: null,
47      toolset: 'v120',
48      version: '12.0',
49      versionMajor: 12,
50      versionMinor: 0,
51      versionYear: 2013
52    })
53  })
54
55  finder.findVisualStudio2017OrNewer = (cb) => {
56    finder.parseData(new Error(), '', '', cb)
57  }
58  finder.regSearchKeys = (keys, value, addOpts, cb) => {
59    for (var i = 0; i < keys.length; ++i) {
60      const fullName = `${keys[i]}\\${value}`
61      switch (fullName) {
62        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
63        case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
64          continue
65        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0':
66          t.pass(`expected search for registry value ${fullName}`)
67          return cb(null, 'C:\\VS2013\\VC\\')
68        case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\12.0\\MSBuildToolsPath':
69          t.pass(`expected search for registry value ${fullName}`)
70          return cb(null, 'C:\\MSBuild12\\')
71        default:
72          t.fail(`unexpected search for registry value ${fullName}`)
73      }
74    }
75    return cb(new Error())
76  }
77  finder.findVisualStudio()
78})
79
80test('VS2013 should not be found on new node versions', function (t) {
81  t.plan(2)
82
83  const finder = new TestVisualStudioFinder({
84    major: 10,
85    minor: 0,
86    patch: 0
87  }, null, (err, info) => {
88    t.ok(/find .* Visual Studio/i.test(err), 'expect error')
89    t.false(info, 'no data')
90  })
91
92  finder.findVisualStudio2017OrNewer = (cb) => {
93    const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt')
94    const data = fs.readFileSync(file)
95    finder.parseData(null, data, '', cb)
96  }
97  finder.regSearchKeys = (keys, value, addOpts, cb) => {
98    for (var i = 0; i < keys.length; ++i) {
99      const fullName = `${keys[i]}\\${value}`
100      switch (fullName) {
101        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
102        case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
103          continue
104        default:
105          t.fail(`unexpected search for registry value ${fullName}`)
106      }
107    }
108    return cb(new Error())
109  }
110  finder.findVisualStudio()
111})
112
113test('VS2015', function (t) {
114  t.plan(4)
115
116  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
117    t.strictEqual(err, null)
118    t.deepEqual(info, {
119      msBuild: 'C:\\MSBuild14\\MSBuild.exe',
120      path: 'C:\\VS2015',
121      sdk: null,
122      toolset: 'v140',
123      version: '14.0',
124      versionMajor: 14,
125      versionMinor: 0,
126      versionYear: 2015
127    })
128  })
129
130  finder.findVisualStudio2017OrNewer = (cb) => {
131    finder.parseData(new Error(), '', '', cb)
132  }
133  finder.regSearchKeys = (keys, value, addOpts, cb) => {
134    for (var i = 0; i < keys.length; ++i) {
135      const fullName = `${keys[i]}\\${value}`
136      switch (fullName) {
137        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
138          t.pass(`expected search for registry value ${fullName}`)
139          return cb(null, 'C:\\VS2015\\VC\\')
140        case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\14.0\\MSBuildToolsPath':
141          t.pass(`expected search for registry value ${fullName}`)
142          return cb(null, 'C:\\MSBuild14\\')
143        default:
144          t.fail(`unexpected search for registry value ${fullName}`)
145      }
146    }
147    return cb(new Error())
148  }
149  finder.findVisualStudio()
150})
151
152test('error from PowerShell', function (t) {
153  t.plan(2)
154
155  const finder = new TestVisualStudioFinder(semverV1, null, null)
156
157  finder.parseData(new Error(), '', '', (info) => {
158    t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error')
159    t.false(info, 'no data')
160  })
161})
162
163test('empty output from PowerShell', function (t) {
164  t.plan(2)
165
166  const finder = new TestVisualStudioFinder(semverV1, null, null)
167
168  finder.parseData(null, '', '', (info) => {
169    t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error')
170    t.false(info, 'no data')
171  })
172})
173
174test('output from PowerShell not JSON', function (t) {
175  t.plan(2)
176
177  const finder = new TestVisualStudioFinder(semverV1, null, null)
178
179  finder.parseData(null, 'AAAABBBB', '', (info) => {
180    t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error')
181    t.false(info, 'no data')
182  })
183})
184
185test('wrong JSON from PowerShell', function (t) {
186  t.plan(2)
187
188  const finder = new TestVisualStudioFinder(semverV1, null, null)
189
190  finder.parseData(null, '{}', '', (info) => {
191    t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error')
192    t.false(info, 'no data')
193  })
194})
195
196test('empty JSON from PowerShell', function (t) {
197  t.plan(2)
198
199  const finder = new TestVisualStudioFinder(semverV1, null, null)
200
201  finder.parseData(null, '[]', '', (info) => {
202    t.ok(/find .* Visual Studio/i.test(finder.errorLog[0]), 'expect error')
203    t.false(info, 'no data')
204  })
205})
206
207test('future version', function (t) {
208  t.plan(3)
209
210  const finder = new TestVisualStudioFinder(semverV1, null, null)
211
212  finder.parseData(null, JSON.stringify([{
213    packages: [
214      'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
215      'Microsoft.VisualStudio.Component.Windows10SDK.17763',
216      'Microsoft.VisualStudio.VC.MSBuild.Base'
217    ],
218    path: 'C:\\VS',
219    version: '9999.9999.9999.9999'
220  }]), '', (info) => {
221    t.ok(/unknown version/i.test(finder.errorLog[0]), 'expect error')
222    t.ok(/find .* Visual Studio/i.test(finder.errorLog[1]), 'expect error')
223    t.false(info, 'no data')
224  })
225})
226
227test('single unusable VS2017', function (t) {
228  t.plan(3)
229
230  const finder = new TestVisualStudioFinder(semverV1, null, null)
231
232  const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt')
233  const data = fs.readFileSync(file)
234  finder.parseData(null, data, '', (info) => {
235    t.ok(/checking/i.test(finder.errorLog[0]), 'expect error')
236    t.ok(/find .* Visual Studio/i.test(finder.errorLog[2]), 'expect error')
237    t.false(info, 'no data')
238  })
239})
240
241test('minimal VS2017 Build Tools', function (t) {
242  t.plan(2)
243
244  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
245    t.strictEqual(err, null)
246    t.deepEqual(info, {
247      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' +
248        'BuildTools\\MSBuild\\15.0\\Bin\\MSBuild.exe',
249      path:
250        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools',
251      sdk: '10.0.17134.0',
252      toolset: 'v141',
253      version: '15.9.28307.665',
254      versionMajor: 15,
255      versionMinor: 9,
256      versionYear: 2017
257    })
258  })
259
260  poison(finder, 'regSearchKeys')
261  finder.findVisualStudio2017OrNewer = (cb) => {
262    const file = path.join(__dirname, 'fixtures',
263      'VS_2017_BuildTools_minimal.txt')
264    const data = fs.readFileSync(file)
265    finder.parseData(null, data, '', cb)
266  }
267  finder.findVisualStudio()
268})
269
270test('VS2017 Community with C++ workload', function (t) {
271  t.plan(2)
272
273  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
274    t.strictEqual(err, null)
275    t.deepEqual(info, {
276      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' +
277        'Community\\MSBuild\\15.0\\Bin\\MSBuild.exe',
278      path:
279        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community',
280      sdk: '10.0.17763.0',
281      toolset: 'v141',
282      version: '15.9.28307.665',
283      versionMajor: 15,
284      versionMinor: 9,
285      versionYear: 2017
286    })
287  })
288
289  poison(finder, 'regSearchKeys')
290  finder.findVisualStudio2017OrNewer = (cb) => {
291    const file = path.join(__dirname, 'fixtures',
292      'VS_2017_Community_workload.txt')
293    const data = fs.readFileSync(file)
294    finder.parseData(null, data, '', cb)
295  }
296  finder.findVisualStudio()
297})
298
299test('VS2017 Express', function (t) {
300  t.plan(2)
301
302  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
303    t.strictEqual(err, null)
304    t.deepEqual(info, {
305      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' +
306        'WDExpress\\MSBuild\\15.0\\Bin\\MSBuild.exe',
307      path:
308        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\WDExpress',
309      sdk: '10.0.17763.0',
310      toolset: 'v141',
311      version: '15.9.28307.858',
312      versionMajor: 15,
313      versionMinor: 9,
314      versionYear: 2017
315    })
316  })
317
318  poison(finder, 'regSearchKeys')
319  finder.findVisualStudio2017OrNewer = (cb) => {
320    const file = path.join(__dirname, 'fixtures', 'VS_2017_Express.txt')
321    const data = fs.readFileSync(file)
322    finder.parseData(null, data, '', cb)
323  }
324  finder.findVisualStudio()
325})
326
327test('VS2019 Preview with C++ workload', function (t) {
328  t.plan(2)
329
330  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
331    t.strictEqual(err, null)
332    t.deepEqual(info, {
333      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' +
334        'Preview\\MSBuild\\Current\\Bin\\MSBuild.exe',
335      path:
336        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Preview',
337      sdk: '10.0.17763.0',
338      toolset: 'v142',
339      version: '16.0.28608.199',
340      versionMajor: 16,
341      versionMinor: 0,
342      versionYear: 2019
343    })
344  })
345
346  poison(finder, 'regSearchKeys')
347  finder.findVisualStudio2017OrNewer = (cb) => {
348    const file = path.join(__dirname, 'fixtures',
349      'VS_2019_Preview.txt')
350    const data = fs.readFileSync(file)
351    finder.parseData(null, data, '', cb)
352  }
353  finder.findVisualStudio()
354})
355
356test('minimal VS2019 Build Tools', function (t) {
357  t.plan(2)
358
359  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
360    t.strictEqual(err, null)
361    t.deepEqual(info, {
362      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' +
363        'BuildTools\\MSBuild\\Current\\Bin\\MSBuild.exe',
364      path:
365        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools',
366      sdk: '10.0.17134.0',
367      toolset: 'v142',
368      version: '16.1.28922.388',
369      versionMajor: 16,
370      versionMinor: 1,
371      versionYear: 2019
372    })
373  })
374
375  poison(finder, 'regSearchKeys')
376  finder.findVisualStudio2017OrNewer = (cb) => {
377    const file = path.join(__dirname, 'fixtures',
378      'VS_2019_BuildTools_minimal.txt')
379    const data = fs.readFileSync(file)
380    finder.parseData(null, data, '', cb)
381  }
382  finder.findVisualStudio()
383})
384
385test('VS2019 Community with C++ workload', function (t) {
386  t.plan(2)
387
388  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
389    t.strictEqual(err, null)
390    t.deepEqual(info, {
391      msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' +
392        'Community\\MSBuild\\Current\\Bin\\MSBuild.exe',
393      path:
394        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community',
395      sdk: '10.0.17763.0',
396      toolset: 'v142',
397      version: '16.1.28922.388',
398      versionMajor: 16,
399      versionMinor: 1,
400      versionYear: 2019
401    })
402  })
403
404  poison(finder, 'regSearchKeys')
405  finder.findVisualStudio2017OrNewer = (cb) => {
406    const file = path.join(__dirname, 'fixtures',
407      'VS_2019_Community_workload.txt')
408    const data = fs.readFileSync(file)
409    finder.parseData(null, data, '', cb)
410  }
411  finder.findVisualStudio()
412})
413
414function allVsVersions (t, finder) {
415  finder.findVisualStudio2017OrNewer = (cb) => {
416    const data0 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
417      'VS_2017_Unusable.txt')))
418    const data1 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
419      'VS_2017_BuildTools_minimal.txt')))
420    const data2 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
421      'VS_2017_Community_workload.txt')))
422    const data3 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
423      'VS_2017_Express.txt')))
424    const data4 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
425      'VS_2019_Preview.txt')))
426    const data5 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
427      'VS_2019_BuildTools_minimal.txt')))
428    const data6 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures',
429      'VS_2019_Community_workload.txt')))
430    const data = JSON.stringify(data0.concat(data1, data2, data3, data4,
431      data5, data6))
432    finder.parseData(null, data, '', cb)
433  }
434  finder.regSearchKeys = (keys, value, addOpts, cb) => {
435    for (var i = 0; i < keys.length; ++i) {
436      const fullName = `${keys[i]}\\${value}`
437      switch (fullName) {
438        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
439        case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0':
440          continue
441        case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0':
442          return cb(null, 'C:\\VS2013\\VC\\')
443        case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\12.0\\MSBuildToolsPath':
444          return cb(null, 'C:\\MSBuild12\\')
445        case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
446          return cb(null, 'C:\\VS2015\\VC\\')
447        case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\14.0\\MSBuildToolsPath':
448          return cb(null, 'C:\\MSBuild14\\')
449        default:
450          t.fail(`unexpected search for registry value ${fullName}`)
451      }
452    }
453    return cb(new Error())
454  }
455}
456
457test('fail when looking for invalid path', function (t) {
458  t.plan(2)
459
460  const finder = new TestVisualStudioFinder(semverV1, 'AABB', (err, info) => {
461    t.ok(/find .* Visual Studio/i.test(err), 'expect error')
462    t.false(info, 'no data')
463  })
464
465  allVsVersions(t, finder)
466  finder.findVisualStudio()
467})
468
469test('look for VS2013 by version number', function (t) {
470  t.plan(2)
471
472  const finder = new TestVisualStudioFinder(semverV1, '2013', (err, info) => {
473    t.strictEqual(err, null)
474    t.deepEqual(info.versionYear, 2013)
475  })
476
477  allVsVersions(t, finder)
478  finder.findVisualStudio()
479})
480
481test('look for VS2013 by installation path', function (t) {
482  t.plan(2)
483
484  const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2013',
485    (err, info) => {
486      t.strictEqual(err, null)
487      t.deepEqual(info.path, 'C:\\VS2013')
488    })
489
490  allVsVersions(t, finder)
491  finder.findVisualStudio()
492})
493
494test('look for VS2015 by version number', function (t) {
495  t.plan(2)
496
497  const finder = new TestVisualStudioFinder(semverV1, '2015', (err, info) => {
498    t.strictEqual(err, null)
499    t.deepEqual(info.versionYear, 2015)
500  })
501
502  allVsVersions(t, finder)
503  finder.findVisualStudio()
504})
505
506test('look for VS2015 by installation path', function (t) {
507  t.plan(2)
508
509  const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015',
510    (err, info) => {
511      t.strictEqual(err, null)
512      t.deepEqual(info.path, 'C:\\VS2015')
513    })
514
515  allVsVersions(t, finder)
516  finder.findVisualStudio()
517})
518
519test('look for VS2017 by version number', function (t) {
520  t.plan(2)
521
522  const finder = new TestVisualStudioFinder(semverV1, '2017', (err, info) => {
523    t.strictEqual(err, null)
524    t.deepEqual(info.versionYear, 2017)
525  })
526
527  allVsVersions(t, finder)
528  finder.findVisualStudio()
529})
530
531test('look for VS2017 by installation path', function (t) {
532  t.plan(2)
533
534  const finder = new TestVisualStudioFinder(semverV1,
535    'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community',
536    (err, info) => {
537      t.strictEqual(err, null)
538      t.deepEqual(info.path,
539        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community')
540    })
541
542  allVsVersions(t, finder)
543  finder.findVisualStudio()
544})
545
546test('look for VS2019 by version number', function (t) {
547  t.plan(2)
548
549  const finder = new TestVisualStudioFinder(semverV1, '2019', (err, info) => {
550    t.strictEqual(err, null)
551    t.deepEqual(info.versionYear, 2019)
552  })
553
554  allVsVersions(t, finder)
555  finder.findVisualStudio()
556})
557
558test('look for VS2019 by installation path', function (t) {
559  t.plan(2)
560
561  const finder = new TestVisualStudioFinder(semverV1,
562    'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools',
563    (err, info) => {
564      t.strictEqual(err, null)
565      t.deepEqual(info.path,
566        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools')
567    })
568
569  allVsVersions(t, finder)
570  finder.findVisualStudio()
571})
572
573test('msvs_version match should be case insensitive', function (t) {
574  t.plan(2)
575
576  const finder = new TestVisualStudioFinder(semverV1,
577    'c:\\program files (x86)\\microsoft visual studio\\2019\\BUILDTOOLS',
578    (err, info) => {
579      t.strictEqual(err, null)
580      t.deepEqual(info.path,
581        'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools')
582    })
583
584  allVsVersions(t, finder)
585  finder.findVisualStudio()
586})
587
588test('latest version should be found by default', function (t) {
589  t.plan(2)
590
591  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
592    t.strictEqual(err, null)
593    t.deepEqual(info.versionYear, 2019)
594  })
595
596  allVsVersions(t, finder)
597  finder.findVisualStudio()
598})
599
600test('run on a usable VS Command Prompt', function (t) {
601  t.plan(2)
602
603  process.env.VCINSTALLDIR = 'C:\\VS2015\\VC'
604  // VSINSTALLDIR is not defined on Visual C++ Build Tools 2015
605  delete process.env.VSINSTALLDIR
606
607  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
608    t.strictEqual(err, null)
609    t.deepEqual(info.path, 'C:\\VS2015')
610  })
611
612  allVsVersions(t, finder)
613  finder.findVisualStudio()
614})
615
616test('VCINSTALLDIR match should be case insensitive', function (t) {
617  t.plan(2)
618
619  process.env.VCINSTALLDIR =
620    'c:\\program files (x86)\\microsoft visual studio\\2019\\BUILDTOOLS\\VC'
621
622  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
623    t.strictEqual(err, null)
624    t.deepEqual(info.path,
625      'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools')
626  })
627
628  allVsVersions(t, finder)
629  finder.findVisualStudio()
630})
631
632test('run on a unusable VS Command Prompt', function (t) {
633  t.plan(2)
634
635  process.env.VCINSTALLDIR =
636    'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildToolsUnusable\\VC'
637
638  const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => {
639    t.ok(/find .* Visual Studio/i.test(err), 'expect error')
640    t.false(info, 'no data')
641  })
642
643  allVsVersions(t, finder)
644  finder.findVisualStudio()
645})
646
647test('run on a VS Command Prompt with matching msvs_version', function (t) {
648  t.plan(2)
649
650  process.env.VCINSTALLDIR = 'C:\\VS2015\\VC'
651
652  const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015',
653    (err, info) => {
654      t.strictEqual(err, null)
655      t.deepEqual(info.path, 'C:\\VS2015')
656    })
657
658  allVsVersions(t, finder)
659  finder.findVisualStudio()
660})
661
662test('run on a VS Command Prompt with mismatched msvs_version', function (t) {
663  t.plan(2)
664
665  process.env.VCINSTALLDIR =
666    'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC'
667
668  const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015',
669    (err, info) => {
670      t.ok(/find .* Visual Studio/i.test(err), 'expect error')
671      t.false(info, 'no data')
672    })
673
674  allVsVersions(t, finder)
675  finder.findVisualStudio()
676})
677