Support for iterable children was recently released https://github.com/airbnb/enzyme/pull/1187. It enables to write Enzyme tests for components that return array-like children, for example ES6 Map and Set, and Immutable List.
We run our unit tests on PhantomJS, and iterable children support was not working for us. But works just fine on latest version of Chrome.
After some discussion with @ljharb in the comments of https://github.com/airbnb/enzyme/pull/1187, I found that the problem is that the iterable support that was implemented for Enzyme relies on the ES6 Symbol API. A polyfill for Symbol makes sense to make it work on our environment, but there are a few reasons why I think a fallback should be added as part of Enzyme instead.
@@iterator when Symbol API is not available since v 13. Here is a fiddle that shows iterable children support on React 13 https://jsfiddle.net/inucoder/n11gvjgz/ and the source code using @@iterator can be found here https://github.com/facebook/react/blob/v0.13.0/src/utils/getIteratorFn.jsThe purposed fix is as follows. In https://github.com/airbnb/enzyme/blob/master/packages/enzyme-adapter-utils/src/Utils.js from enzyme-adapter-utils, we could change the code for isIterable function from
function isIterable(obj) {
return (
obj != null &&
typeof Symbol === 'function' &&
typeof Symbol.iterator === 'symbol' &&
typeof obj[Symbol.iterator] === 'function'
);
}
to
function isIterable(obj) {
return (
obj != null && (
(
typeof Symbol === 'function' &&
typeof Symbol.iterator === 'symbol' &&
typeof obj[Symbol.iterator] === 'function'
) ||
obj['@@iterator']
)
);
}
If you guys think it makes sense to include such change, I'm open to submit a PR during this week (our team is looking forward to bump to v3). Thanks so much and keep the great work!
After testing above change, I can make below unit test pass when Symbol API is unavailable.
'use strict';
import Enzyme from 'enzyme';
import Immutable from 'immutable';
import Adapter from 'enzyme-adapter-react-15';
import {isArrayLike} from 'enzyme-adapter-utils';
Enzyme.configure({adapter: new Adapter()});
describe('Enzyme 3', () => {
it('should play nice with Immutable.List children', () => {
const children = Immutable.fromJS([1, 2, 3]);
expect(isArrayLike(children))
.toBe(true);
});
});
The real bug is that Immutable should never have installed a @@iterator property in the first place; it was non-standard, and Firefox shouldn't have shipped it either.
However, since React 13+ supports it, we unfortunately have to as well.
@ljharb You could assign it to me if possible, and will submit a PR for it during these days.
I am also experiencing this exact problem; it's good to see there's already a fix ready to be shipped. Any idea when this is going to land in master?
Hi @ljharb, any chance this one can get a couple more reviews and be released soon? Would really appreciate it. And glad that will help others like @anthonyhastings as well!
Fixed in #1334.
Most helpful comment
@ljharb You could assign it to me if possible, and will submit a PR for it during these days.