{"id":24774959,"url":"https://github.com/dentemple/jest-invert","last_synced_at":"2025-10-18T16:55:08.277Z","repository":{"id":44163426,"uuid":"160882459","full_name":"dentemple/jest-invert","owner":"dentemple","description":"Determine the integrity of your Jest unit tests by inverting the return value of jest.expect","archived":false,"fork":false,"pushed_at":"2022-12-25T20:09:14.000Z","size":274,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-15T22:40:59.095Z","etag":null,"topics":["jest","micro-library","tdd","unit-testing"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/jest-invert","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dentemple.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-07T22:37:40.000Z","updated_at":"2023-01-31T17:08:15.000Z","dependencies_parsed_at":"2023-01-30T22:45:42.573Z","dependency_job_id":null,"html_url":"https://github.com/dentemple/jest-invert","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dentemple/jest-invert","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dentemple%2Fjest-invert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dentemple%2Fjest-invert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dentemple%2Fjest-invert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dentemple%2Fjest-invert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dentemple","download_url":"https://codeload.github.com/dentemple/jest-invert/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dentemple%2Fjest-invert/sbom","scorecard":{"id":334504,"data":{"date":"2025-08-11","repo":{"name":"github.com/dentemple/jest-invert","commit":"95a59bfd156ff6705a9f4e745cef628357eab70c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-f9xv-q969-pqx4"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T04:24:16.859Z","repository_id":44163426,"created_at":"2025-08-18T04:24:16.859Z","updated_at":"2025-08-18T04:24:16.859Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279009509,"owners_count":26084609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jest","micro-library","tdd","unit-testing"],"created_at":"2025-01-29T06:31:26.975Z","updated_at":"2025-10-12T00:31:09.268Z","avatar_url":"https://github.com/dentemple.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jest-invert\r\n\r\n[![npm](https://img.shields.io/npm/v/jest-invert.svg)](https://www.npmjs.com/package/jest-invert) [![npm bundle size (minified)](https://img.shields.io/bundlephobia/min/jest-invert.svg)](https://www.npmjs.com/package/jest-invert)\r\n\r\n**A library for breaking a bunch of tests quickly.**\r\n\r\nThis library does not add [matchers](https://jestjs.io/docs/expect#expectextendmatchers).  What this library does is grab your `expect` argument _before_ it hits the function, inverts the value, _then_ passes it on to `expect` (via currying).\r\n\r\n`expect(2 + 2).toEqual(4)` will fail with the result `Expected: 4, Received: -4`.\r\n\r\n`expect('ABC').toEqual('ABC')` will fail with the result `Expected: \"ABC\", Received: \"CBA\"`.\r\n\r\n## But... why?\r\n\r\n~~Because some men want to watch the world burn.~~\r\n\r\nBecause a great unit test is not a good unit test until you see it fail (at least once).  However, manually failing a bunch of tests individually can be tedious.\r\n\r\nSo this allows you to attack all of the tests within a certain scope all at once.  Do it only for a single `describe` block, or fail literally everything in the code base.  It just depends on where you invoke the library's main function.\r\n\r\n~~Also, this can be used to troll your team members to great effect.~~\r\n\r\n[Read more about Test Driven Development](https://en.wikipedia.org/wiki/Test-driven_development)\r\n\r\n### But why \"invert\" the values instead of just, y'know, _throwing an error_\r\n\r\nInverting these return values, as opposed to returning random noise, provides a predictable failure mode. A sample test that returns `\"eurt\"` when it should return `false` can generate a more meaningful message than a generic error message.\r\n\r\n## Library Quick Reference\r\n\r\n```js\r\n/* install */\r\nnpm install --save-dev jest-invert\r\n\r\n/* require */\r\nconst invert = require('./jest-invert')\r\n\r\n/* ES6+ */\r\nimport invert from 'jest-invert'\r\n\r\n/* invert ALL tests...  */\r\n// setupTests.js\r\nglobal.expect = invert()\r\n\r\n/* ... or invert only SOME tests */\r\n// foo.test.ts\r\ndescribe('foo', function() {\r\n  let expect: any\r\n\r\n  beforeAll(function() {\r\n    expect = invert() // ⚠️ Invoke within the `before`/`beforeAll` block\r\n  })\r\n\r\n  afterAll(function() {\r\n    expect = invert({ run: false }) // ⚠️ Deactivate within the `after`/`afterAll` block\r\n  })\r\n\r\n  it('can add 2 + 2', function() {\r\n    expect(2 + 2).toEqual(4) // ⚠️ Fails, as expected\r\n  })\r\n\r\n  /* ... */\r\n})\r\n\r\n/* example tests that will be affected by this library */\r\n\r\nexpect(true).toEqual(true)  // ⚠️ Changes to: false === true\r\nexpect(42).toEqual(42) // ⚠️ Changes to: -42 === 42\r\nexpect('mystring').toEqual('mystring') // ⚠️ Changes to: changes to: \"gnirtsym\" === \"mystring\"\r\nexpect([1, 2, 3]).toEqual([1, 2, 3]) // ⚠️ Changes to: changes to: [3, 2, 1] === [1, 2, 3]\r\nexpect({ a: 1, b: 2 }).toEqual({ a: 1, b: 2 }) // ⚠️ Changes to: changes to: {\"1\":\"a\", \"2\":\"b\"} === { a: 1, b: 2 }\r\nexpect(myFunction).toEqual(myFunction)  // ⚠️ Changes to: [Function inverted] === [Function myFunction]\r\n```\r\n\r\n## How it works\r\n\r\n### 1) Install\r\n\r\n```js\r\n/* with npm */\r\nnpm install --save-dev jest-invert\r\n\r\n/* with yarn */\r\nyarn add --dev jest-invert\r\n```\r\n\r\n### 2) Invoke\r\n\r\n```js\r\n/* ES5 */\r\nconst invert = require('./jest-invert')\r\n\r\n/* ES6+ */\r\nimport invert from 'jest-invert'\r\n\r\nglobal.expect = invert()\r\n\r\n/* For Typescript projects, prefer passing in an empty object for the default settings */\r\nglobal.expect = invert({})\r\n\r\n/* For more explicit activation or control, use the `run` argument */\r\n\r\nglobal.expect = invert({ run: true })\r\nglobal.expect = invert({ run: false })\r\n```\r\n\r\nAlternatively, pass in a configuration object for more explicit activation and deactivation.\r\n\r\n\r\nThis can be placed in Jest's setup/teardown cycle to affect only a block of tests.\r\n\r\nExample:\r\n\r\n```js\r\ndescribe('my tests', function() {\r\n  var expect\r\n  beforeAll(() =\u003e {\r\n    expect = invert({ run: true }) // or just `invert()`\r\n  })\r\n\r\n  afterAll(() =\u003e {\r\n    expect = invert({ run: false })\r\n  })\r\n\r\n  it('my unit test', function() {\r\n    expect(42).not.toEqual(42)\r\n  })\r\n\r\n  /* ... */\r\n})\r\n```\r\n\r\n### 3) Results\r\n\r\nThe following changes will occur:\r\n\r\n- Booleans will flip to the opposite value (`true` to `false`, and vice versa)\r\n- `undefined` and `null` will evaluate to `true`\r\n- Numbers will flip to the opposite sign (`1` to `-1`, and vice versa)\r\n- Strings will be reversed\r\n- Arrays will be reversed\r\n- Objects\\* will swap keys and values (at a shallow-level only)\r\n- Functions\\*\\* will be wrapped in a different, higher order function named \"inverted\"\r\n\r\n_\\*Note on objects_: The key/value swap uses `JSON.stringify()` to create the keys.  This is to avoid `[object Object]` from being the end result of every operation.\r\n\r\n_\\*\\*Note on functions_: \"Inverting\" a function has a precise mathematical definition that falls quite outside the scope of a simple testing libary. Passing a function definition into `expect` also happens to be behavior that is typically _not_ recommended for users of Jest to perform.\r\n\r\nTherefore, to err on the side of predictability ,`jest-invert` simply curries the argument through another function named \"inverted.\"\r\n\r\n```js\r\nfunction invertFunction(actual) {\r\n  return function inverted() {\r\n    return actual\r\n  }\r\n}\r\n```\r\n\r\nThe end result:\r\n\r\nJest's failure message will return `[Function inverted]` as the argument name.\r\n\r\nThis has the added benefit of making it obvious that the original function does or doesn't exist.\r\n\r\n---\r\n\r\n## API\r\n\r\n### `require('jest-invert')`\r\n\r\n\u003e `({ expect, run = true }: config) =\u003e any`\r\n\r\nReturns a higher-order function. Accepts a configuration object, and returns the main `invert` function.\r\n\r\nUse this returned function to replace `jest.expect`.\r\n\r\nAn empty object can be passed in as well.\r\n\r\nUsage:\r\n\r\n```js\r\nconst invert = require('jest-invert')\r\n\r\nconsole.log(global.expect) // function definition from jest\r\n\r\nglobal.expect = invert() // or global.expect = invert({})\r\n\r\nconsole.log(global.expect) // ⚠️ function definition from jest-invert\r\n```\r\n\r\n### `config.run`\r\n\r\n\u003e `run?: boolean | null`\r\n\r\nBoolean.\r\n\r\nIf set to `true`, activates _jest-invert_'s core functionality.\r\n\r\nIf set to `false`, _jest-invert_ will have no effect.\r\n\r\nDefaults to `true`.\r\n\r\nUsage:\r\n\r\n```js\r\ndescribe('my tests', function() {\r\n  var expect\r\n  beforeAll(() =\u003e {\r\n    expect = invert({ run: true })\r\n  })\r\n\r\n  afterAll(() =\u003e {\r\n    expect = invert({ run: false })\r\n  })\r\n\r\n  it('my unit test', function() {\r\n    expect(42).not.toEqual(42)\r\n  })\r\n\r\n  /* ... */\r\n})\r\n```\r\n\r\n### `config.expect`\r\n\r\n\u003e `expect?: any`\r\n\r\nFunction. _For future compatibility only._\r\n\r\nIf ever the Jest team re-configures their library to avoid polluting the global scope, pass Jest's `expect` function as a callback to the `config.expect` property. _jest-invert_ checks this property before checking the global scope.\r\n\r\nMay also be useful in the rare case that your codebases uses a custom or monkeypatched `expect` function--assuming that the API is simmilar.\r\n\r\nUsage:\r\n\r\n```js\r\nconst jest = require('jest')\r\nconst invert = require('jest-invert')\r\n\r\nconsole.log(global.expect) // undefined\r\n\r\nconst expect = invert({ expect: jest.expect })\r\n\r\nconsole.log(expect) // function definition from jest-invert\r\n```\r\n\r\n---\r\n\r\n## Changelog\r\n\r\nView the recent changes [here](CHANGELOG.md).\r\n\r\n## Code of Conduct\r\n\r\nRead the Code of Conduct [here](CODE-OF-CONDUCT.md). Contributions that violate these principles may be removed.\r\n\r\n## License\r\n\r\nThis library is _Free and Open Source_ under the [MIT License](LICENSE).\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdentemple%2Fjest-invert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdentemple%2Fjest-invert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdentemple%2Fjest-invert/lists"}