{"id":12790,"library":"add-matchers","title":"add-matchers","description":"A JavaScript library designed to provide a unified API for creating custom test matchers that are compatible across different versions of popular testing frameworks, specifically Jest and Jasmine (1.x and 2.x). This library addresses the varying native APIs for custom matcher registration, allowing developers to write matchers once and use them interchangeably across these environments. The current stable version is 0.6.2. The project appears to be in an abandoned state, with no new releases or significant activity since 2019, suggesting a lack of future feature development or proactive compatibility updates. Its primary differentiator is simplifying cross-framework matcher development, encouraging reusability within the testing community without needing to rewrite matchers for each framework version.","status":"abandoned","version":"0.6.2","language":"javascript","source_language":"en","source_url":"https://github.com/JamieMason/add-matchers","tags":["javascript","BDD","TDD","jasmine","testing"],"install":[{"cmd":"npm install add-matchers","lang":"bash","label":"npm"},{"cmd":"yarn add add-matchers","lang":"bash","label":"yarn"},{"cmd":"pnpm add add-matchers","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily uses ES module syntax in its documentation, though older Node.js projects might attempt CommonJS. Ensure your environment supports ESM for direct usage.","wrong":"const { addMatchers } = require('add-matchers');","symbol":"addMatchers","correct":"import { addMatchers } from 'add-matchers';"},{"note":"Asymmetric matchers are exposed as a property of the main `addMatchers` function, not a separate named export.","wrong":"import { asymmetric } from 'add-matchers';","symbol":"addMatchers.asymmetric","correct":"import { addMatchers } from 'add-matchers'; addMatchers.asymmetric(...);"}],"quickstart":{"code":"import { addMatchers } from 'add-matchers';\n\n// Register your custom matchers in a setup file (e.g., setupTests.js or jest.setup.js)\naddMatchers({\n  toBeEvenNumber: function(received) {\n    return {\n      pass: received % 2 === 0,\n      message: () => `Expected ${received} to be an even number`\n    };\n  },\n  toBeOfType: function(type, received) {\n    return {\n      pass: Object.prototype.toString.call(received) === '[object ' + type + ']',\n      message: () => `Expected ${received} to be of type ${type}`\n    };\n  },\n  toContainItems: function(arg1, arg2, arg3, received) {\n    // Important: Arguments are ordered (matcherArgs..., receivedValue)\n    const allIncluded = received.indexOf(arg1) !== -1 &&\n                        received.indexOf(arg2) !== -1 &&\n                        received.indexOf(arg3) !== -1;\n    return {\n      pass: allIncluded,\n      message: () => `Expected ${received} to contain items ${arg1}, ${arg2}, ${arg3}`\n    };\n  }\n});\n\n// Register asymmetric matchers\naddMatchers.asymmetric({\n  toBeFoo: function(value) {\n    return {\n      pass: value === 'foo',\n      message: () => `Expected value to be 'foo'`\n    };\n  },\n  toInclude: function(other, value) {\n    return {\n      pass: value.includes(other),\n      message: () => `Expected '${value}' to include '${other}'`\n    };\n  }\n});\n\n// Example usage in your test file (e.g., my.test.js)\ndescribe('Custom matchers', () => {\n  it('should check for even numbers', () => {\n    expect(4).toBeEvenNumber();\n    expect(3).not.toBeEvenNumber();\n  });\n\n  it('should check for object type', () => {\n    expect({}).toBeOfType('Object');\n    expect([]).not.toBeOfType('Object');\n  });\n\n  it('should check for multiple contained items', () => {\n    expect([100, 14, 15, 2]).toContainItems(2, 15, 100);\n    expect([1, 2, 3]).not.toContainItems(4, 5);\n  });\n});\n\ndescribe('Custom asymmetric matchers', () => {\n  it('should work with toEqual for object properties', () => {\n    const any = expect; // In Jest, `expect` typically exposes `any` for asymmetric matchers\n\n    expect({ key: 'foo', prop: 'bar' }).toEqual({\n      key: any.toBeFoo(),\n      prop: any.toInclude('ar')\n    });\n\n    expect({ key: 'baz', prop: 'qux' }).not.toEqual({\n      key: any.toBeFoo(),\n      prop: any.toInclude('ar')\n    });\n  });\n});","lang":"javascript","description":"Demonstrates how to define and use both standard and asymmetric custom matchers compatible with Jest and Jasmine, highlighting the argument order convention for matcher functions."},"warnings":[{"fix":"Always define your custom matcher functions with the `(arg1, arg2, ..., received)` signature, where `received` is the value passed to `expect()`.","message":"Custom matcher functions in `add-matchers` expect the `received` value (the argument passed to `expect()`) as the *last* argument. Any other matcher arguments (`arg1, arg2, ...`) precede it. This is a common source of bugs if developers assume `received` is the first argument, as is often the case with native Jest/Jasmine custom matchers.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"For critical projects, consider forking the library to manage updates internally, or evaluate actively maintained alternatives if long-term support and active development are crucial.","message":"The `add-matchers` project has seen no releases or significant activity since 2019 (version 0.6.2). This means it is effectively abandoned, and may not receive updates for new features, bug fixes, or compatibility with future major versions of Jest or Jasmine. Users should be prepared to maintain compatibility patches themselves.","severity":"breaking","affected_versions":">=0.6.2"},{"fix":"Create custom `d.ts` files for `add-matchers` and extend Jest/Jasmine's `Matchers` interface to provide type safety for your custom matchers.","message":"This library does not ship with TypeScript type definitions (`.d.ts` files). TypeScript users will need to create ambient type declarations (`declare module 'add-matchers' { ... }`) to properly type their custom matchers and the `addMatchers` API, particularly if extending Jest's `expect` matchers.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure that `addMatchers` is called in a test setup file (e.g., `setupTests.js` or `jest.setup.js`) that is configured to run before your tests, or import and call it directly in the test file where the matcher is used.","cause":"The `addMatchers` function was not called or executed before the tests that attempt to use the custom matcher, or the import path was incorrect.","error":"TypeError: expect(...).toBeMyCustomMatcher is not a function"},{"fix":"Review the custom matcher function signature and ensure the `received` value is the last argument, with all other matcher-specific arguments (`arg1`, etc.) preceding it. This mistake often leads to subtle logic errors rather than clear TypeError messages.","cause":"The custom matcher function's arguments were implemented in the incorrect order. `add-matchers` expects `(arg1, arg2, ..., received)` where `received` is the value from `expect(received)`.","error":"Expected value to be X, received Y (and the actual and expected values are swapped or incorrect)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null}