1
+ import { createMockLogger } from '@openfn/logger' ;
1
2
import test from 'ava' ;
2
3
import mock from 'mock-fs' ;
3
- import path from 'node:path ' ;
4
+ import { execSync } from 'node:child_process ' ;
4
5
import fs from 'node:fs/promises' ;
5
- import { createMockLogger } from '@openfn/logger' ;
6
+ import os from 'node:os' ;
7
+ import path from 'node:path' ;
6
8
9
+ import { writeFileSync } from 'node:fs' ;
7
10
import { cmd } from '../src/cli' ;
8
11
import commandParser from '../src/commands' ;
9
12
import type { Opts } from '../src/options' ;
@@ -93,6 +96,47 @@ async function run(command: string, job: string, options: RunOptions = {}) {
93
96
}
94
97
}
95
98
99
+ async function mockResources ( ) {
100
+ const tmpdir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'commands-' ) ) ;
101
+ execSync ( `cp -r ${ path . resolve ( 'test' ) } /__*__ ${ tmpdir } ` ) ;
102
+
103
+ const generateJob = async ( job : string ) => {
104
+ if ( job ) writeFileSync ( path . join ( tmpdir , '/job.js' ) , job ) ;
105
+ } ;
106
+
107
+ const generateOutput = async ( value : string ) => {
108
+ if ( value ) writeFileSync ( path . join ( tmpdir , '/output.json' ) , value ) ;
109
+ } ;
110
+
111
+ const createNew = async ( filename : string , content : string ) => {
112
+ const newPath = path . join ( tmpdir , filename ) ;
113
+ writeFileSync ( newPath , content ) ;
114
+ return newPath ;
115
+ } ;
116
+
117
+ return {
118
+ mockPath : tmpdir ,
119
+ modulesPath : path . join ( tmpdir , '/__modules__' ) ,
120
+ monorepoPath : path . join ( tmpdir , '/__monorepo__' ) ,
121
+ repoPath : path . join ( tmpdir , '__repo__' ) ,
122
+ jobPath : path . join ( tmpdir , '/job.js' ) ,
123
+ outputPath : path . join ( tmpdir , '/output.json' ) ,
124
+ generateJob,
125
+ generateOutput,
126
+ createNew,
127
+ } ;
128
+ }
129
+
130
+ let resMock : Awaited < ReturnType < typeof mockResources > > ;
131
+
132
+ test . before ( async ( ) => {
133
+ resMock = await mockResources ( ) ;
134
+ } ) ;
135
+
136
+ test . after ( async ( ) => {
137
+ execSync ( `rm -rf ${ resMock . mockPath } ` ) ;
138
+ } ) ;
139
+
96
140
test . serial ( 'run an execution plan' , async ( t ) => {
97
141
const plan = {
98
142
workflow : {
@@ -404,36 +448,48 @@ test.serial(
404
448
) ;
405
449
406
450
test . serial (
407
- 'override an adaptor: openfn --no-expand-adaptors -S <obj> --adaptor times-two=/modules/times-two ' ,
451
+ 'override an adaptor: openfn --no-expand-adaptors -S <obj> --adaptor times-two=<path-to-module> ' ,
408
452
async ( t ) => {
409
453
const state = JSON . stringify ( { data : { count : 49.5 } } ) ;
454
+
455
+ await resMock . generateJob ( EXPR_MOCK_ADAPTOR ) ;
456
+
410
457
const result = await run (
411
- `openfn --no-expand-adaptors -S ${ state } --adaptor times-two=/modules/times-two` ,
412
- EXPR_MOCK_ADAPTOR
458
+ `openfn ${ resMock . jobPath } --no-expand-adaptors -S ${ state } --adaptor times-two=${ resMock . modulesPath } /times-two` ,
459
+ '' ,
460
+ { disableMock : true , outputPath : resMock . outputPath }
413
461
) ;
462
+
414
463
t . assert ( result . data . count === 99 ) ;
415
464
}
416
465
) ;
417
466
418
467
test . serial (
419
- 'override adaptors: openfn --no-expand-adaptors -S <obj> --adaptors times-two=/modules/times-two ' ,
468
+ 'override adaptors: openfn --no-expand-adaptors -S <obj> --adaptors times-two=<path-to-module> ' ,
420
469
async ( t ) => {
421
470
const state = JSON . stringify ( { data : { count : 49.5 } } ) ;
471
+
472
+ await resMock . generateJob ( EXPR_MOCK_ADAPTOR ) ;
422
473
const result = await run (
423
- `openfn --no-expand-adaptors -S ${ state } --adaptors times-two=/modules/times-two` ,
424
- EXPR_MOCK_ADAPTOR
474
+ `openfn ${ resMock . jobPath } --no-expand-adaptors -S ${ state } --adaptors times-two=${ resMock . modulesPath } /times-two` ,
475
+ '' ,
476
+ { disableMock : true , outputPath : resMock . outputPath }
425
477
) ;
426
478
t . assert ( result . data . count === 99 ) ;
427
479
}
428
480
) ;
429
481
430
482
test . serial (
431
- 'override adaptors: openfn --no-expand-adaptors -S <obj> -a times-two=/modules/times-two ' ,
483
+ 'override adaptors: openfn --no-expand-adaptors -S <obj> -a times-two=<path-to-module> ' ,
432
484
async ( t ) => {
433
485
const state = JSON . stringify ( { data : { count : 49.5 } } ) ;
486
+
487
+ // mock module with real filesystem
488
+ await resMock . generateJob ( EXPR_MOCK_ADAPTOR ) ;
434
489
const result = await run (
435
- `openfn --no-expand-adaptors -S ${ state } -a times-two=/modules/times-two` ,
436
- EXPR_MOCK_ADAPTOR
490
+ `openfn ${ resMock . jobPath } --no-expand-adaptors -S ${ state } -a times-two=${ resMock . modulesPath } /times-two` ,
491
+ '' ,
492
+ { disableMock : true , outputPath : resMock . outputPath }
437
493
) ;
438
494
t . assert ( result . data . count === 99 ) ;
439
495
}
@@ -444,11 +500,14 @@ test.serial(
444
500
async ( t ) => {
445
501
const state = JSON . stringify ( { data : { count : 11 } } ) ;
446
502
const job = 'export default [byTwo]' ;
503
+ await resMock . generateJob ( job ) ;
447
504
const result = await run (
448
- `openfn --no-expand-adaptors -S ${ state } -a times-two --no-autoinstall` ,
449
- job ,
505
+ `openfn ${ resMock . jobPath } --no-expand-adaptors -S ${ state } -a times-two --no-autoinstall` ,
506
+ '' ,
450
507
{
451
- repoDir : '/repo' ,
508
+ disableMock : true ,
509
+ repoDir : resMock . repoPath ,
510
+ outputPath : resMock . outputPath ,
452
511
}
453
512
) ;
454
513
t . assert ( result . data . count === 22 ) ;
@@ -460,9 +519,11 @@ test.serial(
460
519
async ( t ) => {
461
520
const state = JSON . stringify ( { data : { count : 22 } } ) ;
462
521
const job = 'export default [byTwo]' ;
522
+ await resMock . generateJob ( job ) ;
463
523
const result = await run (
464
- `openfn -S ${ state } -a times-two=/modules/times-two` ,
465
- job
524
+ `openfn ${ resMock . jobPath } -S ${ state } -a times-two=${ resMock . modulesPath } /times-two` ,
525
+ '' ,
526
+ { disableMock : true , outputPath : resMock . outputPath }
466
527
) ;
467
528
t . assert ( result . data . count === 44 ) ;
468
529
}
@@ -472,9 +533,16 @@ test.serial(
472
533
'auto-import from language-common (job): openfn job.js -a @openfn/[email protected] ' ,
473
534
async ( t ) => {
474
535
const job = 'fn((state) => { state.data.done = true; return state; });' ;
475
- const result = await run ( 'openfn -a @openfn/[email protected] ' , job , {
476
- repoDir : '/repo' ,
477
- } ) ;
536
+ await resMock . generateJob ( job ) ;
537
+ const result = await run (
538
+ `openfn ${ resMock . jobPath } -a @openfn/[email protected] ` ,
539
+ '' ,
540
+ {
541
+ disableMock : true ,
542
+ repoDir : resMock . repoPath ,
543
+ outputPath : resMock . outputPath ,
544
+ }
545
+ ) ;
478
546
t . true ( result . data ?. done ) ;
479
547
}
480
548
) ;
@@ -492,17 +560,19 @@ test.serial(
492
560
] ,
493
561
} ;
494
562
563
+ const wfPath = await resMock . createNew (
564
+ '/wf.json' ,
565
+ JSON . stringify ( workflow )
566
+ ) ;
495
567
const options = {
496
- outputPath : 'output.json' ,
497
- expressionPath : 'wf.json' ,
498
- repoDir : '/repo' ,
568
+ disableMock : true ,
569
+ outputPath : resMock . outputPath ,
570
+ expressionPath : wfPath ,
571
+ repoDir : resMock . repoPath ,
499
572
} ;
500
573
501
- const result = await run (
502
- 'openfn wf.json' ,
503
- JSON . stringify ( workflow ) ,
504
- options
505
- ) ;
574
+ await resMock . generateJob ( JSON . stringify ( workflow ) ) ;
575
+ const result = await run ( `openfn ${ wfPath } ` , '' , options ) ;
506
576
t . true ( result . data ?. done ) ;
507
577
}
508
578
) ;
@@ -512,11 +582,15 @@ test.serial(
512
582
async ( t ) => {
513
583
const job =
514
584
'alterState((state) => { /* function isn\t actually called by the mock adaptor */ throw new Error("fake adaptor") });' ;
585
+
586
+ await resMock . generateJob ( job ) ;
515
587
const result = await run (
516
- ' openfn -a @openfn/language-postgres --no-autoinstall' ,
517
- job ,
588
+ ` openfn ${ resMock . jobPath } -a @openfn/language-postgres --no-autoinstall` ,
589
+ '' ,
518
590
{
519
- repoDir : '/repo' ,
591
+ disableMock : true ,
592
+ repoDir : resMock . repoPath ,
593
+ outputPath : resMock . outputPath ,
520
594
}
521
595
) ;
522
596
t . assert ( result === 'execute called!' ) ;
@@ -526,9 +600,13 @@ test.serial(
526
600
test . serial (
527
601
'load an adaptor from the monorepo env var: openfn job.js -m -a common' ,
528
602
async ( t ) => {
529
- process . env . OPENFN_ADAPTORS_REPO = '/monorepo/' ;
603
+ process . env . OPENFN_ADAPTORS_REPO = resMock . monorepoPath ;
530
604
const job = 'export default [alterState(() => 39)]' ;
531
- const result = await run ( 'job.js -m -a common' , job ) ;
605
+ await resMock . generateJob ( job ) ;
606
+ const result = await run ( `${ resMock . jobPath } -m -a common` , '' , {
607
+ disableMock : true ,
608
+ outputPath : resMock . outputPath ,
609
+ } ) ;
532
610
t . assert ( result === 39 ) ;
533
611
delete process . env . OPENFN_ADAPTORS_REPO ;
534
612
}
0 commit comments