1- const { test } = require ( ' node:test' )
2- const assert = require ( 'node:assert/strict' )
1+ #!/usr/bin/env node
2+ // Custom test runner to avoid Node.js test runner serialization issues
33const awsLite = require ( '@aws-lite/client' )
44const { join, dirname } = require ( 'path' )
55const { mkdtempSync, mkdirSync, writeFileSync, rmSync } = require ( 'fs' )
66const { tmpdir } = require ( 'os' )
77const _inventory = require ( '@architect/inventory' )
88const { updater } = require ( '@architect/utils' )
99
10+ let passed = 0
11+ let failed = 0
1012let tmpDir
13+ let inventory
14+ let params
15+ let putted
16+ let deleted
17+ let aws
1118
1219function createTmpDir ( structure ) {
1320 const dir = mkdtempSync ( join ( tmpdir ( ) , 'arc-test-' ) )
@@ -20,7 +27,6 @@ function createTmpDir (structure) {
2027 createStructure ( path , value )
2128 }
2229 else {
23- // Ensure parent directory exists for files
2430 const parentDir = dirname ( path )
2531 mkdirSync ( parentDir , { recursive : true } )
2632 writeFileSync ( path , value || '' )
@@ -32,15 +38,11 @@ function createTmpDir (structure) {
3238 return dir
3339}
3440
35- let inventory
36- let params
37- let putted
38- let deleted
39-
4041function putFiles ( params , callback ) {
4142 putted = params
4243 callback ( null , params . files . length , 0 )
4344}
45+
4446function deleteFiles ( params , callback ) {
4547 deleted = params
4648 callback ( )
@@ -50,18 +52,20 @@ function deleteFiles (params, callback) {
5052const Module = require ( 'module' )
5153const originalLoad = Module . _load
5254Module . _load = function ( request , parent ) {
53- if ( request === './s3/put-files' && parent . filename . includes ( 'src/static/publish/index.js' ) ) {
55+ if ( request === './s3/put-files' && parent . filename && parent . filename . includes ( 'src/static/publish/index.js' ) ) {
5456 return putFiles
5557 }
56- if ( request === './s3/delete-files' && parent . filename . includes ( 'src/static/publish/index.js' ) ) {
58+ if ( request === './s3/delete-files' && parent . filename && parent . filename . includes ( 'src/static/publish/index.js' ) ) {
5759 return deleteFiles
5860 }
5961 return originalLoad . apply ( this , arguments )
6062}
6163
6264const sut = require ( join ( process . cwd ( ) , 'src' , 'static' , 'publish' , 'index.js' ) )
6365
64- let aws
66+ // Restore immediately after loading
67+ Module . _load = originalLoad
68+
6569let defaultParams = ( ) => ( {
6670 aws,
6771 Bucket : 'a-bucket' ,
@@ -85,85 +89,138 @@ function setup () {
8589 awsLite . testing . mock ( 'S3.DeleteObjects' , '' )
8690}
8791
88- test ( 'Set up env' , async ( ) => {
89- assert . ok ( sut , 'S3 publish module is present' )
90-
91- aws = await awsLite ( { region : 'us-west-2' , plugins : [ import ( '@aws-lite/s3' ) ] } )
92- awsLite . testing . enable ( )
93- assert . ok ( awsLite . testing . isEnabled ( ) , 'AWS client testing enabled' )
92+ async function test ( name , fn ) {
93+ try {
94+ await fn ( )
95+ console . log ( `✔ ${ name } ` )
96+ passed ++
97+ }
98+ catch ( err ) {
99+ console . error ( `✖ ${ name } ` )
100+ console . error ( err )
101+ failed ++
102+ }
103+ }
94104
95- tmpDir = createTmpDir ( {
96- 'app.arc' : arc ,
97- public : {
98- 'index.html' : content ,
99- 'something.json' : content ,
100- 'index.js' : content ,
101- } ,
105+ async function main ( ) {
106+ await test ( 'Set up env' , async ( ) => {
107+ if ( ! sut ) throw new Error ( 'S3 publish module is not present' )
108+
109+ aws = await awsLite ( { region : 'us-west-2' , plugins : [ import ( '@aws-lite/s3' ) ] } )
110+ awsLite . testing . enable ( )
111+ if ( ! awsLite . testing . isEnabled ( ) ) throw new Error ( 'AWS client testing not enabled' )
112+
113+ tmpDir = createTmpDir ( {
114+ 'app.arc' : arc ,
115+ public : {
116+ 'index.html' : content ,
117+ 'something.json' : content ,
118+ 'index.js' : content ,
119+ } ,
120+ } )
121+ inventory = await _inventory ( { cwd : tmpDir } )
122+ if ( ! inventory ) throw new Error ( 'Failed to get inventory obj' )
102123 } )
103- inventory = await _inventory ( { cwd : tmpDir } )
104- assert . ok ( inventory , 'Got inventory obj' )
105- } )
106124
107- test ( 'Static asset publishing' , ( t , done ) => {
108- setup ( )
109- sut ( params , err => {
110- if ( err ) assert . fail ( err )
111- assert . strictEqual ( putted . files . length , 3 , 'Passed files to be published' )
112- assert . strictEqual ( putted . fingerprint , null , 'Passed fingerprint unmutated' )
113- assert . ok ( putted . publicDir , 'Passed publicDir' )
114- assert . strictEqual ( putted . prefix , undefined , 'Passed prefix unmutated' )
115- assert . strictEqual ( putted . region , params . region , 'Passed region unmutated' )
116- assert . deepStrictEqual ( putted . staticManifest , { } , 'Passed empty staticManifest by default' )
117- assert . ok ( ! deleted , 'No files pruned' )
118- done ( )
125+ await test ( 'Static asset publishing' , async ( ) => {
126+ setup ( )
127+ await new Promise ( ( resolve , reject ) => {
128+ sut ( params , err => {
129+ if ( err ) reject ( err )
130+ else {
131+ try {
132+ if ( putted . files . length !== 3 ) throw new Error ( 'Expected 3 files to be published' )
133+ if ( putted . fingerprint !== null ) throw new Error ( 'Expected fingerprint to be null' )
134+ if ( ! putted . publicDir ) throw new Error ( 'Expected publicDir to be set' )
135+ if ( putted . prefix !== undefined ) throw new Error ( 'Expected prefix to be undefined' )
136+ if ( putted . region !== params . region ) throw new Error ( 'Expected region to match' )
137+ if ( JSON . stringify ( putted . staticManifest ) !== '{}' ) throw new Error ( 'Expected empty staticManifest' )
138+ if ( deleted ) throw new Error ( 'Expected no files to be pruned' )
139+ resolve ( )
140+ }
141+ catch ( err ) {
142+ reject ( err )
143+ }
144+ }
145+ } )
146+ } )
119147 } )
120- } )
121148
122- test ( `Static asset deletion (deployAction is 'all')` , ( t , done ) => {
123- setup ( )
124- let params = defaultParams ( )
125- params . prune = true
126- params . deployAction = 'all'
127- sut ( params , err => {
128- if ( err ) assert . fail ( err )
129- assert . strictEqual ( deleted . Bucket , params . Bucket , 'Passed bucket unmutated' )
130- assert . strictEqual ( deleted . files . length , 3 , 'Passed files to be published' )
131- assert . strictEqual ( deleted . fingerprint , null , 'Passed fingerprint unmutated' )
132- assert . strictEqual ( deleted . folder , params . folder , 'Passed folder unmutated' )
133- assert . strictEqual ( deleted . prefix , undefined , 'Passed prefix unmutated' )
134- assert . strictEqual ( deleted . region , params . region , 'Passed region setting unmutated' )
135- assert . deepStrictEqual ( deleted . staticManifest , { } , 'Passed empty staticManifest by default' )
136- done ( )
149+ await test ( 'Static asset deletion (deployAction is all)' , async ( ) => {
150+ setup ( )
151+ let testParams = defaultParams ( )
152+ testParams . prune = true
153+ testParams . deployAction = 'all'
154+ await new Promise ( ( resolve , reject ) => {
155+ sut ( testParams , err => {
156+ if ( err ) reject ( err )
157+ else {
158+ try {
159+ if ( deleted . Bucket !== testParams . Bucket ) throw new Error ( 'Expected bucket to match' )
160+ if ( deleted . files . length !== 3 ) throw new Error ( 'Expected 3 files' )
161+ if ( deleted . fingerprint !== null ) throw new Error ( 'Expected fingerprint to be null' )
162+ if ( deleted . folder !== testParams . folder ) throw new Error ( 'Expected folder to match' )
163+ if ( deleted . prefix !== undefined ) throw new Error ( 'Expected prefix to be undefined' )
164+ if ( deleted . region !== testParams . region ) throw new Error ( 'Expected region to match' )
165+ if ( JSON . stringify ( deleted . staticManifest ) !== '{}' ) throw new Error ( 'Expected empty staticManifest' )
166+ resolve ( )
167+ }
168+ catch ( err ) {
169+ reject ( err )
170+ }
171+ }
172+ } )
173+ } )
137174 } )
138- } )
139175
140- test ( `Static asset deletion (deployAction is 'delete')` , ( t , done ) => {
141- setup ( )
142- let params = defaultParams ( )
143- params . prune = true
144- params . deployAction = 'delete'
145- sut ( params , err => {
146- if ( err ) assert . fail ( err )
147- assert . strictEqual ( deleted . Bucket , params . Bucket , 'Passed bucket unmutated' )
148- assert . strictEqual ( deleted . files . length , 3 , 'Passed files to be published' )
149- assert . strictEqual ( deleted . fingerprint , null , 'Passed fingerprint unmutated' )
150- assert . strictEqual ( deleted . folder , params . folder , 'Passed folder unmutated' )
151- assert . strictEqual ( deleted . prefix , undefined , 'Passed prefix unmutated' )
152- assert . strictEqual ( deleted . region , params . region , 'Passed region setting unmutated' )
153- assert . deepStrictEqual ( deleted . staticManifest , { } , 'Passed empty staticManifest by default' )
154- done ( )
176+ await test ( 'Static asset deletion (deployAction is delete)' , async ( ) => {
177+ setup ( )
178+ let testParams = defaultParams ( )
179+ testParams . prune = true
180+ testParams . deployAction = 'delete'
181+ await new Promise ( ( resolve , reject ) => {
182+ sut ( testParams , err => {
183+ if ( err ) reject ( err )
184+ else {
185+ try {
186+ if ( deleted . Bucket !== testParams . Bucket ) throw new Error ( 'Expected bucket to match' )
187+ if ( deleted . files . length !== 3 ) throw new Error ( 'Expected 3 files' )
188+ if ( deleted . fingerprint !== null ) throw new Error ( 'Expected fingerprint to be null' )
189+ if ( deleted . folder !== testParams . folder ) throw new Error ( 'Expected folder to match' )
190+ if ( deleted . prefix !== undefined ) throw new Error ( 'Expected prefix to be undefined' )
191+ if ( deleted . region !== testParams . region ) throw new Error ( 'Expected region to match' )
192+ if ( JSON . stringify ( deleted . staticManifest ) !== '{}' ) throw new Error ( 'Expected empty staticManifest' )
193+ resolve ( )
194+ }
195+ catch ( err ) {
196+ reject ( err )
197+ }
198+ }
199+ } )
200+ } )
155201 } )
156- } )
157202
158- test ( 'Teardown' , ( ) => {
159- if ( tmpDir ) {
160- try {
161- rmSync ( tmpDir , { recursive : true , force : true } )
162- }
163- catch {
164- // Ignore cleanup errors
203+ await test ( 'Teardown' , async ( ) => {
204+ if ( tmpDir ) {
205+ try {
206+ rmSync ( tmpDir , { recursive : true , force : true } )
207+ }
208+ catch {
209+ // Ignore cleanup errors
210+ }
165211 }
166- }
167- awsLite . testing . disable ( )
168- assert . ok ( ! awsLite . testing . isEnabled ( ) , 'Done' )
169- } )
212+ awsLite . testing . disable ( )
213+ if ( awsLite . testing . isEnabled ( ) ) throw new Error ( 'AWS testing not disabled' )
214+ } )
215+
216+ console . log ( `\nℹ tests ${ passed + failed } ` )
217+ console . log ( `ℹ pass ${ passed } ` )
218+ console . log ( `ℹ fail ${ failed } ` )
219+
220+ process . exit ( failed > 0 ? 1 : 0 )
221+ }
222+
223+ // Only run if executed directly
224+ if ( require . main === module ) {
225+ main ( )
226+ }
0 commit comments