diff --git a/src/allEqualTo.js b/src/allEqualTo.js new file mode 100644 index 0000000000..07da14ce66 --- /dev/null +++ b/src/allEqualTo.js @@ -0,0 +1,25 @@ +import { all, equals, curry } from 'ramda'; + +/** + * Returns true if all items in the list are equivalent to user provided value using `R.equals` for equality comparisons. + * + * @func allEqualTo + * @memberOf RA + * @since {@link https://char0n.github.io/ramda-adjunct/2.11.0|v2.11.0} + * @category List + * @sig a -> [b] -> Boolean + * @param {*} val User provided value to check the `list` against + * @param {Array} list The list of values + * @return {boolean} + * @see {@link RA.allEqual|allEqual}, {@link https://ramdajs.com/docs/#equals|equals} + * @example + * + * RA.allEqualTo(1, [ 1, 2, 3, 4 ]); //=> false + * RA.allEqualTo(1, [ 1, 1, 1, 1 ]); //=> true + * RA.allEqualTo({}, [ {}, {} ]); //=> true + * RA.allEqualTo(1, []); //=> true + * + */ +const allEqualTo = curry((val, list) => all(equals(val), list)); + +export default allEqualTo; diff --git a/src/index.d.ts b/src/index.d.ts index 55c9cdea7b..0a374d65bc 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -878,6 +878,12 @@ declare namespace RamdaAdjunct { allIdenticalTo(val: T, list: T[]): boolean; allIdenticalTo(val: T): (list: T[]) => boolean; + /* + * Returns true if all items in the list are equivalent to user provided value using `R.equals` for equality comparisons. + */ + allEqualTo(val: T, list: T[]): boolean; + allEqualTo(val: T): (list: T[]) => boolean; + /** * Checks if input value is a `thenable`. * `thenable` is an object or function that defines a `then` method. diff --git a/src/index.js b/src/index.js index e19bc86681..ac52da40ce 100644 --- a/src/index.js +++ b/src/index.js @@ -122,6 +122,7 @@ export { default as allEqual } from './allEqual'; export { default as repeatStr } from './repeatStr'; export { default as allIdentical } from './allIdentical'; export { default as allIdenticalTo } from './allIdenticalTo'; +export { default as allEqualTo } from './allEqualTo'; // Object export { default as paths } from './paths'; export { default as renameKeys } from './renameKeys'; diff --git a/test/allEqualTo.js b/test/allEqualTo.js new file mode 100644 index 0000000000..e3bda5b002 --- /dev/null +++ b/test/allEqualTo.js @@ -0,0 +1,68 @@ +import { assert } from 'chai'; +import * as R from 'ramda'; + +import * as RA from '../src'; + +// https://github.com/ramda/ramda/pull/1992 +const hasFunctionReferenceEqualityBug = (() => { + const f = () => {}; + return R.uniq([f, f, f]).length !== 1; +})(); + +describe('allEqualTo', function() { + context('given all items are equal', function() { + specify('returns true', function() { + assert.isTrue(RA.allEqualTo(4, [4, 4, 4, 4])); + }); + }); + + context('given all items are deeply equal', function() { + specify('should return true', function() { + assert.isTrue( + RA.allEqualTo({ key: 'foo' }, [{ key: 'foo' }, { key: 'foo' }]) + ); + }); + }); + + context('given items are not equal', function() { + specify('should return false', function() { + assert.isFalse(RA.allEqualTo(1, [1, 1, 2, 1, 1])); + }); + }); + + context('given items have different type', function() { + specify('should return false', function() { + assert.isFalse(RA.allEqualTo(1, [1, 1, '1', 1])); + }); + }); + + if (!hasFunctionReferenceEqualityBug) { + context('given items are reference to function', function() { + specify('should return true', function() { + const f = () => {}; + assert.isTrue(RA.allEqualTo(f, [f, f, f])); + }); + }); + + context( + 'given items are same functions without the same reference', + function() { + specify('should return false', function() { + const getF = () => () => {}; + assert.isFalse(RA.allEqualTo(getF(), [getF(), getF(), getF()])); + }); + } + ); + } + + context('given empty list provided', function() { + specify('should return true', function() { + assert.isTrue(RA.allEqualTo(1, [])); + }); + }); + + it('should curry', function() { + assert.isTrue(RA.allEqualTo(1, [1, 1])); + assert.isTrue(RA.allEqualTo(1)([1, 1])); + }); +});