Removed knex mock (#9685)

no issue

- this mock eat already too much of my/our time
- the idea of adding a knex mock was definitely a failed approach/try
- it's too much to maintaince and have not found a module which does this already
  - we have to support any query format
  - this is too crazy
- the idea was to use the knex mock for model unit tests, because if we want to unit test models we have to
  run through bookshelf, because the whole model layer depends on bookshelf e.g. events
- for now we simply use the real database
  - we could use the sqlite3 memory mode, but that would mean every unit test runs on sqlite3
  - something to consider for later e.g. run unit tests on one matrix
  - run the rest on another matrix for sqlite + mysql
This commit is contained in:
Katharina Irrgang 2018-06-12 20:26:16 +02:00 committed by GitHub
parent 5079830ddb
commit 835fd6c45b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 70 additions and 552 deletions

View File

@ -16,7 +16,14 @@ const should = require('should'),
* either move to integration tests or rewrite!!!
*/
describe('{{ghost_head}} helper', function () {
let posts = [], tags = [], users = [], knexMock, firstCollection;
let posts = [], tags = [], users = [], firstCollection;
before(function () {
testUtils.integrationTesting.defaultMocks(sandbox);
});
before(testUtils.teardown);
before(testUtils.setup('users:roles', 'posts'));
before(function () {
models.init();
@ -25,16 +32,11 @@ describe('{{ghost_head}} helper', function () {
firstCollection.getRssUrl = sandbox.stub().returns('http://localhost:65530/rss/');
sandbox.stub(routing.registry, 'getFirstCollectionRouter').returns(firstCollection);
testUtils.integrationTesting.defaultMocks(sandbox);
settingsCache.get.withArgs('title').returns('Ghost');
settingsCache.get.withArgs('description').returns('blog description');
settingsCache.get.withArgs('cover_image').returns('/content/images/blog-cover.png');
settingsCache.get.withArgs('amp').returns(true);
knexMock = new testUtils.mocks.knex();
knexMock.mock();
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
meta_description: 'all about our blog',
title: 'About',
@ -324,7 +326,6 @@ describe('{{ghost_head}} helper', function () {
});
after(function () {
knexMock.unmock();
testUtils.integrationTesting.urlService.resetGenerators();
sandbox.restore();
configUtils.restore();

View File

@ -1,5 +1,4 @@
const _ = require('lodash');
const Promise = require('bluebird');
const should = require('should');
const sinon = require('sinon');
const rewire = require('rewire');
@ -11,24 +10,15 @@ const UrlService = rewire('../../../../server/services/url/UrlService');
const sandbox = sinon.sandbox.create();
describe('Unit: services/url/UrlService', function () {
let knexMock, urlService;
let urlService;
before(function () {
models.init();
});
beforeEach(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
knexMock.unmock();
});
before(testUtils.teardown);
before(testUtils.setup('users:roles', 'posts'));
after(testUtils.teardown);
after(function () {
sandbox.restore();
@ -37,7 +27,7 @@ describe('Unit: services/url/UrlService', function () {
describe('functional: default routing set', function () {
let router1, router2, router3, router4;
beforeEach(function (done) {
before(function (done) {
urlService = new UrlService();
router1 = {
@ -131,7 +121,7 @@ describe('Unit: services/url/UrlService', function () {
})();
});
afterEach(function () {
after(function () {
urlService.reset();
});
@ -211,6 +201,9 @@ describe('Unit: services/url/UrlService', function () {
});
describe('update resource', function () {
afterEach(testUtils.teardown);
afterEach(testUtils.setup('users:roles', 'posts'));
it('featured: false => featured:true', function () {
return models.Post.edit({featured: true}, {id: testUtils.DataGenerator.forKnex.posts[1].id})
.then(function (post) {
@ -307,7 +300,14 @@ describe('Unit: services/url/UrlService', function () {
describe('functional: extended/modified routing set', function () {
let router1, router2, router3, router4, router5;
beforeEach(function (done) {
before(testUtils.teardown);
before(testUtils.setup('users:roles', 'posts'));
before(function () {
urlService.resetGenerators();
});
before(function (done) {
urlService = new UrlService();
router1 = {
@ -420,7 +420,7 @@ describe('Unit: services/url/UrlService', function () {
})();
});
afterEach(function () {
after(function () {
urlService.resetGenerators();
});
@ -498,6 +498,9 @@ describe('Unit: services/url/UrlService', function () {
});
describe('update resource', function () {
afterEach(testUtils.teardown);
afterEach(testUtils.setup('users:roles', 'posts'));
it('featured: false => featured:true', function () {
return models.Post.edit({featured: true}, {id: testUtils.DataGenerator.forKnex.posts[1].id})
.then(function (post) {
@ -526,11 +529,11 @@ describe('Unit: services/url/UrlService', function () {
urlService.urlGenerators.forEach(function (generator) {
if (generator.router.getType() === 'posts' && generator.router.getFilter() === 'featured:false') {
generator.getUrls().length.should.eql(3);
generator.getUrls().length.should.eql(2);
}
if (generator.router.getType() === 'posts' && generator.router.getFilter() === 'featured:true') {
generator.getUrls().length.should.eql(1);
generator.getUrls().length.should.eql(2);
}
});
});

View File

@ -10,18 +10,11 @@ const should = require('should'),
sandbox = sinon.sandbox.create();
describe('Integration - Web - Site', function () {
let app, knexMock;
let app;
before(testUtils.setup('users:roles', 'posts'));
describe('default routes.yaml', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(themeConfig, 'create').returns({
posts_per_page: 2
@ -432,15 +425,6 @@ describe('Integration - Web - Site', function () {
});
describe('extended routes.yaml (1): 2 collections', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {
@ -575,15 +559,6 @@ describe('Integration - Web - Site', function () {
});
describe('extended routes.yaml (2): static permalink route', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},
@ -691,15 +666,6 @@ describe('Integration - Web - Site', function () {
describe('extended routes.yaml (3): templates', function () {
describe('(3) (1)', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},
@ -770,15 +736,6 @@ describe('Integration - Web - Site', function () {
});
describe('(3) (2)', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},
@ -831,15 +788,6 @@ describe('Integration - Web - Site', function () {
});
describe('(3) (3)', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},
@ -912,15 +860,6 @@ describe('Integration - Web - Site', function () {
});
describe('extended routes.yaml (4): primary author permalink', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},
@ -1006,15 +945,6 @@ describe('Integration - Web - Site', function () {
});
describe('extended routes.yaml (4): primary tag permalink', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {},

View File

@ -16,17 +16,11 @@ describe('Unit: models/invite', function () {
sandbox.restore();
});
before(testUtils.teardown);
describe('add', function () {
let knexMock;
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
beforeEach(testUtils.setup('roles'));
afterEach(testUtils.teardown);
it('default', function () {
return models.Invite.add({email: 'invited@test.org', role_id: testUtils.DataGenerator.forKnex.roles[1].id})

View File

@ -2,6 +2,7 @@ const should = require('should'),
sinon = require('sinon'),
models = require('../../../server/models'),
testUtils = require('../../utils'),
configUtils = require('../../utils/configUtils'),
sandbox = sinon.sandbox.create();
describe('Unit: models/permission', function () {
@ -11,19 +12,14 @@ describe('Unit: models/permission', function () {
after(function () {
sandbox.restore();
configUtils.restore();
});
before(testUtils.teardown);
describe('add', function () {
let knexMock;
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
beforeEach(testUtils.setup('roles'));
afterEach(testUtils.teardown);
it('without roles', function () {
return models.Permission.add({name: 'test', object_type: 'something', action_type: 'read something'})

View File

@ -5,26 +5,20 @@ const should = require('should'),
_ = require('lodash'),
testUtils = require('../../utils'),
knex = require('../../../server/data/db').knex,
settingsCache = require('../../../server/services/settings/cache'),
urlService = require('../../../server/services/url'),
schema = require('../../../server/data/schema'),
models = require('../../../server/models'),
common = require('../../../server/lib/common'),
security = require('../../../server/lib/security'),
utils = require('../../utils'),
sandbox = sinon.sandbox.create();
describe('Unit: models/post', function () {
let knexMock;
before(function () {
models.init();
});
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
before(testUtils.teardown);
before(testUtils.setup('users:roles', 'posts'));
beforeEach(function () {
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
@ -35,10 +29,6 @@ describe('Unit: models/post', function () {
sandbox.restore();
});
after(function () {
knexMock.unmock();
});
after(function () {
sandbox.restore();
});
@ -286,7 +276,7 @@ describe('Unit: models/post', function () {
// post will be updated, tags relation not
return models.Post.edit({
title: 'change',
tags: post.related('tags').toJSON()
tags: post.related('tags').attributes
}, _.merge({id: testUtils.DataGenerator.forKnex.posts[3].id}, testUtils.context.editor));
})
.then((post) => {
@ -820,9 +810,10 @@ describe('Unit: models/post', function () {
});
describe('edit', function () {
beforeEach(function () {
knexMock.resetDb();
beforeEach(testUtils.teardown);
beforeEach(testUtils.setup('users:roles', 'posts'));
beforeEach(function () {
// posts[3] has the following author_id
testUtils.DataGenerator.forKnex.posts[3].author_id.should.eql(testUtils.DataGenerator.forKnex.users[0].id);

View File

@ -13,18 +13,10 @@ describe('Unit: models/tags', function () {
sandbox.restore();
});
before(testUtils.teardown);
before(testUtils.setup('tags'));
describe('Edit', function () {
let knexMock;
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
it('resets given empty value to null', function () {
return models.Tag.findOne({slug: 'kitchen-sink'})
.then(function (tag) {

View File

@ -8,30 +8,22 @@ const should = require('should'),
sandbox = sinon.sandbox.create();
describe('Unit: models/user', function () {
let knexMock;
before(function () {
models.init();
});
before(testUtils.teardown);
before(testUtils.setup('users:roles'));
afterEach(function () {
sandbox.restore();
});
describe('validation', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
beforeEach(function () {
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
});
after(function () {
knexMock.unmock();
});
describe('password', function () {
it('no password', function () {
return models.User.add({email: 'test1@ghost.org', name: 'Ghosty'})
@ -96,19 +88,10 @@ describe('Unit: models/user', function () {
});
describe('fn: check', function () {
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
beforeEach(function () {
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
});
after(function () {
knexMock.unmock();
});
it('user status is warn', function () {
sandbox.stub(security.password, 'compare').resolves(true);
@ -308,8 +291,6 @@ describe('Unit: models/user', function () {
});
describe('Fetch', function () {
let knexMock;
before(function () {
models.init();
});
@ -318,15 +299,6 @@ describe('Unit: models/user', function () {
sandbox.restore();
});
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
it('ensure data type', function () {
return models.User.findOne({slug: 'joe-bloggs'}, testUtils.context.internal)
.then((user) => {
@ -339,8 +311,6 @@ describe('Unit: models/user', function () {
});
describe('Edit', function () {
let knexMock;
before(function () {
models.init();
});
@ -349,15 +319,6 @@ describe('Unit: models/user', function () {
sandbox.restore();
});
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
it('resets given empty value to null', function () {
return models.User.findOne({slug: 'joe-bloggs'})
.then(function (user) {

View File

@ -9,16 +9,16 @@ const Resources = require('../../../../server/services/url/Resources');
const sandbox = sinon.sandbox.create();
describe('Unit: services/url/Resources', function () {
let knexMock, onEvents, emitEvents, resources, queue;
let onEvents, emitEvents, resources, queue;
before(function () {
models.init();
});
beforeEach(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
before(testUtils.teardown);
before(testUtils.setup('users:roles', 'posts'));
beforeEach(function () {
onEvents = {};
emitEvents = {};
@ -38,7 +38,6 @@ describe('Unit: services/url/Resources', function () {
afterEach(function () {
sandbox.restore();
resources.reset();
knexMock.unmock();
});
it('db.ready', function (done) {

View File

@ -467,7 +467,14 @@ DataGenerator.forKnex = (function () {
}
function createUser(overrides) {
var newObj = _.cloneDeep(overrides);
var newObj = _.cloneDeep(overrides || {});
if (!newObj.slug) {
newObj.slug = 'slug_' + Date.now();
}
if (!newObj.email) {
newObj.email = `test${newObj.slug}@ghost.org`;
}
return _.defaults(newObj, {
id: ObjectId.generate(),
@ -475,7 +482,6 @@ DataGenerator.forKnex = (function () {
email: 'test@ghost.org',
bio: 'bio',
website: null,
slug: 'slug_' + Date.now(),
profile_image: null,
status: 'active',
password: 'Sl1m3rson99',

View File

@ -1031,6 +1031,7 @@ startGhost = function startGhost(options) {
module.exports = {
startGhost: startGhost,
integrationTesting: {
overrideGhostConfig: function overrideGhostConfig(configUtils) {
configUtils.set('paths:contentPath', path.join(__dirname, 'fixtures'));

View File

@ -1,3 +1,2 @@
exports.utils = require('./utils');
exports.express = require('./express');
exports.knex = require('./knex');

View File

@ -1,346 +0,0 @@
/* eslint-disable */
const mockKnex = require('mock-knex'),
_ = require('lodash'),
debug = require('ghost-ignition').debug('tests:knex-mock'),
DataGenerator = require('../fixtures/data-generator'),
knex = require('../../../server/data/db').knex;
/**
* Knex mock. The database values are taken from our Datagenerator.
* You can either self register queries or you simply rely on the data generator data.
*
* Please extend if your use-case does not work.
*
* @TODO: sqlite3 :memory: mode wasn't working for me
*/
class KnexMock {
initialiseDb() {
this.db = {};
_.each(_.pick(_.cloneDeep(DataGenerator.forKnex), [
'posts',
'users',
'tags',
'invites',
'permissions',
'roles',
'posts_authors',
'posts_tags'
]), (objects, tableName) => {
this.db[tableName] = [];
_.each(objects, (object) => {
this.db[tableName].push(object);
});
});
}
resetDb() {
return this.initialiseDb();
}
mock(options) {
options = options || {autoMock: true};
mockKnex.mock(knex);
this.initialiseDb();
this.tracker = mockKnex.getTracker();
this.tracker.install();
if (options.autoMock) {
this.tracker.on('query', (query) => {
query.sql = query.sql.replace(/`/g, '"');
debug('#### Query start.');
debug(query.sql);
// CASE: transactions
if (query.sql.match(/BEGIN|COMMIT|ROLLBACK/)) {
query.response();
debug('#### Query end.\n');
return;
}
if (query.method === 'select') {
if (query.bindings.length && query.sql.match(/where/)) {
// CASE: joins should return e.g. `posts_tags=[tag,tag]`
if (query.sql.match(/inner\sjoin/)) {
let targetTable = query.sql.match(/inner\sjoin\s(\"\w+\")/)[1],
targetAttribute = query.sql.match(/on\s\"\w+\"\.(\"\w+\")/)[1],
joinAttribute = query.sql.match(/on\s\"\w+\"\.\"\w+\"\s\=\s\"\w+\"\.(\"\w+\")/)[1],
joinTable = query.sql.match(/on\s\"\w+\"\.\"\w+\"\s\=\s(\"\w+\")/)[1],
targetIdentifier = query.sql.match(/(\"\w+\")\sin\s\(\?\)/),
values = query.bindings,
targetEntries,
toReturn = [];
if (!targetIdentifier) {
targetIdentifier = query.sql.match(/where\s\"\w+\"\.\"(\w+)\"\s\=/);
}
if (!targetIdentifier) {
targetIdentifier = query.sql.match(/where\s\"\w+\"\.\"(\w+)\"\s\in\s/);
}
if (targetIdentifier) {
targetIdentifier = targetIdentifier[1];
}
targetTable = targetTable.replace(/"/g, '');
targetIdentifier = targetIdentifier.replace(/"/g, '');
targetAttribute = targetAttribute.replace(/"/g, '');
joinTable = joinTable.replace(/"/g, '');
joinAttribute = joinAttribute.replace(/"/g, '');
debug(targetTable, targetIdentifier, targetAttribute, joinTable, joinAttribute);
targetEntries = _.filter(this.db[targetTable], ((existing) => {
if (values.indexOf(existing[targetIdentifier]) !== -1) {
return true;
}
}));
if (targetEntries && targetEntries.length) {
_.each(targetEntries, ((target) => {
let found = _.cloneDeep(_.find(this.db[joinTable], ((joinEntry) => {
if (joinEntry[joinAttribute] === target[targetAttribute]) {
return true;
}
})));
_.each(target, function (value, key) {
let match = query.sql.match(new RegExp('\\"' + targetTable + '\\"\\.\\"' + key + '"\\sas\\s(\\"\\w+\\")'));
// CASE: "posts_tags"."post_id" as "post_id"
if (match) {
match = match[1];
match = match.replace(/"/g, '');
found[match] = value;
}
});
let keys = query.sql.match(/select\s(\".*\"\,?)+\sfrom/)[1];
if (!keys.match(/\.*/)) {
_.each(found, (value, key)=> {
if (keys.indexOf(key) === -1) {
delete found[key];
}
});
}
if (found) {
toReturn.push(found);
}
}));
// @TODO: This is not really generic ;)
toReturn = _.orderBy(toReturn, ['_pivot_sort_order'], ['asc']);
query.response(toReturn);
debug('#### Query end.\n');
} else {
query.response([]);
debug('#### Query end.\n');
}
} else {
let tableName = query.sql.match(/from\s\"(\w+)\"/)[1],
where = query.sql.match(/\"(\w+)\"\s\=\s\?/),
values = query.bindings,
dbEntry,
wheres = [];
// where "users"."id" in ('1')
if (!where) {
where = query.sql.match(/\"\w+\"\.\"(\w+)\"\sin\s\(\?\)/)[1];
} else {
let wheresMatch = query.sql.match(/\(?\"(\w+)\"\.?\"?(\w+)?\"?\s=\s\?\)?/g);
// e.g. [ '("posts"."status" = ?)', '("posts"."page" = ?)' ]
// e.g. [ '"status" = ?' ]
_.each(wheresMatch, (result)=> {
let attr = result.match(/\(?\"(\w+)\"\.?\"?(\w+)?\"?\s=\s\?\)?/);
wheres.push(attr[2] || attr[1]);
});
}
values = query.bindings.slice(0, wheres.length);
debug(tableName, wheres, values);
dbEntry = _.filter(this.db[tableName], ((existing) => {
if (_.isEqual(_.values(_.pick(existing, wheres)), values)) {
return true;
}
}));
if (dbEntry) {
// select fields
dbEntry = _.map(dbEntry, (obj) => {
let keys = query.sql.match(/select\s(\".*\"\,?)+\sfrom/);
if (keys) {
keys = keys[1];
keys = keys.replace(/"/g, '');
keys = keys.replace(/\s/g, '');
keys = keys.split(',');
return _.pick(obj, keys);
}
return obj;
});
if (query.sql.match(/count\(/)) {
const as = query.sql.match(/count\(.*\)\sas\s(\w+)/)[1];
return query.response([{[as]: dbEntry.length}]);
}
if (query.sql.match(/limit\s\?\soffset\s\?/)) {
const limit = query.bindings[query.bindings.length - 2];
const offset = query.bindings[query.bindings.length - 1];
function separateIt(arr, size) {
const newArr = [];
for (let i = 0; i < arr.length; i += size) {
let sliceIt = arr.slice(i, i + size);
newArr.push(sliceIt);
}
return newArr;
}
dbEntry = separateIt(dbEntry, limit)[offset - 1];
} else if (query.sql.match(/limit\s\?$/)) {
const limit = query.bindings[query.bindings.length - 1];
dbEntry = dbEntry.splice(0, limit);
}
query.response(dbEntry);
debug('#### Query end.\n');
} else {
query.response([]);
debug('#### Query end. Not found\n');
}
}
} else {
const tableName = query.sql.match(/from\s\"(\w+)\"/)[1];
query.response(this.db[tableName]);
}
} else if (query.method === 'insert') {
const tableName = query.sql.match(/into\s\"(\w+)\"/)[1];
let keys = query.sql.match(/\(([^)]+)\)/)[1],
entry = {};
keys = keys.replace(/"/g, '');
keys = keys.replace(/\s/g, '');
keys = keys.split(',');
_.each(keys, (key, index) => {
entry[key] = query.bindings[index];
});
if (!this.db[tableName]) {
this.db[tableName] = [];
}
this.db[tableName].push(entry);
query.response(entry);
debug('#### Query end.\n');
} else if (query.method === 'update') {
let tableName = query.sql.match(/update\s\"(\w+)\"/)[1],
where = query.sql.match(/where\s\"(\w+)\"\s\=\s\?/)[1],
andWhere = query.sql.match(/where\s\"\w+\"\s\=\s\?\sand\s\"(\w+)\"/),
valueWhere,
valueAndWhere,
dbEntry;
if (andWhere) {
andWhere = andWhere[1];
valueWhere = query.bindings.slice(1, -1)[0];
valueAndWhere = query.bindings.slice(-1)[0];
} else {
valueWhere = query.bindings.slice(-1)[0];
}
debug(tableName, where, valueWhere, andWhere, valueAndWhere, query.bindings);
dbEntry = _.find(this.db[tableName], ((existing) => {
if (existing[where] === valueWhere) {
if (andWhere) {
if (existing[andWhere] === valueAndWhere) {
return true;
}
} else {
return true;
}
}
}));
if (!dbEntry) {
query.response([]);
debug('#### Query end. Can\'t update - not found.\n');
} else {
let keys = query.sql.match(/set(.*)where/)[1],
entry = {};
keys = keys.match(/\"\w+\"/g).join(',');
keys = keys.replace(/"/g, '');
keys = keys.replace(/\s/g, '');
keys = keys.split(',');
debug('set', keys);
_.each(keys, (key, index) => {
entry[key] = query.bindings[index];
dbEntry[key] = entry[key];
});
query.response(entry);
debug('#### Query end.\n');
}
} else {
let tableName = query.sql.match(/from\s\"(\w+)\"/)[1],
where = query.sql.match(/where\s\"(\w+)\"\s\=\s\?/)[1],
andWhere = query.sql.match(/where\s\"\w+\"\s\=\s\?\sand\s\"(\w+)\"/),
valueWhere,
valueAndWhere;
valueWhere = query.bindings[0];
if (andWhere) {
andWhere = andWhere[1];
valueAndWhere = query.bindings[1];
}
debug(tableName, where, valueWhere, andWhere, valueAndWhere, query.bindings);
this.db[tableName] = this.db[tableName].filter((existing) => {
if (existing[where] === valueWhere) {
if (andWhere) {
if (existing[andWhere] === valueAndWhere) {
return false;
} else {
return true;
}
} else {
return false;
}
} else {
return true;
}
});
query.response([]);
}
});
}
return this.tracker;
}
unmock() {
this.tracker.uninstall();
mockKnex.unmock(knex);
}
}
module.exports = KnexMock;

View File

@ -123,7 +123,6 @@
"matchdep": "2.0.0",
"minimist": "1.2.0",
"mocha": "4.1.0",
"mock-knex": "0.4.0",
"nock": "9.3.0",
"rewire": "3.0.2",
"should": "13.2.1",

View File

@ -3530,7 +3530,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
lodash@4.17.10, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.5:
lodash@4.17.10, lodash@^4.13.1, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.5:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
@ -3870,14 +3870,6 @@ mocha@^3.1.2:
mkdirp "0.5.1"
supports-color "3.1.2"
mock-knex@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/mock-knex/-/mock-knex-0.4.0.tgz#32c4ed97ff7cf9c86eca2400902f34e1f7f88de1"
dependencies:
bluebird "^3.4.1"
lodash "^4.14.2"
semver "^5.3.0"
moment-timezone@0.5.17:
version "0.5.17"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.17.tgz#3c8fef32051d84c3af174d91dc52977dcb0ad7e5"