Skip to content

Latest commit

 

History

History
106 lines (77 loc) · 3.58 KB

Beyond Strict Equality.md

File metadata and controls

106 lines (77 loc) · 3.58 KB

Most of us have been living in the "everything should be immutable" world long enough to know that there is a difference between comparing objects by reference and comparing it with object that looks the same in terms of its value, but has a difference refernce in memory.

toBe

So far, we're only used .toBe, which checks for strict equality (e.g. === or Object.is).

This works like we expect for simple types (as seen in examples/great-expectations/primitives.test.ts):

test('strings should be strictly equal', () => {
  expect('string').toBe('string');
});

test('numbers should be strictly equal', () => {
  expect(2).toBe(2);
});

test('booleans should be strictly equal', () => {
  expect(true).toBe(true);
  expect(false).toBe(false);
});

test('undefined should be strictly equal to itself', () => {
  expect(undefined).toBe(undefined);
});

test('null should be strictly equal to itself', () => {
  expect(null).toBe(null);
});

test('BigInts should be strickly equal', () => {
  expect(BigInt(Number.MAX_SAFE_INTEGER)).toBe(BigInt(Number.MAX_SAFE_INTEGER));
});

But, things get a little trickier when comparing objects (arrays and functions are objects in JavaScript) as seen in src/examples/great-expectations/objects.test.ts:

describe('toBe', () => {
  test.fails('objects should not be strictly equal', () => {
    expect({ a: 1 }).toBe({ a: 1 });
  });

  test.fails('arrays should be strictly equal', () => {
    expect([1, 2, 3]).toBe([1, 2, 3]);
  });

  test.fails('functions should to be strictly equal', () => {
    expect(() => {}).toBe(() => {});
  });
});

toEqual

Instead, when we're comparing two objects that are not referentially equal, we can user toEqual. I'm going to just quote the documentation for a hot minute:

toEqual asserts if actual value is equal to received one or has the same structure, if it is an object (compares them recursively).

Looking further down in examples/great-expectations/objects.test.ts, you'll see the following:

describe('toEqual', () => {
  test('similar objects should pass with #toEqual', () => {
    expect({ a: 1 }).toEqual({ a: 1 });
  });

  test('similar nested objects should pass with #toEqual', () => {
    expect({ a: 1, b: { c: 2 } }).toEqual({ a: 1, b: { c: 2 } });
  });

  test('similar arrays should pass with #toEqual', () => {
    expect([1, 2, 3]).toEqual([1, 2, 3]);
  });

  test('similar multi-dimensional arrays should pass with #toEqual', () => {
    expect([1, [2, 3]]).toEqual([1, [2, 3]]);
  });

  test('functions should to be strictly equal if compared by reference', () => {
    const fn = () => {};
    expect(fn).toBe(fn);
  });
});

Exercise

Take a look at the tests in examples/great-expectations/exercise.test.ts. Can you make them pass? (If you need any hints, the solution is hanging out in exercise.solution.test.ts)

Too easy? Feel free to move on to the bonus-exercise.test.ts!

Here are some assertions that you may want to consider:

You can see the full API for expect here: