Skip to content

Commit 5d71c91

Browse files
authored
Feature: Add support for ES.next Set, Map, ArrayBuffer (#51)
- Update library to include ES.next support for `Map`, `Set`, `ArrayBuffer`. Part of #36 - Update to `fast-deep-equal@3.1.1` with modified support for ES.next data types. - Upgrade lots of `devDependenices` - Use `fast-deep-equal` tests directly in our correctness tests. - Update CI to modern Node.js versions. - **Note**: There's a bug / limitation of `Set` comparisons whereby objects are compared by reference not value. Tracked at #50 . In our `yarn benchmark`, `lodash.isEqual` gets test differences because it correctly handles those.
1 parent 65c3eb7 commit 5d71c91

17 files changed

Lines changed: 3491 additions & 4206 deletions

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ dist: trusty
33
language: node_js
44

55
node_js:
6-
- "6"
76
- "8"
8-
- "9"
7+
- "10"
8+
- "12"
9+
- "13"
910

1011
branches:
1112
only:

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## UNRELEASED
4+
5+
**Features:**
6+
- Update library to include ES.next support for `Map`, `Set`, `ArrayBuffer`. [#36](https://github.com/FormidableLabs/react-fast-compare/pull/36).
7+
8+
**Breaking changes:**
9+
- Update to `fast-deep-equal@3.1.1` with modified support for ES.next data types.
10+
11+
**Infrastructure:**
12+
- Upgrade lots of `devDependenices`
13+
- Use `fast-deep-equal` tests directly in our correctness tests.
14+
- Update CI to modern Node.js versions.
15+
- Update Appveyor to use straight IE11 (not emulated IE9) because mocha no longer runs in IE9.
16+
317
## 2.0.4 (2018-11-09)
418

519
- [#39](https://github.com/FormidableLabs/react-fast-compare/pull/39). Fix `react-native` bug introduced by DOM element checking.
@@ -11,7 +25,7 @@
1125
## 2.0.2 (2018-08-21)
1226

1327
- [#28](https://github.com/FormidableLabs/react-fast-compare/pull/28). Fix for localized versions of IE11. Thanks @excentrik!
14-
- [#34](https://github.com/FormidableLabs/react-fast-compare/pull/34). Fix typo. Thanks @Marviel!
28+
- [#34](https://github.com/FormidableLabs/react-fast-compare/pull/34). Fix typo. Thanks @Marviel!
1529

1630
## 2.0.1 (2018-06-25)
1731

CONTRIBUTING.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ This package is a fork of [fast-deep-equal](https://github.com/epoberezkin/fast-
1010
We encourage pull requests concerning:
1111

1212
* React features not handled in this library
13-
* Integrating updates from fast-deep-equal
14-
* Integrating tests from fast-deep-equal
13+
* Integrating updates from `fast-deep-equal`. This unfortunately, now requires more manual work to use the comment blocks in `index.js` to figure out what to paste and where.
14+
* Integrating tests from `fast-deep-equal`. This usually entails upgrading the `git`-based dependencies of `fast-deep-equal-git` and `npm`-published package of `fast-deep-equal` in `package.json:devDependencies`.
1515
* Bugs in this library
1616
* New tests for React
1717
* Documentation
@@ -65,7 +65,7 @@ $ yarn run test-node --watch
6565

6666
The same tests are then imported and built with `webpack` to a test bundle that
6767
can be run in arbitrary browsers. So far in CI, we execute the tests in headless
68-
Chrome on Linux in Travis and IE9-emulated IE11 in Appveyor.
68+
Chrome on Linux in Travis and IE11 in Appveyor.
6969

7070
To run the browser tests on your machine (note: you must already have the
7171
browser you're running installed):
@@ -76,7 +76,7 @@ $ yarn run test-browser
7676
# Example: real Chrome + Firefox + Safari
7777
$ yarn run test-browser --browsers Chrome,Firefox,Safari
7878

79-
# IE9 emulation (on Windows)
79+
# IE11 (on Windows)
8080
$ yarn run test-browser-ie
8181
```
8282

@@ -94,6 +94,21 @@ $ yarn run test-ts
9494
$ yarn run eslint
9595
```
9696

97+
### Size
98+
99+
You can check how we do with minification + compression with:
100+
101+
```sh
102+
# Show minified output
103+
$ yarn -s compress
104+
105+
# Display minified + gzip'ed size in bytes.
106+
$ yarn size-min-gz
107+
687
108+
```
109+
110+
**Note**: If the min+gz size increases, please note it in the README. If it is a significant increase, please flag to your reviewers and have a discussion about whether or not the size addition is justified.
111+
97112
## Before submitting a PR...
98113

99114
Before you go ahead and submit a PR, make sure that you have done the following:
@@ -103,9 +118,9 @@ $ yarn run test
103118
$ yarn run benchmark
104119
```
105120

106-
Everything must be correct / pass checks. You should also check the benchmark
107-
stats and make sure that we don't have any significant performance regressions
108-
(check out `master` for a baseline comparison on _your_ machine).
121+
1. Everything must be correct / pass checks.
122+
2. You should also check the benchmark stats and make sure that we don't have any significant performance regressions (check out `master` for a baseline comparison on _your_ machine).
123+
- Please **do** update the README benchmark numbers for changes in your PR so that we have much easier discussion points _and_ our users get up-to-date information.
109124

110125
## Releasing a new version to NPM
111126

README.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ $ npm install react-fast-compare
3232
* deeply compares any value (besides objects with circular references)
3333
* handles React-specific circular references, like elements
3434
* checks equality Date and RegExp objects
35-
* should be just as fast as [fast-deep-equal](https://github.com/epoberezkin/fast-deep-equal) for general use, and faster for React use
36-
* small: under 600 bytes minified+gzipped
35+
* should as fast as [fast-deep-equal](https://github.com/epoberezkin/fast-deep-equal) via a single unified library, and with added guardrails for circular references.
36+
* small: under 700 bytes minified+gzipped
3737

3838
## Usage
3939

@@ -86,11 +86,11 @@ simply because there are more tests in each operation.
8686
### Generic Data
8787

8888
```
89-
react-fast-compare x 207,503 ops/sec ±0.54% (92 runs sampled)
90-
fast-deep-equal x 195,006 ops/sec ±0.70% (91 runs sampled)
91-
lodash.isEqual x 43,778 ops/sec ±0.55% (91 runs sampled)
92-
nano-equal x 198,036 ops/sec ±0.37% (95 runs sampled)
93-
shallow-equal-fuzzy x 173,023 ops/sec ±0.59% (95 runs sampled)
89+
react-fast-compare x 157,863 ops/sec ±0.54% (94 runs sampled)
90+
fast-deep-equal x 149,877 ops/sec ±0.76% (93 runs sampled)
91+
lodash.isEqual x 33,298 ops/sec ±0.70% (93 runs sampled)
92+
nano-equal x 144,836 ops/sec ±0.51% (94 runs sampled)
93+
shallow-equal-fuzzy x 110,192 ops/sec ±0.57% (95 runs sampled)
9494
fastest: react-fast-compare
9595
```
9696

@@ -101,16 +101,14 @@ tests; any difference is just noise. `react-fast-compare` won't be faster than
101101
### React and Generic Data
102102

103103
```
104-
react-fast-compare x 187,628 ops/sec ±0.58% (93 runs sampled)
105-
fast-deep-equal x 477 ops/sec ±0.55% (91 runs sampled)
106-
lodash.isEqual x 35,100 ops/sec ±0.16% (95 runs sampled)
107-
nano-equal x 468 ops/sec ±0.53% (94 runs sampled)
108-
shallow-equal-fuzzy x 684 ops/sec ±0.43% (92 runs sampled)
109-
fastest: react-fast-compare
104+
react-fast-compare x 64,102 ops/sec ±0.36% (94 runs sampled)
105+
fast-deep-equal x 63,844 ops/sec ±0.43% (94 runs sampled)
106+
lodash.isEqual x 6,243 ops/sec ±0.72% (90 runs sampled)
107+
fastest: react-fast-compare,fast-deep-equal
110108
```
111109

112-
Three of these packages cannot handle comparing React elements (which are
113-
circular): `fast-deep-equal`, `nano-equal`, and `shallow-equal-fuzzy`.
110+
Two of these packages cannot handle comparing React elements (which are
111+
circular): `nano-equal` and `shallow-equal-fuzzy`.
114112

115113
### Running Benchmarks
116114

@@ -121,7 +119,12 @@ $ yarn run benchmark
121119

122120
## fast-deep-equal Versioning
123121

124-
react-fast-compare@2 tracks fast-deep-equal@2.0.1
122+
react-fast-compare@3 tracks fast-deep-equal@3.1.1
123+
124+
Now that `fast-deep-equal` has separate es5, es6, and es6 + React entry points, the main differences with this library are:
125+
126+
* `try/catch` guardrails for stack overflows from undetected circular references.
127+
* A single unified entry point for **all** uses. No matter what your target application is, `import equal fro 'react-fast-compare'` just works.
125128

126129
## License
127130

@@ -133,7 +136,7 @@ Please see our [contributions guide](./CONTRIBUTING.md).
133136

134137
## Maintenance Status
135138

136-
**Active:** Formidable is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.
139+
**Active:** Formidable is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.
137140

138141
[trav_img]: https://api.travis-ci.com/FormidableLabs/react-fast-compare.svg
139142
[trav_site]: https://travis-ci.com/FormidableLabs/react-fast-compare

appveyor.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Test against this version of Node.js
22
environment:
33
matrix:
4-
- nodejs_version: "6"
54
- nodejs_version: "8"
65
- nodejs_version: "10"
6+
- nodejs_version: "12"
7+
- nodejs_version: "13"
78

89
# Install scripts. (runs after repo cloning)
910
install:

benchmark/index.js

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@ const Benchmark = require('benchmark');
55

66
const correctnessTests = [];
77
const genericSuite = new Benchmark.Suite;
8-
const allSuite = new Benchmark.Suite;
8+
const advancedSuite = new Benchmark.Suite;
99

1010
const equalPackages = {
1111
'react-fast-compare': require('../index'),
12-
'fast-deep-equal': require('fast-deep-equal'),
12+
'fast-deep-equal': require('fast-deep-equal/es6/react'),
1313
'lodash.isEqual': require('lodash').isEqual,
1414
'nano-equal': require('nano-equal'),
1515
'shallow-equal-fuzzy': require('shallow-equal-fuzzy')
1616
};
1717

18+
const advancedPkgs = new Set([
19+
'react-fast-compare',
20+
'fast-deep-equal',
21+
'lodash.isEqual'
22+
]);
23+
1824
for (const equalName in equalPackages) {
1925
const equalFunc = equalPackages[equalName];
2026

@@ -30,29 +36,31 @@ for (const equalName in equalPackages) {
3036
}
3137
});
3238

33-
allSuite.add(equalName, function() {
34-
for (const testSuite of tests.all) {
35-
for (const test of testSuite.tests) {
36-
try {
37-
equalFunc(test.value1, test.value2);
38-
} catch (error) {
39-
// swallow errors during benchmarking. they are reported in the test section
39+
if (advancedPkgs.has(equalName)) {
40+
advancedSuite.add(equalName, function() {
41+
for (const testSuite of tests.all) {
42+
for (const test of testSuite.tests) {
43+
try {
44+
equalFunc(test.value1, test.value2);
45+
} catch (error) {
46+
// swallow errors during benchmarking. they are reported in the test section
47+
}
4048
}
4149
}
42-
}
43-
});
50+
});
4451

45-
correctnessTests.push(() => console.log(equalName));
46-
for (const testSuite of tests.all) {
47-
for (const test of testSuite.tests) {
48-
correctnessTests.push(() => {
49-
try {
50-
if (equalFunc(test.value1, test.value2) !== test.equal)
51-
console.error('- different result:', equalName, testSuite.description, test.description);
52-
} catch(error) {
53-
console.error('- error:', testSuite.description, test.description, error.message);
54-
}
55-
});
52+
correctnessTests.push(() => console.log(equalName));
53+
for (const testSuite of tests.all) {
54+
for (const test of testSuite.tests) {
55+
correctnessTests.push(() => {
56+
try {
57+
if (equalFunc(test.value1, test.value2) !== test.equal)
58+
console.error('- different result:', equalName, testSuite.description, test.description);
59+
} catch(error) {
60+
console.error('- error:', testSuite.description, test.description, error.message);
61+
}
62+
});
63+
}
5664
}
5765
}
5866
}
@@ -75,7 +83,7 @@ genericSuite
7583

7684
console.log('\n--- speed tests: generic and react ---\n');
7785

78-
allSuite
86+
advancedSuite
7987
.on('cycle', (event) => console.log(String(event.target)))
8088
.on('complete', function () {
8189
console.log(' fastest: ' + this.filter('fastest').map('name'));
@@ -86,6 +94,9 @@ allSuite
8694
})
8795
.run({async: false});
8896

97+
// **Note**: `lodash.isEqual` gets different results for Sets, Maps
98+
// because it **is** correct and `fast-deep-equal` is not.
99+
// See: https://github.com/FormidableLabs/react-fast-compare/issues/50
89100
console.log('\n--- correctness tests: generic and react ---\n');
90101

91102
correctnessTests.forEach(test => test());

0 commit comments

Comments
 (0)