-
-
Notifications
You must be signed in to change notification settings - Fork 693
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
addMethod returns a new assertion with flags copied over instead of this #642
Changes from all commits
1028fd2
67a3ca5
8f8f186
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 |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
var config = require('../config'); | ||
var flag = require('./flag'); | ||
var transferFlags = require('./transferFlags'); | ||
|
||
/** | ||
* ### addProperty (ctx, name, getter) | ||
|
@@ -34,14 +35,19 @@ var flag = require('./flag'); | |
*/ | ||
|
||
module.exports = function (ctx, name, getter) { | ||
getter = getter === undefined ? new Function() : getter; | ||
|
||
Object.defineProperty(ctx, name, | ||
{ get: function addProperty() { | ||
var old_ssfi = flag(this, 'ssfi'); | ||
if (old_ssfi && config.includeStack === false) | ||
flag(this, 'ssfi', addProperty); | ||
|
||
var result = getter.call(this); | ||
return result === undefined ? this : result; | ||
var newAssertion = new chai.Assertion(); | ||
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. same here: |
||
transferFlags(this, newAssertion); | ||
|
||
return result === undefined ? newAssertion: result; | ||
} | ||
, configurable: true | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -232,6 +232,46 @@ describe('utilities', function () { | |
expect(expect('foo').result()).to.equal('result'); | ||
}); | ||
|
||
it('addMethod returns new assertion with flags copied over', function () { | ||
var assertionConstructor; | ||
|
||
chai.use(function(_chai, utils) { | ||
assertionConstructor = _chai.Assertion; | ||
_chai.Assertion.addMethod('returnNewAssertion', function () { | ||
utils.flag(this, 'mySpecificFlag', 'value1'); | ||
utils.flag(this, 'ultraSpecificFlag', 'value2'); | ||
}); | ||
|
||
_chai.Assertion.addMethod('checkFlags', function() { | ||
this.assert( | ||
utils.flag(this, 'mySpecificFlag') === 'value1' && | ||
utils.flag(this, 'ultraSpecificFlag') === 'value2' | ||
, 'expected assertion to have specific flags' | ||
, "this doesn't matter" | ||
); | ||
}); | ||
}); | ||
|
||
assertion1 = expect('foo'); | ||
assertion2 = assertion1.to.returnNewAssertion(); | ||
|
||
// Checking if a new assertion was returned | ||
expect(assertion1).to.not.be.equal(assertion2); | ||
|
||
// Check if flags were copied | ||
assertion2.checkFlags(); | ||
|
||
// Checking if it's really an instance of an Assertion | ||
expect(assertion2).to.be.instanceOf(assertionConstructor); | ||
|
||
// Test chaining `.length` after a method to guarantee it is not a function's `length` | ||
var anAssertion = expect([1, 2, 3]).to.be.an.instanceof(Array); | ||
expect(anAssertion.length).to.be.an.instanceof(assertionConstructor); | ||
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. Could you please add some assertions that feature the expect([1, 2, 3]).to.be.an.instanceOf(Array).and.to.have.length.below(1000) 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. Well thought @keithamus. expect(my_object).to.have.a.deep.property("foo.bar").that.is.an("array").with.a.length.of.at.least(1); The reason is the same you explained on the issue, we are getting back an I'll take a further look at this to find the exact reason. Thanks again for your feedback, it was really useful 😃 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. Hey @lucasfcosta thanks for doing that, and also awesome work adding some more tests and discovering another issue 😄 It looks like in that case, the > chai.expect({foo: [1,2,3]}).to
Assertion {
__flags:
{ ssfi: [Function: addProperty],
object: { foo: [Object] },
message: undefined } }
> chai.expect({foo: [1,2,3]}).to.have
Assertion {
__flags:
{ ssfi: [Function: addProperty],
object: { foo: [Object] },
message: undefined } }
> chai.expect({foo: [1,2,3]}).to.have.a
[Function: assert]
> chai.expect({foo: [1,2,3]}).to.have.a.deep
[Function: assert] Luckily, it looks like the fix will be pretty much the same thing. L44 of addProperty has the same ternary. 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. EDIT: Please ignore this comment and just read this. Ah, that makes sense. I was also doing some research on this too, shouldn't we create another assertion and transfer flags to it instead of returning I'm not sure this is needed, I will do some further experiments with this, but it may be good to prevent further errors related to this. |
||
|
||
var anotherAssertion = expect([1, 2, 3]).to.have.a.lengthOf(3).and.to.be.ok; | ||
expect(anotherAssertion.length).to.be.an.instanceof(assertionConstructor); | ||
}); | ||
|
||
it('overwriteMethod', function () { | ||
chai.use(function (_chai, _) { | ||
expect(_chai.Assertion).to.respondTo('eqqqual'); | ||
|
@@ -291,6 +331,49 @@ describe('utilities', function () { | |
expect(assert.__flags.tea).to.equal('chai'); | ||
}); | ||
|
||
it('addProperty returns a new assertion with flags copied over', function () { | ||
var assertionConstructor = chai.Assertion; | ||
|
||
chai.use(function(_chai, utils) { | ||
assertionConstructor = _chai.Assertion; | ||
_chai.Assertion.addProperty('thing', function () { | ||
utils.flag(this, 'mySpecificFlag', 'value1'); | ||
utils.flag(this, 'ultraSpecificFlag', 'value2'); | ||
}); | ||
|
||
_chai.Assertion.addMethod('checkFlags', function() { | ||
this.assert( | ||
utils.flag(this, 'mySpecificFlag') === 'value1' && | ||
utils.flag(this, 'ultraSpecificFlag') === 'value2' | ||
, 'expected assertion to have specific flags' | ||
, "this doesn't matter" | ||
); | ||
}); | ||
}); | ||
|
||
assertion1 = expect('foo'); | ||
assertion2 = assertion1.is.thing; | ||
|
||
// Checking if a new assertion was returned | ||
expect(assertion1).to.not.be.equal(assertion2); | ||
|
||
// Check if flags were copied | ||
assertion2.checkFlags(); | ||
|
||
// If it is, calling length on it should return an assertion, not a function | ||
expect([1, 2, 3]).to.be.an.instanceof(Array); | ||
|
||
// Checking if it's really an instance of an Assertion | ||
expect(assertion2).to.be.instanceOf(assertionConstructor); | ||
|
||
// Test chaining `.length` after a property to guarantee it is not a function's `length` | ||
expect([1, 2, 3]).to.be.a.thing.with.length.above(2); | ||
expect([1, 2, 3]).to.be.an.instanceOf(Array).and.have.length.below(4); | ||
|
||
expect(expect([1, 2, 3]).be).to.be.an.instanceOf(assertionConstructor); | ||
expect(expect([1, 2, 3]).thing).to.be.an.instanceOf(assertionConstructor); | ||
}); | ||
|
||
it('addProperty returning result', function () { | ||
chai.use(function(_chai, _) { | ||
_chai.Assertion.addProperty('result', function () { | ||
|
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.
I'm getting
ReferenceError: chai is not defined
thrown hereThere 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.
I guess this problem has been shadowed by
global.chai = require('../..');
in all tests...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.
Good catch, thanks @Turbo87. Fancy making a PR for this?
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.
Awesome, I see you already have 🎉 👍