-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
105 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |