2021-02-19 04:31:33 +00:00
import { promises as fs } from 'fs'
import { tmpdir } from 'os'
import { join , resolve } from 'path'
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
import type { Report } from '../index.d'
2020-12-13 00:18:25 +00:00
import runPackwatch from '..'
2021-02-19 04:31:33 +00:00
async function prepareWorkspace ( ) : Promise < string > {
const workspacePath = await fs . mkdtemp ( ` ${ tmpdir ( ) } / ` , { recursive : true } )
return workspacePath
2020-12-13 00:18:25 +00:00
}
2021-02-19 04:31:33 +00:00
async function cleanUpWorkspace ( paths : string [ ] ) : Promise < void > {
return Promise . all (
paths . map ( async path = > fs . rmdir ( path , { recursive : true } ) ) ,
)
2020-12-13 00:18:25 +00:00
}
2021-02-19 04:31:33 +00:00
async function createFile ( path : string , content : string ) : Promise < void > {
await fs . writeFile ( path , content )
}
async function createPackageJson ( cwd : string ) : Promise < void > {
const path = resolve ( join ( cwd , 'package.json' ) )
await createFile (
path ,
'{ "name": "wow", "version": "0.0.0", "files": ["!.packwatch.json"] }' ,
)
}
async function createManifest (
cwd : string ,
configuration : Report ,
) : Promise < void > {
const path = resolve ( join ( cwd , '.packwatch.json' ) )
await createFile ( path , JSON . stringify ( configuration ) )
2020-12-13 00:18:25 +00:00
}
describe ( 'Packwatch' , ( ) = > {
let mockLogger
2021-02-19 04:31:33 +00:00
let workspacePath
2020-12-13 00:18:25 +00:00
beforeEach ( ( ) = > {
mockLogger = jest . spyOn ( global . console , 'log' ) . mockImplementation ( )
} )
2021-02-19 04:31:33 +00:00
afterEach ( async ( ) = > {
jest . restoreAllMocks ( )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
if ( workspacePath ) {
await cleanUpWorkspace ( [ workspacePath ] )
workspacePath = null
}
} )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
it ( 'warns the user and errors if run away from package.json' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
'There is no package.json file here. Are you in the root directory of your project?' ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
describe ( 'without manifest' , ( ) = > {
2021-02-19 04:31:33 +00:00
it ( 'generates the initial manifest properly' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
const generatedManifest = await fs . readFile (
resolve ( join ( workspacePath , '.packwatch.json' ) ) ,
{ encoding : 'utf8' } ,
)
expect ( generatedManifest ) . toEqual (
'{"limit":"160 B","packageSize":"160 B","unpackedSize":"68 B"}' ,
)
} )
it ( 'outputs expected messaging' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 2 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/No Manifest to compare against! Current package stats written to \.packwatch\.json!\nPackage size \(\d+ B\) adopted as new limit\./ ,
) ,
)
expect ( mockLogger . mock . calls [ 1 ] [ 0 ] ) . toEqual (
expect . stringMatching (
'It looks like you ran PackWatch without a manifest. To prevent accidental passes in CI or hooks, packwatch will terminate with an error. If you are running packwatch for the first time in your project, this is expected!' ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
2021-02-19 04:31:33 +00:00
it ( 'outputs expected messaging when not updating the manifest' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
2020-12-13 00:18:25 +00:00
2021-02-19 04:31:33 +00:00
await createPackageJson ( workspacePath )
runPackwatch ( { cwd : workspacePath , isUpdatingManifest : true } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/No Manifest to compare against! Current package stats written to \.packwatch\.json!\nPackage size \(\d+ B\) adopted as new limit\./ ,
) ,
)
2020-12-13 00:18:25 +00:00
} )
} )
describe ( 'with manifest' , ( ) = > {
2021-02-19 04:31:33 +00:00
it ( 'messages when the size is equal to the limit' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '160B' ,
packageSize : '160B' ,
unpackedSize : '150B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 160B\)/ ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
2021-02-19 04:31:33 +00:00
it ( 'messages when the size is lower than the limit (no growth)' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '170B' ,
packageSize : '160B' ,
unpackedSize : '150B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 170B\)/ ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
2021-02-19 04:31:33 +00:00
it ( 'messages when the size is lower than the limit (growth)' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '180B' ,
packageSize : '150B' ,
unpackedSize : '140B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Your package grew! \d+ B > 150B \(Limit: 180B\)/ ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
2021-02-19 04:31:33 +00:00
it ( 'messages when the size is lower than the limit (shrinkage)' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '180B' ,
packageSize : '170B' ,
unpackedSize : '140B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Your package shrank! \d+ B < 170B \(Limit: 180B\)/ ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
2021-02-19 04:31:33 +00:00
it ( 'messages when the size exceeds the limit' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '10B' ,
packageSize : '170B' ,
unpackedSize : '140B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Your package exceeds the limit set in \.packwatch\.json! \d+ B > 10B\nEither update the limit by using the --update-manifest flag or trim down your packed files!/ ,
) ,
)
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
it ( 'messages when updating the manifest' , async ( ) = > {
workspacePath = await prepareWorkspace ( )
await createPackageJson ( workspacePath )
await createManifest ( workspacePath , {
limit : '10B' ,
packageSize : '170B' ,
unpackedSize : '140B' ,
2020-12-13 00:18:25 +00:00
} )
2021-02-19 04:31:33 +00:00
runPackwatch ( { cwd : workspacePath , isUpdatingManifest : true } )
2020-12-13 00:18:25 +00:00
expect ( mockLogger . mock . calls ) . toHaveLength ( 1 )
2021-02-19 04:31:33 +00:00
expect ( mockLogger . mock . calls [ 0 ] [ 0 ] ) . toEqual (
expect . stringMatching (
/Updated the manifest! Package size: \d+ B, Limit: \d+ B/ ,
) ,
2020-12-13 00:18:25 +00:00
)
} )
} )
} )