New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix event listener duplication #2982
Changes from 3 commits
f9ab896
29e3196
e2f3a8f
83a52fc
e413805
a87c961
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -986,7 +986,7 @@ module.exports = function(knex) { | |
}); | ||
}); | ||
|
||
it('Event: does not duplicate listeners on a copy with user params', function() { | ||
it('Event: preserves listeners on a copy with user params', function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably users are going to be confused if listeners set on original knex suddenly disappear when we copy it with user params, so this is an improvement. |
||
let queryCount = 0; | ||
|
||
const onQueryResponse = function(response, obj, builder) { | ||
|
@@ -1012,7 +1012,7 @@ module.exports = function(knex) { | |
}) | ||
.then(function() { | ||
expect(Object.keys(knex._events).length).to.equal(1); | ||
expect(Object.keys(knexCopy._events).length).to.equal(0); | ||
expect(Object.keys(knexCopy._events).length).to.equal(1); | ||
knex.removeListener('query-response', onQueryResponse); | ||
expect(Object.keys(knex._events).length).to.equal(0); | ||
expect(queryCount).to.equal(4); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const knex = require('../../../knex'); | ||
const config = require('../../knexfile'); | ||
|
||
/* | ||
Please do not remove this file even though it is not referenced anywhere. | ||
This helper is meant for local debugging of specific tests. | ||
*/ | ||
|
||
function getSqliteKnex() { | ||
return knex(config.sqlite3); | ||
} | ||
|
||
module.exports = { | ||
getSqliteKnex, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,10 +98,68 @@ describe('knex', () => { | |
const knexWithParams = knex.withUserParams({ userParam: '451' }); | ||
|
||
expect(knexWithParams.migrate.knex.userParams).to.deep.equal({ | ||
isProcessingDisabled: true, | ||
postProcessResponse: undefined, | ||
userParam: '451', | ||
wrapIdentifier: undefined, | ||
}); | ||
}); | ||
|
||
it('copying does not result in duplicate listeners', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. kind of duplicate with test "adding listener to copy does not affect base knex" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are different, actually. One tests for what happens after you copy, another one what happens after you mutate the copy. |
||
const knex = Knex({ | ||
client: 'sqlite', | ||
}); | ||
const knexWithParams = knex.withUserParams(); | ||
|
||
expect(knex.client.listeners('start').length).to.equal(1); | ||
expect(knex.client.listeners('query').length).to.equal(1); | ||
expect(knex.client.listeners('query-error').length).to.equal(1); | ||
expect(knex.client.listeners('query-response').length).to.equal(1); | ||
|
||
expect(knexWithParams.client.listeners('start').length).to.equal(1); | ||
expect(knexWithParams.client.listeners('query').length).to.equal(1); | ||
expect(knexWithParams.client.listeners('query-error').length).to.equal(1); | ||
expect(knexWithParams.client.listeners('query-response').length).to.equal( | ||
1 | ||
); | ||
}); | ||
|
||
it('listeners added to knex directly get copied correctly', () => { | ||
const knex = Knex({ | ||
client: 'sqlite', | ||
}); | ||
const onQueryResponse = function(response, obj, builder) {}; | ||
expect(knex.listeners('query-response').length).to.equal(0); | ||
knex.on('query-response', onQueryResponse); | ||
|
||
const knexWithParams = knex.withUserParams(); | ||
|
||
expect(knex.listeners('query-response').length).to.equal(1); | ||
expect(knexWithParams.listeners('query-response').length).to.equal(1); | ||
}); | ||
|
||
it('adding listener to copy does not affect base knex', () => { | ||
const knex = Knex({ | ||
client: 'sqlite', | ||
}); | ||
|
||
expect(knex.client.listeners('start').length).to.equal(1); | ||
expect(knex.client.listeners('query').length).to.equal(1); | ||
expect(knex.client.listeners('query-error').length).to.equal(1); | ||
expect(knex.client.listeners('query-response').length).to.equal(1); | ||
|
||
const knexWithParams = knex.withUserParams(); | ||
knexWithParams.client.on('query', (obj) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm starting to have second thoughts if this was a good idea to allow creating modifiable clones of knex instance which are sharing the same pool (feature came kind of accidentally). I think it is a really nice feature to have, but API could have separated cloning and setting same pools for them and setting user parameters of each instance more clearly... anyways test looks good 👍 Wanted to just mention how this small feature of user parameters has exploded a bit for allowing to set custom event handlers too, which is good. |
||
knexWithParams.emit('query', obj); | ||
}); | ||
|
||
expect(knex.client.listeners('start').length).to.equal(1); | ||
expect(knex.client.listeners('query').length).to.equal(1); | ||
expect(knex.client.listeners('query-error').length).to.equal(1); | ||
expect(knex.client.listeners('query-response').length).to.equal(1); | ||
expect(knexWithParams.client.listeners('query').length).to.equal(2); | ||
}); | ||
|
||
it('sets correct postProcessResponse for builders instantiated from clone', () => { | ||
const knex = Knex({ | ||
client: 'sqlite', | ||
|
@@ -171,8 +229,10 @@ describe('knex', () => { | |
}); | ||
|
||
it('throws if client module has not been installed', () => { | ||
expect(Knex({ client: 'oracle' })).to.throw( | ||
/Knex: run\n$ npm install oracle/ | ||
expect(() => { | ||
Knex({ client: 'oracledb', connection: {} }); | ||
}).to.throw( | ||
"Knex: run\n$ npm install oracledb --save\nCannot find module 'oracledb'" | ||
); | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one looks like it got broken quite a while ago, I'll open a separate issue for it