Skip to content

Commit

Permalink
fix: Add some perf tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S committed Apr 19, 2024
1 parent f345cef commit 1dd4d3c
Show file tree
Hide file tree
Showing 11 changed files with 1,444 additions and 66 deletions.
651 changes: 651 additions & 0 deletions fixtures/sample-data.txt

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@
"dependencies": {
"chalk": "^5.3.0",
"commander": "^12.0.0",
"globby": "^14.0.1"
"globby": "^14.0.1",
"lorem-ipsum": "^2.0.8",
"ora": "^8.0.1"
},
"files": [
"bin.mjs",
Expand Down
112 changes: 108 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 44 additions & 26 deletions src/app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { promises as fs } from 'node:fs';
import { fileURLToPath } from 'node:url';

import chalk from 'chalk';
import { Command, program as defaultCommand } from 'commander';
import { Argument, Command, program as defaultCommand } from 'commander';
import * as path from 'path';

import { findFiles } from './findFiles.mjs';
import { measureAnonymous } from './measureAnonymous.mjs';
import { measureMap } from './measureMap.mjs';
import { measureSearch } from './measureSearch.mjs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand All @@ -16,36 +18,52 @@ async function version(): Promise<string> {
return (typeof packageJson === 'object' && packageJson?.version) || '0.0.0';
}

interface CliOptions {
mustFindFiles?: boolean;
cwd?: string;
color?: boolean;
const knownTests = {
search: measureSearch,
anonymous: measureAnonymous,
map: measureMap,
};

const allTests = {
search: measureSearch,
anonymous: measureAnonymous,
map: measureMap,
all: async (timeout?: number) => {
for (const test of Object.values(knownTests)) {
await test(timeout);
}
},
};

interface AppOptions {
timeout?: number;
}

export async function app(program = defaultCommand): Promise<Command> {
const argument = new Argument('[test-methods...]', 'list of test methods to run');
argument.choices(Object.keys(allTests));
argument.default(['all']);
argument.variadic = true;

program
.name('list-files')
.description('List Files')
.argument('<files...>', 'Files to scan for injected content.')
.option('--no-must-find-files', 'No error if files are not found.')
.option('--cwd <dir>', 'Current Directory')
.option('--color', 'Force color.')
.option('--no-color', 'Do not use color.')
.name('perf runner')
.addArgument(argument)
.description('Run performance tests.')
.option('-t, --timeout <timeout>', 'timeout for each test', (v) => Number(v), 1000)
.version(await version())
.action(async (globs: string[], optionsCli: CliOptions, _command: Command) => {
.action(async (methods: string[], options: AppOptions) => {
// console.log('Options: %o', optionsCli);
program.showHelpAfterError(false);
if (optionsCli.color !== undefined) {
chalk.level = optionsCli.color ? 3 : 0;
}
console.log(chalk.yellow('Find Files:'));
const files = await findFiles(globs, optionsCli);
if (!files.length && optionsCli.mustFindFiles) {
program.error('No files found.');
}
const prefix = ' - ';
for (const file of files) {
console.log(chalk.gray(prefix) + chalk.white(file));
const timeout = options.timeout || 1000;
const tests = Object.entries(allTests);
for (const method of methods) {
const test = tests.find(([key]) => key === method);
if (!test) {
console.log(chalk.red(`Unknown test method: ${method}`));
continue;
}
const [key, fn] = test;
console.log(chalk.green(`Running test: ${key}`));
await fn(timeout);
}
console.log(chalk.green('done.'));
});
Expand Down
38 changes: 3 additions & 35 deletions src/app.test.mts
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
import { Command, CommanderError } from 'commander';
import { afterEach, describe, expect, test, vi } from 'vitest';

import { app, run } from './app.mjs';
import { run } from './app.mjs';

// const oc = expect.objectContaining;
const sc = expect.stringContaining;
const ac = expect.arrayContaining;
// const sc = expect.stringContaining;
// const ac = expect.arrayContaining;

describe('app', () => {
afterEach(() => {
vi.clearAllMocks();
});

test.each`
args | expected
${'*.md'} | ${ac([sc('README.md'), sc('done.')])}
${['not_found', '--no-must-find-files', '--no-color']} | ${ac(['Find Files:', 'done.'])}
`('run $args', async ({ args, expected }) => {
const argv = genArgv(args);
const program = new Command();
program.exitOverride((e) => {
throw e;
});
const spyLog = vi.spyOn(console, 'log').mockImplementation(() => undefined);
await expect(run(argv, program)).resolves.toBeUndefined();
expect(spyLog.mock.calls.map(([a]) => a)).toEqual(expected);
});

test.each`
args
${'--help'}
Expand All @@ -47,23 +32,6 @@ describe('app', () => {
expect(output.writeOut).toHaveBeenCalled();
expect(output.writeErr).not.toHaveBeenCalled();
});

test.each`
args | expected
${'*.md'} | ${ac([sc('README.md')])}
${['*.md', '--no-color']} | ${ac([sc(' - README.md')])}
`('app $args', async ({ args, expected }) => {
const argv = genArgv(args);
const program = new Command();
program.exitOverride((e) => {
throw e;
});
const spyLog = vi.spyOn(console, 'log').mockImplementation(() => undefined);
const cmd = await app(program);
expect(cmd).toBe(program);
await expect(cmd.parseAsync(argv)).resolves.toBe(program);
expect(spyLog.mock.calls.map(([a]) => a)).toEqual(expected);
});
});

function genArgv(args: string | string[]): string[] {
Expand Down
Loading

0 comments on commit 1dd4d3c

Please sign in to comment.