forked from knex/knex
-
Notifications
You must be signed in to change notification settings - Fork 1
/
logger.js
148 lines (137 loc) · 4.22 KB
/
logger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
'use strict';
const { expect } = require('chai');
const _ = require('lodash');
const { DRIVER_NAMES } = require('../../lib/constants');
const { isObject } = require('../../lib/util/is');
const { TEST_TIMESTAMP, TEST_ID } = require('../util/constants');
module.exports = function (knex) {
const client = knex.client;
// allowed driver name of a client
const allowedClients = Object.values(DRIVER_NAMES);
function compareBindings(gotBindings, wantedBindings) {
if (Array.isArray(wantedBindings)) {
wantedBindings.forEach(function (wantedBinding, index) {
if (typeof wantedBinding === 'function') {
expect(
wantedBinding(gotBindings[index]),
'binding cheker function failed got: ' + gotBindings
).to.equal(true);
} else {
expect(gotBindings[index]).to.eql(wantedBinding);
}
});
expect(
gotBindings.length,
"length doesn't match got: " + gotBindings
).to.equal(wantedBindings.length);
} else {
expect(gotBindings).to.eql(wantedBindings);
}
}
// Useful in cases where we want to just test the sql for both PG and SQLite3
function testSqlTester(qb, driverName, statement, bindings, returnval) {
if (Array.isArray(driverName)) {
driverName.forEach(function (val) {
testSqlTester(qb, val, statement, bindings, returnval);
});
} else if (client.driverName === driverName) {
const sql = qb.toSQL();
if (statement) {
if (Array.isArray(sql)) {
expect(_.map(sql, 'sql')).to.eql(statement);
} else {
expect(sql.sql).to.equal(statement);
}
}
if (bindings) {
if (Array.isArray(sql)) {
compareBindings(_.map(sql, 'bindings'), bindings);
} else {
compareBindings(sql.bindings, bindings);
}
}
if (returnval !== undefined && returnval !== null) {
const oldThen = qb.then;
qb.then = function () {
let promise = oldThen.apply(this, []);
promise = promise.then(function (resp) {
if (typeof returnval === 'function') {
expect(!!returnval(resp)).to.equal(true);
} else {
try {
expect(stripDates(resp)).to.eql(returnval);
} catch (err) {
console.log('Actual:');
console.log(JSON.stringify(resp));
console.log('Expected:');
console.log(JSON.stringify(returnval));
throw err;
}
}
return resp;
});
return promise.then.apply(promise, arguments);
};
}
} else {
if (!allowedClients.includes(driverName)) {
throw new Error(
'Invalid client name: ' +
driverName +
' Should be one of: ' +
allowedClients.join(',')
);
}
}
}
function stripDates(resp) {
if (!isObject(resp[0])) return resp;
return _.map(resp, function (val) {
return _.reduce(
val,
function (memo, val, key) {
if (
_.includes(
['created_at', 'updated_at', 'createdAt', 'updatedAt'],
key
)
) {
memo[key] = TEST_TIMESTAMP;
} else if (_.includes(['dummy_id'], key)) {
memo[key] = TEST_ID;
} else {
memo[key] = val;
}
return memo;
},
{}
);
});
}
function makeTestSQL(builder) {
const tester = testSqlTester.bind(null, builder);
return function (handler) {
handler(tester);
return this;
};
}
const originalRaw = client.raw;
const originalQueryBuilder = client.queryBuilder;
const originalSchemaBuilder = client.schemaBuilder;
client.raw = function () {
const raw = originalRaw.apply(this, arguments);
raw.testSql = makeTestSQL(raw);
return raw;
};
client.queryBuilder = function () {
const qb = originalQueryBuilder.apply(this, arguments);
qb.testSql = makeTestSQL(qb);
return qb;
};
client.schemaBuilder = function () {
const sb = originalSchemaBuilder.apply(this, arguments);
sb.testSql = makeTestSQL(sb);
return sb;
};
return knex;
};