-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
[FEATURE ember-runtime-enumerable-includes] Implements Array.includes and deprecates Array.contains #13553
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
[FEATURE ember-runtime-enumerable-includes] Implements Array.includes and deprecates Array.contains #13553
Changes from all commits
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 |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ import { | |
| } from 'ember-metal/events'; | ||
| import compare from 'ember-runtime/compare'; | ||
| import require from 'require'; | ||
| import { assert, deprecate } from 'ember-metal/debug'; | ||
|
|
||
| let _emberA; | ||
|
|
||
|
|
@@ -231,6 +232,14 @@ var Enumerable = Mixin.create({ | |
| @public | ||
| */ | ||
| contains(obj) { | ||
| if (isEnabled('ember-runtime-enumerable-includes')) { | ||
| deprecate( | ||
| '`Enumerable#contains` is deprecated, use `Enumerable#includes` instead.', | ||
| false, | ||
| { id: 'ember-runtime.enumerable-contains', until: '3.0.0', url: 'http://emberjs.com/deprecations/v2.x#toc_enumerable-contains' } | ||
| ); | ||
| } | ||
|
|
||
| var found = this.find(function(item) { | ||
| return item === obj; | ||
| }); | ||
|
|
@@ -797,8 +806,8 @@ var Enumerable = Mixin.create({ | |
|
|
||
| /** | ||
| Returns a new enumerable that excludes the passed value. The default | ||
| implementation returns an array regardless of the receiver type unless | ||
| the receiver does not contain the value. | ||
| implementation returns an array regardless of the receiver type. | ||
| If the receiver does not contain the value it returns the original enumerable. | ||
|
|
||
| ```javascript | ||
| var arr = ['a', 'b', 'a', 'c']; | ||
|
|
@@ -1118,4 +1127,63 @@ if (isEnabled('ember-runtime-computed-uniq-by')) { | |
| }); | ||
| } | ||
|
|
||
| if (isEnabled('ember-runtime-enumerable-includes')) { | ||
| Enumerable.reopen({ | ||
| /** | ||
| Returns `true` if the passed object can be found in the enumerable. | ||
| ```javascript | ||
| [1, 2, 3].includes(2); // true | ||
| [1, 2, 3].includes(4); // false | ||
| [1, 2, undefined].includes(undefined); // true | ||
| [1, 2, null].includes(null); // true | ||
| [1, 2, NaN].includes(NaN); // true | ||
| ``` | ||
| @method includes | ||
| @param {Object} obj The object to search for. | ||
| @return {Boolean} `true` if object is found in the enumerable. | ||
| @public | ||
| */ | ||
| includes(obj) { | ||
| assert('Enumerable#includes cannot accept a second argument "startAt" as enumerable items are unordered.', arguments.length === 1); | ||
|
|
||
| var len = get(this, 'length'); | ||
| var idx, next; | ||
| var last = null; | ||
| var found = false; | ||
|
|
||
| var context = popCtx(); | ||
|
|
||
| for (idx = 0; idx < len && !found; idx++) { | ||
| next = this.nextObject(idx, last, context); | ||
|
|
||
| found = obj === next || (obj !== obj && next !== next); | ||
|
|
||
| last = next; | ||
| } | ||
|
|
||
| next = last = null; | ||
| context = pushCtx(context); | ||
|
|
||
| return found; | ||
| }, | ||
|
|
||
| without(value) { | ||
|
||
| if (!this.includes(value)) { | ||
|
||
| return this; // nothing to do | ||
| } | ||
|
|
||
| var ret = emberA(); | ||
|
|
||
| this.forEach(function(k) { | ||
| // SameValueZero comparison (NaN !== NaN) | ||
| if (!(k === value || k !== k && value !== value)) { | ||
| ret[ret.length] = k; | ||
| } | ||
| }); | ||
|
|
||
| return ret; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| export default Enumerable; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import {SuiteModuleBuilder} from 'ember-runtime/tests/suites/suite'; | ||
|
|
||
| var suite = SuiteModuleBuilder.create(); | ||
|
|
||
| suite.module('includes'); | ||
|
||
|
|
||
| suite.test('includes returns correct value if startAt is positive', function() { | ||
| var data = this.newFixture(3); | ||
| var obj = this.newObject(data); | ||
|
|
||
| equal(obj.includes(data[1], 1), true, 'should return true if included'); | ||
| equal(obj.includes(data[0], 1), false, 'should return false if not included'); | ||
| }); | ||
|
|
||
| suite.test('includes returns correct value if startAt is negative', function() { | ||
| var data = this.newFixture(3); | ||
| var obj = this.newObject(data); | ||
|
|
||
| equal(obj.includes(data[1], -2), true, 'should return true if included'); | ||
| equal(obj.includes(data[0], -2), false, 'should return false if not included'); | ||
| }); | ||
|
|
||
| suite.test('includes returns true if startAt + length is still negative', function() { | ||
| var data = this.newFixture(1); | ||
| var obj = this.newObject(data); | ||
|
|
||
| equal(obj.includes(data[0], -2), true, 'should return true if included'); | ||
| equal(obj.includes(this.newFixture(1), -2), false, 'should return false if not included'); | ||
| }); | ||
|
|
||
| suite.test('includes returns false if startAt out of bounds', function() { | ||
| var data = this.newFixture(1); | ||
| var obj = this.newObject(data); | ||
|
|
||
| equal(obj.includes(data[0], 2), false, 'should return false if startAt >= length'); | ||
| equal(obj.includes(this.newFixture(1), 2), false, 'should return false if startAt >= length'); | ||
| }); | ||
|
|
||
| export default suite; | ||
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 did not change deprecation id because feature is about
includesbut deprecation is aboutcontains.But I don't know if it is accepted. Let me know
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.
the deprecation id and feature id are totally distinct. Seems fine to use different names 👍