Skip to content

Commit

Permalink
chore: swap test runner
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeed committed Sep 18, 2020
1 parent c575213 commit b90c61c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 110 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"node": ">= 8"
},
"scripts": {
"test": "tape test/*.js | tap-spec"
"test": "uvu test -i fixtures"
},
"dependencies": {
"kleur": "^3.0.3",
Expand All @@ -31,7 +31,6 @@
"totalist": "^1.0.1"
},
"devDependencies": {
"tap-spec": "5.0.0",
"tape": "4.13.0"
"uvu": "0.3.3"
}
}
14 changes: 8 additions & 6 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const test = require('tape');
const { test } = require('uvu');
const assert = require('uvu/assert');
const ley = require('..');

test('exports', t => {
t.is(typeof ley, 'object');
t.is(typeof ley.up, 'function');
t.is(typeof ley.down, 'function');
t.end();
test('exports', () => {
assert.type(ley, 'object');
assert.type(ley.up, 'function');
assert.type(ley.down, 'function');
});

test.run();
196 changes: 95 additions & 101 deletions test/util.js
Original file line number Diff line number Diff line change
@@ -1,240 +1,234 @@
const test = require('tape');
const { join, resolve, isAbsolute } = require('path');
const { test } = require('uvu');
const assert = require('uvu/assert');
const { join, isAbsolute } = require('path');
const $ = require('../lib/util');

const cwd = join(__dirname, 'pg');
const cwd = join(__dirname, 'fixtures', 'pg');
const dir = join(cwd, 'migrations');

test('(utils) glob', async t => {
test('(utils) glob', async () => {
const out = await $.glob(dir);
t.true(Array.isArray(out), 'returns Promise<Array>');
t.is(out.length, 6, '~> has 6 items');
assert.ok(Array.isArray(out), 'returns Promise<Array>');
assert.is(out.length, 6, '~> has 6 items');

const first = out[0];
t.is(typeof first, 'object', 'items are objects');
t.is(typeof first.name, 'string', '~> has "name" string');
t.is(typeof first.abs, 'string', '~> has "abs" string');
t.true(isAbsolute(first.abs), '~~> is absolute path');
assert.type(first, 'object', 'items are objects');
assert.type(first.name, 'string', '~> has "name" string');
assert.type(first.abs, 'string', '~> has "abs" string');
assert.ok(isAbsolute(first.abs), '~~> is absolute path');

const names = out.map(x => x.name);
const expects = ['001.js', '002.js', '003.js', '004.js', '005.js', '006.js'];
t.same(names, expects, '~> file order is expected');

t.end();
assert.equal(names, expects, '~> file order is expected');
});


test('(utils) glob :: throws', async t => {
t.plan(3);
test('(utils) glob :: throws', async () => {
let caught = false;

try {
await $.glob(join(cwd, 'foobar'));
t.pass('should not run');
assert.unreachable('should not run');
} catch (err) {
t.true(err instanceof Error, 'throws an Error');
t.is(err.code, 'ENOENT', '~> is "ENOENT" code');
t.true(err.stack.includes('no such file or directory'), '~> has detail');
assert.instance(err, Error, 'throws an Error');
assert.is(err.code, 'ENOENT', '~> is "ENOENT" code');
assert.ok(err.stack.includes('no such file or directory'), '~> has detail');
caught = true;
}

assert.ok(caught);
});


test('(utils) diff', t => {
test('(utils) diff', () => {
const exists = ['001', '002', '003'].map(name => ({ name }));
const locals = ['001', '002', '003', '004', '005'].map(name => ({ name }));

const output = $.diff(exists, locals);
t.true(Array.isArray(output), 'returns an Array');
t.true(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
t.is(output.length, 2, '~> has 2 NEW items');
assert.ok(Array.isArray(output), 'returns an Array');
assert.ok(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
assert.is(output.length, 2, '~> has 2 NEW items');

const names = output.map(x => x.name);
t.same(names, ['004', '005']);

t.end();
assert.equal(names, ['004', '005']);
});


test('(utils) diff :: identical', t => {
test('(utils) diff :: identical', () => {
const exists = ['001', '002', '003'].map(name => ({ name }));
const locals = ['001', '002', '003'].map(name => ({ name }));

const output = $.diff(exists, locals);
t.true(Array.isArray(output), 'returns an Array');
t.is(output.length, 0, '~> has 0 NEW items');

t.end();
assert.ok(Array.isArray(output), 'returns an Array');
assert.is(output.length, 0, '~> has 0 NEW items');
});


test('(utils) diff :: throws sequence error', t => {
t.plan(3);
test('(utils) diff :: throws sequence error', () => {
let caught = false;

try {
const exists = ['001', '003'].map(name => ({ name }));
const locals = ['001', '002', '003'].map(name => ({ name }));

$.diff(exists, locals);
t.pass('SHOULD NOT REACH');
assert.unreachable('SHOULD NOT REACH');
} catch (err) {
t.true(err instanceof Error, 'throws an Error');
t.is(err.message, `Cannot run "002" after "003" has been applied`);
t.true(err.stack.length > err.message.length, '~> has "stack" details');
caught = true;
assert.instance(err, Error, 'throws an Error');
assert.is(err.message, `Cannot run "002" after "003" has been applied`);
assert.ok(err.stack.length > err.message.length, '~> has "stack" details');
}

assert.ok(caught);
});


// Note: Arrays are received in reverse
test('(utils) pluck', t => {
test('(utils) pluck', () => {
// should return everything, in sync
const foobar = ['003', '002', '001'];

const exists = foobar.map(name => ({ name }));
const locals = foobar.map(name => ({ name }));

const output = $.pluck(exists, locals);
t.true(Array.isArray(output), 'returns an Array');
t.true(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
t.is(output.length, 3, '~> has 3 candidates');
assert.ok(Array.isArray(output), 'returns an Array');
assert.ok(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
assert.is(output.length, 3, '~> has 3 candidates');

const names = output.map(x => x.name);
t.same(names, foobar);

t.end();
assert.equal(names, foobar);
});


// Note: Arrays are received in reverse
test('(utils) pluck :: locals >> exists', t => {
test('(utils) pluck :: locals >> exists', () => {
// should NOT return items that don't exist yet
const exists = ['003', '002', '001'].map(name => ({ name }));
const locals = ['005', '004', '003', '002', '001'].map(name => ({ name }));

const output = $.pluck(exists, locals);
t.true(Array.isArray(output), 'returns an Array');
t.true(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
t.is(output.length, 3, '~> has 3 candidates');
assert.ok(Array.isArray(output), 'returns an Array');
assert.ok(output.every(x => locals.includes(x)), '~> only returns items from `locals` list');
assert.is(output.length, 3, '~> has 3 candidates');

const names = output.map(x => x.name);
t.same(names, ['003', '002', '001']);

t.end();
assert.equal(names, ['003', '002', '001']);
});


// Note: Arrays are received in reverse
test('(utils) pluck :: exists >> locals :: throws', t => {
t.plan(3);
test('(utils) pluck :: exists >> locals :: throws', () => {
let caught = false;

try {
// throws error because we don't have 005 definitions
const exists = ['005', '004', '003', '002', '001'].map(name => ({ name }));
const locals = ['003', '002', '001'].map(name => ({ name }));

$.pluck(exists, locals);
t.pass('SHOULD NOT REACH');
assert.unreachable('SHOULD NOT REACH');
} catch (err) {
t.true(err instanceof Error, 'throws an Error');
t.is(err.message, `Cannot find "005" migration file`);
t.true(err.stack.length > err.message.length, '~> has "stack" details');
caught = true;
assert.instance(err, Error, 'throws an Error');
assert.is(err.message, `Cannot find "005" migration file`);
assert.ok(err.stack.length > err.message.length, '~> has "stack" details');
}

assert.ok(caught);
});


test('(utils) exists :: success', t => {
const output = $.exists('tape');
t.is(typeof output, 'string', 'returns string (success)');
t.is(output, require.resolve('tape'));
t.end();
test('(utils) exists :: success', () => {
const output = $.exists('uvu');
assert.type(output, 'string', 'returns string (success)');
assert.is(output, require.resolve('uvu'))
});


test('(utils) exists :: failure', t => {
test('(utils) exists :: failure', () => {
const output = $.exists('foobar');
t.is(typeof output, 'boolean', 'returns boolean (fail)');
t.is(output, false);
t.end();
assert.type(output, 'boolean', 'returns boolean (fail)');
assert.is(output, false)
});


test('(utils) exists :: failure :: relative', t => {
test('(utils) exists :: failure :: relative', () => {
const output = $.exists('./foobar');
t.is(typeof output, 'boolean', 'returns boolean (fail)');
t.is(output, false);
t.end();
assert.type(output, 'boolean', 'returns boolean (fail)');
assert.is(output, false)
});


test('(utils) detect', t => {
test('(utils) detect', () => {
const ORDER = ['postgres', 'pg', 'mysql', 'mysql2', 'better-sqlite3'];

const seen = [];
const prev = $.exists;

// @ts-ignore
$.exists = x => {
seen.push(x);
}

const foo = $.detect();
t.is(foo, undefined, 'returns undefined (failure)');
t.same(seen, ORDER, '~> looks for drivers (ordered)');
assert.is(foo, undefined, 'returns undefined (failure)');
assert.equal(seen, ORDER, '~> looks for drivers (ordered)');

// @ts-ignore
$.exists = x => x === 'pg';
const bar = $.detect();
t.is(bar, 'pg', '~> found "pg" (mock)');
assert.is(bar, 'pg', '~> found "pg" (mock)');

$.exists = prev;
t.end();
});


test('(utils) local :: success', t => {
test('(utils) local :: success', () => {
const output = $.local('index.js'); // root/index.js
t.is(typeof output, 'object', '~> returns _something_ if exists');
t.true(!!output.down, '~> had "down" export');
t.true(!!output.up, '~> had "up" export');
t.end();
assert.type(output, 'object', '~> returns _something_ if exists');
assert.type(output.down, 'function', '~> had "down" export');
assert.type(output.up, 'function', '~> had "up" export')
});


test('(utils) local :: success w/ cwd', t => {
test('(utils) local :: success w/ cwd', () => {
const output = $.local('util.js', __dirname); // this file
t.is(typeof output, 'object', '~> returns _something_ if exists');
t.end();
assert.type(output, 'object', '~> returns _something_ if exists')
});


test('(utils) local :: failure', t => {
test('(utils) local :: failure', () => {
const output = $.local('foobar.ts'); // root dir
t.is(output, false, '~> returns `false` if not found');
t.end();
assert.is(output, false, '~> returns `false` if not found')
});


test('(utils) local :: failure w/ cwd', t => {
test('(utils) local :: failure w/ cwd', () => {
const output = $.local('index.js', dir); // => pg/migrations/index.js
t.is(output, false, '~> returns `false` if not found');
t.end();
assert.is(output, false, '~> returns `false` if not found')
});


test('(utils) MigrationError', t => {
test('(utils) MigrationError', () => {
const original = new Error('hello world');
const migration = { name: '000.js', abs: 'path/to/000.js' };
Object.assign(original, { code: 42703, position: 8, foobar: undefined });

const error = new $.MigrationError(original, migration);
t.true(error instanceof $.MigrationError, 'is MigrationError');
t.true(error instanceof Error, '~> still inherits Error class');
assert.instance(error, $.MigrationError, 'is MigrationError');
assert.instance(error, Error, '~> still inherits Error class');

t.true(error.stack.length > 0, 'has "stack" trace');
t.true(error.stack.length > original.stack.length, '~> is longer than original trace');
t.true(error.stack.includes(original.stack), '~> contains original trace');
assert.ok(error.stack.length > 0, 'has "stack" trace');
assert.ok(error.stack.length > original.stack.length, '~> is longer than original trace');
assert.ok(error.stack.includes(original.stack), '~> contains original trace');

t.is(error.code, original.code, 'inherits original "code" property (custom)');
t.is(error.foobar, original.foobar, 'inherits original "foobar" property (custom)');
t.is(error.position, original.position, 'inherits original "position" property (custom)');
assert.is(error.code, original.code, 'inherits original "code" property (custom)');
assert.is(error.foobar, original.foobar, 'inherits original "foobar" property (custom)');
assert.is(error.position, original.position, 'inherits original "position" property (custom)');

t.same(error.migration, migration, 'attaches custom "migration" key w/ file data');

t.end();
assert.equal(error.migration, migration, 'attaches custom "migration" key w/ file data');
});

test.run();

0 comments on commit b90c61c

Please sign in to comment.