Skip to content

Commit

Permalink
✅ More test adjustments (#865)
Browse files Browse the repository at this point in the history
* 🔧 Add build pack script to aid in installing unreleased packages

* 🐛 Fix config packaged file path

* ✅ Lazily import test helper deps in case peer deps not installed

* ✅ Only import core test server helper in sdk-utils helper

Avoids importing other test helpers such as for client and config
  • Loading branch information
wwilsman authored Apr 5, 2022
1 parent 531d71a commit fe0e69e
Show file tree
Hide file tree
Showing 15 changed files with 42 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ oclif.manifest.json
.local-chromium
packages/logger/test/client.js
packages/sdk-utils/test/client.js
packs
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"scripts": {
"build": "lerna run build --stream",
"build:watch": "lerna run build --stream -- --watch",
"build:pack": "mkdir -p ./packs && lerna exec npm pack && mv ./packages/*/*.tgz ./packs",
"bump-version": "lerna version --exact --no-git-tag-version --no-push",
"chromium-revision": "./scripts/chromium-revision",
"clean": "git clean -Xdf -e !node_modules -e !**/node_modules/**",
Expand Down
17 changes: 8 additions & 9 deletions packages/cli/test/commands.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import { importCommands } from '../src/commands.js';

describe('CLI commands', () => {
beforeEach(async () => {
await logger.mock();
logger.loglevel('debug');
mockfs({ $modules: true });
await logger.mock({ level: 'debug' });
await mockfs({ $modules: true });
});

describe('from node_modules', () => {
Expand All @@ -30,28 +29,28 @@ describe('CLI commands', () => {
];

it('imports from dependencies', async () => {
mockModuleCommands(path.resolve('.'), mockCmds);
await mockModuleCommands(path.resolve('.'), mockCmds);
await expectAsync(importCommands()).toBeResolvedTo(expectedCmds);
expect(logger.stdout).toEqual([]);
expect(logger.stderr).toEqual([]);
});

it('imports from a parent directory', async () => {
mockModuleCommands(path.resolve('../..'), mockCmds);
await mockModuleCommands(path.resolve('../..'), mockCmds);
await expectAsync(importCommands()).toBeResolvedTo(expectedCmds);
expect(logger.stdout).toEqual([]);
expect(logger.stderr).toEqual([]);
});

it('imports from the current project', async () => {
mockModuleCommands(process.cwd(), mockCmds);
await mockModuleCommands(process.cwd(), mockCmds);
await expectAsync(importCommands()).toBeResolvedTo(expectedCmds);
expect(logger.stdout).toEqual([]);
expect(logger.stderr).toEqual([]);
});

it('automatically includes package information', async () => {
mockModuleCommands(path.resolve('.'), mockCmds);
await mockModuleCommands(path.resolve('.'), mockCmds);
let cmds = await importCommands();

expect(cmds[0].packageInformation.name).toEqual('@percy/cli-config');
Expand Down Expand Up @@ -96,7 +95,7 @@ describe('CLI commands', () => {

describe('legacy support', () => {
it('transforms oclif-like classes', async () => {
mockLegacyCommands(process.cwd(), {
await mockLegacyCommands(process.cwd(), {
'@percy/cli-legacy': { name: 'a' },
'@percy/cli-legacy-topic': { name: 'b', index: true },
'@percy/cli-legacy-index': { name: 'c', topic: true }
Expand Down Expand Up @@ -125,7 +124,7 @@ describe('CLI commands', () => {
it('runs oclif init hooks', async () => {
let init = jasmine.createSpy('init');

mockLegacyCommands(process.cwd(), {
await mockLegacyCommands(process.cwd(), {
'percy-cli-legacy': { name: 'test', init }
});

Expand Down
10 changes: 5 additions & 5 deletions packages/cli/test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export function mockUpdateCache(data, createdAt = Date.now()) {
}

// Mocks the filesystem and require cache to simulate installed commands
export function mockModuleCommands(atPath, cmdMocks) {
export async function mockModuleCommands(atPath, cmdMocks) {
let modulesPath = `${atPath}/node_modules`;
let vol = mockfs({ $modules: true, [modulesPath]: null });
let vol = await mockfs({ $modules: true, [modulesPath]: null });
let write = (rel, str) => vol.fromJSON({ [`${modulesPath}/${rel}`]: str });

// for coverage
Expand Down Expand Up @@ -57,7 +57,7 @@ export async function mockPnpCommands(atPath, cmdMocks) {
findPackageLocator.withArgs(projectInfo.packageLocation).and.returnValue(projectLoc);
getPackageInformation.withArgs(projectLoc).and.returnValue(projectInfo);

let vol = mockfs({ $modules: true });
let vol = await mockfs({ $modules: true });
let pnpPath = path.join('/.yarn/berry/cache');
let write = (fp, str) => vol.fromJSON({ [`${pnpPath}/${fp}`]: str });

Expand All @@ -80,9 +80,9 @@ export async function mockPnpCommands(atPath, cmdMocks) {
}

// Mocks the filesystem and require cache to simulate installed legacy commands
export function mockLegacyCommands(atPath, cmdMocks) {
export async function mockLegacyCommands(atPath, cmdMocks) {
let modulesPath = `${atPath}/node_modules`;
let vol = mockfs({ $modules: true, [modulesPath]: null });
let vol = await mockfs({ $modules: true, [modulesPath]: null });
let write = (fp, str) => vol.fromJSON({ [`${modulesPath}/${fp}`]: str });

for (let [pkgName, cmdMock] of Object.entries(cmdMocks)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/test/update.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('CLI update check', () => {

beforeEach(async () => {
let pkg = { name: '@percy/cli', version: '1.0.0' };
mockfs({ './package.json': JSON.stringify(pkg) });
await mockfs({ './package.json': JSON.stringify(pkg) });
ghAPI = await mockRequests('https://api.github.com');
await logger.mock();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"files": [
"dist",
"types/index.d.ts",
"tests/helpers.js"
"test/helpers.js"
],
"main": "./dist/index.js",
"types": "./types/index.d.ts",
Expand Down
18 changes: 9 additions & 9 deletions packages/config/test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import os from 'os';
import url from 'url';
import path from 'path';
import Module from 'module';
import { Volume, createFsFromVolume } from 'memfs';

import { clearMigrations } from '../src/migrate.js';
import { resetSchema } from '../src/validate.js';
import { cache } from '../src/load.js';

// Reset various global @percy/config internals for testing
export function resetPercyConfig(all) {
export async function resetPercyConfig(all) {
// aliased to src during tests
let { clearMigrations } = await import('../dist/migrate.js');
let { resetSchema } = await import('../dist/validate.js');
let { cache } = await import('../dist/load.js');
if (all) clearMigrations();
if (all) resetSchema();
cache.clear();
Expand All @@ -30,15 +29,16 @@ const INTERNAL_FILE_REG = new RegExp(
);

// Mock and spy on fs methods using an in-memory filesystem
export function mockfs({
export async function mockfs({
// set `true` to allow mocking files within `node_modules` (may cause dynamic import issues)
$modules = false,
// list of filepaths or function matchers to allow direct access to the real filesystem
$bypass = [],
// initial flat map of files and/or directories to create
...initial
} = {}) {
let vol = new Volume();
let memfs = await import('memfs');
let vol = new memfs.Volume();

// automatically cleanup mock imports
global.__MOCK_IMPORTS__?.clear();
Expand Down Expand Up @@ -81,7 +81,7 @@ export function mockfs({
};

// mock and install fs methods using the in-memory filesystem
let mock = createFsFromVolume(vol);
let mock = memfs.createFsFromVolume(vol);
installFakes(fs.promises, mock.promises);
installFakes(fs, mock);

Expand Down
4 changes: 2 additions & 2 deletions packages/config/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import PercyConfig from '@percy/config';

describe('PercyConfig', () => {
beforeEach(async () => {
await resetPercyConfig(true);
await logger.mock();
resetPercyConfig(true);
mockfs();
await mockfs();

PercyConfig.addSchema({
test: {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"./utils": "./dist/utils.js",
"./config": "./dist/config.js",
"./install": "./dist/install.js",
"./test/helpers": "./test/helpers/index.js"
"./test/helpers": "./test/helpers/index.js",
"./test/helpers/server": "./test/helpers/server.js"
},
"scripts": {
"build": "node ../../scripts/build",
Expand Down
6 changes: 3 additions & 3 deletions packages/core/test/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export async function setupTest({
loggerTTY,
apiDelay
} = {}) {
await logger.mock({ isTTY: loggerTTY });
await api.mock({ delay: apiDelay });
resetPercyConfig(resetConfig);
mockfs(filesystem);
await logger.mock({ isTTY: loggerTTY });
await resetPercyConfig(resetConfig);
await mockfs(filesystem);
}

export * from '@percy/client/test/helpers';
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/helpers/server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// aliased to src for coverage during tests without needing to compile this file
// aliased to src during tests
import Server from '../../dist/server.js';

export function createTestServer({ default: defaultReply, ...replies }, port = 8000) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/unit/install.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('Unit / Install', () => {

beforeEach(async () => {
await logger.mock({ isTTY: true });
mockfs();
await mockfs();

// mock a fake download api
dl = await mockRequests('https://fake-download.org/archive.zip');
Expand Down
4 changes: 2 additions & 2 deletions packages/core/test/unit/server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ describe('Unit / Server', () => {
return request(new URL(path, server.address()), ...args);
}

beforeEach(() => {
beforeEach(async () => {
server = new Server({ port: 8000 });
mockfs();
await mockfs();
});

afterEach(async () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/logger/test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ const helpers = {
async mock(options = {}) {
helpers.reset();

if (options.level) {
loglevel(options.level);
}

if (process.env.__PERCY_BROWSERIFIED__) {
spy(Logger.prototype, 'write', function(lvl, msg) {
let stdio = lvl === 'info' ? 'stdout' : 'stderr';
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk-utils/test/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'path';

// create a testing context for mocking the local percy server and a local testing site
export async function context() {
let { createTestServer } = await import('@percy/core/test/helpers');
let { createTestServer } = await import('@percy/core/test/helpers/server');

let ctx = {
async call(path, ...args) {
Expand Down

0 comments on commit fe0e69e

Please sign in to comment.