While using Traitful JavaScript it could often be hard to assert your structs
jest-traitful aims to add additional matchers to Jest's default ones that simplifying testing traitful structs
If you've come here to help contribute - Sweet! Thanks! Take a look at the contributing and read the Code of Conduct docs as a way of getting started!
With npm:
npm install -D jest-traitfulWith yarn:
yarn add -D jest-traitfulAdd jest-traitful to your Jest setupFilesAfterEnv configuration. See for help
"jest": {
"setupFilesAfterEnv": ["jest-traitful"]
}All matchers described below have asymmetric variants. Example:
test("symmetric vs asymmetric", () => {
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({ a: 1 });
expect({ a: 1, x: () => {} }).toEqual(expect.methodlessly({ a: 1 }));
});Asserts that two objects are deeply equal if all their methods were completely ignored
expect({ a: 1 }).toEqualWithoutMethods({ a: 1 }); // true
expect({ a: 1 }).toEqualWithoutMethods({ a: 1, x: () => {} }); // true
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({ a: 1 }); // true
expect({ a: 1 }).toEqualWithoutMethods({ a: expect.any(Number) }); // true, allows use of other asymmetric within it
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({ a: 1, x: () => {} }); // true
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({ a: 1, y: () => {} }); // true
expect({ b: 1, x: () => {} }).not.toEqualWithoutMethods({ a: 1, x: () => {} }); // true
// It should be noted that by using expect.any(Function) or expect.anything() or similar
// you are explicitly opting out of methodlessly's function === undefined equality.
// Example:
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({
a: 1,
x: () => {},
y: expect.any(Function), // or expect.anything()
}); // false!
// But of course this will work as expected:
expect({ a: 1, x: () => {} }).toEqualWithoutMethods({
a: 1,
x: expect.any(Function),
}); // trueThe asymmetric variant of .toEqualWithoutMethods.
expect({ a: 1 }).toEqual(expect.methodlessly({ a: 1 })); // true
expect({ a: 1 }).toEqual(expect.methodlessly({ a: 1, x: () => {} })); // true
expect({ a: 1, x: () => {} }).toEqual(expect.methodlessly({ a: 1 })); // true
expect({ a: 1 }).toEqual(expect.methodlessly({ a: expect.any(Number) })); // true, allows use of other asymmetric within it
expect({ a: 1, x: () => {} }).toEqual(
expect.methodlessly({ a: 1, x: () => {} }),
); // true
expect({ a: 1, x: () => {} }).toEqual(
expect.methodlessly({ a: 1, y: () => {} }),
); // true
expect({ b: 1, x: () => {} }).toEqual(
expect.not.methodlessly({ a: 1, x: () => {} }),
); // true
// Same as .toEqualWithoutMethods() above
expect({ a: 1, x: () => {} }).toEqual(
expect.methodlessly({ a: 1, x: () => {}, y: expect.any(Function) }),
); // false!
expect({ a: 1, x: () => {} }).toEqual(
expect.methodlessly({ a: 1, x: expect.any(Function) }),
); // trueAsserts that two objects are deeply equal if all properties were identical but their methods were compared ONLY by name
Whatever the methods' implementations or their signatures doesn't matter to this matcher
If Traitful JavaScript was followed this should basically assert full equality including functionality
expect({a: 1}).toEqualTraitfully({a: 1}); // true
expect({a: 1, x: () => {}}).toEqualTraitfully({a: 1, x: () => {}}); // true
expect({a: 1, x: () => true}).toEqualTraitfully({a: 1, x: () => false); // true
expect({a: 1, x: () => {}}).toEqualTraitfully({a: expect.any(Number), x: () => {}}); // true, allows use of other asymmetric within it
expect({a: 1, x: () => {}}).not.toEqualTraitfully({a: 1}); // true
expect({a: 1, x: () => {}}).not.toEqualTraitfully({a: 1, y: () => {}}); // true
expect({b: 1, x: () => {}}).not.toEqualTraitfully({a: 1, x: () => {}}); // trueThe asymmetric variant of .toEqualTraitfully.
expect({a: 1}).toEqual(expect.traitfully({a: 1})); // true
expect({a: 1, x: () => {}}).toEqual(expect.traitfully({a: 1, x: () => {}})); // true
expect({a: 1, x: () => true}).toEqual(expect.traitfully({a: 1, x: () => false)); // true
expect({a: 1, x: () => {}}).toEqual(expect.traitfully({a: expect.any(Number), x: () => {}})); // true, allows use of other asymmetric within it
expect({a: 1, x: () => {}}).toEqual(expect.traitfully({a: 1})); // true
expect({a: 1, x: () => {}}).toEqual(expect.traitfully({a: 1, y: () => {}})); // true
expect({b: 1, x: () => {}}).toEqual(expect.traitfully({a: 1, x: () => {}})); // true