biz-a-cli 2.3.66 → 2.3.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/app.js CHANGED
@@ -5,7 +5,7 @@ import axios from "axios"
5
5
  import fs from "fs"
6
6
  import * as tar from "tar"
7
7
  import { verify, sign, privateDecrypt, constants as cryptoConstants } from "node:crypto"
8
- import { basename } from "node:path"
8
+ import path, { basename } from "node:path"
9
9
  import { env } from "../envs/env.js"
10
10
  import { prepareScript, encryptScript } from "./script.js"
11
11
  import { spawn } from "node:child_process"
@@ -124,11 +124,33 @@ Object
124
124
  }
125
125
 
126
126
  async function runUnitTests() { //SCY BZ 4331
127
- process.chdir(options.workingDir)
127
+ let jestCommand = ['--no-install', 'jest', '--json'];
128
+ let output = '';
128
129
 
129
- const child = spawn('npx', ['jest'], { stdio: 'inherit', shell: true });
130
- child.on('close', async (code) => {
131
- if (code == 0) {
130
+ const testDir = path.join(options.workingDir, "test");
131
+ const workDir = path.resolve(options.workingDir);
132
+ try {
133
+ process.chdir(testDir)
134
+ } catch (error) {
135
+ if (error.code === 'ENOENT') {
136
+ jestCommand.push('--passWithNoTests')
137
+ }
138
+ }
139
+ process.chdir(workDir);
140
+
141
+ const child = spawn('npx', jestCommand, { shell: true });
142
+ child.stderr.on('data', data => output += data?.toString())
143
+ child.on('close', async code => {
144
+ console.log('====================');
145
+ console.log(output);
146
+ console.log('====================');
147
+ let noTestsFound = output.includes('No tests found');
148
+ let missingJest = (output.includes('missing packages') && output.includes('jest'));
149
+ let passWithNoTests = jestCommand.includes('--passWithNoTests');
150
+
151
+ if ((code == 0) ||
152
+ ((code == 1) && noTestsFound) ||
153
+ ((code == 1) && missingJest && passWithNoTests)) {
132
154
  await addApp()
133
155
  } else {
134
156
  console.error('Biz-A Add aborted');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "biz-a-cli",
3
3
  "nameDev": "biz-a-cli-dev",
4
- "version": "2.3.66",
4
+ "version": "2.3.68",
5
5
  "versionDev": "0.0.34",
6
6
  "description": "",
7
7
  "main": "bin/index.js",
package/tests/app.test.js CHANGED
@@ -5,10 +5,14 @@ import { finished } from 'node:stream/promises'
5
5
  import { createDecipheriv } from 'node:crypto'
6
6
  import * as tar from "tar"
7
7
  import { env } from "../envs/env.js"
8
+ import path from "node:path"
8
9
 
9
10
  describe('Biz-A Apps CLI', () => {
10
11
  let originalOptions, originalCWD, axios, child_process;
12
+
13
+ const JEST_MESSAGE_TOTAL = 3;
11
14
  let returnedCode = 0;
15
+ let jestMessage = '';
12
16
 
13
17
  const logSpy = jest.spyOn(global.console, 'log').mockImplementation()
14
18
  const errorSpy = jest.spyOn(global.console, 'error').mockImplementation()
@@ -41,12 +45,15 @@ describe('Biz-A Apps CLI', () => {
41
45
  jest.unstable_mockModule('node:child_process', () => ({
42
46
  spawn: jest.fn().mockReturnValue({
43
47
  on: jest.fn((event, callback) => {
44
- if (event === "close") {
45
- callback(returnedCode);
46
- }
47
- })
48
+ if (event === "close") callback(returnedCode)
49
+ }),
50
+ stderr: {
51
+ on: jest.fn((event, callback) => {
52
+ if (event === "data") callback(jestMessage)
53
+ })
54
+ }
48
55
  })
49
- }));
56
+ }))
50
57
  child_process = (await import('node:child_process'));
51
58
  })
52
59
 
@@ -242,8 +249,8 @@ describe('Biz-A Apps CLI', () => {
242
249
 
243
250
  expect(postArgs[2]).toStrictEqual({ "headers": { "Content-Type": "text/plain" } })
244
251
 
245
- expect(logSpy.mock.calls[0][0]).toContain(`Finished packing ${Object.keys(mockScripts).length} files into "./upload/${appName.toLowerCase()}.tgz"`)
246
- expect(logSpy.mock.calls[1][0]).toContain(`Finished uploading "./upload/${appName.toLocaleLowerCase()}.tgz"`)
252
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 0][0]).toContain(`Finished packing ${Object.keys(mockScripts).length} files into "./upload/${appName.toLowerCase()}.tgz"`)
253
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 1][0]).toContain(`Finished uploading "./upload/${appName.toLocaleLowerCase()}.tgz"`)
247
254
 
248
255
  // fs.rmSync(mockDataFolder + '/' + appName, {recursive: true, force: true})
249
256
  })
@@ -303,12 +310,12 @@ describe('Biz-A Apps CLI', () => {
303
310
  'Invalid script syntax',
304
311
  { act: 'get = function () {return {modelA: {}}' }, // missing close closure at the end',
305
312
  () => {
306
- expect(logSpy.mock.calls.length).toBe(5)
307
- expect(logSpy.mock.calls[0][0]).toBe('===================\nA.JS\n===================')
308
- expect(logSpy.mock.calls[1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
309
- expect(logSpy.mock.calls[2][0]).toStrictEqual('a.js:1:38: SyntaxError: Unexpected token: eof, expected: punc «}»')
310
- expect(logSpy.mock.calls[3][0]).toStrictEqual('Running script with Import function')
311
- expect(logSpy.mock.calls[4][0]).toStrictEqual('===================\nEOF A.JS\n===================')
313
+ expect(logSpy.mock.calls.length).toBe(JEST_MESSAGE_TOTAL + 5)
314
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 0][0]).toBe('===================\nA.JS\n===================')
315
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
316
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 2][0]).toStrictEqual('a.js:1:38: SyntaxError: Unexpected token: eof, expected: punc «}»')
317
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 3][0]).toStrictEqual('Running script with Import function')
318
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 4][0]).toStrictEqual('===================\nEOF A.JS\n===================')
312
319
 
313
320
  expect(errorSpy.mock.calls.length).toBe(1)
314
321
  expect(errorSpy.mock.calls[0][0]).toBe('a.js : SyntaxError: Unexpected end of input')
@@ -318,13 +325,13 @@ describe('Biz-A Apps CLI', () => {
318
325
  'Failed to compile script with node sandbox and ES6 Import',
319
326
  { act: 'get = function () {return {modelA: {}}}\n modul.expor = get;\n' }, // wrong "module.export"
320
327
  () => {
321
- expect(logSpy.mock.calls.length).toBe(6)
322
- expect(logSpy.mock.calls[0][0]).toBe('===================\nA.JS\n===================')
323
- expect(logSpy.mock.calls[1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
324
- expect(logSpy.mock.calls[2][0]).toBe('Minify : \nget=function(){return{modelA:{}}};modul.expor=get;')
325
- expect(logSpy.mock.calls[3][0]).toBe("a.js : ReferenceError: modul is not defined")
326
- expect(logSpy.mock.calls[4][0]).toBe('Running script with Import function')
327
- expect(logSpy.mock.calls[5][0]).toStrictEqual('===================\nEOF A.JS\n===================')
328
+ expect(logSpy.mock.calls.length).toBe(JEST_MESSAGE_TOTAL + 6)
329
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 0][0]).toBe('===================\nA.JS\n===================')
330
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
331
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 2][0]).toBe('Minify : \nget=function(){return{modelA:{}}};modul.expor=get;')
332
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 3][0]).toBe("a.js : ReferenceError: modul is not defined")
333
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 4][0]).toBe('Running script with Import function')
334
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 5][0]).toStrictEqual('===================\nEOF A.JS\n===================')
328
335
 
329
336
  expect(errorSpy.mock.calls.length).toBe(1)
330
337
  expect(errorSpy.mock.calls[0][0]).toStrictEqual('a.js : Error: Invalid data URI')// ES6 import error
@@ -334,12 +341,12 @@ describe('Biz-A Apps CLI', () => {
334
341
  'Shall not allow empty script',
335
342
  { act: 'get = function () {}' }, // empty script
336
343
  () => {
337
- expect(logSpy.mock.calls.length).toBe(5)
338
- expect(logSpy.mock.calls[0][0]).toBe('===================\nA.JS\n===================')
339
- expect(logSpy.mock.calls[1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
340
- expect(logSpy.mock.calls[2][0]).toBe('Minify : \nget=function(){};')
341
- expect(logSpy.mock.calls[3][0]).toBe('Running script with Import function')
342
- expect(logSpy.mock.calls[4][0]).toStrictEqual('===================\nEOF A.JS\n===================')
344
+ expect(logSpy.mock.calls.length).toBe(JEST_MESSAGE_TOTAL + 5)
345
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 0][0]).toBe('===================\nA.JS\n===================')
346
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 1][0]).toBe('Running script with VM') // node sandbox (VN) error as console.log
347
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 2][0]).toBe('Minify : \nget=function(){};')
348
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 3][0]).toBe('Running script with Import function')
349
+ expect(logSpy.mock.calls[JEST_MESSAGE_TOTAL + 4][0]).toStrictEqual('===================\nEOF A.JS\n===================')
343
350
 
344
351
  expect(errorSpy.mock.calls.length).toBe(1)
345
352
  expect(errorSpy.mock.calls[0][0]).toStrictEqual('a.js : Failed to compile template script.\nPlease make sure the script is correct and not returning empty result')
@@ -359,7 +366,7 @@ describe('Biz-A Apps CLI', () => {
359
366
  mockIssuerKeyResponse()
360
367
  await runCommand('add', '-s', 'https://a.b.c', '-p', '1205', '-i', '2', '-d', mockDataFolder + '/' + expect.getState().currentTestName, "-v")
361
368
 
362
- expect(logSpy.mock.calls.length).toBe(0)
369
+ expect(logSpy.mock.calls.length).toBe(JEST_MESSAGE_TOTAL + 0)
363
370
 
364
371
  expect(errorSpy.mock.calls.length).toBe(1)
365
372
  expect(errorSpy.mock.calls[0][0]).toBe('Nothing to upload. Please recheck your app folder.')
@@ -389,9 +396,7 @@ describe('Biz-A Apps CLI', () => {
389
396
  expect(errorSpy.mock.calls[errorSpy.mock.calls.length - 1][0]).toBe('Unknown argument: Unknown Command')
390
397
  })
391
398
 
392
- it('Shall not continue add biz a template if code is not zero', async () => { //SCY BZ 4331
393
- returnedCode = 1;
394
-
399
+ describe('run Jest', () => { //SCY BZ 4331
395
400
  const mockScripts = {
396
401
  'a.js': {
397
402
  act: 'get = function () {return {modelA: {}}}',
@@ -399,13 +404,138 @@ describe('Biz-A Apps CLI', () => {
399
404
  }
400
405
  }
401
406
  const appName = 'compressStressTest1';
402
- const oldCwd = process.cwd();
403
- mockValidTemplates(appName, mockScripts);
404
- await runCommand('add', '-s', 'https://a.b.c', '-p', '1205', '-i', '2', '-d', mockDataFolder + '/' + appName)
407
+ const fullTestPath = mockDataFolder + appName;
408
+ const absoluteFullTestPath = path.resolve(fullTestPath);
409
+
410
+ let jestArgs = ['--no-install', 'jest', '--json'];
411
+ let jestArgsWithPassNoTest = jestArgs.slice();
412
+ jestArgsWithPassNoTest.push('--passWithNoTests');
413
+
414
+ async function runJest() {
415
+ mockIssuerKeyResponse();
416
+ await runCommand('add', '-s', 'https://a.b.c', '-p', '1205', '-i', '2', '-d', fullTestPath)
417
+ }
418
+
419
+ function continueExpect(args) {
420
+ expect(process.cwd()).toBe(absoluteFullTestPath);
421
+ expect(child_process.spawn).toBeCalledWith("npx", args, { "shell": true });
422
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL - 2][0]).toBe('====================');
423
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL - 1][0]).toBe(jestMessage);
424
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL][0]).toBe('====================');
425
+ expect(errorSpy.mock.calls.length).toBe(0);
426
+ }
427
+
428
+ function abortExpect(args) {
429
+ expect(process.cwd()).toBe(absoluteFullTestPath);
430
+ expect(child_process.spawn).toBeCalledWith("npx", args, { "shell": true });
431
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL][0]).toBe('====================');
432
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL + 1][0]).toBe(jestMessage);
433
+ expect(logSpy.mock.calls[logSpy.mock.calls.length - JEST_MESSAGE_TOTAL + 2][0]).toBe('====================');
434
+ expect(errorSpy.mock.calls[errorSpy.mock.calls.length - 1][0]).toBe('Biz-A Add aborted');
435
+ }
436
+
437
+ it('Shall continue add biz a template, jest found, folder test found, unit test found, unit test passed', async () => {
438
+ returnedCode = 0;
439
+ jestMessage = 'Passed';
440
+
441
+ mockValidTemplates(appName, mockScripts);
442
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
443
+ fs.writeFileSync(fullTestPath + '/test/a.test.js', `it('dummy test', () => {
444
+ expect(true).toBe(true);
445
+ })`)
446
+
447
+ await runJest();
448
+ continueExpect(jestArgs);
449
+ })
450
+
451
+ it('Shall abort add biz a template, jest found, folder test found, unit test found, unit test failed', async () => {
452
+ returnedCode = 1;
453
+ jestMessage = 'FAIL';
454
+
455
+ mockValidTemplates(appName, mockScripts);
456
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
457
+ fs.writeFileSync(fullTestPath + '/test/a.test.js', `it('dummy test', () => {
458
+ expect(true).toBe(false);
459
+ })`)
460
+
461
+ await runJest();
405
462
 
406
- expect(process.cwd()).toStrictEqual(`${oldCwd}${mockDataFolder.split('.')[1].replaceAll('/', '\\')}${appName}`);
407
- expect(child_process.spawn).toBeCalledWith("npx", ["jest"], { "shell": true, "stdio": "inherit" });
408
- expect(errorSpy.mock.calls[errorSpy.mock.calls.length - 1][0]).toBe('Biz-A Add aborted');
463
+ abortExpect(jestArgs);
464
+ })
465
+
466
+ it('Shall continue add biz a template, jest found, folder test found, no unit test', async () => {
467
+ returnedCode = 1;
468
+ jestMessage = 'No tests found';
469
+
470
+ mockValidTemplates(appName, mockScripts);
471
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
472
+
473
+ await runJest();
474
+
475
+ continueExpect(jestArgs);
476
+ })
477
+
478
+ it('Shall continue add biz a template, jest found, no folder test', async () => {
479
+ returnedCode = 0;
480
+ jestMessage = 'No tests found';
481
+
482
+ mockValidTemplates(appName, mockScripts);
483
+ await runJest();
484
+
485
+ continueExpect(jestArgsWithPassNoTest);
486
+ })
487
+
488
+ it('Shall abort add biz a template, no jest found, folder test found, unit test found, unit test passed', async () => {
489
+ returnedCode = 1;
490
+ jestMessage = 'missing packages jest';
491
+
492
+ mockValidTemplates(appName, mockScripts);
493
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
494
+ fs.writeFileSync(fullTestPath + '/test/a.test.js', `it('dummy test', () => {
495
+ expect(true).toBe(true);
496
+ })`)
497
+
498
+ await runJest();
499
+
500
+ abortExpect(jestArgs);
501
+ })
502
+
503
+ it('Shall abort add biz a template, no jest found, folder test found, unit test found, unit test failed', async () => {
504
+ returnedCode = 1;
505
+ jestMessage = 'missing packages jest';
506
+
507
+ mockValidTemplates(appName, mockScripts);
508
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
509
+ fs.writeFileSync(fullTestPath + '/test/a.test.js', `it('dummy test', () => {
510
+ expect(true).toBe(false);
511
+ })`)
512
+
513
+ await runJest();
514
+
515
+ abortExpect(jestArgs);
516
+ })
517
+
518
+ it('Shall abort add biz a template, no jest found, folder test found, no unit test', async () => {
519
+ returnedCode = 1;
520
+ jestMessage = 'missing packages jest';
521
+
522
+ mockValidTemplates(appName, mockScripts);
523
+ fs.mkdirSync(fullTestPath + '/test', { recursive: true })
524
+
525
+ await runJest();
526
+
527
+ abortExpect(jestArgs);
528
+ })
529
+
530
+ it('Shall continue add biz a template, no jest found, no folder test', async () => {
531
+ returnedCode = 1;
532
+ jestMessage = 'missing packages jest';
533
+
534
+ mockValidTemplates(appName, mockScripts);
535
+ await runJest();
536
+
537
+ continueExpect(jestArgsWithPassNoTest);
538
+ })
409
539
  })
410
540
  })
411
541