refactor: mockless tests #163

Merged
mcataford merged 8 commits from mockless-tests into master 2021-02-19 04:31:33 +00:00
3 changed files with 131 additions and 223 deletions
Showing only changes of commit c11dc479ec - Show all commits

View file

@ -52,7 +52,6 @@
"eslint-plugin-jest": "^24.1.5", "eslint-plugin-jest": "^24.1.5",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.2",
"jest": "^26.0.1", "jest": "^26.0.1",
"mock-fs": "^4.11.0",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"semantic-release": "^17.0.4", "semantic-release": "^17.0.4",

View file

@ -1,35 +1,10 @@
import * as childProcess from 'child_process' import { promises as fs } from 'fs'
import { promises as fs, readFileSync } from 'fs'
import { tmpdir } from 'os' import { tmpdir } from 'os'
import { join, resolve } from 'path' import { join, resolve } from 'path'
import mockFS from 'mock-fs' import type { Report } from '../index.d'
import runPackwatch from '..' import runPackwatch from '..'
//jest.mock('child_process')
function getPackOutput({ packageSize, unpackedSize }) {
return `
npm notice
npm notice 📦 footprint@0.0.0
npm notice === Tarball Contents ===
npm notice 732B package.json
npm notice 1.8kB dist/helpers.js
npm notice 1.9kB dist/index.js
npm notice === Tarball Details ===
npm notice name: footprint
npm notice version: 0.0.0
npm notice filename: footprint-0.0.0.tgz
npm notice package size: ${packageSize}
npm notice unpacked size: ${unpackedSize}
npm notice shasum: bdf33d471543cd8126338a82a27b16a9010b8dbd
npm notice integrity: sha512-ZZvTg9GVcJw8J[...]bkE0xlqQhlt4Q==
npm notice total files: 3
npm notice
`
}
async function prepareWorkspace(): Promise<string> { async function prepareWorkspace(): Promise<string> {
const workspacePath = await fs.mkdtemp(`${tmpdir()}/`, { recursive: true }) const workspacePath = await fs.mkdtemp(`${tmpdir()}/`, { recursive: true })
return workspacePath return workspacePath
@ -45,41 +20,26 @@ async function createFile(path: string, content: string): Promise<void> {
await fs.writeFile(path, content) await fs.writeFile(path, content)
} }
/* async function createPackageJson(cwd: string): Promise<void> {
function getManifest() { const path = resolve(join(cwd, 'package.json'))
try { await createFile(
return JSON.parse(readFileSync(".packwatch.json", { encoding: "utf8" })) path,
} catch { '{ "name": "wow", "version": "0.0.0", "files": ["!.packwatch.json"] }',
} )
} }
function setupMockFS({ async function createManifest(
hasPackageJSON, cwd: string,
hasManifest, configuration: Report,
manifestLimit, ): Promise<void> {
manifestSize, const path = resolve(join(cwd, '.packwatch.json'))
}) { await createFile(path, JSON.stringify(configuration))
const fs = {}
if (hasPackageJSON) fs["package.json"] = "{}"
if (hasManifest)
fs[".packwatch.json"] = JSON.stringify({
unpackedSize: "0.5 B",
limitBytes: manifestLimit,
limit: `${manifestLimit} B`,
packageSize: `${manifestSize} B`,
packageSizeBytes: manifestSize,
})
mockFS(fs)
} }
*/
describe('Packwatch', () => { describe('Packwatch', () => {
let mockLogger let mockLogger
let workspacePath let workspacePath
beforeEach(() => { beforeEach(() => {
//mockFS({}) mockLogger = jest.spyOn(global.console, 'log').mockImplementation()
//mockLogger = jest.spyOn(global.console, 'log').mockImplementation()
}) })
afterEach(async () => { afterEach(async () => {
@ -91,34 +51,22 @@ describe('Packwatch', () => {
} }
}) })
/* it('warns the user and errors if run away from package.json', async () => {
afterAll(mockFS.restore)
*/
it.skip('warns the user and errors if run away from package.json', async () => {
workspacePath = await prepareWorkspace() workspacePath = await prepareWorkspace()
runPackwatch({ cwd: workspacePath }) runPackwatch({ cwd: workspacePath })
expect(mockLogger.mock.calls).toHaveLength(1) expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( expect(mockLogger.mock.calls[0][0]).toEqual(
'"🤔 There is no package.json file here. Are you in the root directory of your project?"', expect.stringMatching(
'There is no package.json file here. Are you in the root directory of your project?',
),
) )
}) })
describe('without manifest', () => { describe('without manifest', () => {
/*
beforeEach(() => {
setupMockFS({ hasPackageJSON: true })
})
*/
it('generates the initial manifest properly', async () => { it('generates the initial manifest properly', async () => {
workspacePath = await prepareWorkspace() workspacePath = await prepareWorkspace()
await createPackageJson(workspacePath)
await createFile(
resolve(join(workspacePath, 'package.json')),
'{ "name": "wow", "version": "0.0.0" }',
)
runPackwatch({ cwd: workspacePath }) runPackwatch({ cwd: workspacePath })
@ -127,185 +75,154 @@ describe('Packwatch', () => {
{ encoding: 'utf8' }, { encoding: 'utf8' },
) )
expect(generatedManifest).toMatchInlineSnapshot( expect(generatedManifest).toEqual(
'"{\\"limit\\":\\"138 B\\",\\"packageSize\\":\\"138 B\\",\\"unpackedSize\\":\\"37 B\\"}"', '{"limit":"160 B","packageSize":"160 B","unpackedSize":"68 B"}',
) )
}) })
/*it.each(["1 B", "1.1 B", "1 kB", "1.1 kB", "1 mB", "1.1 mB"])( it('outputs expected messaging', async () => {
"generates the initial manifest properly (size = %s)", workspacePath = await prepareWorkspace()
(mockSize) => { await createPackageJson(workspacePath)
jest.spyOn(childProcess, "spawnSync").mockReturnValue({
stderr: getPackOutput({
packageSize: mockSize,
unpackedSize: mockSize,
}),
})
const returnCode = runPackwatch({})
const manifest = getManifest()
expect(returnCode).toEqual(1)
expect(manifest).toEqual({
limit: mockSize,
packageSize: mockSize,
unpackedSize: mockSize,
})
}
)*/
it.skip('outputs expected messaging', () => { runPackwatch({ cwd: workspacePath })
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(2) expect(mockLogger.mock.calls).toHaveLength(2)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(` expect(mockLogger.mock.calls[0][0]).toEqual(
"📝 No Manifest to compare against! Current package stats written to .packwatch.json! expect.stringMatching(
Package size (1 B) adopted as new limit." /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]).toMatchInlineSnapshot( )
'"❗ 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!"', 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!',
),
) )
}) })
it.skip('outputs expected messaging when not updating the manifest', () => { it('outputs expected messaging when not updating the manifest', async () => {
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ workspacePath = await prepareWorkspace()
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({ isUpdatingManifest: true }) await createPackageJson(workspacePath)
runPackwatch({ cwd: workspacePath, isUpdatingManifest: true })
expect(mockLogger.mock.calls).toHaveLength(1) expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(` expect(mockLogger.mock.calls[0][0]).toEqual(
"📝 No Manifest to compare against! Current package stats written to .packwatch.json! expect.stringMatching(
Package size (1 B) adopted as new limit." /No Manifest to compare against! Current package stats written to \.packwatch\.json!\nPackage size \(\d+ B\) adopted as new limit\./,
`) ),
)
}) })
}) })
describe.skip('with manifest', () => { describe('with manifest', () => {
it('messages when the size is equal to the limit', () => { it('messages when the size is equal to the limit', async () => {
setupMockFS({ workspacePath = await prepareWorkspace()
hasPackageJSON: true,
hasManifest: true, await createPackageJson(workspacePath)
manifestLimit: 1, await createManifest(workspacePath, {
manifestSize: 1, limit: '160B',
packageSize: '160B',
unpackedSize: '150B',
}) })
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ runPackwatch({ cwd: workspacePath })
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(1) expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( expect(mockLogger.mock.calls[0][0]).toEqual(
'"📦 Nothing to report! Your package is the same size as the latest manifest reports! (Limit: 1 B)"', expect.stringMatching(
/Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 160B\)/,
),
) )
}) })
it('messages when the size is lower than the limit (no growth)', () => { it('messages when the size is lower than the limit (no growth)', async () => {
setupMockFS({ workspacePath = await prepareWorkspace()
hasPackageJSON: true,
hasManifest: true, await createPackageJson(workspacePath)
manifestLimit: 5, await createManifest(workspacePath, {
manifestSize: 1, limit: '170B',
}) packageSize: '160B',
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ unpackedSize: '150B',
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(
'"📦 Nothing to report! Your package is the same size as the latest manifest reports! (Limit: 5 B)"',
)
})
it('messages when the size is lower than the limit (growth)', () => {
setupMockFS({
hasPackageJSON: true,
hasManifest: true,
manifestLimit: 5,
manifestSize: 2,
})
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({
stderr: getPackOutput({
packageSize: '3 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(
'"📦 👀 Your package grew! 3 B > 2 B (Limit: 5 B)"',
)
})
it('messages when the size is lower than the limit (shrinkage)', () => {
setupMockFS({
hasPackageJSON: true,
hasManifest: true,
manifestLimit: 5,
manifestSize: 2,
})
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(
'"📦 💯 Your package shrank! 1 B < 2 B (Limit: 5 B)"',
)
})
it('messages when the size exceeds the limit', () => {
setupMockFS({
hasPackageJSON: true,
hasManifest: true,
manifestLimit: 0.5,
manifestSize: 0.5,
})
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({})
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(`
"🔥🔥📦🔥🔥 Your package exceeds the limit set in .packwatch.json! 1 B > 0.5 B
Either update the limit by using the --update-manifest flag or trim down your packed files!"
`)
}) })
it('messages when updating the manifest', () => { runPackwatch({ cwd: workspacePath })
setupMockFS({
hasPackageJSON: true,
hasManifest: true,
manifestLimit: 0.5,
manifestSize: 0.5,
})
jest.spyOn(childProcess, 'spawnSync').mockReturnValue({
stderr: getPackOutput({
packageSize: '1 B',
unpackedSize: '2 B',
}),
})
runPackwatch({ isUpdatingManifest: true })
expect(mockLogger.mock.calls).toHaveLength(1) expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( expect(mockLogger.mock.calls[0][0]).toEqual(
'"📝 Updated the manifest! Package size: 1 B, Limit: 1 B"', expect.stringMatching(
/Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 170B\)/,
),
)
})
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',
})
runPackwatch({ cwd: workspacePath })
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toEqual(
expect.stringMatching(
/Your package grew! \d+ B > 150B \(Limit: 180B\)/,
),
)
})
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',
})
runPackwatch({ cwd: workspacePath })
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toEqual(
expect.stringMatching(
/Your package shrank! \d+ B < 170B \(Limit: 180B\)/,
),
)
})
it('messages when the size exceeds the limit', async () => {
workspacePath = await prepareWorkspace()
await createPackageJson(workspacePath)
await createManifest(workspacePath, {
limit: '10B',
packageSize: '170B',
unpackedSize: '140B',
})
runPackwatch({ cwd: workspacePath })
expect(mockLogger.mock.calls).toHaveLength(1)
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!/,
),
)
})
it('messages when updating the manifest', async () => {
workspacePath = await prepareWorkspace()
await createPackageJson(workspacePath)
await createManifest(workspacePath, {
limit: '10B',
packageSize: '170B',
unpackedSize: '140B',
})
runPackwatch({ cwd: workspacePath, isUpdatingManifest: true })
expect(mockLogger.mock.calls).toHaveLength(1)
expect(mockLogger.mock.calls[0][0]).toEqual(
expect.stringMatching(
/Updated the manifest! Package size: \d+ B, Limit: \d+ B/,
),
) )
}) })
}) })

View file

@ -7501,13 +7501,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mock-fs@npm:^4.11.0":
version: 4.13.0
resolution: "mock-fs@npm:4.13.0"
checksum: cfb2134de7dfa53ebbbbacdd1b4fc834cce99ee9c231e8e129d9d32b669d15936217a7cdef8325946dd4e398ecfc401aa14c79030b8421cdf6ebd904786d8578
languageName: node
linkType: hard
"modify-values@npm:^1.0.0": "modify-values@npm:^1.0.0":
version: 1.0.1 version: 1.0.1
resolution: "modify-values@npm:1.0.1" resolution: "modify-values@npm:1.0.1"
@ -8423,7 +8416,6 @@ __metadata:
eslint-plugin-jest: ^24.1.5 eslint-plugin-jest: ^24.1.5
eslint-plugin-prettier: ^3.1.2 eslint-plugin-prettier: ^3.1.2
jest: ^26.0.1 jest: ^26.0.1
mock-fs: ^4.11.0
prettier: ^2.0.5 prettier: ^2.0.5
rimraf: ^3.0.2 rimraf: ^3.0.2
semantic-release: ^17.0.4 semantic-release: ^17.0.4