From 94734e1469ff9e13c1fa230b72a3de530f2f698a Mon Sep 17 00:00:00 2001 From: khai93 <33293519+khai93@users.noreply.github.com> Date: Wed, 29 Sep 2021 05:43:30 -0500 Subject: [PATCH] feat(expect): Add equality support for Array Buffers to ToStrictEqual method (#11805) --- CHANGELOG.md | 2 ++ .../expect/src/__tests__/matchers.test.js | 24 +++++++++++++++++ packages/expect/src/__tests__/utils.test.ts | 21 +++++++++++++++ packages/expect/src/matchers.ts | 2 ++ packages/expect/src/utils.ts | 26 +++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e4c4bdf3d24..424b5d74f462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Features +- `[expect]` Add equality checks for Array Buffers in `expect.ToStrictEqual()` ([#11805](https://github.com/facebook/jest/pull/11805)) + ### Fixes ### Chore & Maintenance diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 81ceabf09c81..1e244e6d7d57 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -426,6 +426,30 @@ describe('.toStrictEqual()', () => { it('does not pass when equally sparse arrays have different values', () => { expect([, 1]).not.toStrictEqual([, 2]); }); + + it('does not pass when ArrayBuffers are not equal', () => { + expect(Uint8Array.from([1, 2]).buffer).not.toStrictEqual( + Uint8Array.from([0, 0]).buffer, + ); + expect(Uint8Array.from([2, 1]).buffer).not.toStrictEqual( + Uint8Array.from([2, 2]).buffer, + ); + expect(Uint8Array.from([]).buffer).not.toStrictEqual( + Uint8Array.from([1]).buffer, + ); + }); + + it('passes for matching buffers', () => { + expect(Uint8Array.from([1]).buffer).toStrictEqual( + Uint8Array.from([1]).buffer, + ); + expect(Uint8Array.from([]).buffer).toStrictEqual( + Uint8Array.from([]).buffer, + ); + expect(Uint8Array.from([9, 3]).buffer).toStrictEqual( + Uint8Array.from([9, 3]).buffer, + ); + }); /* eslint-enable */ }); diff --git a/packages/expect/src/__tests__/utils.test.ts b/packages/expect/src/__tests__/utils.test.ts index c210abf9fb34..0654d99a43c2 100644 --- a/packages/expect/src/__tests__/utils.test.ts +++ b/packages/expect/src/__tests__/utils.test.ts @@ -8,6 +8,7 @@ import {stringify} from 'jest-matcher-utils'; import { + arrayBufferEquality, emptyObject, getObjectSubset, getPath, @@ -466,3 +467,23 @@ describe('iterableEquality', () => { expect(iterableEquality(a, b)).toBe(true); }); }); + +describe('arrayBufferEquality', () => { + test('returns undefined if given a non instance of ArrayBuffer', () => { + expect(arrayBufferEquality(2, 's')).toBeUndefined(); + expect(arrayBufferEquality(undefined, 2)).toBeUndefined(); + expect(arrayBufferEquality(new Date(), new ArrayBuffer(2))).toBeUndefined(); + }); + + test('returns false when given non-matching buffers', () => { + const a = Uint8Array.from([2, 4]).buffer; + const b = Uint16Array.from([1, 7]).buffer; + expect(arrayBufferEquality(a, b)).not.toBeTruthy(); + }); + + test('returns true when given matching buffers', () => { + const a = Uint8Array.from([1, 2]).buffer; + const b = Uint8Array.from([1, 2]).buffer; + expect(arrayBufferEquality(a, b)).toBeTruthy(); + }); +}); diff --git a/packages/expect/src/matchers.ts b/packages/expect/src/matchers.ts index d0ec1480dab4..344374330cb6 100644 --- a/packages/expect/src/matchers.ts +++ b/packages/expect/src/matchers.ts @@ -40,6 +40,7 @@ import { } from './print'; import type {MatcherState, MatchersObject} from './types'; import { + arrayBufferEquality, getObjectSubset, getPath, iterableEquality, @@ -61,6 +62,7 @@ const toStrictEqualTesters = [ iterableEquality, typeEquality, sparseArrayEquality, + arrayBufferEquality, ]; type ContainIterable = diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 858f7a7d03cb..eab02cd36204 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -319,6 +319,32 @@ export const typeEquality = (a: any, b: any): boolean | undefined => { return false; }; +export const arrayBufferEquality = ( + a: unknown, + b: unknown, +): boolean | undefined => { + if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) { + return undefined; + } + + const dataViewA = new DataView(a); + const dataViewB = new DataView(b); + + // Buffers are not equal when they do not have the same byte length + if (dataViewA.byteLength !== dataViewB.byteLength) { + return false; + } + + // Check if every byte value is equal to each other + for (let i = 0; i < dataViewA.byteLength; i++) { + if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) { + return false; + } + } + + return true; +}; + export const sparseArrayEquality = ( a: unknown, b: unknown,