astorije / chai-immutable Goto Github PK
View Code? Open in Web Editor NEWChai assertions for Facebook's Immutable library for JavaScript collections
License: MIT License
Chai assertions for Facebook's Immutable library for JavaScript collections
License: MIT License
At the moment, only successful cases are tested (to detect false negatives, cases that fail although they should pass). This prevents us to detect false positives (cases that pass although they should fail).
Failing tests should be added, similarly to Chai's tests, see example here.
I already suspect one bug that can be proven with this, there might be more.
Spent some time on this tonight, not sure how to do that.
Is it possible to setup Sauce Labs so that tests are run in different browsers?
Right now they are just run in phantomjs, it would be nice to know if they pass on all browsers or not.
Any help on that will be appreciated.
Chai v4 adds .deep.include
and this plugin should do too for Immutable structures.
See chaijs/chai#761.
Given the following assertion:
expect(fromJS({ x: 1})).to.not.have.key('y');
I get the following result:
AssertionError: expected 'Map { "x": 1 }' to have key 'y'
So it seems that the not
statement in the assertion is ignored.
I am using:
mocha 2.4.5
chai 3.5.0
chai-immutable: 1.5.4
Upstream Chai project has added a Code of Conduct (chaijs/chai#565) so it would be a good idea to add it here as well.
Easy to do if someone wants to give it a shot.
To appear on the plugin page, a new entry needs to be added to chai-doc's JSON index.
Consider this assertion:
assert.equal(Immutable.Set([Immutable.Map({ id: "one", propName: "subref" })]),
Immutable.Set([1, 2]));
This fails with this ugly error:
AssertionError: expected { Object (size, _map, ...) } to equal Set { 1, 2 }
I debugged why I sometimes got this kind of error. It's because the length of the string representation of the actual value exceeds Chai's truncate threshold. Chai then proceeds to fall back to another method and displays the object in a truncated fashion.
I don't think it looks like Chai's objDisplay function can be easily taught about truncating Immutable.js's values. So I think it would be best to detect whether what we pass into actual (or expected) is an Immutable object, and if so, pass in the string instead of the object itself. It should then pass through without harm.
In vanilla Chai, you can assert that a JS object includes all properties (and values) of another obj
i.e.
expect({a: 1, b: 2, c: 3}).to.include({b: 2, c: 3});
Would it be possible to add a similar feature to chai-immutable for comparing Maps?
Potentially isSuperset
could be used(?), or perhaps each key/value pair would need to be compared individually.
Vanilla chai behaviour, for reference: https://jsbin.com/cihiteyoyu/2/edit?html,js,output
This would be port of chaijs/chai#668 applied to Immutable objects.
See original discussion here:
glenjamin/transit-immutable-js#13 (comment)
Notable points:
var FooRecord = Immutable.Record({ a: 1, b: 2 }, 'foo');
// This assertion passes
expect(new FooRecord()).to.eql(new Immutable.Map({a: 1, b: 2}));
// Because this is true
Immutable.is(new FooRecord(), new Immutable.Map({a: 1, b: 2}));
And this is currently by design: https://twitter.com/glenathan/status/688050710047539200
I think it'd be useful to provide a way to opt into a stricter comparison in chai-immutable
. I'm unsure whether or not I think it should be the default at this point.
One suggested approach is to say that immutable object should be both equal, and stringly equal - as records include their names in the string output. This doesn't handle records with the same name though - so perhaps it would need something more complicated.
/cc @corbt
A long, long time ago, I listed a few things to look at to be ready for Chai v4 here: #69 (comment)
Need to wrap these.
The following test fails (see this build):
var list3 = List.of(1, 2, 3);
var deepMap = new Map({ foo: 'bar', list: List.of(1, 2, 3) });
var sameDeepMap = new Map({ foo: 'bar', list: List.of(1, 2, 3) });
it('should fail given equal values', function () {
assert.throws(function () { assert.notEqual(list3, List.of(1, 2, 3)); }, Error);
});
it('should fail given deeply equal values', function () {
assert.throws(function () { assert.notEqual(deepMap, sameDeepMap); }, Error);
});
This shows that assert.notEqual
needs to be overriden to take into account equality between values even though the underlying objects are different.
Given a couple of immutable lists with identical items in some instances I've had problems when deep comparing them in my tests using the chai-immutable plugin.
expect(Immutable.is(listOne, listTwo)).to.equal(true); // works ok
expect(listOne).is.eql(listTwo); // fails
Not sure if the code should go for ES6 yet, but we could at least start with examples from the documentation. If so, then maybe the test suite should be moved to ES6 to reflect the documentation too.
Get following error when attempting to install chai-immutable:
> npm install chai-immutable
npm ERR! fetch failed https://registry.npmjs.org/chai-immutable/-/chai-immutable-1.0.0.tgz
npm WARN retry will retry, error on last attempt: Error: fetch failed with status code 404
Seems like https://registry.npmjs.org/chai-immutable/-/chai-immutable-1.0.0.tgz does not exist.
npm install [email protected] works correctly
As soon as this plugin uses Chai v4, .deep.property
will have a different meaning there, and this plugin should port it for Immutable objects.
This will need new tests as well.
See chaijs/chai#758 and #69 fore more info.
The following test fails (see this build):
var map = new Map({ x: 1, y: 2 });
var obj = { x: 1, y: 2 };
it('should fail using `not` given an inexisting key', function () {
expect(function () { expect(map).to.not.have.key('x'); }).to.throw(Error);
expect(function () { expect(obj).to.not.have.key('x'); }).to.throw(Error);
});
@astorije could you please publish a new version of this lib to npm?
I am upgrading my package dependencies, including chai-immutable to 1.6.0, and I am getting this error upon running my code:
Error: Cannot find module 'immutable'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Assertion (/Users/elliott/Documents/GitHub/onestop/client/node_modules/chai-immutable/chai-immutable.js:8:30)
at Object.<anonymous> (/Users/elliott/Documents/GitHub/onestop/client/node_modules/chai-immutable/chai-immutable.js:18:2)
As far as I can tell, chai-immutable handles 'immutable' as a dependency in it's own package.json. So why is it barfing here, suddenly?
I have done a rm -rf
on my node_modules directory and reinstalled via npm -i
before running, for the record.
Although JSCS now appears as out-of-date for this repo (a new major version was released), it is end of life. Their maintainers are merging with the ESLint team and somewhat suggest projects to do the same.
I was initially planning to support it, but removed support completely in 46ea795 as it is clear it will not work as is.
I have no idea how AMD loaders nor RequireJS work as I'm not using them myself, so I'd be glad if someone can step in and provide a fix.
Probably not a lot to do, but not something I am intending to focus on myself, at least in the near future.
Hi,
First of all, it appears (and it makes sense) that key order in an immutable Map with primitive fields does not matter, as illustrated by the following test:
it('Key order for Maps with primitive fields does not matter', ()=>{
const simpleMap = Map({
loaded: false,
working: true
});
expect(simpleMap).to.equal(Map({ // key order different
working: true,
loaded: false
}));
})
However, if an immutable Map contains one or more key with plain object in it will cause equality to fail if the order of keys is different, as illustrated in the following test (notice I use to.eql
, not to.equal
):
it('Map field data order matters!!', ()=>{
const map = Map({
loaded: false,
working: true,
message: {first_name: 'john', last_name: 'due'}
});
expect(map).to.eql(Map({ // key order the same
loaded: false,
working: true,
message: {first_name: 'john', last_name: 'due'}
}));
expect(map).to.eql(Map({ // key order different
working: true,
loaded: false,
message: {first_name: 'john', last_name: 'due'}
}));
})
The second expect
fails.
Is that an intended behavior or a bug in chai-immutable?
Thanks,
Alex
PS. I am using chai-immutable v. 1.3.0.
I tried to use this plugin but was confused why it didn't work for "assert.equal". It turns out you need to install a bridging function on the "assert" object, see this mailing list entry:
https://groups.google.com/forum/#!topic/chaijs/Dwnbsbe0C70
I tried the following:
assert.equal = function(act, exp, msg) {
new chai.Assertion(act, msg).to.equal(exp);
};
and now it works. The same should be done with the other overrides.
Maintenance of v0.12 stops in 31 December 2016, and maintenance of v0.10 has already stopped. Additionally, Chai v4 will drop these as well.
This will allow for lots of ES6 features, such as arrow functions at the very least.
This is a backward-incompatible change though, so this will be a major version bump.
Meaning of .not.property
changes between Chai v3 and v4 (see chaijs/chai#744) and as pointed out by #69, currently tests aren't breaking for any version.
There needs to be tests proving .not.property
works properly on v3 and breaks on v4, so the v4 transition can be done smoothly.
(This is not a chai v4
issue because it does not require Chai v4, it's the other way around.)
Not sure how the new site will or will not leverage this, but chai-immutable
should reproduce chaijs/chai#552 for consistency.
It is a very easy thing to add if someone wants to get some GitHub contribution, otherwise I'll do that within the next few weeks when I have a bit of time to spend on chai-immutable
.
I have never used browserify so I am not sure if chai-immutable is compatible with it out of the box or if any additional work is needed.
That'd be great if someone can test this and give a report here.
First of, is this a desired feature?
@ulrikhindoe started working on this at #85 but it never got in simply because I wasn't responsive enough.
If anyone wants to help with this, I'll be more careful :)
There are several commits which are not published to NPM.
One really important to me is 7c8697f
Can you please publish them?
Thank you.
I have some promises returning collections from immutable.js.
It'd be nice to expect the promised values with chai-as-promised.
Something like:
expect(Promise.resolve(immutable.List())).to.eventually.be.empty
Hello. Apologies if this has been addressed or if I've done something foolish, but I'm pretty sure this is legitimately unexpected behavior.
I'm using Immutable 3.7.5, Chai 3.4.1 and chai-immutable 1.5.3 with Node 4.2.2 on Windoze. Here's what I'm seeing:
describe('A List', () => {
function addListItem(currentState,item) {
// Push item onto currentState and return the new state
return currentState.push(item);
}
it('is immutable', () => {
let state = List.of('Bar','Foo');
let nextState = addListItem(state, 'Baz');
expect(nextState).to.equal(List.of(
'Bar',
'Foo',
'Baz'
));
});
});
I expect this test to pass, however:
AssertionError: expected List [ "Bar", "Foo", "Baz" ] to equal List [ "Bar", "Foo", "Baz" ]
+ expected - actual
{
- "__altered": true
+ "__altered": false
"__hash": [undefined]
"__ownerID": [undefined]
"_capacity": 3
"_level": 5
"Bar"
"Foo"
"Baz"
]
- "ownerID": {}
+ "ownerID": [undefined]
}
"size": 3
}
These internal implementation properties "ownerID" and "__altered" are resulting in a failed assertion that I believe should pass.
Hi there, I'm working on unit tests for a Redux application and I'm trying to compare two so called "actions" which are objects that looks something like this:
action = {
type: 'myType',
list: myImmutableList
}
expectedAction = {
type: 'myType',
list: anIdenticalList
}
This happens:
console.log(action.type === expectedAction.type); // true
console.log(action.list.equals(expectedAction.list)); // true
expect(action.list).to.equal(expectedAction.list); // works
expect(action).to.equal(expectedAction); // throws AssertionError, as it should
// BUT
expect(action).to.deep.equal(expectedAction); // throws AssertionError, this is unexpected
I'm new to Immutable but so I'm not sure, but this looks like a bug to me? Thanks
Chai's dot-notation for property
lets us do the following for Array
and Object
elements:
expect([1, 2, 3]).to.have.deep.property('[2]', 3);
Without more custom assertions for Immutable
, I don't think we have an alternative to:
expect(List.of(1, 2, 3).get(2)).to.equal(3);
which causes a problem when using something like Chai as Promised because we end up with something not as straightforward as with Array
elements.
// Assuming p promises us [1, 2, 3]
return expect(p).to.eventually.have.deep.property('[2]', 3);
// Assuming p promises us List.of(1, 2, 3)
return p.then(function (list) { return expect(list.get(2)).to.equal(3); });
A suitable solution would be an assertion that lets us do:
expect(List.of(1, 2, 3)).to.whatever(2, 3);
where its signature is whatever(key, value)
. This lets us use eventually
:
// Assuming p promises us List.of(1, 2, 3)
return expect(p).to.eventually.whatever(2, 3);
An even better solution, IMO, would be:
expect(List.of(1, 2, 3)).to.whatever(2).equal(3);
so that we could have things like:
expect(List.of('abc', 'def', 'ghi')).to.whatever(2).contain('bc');
expect(List.of(1, 2, 3)).to.whatever(2).above(0);
Which idea seems best?
Any reasons why these would be bad ideas? If so, any better ideas?
I found myself in the need to test if an object was frozen.
Right now, one has to do:
expect(Object.isFrozen(obj)).to.be.true;
which is not very pretty. I came up with a simple helper to allow the following syntax:
expect(obj).to.be.frozen;
I am not sure if this helper should be part of this project. On one end, it's not using Immutable, but on the other end, Object#freeze()
is the closest we have to immutable objects in JS...
So, should I include it here? Any other suggestion?
dot-and-bracket notation can be used for Array
and Object
elements.
A similar thing should be possible with Immutable
collections.
var deepMap = new Map({
green: new Map({ tea: 'matcha' }),
teas: List.of('chai', 'matcha', new Map({ tea: 'konacha' }))
});
expect(deepObj).to.have.deep.property('green.tea', 'matcha');
expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
expect(deepObj).to.have.deep.property('teas.[2].tea', 'konacha');
Specific syntax to define (I may prefer to use obj.get(prop)
instead of obj.prop
to reflect the library's API).
According to this comment by @matthewwithanm, it's not possible to leave comments like:
// Lorem ipsum dolor sit amet
// consectetur adipiscing elit
But only:
/*
* Lorem ipsum dolor sit amet
* consectetur adipiscing elit
*/
Which is quite painful! I think I went a bit too far on comment conventions and I need to relax them a bit...
my bad dude, didn't mean to create this
It is currently possible to give an Array
of keys and an Object
of keys to the keys
assertion, but considering the library we are testing against, it would be a shame to not be able to use List
and Map
elements.
Should I allow other input types too (Set
, ...) ? Should I be more generic instead (like testing against KeyedCollection
instead of Map
, ...)?
Is there support for [email protected]?
$ npm install --save-dev chai-immutable
[email protected] /Library/WebServer/Documents/www.mike-austin.com/models
├── UNMET PEER DEPENDENCY [email protected]
└── [email protected]
npm WARN [email protected] requires a peer of chai@>= 2.0.0 < 4 but none was installed.
To have something like original does
expect(Map({'a': 'value'})).to.have.property('a', 'value');
but for immutable objects
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.