pax_global_header00006660000000000000000000000064150521200540014504gustar00rootroot0000000000000052 comment=2a3ecff347dd4a354b20c953ef6f6d5dc99f851a chaijs-chai-2a3ecff/000077500000000000000000000000001505212005400144225ustar00rootroot00000000000000chaijs-chai-2a3ecff/.github/000077500000000000000000000000001505212005400157625ustar00rootroot00000000000000chaijs-chai-2a3ecff/.github/FUNDING.yml000066400000000000000000000000271505212005400175760ustar00rootroot00000000000000open_collective: chaijschaijs-chai-2a3ecff/.github/workflows/000077500000000000000000000000001505212005400200175ustar00rootroot00000000000000chaijs-chai-2a3ecff/.github/workflows/browsers.yml000066400000000000000000000012411505212005400224060ustar00rootroot00000000000000# This workflow will do a clean install of node dependencies, build the source # code and run tests across different versions of browsers name: Browsers CI on: push: branches: [ main, 4.x.x ] pull_request: branches: [ main, 4.x.x ] jobs: build: runs-on: ubuntu-latest strategy: matrix: browser-name: - chromium - firefox steps: - uses: actions/checkout@v4 - name: ${{ matrix.browser-name }} uses: actions/setup-node@v4 - run: npm ci - run: npx playwright install --with-deps - run: npm run build --if-present - run: npm run test-chrome -- --browsers ${{ matrix.browser-name }} chaijs-chai-2a3ecff/.github/workflows/node.js.yml000066400000000000000000000022471505212005400221070ustar00rootroot00000000000000# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Node.js CI on: push: branches: [ main, 4.x.x ] pull_request: branches: [ main, 4.x.x ] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - run: npm run lint build: runs-on: ubuntu-latest strategy: matrix: node-version: - 18 # to be removed 2025-04-30 - 20 # to be removed 2026-04-30 - latest # See supported Node.js release schedule at https://github.com/nodejs/release#release-schedule steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm ci - run: npm run build --if-present - run: npm run test-node chaijs-chai-2a3ecff/.github/workflows/npm-publish.yml000066400000000000000000000022351505212005400230020ustar00rootroot00000000000000# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Publish to npm on: release: types: [created] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - run: npx playwright install --with-deps - run: npm run build --if-present - run: npm test publish-npm: needs: build runs-on: ubuntu-latest permissions: id-token: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.x registry-url: "https://registry.npmjs.org" cache: "npm" - run: npm ci - run: npm run build --if-present - run: npm version ${TAG_NAME} --git-tag-version=false env: TAG_NAME: ${{ github.ref_name }} - run: npm publish --provenance --access public env: NODE_AUTH_TOKEN: ${{ secrets.npm_secret }} chaijs-chai-2a3ecff/.gitignore000066400000000000000000000002501505212005400164070ustar00rootroot00000000000000lib-cov *.seed *.log *.csv *.dat *.out *.pid *.gz pids logs results build components node_modules npm-debug.log coverage test/auth/* !test/auth/.gitkeep /index.js chaijs-chai-2a3ecff/.mailmap000066400000000000000000000000571505212005400160450ustar00rootroot00000000000000Domenic Denicola chaijs-chai-2a3ecff/.prettierrc.json000066400000000000000000000002641505212005400175600ustar00rootroot00000000000000{ "bracketSpacing": false, "printWidth": 80, "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "none", "useTabs": false, "arrowParens": "always" } chaijs-chai-2a3ecff/CODEOWNERS000066400000000000000000000000251505212005400160120ustar00rootroot00000000000000* @chaijs/chai chaijs-chai-2a3ecff/CODE_OF_CONDUCT.md000066400000000000000000000054631505212005400172310ustar00rootroot00000000000000# Contributor Code of Conduct > Read in: [Español](http://contributor-covenant.org/version/1/3/0/es/) | [Français](http://contributor-covenant.org/version/1/3/0/fr/) | [Italiano](http://contributor-covenant.org/version/1/3/0/it/) | [Magyar](http://contributor-covenant.org/version/1/3/0/hu/) | [Polskie](http://contributor-covenant.org/version/1/3/0/pl/) | [Português](http://contributor-covenant.org/version/1/3/0/pt/) | [Português do Brasil](http://contributor-covenant.org/version/1/3/0/pt_br/) As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at chaijs@keithcirkel.co.uk. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/3/0/ chaijs-chai-2a3ecff/CONTRIBUTING.md000066400000000000000000000236211505212005400166570ustar00rootroot00000000000000# Chai Contribution Guidelines We like to encourage you to contribute to the Chai.js repository. This should be as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request or open an issue. Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. #### Table of Contents - [TLDR;](#tldr) - [Contributing](#contributing) - [Bug Reports](#bugs) - [Feature Requests](#features) - [Pull Requests](#pull-requests) - [Releasing](#releasing) - [Support](#support) - [Resources](#resources) - [Core Contributors](#contributors) ## TLDR; - Creating an Issue or Pull Request requires a [GitHub](http://github.com) account. - Issue reports should be **clear**, **concise** and **reproducible**. Check to see if your issue has already been resolved in the [master]() branch or already reported in Chai's [GitHub Issue Tracker](https://github.com/chaijs/chai/issues). - Pull Requests must adhere to strict [coding style guidelines](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). - In general, avoid submitting PRs for new Assertions without asking core contributors first. More than likely it would be better implemented as a plugin. - Additional support is available via the [Google Group](http://groups.google.com/group/chaijs) or on irc.freenode.net#chaijs. - **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. ## Contributing The issue tracker is the preferred channel for [bug reports](#bugs), [feature requests](#features) and [submitting pull requests](#pull-requests), but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests (use [Google Group](https://groups.google.com/forum/#!forum/chaijs) or IRC). * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others ### Bug Reports A bug is a **demonstrable problem** that is caused by the code in the repository. Guidelines for bug reports: 1. **Use the GitHub issue search** — check if the issue has already been reported. 2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. 3. **Isolate the problem** — create a test case to demonstrate your issue. Provide either a repo, gist, or code sample to demonstrate you problem. A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and/or Node.js versions experience the problem? What would you expect to be the outcome? All these details will help people to fix any potential bugs. Example: > Short and descriptive example bug report title > > A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the steps required to reproduce the bug. > > 1. This is the first step > 2. This is the second step > 3. Further steps, etc. > > `` - a link to the reduced test case OR > ```js > expect(a).to.equal('a'); > // code sample > ``` > > Any other information you want to share that is relevant to the issue being reported. This might include the lines of code that you have identified as causing the bug, and potential solutions (and your opinions on their merits). ### Feature Requests Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. Furthermore, since Chai.js has a [robust plugin API](http://chaijs.com/guide/plugins/), we encourage you to publish **new Assertions** as plugins. If your feature is an enhancement to an **existing Assertion**, please propose your changes as an issue prior to opening a pull request. If the core Chai.js contributors feel your plugin would be better suited as a core assertion, they will invite you to open a PR in [chaijs/chai](https://github.com/chaijs/chai). ### Pull Requests - PRs for new core-assertions are advised against. - PRs for core-assertion bug fixes are always welcome. - PRs for enhancing the interfaces are always welcome. - PRs that increase test coverage are always welcome. - PRs are scrutinized for coding-style. Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. **Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. Please adhere to the coding conventions used throughout a project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). Please review the [Chai.js Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). Follow this process if you'd like your work considered for inclusion in the project: 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes: ```bash # Clone your fork of the repo into the current directory git clone https://github.com// # Navigate to the newly cloned directory cd # Assign the original repo to a remote called "upstream" git remote add upstream https://github.com// ``` 2. If you cloned a while ago, get the latest changes from upstream: ```bash git checkout git pull upstream ``` 3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: ```bash git checkout -b ``` 4. Commit your changes in logical chunks. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. 5. Run you code to make sure it works. If you're still having problems please try to run `make clean` and then test your code again. ```bash npm test # when finished running tests... git checkout chai.js ``` 6. Locally merge (or rebase) the upstream development branch into your topic branch: ```bash git pull [--rebase] upstream ``` 7. Push your topic branch up to your fork: ```bash git push origin ``` 8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description. **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. ## Releasing Releases can be **prepared** by anyone with access to the code. Simply run `make release-major`, `make release-minor`, or `make-release-patch` and it will automatically do the following: - Build chai.js - Bump the version numbers across the project - Make a commit within git All you need to do is push the commit up and make a pull request, one of the core contributors will merge it and publish a release. ### Publishing a Release Anyone who is a core contributor (see the [Core Contributors Heading in the Readme](https://github.com/chaijs/chai#core-contributors)) can publish a release: 1. Go to the [Releases page on Github](https://github.com/chaijs/chai/releases) 2. Hit "Draft a new release" (if you can't see this, you're not a core contributor!) 3. Write human-friendly Release Notes based on changelog. - The release title is "x.x.x / YYYY-MM-DD" (where x.x.x is the version number) - If breaking changes, write migration tutorial(s) and reasoning. - Callouts for community contributions (PRs) with links to PR and contributing user. - Callouts for other fixes made by core contributors with links to issue. 4. Hit "Save Draft" and get other core contributors to check your work, or alternatively hit "Publish release" 5. That's it! ## Support ### Resources For most of the documentation you are going to want to visit [ChaiJS.com](http://chaijs.com). - [Getting Started Guide](http://chaijs.com/guide/) - [API Reference](http://chaijs.com/api/) - [Plugins](http://chaijs.com/plugins/) Alternatively, the [wiki](https://github.com/chaijs/chai/wiki) might be what you are looking for. - [Chai Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide) - [Third-party Resources](https://github.com/chaijs/chai/wiki/Third-Party-Resources) Or finally, you may find a core-contributor or like-minded developer in any of our support channels. - IRC: irc.freenode.org #chaijs - [Mailing List / Google Group](https://groups.google.com/forum/#!forum/chaijs) ### Core Contributors Feel free to reach out to any of the core-contributors with you questions or concerns. We will do our best to respond in a timely manner. - Jake Luer - GH: [@logicalparadox](https://github.com/logicalparadox) - TW: [@jakeluer](http://twitter.com/jakeluer) - IRC: logicalparadox - Veselin Todorov - GH: [@vesln](https://github.com/vesln/) - TW: [@vesln](http://twitter.com/vesln) - IRC: vesln - Keith Cirkel - GH: [@keithamus](https://github.com/keithamus) - TW: [@keithamus](http://twitter.com/keithamus) - IRC: keithamus - Lucas Fernandes da Costa - GH: [@lucasfcosta](https://github.com/lucasfcosta) - TW: [@lfernandescosta](https://twitter.com/lfernandescosta) - IRC: lucasfcosta chaijs-chai-2a3ecff/History.md000066400000000000000000001113441505212005400164110ustar00rootroot00000000000000### Note As of 3.0.0, the History.md file has been deprecated. [Please refer to the full commit logs available on GitHub](https://github.com/chaijs/chai/commits). --- 2.3.0 / 2015-04-26 ================== * Merge pull request #423 from ehntoo/patch-1 * Merge pull request #422 from ljharb/fix_descriptor_tests * Fix a small bug in the .null assertion docs * Use a regex to account for property ordering issues across engines. * Add `make test-firefox` * Merge pull request #417 from astorije/astorije/minimalist-typo * Remove trailing whitespaces * Fix super minor typo in an example * Merge pull request #408 from ljharb/enumerableProperty * Add `ownPropertyDescriptor` assertion. 2.2.0 / 2015-03-26 ================== * Merge pull request #405 from chaijs/deep-escape-doc-tweaks * Tweak documentation on `.deep` flag. * Merge pull request #402 from umireon/escaping-dot-should-be-taken * Documentation of escaping in `.deep` flag. * take regular expression apart * Feature: backslash-escaping in `.deep.property` * Escaping dot should be taken in deep property 2.1.2 / 2015-03-15 ================== * Merge pull request #396 from chaijs/add-keith-cirkel-contributing-md * Add Keith Cirkel to CONTRIBUTING.md * Merge pull request #395 from cjqed/386-assert-operator-no-eval * No longer using eval on assert operator #386 * Merge pull request #389 from chaijs/update-git-summary * Update `git summary` in README 2.1.1 / 2015-03-04 ================== * Merge pull request #385 from eldritch-fossicker/master * updates to reflect code style preference from @keithamus * fix indexing into array with deep propery * Merge pull request #382 from astorije/patch-2 * Merge pull request #383 from gurdiga/config-doc-wording-improvement * config.truncateThreshold docs: simpler wording * Add missing docstring for showDiff argument of assert * Merge pull request #381 from astorije/patch-1 * Add a minor precision that empty asserts on strings too. * Merge pull request #379 from dcneiner/should-primitive-fix * Primitives now use valueOf in shouldGetter 2.1.0 / 2015-02-23 ================== * Merge pull request #374 from jmm/v2.0.1 * Increment version to 2.0.1. * Merge pull request #365 from chaijs/fix-travis * Fix travis.yml deploy * Merge pull request #356 from Soviut/master * documented fail methods for expect and should interfaces * fail method added directly to expect 2.0.0 / 2015-02-09 ================== * Merge pull request #361 from gregglind/b265-keys-object * fix #359. Add `.keys(object)` * Merge pull request #359 from gregglind/b359-unexpected-keys-sort * Fix #359 keys() sorts input unexpectedly * contrib: publish release strategy and travis npm creds #337 * Merge pull request #357 from danilovaz/master * Update copyright date * Merge pull request #349 from toastynerd/add-which-chain-method * add the which chain method as per issue #347 * Merge pull request #333 from cmpolis/change-assertions * more `by` cleanup * cleaned out `.by` for #333 * Merge pull request #335 from DingoEatingFuzz/expose-util * Expose chai util through the chai object * cleanup (per notes on pr #333) * updated `change` to work w/ non-number values + tests * Merge pull request #334 from hurrymaplelad/patch-1 * Typo, the flag is called 'contains' with an 's' * updated assertion interface with `change` (#330) * added `change`,`increase`,`decrease` assertions (#330) * assert tests for `change`,`increase`,`decrease` * expect/should tests for `change`,`increase`,`decrease` * Merge pull request #328 from lo1tuma/issue-327 * Add includes and contains alias (fixes #327) * Merge pull request #325 from chasenlehara/overwriteChainableMethodDocs * Fix docs for overwriteChainableMethod parameters * Merge pull request #317 from jasonkarns/patch-2 * Merge pull request #318 from jasonkarns/patch-3 * Merge pull request #316 from jasonkarns/patch-1 * typos in docs * minor docs typo * update docs: getAllFlags -> transferFlags * Merge pull request #313 from cjqed/254-expect-any-all * Added the all and any flags for keys assertion, with all being the default behavior * Merge pull request #312 from cjqed/291-assert-same-deep-members * Changed public comment of sameDeepMemebers to be more clear * Fixes issue #291, adds assert.sameDeepMembers * Merge pull request #311 from cjqed/305-above-below-on-assert * Merge pull request #308 from prodatakey/hasproperty * Issue #305 fixed, added assert.isAbove and assert.isBelow * Fix typo * More unit tests for new utility functions * Refactor common functionality, document, test * Refactor if statement out * Small unit test fix * Handle array indexing terminating paths * Merge pull request #309 from ericdouglas/iterableEqual-couting-once * couting variables just once * Fix properties with `undefined` value pass property assertion * Merge pull request #306 from chaijs/revert-297-noopchainfunc * Revert "Allows writing lint-friendly tests" 1.10.0 / 2014-11-10 ================== * Merge pull request #297 from prodatakey/noopchainfunc * Merge pull request #300 from julienw/299-fix-getMessage-test * Fix #299: the test is defining global variables * Add a couple more unit tests * Add unit tests for chained terminating property asserts * Revise documentation wording * Add docs for function style NOOP asserts * Make the NOOP function a shared constant * Merge pull request #298 from dasilvacontin/negativeZeroLogging * why not more assertions * added test for inspecting `-0` * a more readable/simple condition statement, as pointed out by @keithamus * added check for logging negative zero * Change test to not trigger argument bug * Allows writing lint-friendly tests * readme: update contributors for 1.9.2 1.9.2 / 2014-09-29 ================== * Merge pull request #268 from charlierudolph/cr-lazyMessages * Merge pull request #269 from charlierudolph/cr-codeCleanup * Merge pull request #277 from charlierudolph/fix-doc * Merge pull request #279 from mohayonao/fix-closeTo * Merge pull request #292 from boneskull/mocha * resolves #255: upgrade mocha * Merge pull request #289 from charlierudolph/cr-dryUpCode * Dry up code * Merge pull request #275 from DrRataplan/master * assert: .closeTo() verify value's type before assertion * Rewrite pretty-printing HTML elements to prevent throwing internal errors Fixes errors occuring when using a non-native DOM implementation * Fix assert documentation * Remove unused argument * Allow messages to be functions * Merge pull request #267 from shinnn/master * Use SVG badge * Merge pull request #264 from cjthompson/keys_diff * Show diff for keys assertion 1.9.1 / 2014-03-19 ================== * deps update * util: [getActual] select actual logic now allows undefined for actual. Closes #183 * docs: [config] make public, express param type * Merge pull request #251 from romario333/threshold3 * Fix issue #166 - configurable threshold in objDisplay. * Move configuration options to config.js. * Merge pull request #233 from Empeeric/master * Merge pull request #244 from leider/fix_for_contains * Merge pull request #247 from didoarellano/typo-fixes * Fix typos * Merge pull request #245 from lfac-pt/patch-1 * Update `exports.version` to 1.9.0 * aborting loop on finding * declaring variable only once * additional test finds incomplete implementation * simplified code * fixing #239 (without changing chai.js) * ssfi as it should be * Merge pull request #228 from duncanbeevers/deep_members * Deep equality check for collection membership 1.9.0 / 2014-01-29 ================== * docs: add contributing.md #238 * assert: .throws() returns thrown error. Closes #185 * Merge pull request #232 from laconbass/assert-throws * assert: .fail() parameter mismatch. Closes #206 * Merge branch 'karma-fixes' * Add karma phantomjs launcher * Use latest karma and sauce launcher * Karma tweaks * Merge pull request #230 from jkroso/include * Merge pull request #237 from chaijs/coverage * Add coverage to npmignore * Remove lib-cov from test-travisci dependents * Remove the not longer needed lcov reporter * Test coverage with istanbul * Remove jscoverage * Remove coveralls * Merge pull request #226 from duncanbeevers/add_has * Avoid error instantiation if possible on assert.throws * Merge pull request #231 from duncanbeevers/update_copyright_year * Update Copyright notices to 2014 * handle negation correctly * add failing test case * support `{a:1,b:2}.should.include({a:1})` * Merge pull request #224 from vbardales/master * Add `has` to language chains * Merge pull request #219 from demands/overwrite_chainable * return error on throw method to chain on error properties, possibly different from message * util: store chainable behavior in a __methods object on ctx * util: code style fix * util: add overwriteChainableMethod utility (for #215) * Merge pull request #217 from demands/test_cleanup * test: make it possible to run utilities tests with --watch * makefile: change location of karma-runner bin script * Merge pull request #202 from andreineculau/patch-2 * test: add tests for throwing custom errors * Merge pull request #201 from andreineculau/patch-1 * test: updated for the new assertion errors * core: improve message for assertion errors (throw assertion) 1.8.1 / 2013-10-10 ================== * pkg: update deep-eql version 1.8.0 / 2013-09-18 ================== * test: [sauce] add a few more browsers * Merge branch 'refactor/deep-equal' * util: remove embedded deep equal utility * util: replace embedded deep equal with external module * Merge branch 'feature/karma' * docs: add sauce badge to readme [ci skip] * test: [sauce] use karma@canary to prevent timeouts * travis: only run on node 0.10 * test: [karma] use karma phantomjs runner * Merge pull request #181 from tricknotes/fix-highlight * Fix highlight for example code 1.7.2 / 2013-06-27 ================== * coverage: add coveralls badge * test: [coveralls] add coveralls api integration. testing travis-ci integration * Merge branch 'master' of github.com:chaijs/chai * Merge branch 'feature/bower' * Merge pull request #180 from tricknotes/modify-method-title * Merge pull request #179 from tricknotes/highlight-code-example * Modify method title to include argument name * Fix to highlight code example * bower: granular ignores 1.7.1 / 2013-06-24 ================== * Merge branch 'feature/bower'. #175 * bower: add json file * build: browser 1.7.0 / 2013-06-17 ================== * error: remove internal assertion error constructor * core: [assertion-error] replace internal assertion error with dep * deps: add chaijs/assertion-error@1.0.0 * docs: fix typo in source file. #174 * Merge pull request #174 from piecioshka/master * typo * Merge branch 'master' of github.com:chaijs/chai * pkg: lock mocha/mocha-phantomjs versions (for now) * Merge pull request #173 from chaijs/inspect-fix * Fix `utils.inspect` with custom object-returning inspect()s. * Merge pull request #171 from Bartvds/master * replaced tabs with 2 spaces * added assert.notOk() * Merge pull request #169 from katsgeorgeek/topics/master * Fix comparison objects. 1.6.1 / 2013-06-05 ================== * Merge pull request #168 from katsgeorgeek/topics/master * Add test for different RegExp flags. * Add test for regexp comparison. * Downgrade mocha version for fix running Phantom tests. * Fix comparison equality of two regexps. * Merge pull request #161 from brandonpayton/master * Fix documented name for assert interfaces isDefined method 1.6.0 / 2013-04-29 ================== * build: browser * assert: [(not)include] throw on incompatible haystack. Closes #142 * assert: [notInclude] add assert.notInclude. Closes #158 * browser build * makefile: force browser build on browser-test * makefile: use component for browser build * core: [assertions] remove extraneous comments * Merge branch 'master' of github.com:chaijs/chai * test: [assert] deep equal ordering * Merge pull request #153 from NickHeiner/array-assertions * giving members a no-flag assertion * Code review comments - changing syntax * Code review comments * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148. * Merge pull request #140 from RubenVerborgh/function-prototype * Restore the `call` and `apply` methods of Function when adding a chainable method. * readme: 2013 * notes: migration notes for deep equal changes * test: for ever err() there must be a passing version 1.5.0 / 2013-02-03 ================== * docs: add Release Notes for non-gitlog summary of changes. * lib: update copyright to 2013 * Merge branch 'refactor/travis' * makefile: remove test-component for full test run * pkg: script test now runs make test so travis will test browser * browser: build * tests: refactor some tests to support new objDisplay output * test: [bootstrap] normalize boostrap across all test scenarios * assertions: refactor some assertions to use objDisplay instead of inspect * util: [objDisplay] normalize output of functions * makefile: refactor for full build scenarios * component: fix build bug where missing util:type file * assertions: [throw] code cleanup * Merge branch 'refactor/typeDetection' * browser: build * makefile: chai.js is .PHONY so it builds every time * test: [expect] add arguments type detection test * core/assertions: [type] (a/an) refactor to use type detection utility * util: add cross-browser type detection utility * Merge branch 'feature/component' * browser: build * component: add component.json file * makefile: refactor for fine grain control of testing scenarios * test: add mochaPhantomJS support and component test file * deps: add component and mocha-phantomjs for browser testing * ignore: update ignore files for component support * travis: run for all branches * Merge branch 'feature/showDiff' * test: [Assertion] configruable showDiff flag. Closes #132 * lib: [Assertion] add configurable showDiff flag. #132 * Merge branch 'feature/saucelabs' * Merge branch 'master' into feature/saucelabs * browser: build * support: add mocha cloud runner, client, and html test page * test: [saucelabs] add auth placeholder * deps: add mocha-cloud * Merge pull request #136 from whatthejeff/message_fix * Merge pull request #138 from timnew/master * Fix issue #137, test message existence by using message!=null rather than using message * Fixed backwards negation messages. * Merge pull request #133 from RubenVerborgh/throw * Functions throwing strings can reliably be tested. * Merge pull request #131 from RubenVerborgh/proto * Cache whether __proto__ is supported. * Use __proto__ if available. * Determine the property names to exclude beforehand. * Merge pull request #126 from RubenVerborgh/eqls * Add alias eqls for eql. * Use inherited enumerable properties in deep equality comparison. * Show inherited properties when inspecting an object. * Add new getProperties and getEnumerableProperties utils. * showDiff: force true for equal and eql 1.4.2 / 2012-12-21 ================== * browser build: (object diff support when used with mocha) #106 * test: [display] array test for mocha object diff * browser: no longer need different AssertionError constructor 1.4.1 / 2012-12-21 ================== * showDiff: force diff for equal and eql. #106 * test: [expect] type null. #122 * Merge pull request #115 from eshao/fix-assert-Throw * FIX: assert.Throw checks error type/message * TST: assert.Throw should check error type/message 1.4.0 / 2012-11-29 ================== * pre-release browser build * clean up index.js to not check for cov, revert package.json to use index.js * convert tests to use new bootstrap * refactor testing bootstrap * use spaces (not tabs). Clean up #114 * Merge pull request #114 from trantorLiu/master * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of". * Change `main` to ./lib/chai. Fixes #28. * Merge pull request #104 from connec/deep_equals_circular_references_ * Merge pull request #109 from nnarhinen/patch-1 * Check for 'actual' type * Added support for circular references when checking deep (in)equality. 1.3.0 / 2012-10-01 ================== * browser build w/ folio >= 0.3.4. Closes #99 * add back buffer test for deep equal * do not write flags to assertion.prototype * remove buffer test from expect * browser build * improve documentation of custom error messages * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master * browser build * improved buffer deep equal checking * mocha is npm test command * Cleaning up the js style… * expect tests now include message pass-through * packaging up browser-side changes… * Increasing Throws error message verbosity * Should syntax: piping message through * Make globalShould test work in browser too. * Add a setter for `Object.prototype.should`. Closes #86. 1.2.0 / 2012-08-07 ================== * Merge branch 'feature/errmsg' * browser build * comment updates for utilities * tweak objDislay to only kick in if object inspection is too long * Merge branch 'master' into feature/errmsg * add display sample for error message refactor * first draft of error message refactor. #93 * add `closeTo` assertion to `assert` interface. Closes #89. * update folio build for better require.js handling. Closes #85 * Merge pull request #92 from paulmillr/topics/add-dom-checks * Add check for DOM objects. * browser build * Merge branch 'master' of github.com:chaijs/chai * bug - getActual not defaulting to assertion subject * Merge pull request #88 from pwnall/master * Don't inspect() assertion arguments if the assertion passes. 1.1.1 / 2012-07-09 ================== * improve commonjs support on browser build * Merge pull request #83 from tkazec/equals * Document .equals * Add .equals as an alias of .equal * remove unused browser prefix/suffix * Merge branch 'feature/folio-build' * browser build * using folio to compile * clean up makefile * early folio 0.3.x support 1.1.0 / 2012-06-26 ================== * browser build * Disable "Assertion.includeStack is false" test in IE. * Use `utils.getName` for all function inspections. * Merge pull request #80 from kilianc/closeTo * fixes #79 * browser build * expand docs to indicate change of subject for chaining. Closes #78 * add `that` chain noop * Merge branch 'bug/74' * comments on how to property use `length` as chain. Closes #74 * tests for length as chainable property. #74 * add support for `length` as chainable prop/method. * Merge branch 'bug/77' * tests for getPathValue when working with nested arrays. Closes #77 * add getPathValue support for nested arrays * browser build * fix bug for missing browser utils * compile tool aware of new folder layout * Merge branch 'refactor/1dot1' * move core assertions to own file and refactor all using utils * rearrange folder structure 1.0.4 / 2012-06-03 ================== * Merge pull request #68 from fizker/itself * Added itself chain. * simplify error inspections for cross browser compatibility * fix safari `addChainableMethod` errors. Closes #69 1.0.3 / 2012-05-27 ================== * Point Travis badge to the right place. * Make error message for eql/deep.equal more clear. * Fix .not.deep.equal. * contributors list 1.0.2 / 2012-05-26 ================== * Merge pull request #67 from chaijs/chaining-and-flags * Browser build. * Use `addChainableMethod` to get away from `__proto__` manipulation. * New `addChainableMethod` utility. * Replace `getAllFlags` with `transferFlags` utility. * browser build * test - get all flags * utility - get all flags * Add .mailmap to .npmignore. * Add a .mailmap file to fix my name in shortlogs. 1.0.1 / 2012-05-18 ================== * browser build * Fixing "an" vs. "a" grammar in type assertions. * Uniformize `assert` interface inline docs. * Don't use `instanceof` for `assert.isArray`. * Add `deep` flag for equality and property value. * Merge pull request #64 from chaijs/assertion-docs * Uniformize assertion inline docs. * Add npm-debug.log to .gitignore. * no reserved words as actuals. #62 1.0.0 / 2012-05-15 ================== * readme cleanup * browser build * utility comments * removed docs * update to package.json * docs build * comments / docs updates * plugins app cleanup * Merge pull request #61 from joliss/doc * Fix and improve documentation of assert.equal and friends * browser build * doc checkpoint - texture * Update chai-jquery link * Use defined return value of Assertion extension functions * Update utility docs 1.0.0-rc3 / 2012-05-09 ================== * Merge branch 'feature/rc3' * docs update * browser build * assert test conformity for minor refactor api * assert minor refactor * update util tests for new add/overwrite prop/method format * added chai.Assertion.add/overwrite prop/method for plugin toolbox * add/overwrite prop/method don't make assumptions about context * doc test suite * docs don't need coverage * refactor all simple chains into one forEach loop, for clean documentation * updated npm ignore * remove old docs * docs checkpoint - guide styled * Merge pull request #59 from joliss/doc * Document how to run the test suite * don't need to rebuild docs to view * dep update * docs checkpoint - api section * comment updates for docs * new doc site checkpoint - plugin directory! * Merge pull request #57 from kossnocorp/patch-1 * Fix typo: devDependancies → devDependencies * Using message flag in `getMessage` util instead of old `msg` property. * Adding self to package.json contributors. * `getMessage` shouldn't choke on null/omitted messages. * `return this` not necessary in example. * `return this` not necessary in example. * Sinon–Chai has a dash * updated plugins list for docs 1.0.0-rc2 / 2012-05-06 ================== * Merge branch 'feature/test-cov' * browser build * missing assert tests for ownProperty * appropriate assert equivalent for expect.to.have.property(key, val) * reset AssertionError to include full stack * test for plugin utilities * overwrite Property and Method now ensure chain * version notes in readme 1.0.0-rc1 / 2012-05-04 ================== * browser build (rc1) * assert match/notMatch tests * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal * cleaner should interface export. * added chai.Assertion.prototype._obj (getter) for quick access to object flag * moved almostEqual / almostDeepEqual to stats plugin * added mocha.opts * Add test for `utils.addMethod` * Fix a typo * Add test for `utils.overwriteMethod` * Fix a typo * Browser build * Add undefined assertion * Add null assertion * Fix an issue with `mocha --watch` * travis no longer tests on node 0.4.x * removing unnecissary carbon dep * Merge branch 'feature/plugins-app' * docs build * templates for docs express app for plugin directory * express app for plugin and static serving * added web server deps * Merge pull request #54 from josher19/master * Remove old test.assert code * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual * browser build * Added almostEqual and deepAlmostEqual to assert test suite. * bug - context determinants for utils * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true * wrong travis link * readme updates for version information * travis tests 0.5.x branch as well * [bug] util `addProperty` not correctly exporting * read me version notes * browser build 1.0.0alpha1 * not using reserved words in internal assertions. #52 * version tick * clean up redundant tests * Merge branch 'refs/heads/0.6.x' * update version tag in package 1.0.0alpha1 * browser build * added utility tests to browser specs * beginning utility testing * updated utility comments * utility - overwriteMethod * utility - overwriteProperty * utility - addMethod * utility - addProperty * missing ; * contributors list update * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x * Added guide link to docs. WIP * Include/contain are now both properties and methods * Add an alias annotation * Remove usless function wrapper * Fix a typo * A/an are now both properties and methods * [docs] new site homepage layout / color checkpoint * Ignore IE-specific error properties. * Fixing order of error message test. * New cross-browser `getName` util. * Fixing up `AssertionError` inheritance. * backup docs * Add doctypes * [bug] was still using `constructor.name` in `throw` assertion * [bug] flag Object.create(null) instead of new Object * [test] browser build * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags * [refactor] remove Assertion.prototype.inspect for testable object inspection * [refactor] object to test is now stored in flag, with ssfi and custom message * [bug] flag util - don't return on `set` * [docs] comments for getMessage utility * [feature] getMessage * [feature] testing utilities * [refactor] flag doesn't require `call` * Make order of source files well-defined * Added support for throw(errorInstance). * Use a foolproof method of grabbing an error's name. * Removed constructor.name check from throw. * disabled stackTrack configuration tests until api is stable again * first version of line displayed error for node js (unstable) * refactor core Assertion to use flag utility for negation * added flag utility * tests for assert interface negatives. Closed #42 * added assertion negatives that were missing. #42 * Support for expected and actual parameters in assert-style error object * chai as promised - readme * Added assert.fail. Closes #40 * better error message for assert.operator. Closes #39 * [refactor] Assertion#property to use getPathValue property * added getPathValue utility helper * removed todo about browser build * version notes * version bumb 0.6.0 * browser build * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')' * [feature] browser uses different error.js * [refactor] error without chai.fail * Assertion & interfaces use new utils helper export * [refactor] primary export for new plugin util usage * added util index.js helper * added 2012 to copyright headers * Added DeepEqual assertions 0.5.3 / 2012-04-21 ================== * Merge branch 'refs/heads/jgonera-oldbrowsers' * browser build * fixed reserved names for old browsers in interface/assert * fixed reserved names for old browsers in interface/should * fixed: chai.js no longer contains fail() * fixed reserved names for old browsers in Assertion * Merge pull request #49 from joliss/build-order * Make order of source files well-defined * Merge pull request #43 from zzen/patch-1 * Support for expected and actual parameters in assert-style error object * chai as promised - readme 0.5.2 / 2012-03-21 ================== * browser build * Merge branch 'feature/assert-fail' * Added assert.fail. Closes #40 * Merge branch 'bug/operator-msg' * better error message for assert.operator. Closes #39 * version notes 0.5.1 / 2012-03-14 ================== * chai.fail no longer exists * Merge branch 'feature/assertdefined' * Added asset#isDefined. Closes #37. * dev docs update for Assertion#assert 0.5.0 / 2012-03-07 ================== * [bug] on inspect of reg on n 0.4.12 * Merge branch 'bug/33-throws' * Merge pull request #35 from logicalparadox/empty-object * browser build * updated #throw docs * Assertion#throw `should` tests updated * Assertion#throw `expect` tests * Should interface supports multiple throw parameters * Update Assertion#throw to support strings and type checks. * Add more tests for `empty` in `should`. * Add more tests for `empty` in `expect`. * Merge branch 'master' into empty-object * don't switch act/exp * Merge pull request #34 from logicalparadox/assert-operator * Update the compiled verison. * Add `assert.operator`. * Notes on messages. #22 * browser build * have been test * below tests * Merge branch 'feature/actexp' * browser build * remove unnecessary fail export * full support for actual/expected where relevant * Assertion.assert support expected value * clean up error * Update the compiled version. * Add object & sane arguments support to `Assertion#empty`. 0.4.2 / 2012-02-28 ================== * fix for `process` not available in browser when used via browserify. Closes #28 * Merge pull request #31 from joliss/doc * Document that "should" works in browsers other than IE * Merge pull request #30 from logicalparadox/assert-tests * Update the browser version of chai. * Update `assert.doesNotThrow` test in order to check the use case when type is a string. * Add test for `assert.ifError`. * Falsey -> falsy. * Full coverage for `assert.throws` and `assert.doesNotThrow`. * Add test for `assert.doesNotThrow`. * Add test for `assert.throws`. * Add test for `assert.length`. * Add test for `assert.include`. * Add test for `assert.isBoolean`. * Fix the implementation of `assert.isNumber`. * Add test for `assert.isNumber`. * Add test for `assert.isString`. * Add test for `assert.isArray`. * Add test for `assert.isUndefined`. * Add test for `assert.isNotNull`. * Fix `assert.isNotNull` implementation. * Fix `assert.isNull` implementation. * Add test for `assert.isNull`. * Add test for `assert.notDeepEqual`. * Add test for `assert.deepEqual`. * Add test for `assert.notStrictEqual`. * Add test for `assert.strictEqual`. * Add test for `assert.notEqual`. 0.4.1 / 2012-02-26 ================== * Merge pull request #27 from logicalparadox/type-fix * Update the browser version. * Add should tests for type checks. * Add function type check test. * Add more type checks tests. * Add test for `new Number` type check. * Fix type of actual checks. 0.4.0 / 2012-02-25 ================== * docs and readme for upcoming 0.4.0 * docs generated * putting coverage and tests for docs in docs/out/support * make docs * makefile copy necessary resources for tests in docs * rename configuration test * Merge pull request #21 from logicalparadox/close-to * Update the browser version. * Update `closeTo()` docs. * Add `Assertion.closeTo()` method. * Add `.closeTo()` should test. * Add `.closeTo()` expect test. * Merge pull request #20 from logicalparadox/satisfy * Update the browser version. * `..` -> `()` in `.satisfy()` should test. * Update example for `.satisfy()`. * Update the compiled browser version. * Add `Assertion.satisfy()` method. * Add `.satisfy()` should test. * Add `.satisfy()` expect test. * Merge pull request #19 from logicalparadox/respond-to * Update the compiled browser version. * Add `respondTo` Assertion. * Add `respondTo` should test. * Add `respondTo` expect test. * Merge branch 'feature/coverage' * mocha coverage support * doc contributors * README contributors 0.3.4 / 2012-02-23 ================== * inline comment typos for #15 * Merge branch 'refs/heads/jeffbski-configErrorStackCompat' * includeStack documentation for all interfaces * suite name more generic * Update test to be compatible with browsers that do not support err.stack * udpated compiled chai.js and added to browser tests * Allow inclusion of stack trace for Assert error messages to be configurable * docs sharing buttons * sinon-chai link * doc updates * read me updates include plugins 0.3.3 / 2012-02-12 ================== * Merge pull request #14 from jfirebaugh/configurable_properties * Make Assertion.prototype properties configurable 0.3.2 / 2012-02-10 ================== * codex version * docs * docs cleanup 0.3.1 / 2012-02-07 ================== * node 0.4.x compat 0.3.0 / 2012-02-07 ================== * Merge branch 'feature/03x' * browser build * remove html/json/headers testign * regex error.message testing * tests for using plugins * Merge pull request #11 from domenic/master * Make `chai.use` a no-op if the function has already been used. 0.2.4 / 2012-02-02 ================== * added in past tense switch for `been` 0.2.3 / 2012-02-01 ================== * try that again 0.2.2 / 2012-02-01 ================== * added `been` (past of `be`) alias 0.2.1 / 2012-01-29 ================== * added Throw, with a capital T, as an alias to `throw` (#7) 0.2.0 / 2012-01-26 ================== * update gitignore for vim *.swp * Merge branch 'feature/plugins' * browser build * interfaces now work with use * simple .use function. See #9. * readme notice on browser compat 0.1.7 / 2012-01-25 ================== * added assert tests to browser test runner * browser update * `should` interface patch for primitives support in FF * fix isObject() Thanks @milewise * travis only on branch `master` * add instanceof alias `instanceOf`. #6 * some tests for assert module 0.1.6 / 2012-01-02 ================== * commenting for assert interface * updated codex dep 0.1.5 / 2012-01-02 ================== * browser tests pass * type in should.not.equal * test for should (not) exist * added should.exist and should.not.exist * browser uses tdd * convert tests to tdd 0.1.4 / 2011-12-26 ================== * browser lib update for new assert interface compatiblitiy * inspect typos * added strict equal + negatives and ifError * interface assert had doesNotThrow * added should tests to browser * new expect empty tests * should test browser compat * Fix typo for instanceof docs. Closes #3 [ci skip] 0.1.3 / 2011-12-18 ================== * much cleaner reporting string on error. 0.1.2 / 2011-12-18 ================== * [docs] for upcoming 0.1.2 * browser version built with pre/suffix … all tests passing * make / compile now use prefix/suffix correctly * code clean * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods. * Merge branch 'feature/should4xcompatibility' * compile for browser tests.. all pass * added header/status/html/json * throw tests * should.throw & should.not.throw shortcuts * improved `throw` type detection and messaging * contain is now `include` … keys modifier is now `contain` * removed object() test * removed #respondTo * Merge branch 'bug/2' * replaced __defineGetter__ with defineProperty for all uses * [docs] change mp tracking code * docs site updated with assert (TDD) interface * updated doc comments for assert interface 0.1.1 / 2011-12-16 ================== * docs ready for upcoming 0.1.1 * readme image fixed [ci skip] * more readme tweaks [ci skip] * réadmet image fixed [ci skip] * documentation * codex locked in version 0.0.5 * more comments to assertions for docs * assertions fully commented, browser library updated * adding codex as doc dependancy * prepping for docs * assertion component completely commented for documentation * added exist test * var expect outside of browser if check * added keywords to package.json 0.1.0 / 2011-12-15 ================== * failing on purpose successful .. back to normal * testing travis failure * assert#arguments getter * readme typo * updated README * added travis and npmignore * copyright notices … think i got them all * moved expect interface to own file for consistency * assert ui deepEqual * browser tests expect (all working) * browser version built * chai.fail (should ui) * expect tests browser compatible * tests for should and expect (all pass) * moved fail to primary export * should compatibility testing * within, greaterThan, object, keys, * Aliases * Assertion#property now correctly works with negate and undefined values * error message language matches should * Assertion#respondTo * Assertion now uses inspect util * git ignore node modules * should is exported * AssertionError __proto__ from Error.prototype * add should interface for should.js compatibility * moved eql to until folder and added inspect from (joyent/node) * added mocha for testing * browser build for current api * multiple .property assertions * added deep equal from node 0.0.2 / 2011-12-07 ================== * cleaner output on error * improved exists detection * package remnant artifact * empty deep equal * test browser build * assertion cleanup * client compile script * makefile * most of the basic assertions * allow no parameters to assertion error * name change * assertion error instance * main exports: assert() & expect() * initialize chaijs-chai-2a3ecff/LICENSE000066400000000000000000000020721505212005400154300ustar00rootroot00000000000000MIT License Copyright (c) 2017 Chai.js Assertion Library Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. chaijs-chai-2a3ecff/README.md000066400000000000000000000140761505212005400157110ustar00rootroot00000000000000

ChaiJS
chai

Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

downloads:? node:?
Join the Slack chat Join the Gitter chat OpenCollective Backers

For more information or to download plugins, view the [documentation](http://chaijs.com). ## What is Chai? Chai is an _assertion library_, similar to Node's built-in `assert`. It makes testing much easier by giving you lots of assertions you can run against your code. ## Installation ### Node.js `chai` is available on [npm](http://npmjs.org). To install it, type: $ npm install --save-dev chai ### Browsers You can also use it within the browser; install via npm and use the `chai.js` file found within the download. For example: ```html ``` ## Usage Import the library in your code, and then pick one of the styles you'd like to use - either `assert`, `expect` or `should`: ```js import { assert } from 'chai'; // Using Assert style import { expect } from 'chai'; // Using Expect style import { should } from 'chai'; // Using Should style ``` ### Register the chai testing style globally ```js import 'chai/register-assert'; // Using Assert style import 'chai/register-expect'; // Using Expect style import 'chai/register-should'; // Using Should style ``` ### Import assertion styles as local variables ```js import { assert } from 'chai'; // Using Assert style import { expect } from 'chai'; // Using Expect style import { should } from 'chai'; // Using Should style should(); // Modifies `Object.prototype` import { expect, use } from 'chai'; // Creates local variables `expect` and `use`; useful for plugin use ``` ### Usage with Mocha ```bash mocha spec.js --require chai/register-assert.js # Using Assert style mocha spec.js --require chai/register-expect.js # Using Expect style mocha spec.js --require chai/register-should.js # Using Should style ``` [Read more about these styles in our docs](http://chaijs.com/guide/styles/). ## Plugins Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces. - Need a plugin? View the [official plugin list](http://chaijs.com/plugins). - Want to build a plugin? Read the [plugin api documentation](http://chaijs.com/guide/plugins/). - Have a plugin and want it listed? Simply add the following keywords to your package.json: - `chai-plugin` - `browser` if your plugin works in the browser as well as Node.js - `browser-only` if your plugin does not work with Node.js ### Related Projects - [chaijs / chai-docs](https://github.com/chaijs/chai-docs): The chaijs.com website source code. - [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. - [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. - [chaijs / check-error](https://github.com/chaijs/check-error): Error comparison and information related utility for Node.js and the browser. - [chaijs / loupe](https://github.com/chaijs/loupe): Inspect utility for Node.js and browsers. - [chaijs / pathval](https://github.com/chaijs/pathval): Object value retrieval given a string path. ### Contributing Thank you very much for considering to contribute! Please make sure you follow our [Code Of Conduct](https://github.com/chaijs/chai/blob/master/CODE_OF_CONDUCT.md) and we also strongly recommend reading our [Contributing Guide](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md). Here are a few issues other contributors frequently ran into when opening pull requests: - Please do not commit changes to the `chai.js` build. We do it once per release. - Before pushing your commits, please make sure you [rebase](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md#pull-requests) them. ### Contributors Please see the full [Contributors Graph](https://github.com/chaijs/chai/graphs/contributors) for our list of contributors. ### Core Contributors Feel free to reach out to any of the core contributors with your questions or concerns. We will do our best to respond in a timely manner. [![Keith Cirkel](https://avatars3.githubusercontent.com/u/118266?v=3&s=50)](https://github.com/keithamus) [![James Garbutt](https://avatars3.githubusercontent.com/u/5677153?v=3&s=50)](https://github.com/43081j) [![Kristján Oddsson](https://avatars3.githubusercontent.com/u/318208?v=3&s=50)](https://github.com/koddsson) ### Core Contributor Alumni This project would not be what it is without the contributions from our prior core contributors, for whom we are forever grateful: [![Jake Luer](https://avatars3.githubusercontent.com/u/58988?v=3&s=50)](https://github.com/logicalparadox) [![Veselin Todorov](https://avatars3.githubusercontent.com/u/330048?v=3&s=50)](https://github.com/vesln) [![Lucas Fernandes da Costa](https://avatars3.githubusercontent.com/u/6868147?v=3&s=50)](https://github.com/lucasfcosta) [![Grant Snodgrass](https://avatars3.githubusercontent.com/u/17260989?v=3&s=50)](https://github.com/meeber) chaijs-chai-2a3ecff/ReleaseNotes.md000066400000000000000000000725101505212005400173420ustar00rootroot00000000000000# Release Notes ## Note As of 3.0.0, the ReleaseNotes.md file has been deprecated. [Please refer to the release notes available on Github](https://github.com/chaijs/chai/releases). Or [the release notes on the chaijs.com website](https://chaijs.com/releases). --- ## 2.3.0 / 2015-04-26 Added `ownPropertyDescriptor` assertion: ```js expect('test').to.have.ownPropertyDescriptor('length'); expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); expect('test').ownPropertyDescriptor('length').to.have.keys('value'); ``` ### Community Contributions #### Code Features & Fixes * [#408](https://github.com/chaijs/chai/pull/408) Add `ownPropertyDescriptor` assertion. By [@ljharb](https://github.com/ljharb) * [#422](https://github.com/chaijs/chai/pull/422) Improve ownPropertyDescriptor tests. By [@ljharb](https://github.com/ljharb) #### Documentation fixes * [#417](https://github.com/chaijs/chai/pull/417) Fix documentation typo By [@astorije](https://github.com/astorije) * [#423](https://github.com/chaijs/chai/pull/423) Fix inconsistency in docs. By [@ehntoo](https://github.com/ehntoo) ## 2.2.0 / 2015-03-26 Deep property strings can now be escaped using `\\` - for example: ```js var deepCss = { '.link': { '[target]': 42 }}; expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42) ``` ### Community Contributions #### Code Features & Fixes * [#402](https://github.com/chaijs/chai/pull/402) Allow escaping of deep property keys. By [@umireon](https://github.com/umireon) #### Documentation fixes * [#405](https://github.com/chaijs/chai/pull/405) Tweak documentation around deep property escaping. By [@keithamus](https://github.com/keithamus) ## 2.1.2 / 2015-03-15 A minor bug fix. No new features. ### Community Contributions #### Code Features & Fixes * [#395](https://github.com/chaijs/chai/pull/395) Fix eval-related bugs with assert.operator ([#386](https://github.com/chaijs/chai/pull/386)). By [@cjqed](https://github.com/cjqed) ## 2.1.1 / 2015-03-04 Two minor bugfixes. No new features. ### Community Contributions #### Code Features & Fixes * [#385](https://github.com/chaijs/chai/pull/385) Fix a bug (also described in [#387](https://github.com/chaijs/chai/pull/385)) where `deep.property` would not work with single key names. By [@eldritch-fossicker](https://github.com/eldritch-fossicker) * [#379](https://github.com/chaijs/chai/pull/379) Fix bug where tools which overwrite primitive prototypes, such as Babel or core-js would fail. By [@dcneiner](https://github.com/dcneiner) #### Documentation fixes * [#382](https://github.com/chaijs/chai/pull/382) Add doc for showDiff argument in assert. By [@astorije](https://github.com/astorije) * [#383](https://github.com/chaijs/chai/pull/383) Improve wording for truncateTreshold docs By [@gurdiga](https://github.com/gurdiga) * [#381](https://github.com/chaijs/chai/pull/381) Improve wording for assert.empty docs By [@astorije](https://github.com/astorije) ## 2.1.0 / 2015-02-23 Small release; fixes an issue where the Chai lib was incorrectly reporting the version number. Adds new `should.fail()` and `expect.fail()` methods, which are convinience methods to throw Assertion Errors. ### Community Contributions #### Code Features & Fixes * [#356](https://github.com/chaijs/chai/pull/356) Add should.fail(), expect.fail(). By [@Soviut](https://github.com/Soviut) * [#374](https://github.com/chaijs/chai/pull/374) Increment version. By [@jmm](https://github.com/jmm) ## 2.0.0 / 2015-02-09 Unfortunately with 1.10.0 - compatibility broke with older versions because of the `addChainableNoop`. This change has been reverted. Any plugins using `addChainableNoop` should cease to do so. Any developers wishing for this behaviour can use [dirty-chai](https://www.npmjs.com/package/dirty-chai) by [@joshperry](https://github.com/joshperry) ### Community Contributions #### Code Features & Fixes * [#361](https://github.com/chaijs/chai/pull/361) `.keys()` now accepts Objects, extracting keys from them. By [@gregglind](https://github.com/gregglind) * [#359](https://github.com/chaijs/chai/pull/359) `.keys()` no longer mutates passed arrays. By [@gregglind](https://github.com/gregglind) * [#349](https://github.com/chaijs/chai/pull/349) Add a new chainable keyword - `.which`. By [@toastynerd](https://github.com/toastynerd) * [#333](https://github.com/chaijs/chai/pull/333) Add `.change`, `.increase` and `.decrease` assertions. By [@cmpolis](https://github.com/cmpolis) * [#335](https://github.com/chaijs/chai/pull/335) `chai.util` is now exposed [@DingoEatingFuzz](https://github.com/DingoEatingFuzz) * [#328](https://github.com/chaijs/chai/pull/328) Add `.includes` and `.contains` aliases (for `.include` and `.contain`). By [@lo1tuma](https://github.com/lo1tuma) * [#313](https://github.com/chaijs/chai/pull/313) Add `.any.keys()` and `.all.keys()` qualifiers. By [@cjqed](https://github.com/cjqed) * [#312](https://github.com/chaijs/chai/pull/312) Add `assert.sameDeepMembers()`. By [@cjqed](https://github.com/cjqed) * [#311](https://github.com/chaijs/chai/pull/311) Add `assert.isAbove()` and `assert.isBelow()`. By [@cjqed](https://github.com/cjqed) * [#308](https://github.com/chaijs/chai/pull/308) `property` and `deep.property` now pass if a value is set to `undefined`. By [@prodatakey](https://github.com/prodatakey) * [#309](https://github.com/chaijs/chai/pull/309) optimize deep equal in Arrays. By [@ericdouglas](https://github.com/ericdouglas) * [#306](https://github.com/chaijs/chai/pull/306) revert #297 - allowing lint-friendly tests. By [@keithamus](https://github.com/keithamus) #### Documentation fixes * [#357](https://github.com/chaijs/chai/pull/357) Copyright year updated in docs. By [@danilovaz](https://github.com/danilovaz) * [#325](https://github.com/chaijs/chai/pull/325) Fix documentation for overwriteChainableMethod. By [@chasenlehara](https://github.com/chasenlehara) * [#334](https://github.com/chaijs/chai/pull/334) Typo fix. By [@hurrymaplelad](https://github.com/hurrymaplelad) * [#317](https://github.com/chaijs/chai/pull/317) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) * [#318](https://github.com/chaijs/chai/pull/318) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) * [#316](https://github.com/chaijs/chai/pull/316) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) ## 1.10.0 / 2014-11-10 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required - **Plugin Developers:** - Review `addChainableNoop` notes below. - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Noop Function for Terminating Assertion Properties The following assertions can now also be used in the function-call form: * ok * true * false * null * undefined * exist * empty * arguments * Arguments The above list of assertions are property getters that assert immediately on access. Because of that, they were written to be used by terminating the assertion chain with a property access. ```js expect(true).to.be.true; foo.should.be.ok; ``` This syntax is definitely aesthetically pleasing but, if you are linting your test code, your linter will complain with an error something like "Expected an assignment or function call and instead saw an expression." Since the linter doesn't know about the property getter it assumes this line has no side-effects, and throws a warning in case you made a mistake. Squelching these errors is not a good solution as test code is getting to be just as important as, if not more than, production code. Catching syntactical errors in tests using static analysis is a great tool to help make sure that your tests are well-defined and free of typos. A better option was to provide a function-call form for these assertions so that the code's intent is more clear and the linters stop complaining about something looking off. This form is added in addition to the existing property access form and does not impact existing test code. ```js expect(true).to.be.true(); foo.should.be.ok(); ``` These forms can also be mixed in any way, these are all functionally identical: ```js expect(true).to.be.true.and.not.false(); expect(true).to.be.true().and.not.false; expect(true).to.be.true.and.not.false; ``` #### Plugin Authors If you would like to provide this function-call form for your terminating assertion properties, there is a new function to register these types of asserts. Instead of using `addProperty` to register terminating assertions, simply use `addChainableNoop` instead; the arguments to both are identical. The latter will make the assertion available in both the attribute and function-call forms and should have no impact on existing users of your plugin. ### Community Contributions - [#297](https://github.com/chaijs/chai/pull/297) Allow writing lint-friendly tests. [@joshperry](https://github.com/joshperry) - [#298](https://github.com/chaijs/chai/pull/298) Add check for logging `-0`. [@dasilvacontin](https://github.com/dasilvacontin) - [#300](https://github.com/chaijs/chai/pull/300) Fix #299: the test is defining global variables [@julienw](https://github.com/julienw) Thank you to all who took time to contribute! ## 1.9.2 / 2014-09-29 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Community Contributions - [#264](https://github.com/chaijs/chai/pull/264) Show diff for keys assertions [@cjthompson](https://github.com/cjthompson) - [#267](https://github.com/chaijs/chai/pull/267) Use SVG badges [@shinnn](https://github.com/shinnn) - [#268](https://github.com/chaijs/chai/pull/268) Allow messages to be functions (sinon-compat) [@charlierudolph](https://github.com/charlierudolph) - [#269](https://github.com/chaijs/chai/pull/269) Remove unused argument for #lengthOf [@charlierudolph](https://github.com/charlierudolph) - [#275](https://github.com/chaijs/chai/pull/275) Rewrite pretty-printing HTML elements to prevent throwing internal errors [@DrRataplan](https://github.com/DrRataplan) - [#277](https://github.com/chaijs/chai/pull/277) Fix assert documentation for #sameMembers [@charlierudolph](https://github.com/charlierudolph) - [#279](https://github.com/chaijs/chai/pull/279) closeTo should check value's type before assertion [@mohayonao](https://github.com/mohayonao) - [#289](https://github.com/chaijs/chai/pull/289) satisfy is called twice [@charlierudolph](https://github.com/charlierudolph) - [#292](https://github.com/chaijs/chai/pull/292) resolve conflicts with node-webkit and global usage [@boneskull](https://github.com/boneskull) Thank you to all who took time to contribute! ## 1.9.1 / 2014-03-19 The following changes are required if you are upgrading from the previous version: - **Users:** - Migrate configuration options to new interface. (see notes) - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Configuration There have been requests for changes and additions to the configuration mechanisms and their impact in the Chai architecture. As such, we have decoupled the configuration from the `Assertion` constructor. This not only allows for centralized configuration, but will allow us to shift the responsibility from the `Assertion` constructor to the `assert` interface in future releases. These changes have been implemented in a non-breaking way, but a depretiation warning will be presented to users until they migrate. The old config method will be removed in either `v1.11.0` or `v2.0.0`, whichever comes first. #### Quick Migration ```js // change this: chai.Assertion.includeStack = true; chai.Assertion.showDiff = false; // ... to this: chai.config.includeStack = true; chai.config.showDiff = false; ``` #### All Config Options ##### config.includeStack - **@param** _{Boolean}_ - **@default** `false` User configurable property, influences whether stack trace is included in Assertion error message. Default of `false` suppresses stack trace in the error message. ##### config.showDiff - **@param** _{Boolean}_ - **@default** `true` User configurable property, influences whether or not the `showDiff` flag should be included in the thrown AssertionErrors. `false` will always be `false`; `true` will be true when the assertion has requested a diff be shown. ##### config.truncateThreshold **(NEW)** - **@param** _{Number}_ - **@default** `40` User configurable property, sets length threshold for actual and expected values in assertion errors. If this threshold is exceeded, the value is truncated. Set it to zero if you want to disable truncating altogether. ```js chai.config.truncateThreshold = 0; // disable truncating ``` ### Community Contributions - [#228](https://github.com/chaijs/chai/pull/228) Deep equality check for memebers. [@duncanbeevers](https://github.com/duncanbeevers) - [#247](https://github.com/chaijs/chai/pull/247) Proofreading. [@didorellano](https://github.com/didoarellano) - [#244](https://github.com/chaijs/chai/pull/244) Fix `contain`/`include` 1.9.0 regression. [@leider](https://github.com/leider) - [#233](https://github.com/chaijs/chai/pull/233) Improvements to `ssfi` for `assert` interface. [@refack](https://github.com/refack) - [#251](https://github.com/chaijs/chai/pull/251) New config option: object display threshold. [@romario333](https://github.com/romario333) Thank you to all who took time to contribute! ### Other Bug Fixes - [#183](https://github.com/chaijs/chai/issues/183) Allow `undefined` for actual. (internal api) - Update Karam(+plugins)/Istanbul to most recent versions. ## 1.9.0 / 2014-01-29 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required - **Plugin Developers:** - Review [#219](https://github.com/chaijs/chai/pull/219). - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Community Contributions - [#202](https://github.com/chaijs/chai/pull/201) Improve error message for .throw(). [@andreineculau](https://github.com/andreineculau) - [#217](https://github.com/chaijs/chai/pull/217) Chai tests can be run with `--watch`. [@demands](https://github.com/demands) - [#219](https://github.com/chaijs/chai/pull/219) Add overwriteChainableMethod utility. [@demands](https://github.com/demands) - [#224](https://github.com/chaijs/chai/pull/224) Return error on throw method to chain on error properties. [@vbardales](https://github.com/vbardales) - [#226](https://github.com/chaijs/chai/pull/226) Add `has` to language chains. [@duncanbeevers](https://github.com/duncanbeevers) - [#230](https://github.com/chaijs/chai/pull/230) Support `{a:1,b:2}.should.include({a:1})` [@jkroso](https://github.com/jkroso) - [#231](https://github.com/chaijs/chai/pull/231) Update Copyright notices to 2014 [@duncanbeevers](https://github.com/duncanbeevers) - [#232](https://github.com/chaijs/chai/pull/232) Avoid error instantiation if possible on assert.throws. [@laconbass](https://github.com/laconbass) Thank you to all who took time to contribute! ### Other Bug Fixes - [#225](https://github.com/chaijs/chai/pull/225) Improved AMD wrapper provided by upstream `component(1)`. - [#185](https://github.com/chaijs/chai/issues/185) `assert.throws()` returns thrown error for further assertions. - [#237](https://github.com/chaijs/chai/pull/237) Remove coveralls/jscoverage, include istanbul coverage report in travis test. - Update Karma and Sauce runner versions for consistent CI results. No more karma@canary. ## 1.8.1 / 2013-10-10 The following changes are required if you are upgrading from the previous version: - **Users:** - Refresh `node_modules` folder for updated dependencies. - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Browserify This is a small patch that updates the dependency tree so browserify users can install chai. (Remove conditional requires) ## 1.8.0 / 2013-09-18 The following changes are required if you are upgrading from the previous version: - **Users:** - See `deep.equal` notes. - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Deep Equals This version of Chai focused on a overhaul to the deep equal utility. The code for this tool has been removed from the core lib and can now be found at: [chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases, this is part of a larger initiative to provide transparency, independent testing, and coverage for some of the more complicated internal tools. For the most part `.deep.equal` will behave the same as it has. However, in order to provide a consistent ruleset across all types being tested, the following changes have been made and _might_ require changes to your tests. **1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). _Previously:_ Non-traversable equal via `===`. ```js expect(NaN).to.deep.equal(NaN); expect(-0).to.not.deep.equal(+0); ``` **2.** Arguments are not Arrays (and all types must be equal): _Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates. ```js expect(arguments).to.not.deep.equal([]); expect(Array.prototype.slice.call(arguments)).to.deep.equal([]); ``` - [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array - [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object - [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility ### CI and Browser Testing Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at [SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands... and we get a cool badge: [![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox) Look for the list of browsers/versions to expand over the coming releases. - [#195](https://github.com/chaijs/chai/issues/195) karma test framework ## 1.7.2 / 2013-06-27 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required. - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Coverage Reporting Coverage reporting has always been available for core-developers but the data has never been published for our end users. In our ongoing effort to improve accountability this data will now be published via the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI. ### Other Fixes - [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all) ## 1.7.1 / 2013-06-24 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required. - **Plugin Developers:** - No changes required - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### Official Bower Support Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though Chai could be installed via Bower in the past, this update adds official support via the `bower.json` specification file. - [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. ## 1.7.0 / 2013-06-17 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required. - **Plugin Developers:** - Review AssertionError update notice. - **Core Contributors:** - Refresh `node_modules` folder for updated dependencies. ### AssertionError Update Notice Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal constructor. This will allow for further iteration/experimentation of the AssertionError constructor independant of Chai. Future plans include stack parsing for callsite support. This update constructor has a different constructor param signature that conforms more with the standard `Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin with the new signature. ```js var AssertionError = require('chai').AssertionError; /** * previous * * @param {Object} options */ throw new AssertionError({ message: 'An assertion error occurred' , actual: actual , expect: expect , startStackFunction: arguments.callee , showStack: true }); /** * new * * @param {String} message * @param {Object} options * @param {Function} start stack function */ throw new AssertionError('An assertion error occurred', { actual: actual , expect: expect , showStack: true }, arguments.callee); // other signatures throw new AssertionError('An assertion error occurred'); throw new AssertionError('An assertion error occurred', null, arguments.callee); ``` #### External Dependencies This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing there is an higher need for accountability and documentation. External dependencies will allow us to iterate and test on features independent from our interfaces. Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai. ### Community Contributions - [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek) - [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds) - [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic) Thank you to all who took the time to contribute! ## 1.6.1 / 2013-06-05 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required. - **Plugin Developers:** - No changes required. - **Core Contributors:** - Refresh `node_modules` folder for updated developement dependencies. ### Deep Equality Regular Expressions are now tested as part of all deep equality assertions. In previous versions they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution. ### Community Contributions - [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton) - [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek) Thank you to all who took the time to contribute! ### Additional Notes - Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility. ## 1.6.0 / 2013-04-29 The following changes are required if you are upgrading from the previous version: - **Users:** - No changes required. - **Plugin Developers:** - No changes required. - **Core Contributors:** - Refresh `node_modules` folder for updated developement dependencies. ### New Assertions #### Array Members Inclusion Asserts that the target is a superset of `set`, or that the target and `set` have the same members. Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution. ```js // (expect/should) full set expect([4, 2]).to.have.members([2, 4]); expect([5, 2]).to.not.have.members([5, 2, 1]); // (expect/should) inclusion expect([1, 2, 3]).to.include.members([3, 2]); expect([1, 2, 3]).to.not.include.members([3, 2, 8]); // (assert) full set assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); // (assert) inclusion assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); ``` #### Non-inclusion for Assert Interface Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`. However `include()` did not have a corresponding `notInclude()`. This has been added. ```js assert.notInclude([ 1, 2, 3 ], 8); assert.notInclude('foobar', 'baz'); ``` ### Community Contributions - [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh) - [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner) Thank you to all who took time to contribute! ### Other Bug Fixes - [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack. - [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added. - Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before. ## 1.5.0 / 2013-02-03 ### Migration Requirements The following changes are required if you are upgrading from the previous version: - **Users:** - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139). - **Plugin Developers:** - No changes required. - **Core Contributors:** - Refresh `node_modules` folder for updated developement dependencies. ### Community Contributions - [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh) - [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh) - [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh) - [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew) - [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff) Thank you to all who took time to contribute! ### Other Bug Fixes - Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios. - [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers. - [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers. ### Usage Updates #### For Users **1. Component Support:** Chai now included the proper configuration to be installed as a [component](https://github.com/component/component). Component users are encouraged to consult [chaijs.com](http://chaijs.com) for the latest version number as using the master branch does not gaurantee stability. ```js // relevant component.json devDependencies: { "chaijs/chai": "1.5.0" } ``` Alternatively, bleeding-edge is available: $ component install chaijs/chai **2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/)) include support for showing the diff of strings and objects when an equality error occurs. Chai has already included support for this, however some users may not prefer this display behavior. To revert to no diff display, the following configuration is available: ```js chai.Assertion.showDiff = false; // diff output disabled chai.Assertion.showDiff = true; // default, diff output enabled ``` #### For Plugin Developers **1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof` that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection. - **@param** _{Mixed}_ object to detect type of - **@return** _{String}_ object type ```js chai.use(function (c, utils) { // some examples utils.type({}); // 'object' utils.type(null); // `null' utils.type(undefined); // `undefined` utils.type([]); // `array` }); ``` #### For Core Contributors **1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all pull requests will now be browser tested in this way. _Note: Contributors opening pull requests should still NOT include the browser build._ **2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`. Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account and include their credentials in `./test/auth/sauce.json`. chaijs-chai-2a3ecff/eslint.config.js000066400000000000000000000012721505212005400175240ustar00rootroot00000000000000import jsdoc from "eslint-plugin-jsdoc"; import eslintjs from "@eslint/js"; const {configs: eslintConfigs} = eslintjs; export default [ jsdoc.configs["flat/recommended"], eslintConfigs["recommended"], { languageOptions: { // if we ever use more globals than this, pull in the `globals` package globals: { console: false } }, rules: { "no-var": "error", "jsdoc/require-param-description": "off", "jsdoc/require-returns-description": "off", "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], "no-unused-vars": ["error", { argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" }] }, }, ]; chaijs-chai-2a3ecff/lib/000077500000000000000000000000001505212005400151705ustar00rootroot00000000000000chaijs-chai-2a3ecff/lib/chai.js000066400000000000000000000023741505212005400164400ustar00rootroot00000000000000/*! * chai * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import * as util from './chai/utils/index.js'; import {AssertionError} from 'assertion-error'; import {config} from './chai/config.js'; import './chai/core/assertions.js'; import {expect} from './chai/interface/expect.js'; import {Assertion} from './chai/assertion.js'; import * as should from './chai/interface/should.js'; import {assert} from './chai/interface/assert.js'; const used = []; // Assertion Error export {AssertionError}; /** * # .use(function) * * Provides a way to extend the internals of Chai. * * @param {Function} fn * @returns {this} for chaining * @public */ export function use(fn) { const exports = { use, AssertionError, util, config, expect, assert, Assertion, ...should }; if (!~used.indexOf(fn)) { fn(exports, util); used.push(fn); } return exports; } // Utility Functions export {util}; // Configuration export {config}; // Primary `Assertion` prototype export * from './chai/assertion.js'; // Expect interface export * from './chai/interface/expect.js'; // Should interface export * from './chai/interface/should.js'; // Assert interface export * from './chai/interface/assert.js'; chaijs-chai-2a3ecff/lib/chai/000077500000000000000000000000001505212005400160745ustar00rootroot00000000000000chaijs-chai-2a3ecff/lib/chai/assertion.js000066400000000000000000000145751505212005400204550ustar00rootroot00000000000000/*! * chai * http://chaijs.com * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import {config} from './config.js'; import {AssertionError} from 'assertion-error'; import * as util from './utils/index.js'; export class Assertion { /** @type {{}} */ __flags = {}; /** * Creates object for chaining. * `Assertion` objects contain metadata in the form of flags. Three flags can * be assigned during instantiation by passing arguments to this constructor: * * - `object`: This flag contains the target of the assertion. For example, in * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will * contain `numKittens` so that the `equal` assertion can reference it when * needed. * * - `message`: This flag contains an optional custom error message to be * prepended to the error message that's generated by the assertion when it * fails. * * - `ssfi`: This flag stands for "start stack function indicator". It * contains a function reference that serves as the starting point for * removing frames from the stack trace of the error that's created by the * assertion when it fails. The goal is to provide a cleaner stack trace to * end users by removing Chai's internal functions. Note that it only works * in environments that support `Error.captureStackTrace`, and only when * `Chai.config.includeStack` hasn't been set to `false`. * * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag * should retain its current value, even as assertions are chained off of * this object. This is usually set to `true` when creating a new assertion * from within another assertion. It's also temporarily set to `true` before * an overwritten assertion gets called by the overwriting assertion. * * - `eql`: This flag contains the deepEqual function to be used by the assertion. * * @param {unknown} obj target of the assertion * @param {string} [msg] (optional) custom error message * @param {Function} [ssfi] (optional) starting point for removing stack frames * @param {boolean} [lockSsfi] (optional) whether or not the ssfi flag is locked */ constructor(obj, msg, ssfi, lockSsfi) { util.flag(this, 'ssfi', ssfi || Assertion); util.flag(this, 'lockSsfi', lockSsfi); util.flag(this, 'object', obj); util.flag(this, 'message', msg); util.flag(this, 'eql', config.deepEqual || util.eql); return util.proxify(this); } /** @returns {boolean} */ static get includeStack() { console.warn( 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' ); return config.includeStack; } /** @param {boolean} value */ static set includeStack(value) { console.warn( 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' ); config.includeStack = value; } /** @returns {boolean} */ static get showDiff() { console.warn( 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' ); return config.showDiff; } /** @param {boolean} value */ static set showDiff(value) { console.warn( 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' ); config.showDiff = value; } /** * @param {string} name * @param {Function} fn */ static addProperty(name, fn) { util.addProperty(this.prototype, name, fn); } /** * @param {string} name * @param {Function} fn */ static addMethod(name, fn) { util.addMethod(this.prototype, name, fn); } /** * @param {string} name * @param {Function} fn * @param {Function} chainingBehavior */ static addChainableMethod(name, fn, chainingBehavior) { util.addChainableMethod(this.prototype, name, fn, chainingBehavior); } /** * @param {string} name * @param {Function} fn */ static overwriteProperty(name, fn) { util.overwriteProperty(this.prototype, name, fn); } /** * @param {string} name * @param {Function} fn */ static overwriteMethod(name, fn) { util.overwriteMethod(this.prototype, name, fn); } /** * @param {string} name * @param {Function} fn * @param {Function} chainingBehavior */ static overwriteChainableMethod(name, fn, chainingBehavior) { util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); } /** * ### .assert(expression, message, negateMessage, expected, actual, showDiff) * * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. * * @name assert * @param {unknown} _expr to be tested * @param {string | Function} msg or function that returns message to display if expression fails * @param {string | Function} _negateMsg or function that returns negatedMessage to display if negated expression fails * @param {unknown} expected value (remember to check for negation) * @param {unknown} _actual (optional) will default to `this.obj` * @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails * @returns {void} */ assert(_expr, msg, _negateMsg, expected, _actual, showDiff) { const ok = util.test(this, arguments); if (false !== showDiff) showDiff = true; if (undefined === expected && undefined === _actual) showDiff = false; if (true !== config.showDiff) showDiff = false; if (!ok) { msg = util.getMessage(this, arguments); const actual = util.getActual(this, arguments); /** @type {Record} */ const assertionErrorObjectProperties = { actual: actual, expected: expected, showDiff: showDiff }; const operator = util.getOperator(this, arguments); if (operator) { assertionErrorObjectProperties.operator = operator; } throw new AssertionError( msg, assertionErrorObjectProperties, // @ts-expect-error Not sure what to do about these types yet config.includeStack ? this.assert : util.flag(this, 'ssfi') ); } } /** * Quick reference to stored `actual` value for plugin developers. * * @returns {unknown} */ get _obj() { return util.flag(this, 'object'); } /** * Quick reference to stored `actual` value for plugin developers. * * @param {unknown} val */ set _obj(val) { util.flag(this, 'object', val); } } chaijs-chai-2a3ecff/lib/chai/config.js000066400000000000000000000073111505212005400177010ustar00rootroot00000000000000export const config = { /** * ### config.includeStack * * User configurable property, influences whether stack trace * is included in Assertion error message. Default of false * suppresses stack trace in the error message. * * chai.config.includeStack = true; // enable stack on error * * @param {boolean} * @public */ includeStack: false, /** * ### config.showDiff * * User configurable property, influences whether or not * the `showDiff` flag should be included in the thrown * AssertionErrors. `false` will always be `false`; `true` * will be true when the assertion has requested a diff * be shown. * * @param {boolean} * @public */ showDiff: true, /** * ### config.truncateThreshold * * User configurable property, sets length threshold for actual and * expected values in assertion errors. If this threshold is exceeded, for * example for large data structures, the value is replaced with something * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. * * Set it to zero if you want to disable truncating altogether. * * This is especially userful when doing assertions on arrays: having this * set to a reasonable large value makes the failure messages readily * inspectable. * * chai.config.truncateThreshold = 0; // disable truncating * * @param {number} * @public */ truncateThreshold: 40, /** * ### config.useProxy * * User configurable property, defines if chai will use a Proxy to throw * an error when a non-existent property is read, which protects users * from typos when using property-based assertions. * * Set it to false if you want to disable this feature. * * chai.config.useProxy = false; // disable use of Proxy * * This feature is automatically disabled regardless of this config value * in environments that don't support proxies. * * @param {boolean} * @public */ useProxy: true, /** * ### config.proxyExcludedKeys * * User configurable property, defines which properties should be ignored * instead of throwing an error if they do not exist on the assertion. * This is only applied if the environment Chai is running in supports proxies and * if the `useProxy` configuration setting is enabled. * By default, `then` and `inspect` will not throw an error if they do not exist on the * assertion object because the `.inspect` property is read by `util.inspect` (for example, when * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. * * // By default these keys will not throw an error if they do not exist on the assertion object * chai.config.proxyExcludedKeys = ['then', 'inspect']; * * @param {Array} * @public */ proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'], /** * ### config.deepEqual * * User configurable property, defines which a custom function to use for deepEqual * comparisons. * By default, the function used is the one from the `deep-eql` package without custom comparator. * * // use a custom comparator * chai.config.deepEqual = (expected, actual) => { * return chai.util.eql(expected, actual, { * comparator: (expected, actual) => { * // for non number comparison, use the default behavior * if(typeof expected !== 'number') return null; * // allow a difference of 10 between compared numbers * return typeof actual === 'number' && Math.abs(actual - expected) < 10 * } * }) * }; * * @param {Function} * @public */ deepEqual: null }; chaijs-chai-2a3ecff/lib/chai/core/000077500000000000000000000000001505212005400170245ustar00rootroot00000000000000chaijs-chai-2a3ecff/lib/chai/core/assertions.js000066400000000000000000004050351505212005400215630ustar00rootroot00000000000000/*! * chai * http://chaijs.com * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {AssertionError} from 'assertion-error'; import * as _ from '../utils/index.js'; import {config} from '../config.js'; const {flag} = _; /** * ### Language Chains * * The following are provided as chainable getters to improve the readability * of your assertions. * * **Chains** * * - to * - be * - been * - is * - that * - which * - and * - has * - have * - with * - at * - of * - same * - but * - does * - still * - also * * @name language chains * @namespace BDD * @public */ [ 'to', 'be', 'been', 'is', 'and', 'has', 'have', 'with', 'that', 'which', 'at', 'of', 'same', 'but', 'does', 'still', 'also' ].forEach(function (chain) { Assertion.addProperty(chain); }); /** * ### .not * * Negates all assertions that follow in the chain. * * expect(function () {}).to.not.throw(); * expect({a: 1}).to.not.have.property('b'); * expect([1, 2]).to.be.an('array').that.does.not.include(3); * * Just because you can negate any assertion with `.not` doesn't mean you * should. With great power comes great responsibility. It's often best to * assert that the one expected output was produced, rather than asserting * that one of countless unexpected outputs wasn't produced. See individual * assertions for specific guidance. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.equal(1); // Not recommended * * @name not * @namespace BDD * @public */ Assertion.addProperty('not', function () { flag(this, 'negate', true); }); /** * ### .deep * * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` * assertions that follow in the chain to use deep equality instead of strict * (`===`) equality. See the `deep-eql` project page for info on the deep * equality algorithm: https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) equals `{a: 1}` * expect({a: 1}).to.deep.equal({a: 1}); * expect({a: 1}).to.not.equal({a: 1}); * * // Target array deeply (but not strictly) includes `{a: 1}` * expect([{a: 1}]).to.deep.include({a: 1}); * expect([{a: 1}]).to.not.include({a: 1}); * * // Target object deeply (but not strictly) includes `x: {a: 1}` * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); * * // Target array deeply (but not strictly) has member `{a: 1}` * expect([{a: 1}]).to.have.deep.members([{a: 1}]); * expect([{a: 1}]).to.not.have.members([{a: 1}]); * * // Target set deeply (but not strictly) has key `{a: 1}` * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); * * // Target object deeply (but not strictly) has property `x: {a: 1}` * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); * * @name deep * @namespace BDD * @public */ Assertion.addProperty('deep', function () { flag(this, 'deep', true); }); /** * ### .nested * * Enables dot- and bracket-notation in all `.property` and `.include` * assertions that follow in the chain. * * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); * * `.nested` cannot be combined with `.own`. * * @name nested * @namespace BDD * @public */ Assertion.addProperty('nested', function () { flag(this, 'nested', true); }); /** * ### .own * * Causes all `.property` and `.include` assertions that follow in the chain * to ignore inherited properties. * * Object.prototype.b = 2; * * expect({a: 1}).to.have.own.property('a'); * expect({a: 1}).to.have.property('b'); * expect({a: 1}).to.not.have.own.property('b'); * * expect({a: 1}).to.own.include({a: 1}); * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); * * `.own` cannot be combined with `.nested`. * * @name own * @namespace BDD * @public */ Assertion.addProperty('own', function () { flag(this, 'own', true); }); /** * ### .ordered * * Causes all `.members` assertions that follow in the chain to require that * members be in the same order. * * expect([1, 2]).to.have.ordered.members([1, 2]) * .but.not.have.ordered.members([2, 1]); * * When `.include` and `.ordered` are combined, the ordering begins at the * start of both arrays. * * expect([1, 2, 3]).to.include.ordered.members([1, 2]) * .but.not.include.ordered.members([2, 3]); * * @name ordered * @namespace BDD * @public */ Assertion.addProperty('ordered', function () { flag(this, 'ordered', true); }); /** * ### .any * * Causes all `.keys` assertions that follow in the chain to only require that * the target have at least one of the given keys. This is the opposite of * `.all`, which requires that the target have all of the given keys. * * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); * * See the `.keys` doc for guidance on when to use `.any` or `.all`. * * @name any * @namespace BDD * @public */ Assertion.addProperty('any', function () { flag(this, 'any', true); flag(this, 'all', false); }); /** * ### .all * * Causes all `.keys` assertions that follow in the chain to require that the * target have all of the given keys. This is the opposite of `.any`, which * only requires that the target have at least one of the given keys. * * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * * Note that `.all` is used by default when neither `.all` nor `.any` are * added earlier in the chain. However, it's often best to add `.all` anyway * because it improves readability. * * See the `.keys` doc for guidance on when to use `.any` or `.all`. * * @name all * @namespace BDD * @public */ Assertion.addProperty('all', function () { flag(this, 'all', true); flag(this, 'any', false); }); const functionTypes = { function: [ 'function', 'asyncfunction', 'generatorfunction', 'asyncgeneratorfunction' ], asyncfunction: ['asyncfunction', 'asyncgeneratorfunction'], generatorfunction: ['generatorfunction', 'asyncgeneratorfunction'], asyncgeneratorfunction: ['asyncgeneratorfunction'] }; /** * ### .a(type[, msg]) * * Asserts that the target's type is equal to the given string `type`. Types * are case insensitive. See the utility file `./type-detect.js` for info on the * type detection algorithm. * * expect('foo').to.be.a('string'); * expect({a: 1}).to.be.an('object'); * expect(null).to.be.a('null'); * expect(undefined).to.be.an('undefined'); * expect(new Error).to.be.an('error'); * expect(Promise.resolve()).to.be.a('promise'); * expect(new Float32Array).to.be.a('float32array'); * expect(Symbol()).to.be.a('symbol'); * * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. * * var myObj = { * [Symbol.toStringTag]: 'myCustomType' * }; * * expect(myObj).to.be.a('myCustomType').but.not.an('object'); * * It's often best to use `.a` to check a target's type before making more * assertions on the same target. That way, you avoid unexpected behavior from * any assertion that does different things based on the target's type. * * expect([1, 2, 3]).to.be.an('array').that.includes(2); * expect([]).to.be.an('array').that.is.empty; * * Add `.not` earlier in the chain to negate `.a`. However, it's often best to * assert that the target is the expected type, rather than asserting that it * isn't one of many unexpected types. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.an('array'); // Not recommended * * `.a` accepts an optional `msg` argument which is a custom error message to * show when the assertion fails. The message can also be given as the second * argument to `expect`. * * expect(1).to.be.a('string', 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.a('string'); * * `.a` can also be used as a language chain to improve the readability of * your assertions. * * expect({b: 2}).to.have.a.property('b'); * * The alias `.an` can be used interchangeably with `.a`. * * @name a * @alias an * @param {string} type * @param {string} msg _optional_ * @namespace BDD * @public */ function an(type, msg) { if (msg) flag(this, 'message', msg); type = type.toLowerCase(); let obj = flag(this, 'object'), article = ~['a', 'e', 'i', 'o', 'u'].indexOf(type.charAt(0)) ? 'an ' : 'a '; const detectedType = _.type(obj).toLowerCase(); if (functionTypes['function'].includes(type)) { this.assert( functionTypes[type].includes(detectedType), 'expected #{this} to be ' + article + type, 'expected #{this} not to be ' + article + type ); } else { this.assert( type === detectedType, 'expected #{this} to be ' + article + type, 'expected #{this} not to be ' + article + type ); } } Assertion.addChainableMethod('an', an); Assertion.addChainableMethod('a', an); /** * @param {unknown} a * @param {unknown} b * @returns {boolean} */ function SameValueZero(a, b) { return (_.isNaN(a) && _.isNaN(b)) || a === b; } /** */ function includeChainingBehavior() { flag(this, 'contains', true); } /** * ### .include(val[, msg]) * * When the target is a string, `.include` asserts that the given string `val` * is a substring of the target. * * expect('foobar').to.include('foo'); * * When the target is an array, `.include` asserts that the given `val` is a * member of the target. * * expect([1, 2, 3]).to.include(2); * * When the target is an object, `.include` asserts that the given object * `val`'s properties are a subset of the target's properties. * * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); * * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a * member of the target. SameValueZero equality algorithm is used. * * expect(new Set([1, 2])).to.include(2); * * When the target is a Map, `.include` asserts that the given `val` is one of * the values of the target. SameValueZero equality algorithm is used. * * expect(new Map([['a', 1], ['b', 2]])).to.include(2); * * Because `.include` does different things based on the target's type, it's * important to check the target's type before using `.include`. See the `.a` * doc for info on testing a target's type. * * expect([1, 2, 3]).to.be.an('array').that.includes(2); * * By default, strict (`===`) equality is used to compare array members and * object properties. Add `.deep` earlier in the chain to use deep equality * instead (WeakSet targets are not supported). See the `deep-eql` project * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * * // Target array deeply (but not strictly) includes `{a: 1}` * expect([{a: 1}]).to.deep.include({a: 1}); * expect([{a: 1}]).to.not.include({a: 1}); * * // Target object deeply (but not strictly) includes `x: {a: 1}` * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); * * By default, all of the target's properties are searched when working with * objects. This includes properties that are inherited and/or non-enumerable. * Add `.own` earlier in the chain to exclude the target's inherited * properties from the search. * * Object.prototype.b = 2; * * expect({a: 1}).to.own.include({a: 1}); * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); * * Note that a target object is always only searched for `val`'s own * enumerable properties. * * `.deep` and `.own` can be combined. * * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); * * Add `.nested` earlier in the chain to enable dot- and bracket-notation when * referencing nested properties. * * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); * * `.deep` and `.nested` can be combined. * * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); * * `.own` and `.nested` cannot be combined. * * Add `.not` earlier in the chain to negate `.include`. * * expect('foobar').to.not.include('taco'); * expect([1, 2, 3]).to.not.include(4); * * However, it's dangerous to negate `.include` when the target is an object. * The problem is that it creates uncertain expectations by asserting that the * target object doesn't have all of `val`'s key/value pairs but may or may * not have some of them. It's often best to identify the exact output that's * expected, and then write an assertion that only accepts that exact output. * * When the target object isn't even expected to have `val`'s keys, it's * often best to assert exactly that. * * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended * * When the target object is expected to have `val`'s keys, it's often best to * assert that each of the properties has its expected value, rather than * asserting that each property doesn't have one of many unexpected values. * * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended * * `.include` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); * expect([1, 2, 3], 'nooo why fail??').to.include(4); * * `.include` can also be used as a language chain, causing all `.members` and * `.keys` assertions that follow in the chain to require the target to be a * superset of the expected set, rather than an identical set. Note that * `.members` ignores duplicates in the subset when `.include` is added. * * // Target object's keys are a superset of ['a', 'b'] but not identical * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); * * // Target array is a superset of [1, 2] but not identical * expect([1, 2, 3]).to.include.members([1, 2]); * expect([1, 2, 3]).to.not.have.members([1, 2]); * * // Duplicates in the subset are ignored * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); * * Note that adding `.any` earlier in the chain causes the `.keys` assertion * to ignore `.include`. * * // Both assertions are identical * expect({a: 1}).to.include.any.keys('a', 'b'); * expect({a: 1}).to.have.any.keys('a', 'b'); * * The aliases `.includes`, `.contain`, and `.contains` can be used * interchangeably with `.include`. * * @name include * @alias contain * @alias includes * @alias contains * @param {unknown} val * @param {string} msg _optional_ * @namespace BDD * @public */ function include(val, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, 'message'), negate = flag(this, 'negate'), ssfi = flag(this, 'ssfi'), isDeep = flag(this, 'deep'), descriptor = isDeep ? 'deep ' : '', isEql = isDeep ? flag(this, 'eql') : SameValueZero; flagMsg = flagMsg ? flagMsg + ': ' : ''; let included = false; switch (objType) { case 'string': included = obj.indexOf(val) !== -1; break; case 'weakset': if (isDeep) { throw new AssertionError( flagMsg + 'unable to use .deep.include with WeakSet', undefined, ssfi ); } included = obj.has(val); break; case 'map': obj.forEach(function (item) { included = included || isEql(item, val); }); break; case 'set': if (isDeep) { obj.forEach(function (item) { included = included || isEql(item, val); }); } else { included = obj.has(val); } break; case 'array': if (isDeep) { included = obj.some(function (item) { return isEql(item, val); }); } else { included = obj.indexOf(val) !== -1; } break; default: { // This block is for asserting a subset of properties in an object. // `_.expectTypes` isn't used here because `.include` should work with // objects with a custom `@@toStringTag`. if (val !== Object(val)) { throw new AssertionError( flagMsg + 'the given combination of arguments (' + objType + ' and ' + _.type(val).toLowerCase() + ')' + ' is invalid for this assertion. ' + 'You can use an array, a map, an object, a set, a string, ' + 'or a weakset instead of a ' + _.type(val).toLowerCase(), undefined, ssfi ); } let props = Object.keys(val); let firstErr = null; let numErrs = 0; props.forEach(function (prop) { let propAssertion = new Assertion(obj); _.transferFlags(this, propAssertion, true); flag(propAssertion, 'lockSsfi', true); if (!negate || props.length === 1) { propAssertion.property(prop, val[prop]); return; } try { propAssertion.property(prop, val[prop]); } catch (err) { if (!_.checkError.compatibleConstructor(err, AssertionError)) { throw err; } if (firstErr === null) firstErr = err; numErrs++; } }, this); // When validating .not.include with multiple properties, we only want // to throw an assertion error if all of the properties are included, // in which case we throw the first property assertion error that we // encountered. if (negate && props.length > 1 && numErrs === props.length) { throw firstErr; } return; } } // Assert inclusion in collection or substring in a string. this.assert( included, 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val), 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val) ); } Assertion.addChainableMethod('include', include, includeChainingBehavior); Assertion.addChainableMethod('contain', include, includeChainingBehavior); Assertion.addChainableMethod('contains', include, includeChainingBehavior); Assertion.addChainableMethod('includes', include, includeChainingBehavior); /** * ### .ok * * Asserts that the target is a truthy value (considered `true` in boolean context). * However, it's often best to assert that the target is strictly (`===`) or * deeply equal to its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.ok; // Not recommended * * expect(true).to.be.true; // Recommended * expect(true).to.be.ok; // Not recommended * * Add `.not` earlier in the chain to negate `.ok`. * * expect(0).to.equal(0); // Recommended * expect(0).to.not.be.ok; // Not recommended * * expect(false).to.be.false; // Recommended * expect(false).to.not.be.ok; // Not recommended * * expect(null).to.be.null; // Recommended * expect(null).to.not.be.ok; // Not recommended * * expect(undefined).to.be.undefined; // Recommended * expect(undefined).to.not.be.ok; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(false, 'nooo why fail??').to.be.ok; * * @name ok * @namespace BDD * @public */ Assertion.addProperty('ok', function () { this.assert( flag(this, 'object'), 'expected #{this} to be truthy', 'expected #{this} to be falsy' ); }); /** * ### .true * * Asserts that the target is strictly (`===`) equal to `true`. * * expect(true).to.be.true; * * Add `.not` earlier in the chain to negate `.true`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `true`. * * expect(false).to.be.false; // Recommended * expect(false).to.not.be.true; // Not recommended * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.true; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(false, 'nooo why fail??').to.be.true; * * @name true * @namespace BDD * @public */ Assertion.addProperty('true', function () { this.assert( true === flag(this, 'object'), 'expected #{this} to be true', 'expected #{this} to be false', flag(this, 'negate') ? false : true ); }); Assertion.addProperty('numeric', function () { const object = flag(this, 'object'); this.assert( ['Number', 'BigInt'].includes(_.type(object)), 'expected #{this} to be numeric', 'expected #{this} to not be numeric', flag(this, 'negate') ? false : true ); }); /** * ### .callable * * Asserts that the target a callable function. * * expect(console.log).to.be.callable; * * A custom error message can be given as the second argument to `expect`. * * expect('not a function', 'nooo why fail??').to.be.callable; * * @name callable * @namespace BDD * @public */ Assertion.addProperty('callable', function () { const val = flag(this, 'object'); const ssfi = flag(this, 'ssfi'); const message = flag(this, 'message'); const msg = message ? `${message}: ` : ''; const negate = flag(this, 'negate'); const assertionMessage = negate ? `${msg}expected ${_.inspect(val)} not to be a callable function` : `${msg}expected ${_.inspect(val)} to be a callable function`; const isCallable = [ 'Function', 'AsyncFunction', 'GeneratorFunction', 'AsyncGeneratorFunction' ].includes(_.type(val)); if ((isCallable && negate) || (!isCallable && !negate)) { throw new AssertionError(assertionMessage, undefined, ssfi); } }); /** * ### .false * * Asserts that the target is strictly (`===`) equal to `false`. * * expect(false).to.be.false; * * Add `.not` earlier in the chain to negate `.false`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to `false`. * * expect(true).to.be.true; // Recommended * expect(true).to.not.be.false; // Not recommended * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.false; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(true, 'nooo why fail??').to.be.false; * * @name false * @namespace BDD * @public */ Assertion.addProperty('false', function () { this.assert( false === flag(this, 'object'), 'expected #{this} to be false', 'expected #{this} to be true', flag(this, 'negate') ? true : false ); }); /** * ### .null * * Asserts that the target is strictly (`===`) equal to `null`. * * expect(null).to.be.null; * * Add `.not` earlier in the chain to negate `.null`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `null`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.null; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.null; * * @name null * @namespace BDD * @public */ Assertion.addProperty('null', function () { this.assert( null === flag(this, 'object'), 'expected #{this} to be null', 'expected #{this} not to be null' ); }); /** * ### .undefined * * Asserts that the target is strictly (`===`) equal to `undefined`. * * expect(undefined).to.be.undefined; * * Add `.not` earlier in the chain to negate `.undefined`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to `undefined`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.undefined; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.undefined; * * @name undefined * @namespace BDD * @public */ Assertion.addProperty('undefined', function () { this.assert( undefined === flag(this, 'object'), 'expected #{this} to be undefined', 'expected #{this} not to be undefined' ); }); /** * ### .NaN * * Asserts that the target is exactly `NaN`. * * expect(NaN).to.be.NaN; * * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `NaN`. * * expect('foo').to.equal('foo'); // Recommended * expect('foo').to.not.be.NaN; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.NaN; * * @name NaN * @namespace BDD * @public */ Assertion.addProperty('NaN', function () { this.assert( _.isNaN(flag(this, 'object')), 'expected #{this} to be NaN', 'expected #{this} not to be NaN' ); }); /** * ### .exist * * Asserts that the target is not strictly (`===`) equal to either `null` or * `undefined`. However, it's often best to assert that the target is equal to * its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.exist; // Not recommended * * expect(0).to.equal(0); // Recommended * expect(0).to.exist; // Not recommended * * Add `.not` earlier in the chain to negate `.exist`. * * expect(null).to.be.null; // Recommended * expect(null).to.not.exist; // Not recommended * * expect(undefined).to.be.undefined; // Recommended * expect(undefined).to.not.exist; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(null, 'nooo why fail??').to.exist; * * The alias `.exists` can be used interchangeably with `.exist`. * * @name exist * @alias exists * @namespace BDD * @public */ function assertExist() { let val = flag(this, 'object'); this.assert( val !== null && val !== undefined, 'expected #{this} to exist', 'expected #{this} to not exist' ); } Assertion.addProperty('exist', assertExist); Assertion.addProperty('exists', assertExist); /** * ### .empty * * When the target is a string or array, `.empty` asserts that the target's * `length` property is strictly (`===`) equal to `0`. * * expect([]).to.be.empty; * expect('').to.be.empty; * * When the target is a map or set, `.empty` asserts that the target's `size` * property is strictly equal to `0`. * * expect(new Set()).to.be.empty; * expect(new Map()).to.be.empty; * * When the target is a non-function object, `.empty` asserts that the target * doesn't have any own enumerable properties. Properties with Symbol-based * keys are excluded from the count. * * expect({}).to.be.empty; * * Because `.empty` does different things based on the target's type, it's * important to check the target's type before using `.empty`. See the `.a` * doc for info on testing a target's type. * * expect([]).to.be.an('array').that.is.empty; * * Add `.not` earlier in the chain to negate `.empty`. However, it's often * best to assert that the target contains its expected number of values, * rather than asserting that it's not empty. * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.not.be.empty; // Not recommended * * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended * * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended * expect({a: 1}).to.not.be.empty; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect([1, 2, 3], 'nooo why fail??').to.be.empty; * * @name empty * @namespace BDD * @public */ Assertion.addProperty('empty', function () { let val = flag(this, 'object'), ssfi = flag(this, 'ssfi'), flagMsg = flag(this, 'message'), itemsCount; flagMsg = flagMsg ? flagMsg + ': ' : ''; switch (_.type(val).toLowerCase()) { case 'array': case 'string': itemsCount = val.length; break; case 'map': case 'set': itemsCount = val.size; break; case 'weakmap': case 'weakset': throw new AssertionError( flagMsg + '.empty was passed a weak collection', undefined, ssfi ); case 'function': { const msg = flagMsg + '.empty was passed a function ' + _.getName(val); throw new AssertionError(msg.trim(), undefined, ssfi); } default: if (val !== Object(val)) { throw new AssertionError( flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), undefined, ssfi ); } itemsCount = Object.keys(val).length; } this.assert( 0 === itemsCount, 'expected #{this} to be empty', 'expected #{this} not to be empty' ); }); /** * ### .arguments * * Asserts that the target is an `arguments` object. * * function test () { * expect(arguments).to.be.arguments; * } * * test(); * * Add `.not` earlier in the chain to negate `.arguments`. However, it's often * best to assert which type the target is expected to be, rather than * asserting that it’s not an `arguments` object. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.arguments; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect({}, 'nooo why fail??').to.be.arguments; * * The alias `.Arguments` can be used interchangeably with `.arguments`. * * @name arguments * @alias Arguments * @namespace BDD * @public */ function checkArguments() { let obj = flag(this, 'object'), type = _.type(obj); this.assert( 'Arguments' === type, 'expected #{this} to be arguments but got ' + type, 'expected #{this} to not be arguments' ); } Assertion.addProperty('arguments', checkArguments); Assertion.addProperty('Arguments', checkArguments); /** * ### .equal(val[, msg]) * * Asserts that the target is strictly (`===`) equal to the given `val`. * * expect(1).to.equal(1); * expect('foo').to.equal('foo'); * * Add `.deep` earlier in the chain to use deep equality instead. See the * `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) equals `{a: 1}` * expect({a: 1}).to.deep.equal({a: 1}); * expect({a: 1}).to.not.equal({a: 1}); * * // Target array deeply (but not strictly) equals `[1, 2]` * expect([1, 2]).to.deep.equal([1, 2]); * expect([1, 2]).to.not.equal([1, 2]); * * Add `.not` earlier in the chain to negate `.equal`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to one of countless unexpected values. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.equal(2); // Not recommended * * `.equal` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.equal(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.equal(2); * * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. * * @name equal * @alias equals * @alias eq * @param {unknown} val * @param {string} msg _optional_ * @namespace BDD * @public */ function assertEqual(val, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'); if (flag(this, 'deep')) { let prevLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); this.eql(val); flag(this, 'lockSsfi', prevLockSsfi); } else { this.assert( val === obj, 'expected #{this} to equal #{exp}', 'expected #{this} to not equal #{exp}', val, this._obj, true ); } } Assertion.addMethod('equal', assertEqual); Assertion.addMethod('equals', assertEqual); Assertion.addMethod('eq', assertEqual); /** * ### .eql(obj[, msg]) * * Asserts that the target is deeply equal to the given `obj`. See the * `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target object is deeply (but not strictly) equal to {a: 1} * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); * * // Target array is deeply (but not strictly) equal to [1, 2] * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); * * Add `.not` earlier in the chain to negate `.eql`. However, it's often best * to assert that the target is deeply equal to its expected value, rather * than not deeply equal to one of countless unexpected values. * * expect({a: 1}).to.eql({a: 1}); // Recommended * expect({a: 1}).to.not.eql({b: 2}); // Not recommended * * `.eql` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); * * The alias `.eqls` can be used interchangeably with `.eql`. * * The `.deep.equal` assertion is almost identical to `.eql` but with one * difference: `.deep.equal` causes deep equality comparisons to also be used * for any other assertions that follow in the chain. * * @name eql * @alias eqls * @param {unknown} obj * @param {string} msg _optional_ * @namespace BDD * @public */ function assertEql(obj, msg) { if (msg) flag(this, 'message', msg); let eql = flag(this, 'eql'); this.assert( eql(obj, flag(this, 'object')), 'expected #{this} to deeply equal #{exp}', 'expected #{this} to not deeply equal #{exp}', obj, this._obj, true ); } Assertion.addMethod('eql', assertEql); Assertion.addMethod('eqls', assertEql); /** * ### .above(n[, msg]) * * Asserts that the target is a number or a date greater than the given number or date `n` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.above(1); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.above(2); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended * * Add `.not` earlier in the chain to negate `.above`. * * expect(2).to.equal(2); // Recommended * expect(1).to.not.be.above(2); // Not recommended * * `.above` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.above(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.above(2); * * The aliases `.gt` and `.greaterThan` can be used interchangeably with * `.above`. * * @name above * @alias gt * @alias greaterThan * @param {number} n * @param {string} msg _optional_ * @namespace BDD * @public */ function assertAbove(n, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), doLength = flag(this, 'doLength'), flagMsg = flag(this, 'message'), msgPrefix = flagMsg ? flagMsg + ': ' : '', ssfi = flag(this, 'ssfi'), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(); if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && objType === 'date' && nType !== 'date') { throw new AssertionError( msgPrefix + 'the argument to above must be a date', undefined, ssfi ); } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { throw new AssertionError( msgPrefix + 'the argument to above must be a number', undefined, ssfi ); } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { let printObj = objType === 'string' ? "'" + obj + "'" : obj; throw new AssertionError( msgPrefix + 'expected ' + printObj + ' to be a number or a date', undefined, ssfi ); } if (doLength) { let descriptor = 'length', itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount > n, 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}', 'expected #{this} to not have a ' + descriptor + ' above #{exp}', n, itemsCount ); } else { this.assert( obj > n, 'expected #{this} to be above #{exp}', 'expected #{this} to be at most #{exp}', n ); } } Assertion.addMethod('above', assertAbove); Assertion.addMethod('gt', assertAbove); Assertion.addMethod('greaterThan', assertAbove); /** * ### .least(n[, msg]) * * Asserts that the target is a number or a date greater than or equal to the given * number or date `n` respectively. However, it's often best to assert that the target is equal to * its expected value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.at.least(1); // Not recommended * expect(2).to.be.at.least(2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than or equal to the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.at.least(2); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended * * Add `.not` earlier in the chain to negate `.least`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.at.least(2); // Not recommended * * `.least` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.at.least(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.at.least(2); * * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with * `.least`. * * @name least * @alias gte * @alias greaterThanOrEqual * @param {unknown} n * @param {string} msg _optional_ * @namespace BDD * @public */ function assertLeast(n, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), doLength = flag(this, 'doLength'), flagMsg = flag(this, 'message'), msgPrefix = flagMsg ? flagMsg + ': ' : '', ssfi = flag(this, 'ssfi'), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && objType === 'date' && nType !== 'date') { errorMessage = msgPrefix + 'the argument to least must be a date'; } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { errorMessage = msgPrefix + 'the argument to least must be a number'; } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { let printObj = objType === 'string' ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { let descriptor = 'length', itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount >= n, 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}', 'expected #{this} to have a ' + descriptor + ' below #{exp}', n, itemsCount ); } else { this.assert( obj >= n, 'expected #{this} to be at least #{exp}', 'expected #{this} to be below #{exp}', n ); } } Assertion.addMethod('least', assertLeast); Assertion.addMethod('gte', assertLeast); Assertion.addMethod('greaterThanOrEqual', assertLeast); /** * ### .below(n[, msg]) * * Asserts that the target is a number or a date less than the given number or date `n` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.below(2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is less than the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.below(4); // Not recommended * * expect([1, 2, 3]).to.have.length(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended * * Add `.not` earlier in the chain to negate `.below`. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.be.below(1); // Not recommended * * `.below` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(2).to.be.below(1, 'nooo why fail??'); * expect(2, 'nooo why fail??').to.be.below(1); * * The aliases `.lt` and `.lessThan` can be used interchangeably with * `.below`. * * @name below * @alias lt * @alias lessThan * @param {unknown} n * @param {string} msg _optional_ * @namespace BDD * @public */ function assertBelow(n, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), doLength = flag(this, 'doLength'), flagMsg = flag(this, 'message'), msgPrefix = flagMsg ? flagMsg + ': ' : '', ssfi = flag(this, 'ssfi'), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && objType === 'date' && nType !== 'date') { errorMessage = msgPrefix + 'the argument to below must be a date'; } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { errorMessage = msgPrefix + 'the argument to below must be a number'; } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { let printObj = objType === 'string' ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { let descriptor = 'length', itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount < n, 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}', 'expected #{this} to not have a ' + descriptor + ' below #{exp}', n, itemsCount ); } else { this.assert( obj < n, 'expected #{this} to be below #{exp}', 'expected #{this} to be at least #{exp}', n ); } } Assertion.addMethod('below', assertBelow); Assertion.addMethod('lt', assertBelow); Assertion.addMethod('lessThan', assertBelow); /** * ### .most(n[, msg]) * * Asserts that the target is a number or a date less than or equal to the given number * or date `n` respectively. However, it's often best to assert that the target is equal to its * expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.at.most(2); // Not recommended * expect(1).to.be.at.most(1); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is less than or equal to the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.at.most(4); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended * * Add `.not` earlier in the chain to negate `.most`. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.be.at.most(1); // Not recommended * * `.most` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(2).to.be.at.most(1, 'nooo why fail??'); * expect(2, 'nooo why fail??').to.be.at.most(1); * * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with * `.most`. * * @name most * @alias lte * @alias lessThanOrEqual * @param {unknown} n * @param {string} msg _optional_ * @namespace BDD * @public */ function assertMost(n, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), doLength = flag(this, 'doLength'), flagMsg = flag(this, 'message'), msgPrefix = flagMsg ? flagMsg + ': ' : '', ssfi = flag(this, 'ssfi'), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && objType === 'date' && nType !== 'date') { errorMessage = msgPrefix + 'the argument to most must be a date'; } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) { errorMessage = msgPrefix + 'the argument to most must be a number'; } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { let printObj = objType === 'string' ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { let descriptor = 'length', itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount <= n, 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}', 'expected #{this} to have a ' + descriptor + ' above #{exp}', n, itemsCount ); } else { this.assert( obj <= n, 'expected #{this} to be at most #{exp}', 'expected #{this} to be above #{exp}', n ); } } Assertion.addMethod('most', assertMost); Assertion.addMethod('lte', assertMost); Assertion.addMethod('lessThanOrEqual', assertMost); /** * ### .within(start, finish[, msg]) * * Asserts that the target is a number or a date greater than or equal to the given * number or date `start`, and less than or equal to the given number or date `finish` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.within(1, 3); // Not recommended * expect(2).to.be.within(2, 3); // Not recommended * expect(2).to.be.within(1, 2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than or equal to the given number `start`, and less * than or equal to the given number `finish`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended * * Add `.not` earlier in the chain to negate `.within`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.within(2, 4); // Not recommended * * `.within` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(4).to.be.within(1, 3, 'nooo why fail??'); * expect(4, 'nooo why fail??').to.be.within(1, 3); * * @name within * @param {unknown} start lower bound inclusive * @param {unknown} finish upper bound inclusive * @param {string} msg _optional_ * @namespace BDD * @public */ Assertion.addMethod('within', function (start, finish, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), doLength = flag(this, 'doLength'), flagMsg = flag(this, 'message'), msgPrefix = flagMsg ? flagMsg + ': ' : '', ssfi = flag(this, 'ssfi'), objType = _.type(obj).toLowerCase(), startType = _.type(start).toLowerCase(), finishType = _.type(finish).toLowerCase(), errorMessage, shouldThrow = true, range = startType === 'date' && finishType === 'date' ? start.toISOString() + '..' + finish.toISOString() : start + '..' + finish; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if ( !doLength && objType === 'date' && (startType !== 'date' || finishType !== 'date') ) { errorMessage = msgPrefix + 'the arguments to within must be dates'; } else if ( (!_.isNumeric(start) || !_.isNumeric(finish)) && (doLength || _.isNumeric(obj)) ) { errorMessage = msgPrefix + 'the arguments to within must be numbers'; } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) { let printObj = objType === 'string' ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { let descriptor = 'length', itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount >= start && itemsCount <= finish, 'expected #{this} to have a ' + descriptor + ' within ' + range, 'expected #{this} to not have a ' + descriptor + ' within ' + range ); } else { this.assert( obj >= start && obj <= finish, 'expected #{this} to be within ' + range, 'expected #{this} to not be within ' + range ); } }); /** * ### .instanceof(constructor[, msg]) * * Asserts that the target is an instance of the given `constructor`. * * function Cat () { } * * expect(new Cat()).to.be.an.instanceof(Cat); * expect([1, 2]).to.be.an.instanceof(Array); * * Add `.not` earlier in the chain to negate `.instanceof`. * * expect({a: 1}).to.not.be.an.instanceof(Array); * * `.instanceof` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); * * Due to limitations in ES5, `.instanceof` may not always work as expected * when using a transpiler such as Babel or TypeScript. In particular, it may * produce unexpected results when subclassing built-in object such as * `Array`, `Error`, and `Map`. See your transpiler's docs for details: * * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) * * The alias `.instanceOf` can be used interchangeably with `.instanceof`. * * @name instanceof * @param {unknown} constructor * @param {string} msg _optional_ * @alias instanceOf * @namespace BDD * @public */ function assertInstanceOf(constructor, msg) { if (msg) flag(this, 'message', msg); let target = flag(this, 'object'); let ssfi = flag(this, 'ssfi'); let flagMsg = flag(this, 'message'); let isInstanceOf; try { isInstanceOf = target instanceof constructor; } catch (err) { if (err instanceof TypeError) { flagMsg = flagMsg ? flagMsg + ': ' : ''; throw new AssertionError( flagMsg + 'The instanceof assertion needs a constructor but ' + _.type(constructor) + ' was given.', undefined, ssfi ); } throw err; } let name = _.getName(constructor); if (name == null) { name = 'an unnamed constructor'; } this.assert( isInstanceOf, 'expected #{this} to be an instance of ' + name, 'expected #{this} to not be an instance of ' + name ); } Assertion.addMethod('instanceof', assertInstanceOf); Assertion.addMethod('instanceOf', assertInstanceOf); /** * ### .property(name[, val[, msg]]) * * Asserts that the target has a property with the given key `name`. * * expect({a: 1}).to.have.property('a'); * * When `val` is provided, `.property` also asserts that the property's value * is equal to the given `val`. * * expect({a: 1}).to.have.property('a', 1); * * By default, strict (`===`) equality is used. Add `.deep` earlier in the * chain to use deep equality instead. See the `deep-eql` project page for * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) has property `x: {a: 1}` * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); * * The target's enumerable and non-enumerable properties are always included * in the search. By default, both own and inherited properties are included. * Add `.own` earlier in the chain to exclude inherited properties from the * search. * * Object.prototype.b = 2; * * expect({a: 1}).to.have.own.property('a'); * expect({a: 1}).to.have.own.property('a', 1); * expect({a: 1}).to.have.property('b'); * expect({a: 1}).to.not.have.own.property('b'); * * `.deep` and `.own` can be combined. * * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); * * Add `.nested` earlier in the chain to enable dot- and bracket-notation when * referencing nested properties. * * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); * * `.deep` and `.nested` can be combined. * * expect({a: {b: [{c: 3}]}}) * .to.have.deep.nested.property('a.b[0]', {c: 3}); * * `.own` and `.nested` cannot be combined. * * Add `.not` earlier in the chain to negate `.property`. * * expect({a: 1}).to.not.have.property('b'); * * However, it's dangerous to negate `.property` when providing `val`. The * problem is that it creates uncertain expectations by asserting that the * target either doesn't have a property with the given key `name`, or that it * does have a property with the given key `name` but its value isn't equal to * the given `val`. It's often best to identify the exact output that's * expected, and then write an assertion that only accepts that exact output. * * When the target isn't expected to have a property with the given key * `name`, it's often best to assert exactly that. * * expect({b: 2}).to.not.have.property('a'); // Recommended * expect({b: 2}).to.not.have.property('a', 1); // Not recommended * * When the target is expected to have a property with the given key `name`, * it's often best to assert that the property has its expected value, rather * than asserting that it doesn't have one of many unexpected values. * * expect({a: 3}).to.have.property('a', 3); // Recommended * expect({a: 3}).to.not.have.property('a', 1); // Not recommended * * `.property` changes the target of any assertions that follow in the chain * to be the value of the property from the original target object. * * expect({a: 1}).to.have.property('a').that.is.a('number'); * * `.property` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing `val`, only use the * second form. * * // Recommended * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); * expect({a: 1}, 'nooo why fail??').to.have.property('b'); * * // Not recommended * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); * * The above assertion isn't the same thing as not providing `val`. Instead, * it's asserting that the target object has a `b` property that's equal to * `undefined`. * * The assertions `.ownProperty` and `.haveOwnProperty` can be used * interchangeably with `.own.property`. * * @name property * @param {string} name * @param {unknown} val (optional) * @param {string} msg _optional_ * @namespace BDD * @public */ function assertProperty(name, val, msg) { if (msg) flag(this, 'message', msg); let isNested = flag(this, 'nested'), isOwn = flag(this, 'own'), flagMsg = flag(this, 'message'), obj = flag(this, 'object'), ssfi = flag(this, 'ssfi'), nameType = typeof name; flagMsg = flagMsg ? flagMsg + ': ' : ''; if (isNested) { if (nameType !== 'string') { throw new AssertionError( flagMsg + 'the argument to property must be a string when using nested syntax', undefined, ssfi ); } } else { if ( nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol' ) { throw new AssertionError( flagMsg + 'the argument to property must be a string, number, or symbol', undefined, ssfi ); } } if (isNested && isOwn) { throw new AssertionError( flagMsg + 'The "nested" and "own" flags cannot be combined.', undefined, ssfi ); } if (obj === null || obj === undefined) { throw new AssertionError( flagMsg + 'Target cannot be null or undefined.', undefined, ssfi ); } let isDeep = flag(this, 'deep'), negate = flag(this, 'negate'), pathInfo = isNested ? _.getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name], isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; let descriptor = ''; if (isDeep) descriptor += 'deep '; if (isOwn) descriptor += 'own '; if (isNested) descriptor += 'nested '; descriptor += 'property '; let hasProperty; if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); else if (isNested) hasProperty = pathInfo.exists; else hasProperty = _.hasProperty(obj, name); // When performing a negated assertion for both name and val, merely having // a property with the given name isn't enough to cause the assertion to // fail. It must both have a property with the given name, and the value of // that property must equal the given val. Therefore, skip this assertion in // favor of the next. if (!negate || arguments.length === 1) { this.assert( hasProperty, 'expected #{this} to have ' + descriptor + _.inspect(name), 'expected #{this} to not have ' + descriptor + _.inspect(name) ); } if (arguments.length > 1) { this.assert( hasProperty && isEql(val, value), 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}', 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}', val, value ); } flag(this, 'object', value); } Assertion.addMethod('property', assertProperty); /** * @param {unknown} _name * @param {unknown} _value * @param {string} _msg */ function assertOwnProperty(_name, _value, _msg) { flag(this, 'own', true); assertProperty.apply(this, arguments); } Assertion.addMethod('ownProperty', assertOwnProperty); Assertion.addMethod('haveOwnProperty', assertOwnProperty); /** * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) * * Asserts that the target has its own property descriptor with the given key * `name`. Enumerable and non-enumerable properties are included in the * search. * * expect({a: 1}).to.have.ownPropertyDescriptor('a'); * * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that * the property's descriptor is deeply equal to the given `descriptor`. See * the `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * expect({a: 1}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. * * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); * * However, it's dangerous to negate `.ownPropertyDescriptor` when providing * a `descriptor`. The problem is that it creates uncertain expectations by * asserting that the target either doesn't have a property descriptor with * the given key `name`, or that it does have a property descriptor with the * given key `name` but it’s not deeply equal to the given `descriptor`. It's * often best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to have a property descriptor with the given * key `name`, it's often best to assert exactly that. * * // Recommended * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); * * // Not recommended * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * When the target is expected to have a property descriptor with the given * key `name`, it's often best to assert that the property has its expected * descriptor, rather than asserting that it doesn't have one of many * unexpected descriptors. * * // Recommended * expect({a: 3}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 3, * }); * * // Not recommended * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * `.ownPropertyDescriptor` changes the target of any assertions that follow * in the chain to be the value of the property descriptor from the original * target object. * * expect({a: 1}).to.have.ownPropertyDescriptor('a') * .that.has.property('enumerable', true); * * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a * custom error message to show when the assertion fails. The message can also * be given as the second argument to `expect`. When not providing * `descriptor`, only use the second form. * * // Recommended * expect({a: 1}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 2, * }, 'nooo why fail??'); * * // Recommended * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 2, * }); * * // Recommended * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); * * // Not recommended * expect({a: 1}) * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); * * The above assertion isn't the same thing as not providing `descriptor`. * Instead, it's asserting that the target object has a `b` property * descriptor that's deeply equal to `undefined`. * * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with * `.ownPropertyDescriptor`. * * @name ownPropertyDescriptor * @alias haveOwnPropertyDescriptor * @param {string} name * @param {object} descriptor _optional_ * @param {string} msg _optional_ * @namespace BDD * @public */ function assertOwnPropertyDescriptor(name, descriptor, msg) { if (typeof descriptor === 'string') { msg = descriptor; descriptor = null; } if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'); let actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); let eql = flag(this, 'eql'); if (actualDescriptor && descriptor) { this.assert( eql(descriptor, actualDescriptor), 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor), 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor), descriptor, actualDescriptor, true ); } else { this.assert( actualDescriptor, 'expected #{this} to have an own property descriptor for ' + _.inspect(name), 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) ); } flag(this, 'object', actualDescriptor); } Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); /** */ function assertLengthChain() { flag(this, 'doLength', true); } /** * ### .lengthOf(n[, msg]) * * Asserts that the target's `length` or `size` is equal to the given number * `n`. * * expect([1, 2, 3]).to.have.lengthOf(3); * expect('foo').to.have.lengthOf(3); * expect(new Set([1, 2, 3])).to.have.lengthOf(3); * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); * * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often * best to assert that the target's `length` property is equal to its expected * value, rather than not equal to one of many unexpected values. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.not.have.lengthOf(4); // Not recommended * * `.lengthOf` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); * * `.lengthOf` can also be used as a language chain, causing all `.above`, * `.below`, `.least`, `.most`, and `.within` assertions that follow in the * chain to use the target's `length` property as the target. However, it's * often best to assert that the target's `length` property is equal to its * expected length, rather than asserting that its `length` property falls * within some range of values. * * // Recommended * expect([1, 2, 3]).to.have.lengthOf(3); * * // Not recommended * expect([1, 2, 3]).to.have.lengthOf.above(2); * expect([1, 2, 3]).to.have.lengthOf.below(4); * expect([1, 2, 3]).to.have.lengthOf.at.least(3); * expect([1, 2, 3]).to.have.lengthOf.at.most(3); * expect([1, 2, 3]).to.have.lengthOf.within(2,4); * * Due to a compatibility issue, the alias `.length` can't be chained directly * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used * interchangeably with `.lengthOf` in every situation. It's recommended to * always use `.lengthOf` instead of `.length`. * * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected * * @name lengthOf * @alias length * @param {number} n * @param {string} msg _optional_ * @namespace BDD * @public */ function assertLength(n, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'), descriptor = 'length', itemsCount; switch (objType) { case 'map': case 'set': descriptor = 'size'; itemsCount = obj.size; break; default: new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); itemsCount = obj.length; } this.assert( itemsCount == n, 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}', 'expected #{this} to not have a ' + descriptor + ' of #{act}', n, itemsCount ); } Assertion.addChainableMethod('length', assertLength, assertLengthChain); Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); /** * ### .match(re[, msg]) * * Asserts that the target matches the given regular expression `re`. * * expect('foobar').to.match(/^foo/); * * Add `.not` earlier in the chain to negate `.match`. * * expect('foobar').to.not.match(/taco/); * * `.match` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect('foobar').to.match(/taco/, 'nooo why fail??'); * expect('foobar', 'nooo why fail??').to.match(/taco/); * * The alias `.matches` can be used interchangeably with `.match`. * * @name match * @alias matches * @param {RegExp} re * @param {string} msg _optional_ * @namespace BDD * @public */ function assertMatch(re, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'); this.assert( re.exec(obj), 'expected #{this} to match ' + re, 'expected #{this} not to match ' + re ); } Assertion.addMethod('match', assertMatch); Assertion.addMethod('matches', assertMatch); /** * ### .string(str[, msg]) * * Asserts that the target string contains the given substring `str`. * * expect('foobar').to.have.string('bar'); * * Add `.not` earlier in the chain to negate `.string`. * * expect('foobar').to.not.have.string('taco'); * * `.string` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect('foobar').to.have.string('taco', 'nooo why fail??'); * expect('foobar', 'nooo why fail??').to.have.string('taco'); * * @name string * @param {string} str * @param {string} msg _optional_ * @namespace BDD * @public */ Assertion.addMethod('string', function (str, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).is.a('string'); this.assert( ~obj.indexOf(str), 'expected #{this} to contain ' + _.inspect(str), 'expected #{this} to not contain ' + _.inspect(str) ); }); /** * ### .keys(key1[, key2[, ...]]) * * Asserts that the target object, array, map, or set has the given keys. Only * the target's own inherited properties are included in the search. * * When the target is an object or array, keys can be provided as one or more * string arguments, a single array argument, or a single object argument. In * the latter case, only the keys in the given object matter; the values are * ignored. * * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * expect(['x', 'y']).to.have.all.keys(0, 1); * * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); * expect(['x', 'y']).to.have.all.keys([0, 1]); * * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 * * When the target is a map or set, each key must be provided as a separate * argument. * * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); * * Because `.keys` does different things based on the target's type, it's * important to check the target's type before using `.keys`. See the `.a` doc * for info on testing a target's type. * * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); * * By default, strict (`===`) equality is used to compare keys of maps and * sets. Add `.deep` earlier in the chain to use deep equality instead. See * the `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target set deeply (but not strictly) has key `{a: 1}` * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); * * By default, the target must have all of the given keys and no more. Add * `.any` earlier in the chain to only require that the target have at least * one of the given keys. Also, add `.not` earlier in the chain to negate * `.keys`. It's often best to add `.any` when negating `.keys`, and to use * `.all` when asserting `.keys` without negation. * * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts * exactly what's expected of the output, whereas `.not.all.keys` creates * uncertain expectations. * * // Recommended; asserts that target doesn't have any of the given keys * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); * * // Not recommended; asserts that target doesn't have all of the given * // keys but may or may not have some of them * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); * * When asserting `.keys` without negation, `.all` is preferred because * `.all.keys` asserts exactly what's expected of the output, whereas * `.any.keys` creates uncertain expectations. * * // Recommended; asserts that target has all the given keys * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * * // Not recommended; asserts that target has at least one of the given * // keys but may or may not have more of them * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); * * Note that `.all` is used by default when neither `.all` nor `.any` appear * earlier in the chain. However, it's often best to add `.all` anyway because * it improves readability. * * // Both assertions are identical * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended * * Add `.include` earlier in the chain to require that the target's keys be a * superset of the expected keys, rather than identical sets. * * // Target object's keys are a superset of ['a', 'b'] but not identical * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); * * However, if `.any` and `.include` are combined, only the `.any` takes * effect. The `.include` is ignored in this case. * * // Both assertions are identical * expect({a: 1}).to.have.any.keys('a', 'b'); * expect({a: 1}).to.include.any.keys('a', 'b'); * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.have.key('b'); * * The alias `.key` can be used interchangeably with `.keys`. * * @name keys * @alias key * @param {...string | Array | object} keys * @namespace BDD * @public */ function assertKeys(keys) { let obj = flag(this, 'object'), objType = _.type(obj), keysType = _.type(keys), ssfi = flag(this, 'ssfi'), isDeep = flag(this, 'deep'), str, deepStr = '', actual, ok = true, flagMsg = flag(this, 'message'); flagMsg = flagMsg ? flagMsg + ': ' : ''; let mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; if (objType === 'Map' || objType === 'Set') { deepStr = isDeep ? 'deeply ' : ''; actual = []; // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. obj.forEach(function (val, key) { actual.push(key); }); if (keysType !== 'Array') { keys = Array.prototype.slice.call(arguments); } } else { actual = _.getOwnEnumerableProperties(obj); switch (keysType) { case 'Array': if (arguments.length > 1) { throw new AssertionError(mixedArgsMsg, undefined, ssfi); } break; case 'Object': if (arguments.length > 1) { throw new AssertionError(mixedArgsMsg, undefined, ssfi); } keys = Object.keys(keys); break; default: keys = Array.prototype.slice.call(arguments); } // Only stringify non-Symbols because Symbols would become "Symbol()" keys = keys.map(function (val) { return typeof val === 'symbol' ? val : String(val); }); } if (!keys.length) { throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); } let len = keys.length, any = flag(this, 'any'), all = flag(this, 'all'), expected = keys, isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; if (!any && !all) { all = true; } // Has any if (any) { ok = expected.some(function (expectedKey) { return actual.some(function (actualKey) { return isEql(expectedKey, actualKey); }); }); } // Has all if (all) { ok = expected.every(function (expectedKey) { return actual.some(function (actualKey) { return isEql(expectedKey, actualKey); }); }); if (!flag(this, 'contains')) { ok = ok && keys.length == actual.length; } } // Key string if (len > 1) { keys = keys.map(function (key) { return _.inspect(key); }); let last = keys.pop(); if (all) { str = keys.join(', ') + ', and ' + last; } if (any) { str = keys.join(', ') + ', or ' + last; } } else { str = _.inspect(keys[0]); } // Form str = (len > 1 ? 'keys ' : 'key ') + str; // Have / include str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; // Assertion this.assert( ok, 'expected #{this} to ' + deepStr + str, 'expected #{this} to not ' + deepStr + str, expected.slice(0).sort(_.compareByInspect), actual.sort(_.compareByInspect), true ); } Assertion.addMethod('keys', assertKeys); Assertion.addMethod('key', assertKeys); /** * ### .throw([errorLike], [errMsgMatcher], [msg]) * * When no arguments are provided, `.throw` invokes the target function and * asserts that an error is thrown. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * expect(badFn).to.throw(); * * When one argument is provided, and it's an error constructor, `.throw` * invokes the target function and asserts that an error is thrown that's an * instance of that error constructor. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * expect(badFn).to.throw(TypeError); * * When one argument is provided, and it's an error instance, `.throw` invokes * the target function and asserts that an error is thrown that's strictly * (`===`) equal to that error instance. * * var err = new TypeError('Illegal salmon!'); * var badFn = function () { throw err; }; * * expect(badFn).to.throw(err); * * When one argument is provided, and it's a string, `.throw` invokes the * target function and asserts that an error is thrown with a message that * contains that string. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * expect(badFn).to.throw('salmon'); * * When one argument is provided, and it's a regular expression, `.throw` * invokes the target function and asserts that an error is thrown with a * message that matches that regular expression. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * expect(badFn).to.throw(/salmon/); * * When two arguments are provided, and the first is an error instance or * constructor, and the second is a string or regular expression, `.throw` * invokes the function and asserts that an error is thrown that fulfills both * conditions as described above. * * var err = new TypeError('Illegal salmon!'); * var badFn = function () { throw err; }; * * expect(badFn).to.throw(TypeError, 'salmon'); * expect(badFn).to.throw(TypeError, /salmon/); * expect(badFn).to.throw(err, 'salmon'); * expect(badFn).to.throw(err, /salmon/); * * Add `.not` earlier in the chain to negate `.throw`. * * var goodFn = function () {}; * expect(goodFn).to.not.throw(); * * However, it's dangerous to negate `.throw` when providing any arguments. * The problem is that it creates uncertain expectations by asserting that the * target either doesn't throw an error, or that it throws an error but of a * different type than the given type, or that it throws an error of the given * type but with a message that doesn't include the given string. It's often * best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to throw an error, it's often best to assert * exactly that. * * var goodFn = function () {}; * * expect(goodFn).to.not.throw(); // Recommended * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended * * When the target is expected to throw an error, it's often best to assert * that the error is of its expected type, and has a message that includes an * expected string, rather than asserting that it doesn't have one of many * unexpected types, and doesn't have a message that includes some string. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended * * `.throw` changes the target of any assertions that follow in the chain to * be the error object that's thrown. * * var err = new TypeError('Illegal salmon!'); * err.code = 42; * var badFn = function () { throw err; }; * * expect(badFn).to.throw(TypeError).with.property('code', 42); * * `.throw` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. When not providing two arguments, always use * the second form. * * var goodFn = function () {}; * * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); * expect(goodFn, 'nooo why fail??').to.throw(); * * Due to limitations in ES5, `.throw` may not always work as expected when * using a transpiler such as Babel or TypeScript. In particular, it may * produce unexpected results when subclassing the built-in `Error` object and * then passing the subclassed constructor to `.throw`. See your transpiler's * docs for details: * * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) * * Beware of some common mistakes when using the `throw` assertion. One common * mistake is to accidentally invoke the function yourself instead of letting * the `throw` assertion invoke the function for you. For example, when * testing if a function named `fn` throws, provide `fn` instead of `fn()` as * the target for the assertion. * * expect(fn).to.throw(); // Good! Tests `fn` as desired * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` * * If you need to assert that your function `fn` throws when passed certain * arguments, then wrap a call to `fn` inside of another function. * * expect(function () { fn(42); }).to.throw(); // Function expression * expect(() => fn(42)).to.throw(); // ES6 arrow function * * Another common mistake is to provide an object method (or any stand-alone * function that relies on `this`) as the target of the assertion. Doing so is * problematic because the `this` context will be lost when the function is * invoked by `.throw`; there's no way for it to know what `this` is supposed * to be. There are two ways around this problem. One solution is to wrap the * method or function call inside of another function. Another solution is to * use `bind`. * * expect(function () { cat.meow(); }).to.throw(); // Function expression * expect(() => cat.meow()).to.throw(); // ES6 arrow function * expect(cat.meow.bind(cat)).to.throw(); // Bind * * Finally, it's worth mentioning that it's a best practice in JavaScript to * only throw `Error` and derivatives of `Error` such as `ReferenceError`, * `TypeError`, and user-defined objects that extend `Error`. No other type of * value will generate a stack trace when initialized. With that said, the * `throw` assertion does technically support any type of value being thrown, * not just `Error` and its derivatives. * * The aliases `.throws` and `.Throw` can be used interchangeably with * `.throw`. * * @name throw * @alias throws * @alias Throw * @param {Error} errorLike * @param {string | RegExp} errMsgMatcher error message * @param {string} msg _optional_ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @returns {void} error for chaining (null if no error) * @namespace BDD * @public */ function assertThrows(errorLike, errMsgMatcher, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), ssfi = flag(this, 'ssfi'), flagMsg = flag(this, 'message'), negate = flag(this, 'negate') || false; new Assertion(obj, flagMsg, ssfi, true).is.a('function'); if (_.isRegExp(errorLike) || typeof errorLike === 'string') { errMsgMatcher = errorLike; errorLike = null; } let caughtErr; let errorWasThrown = false; try { obj(); } catch (err) { errorWasThrown = true; caughtErr = err; } // If we have the negate flag enabled and at least one valid argument it means we do expect an error // but we want it to match a given set of criteria let everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible // See Issue #551 and PR #683@GitHub let everyArgIsDefined = Boolean(errorLike && errMsgMatcher); let errorLikeFail = false; let errMsgMatcherFail = false; // Checking if error was thrown if (everyArgIsUndefined || (!everyArgIsUndefined && !negate)) { // We need this to display results correctly according to their types let errorLikeString = 'an error'; if (errorLike instanceof Error) { errorLikeString = '#{exp}'; } else if (errorLike) { errorLikeString = _.checkError.getConstructorName(errorLike); } let actual = caughtErr; if (caughtErr instanceof Error) { actual = caughtErr.toString(); } else if (typeof caughtErr === 'string') { actual = caughtErr; } else if ( caughtErr && (typeof caughtErr === 'object' || typeof caughtErr === 'function') ) { try { actual = _.checkError.getConstructorName(caughtErr); } catch (_err) { // somehow wasn't a constructor, maybe we got a function thrown // or similar } } this.assert( errorWasThrown, 'expected #{this} to throw ' + errorLikeString, 'expected #{this} to not throw an error but #{act} was thrown', errorLike && errorLike.toString(), actual ); } if (errorLike && caughtErr) { // We should compare instances only if `errorLike` is an instance of `Error` if (errorLike instanceof Error) { let isCompatibleInstance = _.checkError.compatibleInstance( caughtErr, errorLike ); if (isCompatibleInstance === negate) { // These checks were created to ensure we won't fail too soon when we've got both args and a negate // See Issue #551 and PR #683@GitHub if (everyArgIsDefined && negate) { errorLikeFail = true; } else { this.assert( negate, 'expected #{this} to throw #{exp} but #{act} was thrown', 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : ''), errorLike.toString(), caughtErr.toString() ); } } } let isCompatibleConstructor = _.checkError.compatibleConstructor( caughtErr, errorLike ); if (isCompatibleConstructor === negate) { if (everyArgIsDefined && negate) { errorLikeFail = true; } else { this.assert( negate, 'expected #{this} to throw #{exp} but #{act} was thrown', 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : ''), errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) ); } } } if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { // Here we check compatible messages let placeholder = 'including'; if (_.isRegExp(errMsgMatcher)) { placeholder = 'matching'; } let isCompatibleMessage = _.checkError.compatibleMessage( caughtErr, errMsgMatcher ); if (isCompatibleMessage === negate) { if (everyArgIsDefined && negate) { errMsgMatcherFail = true; } else { this.assert( negate, 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}', 'expected #{this} to throw error not ' + placeholder + ' #{exp}', errMsgMatcher, _.checkError.getMessage(caughtErr) ); } } } // If both assertions failed and both should've matched we throw an error if (errorLikeFail && errMsgMatcherFail) { this.assert( negate, 'expected #{this} to throw #{exp} but #{act} was thrown', 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : ''), errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) ); } flag(this, 'object', caughtErr); } Assertion.addMethod('throw', assertThrows); Assertion.addMethod('throws', assertThrows); Assertion.addMethod('Throw', assertThrows); /** * ### .respondTo(method[, msg]) * * When the target is a non-function object, `.respondTo` asserts that the * target has a method with the given name `method`. The method can be own or * inherited, and it can be enumerable or non-enumerable. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(new Cat()).to.respondTo('meow'); * * When the target is a function, `.respondTo` asserts that the target's * `prototype` property has a method with the given name `method`. Again, the * method can be own or inherited, and it can be enumerable or non-enumerable. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(Cat).to.respondTo('meow'); * * Add `.itself` earlier in the chain to force `.respondTo` to treat the * target as a non-function object, even if it's a function. Thus, it asserts * that the target has a method with the given name `method`, rather than * asserting that the target's `prototype` property has a method with the * given name `method`. * * function Cat () {} * Cat.prototype.meow = function () {}; * Cat.hiss = function () {}; * * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); * * When not adding `.itself`, it's important to check the target's type before * using `.respondTo`. See the `.a` doc for info on checking a target's type. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); * * Add `.not` earlier in the chain to negate `.respondTo`. * * function Dog () {} * Dog.prototype.bark = function () {}; * * expect(new Dog()).to.not.respondTo('meow'); * * `.respondTo` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect({}).to.respondTo('meow', 'nooo why fail??'); * expect({}, 'nooo why fail??').to.respondTo('meow'); * * The alias `.respondsTo` can be used interchangeably with `.respondTo`. * * @name respondTo * @alias respondsTo * @param {string} method * @param {string} msg _optional_ * @namespace BDD * @public */ function respondTo(method, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), itself = flag(this, 'itself'), context = 'function' === typeof obj && !itself ? obj.prototype[method] : obj[method]; this.assert( 'function' === typeof context, 'expected #{this} to respond to ' + _.inspect(method), 'expected #{this} to not respond to ' + _.inspect(method) ); } Assertion.addMethod('respondTo', respondTo); Assertion.addMethod('respondsTo', respondTo); /** * ### .itself * * Forces all `.respondTo` assertions that follow in the chain to behave as if * the target is a non-function object, even if it's a function. Thus, it * causes `.respondTo` to assert that the target has a method with the given * name, rather than asserting that the target's `prototype` property has a * method with the given name. * * function Cat () {} * Cat.prototype.meow = function () {}; * Cat.hiss = function () {}; * * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); * * @name itself * @namespace BDD * @public */ Assertion.addProperty('itself', function () { flag(this, 'itself', true); }); /** * ### .satisfy(matcher[, msg]) * * Invokes the given `matcher` function with the target being passed as the * first argument, and asserts that the value returned is truthy. * * expect(1).to.satisfy(function(num) { * return num > 0; * }); * * Add `.not` earlier in the chain to negate `.satisfy`. * * expect(1).to.not.satisfy(function(num) { * return num > 2; * }); * * `.satisfy` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1).to.satisfy(function(num) { * return num > 2; * }, 'nooo why fail??'); * * expect(1, 'nooo why fail??').to.satisfy(function(num) { * return num > 2; * }); * * The alias `.satisfies` can be used interchangeably with `.satisfy`. * * @name satisfy * @alias satisfies * @param {Function} matcher * @param {string} msg _optional_ * @namespace BDD * @public */ function satisfy(matcher, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'); let result = matcher(obj); this.assert( result, 'expected #{this} to satisfy ' + _.objDisplay(matcher), 'expected #{this} to not satisfy' + _.objDisplay(matcher), flag(this, 'negate') ? false : true, result ); } Assertion.addMethod('satisfy', satisfy); Assertion.addMethod('satisfies', satisfy); /** * ### .closeTo(expected, delta[, msg]) * * Asserts that the target is a number that's within a given +/- `delta` range * of the given number `expected`. However, it's often best to assert that the * target is equal to its expected value. * * // Recommended * expect(1.5).to.equal(1.5); * * // Not recommended * expect(1.5).to.be.closeTo(1, 0.5); * expect(1.5).to.be.closeTo(2, 0.5); * expect(1.5).to.be.closeTo(1, 1); * * Add `.not` earlier in the chain to negate `.closeTo`. * * expect(1.5).to.equal(1.5); // Recommended * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended * * `.closeTo` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); * * The alias `.approximately` can be used interchangeably with `.closeTo`. * * @name closeTo * @alias approximately * @param {number} expected * @param {number} delta * @param {string} msg _optional_ * @namespace BDD * @public */ function closeTo(expected, delta, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).is.numeric; let message = 'A `delta` value is required for `closeTo`'; if (delta == undefined) { throw new AssertionError( flagMsg ? `${flagMsg}: ${message}` : message, undefined, ssfi ); } new Assertion(delta, flagMsg, ssfi, true).is.numeric; message = 'A `expected` value is required for `closeTo`'; if (expected == undefined) { throw new AssertionError( flagMsg ? `${flagMsg}: ${message}` : message, undefined, ssfi ); } new Assertion(expected, flagMsg, ssfi, true).is.numeric; const abs = (x) => (x < 0n ? -x : x); // Used to round floating point number precision arithmetics // See: https://stackoverflow.com/a/3644302 const strip = (number) => parseFloat(parseFloat(number).toPrecision(12)); this.assert( strip(abs(obj - expected)) <= delta, 'expected #{this} to be close to ' + expected + ' +/- ' + delta, 'expected #{this} not to be close to ' + expected + ' +/- ' + delta ); } Assertion.addMethod('closeTo', closeTo); Assertion.addMethod('approximately', closeTo); /** * @param {unknown} _subset * @param {unknown} _superset * @param {unknown} cmp * @param {unknown} contains * @param {unknown} ordered * @returns {boolean} */ function isSubsetOf(_subset, _superset, cmp, contains, ordered) { let superset = Array.from(_superset); let subset = Array.from(_subset); if (!contains) { if (subset.length !== superset.length) return false; superset = superset.slice(); } return subset.every(function (elem, idx) { if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; if (!cmp) { let matchIdx = superset.indexOf(elem); if (matchIdx === -1) return false; // Remove match from superset so not counted twice if duplicate in subset. if (!contains) superset.splice(matchIdx, 1); return true; } return superset.some(function (elem2, matchIdx) { if (!cmp(elem, elem2)) return false; // Remove match from superset so not counted twice if duplicate in subset. if (!contains) superset.splice(matchIdx, 1); return true; }); }); } /** * ### .members(set[, msg]) * * Asserts that the target array has the same members as the given array * `set`. * * expect([1, 2, 3]).to.have.members([2, 1, 3]); * expect([1, 2, 2]).to.have.members([2, 1, 2]); * * By default, members are compared using strict (`===`) equality. Add `.deep` * earlier in the chain to use deep equality instead. See the `deep-eql` * project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target array deeply (but not strictly) has member `{a: 1}` * expect([{a: 1}]).to.have.deep.members([{a: 1}]); * expect([{a: 1}]).to.not.have.members([{a: 1}]); * * By default, order doesn't matter. Add `.ordered` earlier in the chain to * require that members appear in the same order. * * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); * expect([1, 2, 3]).to.have.members([2, 1, 3]) * .but.not.ordered.members([2, 1, 3]); * * By default, both arrays must be the same size. Add `.include` earlier in * the chain to require that the target's members be a superset of the * expected members. Note that duplicates are ignored in the subset when * `.include` is added. * * // Target array is a superset of [1, 2] but not identical * expect([1, 2, 3]).to.include.members([1, 2]); * expect([1, 2, 3]).to.not.have.members([1, 2]); * * // Duplicates in the subset are ignored * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); * * `.deep`, `.ordered`, and `.include` can all be combined. However, if * `.include` and `.ordered` are combined, the ordering begins at the start of * both arrays. * * expect([{a: 1}, {b: 2}, {c: 3}]) * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); * * Add `.not` earlier in the chain to negate `.members`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the target array doesn't have all of the same members as * the given array `set` but may or may not have some of them. It's often best * to identify the exact output that's expected, and then write an assertion * that only accepts that exact output. * * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended * * `.members` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); * * @name members * @param {Array} set * @param {string} msg _optional_ * @namespace BDD * @public */ Assertion.addMethod('members', function (subset, msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).to.be.iterable; new Assertion(subset, flagMsg, ssfi, true).to.be.iterable; let contains = flag(this, 'contains'); let ordered = flag(this, 'ordered'); let subject, failMsg, failNegateMsg; if (contains) { subject = ordered ? 'an ordered superset' : 'a superset'; failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; } else { subject = ordered ? 'ordered members' : 'members'; failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; } let cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined; this.assert( isSubsetOf(subset, obj, cmp, contains, ordered), failMsg, failNegateMsg, subset, obj, true ); }); /** * ### .iterable * * Asserts that the target is an iterable, which means that it has a iterator. * * expect([1, 2]).to.be.iterable; * expect("foobar").to.be.iterable; * * Add `.not` earlier in the chain to negate `.iterable`. * * expect(1).to.not.be.iterable; * expect(true).to.not.be.iterable; * * A custom error message can be given as the second argument to `expect`. * * expect(1, 'nooo why fail??').to.be.iterable; * * @name iterable * @namespace BDD * @public */ Assertion.addProperty('iterable', function (msg) { if (msg) flag(this, 'message', msg); let obj = flag(this, 'object'); this.assert( obj != undefined && obj[Symbol.iterator], 'expected #{this} to be an iterable', 'expected #{this} to not be an iterable', obj ); }); /** * ### .oneOf(list[, msg]) * * Asserts that the target is a member of the given array `list`. However, * it's often best to assert that the target is equal to its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended * * Comparisons are performed using strict (`===`) equality. * * Add `.not` earlier in the chain to negate `.oneOf`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended * * It can also be chained with `.contain` or `.include`, which will work with * both arrays and strings: * * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) * expect([1,2,3]).to.contain.oneOf([3,4,5]) * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) * * `.oneOf` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); * * @name oneOf * @param {Array<*>} list * @param {string} msg _optional_ * @namespace BDD * @public */ function oneOf(list, msg) { if (msg) flag(this, 'message', msg); let expected = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'), contains = flag(this, 'contains'), isDeep = flag(this, 'deep'), eql = flag(this, 'eql'); new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); if (contains) { this.assert( list.some(function (possibility) { return expected.indexOf(possibility) > -1; }), 'expected #{this} to contain one of #{exp}', 'expected #{this} to not contain one of #{exp}', list, expected ); } else { if (isDeep) { this.assert( list.some(function (possibility) { return eql(expected, possibility); }), 'expected #{this} to deeply equal one of #{exp}', 'expected #{this} to deeply equal one of #{exp}', list, expected ); } else { this.assert( list.indexOf(expected) > -1, 'expected #{this} to be one of #{exp}', 'expected #{this} to not be one of #{exp}', list, expected ); } } } Assertion.addMethod('oneOf', oneOf); /** * ### .change(subject[, prop[, msg]]) * * When one argument is provided, `.change` asserts that the given function * `subject` returns a different value when it's invoked before the target * function compared to when it's invoked afterward. However, it's often best * to assert that `subject` is equal to its expected value. * * var dots = '' * , addDot = function () { dots += '.'; } * , getDots = function () { return dots; }; * * // Recommended * expect(getDots()).to.equal(''); * addDot(); * expect(getDots()).to.equal('.'); * * // Not recommended * expect(addDot).to.change(getDots); * * When two arguments are provided, `.change` asserts that the value of the * given object `subject`'s `prop` property is different before invoking the * target function compared to afterward. * * var myObj = {dots: ''} * , addDot = function () { myObj.dots += '.'; }; * * // Recommended * expect(myObj).to.have.property('dots', ''); * addDot(); * expect(myObj).to.have.property('dots', '.'); * * // Not recommended * expect(addDot).to.change(myObj, 'dots'); * * Strict (`===`) equality is used to compare before and after values. * * Add `.not` earlier in the chain to negate `.change`. * * var dots = '' * , noop = function () {} * , getDots = function () { return dots; }; * * expect(noop).to.not.change(getDots); * * var myObj = {dots: ''} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'dots'); * * `.change` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {dots: ''} * , addDot = function () { myObj.dots += '.'; }; * * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); * * var dots = '' * , addDot = function () { dots += '.'; } * , getDots = function () { return dots; }; * * expect(addDot, 'nooo why fail??').to.not.change(getDots); * * `.change` also causes all `.by` assertions that follow in the chain to * assert how much a numeric subject was increased or decreased by. However, * it's dangerous to use `.change.by`. The problem is that it creates * uncertain expectations by asserting that the subject either increases by * the given delta, or that it decreases by the given delta. It's often best * to identify the exact output that's expected, and then write an assertion * that only accepts that exact output. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; } * , subtractTwo = function () { myObj.val -= 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended * * The alias `.changes` can be used interchangeably with `.change`. * * @name change * @alias changes * @param {string} subject * @param {string} prop name _optional_ * @param {string} msg _optional_ * @namespace BDD * @public */ function assertChanges(subject, prop, msg) { if (msg) flag(this, 'message', msg); let fn = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); let initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } fn(); let final = prop === undefined || prop === null ? subject() : subject[prop]; let msgObj = prop === undefined || prop === null ? initial : '.' + prop; // This gets flagged because of the .by(delta) assertion flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'change'); flag(this, 'realDelta', final !== initial); this.assert( initial !== final, 'expected ' + msgObj + ' to change', 'expected ' + msgObj + ' to not change' ); } Assertion.addMethod('change', assertChanges); Assertion.addMethod('changes', assertChanges); /** * ### .increase(subject[, prop[, msg]]) * * When one argument is provided, `.increase` asserts that the given function * `subject` returns a greater number when it's invoked after invoking the * target function compared to when it's invoked beforehand. `.increase` also * causes all `.by` assertions that follow in the chain to assert how much * greater of a number is returned. It's often best to assert that the return * value increased by the expected amount, rather than asserting it increased * by any amount. * * var val = 1 * , addTwo = function () { val += 2; } * , getVal = function () { return val; }; * * expect(addTwo).to.increase(getVal).by(2); // Recommended * expect(addTwo).to.increase(getVal); // Not recommended * * When two arguments are provided, `.increase` asserts that the value of the * given object `subject`'s `prop` property is greater after invoking the * target function compared to beforehand. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.increase(myObj, 'val'); // Not recommended * * Add `.not` earlier in the chain to negate `.increase`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either decreases, or that it stays the same. * It's often best to identify the exact output that's expected, and then * write an assertion that only accepts that exact output. * * When the subject is expected to decrease, it's often best to assert that it * decreased by the expected amount. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended * * When the subject is expected to stay the same, it's often best to assert * exactly that. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'val'); // Recommended * expect(noop).to.not.increase(myObj, 'val'); // Not recommended * * `.increase` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); * * var val = 1 * , noop = function () {} * , getVal = function () { return val; }; * * expect(noop, 'nooo why fail??').to.increase(getVal); * * The alias `.increases` can be used interchangeably with `.increase`. * * @name increase * @alias increases * @param {string | Function} subject * @param {string} prop name _optional_ * @param {string} msg _optional_ * @namespace BDD * @public */ function assertIncreases(subject, prop, msg) { if (msg) flag(this, 'message', msg); let fn = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); let initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } // Make sure that the target is a number new Assertion(initial, flagMsg, ssfi, true).is.a('number'); fn(); let final = prop === undefined || prop === null ? subject() : subject[prop]; let msgObj = prop === undefined || prop === null ? initial : '.' + prop; flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'increase'); flag(this, 'realDelta', final - initial); this.assert( final - initial > 0, 'expected ' + msgObj + ' to increase', 'expected ' + msgObj + ' to not increase' ); } Assertion.addMethod('increase', assertIncreases); Assertion.addMethod('increases', assertIncreases); /** * ### .decrease(subject[, prop[, msg]]) * * When one argument is provided, `.decrease` asserts that the given function * `subject` returns a lesser number when it's invoked after invoking the * target function compared to when it's invoked beforehand. `.decrease` also * causes all `.by` assertions that follow in the chain to assert how much * lesser of a number is returned. It's often best to assert that the return * value decreased by the expected amount, rather than asserting it decreased * by any amount. * * var val = 1 * , subtractTwo = function () { val -= 2; } * , getVal = function () { return val; }; * * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended * expect(subtractTwo).to.decrease(getVal); // Not recommended * * When two arguments are provided, `.decrease` asserts that the value of the * given object `subject`'s `prop` property is lesser after invoking the * target function compared to beforehand. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended * * Add `.not` earlier in the chain to negate `.decrease`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either increases, or that it stays the same. * It's often best to identify the exact output that's expected, and then * write an assertion that only accepts that exact output. * * When the subject is expected to increase, it's often best to assert that it * increased by the expected amount. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended * * When the subject is expected to stay the same, it's often best to assert * exactly that. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'val'); // Recommended * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended * * `.decrease` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); * * var val = 1 * , noop = function () {} * , getVal = function () { return val; }; * * expect(noop, 'nooo why fail??').to.decrease(getVal); * * The alias `.decreases` can be used interchangeably with `.decrease`. * * @name decrease * @alias decreases * @param {string | Function} subject * @param {string} prop name _optional_ * @param {string} msg _optional_ * @namespace BDD * @public */ function assertDecreases(subject, prop, msg) { if (msg) flag(this, 'message', msg); let fn = flag(this, 'object'), flagMsg = flag(this, 'message'), ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); let initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } // Make sure that the target is a number new Assertion(initial, flagMsg, ssfi, true).is.a('number'); fn(); let final = prop === undefined || prop === null ? subject() : subject[prop]; let msgObj = prop === undefined || prop === null ? initial : '.' + prop; flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'decrease'); flag(this, 'realDelta', initial - final); this.assert( final - initial < 0, 'expected ' + msgObj + ' to decrease', 'expected ' + msgObj + ' to not decrease' ); } Assertion.addMethod('decrease', assertDecreases); Assertion.addMethod('decreases', assertDecreases); /** * ### .by(delta[, msg]) * * When following an `.increase` assertion in the chain, `.by` asserts that * the subject of the `.increase` assertion increased by the given `delta`. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); * * When following a `.decrease` assertion in the chain, `.by` asserts that the * subject of the `.decrease` assertion decreased by the given `delta`. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); * * When following a `.change` assertion in the chain, `.by` asserts that the * subject of the `.change` assertion either increased or decreased by the * given `delta`. However, it's dangerous to use `.change.by`. The problem is * that it creates uncertain expectations. It's often best to identify the * exact output that's expected, and then write an assertion that only accepts * that exact output. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; } * , subtractTwo = function () { myObj.val -= 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended * * Add `.not` earlier in the chain to negate `.by`. However, it's often best * to assert that the subject changed by its expected delta, rather than * asserting that it didn't change by one of countless unexpected deltas. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * // Recommended * expect(addTwo).to.increase(myObj, 'val').by(2); * * // Not recommended * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); * * `.by` accepts an optional `msg` argument which is a custom error message to * show when the assertion fails. The message can also be given as the second * argument to `expect`. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); * * @name by * @param {number} delta * @param {string} msg _optional_ * @namespace BDD * @public */ function assertDelta(delta, msg) { if (msg) flag(this, 'message', msg); let msgObj = flag(this, 'deltaMsgObj'); let initial = flag(this, 'initialDeltaValue'); let final = flag(this, 'finalDeltaValue'); let behavior = flag(this, 'deltaBehavior'); let realDelta = flag(this, 'realDelta'); let expression; if (behavior === 'change') { expression = Math.abs(final - initial) === Math.abs(delta); } else { expression = realDelta === Math.abs(delta); } this.assert( expression, 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta, 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta ); } Assertion.addMethod('by', assertDelta); /** * ### .extensible * * Asserts that the target is extensible, which means that new properties can * be added to it. Primitives are never extensible. * * expect({a: 1}).to.be.extensible; * * Add `.not` earlier in the chain to negate `.extensible`. * * var nonExtensibleObject = Object.preventExtensions({}) * , sealedObject = Object.seal({}) * , frozenObject = Object.freeze({}); * * expect(nonExtensibleObject).to.not.be.extensible; * expect(sealedObject).to.not.be.extensible; * expect(frozenObject).to.not.be.extensible; * expect(1).to.not.be.extensible; * * A custom error message can be given as the second argument to `expect`. * * expect(1, 'nooo why fail??').to.be.extensible; * * @name extensible * @namespace BDD * @public */ Assertion.addProperty('extensible', function () { let obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible // The following provides ES6 behavior for ES5 environments. let isExtensible = obj === Object(obj) && Object.isExtensible(obj); this.assert( isExtensible, 'expected #{this} to be extensible', 'expected #{this} to not be extensible' ); }); /** * ### .sealed * * Asserts that the target is sealed, which means that new properties can't be * added to it, and its existing properties can't be reconfigured or deleted. * However, it's possible that its existing properties can still be reassigned * to different values. Primitives are always sealed. * * var sealedObject = Object.seal({}); * var frozenObject = Object.freeze({}); * * expect(sealedObject).to.be.sealed; * expect(frozenObject).to.be.sealed; * expect(1).to.be.sealed; * * Add `.not` earlier in the chain to negate `.sealed`. * * expect({a: 1}).to.not.be.sealed; * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.be.sealed; * * @name sealed * @namespace BDD * @public */ Assertion.addProperty('sealed', function () { let obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed // The following provides ES6 behavior for ES5 environments. let isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; this.assert( isSealed, 'expected #{this} to be sealed', 'expected #{this} to not be sealed' ); }); /** * ### .frozen * * Asserts that the target is frozen, which means that new properties can't be * added to it, and its existing properties can't be reassigned to different * values, reconfigured, or deleted. Primitives are always frozen. * * var frozenObject = Object.freeze({}); * * expect(frozenObject).to.be.frozen; * expect(1).to.be.frozen; * * Add `.not` earlier in the chain to negate `.frozen`. * * expect({a: 1}).to.not.be.frozen; * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.be.frozen; * * @name frozen * @namespace BDD * @public */ Assertion.addProperty('frozen', function () { let obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen // The following provides ES6 behavior for ES5 environments. let isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; this.assert( isFrozen, 'expected #{this} to be frozen', 'expected #{this} to not be frozen' ); }); /** * ### .finite * * Asserts that the target is a number, and isn't `NaN` or positive/negative * `Infinity`. * * expect(1).to.be.finite; * * Add `.not` earlier in the chain to negate `.finite`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either isn't a number, or that it's `NaN`, or * that it's positive `Infinity`, or that it's negative `Infinity`. It's often * best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to be a number, it's often best to assert * that it's the expected type, rather than asserting that it isn't one of * many unexpected types. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.finite; // Not recommended * * When the target is expected to be `NaN`, it's often best to assert exactly * that. * * expect(NaN).to.be.NaN; // Recommended * expect(NaN).to.not.be.finite; // Not recommended * * When the target is expected to be positive infinity, it's often best to * assert exactly that. * * expect(Infinity).to.equal(Infinity); // Recommended * expect(Infinity).to.not.be.finite; // Not recommended * * When the target is expected to be negative infinity, it's often best to * assert exactly that. * * expect(-Infinity).to.equal(-Infinity); // Recommended * expect(-Infinity).to.not.be.finite; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect('foo', 'nooo why fail??').to.be.finite; * * @name finite * @namespace BDD * @public */ Assertion.addProperty('finite', function (_msg) { let obj = flag(this, 'object'); this.assert( typeof obj === 'number' && isFinite(obj), 'expected #{this} to be a finite number', 'expected #{this} to not be a finite number' ); }); /** * A subset-aware compare function * * @param {unknown} expected * @param {unknown} actual * @returns {boolean} */ function compareSubset(expected, actual) { if (expected === actual) { return true; } if (typeof actual !== typeof expected) { return false; } if (typeof expected !== 'object' || expected === null) { return expected === actual; } if (!actual) { return false; } if (Array.isArray(expected)) { if (!Array.isArray(actual)) { return false; } return expected.every(function (exp) { return actual.some(function (act) { return compareSubset(exp, act); }); }); } if (expected instanceof Date) { if (actual instanceof Date) { return expected.getTime() === actual.getTime(); } else { return false; } } return Object.keys(expected).every(function (key) { let expectedValue = expected[key]; let actualValue = actual[key]; if ( typeof expectedValue === 'object' && expectedValue !== null && actualValue !== null ) { return compareSubset(expectedValue, actualValue); } if (typeof expectedValue === 'function') { return expectedValue(actualValue); } return actualValue === expectedValue; }); } /** * ### .containSubset * * Asserts that the target primitive/object/array structure deeply contains all provided fields * at the same key/depth as the provided structure. * * When comparing arrays, the target must contain the subset of at least one of each object/value in the subset array. * Order does not matter. * * expect({name: {first: "John", last: "Smith"}}).to.containSubset({name: {first: "John"}}); * * Add `.not` earlier in the chain to negate the assertion. This will cause the assertion to fail * only if the target DOES contains the provided data at the expected keys/depths. * * @name containSubset * @namespace BDD * @public */ Assertion.addMethod('containSubset', function (expected) { const actual = _.flag(this, 'object'); const showDiff = config.showDiff; this.assert( compareSubset(expected, actual), 'expected #{act} to contain subset #{exp}', 'expected #{act} to not contain subset #{exp}', expected, actual, showDiff ); }); chaijs-chai-2a3ecff/lib/chai/interface/000077500000000000000000000000001505212005400200345ustar00rootroot00000000000000chaijs-chai-2a3ecff/lib/chai/interface/assert.js000066400000000000000000002575431505212005400217130ustar00rootroot00000000000000/*! * chai * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import * as chai from '../../chai.js'; import {Assertion} from '../assertion.js'; import {flag, inspect} from '../utils/index.js'; import {AssertionError} from 'assertion-error'; /** * ### assert(expression, message) * * Write your own test expressions. * * assert('foo' !== 'bar', 'foo is not bar'); * assert(Array.isArray([]), 'empty arrays are arrays'); * * @param {unknown} express - expression to test for truthiness * @param {string} errmsg - message to display on error * @name assert * @namespace Assert * @public */ export function assert(express, errmsg) { let test = new Assertion(null, null, chai.assert, true); test.assert(express, errmsg, '[ negation message unavailable ]'); } /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. Node.js `assert` module-compatible. * * assert.fail(); * assert.fail("custom error message"); * assert.fail(1, 2); * assert.fail(1, 2, "custom error message"); * assert.fail(1, 2, "custom error message", ">"); * assert.fail(1, 2, undefined, ">"); * * @name fail * @param {unknown} actual * @param {unknown} expected * @param {string} message * @param {string} operator * @namespace Assert * @public */ assert.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { // Comply with Node's fail([message]) interface message = actual; actual = undefined; } message = message || 'assert.fail()'; throw new AssertionError( message, { actual: actual, expected: expected, operator: operator }, assert.fail ); }; /** * ### .isOk(object, [message]) * * Asserts that `object` is truthy. * * assert.isOk('everything', 'everything is ok'); * assert.isOk(false, 'this will fail'); * * @name isOk * @alias ok * @param {unknown} val object to test * @param {string} msg * @namespace Assert * @public */ assert.isOk = function (val, msg) { new Assertion(val, msg, assert.isOk, true).is.ok; }; /** * ### .isNotOk(object, [message]) * * Asserts that `object` is falsy. * * assert.isNotOk('everything', 'this will fail'); * assert.isNotOk(false, 'this will pass'); * * @name isNotOk * @alias notOk * @param {unknown} val object to test * @param {string} msg * @namespace Assert * @public */ assert.isNotOk = function (val, msg) { new Assertion(val, msg, assert.isNotOk, true).is.not.ok; }; /** * ### .equal(actual, expected, [message]) * * Asserts non-strict equality (`==`) of `actual` and `expected`. * * assert.equal(3, '3', '== coerces values to strings'); * * @name equal * @param {unknown} act * @param {unknown} exp * @param {string} msg * @namespace Assert * @public */ assert.equal = function (act, exp, msg) { let test = new Assertion(act, msg, assert.equal, true); test.assert( exp == flag(test, 'object'), 'expected #{this} to equal #{exp}', 'expected #{this} to not equal #{act}', exp, act, true ); }; /** * ### .notEqual(actual, expected, [message]) * * Asserts non-strict inequality (`!=`) of `actual` and `expected`. * * assert.notEqual(3, 4, 'these numbers are not equal'); * * @name notEqual * @param {unknown} act * @param {unknown} exp * @param {string} msg * @namespace Assert * @public */ assert.notEqual = function (act, exp, msg) { let test = new Assertion(act, msg, assert.notEqual, true); test.assert( exp != flag(test, 'object'), 'expected #{this} to not equal #{exp}', 'expected #{this} to equal #{act}', exp, act, true ); }; /** * ### .strictEqual(actual, expected, [message]) * * Asserts strict equality (`===`) of `actual` and `expected`. * * assert.strictEqual(true, true, 'these booleans are strictly equal'); * * @name strictEqual * @param {unknown} act * @param {unknown} exp * @param {string} msg * @namespace Assert * @public */ assert.strictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); }; /** * ### .notStrictEqual(actual, expected, [message]) * * Asserts strict inequality (`!==`) of `actual` and `expected`. * * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); * * @name notStrictEqual * @param {unknown} act * @param {unknown} exp * @param {string} msg * @namespace Assert * @public */ assert.notStrictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); }; /** * ### .deepEqual(actual, expected, [message]) * * Asserts that `actual` is deeply equal to `expected`. * * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); * * @name deepEqual * @param {unknown} act * @param {unknown} exp * @param {string} msg * @alias deepStrictEqual * @namespace Assert * @public */ assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); }; /** * ### .notDeepEqual(actual, expected, [message]) * * Assert that `actual` is not deeply equal to `expected`. * * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); * * @name notDeepEqual * @param {unknown} act * @param {unknown} exp * @param {string} msg * @namespace Assert * @public */ assert.notDeepEqual = function (act, exp, msg) { new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); }; /** * ### .isAbove(valueToCheck, valueToBeAbove, [message]) * * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. * * assert.isAbove(5, 2, '5 is strictly greater than 2'); * * @name isAbove * @param {unknown} val * @param {unknown} abv * @param {string} msg * @namespace Assert * @public */ assert.isAbove = function (val, abv, msg) { new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); }; /** * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) * * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. * * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); * * @name isAtLeast * @param {unknown} val * @param {unknown} atlst * @param {string} msg * @namespace Assert * @public */ assert.isAtLeast = function (val, atlst, msg) { new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); }; /** * ### .isBelow(valueToCheck, valueToBeBelow, [message]) * * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. * * assert.isBelow(3, 6, '3 is strictly less than 6'); * * @name isBelow * @param {unknown} val * @param {unknown} blw * @param {string} msg * @namespace Assert * @public */ assert.isBelow = function (val, blw, msg) { new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); }; /** * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) * * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. * * assert.isAtMost(3, 6, '3 is less than or equal to 6'); * assert.isAtMost(4, 4, '4 is less than or equal to 4'); * * @name isAtMost * @param {unknown} val * @param {unknown} atmst * @param {string} msg * @namespace Assert * @public */ assert.isAtMost = function (val, atmst, msg) { new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); }; /** * ### .isTrue(value, [message]) * * Asserts that `value` is true. * * var teaServed = true; * assert.isTrue(teaServed, 'the tea has been served'); * * @name isTrue * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isTrue = function (val, msg) { new Assertion(val, msg, assert.isTrue, true).is['true']; }; /** * ### .isNotTrue(value, [message]) * * Asserts that `value` is not true. * * var tea = 'tasty chai'; * assert.isNotTrue(tea, 'great, time for tea!'); * * @name isNotTrue * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotTrue = function (val, msg) { new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); }; /** * ### .isFalse(value, [message]) * * Asserts that `value` is false. * * var teaServed = false; * assert.isFalse(teaServed, 'no tea yet? hmm...'); * * @name isFalse * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isFalse = function (val, msg) { new Assertion(val, msg, assert.isFalse, true).is['false']; }; /** * ### .isNotFalse(value, [message]) * * Asserts that `value` is not false. * * var tea = 'tasty chai'; * assert.isNotFalse(tea, 'great, time for tea!'); * * @name isNotFalse * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotFalse = function (val, msg) { new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); }; /** * ### .isNull(value, [message]) * * Asserts that `value` is null. * * assert.isNull(err, 'there was no error'); * * @name isNull * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNull = function (val, msg) { new Assertion(val, msg, assert.isNull, true).to.equal(null); }; /** * ### .isNotNull(value, [message]) * * Asserts that `value` is not null. * * var tea = 'tasty chai'; * assert.isNotNull(tea, 'great, time for tea!'); * * @name isNotNull * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotNull = function (val, msg) { new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); }; /** * ### .isNaN * * Asserts that value is NaN. * * assert.isNaN(NaN, 'NaN is NaN'); * * @name isNaN * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNaN = function (val, msg) { new Assertion(val, msg, assert.isNaN, true).to.be.NaN; }; /** * ### .isNotNaN * * Asserts that value is not NaN. * * assert.isNotNaN(4, '4 is not NaN'); * * @name isNotNaN * @param {unknown} value * @param {string} message * @namespace Assert * @public */ assert.isNotNaN = function (value, message) { new Assertion(value, message, assert.isNotNaN, true).not.to.be.NaN; }; /** * ### .exists * * Asserts that the target is neither `null` nor `undefined`. * * var foo = 'hi'; * assert.exists(foo, 'foo is neither `null` nor `undefined`'); * * @name exists * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.exists = function (val, msg) { new Assertion(val, msg, assert.exists, true).to.exist; }; /** * ### .notExists * * Asserts that the target is either `null` or `undefined`. * * var bar = null * , baz; * * assert.notExists(bar); * assert.notExists(baz, 'baz is either null or undefined'); * * @name notExists * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.notExists = function (val, msg) { new Assertion(val, msg, assert.notExists, true).to.not.exist; }; /** * ### .isUndefined(value, [message]) * * Asserts that `value` is `undefined`. * * var tea; * assert.isUndefined(tea, 'no tea defined'); * * @name isUndefined * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isUndefined = function (val, msg) { new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); }; /** * ### .isDefined(value, [message]) * * Asserts that `value` is not `undefined`. * * var tea = 'cup of chai'; * assert.isDefined(tea, 'tea has been defined'); * * @name isDefined * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isDefined = function (val, msg) { new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); }; /** * ### .isCallable(value, [message]) * * Asserts that `value` is a callable function. * * function serveTea() { return 'cup of tea'; }; * assert.isCallable(serveTea, 'great, we can have tea now'); * * @name isCallable * @param {unknown} value * @param {string} message * @namespace Assert * @public */ assert.isCallable = function (value, message) { new Assertion(value, message, assert.isCallable, true).is.callable; }; /** * ### .isNotCallable(value, [message]) * * Asserts that `value` is _not_ a callable function. * * var serveTea = [ 'heat', 'pour', 'sip' ]; * assert.isNotCallable(serveTea, 'great, we have listed the steps'); * * @name isNotCallable * @param {unknown} value * @param {string} message * @namespace Assert * @public */ assert.isNotCallable = function (value, message) { new Assertion(value, message, assert.isNotCallable, true).is.not.callable; }; /** * ### .isObject(value, [message]) * * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). * _The assertion does not match subclassed objects._ * * var selection = { name: 'Chai', serve: 'with spices' }; * assert.isObject(selection, 'tea selection is an object'); * * @name isObject * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isObject = function (val, msg) { new Assertion(val, msg, assert.isObject, true).to.be.a('object'); }; /** * ### .isNotObject(value, [message]) * * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). * * var selection = 'chai' * assert.isNotObject(selection, 'tea selection is not an object'); * assert.isNotObject(null, 'null is not an object'); * * @name isNotObject * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotObject = function (val, msg) { new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); }; /** * ### .isArray(value, [message]) * * Asserts that `value` is an array. * * var menu = [ 'green', 'chai', 'oolong' ]; * assert.isArray(menu, 'what kind of tea do we want?'); * * @name isArray * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isArray = function (val, msg) { new Assertion(val, msg, assert.isArray, true).to.be.an('array'); }; /** * ### .isNotArray(value, [message]) * * Asserts that `value` is _not_ an array. * * var menu = 'green|chai|oolong'; * assert.isNotArray(menu, 'what kind of tea do we want?'); * * @name isNotArray * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotArray = function (val, msg) { new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); }; /** * ### .isString(value, [message]) * * Asserts that `value` is a string. * * var teaOrder = 'chai'; * assert.isString(teaOrder, 'order placed'); * * @name isString * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isString = function (val, msg) { new Assertion(val, msg, assert.isString, true).to.be.a('string'); }; /** * ### .isNotString(value, [message]) * * Asserts that `value` is _not_ a string. * * var teaOrder = 4; * assert.isNotString(teaOrder, 'order placed'); * * @name isNotString * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotString = function (val, msg) { new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); }; /** * ### .isNumber(value, [message]) * * Asserts that `value` is a number. * * var cups = 2; * assert.isNumber(cups, 'how many cups'); * * @name isNumber * @param {number} val * @param {string} msg * @namespace Assert * @public */ assert.isNumber = function (val, msg) { new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); }; /** * ### .isNotNumber(value, [message]) * * Asserts that `value` is _not_ a number. * * var cups = '2 cups please'; * assert.isNotNumber(cups, 'how many cups'); * * @name isNotNumber * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotNumber = function (val, msg) { new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); }; /** * ### .isNumeric(value, [message]) * * Asserts that `value` is a number or BigInt. * * var cups = 2; * assert.isNumeric(cups, 'how many cups'); * * var cups = 10n; * assert.isNumeric(cups, 'how many cups'); * * @name isNumeric * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNumeric = function (val, msg) { new Assertion(val, msg, assert.isNumeric, true).is.numeric; }; /** * ### .isNotNumeric(value, [message]) * * Asserts that `value` is _not_ a number or BigInt. * * var cups = '2 cups please'; * assert.isNotNumeric(cups, 'how many cups'); * * @name isNotNumeric * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotNumeric = function (val, msg) { new Assertion(val, msg, assert.isNotNumeric, true).is.not.numeric; }; /** * ### .isFinite(value, [message]) * * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. * * var cups = 2; * assert.isFinite(cups, 'how many cups'); * assert.isFinite(NaN); // throws * * @name isFinite * @param {number} val * @param {string} msg * @namespace Assert * @public */ assert.isFinite = function (val, msg) { new Assertion(val, msg, assert.isFinite, true).to.be.finite; }; /** * ### .isBoolean(value, [message]) * * Asserts that `value` is a boolean. * * var teaReady = true * , teaServed = false; * * assert.isBoolean(teaReady, 'is the tea ready'); * assert.isBoolean(teaServed, 'has tea been served'); * * @name isBoolean * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isBoolean = function (val, msg) { new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); }; /** * ### .isNotBoolean(value, [message]) * * Asserts that `value` is _not_ a boolean. * * var teaReady = 'yep' * , teaServed = 'nope'; * * assert.isNotBoolean(teaReady, 'is the tea ready'); * assert.isNotBoolean(teaServed, 'has tea been served'); * * @name isNotBoolean * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.isNotBoolean = function (val, msg) { new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); }; /** * ### .typeOf(value, name, [message]) * * Asserts that `value`'s type is `name`, as determined by * `Object.prototype.toString`. * * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); * assert.typeOf('tea', 'string', 'we have a string'); * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); * assert.typeOf(null, 'null', 'we have a null'); * assert.typeOf(undefined, 'undefined', 'we have an undefined'); * * @name typeOf * @param {unknown} val * @param {string} type * @param {string} msg * @namespace Assert * @public */ assert.typeOf = function (val, type, msg) { new Assertion(val, msg, assert.typeOf, true).to.be.a(type); }; /** * ### .notTypeOf(value, name, [message]) * * Asserts that `value`'s type is _not_ `name`, as determined by * `Object.prototype.toString`. * * assert.notTypeOf('tea', 'number', 'strings are not numbers'); * * @name notTypeOf * @param {unknown} value * @param {string} type * @param {string} message * @namespace Assert * @public */ assert.notTypeOf = function (value, type, message) { new Assertion(value, message, assert.notTypeOf, true).to.not.be.a(type); }; /** * ### .instanceOf(object, constructor, [message]) * * Asserts that `value` is an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new Tea('chai'); * * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); * * @name instanceOf * @param {object} val * @param {object} type * @param {string} msg * @namespace Assert * @public */ assert.instanceOf = function (val, type, msg) { new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); }; /** * ### .notInstanceOf(object, constructor, [message]) * * Asserts `value` is not an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new String('chai'); * * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); * * @name notInstanceOf * @param {object} val * @param {object} type * @param {string} msg * @namespace Assert * @public */ assert.notInstanceOf = function (val, type, msg) { new Assertion(val, msg, assert.notInstanceOf, true).to.not.be.instanceOf( type ); }; /** * ### .include(haystack, needle, [message]) * * Asserts that `haystack` includes `needle`. Can be used to assert the * inclusion of a value in an array, a substring in a string, or a subset of * properties in an object. * * assert.include([1,2,3], 2, 'array contains value'); * assert.include('foobar', 'foo', 'string contains substring'); * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); * * Strict equality (===) is used. When asserting the inclusion of a value in * an array, the array is searched for an element that's strictly equal to the * given value. When asserting a subset of properties in an object, the object * is searched for the given property keys, checking that each one is present * and strictly equal to the given property value. For instance: * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.include([obj1, obj2], obj1); * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); * * @name include * @param {Array | string} exp * @param {unknown} inc * @param {string} msg * @namespace Assert * @public */ assert.include = function (exp, inc, msg) { new Assertion(exp, msg, assert.include, true).include(inc); }; /** * ### .notInclude(haystack, needle, [message]) * * Asserts that `haystack` does not include `needle`. Can be used to assert * the absence of a value in an array, a substring in a string, or a subset of * properties in an object. * * assert.notInclude([1,2,3], 4, "array doesn't contain value"); * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); * * Strict equality (===) is used. When asserting the absence of a value in an * array, the array is searched to confirm the absence of an element that's * strictly equal to the given value. When asserting a subset of properties in * an object, the object is searched to confirm that at least one of the given * property keys is either not present or not strictly equal to the given * property value. For instance: * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.notInclude([obj1, obj2], {a: 1}); * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); * * @name notInclude * @param {Array | string} exp * @param {unknown} inc * @param {string} msg * @namespace Assert * @public */ assert.notInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notInclude, true).not.include(inc); }; /** * ### .deepInclude(haystack, needle, [message]) * * Asserts that `haystack` includes `needle`. Can be used to assert the * inclusion of a value in an array or a subset of properties in an object. * Deep equality is used. * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.deepInclude([obj1, obj2], {a: 1}); * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); * * @name deepInclude * @param {Array | string} exp * @param {unknown} inc * @param {string} msg * @namespace Assert * @public */ assert.deepInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); }; /** * ### .notDeepInclude(haystack, needle, [message]) * * Asserts that `haystack` does not include `needle`. Can be used to assert * the absence of a value in an array or a subset of properties in an object. * Deep equality is used. * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.notDeepInclude([obj1, obj2], {a: 9}); * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); * * @name notDeepInclude * @param {Array | string} exp * @param {unknown} inc * @param {string} msg * @namespace Assert * @public */ assert.notDeepInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); }; /** * ### .nestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); * * @name nestedInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.nestedInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); }; /** * ### .notNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' does not include 'needle'. * Can be used to assert the absence of a subset of properties in an * object. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); * * @name notNestedInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.notNestedInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notNestedInclude, true).not.nested.include( inc ); }; /** * ### .deepNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while checking for deep equality. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); * * @name deepNestedInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.deepNestedInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.deepNestedInclude, true).deep.nested.include( inc ); }; /** * ### .notDeepNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' does not include 'needle'. * Can be used to assert the absence of a subset of properties in an * object while checking for deep equality. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); * * @name notDeepNestedInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.notDeepNestedInclude = function (exp, inc, msg) { new Assertion( exp, msg, assert.notDeepNestedInclude, true ).not.deep.nested.include(inc); }; /** * ### .ownInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while ignoring inherited properties. * * assert.ownInclude({ a: 1 }, { a: 1 }); * * @name ownInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.ownInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); }; /** * ### .notOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' does not include 'needle'. * Can be used to assert the absence of a subset of properties in an * object while ignoring inherited properties. * * Object.prototype.b = 2; * assert.notOwnInclude({ a: 1 }, { b: 2 }); * * @name notOwnInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.notOwnInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); }; /** * ### .deepOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while ignoring inherited properties and checking for deep equality. * * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); * * @name deepOwnInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.deepOwnInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.deepOwnInclude, true).deep.own.include(inc); }; /** * ### .notDeepOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the absence of a subset of properties in an * object while ignoring inherited properties and checking for deep equality. * * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); * * @name notDeepOwnInclude * @param {object} exp * @param {object} inc * @param {string} msg * @namespace Assert * @public */ assert.notDeepOwnInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notDeepOwnInclude, true).not.deep.own.include( inc ); }; /** * ### .match(value, regexp, [message]) * * Asserts that `value` matches the regular expression `regexp`. * * assert.match('foobar', /^foo/, 'regexp matches'); * * @name match * @param {unknown} exp * @param {RegExp} re * @param {string} msg * @namespace Assert * @public */ assert.match = function (exp, re, msg) { new Assertion(exp, msg, assert.match, true).to.match(re); }; /** * ### .notMatch(value, regexp, [message]) * * Asserts that `value` does not match the regular expression `regexp`. * * assert.notMatch('foobar', /^foo/, 'regexp does not match'); * * @name notMatch * @param {unknown} exp * @param {RegExp} re * @param {string} msg * @namespace Assert * @public */ assert.notMatch = function (exp, re, msg) { new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); }; /** * ### .property(object, property, [message]) * * Asserts that `object` has a direct or inherited property named by * `property`. * * assert.property({ tea: { green: 'matcha' }}, 'tea'); * assert.property({ tea: { green: 'matcha' }}, 'toString'); * * @name property * @param {object} obj * @param {string} prop * @param {string} msg * @namespace Assert * @public */ assert.property = function (obj, prop, msg) { new Assertion(obj, msg, assert.property, true).to.have.property(prop); }; /** * ### .notProperty(object, property, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property`. * * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); * * @name notProperty * @param {object} obj * @param {string} prop * @param {string} msg * @namespace Assert * @public */ assert.notProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.notProperty, true).to.not.have.property(prop); }; /** * ### .propertyVal(object, property, value, [message]) * * Asserts that `object` has a direct or inherited property named by * `property` with a value given by `value`. Uses a strict equality check * (===). * * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); * * @name propertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.propertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.propertyVal, true).to.have.property(prop, val); }; /** * ### .notPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property` with value given by `value`. Uses a strict equality check * (===). * * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); * * @name notPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.notPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.notPropertyVal, true).to.not.have.property( prop, val ); }; /** * ### .deepPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct or inherited property named by * `property` with a value given by `value`. Uses a deep equality check. * * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); * * @name deepPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.deepPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.deepPropertyVal, true).to.have.deep.property( prop, val ); }; /** * ### .notDeepPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property` with value given by `value`. Uses a deep equality check. * * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); * * @name notDeepPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.notDeepPropertyVal = function (obj, prop, val, msg) { new Assertion( obj, msg, assert.notDeepPropertyVal, true ).to.not.have.deep.property(prop, val); }; /** * ### .ownProperty(object, property, [message]) * * Asserts that `object` has a direct property named by `property`. Inherited * properties aren't checked. * * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); * * @name ownProperty * @param {object} obj * @param {string} prop * @param {string} msg * @public */ assert.ownProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.ownProperty, true).to.have.own.property(prop); }; /** * ### .notOwnProperty(object, property, [message]) * * Asserts that `object` does _not_ have a direct property named by * `property`. Inherited properties aren't checked. * * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); * assert.notOwnProperty({}, 'toString'); * * @name notOwnProperty * @param {object} obj * @param {string} prop * @param {string} msg * @public */ assert.notOwnProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.notOwnProperty, true).to.not.have.own.property( prop ); }; /** * ### .ownPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct property named by `property` and a value * equal to the provided `value`. Uses a strict equality check (===). * Inherited properties aren't checked. * * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); * * @name ownPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} value * @param {string} msg * @public */ assert.ownPropertyVal = function (obj, prop, value, msg) { new Assertion(obj, msg, assert.ownPropertyVal, true).to.have.own.property( prop, value ); }; /** * ### .notOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct property named by `property` * with a value equal to the provided `value`. Uses a strict equality check * (===). Inherited properties aren't checked. * * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); * * @name notOwnPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} value * @param {string} msg * @public */ assert.notOwnPropertyVal = function (obj, prop, value, msg) { new Assertion( obj, msg, assert.notOwnPropertyVal, true ).to.not.have.own.property(prop, value); }; /** * ### .deepOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct property named by `property` and a value * equal to the provided `value`. Uses a deep equality check. Inherited * properties aren't checked. * * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); * * @name deepOwnPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} value * @param {string} msg * @public */ assert.deepOwnPropertyVal = function (obj, prop, value, msg) { new Assertion( obj, msg, assert.deepOwnPropertyVal, true ).to.have.deep.own.property(prop, value); }; /** * ### .notDeepOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct property named by `property` * with a value equal to the provided `value`. Uses a deep equality check. * Inherited properties aren't checked. * * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); * * @name notDeepOwnPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} value * @param {string} msg * @public */ assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { new Assertion( obj, msg, assert.notDeepOwnPropertyVal, true ).to.not.have.deep.own.property(prop, value); }; /** * ### .nestedProperty(object, property, [message]) * * Asserts that `object` has a direct or inherited property named by * `property`, which can be a string using dot- and bracket-notation for * nested reference. * * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); * * @name nestedProperty * @param {object} obj * @param {string} prop * @param {string} msg * @namespace Assert * @public */ assert.nestedProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.nestedProperty, true).to.have.nested.property( prop ); }; /** * ### .notNestedProperty(object, property, [message]) * * Asserts that `object` does _not_ have a property named by `property`, which * can be a string using dot- and bracket-notation for nested reference. The * property cannot exist on the object nor anywhere in its prototype chain. * * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); * * @name notNestedProperty * @param {object} obj * @param {string} prop * @param {string} msg * @namespace Assert * @public */ assert.notNestedProperty = function (obj, prop, msg) { new Assertion( obj, msg, assert.notNestedProperty, true ).to.not.have.nested.property(prop); }; /** * ### .nestedPropertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with value given * by `value`. `property` can use dot- and bracket-notation for nested * reference. Uses a strict equality check (===). * * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); * * @name nestedPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.nestedPropertyVal = function (obj, prop, val, msg) { new Assertion( obj, msg, assert.nestedPropertyVal, true ).to.have.nested.property(prop, val); }; /** * ### .notNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a property named by `property` with * value given by `value`. `property` can use dot- and bracket-notation for * nested reference. Uses a strict equality check (===). * * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); * * @name notNestedPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.notNestedPropertyVal = function (obj, prop, val, msg) { new Assertion( obj, msg, assert.notNestedPropertyVal, true ).to.not.have.nested.property(prop, val); }; /** * ### .deepNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with a value given * by `value`. `property` can use dot- and bracket-notation for nested * reference. Uses a deep equality check. * * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); * * @name deepNestedPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.deepNestedPropertyVal = function (obj, prop, val, msg) { new Assertion( obj, msg, assert.deepNestedPropertyVal, true ).to.have.deep.nested.property(prop, val); }; /** * ### .notDeepNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a property named by `property` with * value given by `value`. `property` can use dot- and bracket-notation for * nested reference. Uses a deep equality check. * * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); * * @name notDeepNestedPropertyVal * @param {object} obj * @param {string} prop * @param {unknown} val * @param {string} msg * @namespace Assert * @public */ assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { new Assertion( obj, msg, assert.notDeepNestedPropertyVal, true ).to.not.have.deep.nested.property(prop, val); }; /** * ### .lengthOf(object, length, [message]) * * Asserts that `object` has a `length` or `size` with the expected value. * * assert.lengthOf([1,2,3], 3, 'array has length of 3'); * assert.lengthOf('foobar', 6, 'string has length of 6'); * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); * * @name lengthOf * @param {unknown} exp * @param {number} len * @param {string} msg * @namespace Assert * @public */ assert.lengthOf = function (exp, len, msg) { new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); }; /** * ### .hasAnyKeys(object, [keys], [message]) * * Asserts that `object` has at least one of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); * * @name hasAnyKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.hasAnyKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); }; /** * ### .hasAllKeys(object, [keys], [message]) * * Asserts that `object` has all and only all of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); * * @name hasAllKeys * @param {unknown} obj * @param {string[]} keys * @param {string} msg * @namespace Assert * @public */ assert.hasAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); }; /** * ### .containsAllKeys(object, [keys], [message]) * * Asserts that `object` has all of the `keys` provided but may have more keys not listed. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}]); * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); * * @name containsAllKeys * @param {unknown} obj * @param {string[]} keys * @param {string} msg * @namespace Assert * @public */ assert.containsAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.containsAllKeys, true).to.contain.all.keys( keys ); }; /** * ### .doesNotHaveAnyKeys(object, [keys], [message]) * * Asserts that `object` has none of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{one: 'two'}, 'example']); * * @name doesNotHaveAnyKeys * @param {unknown} obj * @param {string[]} keys * @param {string} msg * @namespace Assert * @public */ assert.doesNotHaveAnyKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true).to.not.have.any.keys( keys ); }; /** * ### .doesNotHaveAllKeys(object, [keys], [message]) * * Asserts that `object` does not have at least one of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{one: 'two'}, 'example']); * * @name doesNotHaveAllKeys * @param {unknown} obj * @param {string[]} keys * @param {string} msg * @namespace Assert * @public */ assert.doesNotHaveAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAllKeys, true).to.not.have.all.keys( keys ); }; /** * ### .hasAnyDeepKeys(object, [keys], [message]) * * Asserts that `object` has at least one of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name hasAnyDeepKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.hasAnyDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAnyDeepKeys, true).to.have.any.deep.keys( keys ); }; /** * ### .hasAllDeepKeys(object, [keys], [message]) * * Asserts that `object` has all and only all of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name hasAllDeepKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.hasAllDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAllDeepKeys, true).to.have.all.deep.keys( keys ); }; /** * ### .containsAllDeepKeys(object, [keys], [message]) * * Asserts that `object` contains all of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name containsAllDeepKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.containsAllDeepKeys = function (obj, keys, msg) { new Assertion( obj, msg, assert.containsAllDeepKeys, true ).to.contain.all.deep.keys(keys); }; /** * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) * * Asserts that `object` has none of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); * * @name doesNotHaveAnyDeepKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { new Assertion( obj, msg, assert.doesNotHaveAnyDeepKeys, true ).to.not.have.any.deep.keys(keys); }; /** * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) * * Asserts that `object` does not have at least one of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); * * @name doesNotHaveAllDeepKeys * @param {unknown} obj * @param {Array | object} keys * @param {string} msg * @namespace Assert * @public */ assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { new Assertion( obj, msg, assert.doesNotHaveAllDeepKeys, true ).to.not.have.all.deep.keys(keys); }; /** * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) * * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an * instance of `errorLike`. * If `errorLike` is an `Error` instance, asserts that the error thrown is the same * instance as `errorLike`. * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a * message matching `errMsgMatcher`. * * assert.throws(fn, 'Error thrown must have this msg'); * assert.throws(fn, /Error thrown must have a msg that matches this/); * assert.throws(fn, ReferenceError); * assert.throws(fn, errorInstance); * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); * * @name throws * @alias throw * @alias Throw * @param {Function} fn * @param {Error} errorLike * @param {RegExp | string} errMsgMatcher * @param {string} msg * @returns {unknown} * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Assert * @public */ assert.throws = function (fn, errorLike, errMsgMatcher, msg) { if ('string' === typeof errorLike || errorLike instanceof RegExp) { errMsgMatcher = errorLike; errorLike = null; } let assertErr = new Assertion(fn, msg, assert.throws, true).to.throw( errorLike, errMsgMatcher ); return flag(assertErr, 'object'); }; /** * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) * * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an * instance of `errorLike`. * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same * instance as `errorLike`. * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a * message matching `errMsgMatcher`. * * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); * assert.doesNotThrow(fn, /Any Error thrown must not match this/); * assert.doesNotThrow(fn, Error); * assert.doesNotThrow(fn, errorInstance); * assert.doesNotThrow(fn, Error, 'Error must not have this message'); * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); * assert.doesNotThrow(fn, Error, /Error must not match this/); * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); * * @name doesNotThrow * @param {Function} fn * @param {Error} errorLike * @param {RegExp | string} errMsgMatcher * @param {string} message * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Assert * @public */ assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, message) { if ('string' === typeof errorLike || errorLike instanceof RegExp) { errMsgMatcher = errorLike; errorLike = null; } new Assertion(fn, message, assert.doesNotThrow, true).to.not.throw( errorLike, errMsgMatcher ); }; /** * ### .operator(val1, operator, val2, [message]) * * Compares two values using `operator`. * * assert.operator(1, '<', 2, 'everything is ok'); * assert.operator(1, '>', 2, 'this will fail'); * * @name operator * @param {unknown} val * @param {string} operator * @param {unknown} val2 * @param {string} msg * @namespace Assert * @public */ assert.operator = function (val, operator, val2, msg) { let ok; switch (operator) { case '==': ok = val == val2; break; case '===': ok = val === val2; break; case '>': ok = val > val2; break; case '>=': ok = val >= val2; break; case '<': ok = val < val2; break; case '<=': ok = val <= val2; break; case '!=': ok = val != val2; break; case '!==': ok = val !== val2; break; default: msg = msg ? msg + ': ' : msg; throw new AssertionError( msg + 'Invalid operator "' + operator + '"', undefined, assert.operator ); } let test = new Assertion(ok, msg, assert.operator, true); test.assert( true === flag(test, 'object'), 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2), 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) ); }; /** * ### .closeTo(actual, expected, delta, [message]) * * Asserts that the target is equal `expected`, to within a +/- `delta` range. * * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); * * @name closeTo * @param {number} act * @param {number} exp * @param {number} delta * @param {string} msg * @namespace Assert * @public */ assert.closeTo = function (act, exp, delta, msg) { new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); }; /** * ### .approximately(actual, expected, delta, [message]) * * Asserts that the target is equal `expected`, to within a +/- `delta` range. * * assert.approximately(1.5, 1, 0.5, 'numbers are close'); * * @name approximately * @param {number} act * @param {number} exp * @param {number} delta * @param {string} msg * @namespace Assert * @public */ assert.approximately = function (act, exp, delta, msg) { new Assertion(act, msg, assert.approximately, true).to.be.approximately( exp, delta ); }; /** * ### .sameMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in any order. Uses a * strict equality check (===). * * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); * * @name sameMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.sameMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.sameMembers, true).to.have.same.members(set2); }; /** * ### .notSameMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in any order. * Uses a strict equality check (===). * * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); * * @name notSameMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.notSameMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.notSameMembers, true ).to.not.have.same.members(set2); }; /** * ### .sameDeepMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in any order. Uses a * deep equality check. * * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); * * @name sameDeepMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.sameDeepMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.sameDeepMembers, true ).to.have.same.deep.members(set2); }; /** * ### .notSameDeepMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in any order. * Uses a deep equality check. * * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); * * @name notSameDeepMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.notSameDeepMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.notSameDeepMembers, true ).to.not.have.same.deep.members(set2); }; /** * ### .sameOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in the same order. * Uses a strict equality check (===). * * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); * * @name sameOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.sameOrderedMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.sameOrderedMembers, true ).to.have.same.ordered.members(set2); }; /** * ### .notSameOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in the same * order. Uses a strict equality check (===). * * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); * * @name notSameOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.notSameOrderedMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.notSameOrderedMembers, true ).to.not.have.same.ordered.members(set2); }; /** * ### .sameDeepOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in the same order. * Uses a deep equality check. * * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); * * @name sameDeepOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.sameDeepOrderedMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.sameDeepOrderedMembers, true ).to.have.same.deep.ordered.members(set2); }; /** * ### .notSameDeepOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in the same * order. Uses a deep equality check. * * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); * * @name notSameDeepOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {string} msg * @namespace Assert * @public */ assert.notSameDeepOrderedMembers = function (set1, set2, msg) { new Assertion( set1, msg, assert.notSameDeepOrderedMembers, true ).to.not.have.same.deep.ordered.members(set2); }; /** * ### .includeMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in any order. Uses a * strict equality check (===). Duplicates are ignored. * * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); * * @name includeMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.includeMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.includeMembers, true).to.include.members( subset ); }; /** * ### .notIncludeMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in any order. Uses a * strict equality check (===). Duplicates are ignored. * * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); * * @name notIncludeMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.notIncludeMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.notIncludeMembers, true ).to.not.include.members(subset); }; /** * ### .includeDeepMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in any order. Uses a deep * equality check. Duplicates are ignored. * * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); * * @name includeDeepMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.includeDeepMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.includeDeepMembers, true ).to.include.deep.members(subset); }; /** * ### .notIncludeDeepMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in any order. Uses a * deep equality check. Duplicates are ignored. * * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); * * @name notIncludeDeepMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.notIncludeDeepMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.notIncludeDeepMembers, true ).to.not.include.deep.members(subset); }; /** * ### .includeOrderedMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in the same order * beginning with the first element in `superset`. Uses a strict equality * check (===). * * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); * * @name includeOrderedMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.includeOrderedMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.includeOrderedMembers, true ).to.include.ordered.members(subset); }; /** * ### .notIncludeOrderedMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in the same order * beginning with the first element in `superset`. Uses a strict equality * check (===). * * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); * * @name notIncludeOrderedMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.notIncludeOrderedMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.notIncludeOrderedMembers, true ).to.not.include.ordered.members(subset); }; /** * ### .includeDeepOrderedMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in the same order * beginning with the first element in `superset`. Uses a deep equality * check. * * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); * * @name includeDeepOrderedMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.includeDeepOrderedMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.includeDeepOrderedMembers, true ).to.include.deep.ordered.members(subset); }; /** * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in the same order * beginning with the first element in `superset`. Uses a deep equality * check. * * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); * * @name notIncludeDeepOrderedMembers * @param {Array} superset * @param {Array} subset * @param {string} msg * @namespace Assert * @public */ assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { new Assertion( superset, msg, assert.notIncludeDeepOrderedMembers, true ).to.not.include.deep.ordered.members(subset); }; /** * ### .oneOf(inList, list, [message]) * * Asserts that non-object, non-array value `inList` appears in the flat array `list`. * * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); * * @name oneOf * @param {*} inList * @param {Array<*>} list * @param {string} msg * @namespace Assert * @public */ assert.oneOf = function (inList, list, msg) { new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); }; /** * ### isIterable(obj, [message]) * * Asserts that the target is an iterable, which means that it has a iterator * with the exception of `String.` * * assert.isIterable([1, 2]); * * @param {unknown} obj * @param {string} [msg] * @namespace Assert * @public */ assert.isIterable = function (obj, msg) { if (obj == undefined || !obj[Symbol.iterator]) { msg = msg ? `${msg} expected ${inspect(obj)} to be an iterable` : `expected ${inspect(obj)} to be an iterable`; throw new AssertionError(msg, undefined, assert.isIterable); } }; /** * ### .changes(function, object, property, [message]) * * Asserts that a function changes the value of a property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 22 }; * assert.changes(fn, obj, 'val'); * * @name changes * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {string} msg _optional_ * @namespace Assert * @public */ assert.changes = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); }; /** * ### .changesBy(function, object, property, delta, [message]) * * Asserts that a function changes the value of a property by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val += 2 }; * assert.changesBy(fn, obj, 'val', 2); * * @name changesBy * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {number} delta msg change amount (delta) * @param {string} msg _optional_ * @namespace Assert * @public */ assert.changesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.changesBy, true).to.change(obj, prop).by(delta); }; /** * ### .doesNotChange(function, object, property, [message]) * * Asserts that a function does not change the value of a property. * * var obj = { val: 10 }; * var fn = function() { console.log('foo'); }; * assert.doesNotChange(fn, obj, 'val'); * * @name doesNotChange * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {string} msg _optional_ * @returns {unknown} * @namespace Assert * @public */ assert.doesNotChange = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotChange, true).to.not.change( obj, prop ); }; /** * ### .changesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val += 10 }; * assert.changesButNotBy(fn, obj, 'val', 5); * * @name changesButNotBy * @param {Function} fn - modifier function * @param {object} obj - object or getter function * @param {string} prop - property name _optional_ * @param {number} delta - change amount (delta) * @param {string} msg - message _optional_ * @namespace Assert * @public */ assert.changesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.changesButNotBy, true).to .change(obj, prop) .but.not.by(delta); }; /** * ### .increases(function, object, property, [message]) * * Asserts that a function increases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 13 }; * assert.increases(fn, obj, 'val'); * * @public * @namespace Assert * @name increases * @param {Function} fn - modifier function * @param {object} obj - object or getter function * @param {string} prop - property name _optional_ * @param {string} msg - message _optional_ * @returns {unknown} */ assert.increases = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.increases, true).to.increase(obj, prop); }; /** * ### .increasesBy(function, object, property, delta, [message]) * * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val += 10 }; * assert.increasesBy(fn, obj, 'val', 10); * * @public * @name increasesBy * @namespace Assert * @param {Function} fn - modifier function * @param {object} obj - object or getter function * @param {string} prop - property name _optional_ * @param {number} delta - change amount (delta) * @param {string} msg - message _optional_ */ assert.increasesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.increasesBy, true).to .increase(obj, prop) .by(delta); }; /** * ### .doesNotIncrease(function, object, property, [message]) * * Asserts that a function does not increase a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 8 }; * assert.doesNotIncrease(fn, obj, 'val'); * * @name doesNotIncrease * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @returns {Assertion} * @param {string} msg _optional_ * @namespace Assert * @public */ assert.doesNotIncrease = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotIncrease, true).to.not.increase( obj, prop ); }; /** * ### .increasesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val = 15 }; * assert.increasesButNotBy(fn, obj, 'val', 10); * * @name increasesButNotBy * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {number} delta change amount (delta) * @param {string} msg _optional_ * @namespace Assert * @public */ assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.increasesButNotBy, true).to .increase(obj, prop) .but.not.by(delta); }; /** * ### .decreases(function, object, property, [message]) * * Asserts that a function decreases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.decreases(fn, obj, 'val'); * * @name decreases * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @returns {Assertion} * @param {string} msg _optional_ * @namespace Assert * @public */ assert.decreases = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.decreases, true).to.decrease(obj, prop); }; /** * ### .decreasesBy(function, object, property, delta, [message]) * * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val -= 5 }; * assert.decreasesBy(fn, obj, 'val', 5); * * @name decreasesBy * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {number} delta change amount (delta) * @param {string} msg _optional_ * @namespace Assert * @public */ assert.decreasesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.decreasesBy, true).to .decrease(obj, prop) .by(delta); }; /** * ### .doesNotDecrease(function, object, property, [message]) * * Asserts that a function does not decreases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 15 }; * assert.doesNotDecrease(fn, obj, 'val'); * * @name doesNotDecrease * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @returns {Assertion} * @param {string} msg _optional_ * @namespace Assert * @public */ assert.doesNotDecrease = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotDecrease, true).to.not.decrease( obj, prop ); }; /** * ### .doesNotDecreaseBy(function, object, property, delta, [message]) * * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.doesNotDecreaseBy(fn, obj, 'val', 1); * * @name doesNotDecreaseBy * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {number} delta change amount (delta) * @returns {Assertion} * @param {string} msg _optional_ * @namespace Assert * @public */ assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotDecreaseBy, true).to.not .decrease(obj, prop) .by(delta); }; /** * ### .decreasesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.decreasesButNotBy(fn, obj, 'val', 1); * * @name decreasesButNotBy * @param {Function} fn modifier function * @param {object} obj object or getter function * @param {string} prop property name _optional_ * @param {number} delta change amount (delta) * @param {string} msg _optional_ * @namespace Assert * @public */ assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { let tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.decreasesButNotBy, true).to .decrease(obj, prop) .but.not.by(delta); }; /** * ### .ifError(object) * * Asserts if value is not a false value, and throws if it is a true value. * This is added to allow for chai to be a drop-in replacement for Node's * assert class. * * var err = new Error('I am a custom error'); * assert.ifError(err); // Rethrows err! * * @name ifError * @param {object} val * @namespace Assert * @public */ assert.ifError = function (val) { if (val) { throw val; } }; /** * ### .isExtensible(object) * * Asserts that `object` is extensible (can have new properties added to it). * * assert.isExtensible({}); * * @name isExtensible * @alias extensible * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isExtensible = function (obj, msg) { new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; }; /** * ### .isNotExtensible(object) * * Asserts that `object` is _not_ extensible. * * var nonExtensibleObject = Object.preventExtensions({}); * var sealedObject = Object.seal({}); * var frozenObject = Object.freeze({}); * * assert.isNotExtensible(nonExtensibleObject); * assert.isNotExtensible(sealedObject); * assert.isNotExtensible(frozenObject); * * @name isNotExtensible * @alias notExtensible * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isNotExtensible = function (obj, msg) { new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; }; /** * ### .isSealed(object) * * Asserts that `object` is sealed (cannot have new properties added to it * and its existing properties cannot be removed). * * var sealedObject = Object.seal({}); * var frozenObject = Object.seal({}); * * assert.isSealed(sealedObject); * assert.isSealed(frozenObject); * * @name isSealed * @alias sealed * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isSealed = function (obj, msg) { new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; }; /** * ### .isNotSealed(object) * * Asserts that `object` is _not_ sealed. * * assert.isNotSealed({}); * * @name isNotSealed * @alias notSealed * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isNotSealed = function (obj, msg) { new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; }; /** * ### .isFrozen(object) * * Asserts that `object` is frozen (cannot have new properties added to it * and its existing properties cannot be modified). * * var frozenObject = Object.freeze({}); * assert.frozen(frozenObject); * * @name isFrozen * @alias frozen * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isFrozen = function (obj, msg) { new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; }; /** * ### .isNotFrozen(object) * * Asserts that `object` is _not_ frozen. * * assert.isNotFrozen({}); * * @name isNotFrozen * @alias notFrozen * @param {object} obj * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isNotFrozen = function (obj, msg) { new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; }; /** * ### .isEmpty(target) * * Asserts that the target does not contain any values. * For arrays and strings, it checks the `length` property. * For `Map` and `Set` instances, it checks the `size` property. * For non-function objects, it gets the count of own * enumerable string keys. * * assert.isEmpty([]); * assert.isEmpty(''); * assert.isEmpty(new Map); * assert.isEmpty({}); * * @name isEmpty * @alias empty * @param {object | Array | string | Map | Set} val * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isEmpty = function (val, msg) { new Assertion(val, msg, assert.isEmpty, true).to.be.empty; }; /** * ### .isNotEmpty(target) * * Asserts that the target contains values. * For arrays and strings, it checks the `length` property. * For `Map` and `Set` instances, it checks the `size` property. * For non-function objects, it gets the count of own * enumerable string keys. * * assert.isNotEmpty([1, 2]); * assert.isNotEmpty('34'); * assert.isNotEmpty(new Set([5, 6])); * assert.isNotEmpty({ key: 7 }); * * @name isNotEmpty * @alias notEmpty * @param {object | Array | string | Map | Set} val * @param {string} msg _optional_ * @namespace Assert * @public */ assert.isNotEmpty = function (val, msg) { new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; }; /** * ### .containsSubset(target, subset) * * Asserts that the target primitive/object/array structure deeply contains all provided fields * at the same key/depth as the provided structure. * * When comparing arrays, the target must contain the subset of at least one of each object/value in the subset array. * Order does not matter. * * assert.containsSubset( * [{name: {first: "John", last: "Smith"}}, {name: {first: "Jane", last: "Doe"}}], * [{name: {first: "Jane"}}] * ); * * @name containsSubset * @alias containSubset * @param {unknown} val * @param {unknown} exp * @param {string} msg _optional_ * @namespace Assert * @public */ assert.containsSubset = function (val, exp, msg) { new Assertion(val, msg).to.containSubset(exp); }; /** * ### .doesNotContainSubset(target, subset) * * The negation of assert.containsSubset. * * @name doesNotContainSubset * @param {unknown} val * @param {unknown} exp * @param {string} msg _optional_ * @namespace Assert * @public */ assert.doesNotContainSubset = function (val, exp, msg) { new Assertion(val, msg).to.not.containSubset(exp); }; /** * Aliases. * * @param {unknown} name * @param {unknown} as * @returns {unknown} */ const aliases = [ ['isOk', 'ok'], ['isNotOk', 'notOk'], ['throws', 'throw'], ['throws', 'Throw'], ['isExtensible', 'extensible'], ['isNotExtensible', 'notExtensible'], ['isSealed', 'sealed'], ['isNotSealed', 'notSealed'], ['isFrozen', 'frozen'], ['isNotFrozen', 'notFrozen'], ['isEmpty', 'empty'], ['isNotEmpty', 'notEmpty'], ['isCallable', 'isFunction'], ['isNotCallable', 'isNotFunction'], ['containsSubset', 'containSubset'] ]; for (const [name, as] of aliases) { assert[as] = assert[name]; } chaijs-chai-2a3ecff/lib/chai/interface/expect.js000066400000000000000000000023441505212005400216650ustar00rootroot00000000000000/*! * chai * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import * as chai from '../../chai.js'; import {Assertion} from '../assertion.js'; import {AssertionError} from 'assertion-error'; /** * @param {unknown} val * @param {string} message * @returns {Assertion} */ function expect(val, message) { return new Assertion(val, message); } export {expect}; /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. * * expect.fail(); * expect.fail("custom error message"); * expect.fail(1, 2); * expect.fail(1, 2, "custom error message"); * expect.fail(1, 2, "custom error message", ">"); * expect.fail(1, 2, undefined, ">"); * * @name fail * @param {unknown} actual * @param {unknown} expected * @param {string} message * @param {string} operator * @namespace expect * @public */ expect.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { message = actual; actual = undefined; } message = message || 'expect.fail()'; throw new AssertionError( message, { actual: actual, expected: expected, operator: operator }, chai.expect.fail ); }; chaijs-chai-2a3ecff/lib/chai/interface/should.js000066400000000000000000000136271505212005400217010ustar00rootroot00000000000000/*! * chai * Copyright(c) 2011-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {AssertionError} from 'assertion-error'; /** * @returns {void} */ function loadShould() { // explicitly define this method as function as to have it's name to include as `ssfi` /** * @returns {Assertion} */ function shouldGetter() { if ( this instanceof String || this instanceof Number || this instanceof Boolean || (typeof Symbol === 'function' && this instanceof Symbol) || (typeof BigInt === 'function' && this instanceof BigInt) ) { return new Assertion(this.valueOf(), null, shouldGetter); } return new Assertion(this, null, shouldGetter); } /** * @param {unknown} value */ function shouldSetter(value) { // See https://github.com/chaijs/chai/issues/86: this makes // `whatever.should = someValue` actually set `someValue`, which is // especially useful for `global.should = require('chai').should()`. // // Note that we have to use [[DefineProperty]] instead of [[Put]] // since otherwise we would trigger this very setter! Object.defineProperty(this, 'should', { value: value, enumerable: true, configurable: true, writable: true }); } // modify Object.prototype to have `should` Object.defineProperty(Object.prototype, 'should', { set: shouldSetter, get: shouldGetter, configurable: true }); let should = {}; /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. * * should.fail(); * should.fail("custom error message"); * should.fail(1, 2); * should.fail(1, 2, "custom error message"); * should.fail(1, 2, "custom error message", ">"); * should.fail(1, 2, undefined, ">"); * * @name fail * @param {unknown} actual * @param {unknown} expected * @param {string} message * @param {string} operator * @namespace BDD * @public */ should.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { message = actual; actual = undefined; } message = message || 'should.fail()'; throw new AssertionError( message, { actual: actual, expected: expected, operator: operator }, should.fail ); }; /** * ### .equal(actual, expected, [message]) * * Asserts non-strict equality (`==`) of `actual` and `expected`. * * should.equal(3, '3', '== coerces values to strings'); * * @name equal * @param {unknown} actual * @param {unknown} expected * @param {string} message * @namespace Should * @public */ should.equal = function (actual, expected, message) { new Assertion(actual, message).to.equal(expected); }; /** * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) * * Asserts that `function` will throw an error that is an instance of * `constructor`, or alternately that it will throw an error with message * matching `regexp`. * * should.throw(fn, 'function throws a reference error'); * should.throw(fn, /function throws a reference error/); * should.throw(fn, ReferenceError); * should.throw(fn, ReferenceError, 'function throws a reference error'); * should.throw(fn, ReferenceError, /function throws a reference error/); * * @name throw * @alias Throw * @param {Function} fn * @param {Error} errt * @param {RegExp} errs * @param {string} msg * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Should * @public */ should.Throw = function (fn, errt, errs, msg) { new Assertion(fn, msg).to.Throw(errt, errs); }; /** * ### .exist * * Asserts that the target is neither `null` nor `undefined`. * * var foo = 'hi'; * should.exist(foo, 'foo exists'); * * @param {unknown} val * @param {string} msg * @name exist * @namespace Should * @public */ should.exist = function (val, msg) { new Assertion(val, msg).to.exist; }; // negation should.not = {}; /** * ### .not.equal(actual, expected, [message]) * * Asserts non-strict inequality (`!=`) of `actual` and `expected`. * * should.not.equal(3, 4, 'these numbers are not equal'); * * @name not.equal * @param {unknown} actual * @param {unknown} expected * @param {string} msg * @namespace Should * @public */ should.not.equal = function (actual, expected, msg) { new Assertion(actual, msg).to.not.equal(expected); }; /** * ### .throw(function, [constructor/regexp], [message]) * * Asserts that `function` will _not_ throw an error that is an instance of * `constructor`, or alternately that it will not throw an error with message * matching `regexp`. * * should.not.throw(fn, Error, 'function does not throw'); * * @name not.throw * @alias not.Throw * @param {Function} fn * @param {Error} errt * @param {RegExp} errs * @param {string} msg * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Should * @public */ should.not.Throw = function (fn, errt, errs, msg) { new Assertion(fn, msg).to.not.Throw(errt, errs); }; /** * ### .not.exist * * Asserts that the target is neither `null` nor `undefined`. * * var bar = null; * should.not.exist(bar, 'bar does not exist'); * * @namespace Should * @name not.exist * @param {unknown} val * @param {string} msg * @public */ should.not.exist = function (val, msg) { new Assertion(val, msg).to.not.exist; }; should['throw'] = should['Throw']; should.not['throw'] = should.not['Throw']; return should; } export const should = loadShould; export const Should = loadShould; chaijs-chai-2a3ecff/lib/chai/utils/000077500000000000000000000000001505212005400172345ustar00rootroot00000000000000chaijs-chai-2a3ecff/lib/chai/utils/addChainableMethod.js000066400000000000000000000122661505212005400232610ustar00rootroot00000000000000/*! * Chai - addChainingMethod utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {addLengthGuard} from './addLengthGuard.js'; import {flag} from './flag.js'; import {proxify} from './proxify.js'; import {transferFlags} from './transferFlags.js'; /** * Module variables */ // Check whether `Object.setPrototypeOf` is supported let canSetPrototype = typeof Object.setPrototypeOf === 'function'; // Without `Object.setPrototypeOf` support, this module will need to add properties to a function. // However, some of functions' own props are not configurable and should be skipped. let testFn = function () {}; let excludeNames = Object.getOwnPropertyNames(testFn).filter(function (name) { let propDesc = Object.getOwnPropertyDescriptor(testFn, name); // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, // but then returns `undefined` as the property descriptor for `callee`. As a // workaround, we perform an otherwise unnecessary type-check for `propDesc`, // and then filter it out if it's not an object as it should be. if (typeof propDesc !== 'object') return true; return !propDesc.configurable; }); // Cache `Function` properties let call = Function.prototype.call, apply = Function.prototype.apply; /** * ### .addChainableMethod(ctx, name, method, chainingBehavior) * * Adds a method to an object, such that the method can also be chained. * * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.equal(str); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); * * The result can then be used as both a method assertion, executing both `method` and * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. * * expect(fooStr).to.be.foo('bar'); * expect(fooStr).to.be.foo.equal('foo'); * * @param {object} ctx object to which the method is added * @param {string} name of method to add * @param {Function} method function to be used for `name`, when called * @param {Function} chainingBehavior function to be called every time the property is accessed * @namespace Utils * @name addChainableMethod * @public */ export function addChainableMethod(ctx, name, method, chainingBehavior) { if (typeof chainingBehavior !== 'function') { chainingBehavior = function () {}; } let chainableBehavior = { method: method, chainingBehavior: chainingBehavior }; // save the methods so we can overwrite them later, if we need to. if (!ctx.__methods) { ctx.__methods = {}; } ctx.__methods[name] = chainableBehavior; Object.defineProperty(ctx, name, { get: function chainableMethodGetter() { chainableBehavior.chainingBehavior.call(this); let chainableMethodWrapper = function () { // Setting the `ssfi` flag to `chainableMethodWrapper` causes this // function to be the starting point for removing implementation // frames from the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then this assertion is being // invoked from inside of another assertion. In this case, the `ssfi` // flag has already been set by the outer assertion. // // Note that overwriting a chainable method merely replaces the saved // methods in `ctx.__methods` instead of completely replacing the // overwritten assertion. Therefore, an overwriting assertion won't // set the `ssfi` or `lockSsfi` flags. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', chainableMethodWrapper); } let result = chainableBehavior.method.apply(this, arguments); if (result !== undefined) { return result; } let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }; addLengthGuard(chainableMethodWrapper, name, true); // Use `Object.setPrototypeOf` if available if (canSetPrototype) { // Inherit all properties from the object by replacing the `Function` prototype let prototype = Object.create(this); // Restore the `call` and `apply` methods from `Function` prototype.call = call; prototype.apply = apply; Object.setPrototypeOf(chainableMethodWrapper, prototype); } // Otherwise, redefine all properties (slow!) else { let asserterNames = Object.getOwnPropertyNames(ctx); asserterNames.forEach(function (asserterName) { if (excludeNames.indexOf(asserterName) !== -1) { return; } let pd = Object.getOwnPropertyDescriptor(ctx, asserterName); Object.defineProperty(chainableMethodWrapper, asserterName, pd); }); } transferFlags(this, chainableMethodWrapper); return proxify(chainableMethodWrapper); }, configurable: true }); } chaijs-chai-2a3ecff/lib/chai/utils/addLengthGuard.js000066400000000000000000000047411505212005400224550ustar00rootroot00000000000000const fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); /*! * Chai - addLengthGuard utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .addLengthGuard(fn, assertionName, isChainable) * * Define `length` as a getter on the given uninvoked method assertion. The * getter acts as a guard against chaining `length` directly off of an uninvoked * method assertion, which is a problem because it references `function`'s * built-in `length` property instead of Chai's `length` assertion. When the * getter catches the user making this mistake, it throws an error with a * helpful message. * * There are two ways in which this mistake can be made. The first way is by * chaining the `length` assertion directly off of an uninvoked chainable * method. In this case, Chai suggests that the user use `lengthOf` instead. The * second way is by chaining the `length` assertion directly off of an uninvoked * non-chainable method. Non-chainable methods must be invoked prior to * chaining. In this case, Chai suggests that the user consult the docs for the * given assertion. * * If the `length` property of functions is unconfigurable, then return `fn` * without modification. * * Note that in ES6, the function's `length` property is configurable, so once * support for legacy environments is dropped, Chai's `length` property can * replace the built-in function's `length` property, and this length guard will * no longer be necessary. In the mean time, maintaining consistency across all * environments is the priority. * * @param {Function} fn * @param {string} assertionName * @param {boolean} isChainable * @returns {unknown} * @namespace Utils * @name addLengthGuard */ export function addLengthGuard(fn, assertionName, isChainable) { if (!fnLengthDesc.configurable) return fn; Object.defineProperty(fn, 'length', { get: function () { if (isChainable) { throw Error( 'Invalid Chai property: ' + assertionName + '.length. Due' + ' to a compatibility issue, "length" cannot directly follow "' + assertionName + '". Use "' + assertionName + '.lengthOf" instead.' ); } throw Error( 'Invalid Chai property: ' + assertionName + '.length. See' + ' docs for proper usage of "' + assertionName + '".' ); } }); return fn; } chaijs-chai-2a3ecff/lib/chai/utils/addMethod.js000066400000000000000000000041751505212005400214720ustar00rootroot00000000000000/*! * Chai - addMethod utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {addLengthGuard} from './addLengthGuard.js'; import {flag} from './flag.js'; import {proxify} from './proxify.js'; import {transferFlags} from './transferFlags.js'; import {Assertion} from '../assertion.js'; /** * ### .addMethod(ctx, name, method) * * Adds a method to the prototype of an object. * * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.equal(str); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addMethod('foo', fn); * * Then can be used as any other assertion. * * expect(fooStr).to.be.foo('bar'); * * @param {object} ctx object to which the method is added * @param {string} name of method to add * @param {Function} method function to be used for name * @namespace Utils * @name addMethod * @public */ export function addMethod(ctx, name, method) { let methodWrapper = function () { // Setting the `ssfi` flag to `methodWrapper` causes this function to be the // starting point for removing implementation frames from the stack trace of // a failed assertion. // // However, we only want to use this function as the starting point if the // `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked from // inside of another assertion. In the first case, the `ssfi` flag has // already been set by the overwriting assertion. In the second case, the // `ssfi` flag has already been set by the outer assertion. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', methodWrapper); } let result = method.apply(this, arguments); if (result !== undefined) return result; let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }; addLengthGuard(methodWrapper, name, false); ctx[name] = proxify(methodWrapper, name); } chaijs-chai-2a3ecff/lib/chai/utils/addProperty.js000066400000000000000000000045271505212005400220770ustar00rootroot00000000000000/*! * Chai - addProperty utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {flag} from './flag.js'; import {isProxyEnabled} from './isProxyEnabled.js'; import {transferFlags} from './transferFlags.js'; /** * ### .addProperty(ctx, name, getter) * * Adds a property to the prototype of an object. * * utils.addProperty(chai.Assertion.prototype, 'foo', function () { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.instanceof(Foo); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addProperty('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.be.foo; * * @param {object} ctx object to which the property is added * @param {string} name of property to add * @param {Function} getter function to be used for name * @namespace Utils * @name addProperty * @public */ export function addProperty(ctx, name, getter) { getter = getter === undefined ? function () {} : getter; Object.defineProperty(ctx, name, { get: function propertyGetter() { // Setting the `ssfi` flag to `propertyGetter` causes this function to // be the starting point for removing implementation frames from the // stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set and proxy protection is disabled. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked // from inside of another assertion. In the first case, the `ssfi` flag // has already been set by the overwriting assertion. In the second // case, the `ssfi` flag has already been set by the outer assertion. // // If proxy protection is enabled, then the `ssfi` flag has already been // set by the proxy getter. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { flag(this, 'ssfi', propertyGetter); } let result = getter.call(this); if (result !== undefined) return result; let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }, configurable: true }); } chaijs-chai-2a3ecff/lib/chai/utils/compareByInspect.js000066400000000000000000000014021505212005400230360ustar00rootroot00000000000000/*! * Chai - compareByInspect utility * Copyright(c) 2011-2016 Jake Luer * MIT Licensed */ import {inspect} from './inspect.js'; /** * ### .compareByInspect(mixed, mixed) * * To be used as a compareFunction with Array.prototype.sort. Compares elements * using inspect instead of default behavior of using toString so that Symbols * and objects with irregular/missing toString can still be sorted without a * TypeError. * * @param {unknown} a first element to compare * @param {unknown} b second element to compare * @returns {number} -1 if 'a' should come before 'b'; otherwise 1 * @name compareByInspect * @namespace Utils * @public */ export function compareByInspect(a, b) { return inspect(a) < inspect(b) ? -1 : 1; } chaijs-chai-2a3ecff/lib/chai/utils/expectTypes.js000066400000000000000000000026711505212005400221150ustar00rootroot00000000000000/*! * Chai - expectTypes utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {AssertionError} from 'assertion-error'; import {flag} from './flag.js'; import {type} from './type-detect.js'; /** * ### .expectTypes(obj, types) * * Ensures that the object being tested against is of a valid type. * * utils.expectTypes(this, ['array', 'object', 'string']); * * @param {unknown} obj constructed Assertion * @param {Array} types A list of allowed types for this assertion * @namespace Utils * @name expectTypes * @public */ export function expectTypes(obj, types) { let flagMsg = flag(obj, 'message'); let ssfi = flag(obj, 'ssfi'); flagMsg = flagMsg ? flagMsg + ': ' : ''; obj = flag(obj, 'object'); types = types.map(function (t) { return t.toLowerCase(); }); types.sort(); // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' let str = types .map(function (t, index) { let art = ~['a', 'e', 'i', 'o', 'u'].indexOf(t.charAt(0)) ? 'an' : 'a'; let or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; return or + art + ' ' + t; }) .join(', '); let objType = type(obj).toLowerCase(); if ( !types.some(function (expected) { return objType === expected; }) ) { throw new AssertionError( flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', undefined, ssfi ); } } chaijs-chai-2a3ecff/lib/chai/utils/flag.js000066400000000000000000000015611505212005400205060ustar00rootroot00000000000000/*! * Chai - flag utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .flag(object, key, [value]) * * Get or set a flag value on an object. If a * value is provided it will be set, else it will * return the currently set value or `undefined` if * the value is not set. * * utils.flag(this, 'foo', 'bar'); // setter * utils.flag(this, 'foo'); // getter, returns `bar` * * @template {{__flags?: {[key: PropertyKey]: unknown}}} T * @param {T} obj object constructed Assertion * @param {string} key * @param {unknown} [value] * @namespace Utils * @name flag * @returns {unknown | undefined} * @private */ export function flag(obj, key, value) { let flags = obj.__flags || (obj.__flags = Object.create(null)); if (arguments.length === 3) { flags[key] = value; } else { return flags[key]; } } chaijs-chai-2a3ecff/lib/chai/utils/getActual.js000066400000000000000000000007441505212005400215100ustar00rootroot00000000000000/*! * Chai - getActual utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .getActual(object, [actual]) * * Returns the `actual` value for an Assertion. * * @param {object} obj object (constructed Assertion) * @param {unknown} args chai.Assertion.prototype.assert arguments * @returns {unknown} * @namespace Utils * @name getActual */ export function getActual(obj, args) { return args.length > 4 ? args[4] : obj._obj; } chaijs-chai-2a3ecff/lib/chai/utils/getMessage.js000066400000000000000000000025651505212005400216660ustar00rootroot00000000000000/*! * Chai - message composition utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {flag} from './flag.js'; import {getActual} from './getActual.js'; import {objDisplay} from './objDisplay.js'; /** * ### .getMessage(object, message, negateMessage) * * Construct the error message based on flags * and template tags. Template tags will return * a stringified inspection of the object referenced. * * Message template tags: * - `#{this}` current asserted object * - `#{act}` actual value * - `#{exp}` expected value * * @param {object} obj object (constructed Assertion) * @param {IArguments} args chai.Assertion.prototype.assert arguments * @returns {string} * @namespace Utils * @name getMessage * @public */ export function getMessage(obj, args) { let negate = flag(obj, 'negate'); let val = flag(obj, 'object'); let expected = args[3]; let actual = getActual(obj, args); let msg = negate ? args[2] : args[1]; let flagMsg = flag(obj, 'message'); if (typeof msg === 'function') msg = msg(); msg = msg || ''; msg = msg .replace(/#\{this\}/g, function () { return objDisplay(val); }) .replace(/#\{act\}/g, function () { return objDisplay(actual); }) .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); return flagMsg ? flagMsg + ': ' + msg : msg; } chaijs-chai-2a3ecff/lib/chai/utils/getOperator.js000066400000000000000000000024541505212005400220720ustar00rootroot00000000000000import {flag} from './flag.js'; import {type} from './type-detect.js'; /** * @param {unknown} obj * @returns {boolean} */ function isObjectType(obj) { let objectType = type(obj); let objectTypes = ['Array', 'Object', 'Function']; return objectTypes.indexOf(objectType) !== -1; } /** * ### .getOperator(message) * * Extract the operator from error message. * Operator defined is based on below link * https://nodejs.org/api/assert.html#assert_assert. * * Returns the `operator` or `undefined` value for an Assertion. * * @param {object} obj object (constructed Assertion) * @param {unknown} args chai.Assertion.prototype.assert arguments * @returns {unknown} * @namespace Utils * @name getOperator * @public */ export function getOperator(obj, args) { let operator = flag(obj, 'operator'); let negate = flag(obj, 'negate'); let expected = args[3]; let msg = negate ? args[2] : args[1]; if (operator) { return operator; } if (typeof msg === 'function') msg = msg(); msg = msg || ''; if (!msg) { return undefined; } if (/\shave\s/.test(msg)) { return undefined; } let isObject = isObjectType(expected); if (/\snot\s/.test(msg)) { return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; } return isObject ? 'deepStrictEqual' : 'strictEqual'; } chaijs-chai-2a3ecff/lib/chai/utils/getOwnEnumerableProperties.js000066400000000000000000000013401505212005400251100ustar00rootroot00000000000000/*! * Chai - getOwnEnumerableProperties utility * Copyright(c) 2011-2016 Jake Luer * MIT Licensed */ import {getOwnEnumerablePropertySymbols} from './getOwnEnumerablePropertySymbols.js'; /** * ### .getOwnEnumerableProperties(object) * * This allows the retrieval of directly-owned enumerable property names and * symbols of an object. This function is necessary because Object.keys only * returns enumerable property names, not enumerable property symbols. * * @param {object} obj * @returns {Array} * @namespace Utils * @name getOwnEnumerableProperties * @public */ export function getOwnEnumerableProperties(obj) { return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); } chaijs-chai-2a3ecff/lib/chai/utils/getOwnEnumerablePropertySymbols.js000066400000000000000000000014401505212005400261520ustar00rootroot00000000000000/*! * Chai - getOwnEnumerablePropertySymbols utility * Copyright(c) 2011-2016 Jake Luer * MIT Licensed */ /** * ### .getOwnEnumerablePropertySymbols(object) * * This allows the retrieval of directly-owned enumerable property symbols of an * object. This function is necessary because Object.getOwnPropertySymbols * returns both enumerable and non-enumerable property symbols. * * @param {object} obj * @returns {Array} * @namespace Utils * @name getOwnEnumerablePropertySymbols * @public */ export function getOwnEnumerablePropertySymbols(obj) { if (typeof Object.getOwnPropertySymbols !== 'function') return []; return Object.getOwnPropertySymbols(obj).filter(function (sym) { return Object.getOwnPropertyDescriptor(obj, sym).enumerable; }); } chaijs-chai-2a3ecff/lib/chai/utils/getProperties.js000066400000000000000000000014601505212005400224270ustar00rootroot00000000000000/*! * Chai - getProperties utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .getProperties(object) * * This allows the retrieval of property names of an object, enumerable or not, * inherited or not. * * @param {object} object * @returns {Array} * @namespace Utils * @name getProperties * @public */ export function getProperties(object) { let result = Object.getOwnPropertyNames(object); /** * @param {unknown} property */ function addProperty(property) { if (result.indexOf(property) === -1) { result.push(property); } } let proto = Object.getPrototypeOf(object); while (proto !== null) { Object.getOwnPropertyNames(proto).forEach(addProperty); proto = Object.getPrototypeOf(proto); } return result; } chaijs-chai-2a3ecff/lib/chai/utils/index.js000066400000000000000000000052411505212005400207030ustar00rootroot00000000000000/*! * chai * Copyright(c) 2011 Jake Luer * MIT Licensed */ // Dependencies that are used for multiple exports are required here only once import * as checkError from 'check-error'; // test utility export {test} from './test.js'; // type utility import {type} from './type-detect.js'; export {type}; // expectTypes utility export {expectTypes} from './expectTypes.js'; // message utility export {getMessage} from './getMessage.js'; // actual utility export {getActual} from './getActual.js'; // Inspect util export {inspect} from './inspect.js'; // Object Display util export {objDisplay} from './objDisplay.js'; // Flag utility export {flag} from './flag.js'; // Flag transferring utility export {transferFlags} from './transferFlags.js'; // Deep equal utility export {default as eql} from 'deep-eql'; // Deep path info export {getPathInfo, hasProperty} from 'pathval'; /** * Function name * * @param {Function} fn * @returns {string} */ export function getName(fn) { return fn.name; } // add Property export {addProperty} from './addProperty.js'; // add Method export {addMethod} from './addMethod.js'; // overwrite Property export {overwriteProperty} from './overwriteProperty.js'; // overwrite Method export {overwriteMethod} from './overwriteMethod.js'; // Add a chainable method export {addChainableMethod} from './addChainableMethod.js'; // Overwrite chainable method export {overwriteChainableMethod} from './overwriteChainableMethod.js'; // Compare by inspect method export {compareByInspect} from './compareByInspect.js'; // Get own enumerable property symbols method export {getOwnEnumerablePropertySymbols} from './getOwnEnumerablePropertySymbols.js'; // Get own enumerable properties method export {getOwnEnumerableProperties} from './getOwnEnumerableProperties.js'; // Checks error against a given set of criteria export {checkError}; // Proxify util export {proxify} from './proxify.js'; // addLengthGuard util export {addLengthGuard} from './addLengthGuard.js'; // isProxyEnabled helper export {isProxyEnabled} from './isProxyEnabled.js'; // isNaN method export {isNaN} from './isNaN.js'; // getOperator method export {getOperator} from './getOperator.js'; /** * Determines if an object is a `RegExp` * This is used since `instanceof` will not work in virtual contexts * * @param {*} obj Object to test * @returns {boolean} */ export function isRegExp(obj) { return Object.prototype.toString.call(obj) === '[object RegExp]'; } /** * Determines if an object is numeric or not * * @param {unknown} obj Object to test * @returns {boolean} */ export function isNumeric(obj) { return ['Number', 'BigInt'].includes(type(obj)); } chaijs-chai-2a3ecff/lib/chai/utils/inspect.js000066400000000000000000000021401505212005400212340ustar00rootroot00000000000000// This is (almost) directly from Node.js utils // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js import {inspect as _inspect} from 'loupe'; import {config} from '../config.js'; /** * ### .inspect(obj, [showHidden], [depth], [colors]) * * Echoes the value of a value. Tries to print the value out * in the best way possible given the different types. * * @param {object} obj The object to print out. * @param {boolean} showHidden Flag that shows hidden (not enumerable) * properties of objects. Default is false. * @param {number} depth Depth in which to descend in object. Default is 2. * @param {boolean} colors Flag to turn on ANSI escape codes to color the * output. Default is false (no coloring). * @returns {string} * @namespace Utils * @name inspect */ export function inspect(obj, showHidden, depth, colors) { let options = { colors: colors, depth: typeof depth === 'undefined' ? 2 : depth, showHidden: showHidden, truncate: config.truncateThreshold ? config.truncateThreshold : Infinity }; return _inspect(obj, options); } chaijs-chai-2a3ecff/lib/chai/utils/isNaN.js000066400000000000000000000002441505212005400206020ustar00rootroot00000000000000/*! * Chai - isNaN utility * Copyright(c) 2012-2015 Sakthipriyan Vairamani * MIT Licensed */ export const isNaN = Number.isNaN; chaijs-chai-2a3ecff/lib/chai/utils/isProxyEnabled.js000066400000000000000000000011311505212005400225160ustar00rootroot00000000000000import {config} from '../config.js'; /*! * Chai - isProxyEnabled helper * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .isProxyEnabled() * * Helper function to check if Chai's proxy protection feature is enabled. If * proxies are unsupported or disabled via the user's Chai config, then return * false. Otherwise, return true. * * @namespace Utils * @name isProxyEnabled * @returns {boolean} */ export function isProxyEnabled() { return ( config.useProxy && typeof Proxy !== 'undefined' && typeof Reflect !== 'undefined' ); } chaijs-chai-2a3ecff/lib/chai/utils/objDisplay.js000066400000000000000000000023301505212005400216700ustar00rootroot00000000000000/*! * Chai - flag utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {inspect} from './inspect.js'; import {config} from '../config.js'; /** * ### .objDisplay(object) * * Determines if an object or an array matches * criteria to be inspected in-line for error * messages or should be truncated. * * @param {unknown} obj javascript object to inspect * @returns {string} stringified object * @name objDisplay * @namespace Utils * @public */ export function objDisplay(obj) { let str = inspect(obj), type = Object.prototype.toString.call(obj); if (config.truncateThreshold && str.length >= config.truncateThreshold) { if (type === '[object Function]') { return !obj.name || obj.name === '' ? '[Function]' : '[Function: ' + obj.name + ']'; } else if (type === '[object Array]') { return '[ Array(' + obj.length + ') ]'; } else if (type === '[object Object]') { let keys = Object.keys(obj), kstr = keys.length > 2 ? keys.splice(0, 2).join(', ') + ', ...' : keys.join(', '); return '{ Object (' + kstr + ') }'; } else { return str; } } else { return str; } } chaijs-chai-2a3ecff/lib/chai/utils/overwriteChainableMethod.js000066400000000000000000000041651505212005400245560ustar00rootroot00000000000000/*! * Chai - overwriteChainableMethod utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {transferFlags} from './transferFlags.js'; /** * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) * * Overwrites an already existing chainable method * and provides access to the previous function or * property. Must return functions to be used for * name. * * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', * function (_super) { * } * , function (_super) { * } * ); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteChainableMethod('foo', fn, fn); * * Then can be used as any other assertion. * * expect(myFoo).to.have.lengthOf(3); * expect(myFoo).to.have.lengthOf.above(3); * * @param {object} ctx object whose method / property is to be overwritten * @param {string} name of method / property to overwrite * @param {Function} method function that returns a function to be used for name * @param {Function} chainingBehavior function that returns a function to be used for property * @namespace Utils * @name overwriteChainableMethod * @public */ export function overwriteChainableMethod(ctx, name, method, chainingBehavior) { let chainableBehavior = ctx.__methods[name]; let _chainingBehavior = chainableBehavior.chainingBehavior; chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { let result = chainingBehavior(_chainingBehavior).call(this); if (result !== undefined) { return result; } let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }; let _method = chainableBehavior.method; chainableBehavior.method = function overwritingChainableMethodWrapper() { let result = method(_method).apply(this, arguments); if (result !== undefined) { return result; } let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }; } chaijs-chai-2a3ecff/lib/chai/utils/overwriteMethod.js000066400000000000000000000060641505212005400227670ustar00rootroot00000000000000/*! * Chai - overwriteMethod utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {addLengthGuard} from './addLengthGuard.js'; import {flag} from './flag.js'; import {proxify} from './proxify.js'; import {transferFlags} from './transferFlags.js'; /** * ### .overwriteMethod(ctx, name, fn) * * Overwrites an already existing method and provides * access to previous function. Must return function * to be used for name. * * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { * return function (str) { * var obj = utils.flag(this, 'object'); * if (obj instanceof Foo) { * new chai.Assertion(obj.value).to.equal(str); * } else { * _super.apply(this, arguments); * } * } * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteMethod('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.equal('bar'); * * @param {object} ctx object whose method is to be overwritten * @param {string} name of method to overwrite * @param {Function} method function that returns a function to be used for name * @namespace Utils * @name overwriteMethod * @public */ export function overwriteMethod(ctx, name, method) { let _method = ctx[name], _super = function () { throw new Error(name + ' is not a function'); }; if (_method && 'function' === typeof _method) _super = _method; let overwritingMethodWrapper = function () { // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this // function to be the starting point for removing implementation frames from // the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if the // `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked from // inside of another assertion. In the first case, the `ssfi` flag has // already been set by the overwriting assertion. In the second case, the // `ssfi` flag has already been set by the outer assertion. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', overwritingMethodWrapper); } // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion // from changing the `ssfi` flag. By this point, the `ssfi` flag is already // set to the correct starting point for this assertion. let origLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); let result = method(_super).apply(this, arguments); flag(this, 'lockSsfi', origLockSsfi); if (result !== undefined) { return result; } let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }; addLengthGuard(overwritingMethodWrapper, name, false); ctx[name] = proxify(overwritingMethodWrapper, name); } chaijs-chai-2a3ecff/lib/chai/utils/overwriteProperty.js000066400000000000000000000062431505212005400233720ustar00rootroot00000000000000/*! * Chai - overwriteProperty utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {Assertion} from '../assertion.js'; import {flag} from './flag.js'; import {isProxyEnabled} from './isProxyEnabled.js'; import {transferFlags} from './transferFlags.js'; /** * ### .overwriteProperty(ctx, name, fn) * * Overwrites an already existing property getter and provides * access to previous value. Must return function to use as getter. * * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { * return function () { * var obj = utils.flag(this, 'object'); * if (obj instanceof Foo) { * new chai.Assertion(obj.name).to.equal('bar'); * } else { * _super.call(this); * } * } * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteProperty('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.be.ok; * * @param {object} ctx object whose property is to be overwritten * @param {string} name of property to overwrite * @param {Function} getter function that returns a getter function to be used for name * @namespace Utils * @name overwriteProperty * @public */ export function overwriteProperty(ctx, name, getter) { let _get = Object.getOwnPropertyDescriptor(ctx, name), _super = function () {}; if (_get && 'function' === typeof _get.get) _super = _get.get; Object.defineProperty(ctx, name, { get: function overwritingPropertyGetter() { // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this // function to be the starting point for removing implementation frames // from the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set and proxy protection is disabled. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked // from inside of another assertion. In the first case, the `ssfi` flag // has already been set by the overwriting assertion. In the second // case, the `ssfi` flag has already been set by the outer assertion. // // If proxy protection is enabled, then the `ssfi` flag has already been // set by the proxy getter. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { flag(this, 'ssfi', overwritingPropertyGetter); } // Setting the `lockSsfi` flag to `true` prevents the overwritten // assertion from changing the `ssfi` flag. By this point, the `ssfi` // flag is already set to the correct starting point for this assertion. let origLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); let result = getter(_super).call(this); flag(this, 'lockSsfi', origLockSsfi); if (result !== undefined) { return result; } let newAssertion = new Assertion(); transferFlags(this, newAssertion); return newAssertion; }, configurable: true }); } chaijs-chai-2a3ecff/lib/chai/utils/proxify.js000066400000000000000000000125651505212005400213030ustar00rootroot00000000000000import {config} from '../config.js'; import {flag} from './flag.js'; import {getProperties} from './getProperties.js'; import {isProxyEnabled} from './isProxyEnabled.js'; /*! * Chai - proxify utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** @type {PropertyKey[]} */ const builtins = ['__flags', '__methods', '_obj', 'assert']; /** * ### .proxify(object) * * Return a proxy of given object that throws an error when a non-existent * property is read. By default, the root cause is assumed to be a misspelled * property, and thus an attempt is made to offer a reasonable suggestion from * the list of existing properties. However, if a nonChainableMethodName is * provided, then the root cause is instead a failure to invoke a non-chainable * method prior to reading the non-existent property. * * If proxies are unsupported or disabled via the user's Chai config, then * return object without modification. * * @namespace Utils * @template {object} T * @param {T} obj * @param {string} [nonChainableMethodName] * @returns {T} */ export function proxify(obj, nonChainableMethodName) { if (!isProxyEnabled()) return obj; return new Proxy(obj, { get: function proxyGetter(target, property) { // This check is here because we should not throw errors on Symbol properties // such as `Symbol.toStringTag`. // The values for which an error should be thrown can be configured using // the `config.proxyExcludedKeys` setting. if ( typeof property === 'string' && config.proxyExcludedKeys.indexOf(property) === -1 && !Reflect.has(target, property) ) { // Special message for invalid property access of non-chainable methods. if (nonChainableMethodName) { throw Error( 'Invalid Chai property: ' + nonChainableMethodName + '.' + property + '. See docs for proper usage of "' + nonChainableMethodName + '".' ); } // If the property is reasonably close to an existing Chai property, // suggest that property to the user. Only suggest properties with a // distance less than 4. let suggestion = null; let suggestionDistance = 4; getProperties(target).forEach(function (prop) { if ( // we actually mean to check `Object.prototype` here // eslint-disable-next-line no-prototype-builtins !Object.prototype.hasOwnProperty(prop) && builtins.indexOf(prop) === -1 ) { let dist = stringDistanceCapped(property, prop, suggestionDistance); if (dist < suggestionDistance) { suggestion = prop; suggestionDistance = dist; } } }); if (suggestion !== null) { throw Error( 'Invalid Chai property: ' + property + '. Did you mean "' + suggestion + '"?' ); } else { throw Error('Invalid Chai property: ' + property); } } // Use this proxy getter as the starting point for removing implementation // frames from the stack trace of a failed assertion. For property // assertions, this prevents the proxy getter from showing up in the stack // trace since it's invoked before the property getter. For method and // chainable method assertions, this flag will end up getting changed to // the method wrapper, which is good since this frame will no longer be in // the stack once the method is invoked. Note that Chai builtin assertion // properties such as `__flags` are skipped since this is only meant to // capture the starting point of an assertion. This step is also skipped // if the `lockSsfi` flag is set, thus indicating that this assertion is // being called from within another assertion. In that case, the `ssfi` // flag is already set to the outer assertion's starting point. if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { flag(target, 'ssfi', proxyGetter); } return Reflect.get(target, property); } }); } /** * # stringDistanceCapped(strA, strB, cap) * Return the Levenshtein distance between two strings, but no more than cap. * * @param {string} strA * @param {string} strB * @param {number} cap * @returns {number} min(string distance between strA and strB, cap) * @private */ function stringDistanceCapped(strA, strB, cap) { if (Math.abs(strA.length - strB.length) >= cap) { return cap; } let memo = []; // `memo` is a two-dimensional array containing distances. // memo[i][j] is the distance between strA.slice(0, i) and // strB.slice(0, j). for (let i = 0; i <= strA.length; i++) { memo[i] = Array(strB.length + 1).fill(0); memo[i][0] = i; } for (let j = 0; j < strB.length; j++) { memo[0][j] = j; } for (let i = 1; i <= strA.length; i++) { let ch = strA.charCodeAt(i - 1); for (let j = 1; j <= strB.length; j++) { if (Math.abs(i - j) >= cap) { memo[i][j] = cap; continue; } memo[i][j] = Math.min( memo[i - 1][j] + 1, memo[i][j - 1] + 1, memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) ); } } return memo[strA.length][strB.length]; } chaijs-chai-2a3ecff/lib/chai/utils/test.js000066400000000000000000000007351505212005400205560ustar00rootroot00000000000000/*! * Chai - test utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ import {flag} from './flag.js'; /** * ### .test(object, expression) * * Test an object for expression. * * @param {object} obj (constructed Assertion) * @param {unknown} args * @returns {unknown} * @namespace Utils * @name test */ export function test(obj, args) { let negate = flag(obj, 'negate'), expr = args[0]; return negate ? !expr : expr; } chaijs-chai-2a3ecff/lib/chai/utils/transferFlags.js000066400000000000000000000025721505212005400224010ustar00rootroot00000000000000/*! * Chai - transferFlags utility * Copyright(c) 2012-2014 Jake Luer * MIT Licensed */ /** * ### .transferFlags(assertion, object, includeAll = true) * * Transfer all the flags for `assertion` to `object`. If * `includeAll` is set to `false`, then the base Chai * assertion flags (namely `object`, `ssfi`, `lockSsfi`, * and `message`) will not be transferred. * * var newAssertion = new Assertion(); * utils.transferFlags(assertion, newAssertion); * * var anotherAssertion = new Assertion(myObj); * utils.transferFlags(assertion, anotherAssertion, false); * * @param {import('../assertion.js').Assertion} assertion the assertion to transfer the flags from * @param {object} object the object to transfer the flags to; usually a new assertion * @param {boolean} includeAll * @namespace Utils * @name transferFlags * @private */ export function transferFlags(assertion, object, includeAll) { let flags = assertion.__flags || (assertion.__flags = Object.create(null)); if (!object.__flags) { object.__flags = Object.create(null); } includeAll = arguments.length === 3 ? includeAll : true; for (let flag in flags) { if ( includeAll || (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message') ) { object.__flags[flag] = flags[flag]; } } } chaijs-chai-2a3ecff/lib/chai/utils/type-detect.js000066400000000000000000000006001505212005400220150ustar00rootroot00000000000000/** * @param {unknown} obj * @returns {string} */ export function type(obj) { if (typeof obj === 'undefined') { return 'undefined'; } if (obj === null) { return 'null'; } const stringTag = obj[Symbol.toStringTag]; if (typeof stringTag === 'string') { return stringTag; } const type = Object.prototype.toString.call(obj).slice(8, -1); return type; } chaijs-chai-2a3ecff/package-lock.json000066400000000000000000007562221505212005400176540ustar00rootroot00000000000000{ "name": "chai", "version": "0.0.0-development", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "chai", "version": "0.0.0-development", "license": "MIT", "devDependencies": { "@eslint/js": "^9.17.0", "@rollup/plugin-commonjs": "^25.0.7", "@web/dev-server-rollup": "^0.6.1", "@web/test-runner": "^0.18.0", "@web/test-runner-playwright": "^0.11.0", "assertion-error": "^2.0.1", "c8": "^10.1.3", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "esbuild": "^0.25.9", "eslint": "^8.56.0", "eslint-plugin-jsdoc": "^48.0.4", "loupe": "^3.1.0", "mocha": "^10.2.0", "pathval": "^2.0.0", "prettier": "^3.4.2", "typescript": "~5.7.3" }, "engines": { "node": ">=18" } }, "node_modules/@75lb/deep-merge": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz", "integrity": "sha512-08K9ou5VNbheZFxM5tDWoqjA3ImC50DiuuJ2tj1yEPRfkp8lLLg6XAaJ4On+a0yAXor/8ay5gHnAIshRM44Kpw==", "dev": true, "dependencies": { "lodash": "^4.17.21", "typical": "^7.1.1" }, "engines": { "node": ">=12.17" } }, "node_modules/@75lb/deep-merge/node_modules/typical": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@es-joy/jsdoccomment": { "version": "0.41.0", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", "integrity": "sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==", "dev": true, "dependencies": { "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { "node": ">=16" } }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", "cpu": [ "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", "cpu": [ "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", "cpu": [ "loong64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", "cpu": [ "mips64el" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", "cpu": [ "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", "cpu": [ "riscv64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", "cpu": [ "s390x" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openharmony-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openharmony" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", "cpu": [ "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/@eslint/js": { "version": "9.17.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "engines": { "node": ">=12.22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@puppeteer/browsers": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^4.3.5", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.4.0", "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" }, "engines": { "node": ">=18" } }, "node_modules/@puppeteer/browsers/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@puppeteer/browsers/node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/@puppeteer/browsers/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/@puppeteer/browsers/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/@puppeteer/browsers/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@puppeteer/browsers/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/@puppeteer/browsers/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/@rollup/plugin-commonjs": { "version": "25.0.7", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", "magic-string": "^0.30.3" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^2.3.1" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", "cpu": [ "ppc64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", "cpu": [ "riscv64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", "cpu": [ "s390x" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "dev": true, "license": "MIT" }, "node_modules/@types/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/babel__code-frame": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.6.tgz", "integrity": "sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==", "dev": true }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/co-body": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/@types/co-body/-/co-body-6.1.3.tgz", "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==", "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*" } }, "node_modules/@types/command-line-args": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", "dev": true }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/content-disposition": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", "dev": true }, "node_modules/@types/convert-source-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-2.0.3.tgz", "integrity": "sha512-ag0BfJLZf6CQz8VIuRIEYQ5Ggwk/82uvTQf27RcpyDNbY0Vw49LIPqAxk5tqYfrCs9xDaIMvl4aj7ZopnYL8bA==", "dev": true }, "node_modules/@types/cookies": { "version": "0.7.10", "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.10.tgz", "integrity": "sha512-hmUCjAk2fwZVPPkkPBcI7jGLIR5mg4OVoNMBwU6aVsMm/iNPY7z9/R+x2fSwLt/ZXoGua6C5Zy2k5xOo9jUyhQ==", "dev": true, "dependencies": { "@types/connect": "*", "@types/express": "*", "@types/keygrip": "*", "@types/node": "*" } }, "node_modules/@types/debounce": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", "dev": true }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "node_modules/@types/http-assert": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", "dev": true }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/keygrip": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==", "dev": true }, "node_modules/@types/koa": { "version": "2.13.12", "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.12.tgz", "integrity": "sha512-vAo1KuDSYWFDB4Cs80CHvfmzSQWeUb909aQib0C0aFx4sw0K9UZFz2m5jaEP+b3X1+yr904iQiruS0hXi31jbw==", "dev": true, "dependencies": { "@types/accepts": "*", "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", "@types/http-errors": "*", "@types/keygrip": "*", "@types/koa-compose": "*", "@types/node": "*" } }, "node_modules/@types/koa-compose": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", "dev": true, "dependencies": { "@types/koa": "*" } }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, "node_modules/@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/parse5": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", "dev": true }, "node_modules/@types/qs": { "version": "6.9.11", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", "dev": true }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@types/node": "*" } }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, "node_modules/@web/browser-logs": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", "dev": true, "dependencies": { "errorstacks": "^2.2.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/config-loader": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.1.tgz", "integrity": "sha512-IYjHXUgSGGNpO3YJQ9foLcazbJlAWDdJGRe9be7aOhon0Nd6Na5JIOJAej7jsMu76fKHr4b4w2LfIdNQ4fJ8pA==", "dev": true, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/dev-server": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.6.tgz", "integrity": "sha512-jj/1bcElAy5EZet8m2CcUdzxT+CRvUjIXGh8Lt7vxtthkN9PzY9wlhWx/9WOs5iwlnG1oj0VGo6f/zvbPO0s9w==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.11", "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.3.0", "@web/dev-server-core": "^0.7.2", "@web/dev-server-rollup": "^0.6.1", "camelcase": "^6.2.0", "command-line-args": "^5.1.1", "command-line-usage": "^7.0.1", "debounce": "^1.2.0", "deepmerge": "^4.2.2", "internal-ip": "^6.2.0", "nanocolors": "^0.2.1", "open": "^8.0.2", "portfinder": "^1.0.32" }, "bin": { "wds": "dist/bin.js", "web-dev-server": "dist/bin.js" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/dev-server-core": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.3.tgz", "integrity": "sha512-GS+Ok6HiqNZOsw2oEv5V2OISZ2s/6icJodyGjUuD3RChr0G5HiESbKf2K8mZV4shTz9sRC9KSQf8qvno2gPKrQ==", "dev": true, "license": "MIT", "dependencies": { "@types/koa": "^2.11.6", "@types/ws": "^7.4.0", "@web/parse5-utils": "^2.1.0", "chokidar": "^4.0.1", "clone": "^2.1.2", "es-module-lexer": "^1.0.0", "get-stream": "^6.0.0", "is-stream": "^2.0.0", "isbinaryfile": "^5.0.0", "koa": "^2.13.0", "koa-etag": "^4.0.0", "koa-send": "^5.0.1", "koa-static": "^5.0.0", "lru-cache": "^8.0.4", "mime-types": "^2.1.27", "parse5": "^6.0.1", "picomatch": "^2.2.2", "ws": "^7.5.10" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/dev-server-core/node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, "engines": { "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/dev-server-core/node_modules/readdirp": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", "dev": true, "license": "MIT", "engines": { "node": ">= 14.16.0" }, "funding": { "type": "individual", "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/dev-server-rollup": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.1.tgz", "integrity": "sha512-vhtsQ8qu1pBHailOBOYJwZnYDc1Lmx6ZAd2j+y5PD2ck0R1LmVsZ7dZK8hDCpkvpvlu2ndURjL9tbzdcsBRJmg==", "dev": true, "dependencies": { "@rollup/plugin-node-resolve": "^15.0.1", "@web/dev-server-core": "^0.7.0", "nanocolors": "^0.2.1", "parse5": "^6.0.1", "rollup": "^4.4.0", "whatwg-url": "^11.0.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/parse5-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", "dev": true, "dependencies": { "@types/parse5": "^6.0.1", "parse5": "^6.0.1" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner": { "version": "0.18.3", "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.18.3.tgz", "integrity": "sha512-QkVK8Qguw3Zhyu8SYR7F4VdcjyXBeJNr8W8L++s4zO/Ok7DR/Wu7+rLswn3H7OH3xYoCHRmwteehcFejefz6ew==", "dev": true, "license": "MIT", "dependencies": { "@web/browser-logs": "^0.4.0", "@web/config-loader": "^0.3.0", "@web/dev-server": "^0.4.0", "@web/test-runner-chrome": "^0.16.0", "@web/test-runner-commands": "^0.9.0", "@web/test-runner-core": "^0.13.0", "@web/test-runner-mocha": "^0.9.0", "camelcase": "^6.2.0", "command-line-args": "^5.1.1", "command-line-usage": "^7.0.1", "convert-source-map": "^2.0.0", "diff": "^5.0.0", "globby": "^11.0.1", "nanocolors": "^0.2.1", "portfinder": "^1.0.32", "source-map": "^0.7.3" }, "bin": { "web-test-runner": "dist/bin.js", "wtr": "dist/bin.js" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-chrome": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.16.0.tgz", "integrity": "sha512-Edc6Y49aVB6k18S5IOj9OCX3rEf8F3jptIu0p95+imqxmcutFEh1GNmlAk2bQGnXS0U6uVY7Xbf61fiaXUQqhg==", "dev": true, "license": "MIT", "dependencies": { "@web/test-runner-core": "^0.13.0", "@web/test-runner-coverage-v8": "^0.8.0", "async-mutex": "0.4.0", "chrome-launcher": "^0.15.0", "puppeteer-core": "^22.0.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-commands": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", "dev": true, "dependencies": { "@web/test-runner-core": "^0.13.0", "mkdirp": "^1.0.4" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-core": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", "integrity": "sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.11", "@types/babel__code-frame": "^7.0.2", "@types/co-body": "^6.1.0", "@types/convert-source-map": "^2.0.0", "@types/debounce": "^1.2.0", "@types/istanbul-lib-coverage": "^2.0.3", "@types/istanbul-reports": "^3.0.0", "@web/browser-logs": "^0.4.0", "@web/dev-server-core": "^0.7.3", "chokidar": "^4.0.1", "cli-cursor": "^3.1.0", "co-body": "^6.1.0", "convert-source-map": "^2.0.0", "debounce": "^1.2.0", "dependency-graph": "^0.11.0", "globby": "^11.0.1", "internal-ip": "^6.2.0", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.0.2", "log-update": "^4.0.0", "nanocolors": "^0.2.1", "nanoid": "^3.1.25", "open": "^8.0.2", "picomatch": "^2.2.2", "source-map": "^0.7.3" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-core/node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, "engines": { "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/test-runner-core/node_modules/readdirp": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", "dev": true, "license": "MIT", "engines": { "node": ">= 14.16.0" }, "funding": { "type": "individual", "url": "https://paulmillr.com/funding/" } }, "node_modules/@web/test-runner-coverage-v8": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, "dependencies": { "@web/test-runner-core": "^0.13.0", "istanbul-lib-coverage": "^3.0.0", "lru-cache": "^8.0.4", "picomatch": "^2.2.2", "v8-to-istanbul": "^9.0.1" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-mocha": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz", "integrity": "sha512-ZL9F6FXd0DBQvo/h/+mSfzFTSRVxzV9st/AHhpgABtUtV/AIpVE9to6+xdkpu6827kwjezdpuadPfg+PlrBWqQ==", "dev": true, "dependencies": { "@web/test-runner-core": "^0.13.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@web/test-runner-playwright": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", "dev": true, "dependencies": { "@web/test-runner-core": "^0.13.0", "@web/test-runner-coverage-v8": "^0.8.0", "playwright": "^1.22.2" }, "engines": { "node": ">=18.0.0" } }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" } }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/agent-base": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.4" }, "engines": { "node": ">= 14" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { "type-fest": "^0.21.3" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/are-docs-informative": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, "engines": { "node": ">=14" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, "engines": { "node": ">=4" } }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "dependencies": { "lodash": "^4.17.14" } }, "node_modules/async-mutex": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.4.0" } }, "node_modules/b4a": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", "dev": true, "license": "Apache-2.0" }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/bare-events": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", "dev": true, "license": "Apache-2.0", "optional": true }, "node_modules/bare-fs": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.2.tgz", "integrity": "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4" }, "engines": { "bare": ">=1.16.0" }, "peerDependencies": { "bare-buffer": "*" }, "peerDependenciesMeta": { "bare-buffer": { "optional": true } } }, "node_modules/bare-os": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", "dev": true, "license": "Apache-2.0", "optional": true, "engines": { "bare": ">=1.14.0" } }, "node_modules/bare-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": { "bare-buffer": { "optional": true }, "bare-events": { "optional": true } } }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/basic-ftp": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/c8": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==", "dev": true, "license": "ISC", "dependencies": { "@bcoe/v8-coverage": "^1.0.1", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", "foreground-child": "^3.1.1", "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.1.6", "test-exclude": "^7.0.1", "v8-to-istanbul": "^9.0.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1" }, "bin": { "c8": "bin/c8.js" }, "engines": { "node": ">=18" }, "peerDependencies": { "monocart-coverage-reports": "^2" }, "peerDependenciesMeta": { "monocart-coverage-reports": { "optional": true } } }, "node_modules/c8/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/c8/node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/c8/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/c8/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/c8/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/c8/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/c8/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/cache-content-type": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", "dev": true, "dependencies": { "mime-types": "^2.1.18", "ylru": "^1.2.0" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/chalk-template": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", "dev": true, "dependencies": { "chalk": "^4.1.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, "node_modules/chalk-template/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/chalk-template/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk-template/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/chalk-template/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/chalk-template/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/chalk-template/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "engines": { "node": ">= 16" } }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chrome-launcher": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" }, "engines": { "node": ">=12.13.0" } }, "node_modules/chrome-launcher/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chromium-bidi": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", "dev": true, "license": "Apache-2.0", "dependencies": { "mitt": "3.0.1", "urlpattern-polyfill": "10.0.0", "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" } }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "dependencies": { "restore-cursor": "^3.1.0" }, "engines": { "node": ">=8" } }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cliui/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/cliui/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, "engines": { "node": ">=0.8" } }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, "node_modules/co-body": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz", "integrity": "sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==", "dev": true, "dependencies": { "inflation": "^2.0.0", "qs": "^6.5.2", "raw-body": "^2.3.3", "type-is": "^1.6.16" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/command-line-args": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", "dev": true, "dependencies": { "array-back": "^3.1.0", "find-replace": "^3.0.0", "lodash.camelcase": "^4.3.0", "typical": "^4.0.0" }, "engines": { "node": ">=4.0.0" } }, "node_modules/command-line-usage": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", "dev": true, "dependencies": { "array-back": "^6.2.2", "chalk-template": "^0.4.0", "table-layout": "^3.0.0", "typical": "^7.1.1" }, "engines": { "node": ">=12.20.0" } }, "node_modules/command-line-usage/node_modules/array-back": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/command-line-usage/node_modules/typical": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, "engines": { "node": ">= 12.0.0" } }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "dependencies": { "safe-buffer": "5.2.1" }, "engines": { "node": ">= 0.6" } }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/cookies": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", "dev": true, "dependencies": { "depd": "~2.0.0", "keygrip": "~1.1.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", "dev": true }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", "dev": true }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, "engines": { "node": ">= 10" } }, "node_modules/define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/degenerator": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" }, "engines": { "node": ">= 14" } }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, "engines": { "node": ">= 0.6.0" } }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/devtools-protocol": { "version": "0.0.1312386", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { "path-type": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" } }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/errorstacks": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/errorstacks/-/errorstacks-2.4.1.tgz", "integrity": "sha512-jE4i0SMYevwu/xxAuzhly/KTwtj0xDhbzB6m1xPImxTkw8wcCbgarOQPfCVMi5JKVyW7in29pNJCCJrry3Ynnw==", "dev": true }, "node_modules/es-module-lexer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", "dev": true }, "node_modules/esbuild": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { "node": ">=18" }, "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.9", "@esbuild/android-arm": "0.25.9", "@esbuild/android-arm64": "0.25.9", "@esbuild/android-x64": "0.25.9", "@esbuild/darwin-arm64": "0.25.9", "@esbuild/darwin-x64": "0.25.9", "@esbuild/freebsd-arm64": "0.25.9", "@esbuild/freebsd-x64": "0.25.9", "@esbuild/linux-arm": "0.25.9", "@esbuild/linux-arm64": "0.25.9", "@esbuild/linux-ia32": "0.25.9", "@esbuild/linux-loong64": "0.25.9", "@esbuild/linux-mips64el": "0.25.9", "@esbuild/linux-ppc64": "0.25.9", "@esbuild/linux-riscv64": "0.25.9", "@esbuild/linux-s390x": "0.25.9", "@esbuild/linux-x64": "0.25.9", "@esbuild/netbsd-arm64": "0.25.9", "@esbuild/netbsd-x64": "0.25.9", "@esbuild/openbsd-arm64": "0.25.9", "@esbuild/openbsd-x64": "0.25.9", "@esbuild/openharmony-arm64": "0.25.9", "@esbuild/sunos-x64": "0.25.9", "@esbuild/win32-arm64": "0.25.9", "@esbuild/win32-ia32": "0.25.9", "@esbuild/win32-x64": "0.25.9" } }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/escodegen": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" }, "engines": { "node": ">=6.0" }, "optionalDependencies": { "source-map": "~0.6.1" } }, "node_modules/escodegen/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint": { "version": "8.56.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-plugin-jsdoc": { "version": "48.0.4", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.0.4.tgz", "integrity": "sha512-A0cH+5svWPXzGZszBjXA1t0aAqVGS+/x3i02KFmb73rU0iMLnadEcVWcD/dGBZHIfAMKr3YpWh58f6wn4N909w==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.41.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", "semver": "^7.5.4", "spdx-expression-parse": "^4.0.0" }, "engines": { "node": ">=18" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/@eslint/js": { "version": "8.56.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { "is-glob": "^4.0.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" }, "engines": { "node": ">= 10.17.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" } }, "node_modules/extract-zip/node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "license": "MIT", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "dev": true, "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, "engines": { "node": ">=8.6.0" } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "license": "MIT", "dependencies": { "pend": "~1.2.0" } }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "dependencies": { "array-back": "^3.0.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { "node": ">=14.14" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-uri": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4", "fs-extra": "^11.2.0" }, "engines": { "node": ">= 14" } }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globals/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "bin": { "he": "bin/he" } }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", "dev": true, "dependencies": { "deep-equal": "~1.0.1", "http-errors": "~1.8.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/http-errors": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, "node_modules/http-errors/node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" }, "engines": { "node": ">= 14" } }, "node_modules/https-proxy-agent": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" }, "engines": { "node": ">= 14" } }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" } }, "node_modules/inflation": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/internal-ip": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", "dev": true, "license": "MIT", "dependencies": { "default-gateway": "^6.0.0", "ipaddr.js": "^1.9.1", "is-ip": "^3.1.0", "p-event": "^4.2.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" } }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, "license": "MIT", "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" }, "engines": { "node": ">= 12" } }, "node_modules/ip-regex": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-builtin-module": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, "dependencies": { "builtin-modules": "^3.3.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "bin": { "is-docker": "cli.js" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-ip": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", "dev": true, "license": "MIT", "dependencies": { "ip-regex": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "dependencies": { "@types/estree": "*" } }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "dependencies": { "is-docker": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/isbinaryfile": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", "dev": true, "engines": { "node": ">= 14.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" } }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/istanbul-reports": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsbn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true, "license": "MIT" }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/keygrip": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", "dev": true, "dependencies": { "tsscmp": "1.0.6" }, "engines": { "node": ">= 0.6" } }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/koa": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/koa/-/koa-2.14.2.tgz", "integrity": "sha512-VFI2bpJaodz6P7x2uyLiX6RLYpZmOJqNmoCst/Yyd7hQlszyPwG/I9CQJ63nOtKSxpt5M7NH67V6nJL2BwCl7g==", "dev": true, "dependencies": { "accepts": "^1.3.5", "cache-content-type": "^1.0.0", "content-disposition": "~0.5.2", "content-type": "^1.0.4", "cookies": "~0.8.0", "debug": "^4.3.2", "delegates": "^1.0.0", "depd": "^2.0.0", "destroy": "^1.0.4", "encodeurl": "^1.0.2", "escape-html": "^1.0.3", "fresh": "~0.5.2", "http-assert": "^1.3.0", "http-errors": "^1.6.3", "is-generator-function": "^1.0.7", "koa-compose": "^4.1.0", "koa-convert": "^2.0.0", "on-finished": "^2.3.0", "only": "~0.0.2", "parseurl": "^1.3.2", "statuses": "^1.5.0", "type-is": "^1.6.16", "vary": "^1.1.2" }, "engines": { "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" } }, "node_modules/koa-compose": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", "dev": true }, "node_modules/koa-convert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", "dev": true, "dependencies": { "co": "^4.6.0", "koa-compose": "^4.1.0" }, "engines": { "node": ">= 10" } }, "node_modules/koa-etag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", "dev": true, "dependencies": { "etag": "^1.8.1" } }, "node_modules/koa-send": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", "dev": true, "dependencies": { "debug": "^4.1.1", "http-errors": "^1.7.3", "resolve-path": "^1.4.0" }, "engines": { "node": ">= 8" } }, "node_modules/koa-static": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", "dev": true, "dependencies": { "debug": "^3.1.0", "koa-send": "^5.0.0" }, "engines": { "node": ">= 7.6.0" } }, "node_modules/koa-static/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/lighthouse-logger": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "node_modules/lighthouse-logger/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/lighthouse-logger/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-symbols/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/log-symbols/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/log-symbols/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/log-symbols/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/log-symbols/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/log-update": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", "slice-ansi": "^4.0.0", "wrap-ansi": "^6.2.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loupe": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, "node_modules/lru-cache": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, "engines": { "node": ">=16.14" } }, "node_modules/magic-string": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" } }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { "semver": "^7.5.3" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/marky": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", "dev": true, "license": "Apache-2.0" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true, "license": "MIT" }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/mocha": { "version": "10.8.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "license": "MIT", "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^8.1.0", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^16.2.0", "yargs-parser": "^20.2.9", "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha.js" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/nanocolors": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", "dev": true }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/only": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", "dev": true }, "node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-event": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", "dev": true, "license": "MIT", "dependencies": { "p-timeout": "^3.1.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-timeout": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dev": true, "license": "MIT", "dependencies": { "p-finally": "^1.0.0" }, "engines": { "node": ">=8" } }, "node_modules/pac-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", "dev": true, "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.5", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.4" }, "engines": { "node": ">= 14" } }, "node_modules/pac-resolver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" }, "engines": { "node": ">= 14" } }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, "license": "ISC" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/pathval": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 14.16" } }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true, "license": "MIT" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/playwright": { "version": "1.49.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dev": true, "license": "Apache-2.0", "dependencies": { "playwright-core": "1.49.1" }, "bin": { "playwright": "cli.js" }, "engines": { "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { "version": "1.49.1", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, "dependencies": { "async": "^2.6.4", "debug": "^3.2.7", "mkdirp": "^0.5.6" }, "engines": { "node": ">= 0.12.0" } }, "node_modules/portfinder/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/portfinder/node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/proxy-agent": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.3", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.0.1", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.2" }, "engines": { "node": ">= 14" } }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true, "license": "MIT" }, "node_modules/pump": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/puppeteer-core": { "version": "22.15.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.3.0", "chromium-bidi": "0.6.3", "debug": "^4.3.6", "devtools-protocol": "0.0.1312386", "ws": "^8.18.0" }, "engines": { "node": ">=18" } }, "node_modules/puppeteer-core/node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/qs": { "version": "6.11.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dev": true, "dependencies": { "side-channel": "^1.0.4" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/raw-body/node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/raw-body/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/resolve-path": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", "dev": true, "dependencies": { "http-errors": "~1.6.2", "path-is-absolute": "1.0.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/resolve-path/node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/resolve-path/node_modules/http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", "statuses": ">= 1.4.0 < 2" }, "engines": { "node": ">= 0.6" } }, "node_modules/resolve-path/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "dev": true }, "node_modules/resolve-path/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { "node": ">=8" } }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/rollup": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", "dev": true, "dependencies": { "@types/estree": "1.0.5" }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.22.4", "@rollup/rollup-android-arm64": "4.22.4", "@rollup/rollup-darwin-arm64": "4.22.4", "@rollup/rollup-darwin-x64": "4.22.4", "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", "@rollup/rollup-linux-arm-musleabihf": "4.22.4", "@rollup/rollup-linux-arm64-gnu": "4.22.4", "@rollup/rollup-linux-arm64-musl": "4.22.4", "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", "@rollup/rollup-linux-riscv64-gnu": "4.22.4", "@rollup/rollup-linux-s390x-gnu": "4.22.4", "@rollup/rollup-linux-x64-gnu": "4.22.4", "@rollup/rollup-linux-x64-musl": "4.22.4", "@rollup/rollup-win32-arm64-msvc": "4.22.4", "@rollup/rollup-win32-ia32-msvc": "4.22.4", "@rollup/rollup-win32-x64-msvc": "4.22.4", "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/set-function-length": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dev": true, "dependencies": { "define-data-property": "^1.1.1", "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/slice-ansi/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "license": "MIT", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.8.3" }, "engines": { "node": ">= 14" } }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/spdx-exceptions": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==", "dev": true }, "node_modules/spdx-expression-parse": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/stream-read-all": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/streamx": { "version": "2.22.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", "dev": true, "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" } }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/table-layout": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", "dev": true, "dependencies": { "@75lb/deep-merge": "^1.1.1", "array-back": "^6.2.2", "command-line-args": "^5.2.1", "command-line-usage": "^7.0.0", "stream-read-all": "^3.0.1", "typical": "^7.1.1", "wordwrapjs": "^5.1.0" }, "bin": { "table-layout": "bin/cli.js" }, "engines": { "node": ">=12.17" } }, "node_modules/table-layout/node_modules/array-back": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/table-layout/node_modules/typical": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/tar-fs": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", "dev": true, "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0" } }, "node_modules/tar-stream": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "license": "MIT", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^9.0.4" }, "engines": { "node": ">=18" } }, "node_modules/test-exclude/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/test-exclude/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/text-decoder": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true, "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/tr46": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", "dev": true, "dependencies": { "punycode": "^2.1.1" }, "engines": { "node": ">=12" } }, "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true, "license": "0BSD" }, "node_modules/tsscmp": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", "dev": true, "engines": { "node": ">=0.6.x" } }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" }, "engines": { "node": ">= 0.6" } }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/typical": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/urlpattern-polyfill": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "dev": true, "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/wordwrapjs": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi-cjs/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, "engines": { "node": ">=10" } }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "node_modules/ylru": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.3.2.tgz", "integrity": "sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==", "dev": true, "engines": { "node": ">= 4.0.0" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zod": { "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } } } } chaijs-chai-2a3ecff/package.json000066400000000000000000000037611505212005400167170ustar00rootroot00000000000000{ "author": "Jake Luer ", "name": "chai", "type": "module", "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", "keywords": [ "test", "assertion", "assert", "testing", "chai" ], "files": [ "index.js", "register-*.js" ], "homepage": "http://chaijs.com", "license": "MIT", "contributors": [ "Jake Luer ", "Domenic Denicola (http://domenicdenicola.com)", "Veselin Todorov ", "John Firebaugh " ], "version": "0.0.0-development", "repository": { "type": "git", "url": "https://github.com/chaijs/chai" }, "bugs": { "url": "https://github.com/chaijs/chai/issues" }, "main": "./index.js", "scripts": { "build": "esbuild --bundle --format=esm --keep-names --outfile=index.js lib/chai.js", "prebuild": "npm run clean", "format": "prettier --write lib", "pretest": "npm run lint", "test": "npm run test-node && npm run test-chrome", "test-node": "c8 --99 --check-coverage mocha --require ./test/bootstrap/index.js test/*.js", "test-chrome": "web-test-runner --playwright", "lint": "npm run lint:js && npm run lint:format", "lint:js": "eslint lib/", "lint:format": "prettier --check lib", "lint:types": "tsc", "clean": "rm -rf index.js coverage/" }, "engines": { "node": ">=18" }, "devDependencies": { "@eslint/js": "^9.17.0", "@rollup/plugin-commonjs": "^25.0.7", "@web/dev-server-rollup": "^0.6.1", "@web/test-runner": "^0.18.0", "@web/test-runner-playwright": "^0.11.0", "assertion-error": "^2.0.1", "c8": "^10.1.3", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "esbuild": "^0.25.9", "eslint": "^8.56.0", "eslint-plugin-jsdoc": "^48.0.4", "loupe": "^3.1.0", "mocha": "^10.2.0", "pathval": "^2.0.0", "prettier": "^3.4.2", "typescript": "~5.7.3" } } chaijs-chai-2a3ecff/register-assert.js000066400000000000000000000001001505212005400200720ustar00rootroot00000000000000import {assert} from './index.js'; globalThis.assert = assert; chaijs-chai-2a3ecff/register-expect.js000066400000000000000000000001001505212005400200610ustar00rootroot00000000000000import {expect} from './index.js'; globalThis.expect = expect; chaijs-chai-2a3ecff/register-should.js000066400000000000000000000001021505212005400200710ustar00rootroot00000000000000import {should} from './index.js'; globalThis.should = should(); chaijs-chai-2a3ecff/test/000077500000000000000000000000001505212005400154015ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/assert.js000066400000000000000000003007551505212005400172520ustar00rootroot00000000000000import * as chai from '../index.js'; import {globalErr as err} from './bootstrap/index.js'; describe('assert', function () { const {assert} = chai; it('assert', function () { var foo = 'bar'; assert(foo == 'bar', "expected foo to equal `bar`"); err(function () { assert(foo == 'baz', "expected foo to equal `bar`"); }, "expected foo to equal `bar`"); err(function () { assert(foo == 'baz', function() { return "expected foo to equal `bar`"; }); }, "expected foo to equal `bar`"); }); describe("fail", function() { it('should accept a message as the 3rd argument', function () { err(function() { assert.fail(0, 1, 'this has failed'); }, /this has failed/); }); it('should accept a message as the only argument', function () { err(function() { assert.fail('this has failed'); }, /this has failed/); }); it('should produce a default message when called without any arguments', function () { err(function() { assert.fail(); }, /assert\.fail()/); }); }); it('isTrue', function () { assert.isTrue(true); err(function() { assert.isTrue(false, 'blah'); }, "blah: expected false to be true"); err(function() { assert.isTrue(1); }, "expected 1 to be true"); err(function() { assert.isTrue('test'); }, "expected 'test' to be true"); }); it('isNotTrue', function () { assert.isNotTrue(false); err(function() { assert.isNotTrue(true, 'blah'); }, "blah: expected true to not equal true"); }); it('isOk / ok', function () { ['isOk', 'ok'].forEach(function (isOk) { assert[isOk](true); assert[isOk](1); assert[isOk]('test'); err(function () { assert[isOk](false, 'blah'); }, "blah: expected false to be truthy"); err(function () { assert[isOk](0); }, "expected +0 to be truthy"); err(function () { assert[isOk](''); }, "expected '' to be truthy"); }); }); it('isNotOk, notOk', function () { ['isNotOk', 'notOk'].forEach(function (isNotOk) { assert[isNotOk](false); assert[isNotOk](0); assert[isNotOk](''); err(function () { assert[isNotOk](true, 'blah'); }, "blah: expected true to be falsy"); err(function () { assert[isNotOk](1); }, "expected 1 to be falsy"); err(function () { assert[isNotOk]('test'); }, "expected 'test' to be falsy"); }); }); it('isFalse', function () { assert.isFalse(false); err(function() { assert.isFalse(true, 'blah'); }, "blah: expected true to be false"); err(function() { assert.isFalse(0); }, "expected +0 to be false"); }); it('isNotFalse', function () { assert.isNotFalse(true); err(function() { assert.isNotFalse(false, 'blah'); }, "blah: expected false to not equal false"); }); it('equal', function () { var foo; assert.equal(foo, undefined); var sym = Symbol(); assert.equal(sym, sym); err(function () { assert.equal(1, 2, 'blah'); }, "blah: expected 1 to equal 2"); }); it('typeof', function () { assert.typeOf('test', 'string'); assert.typeOf(true, 'boolean'); assert.typeOf(5, 'number'); assert.typeOf(() => {}, 'function'); assert.typeOf(function() {}, 'function'); assert.typeOf(async function() {}, 'asyncfunction'); assert.typeOf(function*() {}, 'generatorfunction'); assert.typeOf(async function*() {}, 'asyncgeneratorfunction'); assert.typeOf(Symbol(), 'symbol'); err(function () { assert.typeOf(5, 'function', 'blah'); }, "blah: expected 5 to be a function"); err(function () { assert.typeOf(function() {}, 'asyncfunction', 'blah'); }, "blah: expected [Function] to be an asyncfunction"); assert.typeOf(5n, 'bigint'); assert.typeOf(() => {}, 'function'); assert.typeOf(function() {}, 'function'); assert.typeOf(async function() {}, 'asyncfunction'); assert.typeOf(function*() {}, 'generatorfunction'); assert.typeOf(async function*() {}, 'asyncgeneratorfunction'); assert.typeOf(Symbol(), 'symbol'); err(function () { assert.typeOf(5, 'function', 'blah'); }, "blah: expected 5 to be a function"); err(function () { assert.typeOf(function() {}, 'asyncfunction', 'blah'); }, "blah: expected [Function] to be an asyncfunction"); err(function () { assert.typeOf(5, 'string', 'blah'); }, "blah: expected 5 to be a string"); }); it('notTypeOf', function () { assert.notTypeOf('test', 'number'); assert.notTypeOf(() => {}, 'string'); assert.notTypeOf(function() {}, 'string'); assert.notTypeOf(async function() {}, 'string'); assert.notTypeOf(function*() {}, 'string'); assert.notTypeOf(async function*() {}, 'string'); err(function () { assert.notTypeOf(5, 'number', 'blah'); }, "blah: expected 5 not to be a number"); err(function () { assert.notTypeOf(() => {}, 'function', 'blah'); }, "blah: expected [Function] not to be a function"); }); it('instanceOf', function() { function Foo(){} assert.instanceOf(new Foo(), Foo); // Normally, `instanceof` requires that the constructor be a function or an // object with a callable `@@hasInstance`. But in some older browsers such // as IE11, `instanceof` also accepts DOM-related interfaces such as // `HTMLElement`, despite being non-callable objects in those browsers. // See: https://github.com/chaijs/chai/issues/1000. if (typeof document !== 'undefined' && typeof document.createElement !== 'undefined' && typeof HTMLElement !== 'undefined') { assert.instanceOf(document.createElement('div'), HTMLElement); } err(function(){ assert.instanceOf(new Foo(), 1, 'blah'); }, "blah: The instanceof assertion needs a constructor but Number was given."); err(function(){ assert.instanceOf(new Foo(), 'batman'); }, "The instanceof assertion needs a constructor but String was given."); err(function(){ assert.instanceOf(new Foo(), {}); }, "The instanceof assertion needs a constructor but Object was given."); err(function(){ assert.instanceOf(new Foo(), true); }, "The instanceof assertion needs a constructor but Boolean was given."); err(function(){ assert.instanceOf(new Foo(), null); }, "The instanceof assertion needs a constructor but null was given."); err(function(){ assert.instanceOf(new Foo(), undefined); }, "The instanceof assertion needs a constructor but undefined was given."); err(function(){ function Thing(){}; var t = new Thing(); Thing.prototype = 1337; assert.instanceOf(t, Thing); }, 'The instanceof assertion needs a constructor but Function was given.', true); err(function(){ assert.instanceOf(new Foo(), Symbol()); }, "The instanceof assertion needs a constructor but Symbol was given."); err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 3; }; assert.instanceOf(fakeInstanceB, FakeConstructor); }, 'expected 4 to be an instance of an unnamed constructor') err(function () { assert.instanceOf(5, Foo, 'blah'); }, "blah: expected 5 to be an instance of Foo"); function CrashyObject() {}; CrashyObject.prototype.inspect = function () { throw new Error("Arg's inspect() called even though the test passed"); }; assert.instanceOf(new CrashyObject(), CrashyObject); }); it('notInstanceOf', function () { function Foo(){} assert.notInstanceOf(new Foo(), String); err(function(){ assert.notInstanceOf(new Foo(), 1, 'blah'); }, "blah: The instanceof assertion needs a constructor but Number was given."); err(function(){ assert.notInstanceOf(new Foo(), 'batman'); }, "The instanceof assertion needs a constructor but String was given."); err(function(){ assert.notInstanceOf(new Foo(), {}); }, "The instanceof assertion needs a constructor but Object was given."); err(function(){ assert.notInstanceOf(new Foo(), true); }, "The instanceof assertion needs a constructor but Boolean was given."); err(function(){ assert.notInstanceOf(new Foo(), null); }, "The instanceof assertion needs a constructor but null was given."); err(function(){ assert.notInstanceOf(new Foo(), undefined); }, "The instanceof assertion needs a constructor but undefined was given."); err(function(){ assert.notInstanceOf(new Foo(), Symbol()); }, "The instanceof assertion needs a constructor but Symbol was given."); err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 4; }; assert.notInstanceOf(fakeInstanceB, FakeConstructor); }, 'expected 4 to not be an instance of an unnamed constructor'); err(function () { assert.notInstanceOf(new Foo(), Foo, 'blah'); }, "blah: expected Foo{} to not be an instance of Foo"); }); it('isObject', function () { function Foo(){} assert.isObject({}); assert.isObject(new Foo()); err(function() { assert.isObject(true, 'blah'); }, "blah: expected true to be an object"); err(function() { assert.isObject(Foo); }, "expected [Function Foo] to be an object"); err(function() { assert.isObject('foo'); }, "expected 'foo' to be an object"); }); it('isNotObject', function () { function Foo(){} assert.isNotObject(5); err(function() { assert.isNotObject({}, 'blah'); }, "blah: expected {} not to be an object"); }); it('notEqual', function() { assert.notEqual(3, 4); var sym1 = Symbol() , sym2 = Symbol(); assert.notEqual(sym1, sym2); err(function () { assert.notEqual(5, 5, 'blah'); }, "blah: expected 5 to not equal 5"); }); it('strictEqual', function() { assert.strictEqual('foo', 'foo'); var sym = Symbol(); assert.strictEqual(sym, sym); err(function () { assert.strictEqual('5', 5, 'blah'); }, "blah: expected \'5\' to equal 5"); }); it('notStrictEqual', function() { assert.notStrictEqual(5, '5'); var sym1 = Symbol() , sym2 = Symbol(); assert.notStrictEqual(sym1, sym2); err(function () { assert.notStrictEqual(5, 5, 'blah'); }, "blah: expected 5 to not equal 5"); }); it('deepEqual', function() { assert.deepEqual({tea: 'chai'}, {tea: 'chai'}); assert.deepStrictEqual({tea: 'chai'}, {tea: 'chai'}); // Alias of deepEqual assert.deepEqual([NaN], [NaN]); assert.deepEqual({tea: NaN}, {tea: NaN}); err(function () { assert.deepEqual({tea: 'chai'}, {tea: 'black'}, 'blah'); }, "blah: expected { tea: 'chai' } to deeply equal { tea: 'black' }"); var obja = Object.create({ tea: 'chai' }) , objb = Object.create({ tea: 'chai' }); assert.deepEqual(obja, objb); var obj1 = Object.create({tea: 'chai'}) , obj2 = Object.create({tea: 'black'}); err(function () { assert.deepEqual(obj1, obj2); }, "expected {} to deeply equal {}"); }); it('deepEqual (ordering)', function() { var a = { a: 'b', c: 'd' } , b = { c: 'd', a: 'b' }; assert.deepEqual(a, b); }); it('deepEqual /regexp/', function() { assert.deepEqual(/a/, /a/); assert.notDeepEqual(/a/, /b/); assert.notDeepEqual(/a/, {}); assert.deepEqual(/a/g, /a/g); assert.notDeepEqual(/a/g, /b/g); assert.deepEqual(/a/i, /a/i); assert.notDeepEqual(/a/i, /b/i); assert.deepEqual(/a/m, /a/m); assert.notDeepEqual(/a/m, /b/m); }); it('deepEqual (Date)', function() { var a = new Date(1, 2, 3) , b = new Date(4, 5, 6); assert.deepEqual(a, a); assert.notDeepEqual(a, b); assert.notDeepEqual(a, {}); }); it('deepEqual (circular)', function() { var circularObject = {} , secondCircularObject = {}; circularObject.field = circularObject; secondCircularObject.field = secondCircularObject; assert.deepEqual(circularObject, secondCircularObject); err(function() { secondCircularObject.field2 = secondCircularObject; assert.deepEqual(circularObject, secondCircularObject); }, "expected { field: [Circular] } to deeply equal { field: [Circular], …(1) }"); }); it('notDeepEqual', function() { assert.notDeepEqual({tea: 'jasmine'}, {tea: 'chai'}); err(function () { assert.notDeepEqual({tea: 'chai'}, {tea: 'chai'}, 'blah'); }, "blah: expected { tea: \'chai\' } to not deeply equal { tea: \'chai\' }"); }); it('notDeepEqual (circular)', function() { var circularObject = {} , secondCircularObject = { tea: 'jasmine' }; circularObject.field = circularObject; secondCircularObject.field = secondCircularObject; assert.notDeepEqual(circularObject, secondCircularObject); err(function() { delete secondCircularObject.tea; assert.notDeepEqual(circularObject, secondCircularObject); }, "expected { field: [Circular] } to not deeply equal { field: [Circular] }"); }); it('isNull', function() { assert.isNull(null); err(function () { assert.isNull(undefined, 'blah'); }, "blah: expected undefined to equal null"); }); it('isNotNull', function() { assert.isNotNull(undefined); err(function () { assert.isNotNull(null, 'blah'); }, "blah: expected null to not equal null"); }); it('isNaN', function() { assert.isNaN(NaN); err(function (){ assert.isNaN(Infinity, 'blah'); }, "blah: expected Infinity to be NaN"); err(function (){ assert.isNaN(undefined); }, "expected undefined to be NaN"); err(function (){ assert.isNaN({}); }, "expected {} to be NaN"); err(function (){ assert.isNaN(4); }, "expected 4 to be NaN"); }); it('isNotNaN', function() { assert.isNotNaN(4); assert.isNotNaN(Infinity); assert.isNotNaN(undefined); assert.isNotNaN({}); err(function (){ assert.isNotNaN(NaN, 'blah'); }, "blah: expected NaN not to be NaN"); }); it('exists', function() { var meeber = 'awesome'; var iDoNotExist; assert.exists(meeber); assert.exists(0); assert.exists(false); assert.exists(''); err(function (){ assert.exists(iDoNotExist, 'blah'); }, "blah: expected undefined to exist"); }); it('notExists', function() { var meeber = 'awesome'; var iDoNotExist; assert.notExists(iDoNotExist); err(function (){ assert.notExists(meeber, 'blah'); }, "blah: expected 'awesome' to not exist"); }); it('isUndefined', function() { assert.isUndefined(undefined); err(function () { assert.isUndefined(null, 'blah'); }, "blah: expected null to equal undefined"); }); it('isDefined', function() { assert.isDefined(null); err(function () { assert.isDefined(undefined, 'blah'); }, "blah: expected undefined to not equal undefined"); }); it('isCallable', function() { var func = function() {}; assert.isCallable(func); var func = async function() {}; assert.isCallable(func); var func = function* () {} assert.isCallable(func); var func = async function* () {} assert.isCallable(func); err(function () { assert.isCallable({}, 'blah'); }, "blah: expected {} to be a callable function"); }); it('isNotCallable', function() { assert.isNotCallable(false); assert.isNotCallable(10); assert.isNotCallable('string'); err(function () { assert.isNotCallable(function() {}, 'blah'); }, "blah: expected [Function] not to be a callable function"); }); it('isFunction', function() { var func = function() {}; assert.isFunction(func); err(function () { assert.isFunction({}, 'blah'); }, "blah: expected {} to be a callable function"); }); it('isNotFunction', function () { assert.isNotFunction(5); err(function () { assert.isNotFunction(function () {}, 'blah'); }, "blah: expected [Function] not to be a callable function"); }); it('isArray', function() { assert.isArray([]); assert.isArray(new Array()); err(function () { assert.isArray({}, 'blah'); }, "blah: expected {} to be an array"); }); it('isNotArray', function () { assert.isNotArray(3); err(function () { assert.isNotArray([], 'blah'); }, "blah: expected [] not to be an array"); err(function () { assert.isNotArray(new Array()); }, "expected [] not to be an array"); }); it('isString', function() { assert.isString('Foo'); assert.isString(new String('foo')); err(function () { assert.isString(1, 'blah'); }, "blah: expected 1 to be a string"); }); it('isNotString', function () { assert.isNotString(3); assert.isNotString([ 'hello' ]); err(function () { assert.isNotString('hello', 'blah'); }, "blah: expected 'hello' not to be a string"); }); it('isNumber', function() { assert.isNumber(1); assert.isNumber(Number('3')); err(function () { assert.isNumber('1', 'blah'); }, "blah: expected \'1\' to be a number"); }); it('isNotNumber', function () { assert.isNotNumber('hello'); assert.isNotNumber([ 5 ]); err(function () { assert.isNotNumber(4, 'blah'); }, "blah: expected 4 not to be a number"); }); it('isNumeric', function() { assert.isNumeric(1); assert.isNumeric(Number('3')); assert.isNumeric(6n); assert.isNumeric(BigInt(9)); err(function () { assert.isNumeric('1', 'blah'); }, "blah: expected \'1\' to be numeric"); }); it('isNotNumeric', function () { assert.isNotNumeric('hello'); assert.isNotNumeric([ 5 ]); err(function () { assert.isNotNumeric(4, 'blah'); }, "blah: expected 4 to not be numeric"); }); it('isFinite', function() { assert.isFinite(4); assert.isFinite(-10); err(function(){ assert.isFinite(NaN, 'blah'); }, "blah: expected NaN to be a finite number"); err(function(){ assert.isFinite(Infinity); }, "expected Infinity to be a finite number"); err(function(){ assert.isFinite('foo'); }, "expected \'foo\' to be a finite number"); err(function(){ assert.isFinite([]); }, "expected [] to be a finite number"); err(function(){ assert.isFinite({}); }, "expected {} to be a finite number"); }) it('isBoolean', function() { assert.isBoolean(true); assert.isBoolean(false); err(function () { assert.isBoolean('1', 'blah'); }, "blah: expected \'1\' to be a boolean"); }); it('isNotBoolean', function () { assert.isNotBoolean('true'); err(function () { assert.isNotBoolean(true, 'blah'); }, "blah: expected true not to be a boolean"); err(function () { assert.isNotBoolean(false); }, "expected false not to be a boolean"); }); it('include', function() { assert.include('foobar', 'bar'); assert.include('', ''); assert.include([ 1, 2, 3], 3); // .include should work with Error objects and objects with a custom // `@@toStringTag`. assert.include(new Error('foo'), {message: 'foo'}); var customObj = {a: 1}; customObj[Symbol.toStringTag] = 'foo'; assert.include(customObj, {a: 1}); var obj1 = {a: 1} , obj2 = {b: 2}; assert.include([obj1, obj2], obj1); assert.include({foo: obj1, bar: obj2}, {foo: obj1}); assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); var map = new Map(); var val = [{a: 1}]; map.set('a', val); map.set('b', 2); map.set('c', -0); map.set('d', NaN); assert.include(map, val); assert.include(map, 2); assert.include(map, 0); assert.include(map, NaN); var val = [{a: 1}]; var set = new Set(); set.add(val); set.add(2); set.add(-0); set.add(NaN); assert.include(set, val); assert.include(set, 2); assert.include(set, 0); assert.include(set, NaN); var ws = new WeakSet(); var val = [{a: 1}]; ws.add(val); assert.include(ws, val); var sym1 = Symbol() , sym2 = Symbol(); assert.include([sym1, sym2], sym1); err(function () { assert.include('foobar', 'baz', 'blah'); }, "blah: expected \'foobar\' to include \'baz\'"); err(function () { assert.include([{a: 1}, {b: 2}], {a: 1}); }, "expected [ { a: 1 }, { b: 2 } ] to include { a: 1 }"); err(function () { assert.include({foo: {a: 1}, bar: {b: 2}}, {foo: {a: 1}}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to have property 'foo' of { a: 1 }, but got { a: 1 }"); err(function(){ assert.include(true, true, 'blah'); }, "blah: the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function () { assert.include(42, 'bar'); }, "the given combination of arguments (number and string) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a string" ); err(function(){ assert.include(null, 42); }, "the given combination of arguments (null and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function () { assert.include(undefined, 'bar'); }, "the given combination of arguments (undefined and string) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a string" ); }); it('notInclude', function () { assert.notInclude('foobar', 'baz'); assert.notInclude([ 1, 2, 3 ], 4); var obj1 = {a: 1} , obj2 = {b: 2}; assert.notInclude([obj1, obj2], {a: 1}); assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); var map = new Map(); var val = [{a: 1}]; map.set('a', val); map.set('b', 2); assert.notInclude(map, [{a: 1}]); assert.notInclude(map, 3); var set = new Set(); var val = [{a: 1}]; set.add(val); set.add(2); assert.include(set, val); assert.include(set, 2); assert.notInclude(set, [{a: 1}]); assert.notInclude(set, 3); var ws = new WeakSet(); var val = [{a: 1}]; ws.add(val); assert.notInclude(ws, [{a: 1}]); assert.notInclude(ws, {}); var sym1 = Symbol() , sym2 = Symbol() , sym3 = Symbol(); assert.notInclude([sym1, sym2], sym3); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; assert.notInclude([obj1, obj2], obj1, 'blah'); }, "blah: expected [ { a: 1 }, { b: 2 } ] to not include { a: 1 }"); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have property 'foo' of { a: 1 }"); err(function(){ assert.notInclude(true, true, 'blah'); }, "blah: the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function () { assert.notInclude(42, 'bar'); }, "the given combination of arguments (number and string) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a string" ); err(function(){ assert.notInclude(null, 42); }, "the given combination of arguments (null and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function () { assert.notInclude(undefined, 'bar'); }, "the given combination of arguments (undefined and string) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a string" ); err(function () { assert.notInclude('foobar', 'bar'); }, "expected \'foobar\' to not include \'bar\'"); }); it('deepInclude and notDeepInclude', function () { var obj1 = {a: 1} , obj2 = {b: 2}; assert.deepInclude([obj1, obj2], {a: 1}); assert.notDeepInclude([obj1, obj2], {a: 9}); assert.notDeepInclude([obj1, obj2], {z: 1}); assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {z: 1}}); assert.notDeepInclude({foo: obj1, bar: obj2}, {baz: {a: 1}}); assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); var map = new Map(); map.set(1, [{a: 1}]); assert.deepInclude(map, [{a: 1}]); var set = new Set(); set.add([{a: 1}]); assert.deepInclude(set, [{a: 1}]); err(function() { assert.deepInclude(new WeakSet(), {}, 'foo'); }, 'foo: unable to use .deep.include with WeakSet'); err(function () { assert.deepInclude([obj1, obj2], {a: 9}, 'blah'); }, "blah: expected [ { a: 1 }, { b: 2 } ] to deep include { a: 9 }"); err(function () { assert.notDeepInclude([obj1, obj2], {a: 1}); }, "expected [ { a: 1 }, { b: 2 } ] to not deep include { a: 1 }"); err(function () { assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to have deep property 'bar' of { b: 9 }, but got { b: 2 }"); err(function () { assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }"); }); it('nestedInclude and notNestedInclude', function() { assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'y'}); assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'}); assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.c': 'y'}); assert.notNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); assert.nestedInclude({'.a': {'[b]': 'x'}}, {'\\.a.\\[b\\]': 'x'}); assert.notNestedInclude({'.a': {'[b]': 'x'}}, {'\\.a.\\[b\\]': 'y'}); err(function () { assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'"); err(function () { assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'"); err(function () { assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.c': 'y'}); }, "expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.c'"); err(function () { assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'y'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'"); }); it('deepNestedInclude and notDeepNestedInclude', function() { assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}}); assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.c': {x: 1}}); assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); err(function () { assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }"); err(function () { assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }"); err(function () { assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.c': {x: 1}}); }, "expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.c'"); err(function () { assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to not have deep nested property 'a.b[0]' of { x: 1 }"); }); it('ownInclude and notOwnInclude', function() { assert.ownInclude({a: 1}, {a: 1}); assert.notOwnInclude({a: 1}, {a: 3}); assert.notOwnInclude({a: 1}, {'toString': Object.prototype.toString}); assert.notOwnInclude({a: {b: 2}}, {a: {b: 2}}); err(function () { assert.ownInclude({a: 1}, {a: 3}, 'blah'); }, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1"); err(function () { assert.ownInclude({a: 1}, {a: 3}, 'blah'); }, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1"); err(function () { assert.ownInclude({a: 1}, {'toString': Object.prototype.toString}); }, "expected { a: 1 } to have own property 'toString'"); err(function () { assert.notOwnInclude({a: 1}, {a: 1}, 'blah'); }, "blah: expected { a: 1 } to not have own property 'a' of 1"); }); it('deepOwnInclude and notDeepOwnInclude', function() { assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); assert.notDeepOwnInclude({a: {b: 2}}, {'toString': Object.prototype.toString}); err(function () { assert.deepOwnInclude({a: {b: 2}}, {a: {c: 3}}, 'blah'); }, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }"); err(function () { assert.deepOwnInclude({a: {b: 2}}, {a: {c: 3}}, 'blah'); }, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }"); err(function () { assert.deepOwnInclude({a: {b: 2}}, {'toString': Object.prototype.toString}); }, "expected { a: { b: 2 } } to have deep own property 'toString'"); err(function () { assert.notDeepOwnInclude({a: {b: 2}}, {a: {b: 2}}, 'blah'); }, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }"); }); it('keys(array|Object|arguments)', function(){ assert.hasAllKeys({ foo: 1 }, [ 'foo' ]); assert.hasAllKeys({ foo: 1, bar: 2 }, [ 'foo', 'bar' ]); assert.hasAllKeys({ foo: 1 }, { foo: 30 }); assert.hasAllKeys({ foo: 1, bar: 2 }, { 'foo': 6, 'bar': 7 }); assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, [ 'foo', 'bar' ]); assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, [ 'bar', 'foo' ]); assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, [ 'baz' ]); assert.containsAllKeys({ foo: 1, bar: 2 }, [ 'foo' ]); assert.containsAllKeys({ foo: 1, bar: 2 }, ['bar']); assert.containsAllKeys({ foo: 1, bar: 2 }, { 'foo': 6 }); assert.containsAllKeys({ foo: 1, bar: 2 }, { 'bar': 7 }); assert.containsAllKeys({ foo: 1, bar: 2 }, { 'foo': 6 }); assert.containsAllKeys({ foo: 1, bar: 2 }, { 'bar': 7, 'foo': 6 }); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, [ 'baz' ]); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, [ 'foo' ]); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, [ 'foo', 'baz' ]); assert.doesNotHaveAllKeys({ foo: 1, bar: 2, baz: 3 }, [ 'foo', 'bar', 'baz', 'fake' ]); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, [ 'baz', 'foo' ]); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, { 'baz': 8 }); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, { 'baz': 8, 'foo': 7 }); assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, { 'baz': 8, 'fake': 7 }); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'foo', 'baz' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'foo' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'bar', 'baz' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'bar', 'foo' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'foo', 'bar' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, [ 'baz', 'fake', 'foo' ]); assert.hasAnyKeys({ foo: 1, bar: 2 }, { 'foo': 6 }); assert.hasAnyKeys({ foo: 1, bar: 2 }, { 'baz': 6, 'foo': 12 }); assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, [ 'baz', 'abc', 'def' ]); assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, [ 'baz' ]); assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, { baz: 1, biz: 2, fake: 3 }); assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, { baz: 1 }); var enumProp1 = 'enumProp1' , enumProp2 = 'enumProp2' , nonEnumProp = 'nonEnumProp' , obj = {}; obj[enumProp1] = 'enumProp1'; obj[enumProp2] = 'enumProp2'; Object.defineProperty(obj, nonEnumProp, { enumerable: false, value: 'nonEnumProp' }); assert.hasAllKeys(obj, [enumProp1, enumProp2]); assert.doesNotHaveAllKeys(obj, [enumProp1, enumProp2, nonEnumProp]); var sym1 = Symbol('sym1') , sym2 = Symbol('sym2') , sym3 = Symbol('sym3') , str = 'str' , obj = {}; obj[sym1] = 'sym1'; obj[sym2] = 'sym2'; obj[str] = 'str'; Object.defineProperty(obj, sym3, { enumerable: false, value: 'sym3' }); assert.hasAllKeys(obj, [sym1, sym2, str]); assert.doesNotHaveAllKeys(obj, [sym1, sym2, sym3, str]); var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testMap = new Map(); testMap.set(aKey, 'aValue'); testMap.set(anotherKey, 'anotherValue'); assert.hasAnyKeys(testMap, [ aKey ]); assert.hasAnyKeys(testMap, [ 'thisDoesNotExist', 'thisToo', aKey ]); assert.hasAllKeys(testMap, [ aKey, anotherKey ]); assert.containsAllKeys(testMap, [ aKey ]); assert.doesNotHaveAllKeys(testMap, [ aKey, {iDoNot: 'exist'} ]); assert.doesNotHaveAnyKeys(testMap, [ {iDoNot: 'exist'} ]); assert.doesNotHaveAnyKeys(testMap, [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]); assert.doesNotHaveAllKeys(testMap, [ 'thisDoesNotExist', 'thisToo', anotherKey ]); assert.doesNotHaveAnyKeys(testMap, [ {iDoNot: 'exist'}, 'thisDoesNotExist' ]); assert.doesNotHaveAnyKeys(testMap, [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]); assert.doesNotHaveAllKeys(testMap, [ aKey, {iDoNot: 'exist'} ]); // Ensure the assertions above use strict equality assert.doesNotHaveAnyKeys(testMap, {thisIs: 'anExampleObject'}); assert.doesNotHaveAllKeys(testMap, [ {thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'} ]); err(function(){ assert.hasAnyKeys(testMap, [ {thisIs: 'anExampleObject'} ]); }); err(function(){ assert.hasAllKeys(testMap, [ {thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'} ]); }); err(function(){ assert.containsAllKeys(testMap, [ {thisIs: 'anExampleObject'} ]); }); // Tests for the deep variations of the keys assertion assert.hasAnyDeepKeys(testMap, {thisIs: 'anExampleObject'}); assert.hasAnyDeepKeys(testMap, [{thisIs: 'anExampleObject'}, {three: 'three'}]); assert.hasAnyDeepKeys(testMap, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.hasAllDeepKeys(testMap, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.containsAllDeepKeys(testMap, {thisIs: 'anExampleObject'}); assert.containsAllDeepKeys(testMap, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.doesNotHaveAnyDeepKeys(testMap, {thisDoesNot: 'exist'}); assert.doesNotHaveAnyDeepKeys(testMap, [{twenty: 'twenty'}, {fifty: 'fifty'}]); assert.doesNotHaveAllDeepKeys(testMap, {thisDoesNot: 'exist'}); assert.doesNotHaveAllDeepKeys(testMap, [{twenty: 'twenty'}, {thisIs: 'anExampleObject'}]); var weirdMapKey1 = Object.create(null) , weirdMapKey2 = {toString: NaN} , weirdMapKey3 = [] , weirdMap = new Map(); weirdMap.set(weirdMapKey1, 'val1'); weirdMap.set(weirdMapKey2, 'val2'); assert.hasAllKeys(weirdMap, [weirdMapKey1, weirdMapKey2]); assert.doesNotHaveAllKeys(weirdMap, [weirdMapKey1, weirdMapKey3]); var symMapKey1 = Symbol() , symMapKey2 = Symbol() , symMapKey3 = Symbol() , symMap = new Map(); symMap.set(symMapKey1, 'val1'); symMap.set(symMapKey2, 'val2'); assert.hasAllKeys(symMap, [symMapKey1, symMapKey2]); assert.hasAnyKeys(symMap, [symMapKey1, symMapKey3]); assert.containsAllKeys(symMap, [symMapKey2, symMapKey1]); assert.doesNotHaveAllKeys(symMap, [symMapKey1, symMapKey3]); assert.doesNotHaveAnyKeys(symMap, [symMapKey3]); var errMap = new Map(); errMap.set({1: 20}, 'number'); err(function(){ assert.hasAllKeys(errMap, [], 'blah'); }, "blah: keys required"); err(function(){ assert.containsAllKeys(errMap, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAllKeys(errMap, [], 'blah'); }, "blah: keys required"); err(function(){ assert.hasAnyKeys(errMap, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAnyKeys(errMap, [], 'blah'); }, "blah: keys required"); // Uncomment this after solving https://github.com/chaijs/chai/issues/662 // This should fail because of referential equality (this is a strict comparison) // err(function(){ // assert.containsAllKeys(new Map([[{foo: 1}, 'bar']]), { foo: 1 }); // }, 'expected [ [ { foo: 1 }, 'bar' ] ] to contain key { foo: 1 }'); // err(function(){ // assert.containsAllDeepKeys(new Map([[{foo: 1}, 'bar']]), { iDoNotExist: 0 }) // }, 'expected [ { foo: 1 } ] to deeply contain key { iDoNotExist: 0 }'); var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testSet = new Set(); testSet.add(aKey); testSet.add(anotherKey); assert.hasAnyKeys(testSet, [ aKey ]); assert.hasAnyKeys(testSet, [ 20, 1, aKey ]); assert.hasAllKeys(testSet, [ aKey, anotherKey ]); assert.containsAllKeys(testSet, [ aKey ]); assert.doesNotHaveAllKeys(testSet, [ aKey, {iDoNot: 'exist'} ]); assert.doesNotHaveAnyKeys(testSet, [ {iDoNot: 'exist'} ]); assert.doesNotHaveAnyKeys(testSet, [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]); assert.doesNotHaveAllKeys(testSet, [ 'thisDoesNotExist', 'thisToo', anotherKey ]); assert.doesNotHaveAnyKeys(testSet, [ {iDoNot: 'exist'}, 'thisDoesNotExist' ]); assert.doesNotHaveAnyKeys(testSet, [ 20, 1, {iDoNot: 'exist'} ]); assert.doesNotHaveAllKeys(testSet, [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]); // Ensure the assertions above use strict equality assert.doesNotHaveAnyKeys(testSet, {thisIs: 'anExampleObject'}); assert.doesNotHaveAllKeys(testSet, [ {thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'} ]); err(function(){ assert.hasAnyKeys(testSet, [ {thisIs: 'anExampleObject'} ]); }); err(function(){ assert.hasAllKeys(testSet, [ {thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'} ]); }); err(function(){ assert.containsAllKeys(testSet, [ {thisIs: 'anExampleObject'} ]); }); // Tests for the deep variations of the keys assertion assert.hasAnyDeepKeys(testSet, {thisIs: 'anExampleObject'}); assert.hasAnyDeepKeys(testSet, [{thisIs: 'anExampleObject'}, {three: 'three'}]); assert.hasAnyDeepKeys(testSet, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.hasAllDeepKeys(testSet, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.containsAllDeepKeys(testSet, {thisIs: 'anExampleObject'}); assert.containsAllDeepKeys(testSet, [{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); assert.doesNotHaveAnyDeepKeys(testSet, {twenty: 'twenty'}); assert.doesNotHaveAnyDeepKeys(testSet, [{twenty: 'twenty'}, {fifty: 'fifty'}]); assert.doesNotHaveAllDeepKeys(testSet, {twenty: 'twenty'}); assert.doesNotHaveAllDeepKeys(testSet, [{thisIs: 'anExampleObject'}, {fifty: 'fifty'}]); var weirdSetKey1 = Object.create(null) , weirdSetKey2 = {toString: NaN} , weirdSetKey3 = [] , weirdSet = new Set(); weirdSet.add(weirdSetKey1); weirdSet.add(weirdSetKey2); assert.hasAllKeys(weirdSet, [weirdSetKey1, weirdSetKey2]); assert.doesNotHaveAllKeys(weirdSet, [weirdSetKey1, weirdSetKey3]); var symSetKey1 = Symbol() , symSetKey2 = Symbol() , symSetKey3 = Symbol() , symSet = new Set(); symSet.add(symSetKey1); symSet.add(symSetKey2); assert.hasAllKeys(symSet, [symSetKey1, symSetKey2]); assert.hasAnyKeys(symSet, [symSetKey1, symSetKey3]); assert.containsAllKeys(symSet, [symSetKey2, symSetKey1]); assert.doesNotHaveAllKeys(symSet, [symSetKey1, symSetKey3]); assert.doesNotHaveAnyKeys(symSet, [symSetKey3]); var errSet = new Set(); errSet.add({1: 20}); errSet.add('number'); err(function(){ assert.hasAllKeys(errSet, [], 'blah'); }, "blah: keys required"); err(function(){ assert.containsAllKeys(errSet, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAllKeys(errSet, [], 'blah'); }, "blah: keys required"); err(function(){ assert.hasAnyKeys(errSet, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAnyKeys(errSet, [], 'blah'); }, "blah: keys required"); // Uncomment this after solving https://github.com/chaijs/chai/issues/662 // This should fail because of referential equality (this is a strict comparison) // err(function(){ // assert.containsAllKeys(new Set([{foo: 1}]), { foo: 1 }); // }, 'expected [ [ { foo: 1 }, 'bar' ] ] to contain key { foo: 1 }'); // err(function(){ // assert.containsAllDeepKeys(new Set([{foo: 1}]), { iDoNotExist: 0 }) // }, 'expected [ { foo: 1 } ] to deeply contain key { iDoNotExist: 0 }'); err(function(){ assert.hasAllKeys({ foo: 1 }, [], 'blah'); }, "blah: keys required"); err(function(){ assert.containsAllKeys({ foo: 1 }, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1 }, [], 'blah'); }, "blah: keys required"); err(function(){ assert.hasAnyKeys({ foo: 1 }, [], 'blah'); }, "blah: keys required"); err(function(){ assert.doesNotHaveAnyKeys({ foo: 1 }, [], 'blah'); }, "blah: keys required"); err(function(){ assert.hasAllKeys({ foo: 1 }, ['bar'], 'blah'); }, "blah: expected { foo: 1 } to have key 'bar'"); err(function(){ assert.hasAllKeys({ foo: 1 }, ['bar', 'baz']); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ assert.hasAllKeys({ foo: 1 }, ['foo', 'bar', 'baz']); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1 }, ['foo'], 'blah'); }, "blah: expected { foo: 1 } to not have key 'foo'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, ['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ assert.hasAllKeys({ foo: 1, bar: 2 }, ['foo']); }, "expected { foo: 1, bar: 2 } to have key 'foo'"); err(function(){ assert.containsAllKeys({ foo: 1 }, ['foo', 'bar'], 'blah'); }, "blah: expected { foo: 1 } to contain keys 'foo', and 'bar'"); err(function() { assert.hasAnyKeys({ foo: 1 }, ['baz'], 'blah'); }, "blah: expected { foo: 1 } to have key 'baz'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, ['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, ['foo', 'baz'], 'blah'); }, "blah: expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); // repeat previous tests with Object as arg. err(function(){ assert.hasAllKeys({ foo: 1 }, { 'bar': 1 }, 'blah'); }, "blah: expected { foo: 1 } to have key 'bar'"); err(function(){ assert.hasAllKeys({ foo: 1 }, { 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ assert.hasAllKeys({ foo: 1 }, { 'foo': 1, 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1 }, { 'foo': 1 }, 'blah'); }, "blah: expected { foo: 1 } to not have key 'foo'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1 }, { 'foo': 1 }); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, { 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function() { assert.hasAnyKeys({ foo: 1 }, 'baz', 'blah'); }, "blah: expected { foo: 1 } to have key 'baz'"); err(function(){ assert.doesNotHaveAllKeys({ foo: 1, bar: 2 }, { 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, { 'foo': 1, 'baz': 1}, 'blah'); }, "blah: expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); }); it('lengthOf', function() { assert.lengthOf([1,2,3], 3); assert.lengthOf('foobar', 6); err(function () { assert.lengthOf('foobar', 5, 'blah'); }, "blah: expected 'foobar' to have a length of 5 but got 6"); err(function () { assert.lengthOf(1, 5); }, "expected 1 to have property \'length\'"); assert.lengthOf(new Map(), 0); var map = new Map(); map.set('a', 1); map.set('b', 2); assert.lengthOf(map, 2); err(function(){ assert.lengthOf(map, 3, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2 } to have a size of 3 but got 2"); assert.lengthOf(new Set(), 0); var set = new Set(); set.add(1); set.add(2); assert.lengthOf(set, 2); err(function(){ assert.lengthOf(set, 3, 'blah'); }, "blah: expected Set{ 1, 2 } to have a size of 3 but got 2"); }); it('match', function () { assert.match('foobar', /^foo/); assert.notMatch('foobar', /^bar/); err(function () { assert.match('foobar', /^bar/i, 'blah'); }, "blah: expected 'foobar' to match /^bar/i"); err(function () { assert.notMatch('foobar', /^foo/i, 'blah'); }, "blah: expected 'foobar' not to match /^foo/i"); }); it('property', function () { var obj = { foo: { bar: 'baz' } }; var simpleObj = { foo: 'bar' }; var undefinedKeyObj = { foo: undefined }; var dummyObj = { a: '1' }; assert.property(obj, 'foo'); assert.property(obj, 'toString'); assert.propertyVal(obj, 'toString', Object.prototype.toString); assert.property(undefinedKeyObj, 'foo'); assert.propertyVal(undefinedKeyObj, 'foo', undefined); assert.nestedProperty(obj, 'foo.bar'); assert.notProperty(obj, 'baz'); assert.notProperty(obj, 'foo.bar'); assert.notPropertyVal(simpleObj, 'foo', 'flow'); assert.notPropertyVal(simpleObj, 'flow', 'bar'); assert.notPropertyVal(obj, 'foo', {bar: 'baz'}); assert.notNestedProperty(obj, 'foo.baz'); assert.nestedPropertyVal(obj, 'foo.bar', 'baz'); assert.notNestedPropertyVal(obj, 'foo.bar', 'flow'); assert.notNestedPropertyVal(obj, 'foo.flow', 'baz'); err(function () { assert.property(obj, 'baz', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to have property 'baz'"); err(function () { assert.nestedProperty(obj, 'foo.baz', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to have nested property 'foo.baz'"); err(function () { assert.notProperty(obj, 'foo', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to not have property 'foo'"); err(function () { assert.notNestedProperty(obj, 'foo.bar', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to not have nested property 'foo.bar'"); err(function () { assert.propertyVal(simpleObj, 'foo', 'ball', 'blah'); }, "blah: expected { foo: 'bar' } to have property 'foo' of 'ball', but got 'bar'"); err(function () { assert.propertyVal(simpleObj, 'foo', undefined); }, "expected { foo: 'bar' } to have property 'foo' of undefined, but got 'bar'"); err(function () { assert.nestedPropertyVal(obj, 'foo.bar', 'ball', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to have nested property 'foo.bar' of 'ball', but got 'baz'"); err(function () { assert.notPropertyVal(simpleObj, 'foo', 'bar', 'blah'); }, "blah: expected { foo: 'bar' } to not have property 'foo' of 'bar'"); err(function () { assert.notNestedPropertyVal(obj, 'foo.bar', 'baz', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to not have nested property 'foo.bar' of 'baz'"); err(function () { assert.property(null, 'a', 'blah'); }, "blah: Target cannot be null or undefined."); err(function () { assert.property(undefined, 'a', 'blah'); }, "blah: Target cannot be null or undefined."); err(function () { assert.property({a:1}, {'a':'1'}, 'blah'); }, 'blah: the argument to property must be a string, number, or symbol'); err(function () { assert.propertyVal(dummyObj, 'a', '2', 'blah'); }, "blah: expected { a: '1' } to have property 'a' of '2', but got '1'"); err(function () { assert.nestedProperty({a:1}, {'a':'1'}, 'blah'); }, 'blah: the argument to property must be a string when using nested syntax'); }); it('deepPropertyVal', function () { var obj = {a: {b: 1}}; assert.deepPropertyVal(obj, 'a', {b: 1}); assert.notDeepPropertyVal(obj, 'a', {b: 7}); assert.notDeepPropertyVal(obj, 'a', {z: 1}); assert.notDeepPropertyVal(obj, 'z', {b: 1}); err(function () { assert.deepPropertyVal(obj, 'a', {b: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'a' of { b: 7 }, but got { b: 1 }"); err(function () { assert.deepPropertyVal(obj, 'z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'z'"); err(function () { assert.notDeepPropertyVal(obj, 'a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep property 'a' of { b: 1 }"); }); it('ownProperty', function() { var coffeeObj = { coffee: 'is good' }; // This has length = 17 var teaObj = 'but tea is better'; assert.ownProperty(coffeeObj, 'coffee'); assert.ownProperty(teaObj, 'length'); assert.ownPropertyVal(coffeeObj, 'coffee', 'is good'); assert.ownPropertyVal(teaObj, 'length', 17); assert.notOwnProperty(coffeeObj, 'length'); assert.notOwnProperty(coffeeObj, 'toString'); assert.notOwnProperty(teaObj, 'calories'); assert.notOwnPropertyVal(coffeeObj, 'coffee', 'is bad'); assert.notOwnPropertyVal(teaObj, 'length', 1); assert.notOwnPropertyVal(coffeeObj, 'toString', Object.prototype.toString); assert.notOwnPropertyVal({a: {b: 1}}, 'a', {b: 1}); err(function () { assert.ownProperty(coffeeObj, 'calories', 'blah'); }, "blah: expected { coffee: 'is good' } to have own property 'calories'"); err(function () { assert.notOwnProperty(coffeeObj, 'coffee', 'blah'); }, "blah: expected { coffee: 'is good' } to not have own property 'coffee'"); err(function () { assert.ownPropertyVal(teaObj, 'length', 1, 'blah'); }, "blah: expected 'but tea is better' to have own property 'length' of 1, but got 17"); err(function () { assert.notOwnPropertyVal(teaObj, 'length', 17, 'blah'); }, "blah: expected 'but tea is better' to not have own property 'length' of 17"); err(function () { assert.ownPropertyVal(teaObj, 'calories', 17); }, "expected 'but tea is better' to have own property 'calories'"); err(function () { assert.ownPropertyVal(teaObj, 'calories', 17); }, "expected 'but tea is better' to have own property 'calories'"); }); it('deepOwnPropertyVal', function () { var obj = {a: {b: 1}}; assert.deepOwnPropertyVal(obj, 'a', {b: 1}); assert.notDeepOwnPropertyVal(obj, 'a', {z: 1}); assert.notDeepOwnPropertyVal(obj, 'a', {b: 7}); assert.notDeepOwnPropertyVal(obj, 'toString', Object.prototype.toString); err(function () { assert.deepOwnPropertyVal(obj, 'a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { assert.deepOwnPropertyVal(obj, 'z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { assert.notDeepOwnPropertyVal(obj, 'a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); }); it('deepNestedPropertyVal', function () { var obj = {a: {b: {c: 1}}}; assert.deepNestedPropertyVal(obj, 'a.b', {c: 1}); assert.notDeepNestedPropertyVal(obj, 'a.b', {c: 7}); assert.notDeepNestedPropertyVal(obj, 'a.b', {z: 1}); assert.notDeepNestedPropertyVal(obj, 'a.z', {c: 1}); err(function () { assert.deepNestedPropertyVal(obj, 'a.b', {c: 7}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.b' of { c: 7 }, but got { c: 1 }"); err(function () { assert.deepNestedPropertyVal(obj, 'a.z', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.z'"); err(function () { assert.notDeepNestedPropertyVal(obj, 'a.b', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to not have deep nested property 'a.b' of { c: 1 }"); }); it('throws / throw / Throw', function() { class CustomError extends Error {} ['throws', 'throw', 'Throw'].forEach(function (throws) { assert[throws](function() { throw new Error('foo'); }); assert[throws](function() { throw new Error(''); }, ''); assert[throws](function() { throw new Error('bar'); }, 'bar'); assert[throws](function() { throw new Error('bar'); }, /bar/); assert[throws](function() { throw new Error('bar'); }, Error); assert[throws](function() { throw new Error('bar'); }, Error, 'bar'); assert[throws](function() { throw new Error(''); }, Error, ''); assert[throws](function() { throw new Error('foo') }, ''); assert[throws](function() { throw ''; }, ''); assert[throws](function() { throw ''; }, /^$/); assert[throws](function() { throw new Error(''); }, /^$/); assert[throws](function() { throw undefined; }); assert[throws](function() { throw new CustomError('foo'); }); assert[throws](function() { throw (() => {}); }); var thrownErr = assert[throws](function() { throw new Error('foo'); }); assert(thrownErr instanceof Error, 'assert.' + throws + ' returns error'); assert(thrownErr.message === 'foo', 'assert.' + throws + ' returns error message'); err(function () { assert[throws](function() { throw new Error('foo') }, TypeError); }, "expected [Function] to throw 'TypeError' but 'Error: foo' was thrown") err(function () { assert[throws](function() { throw new Error('foo') }, 'bar'); }, "expected [Function] to throw error including 'bar' but got 'foo'") err(function () { assert[throws](function() { throw new Error('foo') }, Error, 'bar', 'blah'); }, "blah: expected [Function] to throw error including 'bar' but got 'foo'") err(function () { assert[throws](function() { throw new Error('foo') }, TypeError, 'bar', 'blah'); }, "blah: expected [Function] to throw 'TypeError' but 'Error: foo' was thrown") err(function () { assert[throws](function() {}); }, "expected [Function] to throw an error"); err(function () { assert[throws](function() { throw new Error('') }, 'bar'); }, "expected [Function] to throw error including 'bar' but got ''"); err(function () { assert[throws](function() { throw new Error('') }, /bar/); }, "expected [Function] to throw error matching /bar/ but got ''"); err(function () { assert[throws]({}); }, "expected {} to be a function"); err(function () { assert[throws]({}, Error, 'testing', 'blah'); }, "blah: expected {} to be a function"); }); }); it('doesNotThrow', function() { function CustomError(message) { this.name = 'CustomError'; this.message = message; } CustomError.prototype = Object.create(Error.prototype); assert.doesNotThrow(function() { }); assert.doesNotThrow(function() { }, 'foo'); assert.doesNotThrow(function() { }, ''); assert.doesNotThrow(function() { throw new Error('This is a message'); }, TypeError); assert.doesNotThrow(function() { throw new Error('This is a message'); }, 'Another message'); assert.doesNotThrow(function() { throw new Error('This is a message'); }, /Another message/); assert.doesNotThrow(function() { throw new Error('This is a message'); }, Error, 'Another message'); assert.doesNotThrow(function() { throw new Error('This is a message'); }, Error, /Another message/); assert.doesNotThrow(function() { throw new Error('This is a message'); }, TypeError, 'Another message'); assert.doesNotThrow(function() { throw new Error('This is a message'); }, TypeError, /Another message/); err(function () { assert.doesNotThrow(function() { throw new Error('foo'); }); }, "expected [Function] to not throw an error but 'Error: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new CustomError('foo'); }); }, "expected [Function] to not throw an error but 'CustomError: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new Error('foo'); }, Error); }, "expected [Function] to not throw 'Error' but 'Error: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new CustomError('foo'); }, CustomError); }, "expected [Function] to not throw 'CustomError' but 'CustomError: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new Error('foo'); }, 'foo'); }, "expected [Function] to throw error not including 'foo'"); err(function () { assert.doesNotThrow(function() { throw new Error('foo'); }, /foo/); }, "expected [Function] to throw error not matching /foo/"); err(function () { assert.doesNotThrow(function() { throw new Error('foo'); }, Error, 'foo', 'blah'); }, "blah: expected [Function] to not throw 'Error' but 'Error: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new CustomError('foo'); }, CustomError, 'foo', 'blah'); }, "blah: expected [Function] to not throw 'CustomError' but 'CustomError: foo' was thrown"); err(function () { assert.doesNotThrow(function() { throw new Error(''); }, ''); }, "expected [Function] to throw error not including ''"); err(function () { assert.doesNotThrow(function() { throw new Error(''); }, Error, ''); }, "expected [Function] to not throw 'Error' but 'Error' was thrown"); err(function () { assert.doesNotThrow({}); }, "expected {} to be a function"); err(function () { assert.doesNotThrow({}, Error, 'testing', 'blah'); }, "blah: expected {} to be a function"); }); it('ifError', function() { assert.ifError(false); assert.ifError(null); assert.ifError(undefined); err(function () { var err = new Error('This is an error message'); assert.ifError(err); }, 'This is an error message'); }); it('operator', function() { // For testing undefined and null with == and === var w; assert.operator(1, '<', 2); assert.operator(2, '>', 1); assert.operator(1, '==', 1); assert.operator(1, '<=', 1); assert.operator(1, '>=', 1); assert.operator(1, '!=', 2); assert.operator(1, '!==', 2); assert.operator(1, '!==', '1'); assert.operator(w, '==', undefined); assert.operator(w, '===', undefined); assert.operator(w, '==', null); err(function () { assert.operator(1, '=', 2, 'blah'); }, 'blah: Invalid operator "="'); err(function () { assert.operator(2, '<', 1, 'blah'); }, "blah: expected 2 to be < 1"); err(function () { assert.operator(1, '>', 2); }, "expected 1 to be > 2"); err(function () { assert.operator(1, '==', 2); }, "expected 1 to be == 2"); err(function () { assert.operator(1, '===', '1'); }, "expected 1 to be === \'1\'"); err(function () { assert.operator(2, '<=', 1); }, "expected 2 to be <= 1"); err(function () { assert.operator(1, '>=', 2); }, "expected 1 to be >= 2"); err(function () { assert.operator(1, '!=', 1); }, "expected 1 to be != 1"); err(function () { assert.operator(1, '!==', 1); }, "expected 1 to be !== 1"); err(function () { assert.operator(w, '===', null); }, "expected undefined to be === null"); }); it('closeTo', function(){ assert.closeTo(1.5, 1.0, 0.5); assert.closeTo(10, 20, 20); assert.closeTo(-10, 20, 30); assert.closeTo(10, 10, 0); assert.closeTo(1682.6, 1682.7, 0.1); assert.closeTo(1n, 2n, 1n); err(function(){ assert.closeTo(2, 1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function(){ assert.closeTo(-10, 20, 29); }, "expected -10 to be close to 20 +/- 29"); err(function() { assert.closeTo([1.5], 1.0, 0.5, 'blah'); }, "blah: expected [ 1.5 ] to be numeric"); err(function() { assert.closeTo(1.5, "1.0", 0.5, 'blah'); }, "blah: expected '1.0' to be numeric"); err(function() { assert.closeTo(1.5, 1.0, true, 'blah'); }, "blah: expected true to be numeric"); err(function() { assert.closeTo(1.5, 1.0, undefined, 'blah'); }, "blah: A `delta` value is required for `closeTo`"); err(function() { assert.closeTo(1.5, undefined, 0.5); }, "A `expected` value is required for `closeTo`"); }); it('approximately', function(){ assert.approximately(1.5, 1.0, 0.5); assert.approximately(10, 20, 20); assert.approximately(-10, 20, 30); assert.approximately(10, 10, 0); assert.approximately(1682.6, 1682.7, 0.1); assert.approximately(1n, 2n, 1n); err(function(){ assert.approximately(2, 1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function(){ assert.approximately(-10, 20, 29); }, "expected -10 to be close to 20 +/- 29"); err(function() { assert.approximately([1.5], 1.0, 0.5); }, "expected [ 1.5 ] to be numeric"); err(function() { assert.approximately(1.5, "1.0", 0.5, 'blah'); }, "blah: expected '1.0' to be numeric"); err(function() { assert.approximately(1.5, 1.0, true, 'blah'); }, "blah: expected true to be numeric"); err(function() { assert.approximately(1.5, 1.0, undefined, 'blah'); }, "blah: A `delta` value is required for `closeTo`"); }); it('sameMembers', function() { assert.sameMembers([], []); assert.sameMembers([1, 2, 3], [3, 2, 1]); assert.sameMembers([4, 2], [4, 2]); assert.sameMembers([4, 2, 2], [4, 2, 2]); assert.sameMembers(new Set([1,2,3]), new Set([3,2,1])); err(function() { assert.sameMembers([], [1, 2], 'blah'); }, 'blah: expected [] to have the same members as [ 1, 2 ]'); err(function() { assert.sameMembers([1, 54], [6, 1, 54]); }, 'expected [ 1, 54 ] to have the same members as [ 6, 1, 54 ]'); err(function () { assert.sameMembers({}, [], 'blah'); }, 'blah: expected {} to be an iterable'); err(function () { assert.sameMembers([], {}, 'blah'); }, 'blah: expected {} to be an iterable'); }); it('notSameMembers', function() { assert.notSameMembers([1, 2, 3], [2, 1, 5]); assert.notSameMembers([1, 2, 3], [1, 2, 3, 3]); assert.notSameMembers([1, 2], [1, 2, 2]); assert.notSameMembers([1, 2, 2], [1, 2]); assert.notSameMembers([1, 2, 2], [1, 2, 3]); assert.notSameMembers([1, 2, 3], [1, 2, 2]); assert.notSameMembers([{a: 1}], [{a: 1}]); err(function() { assert.notSameMembers([1, 2, 3], [2, 1, 3], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to not have the same members as [ 2, 1, 3 ]'); }); it('sameDeepMembers', function() { assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members'); assert.sameDeepMembers([ {b: 3}, {a: 2}, 5, "hello" ], [ "hello", 5, {b: 3}, {a: 2} ], 'same deep members'); assert.sameDeepMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}, {b: 2}]); err(function() { assert.sameDeepMembers([ {b: 3} ], [ {c: 3} ], 'blah') }, 'blah: expected [ { b: 3 } ] to have the same members as [ { c: 3 } ]'); err(function() { assert.sameDeepMembers([ {b: 3} ], [ {b: 5} ]) }, 'expected [ { b: 3 } ] to have the same members as [ { b: 5 } ]'); }); it('notSameDeepMembers', function() { assert.notSameDeepMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}, {f: 5}]); assert.notSameDeepMembers([{a: 1}, {b: 2}], [{a: 1}, {b: 2}, {b: 2}]); assert.notSameDeepMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}]); assert.notSameDeepMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}, {c: 3}]); assert.notSameDeepMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {b: 2}]); err(function() { assert.notSameDeepMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}, {c: 3}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not have the same members as [ { b: 2 }, { a: 1 }, { c: 3 } ]'); }); it('sameOrderedMembers', function() { assert.sameOrderedMembers([1, 2, 3], [1, 2, 3]); assert.sameOrderedMembers([1, 2, 2], [1, 2, 2]); err(function() { assert.sameOrderedMembers([1, 2, 3], [2, 1, 3], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to have the same ordered members as [ 2, 1, 3 ]'); }); it('notSameOrderedMembers', function() { assert.notSameOrderedMembers([1, 2, 3], [2, 1, 3]); assert.notSameOrderedMembers([1, 2, 3], [1, 2]); assert.notSameOrderedMembers([1, 2], [1, 2, 2]); assert.notSameOrderedMembers([1, 2, 2], [1, 2]); assert.notSameOrderedMembers([1, 2, 2], [1, 2, 3]); assert.notSameOrderedMembers([1, 2, 3], [1, 2, 2]); err(function() { assert.notSameOrderedMembers([1, 2, 3], [1, 2, 3], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to not have the same ordered members as [ 1, 2, 3 ]'); }); it('sameDeepOrderedMembers', function() { assert.sameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {c: 3}]); assert.sameDeepOrderedMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}, {b: 2}]); err(function() { assert.sameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}, {c: 3}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to have the same ordered members as [ { b: 2 }, { a: 1 }, { c: 3 } ]'); }); it('notSameDeepOrderedMembers', function() { assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}, {c: 3}]); assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {f: 5}]); assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}], [{a: 1}, {b: 2}, {b: 2}]); assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}]); assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {b: 2}], [{a: 1}, {b: 2}, {c: 3}]); assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {b: 2}]); err(function() { assert.notSameDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {c: 3}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not have the same ordered members as [ { a: 1 }, { b: 2 }, { c: 3 } ]'); }); it('includeMembers', function() { assert.includeMembers([1, 2, 3], [2, 3, 2]); assert.includeMembers([1, 2, 3], []); assert.includeMembers([1, 2, 3], [3]); err(function() { assert.includeMembers([5, 6], [7, 8], 'blah'); }, 'blah: expected [ 5, 6 ] to be a superset of [ 7, 8 ]'); err(function() { assert.includeMembers([5, 6], [5, 6, 0]); }, 'expected [ 5, 6 ] to be a superset of [ 5, 6, +0 ]'); }); it('notIncludeMembers', function() { assert.notIncludeMembers([1, 2, 3], [5, 1]); assert.notIncludeMembers([{a: 1}], [{a: 1}]); err(function() { assert.notIncludeMembers([1, 2, 3], [2, 1], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to not be a superset of [ 2, 1 ]'); }); it('includeDeepMembers', function() { assert.includeDeepMembers([{a:1}, {b:2}, {c:3}], [{c:3}, {b:2}]); assert.includeDeepMembers([{a:1}, {b:2}, {c:3}], []); assert.includeDeepMembers([{a:1}, {b:2}, {c:3}], [{c:3}]); assert.includeDeepMembers([{a:1}, {b:2}, {c:3}, {c:3}], [{c:3}, {c:3}]); assert.includeDeepMembers([{a:1}, {b:2}, {c:3}], [{c:3}, {c:3}]); err(function() { assert.includeDeepMembers([{e:5}, {f:6}], [{g:7}, {h:8}], 'blah'); }, 'blah: expected [ { e: 5 }, { f: 6 } ] to be a superset of [ { g: 7 }, { h: 8 } ]'); err(function() { assert.includeDeepMembers([{e:5}, {f:6}], [{e:5}, {f:6}, {z:0}]); }, 'expected [ { e: 5 }, { f: 6 } ] to be a superset of [ { e: 5 }, { f: 6 }, { z: +0 } ]'); }); it('notIncludeDeepMembers', function() { assert.notIncludeDeepMembers([{a:1}, {b:2}, {c:3}], [{b:2}, {f:5}]); err(function() { assert.notIncludeDeepMembers([{a:1}, {b:2}, {c:3}], [{b:2}, {a:1}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be a superset of [ { b: 2 }, { a: 1 } ]'); }); it('includeOrderedMembers', function() { assert.includeOrderedMembers([1, 2, 3], [1, 2]); err(function() { assert.includeOrderedMembers([1, 2, 3], [2, 1], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to be an ordered superset of [ 2, 1 ]'); }); it('notIncludeOrderedMembers', function() { assert.notIncludeOrderedMembers([1, 2, 3], [2, 1]); assert.notIncludeOrderedMembers([1, 2, 3], [2, 3]); assert.notIncludeOrderedMembers([1, 2, 3], [1, 2, 2]); err(function() { assert.notIncludeOrderedMembers([1, 2, 3], [1, 2], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to not be an ordered superset of [ 1, 2 ]'); }); it('includeDeepOrderedMembers', function() { assert.includeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}]); err(function() { assert.includeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be an ordered superset of [ { b: 2 }, { a: 1 } ]'); }); it('notIncludeDeepOrderedMembers', function() { assert.notIncludeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{b: 2}, {a: 1}]); assert.notIncludeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {f: 5}]); assert.notIncludeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}, {b: 2}]); err(function() { assert.notIncludeDeepOrderedMembers([{a: 1}, {b: 2}, {c: 3}], [{a: 1}, {b: 2}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be an ordered superset of [ { a: 1 }, { b: 2 } ]'); }); it('oneOf', function() { assert.oneOf(1, [1, 2, 3]); var three = [3]; assert.oneOf(three, [1, 2, three]); var four = { four: 4 }; assert.oneOf(four, [1, 2, four]); err(function() { assert.oneOf(1, 1, 'blah'); }, 'blah: expected 1 to be an array'); err(function() { assert.oneOf(1, { a: 1 }); }, 'expected { a: 1 } to be an array'); err(function() { assert.oneOf(9, [1, 2, 3], 'Message'); }, 'Message: expected 9 to be one of [ 1, 2, 3 ]'); err(function() { assert.oneOf([3], [1, 2, [3]]); }, 'expected [ 3 ] to be one of [ 1, 2, [ 3 ] ]'); err(function() { assert.oneOf({ four: 4 }, [1, 2, { four: 4 }]); }, 'expected { four: 4 } to be one of [ 1, 2, { four: 4 } ]'); }); it('above', function() { assert.isAbove(5, 2, '5 should be above 2'); assert.isAbove(5n, 2, '5 should be above 2'); assert.isAbove(5, 2n, '5 should be above 2'); assert.isAbove(5n, 2n, '5 should be above 2'); assert.isAbove(9007199254740994n, 2, '9007199254740994 should be above 2'); err(function() { assert.isAbove(1, 3, 'blah'); }, 'blah: expected 1 to be above 3'); err(function() { assert.isAbove(1, 1); }, 'expected 1 to be above 1'); err(function() { assert.isAbove(null, 1, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isAbove(1, null, 'blah'); }, 'blah: the argument to above must be a number'); }); it('above (dates)', function() { var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); assert.isAbove(now, oneSecondAgo, 'Now should be above 1 second ago'); err(function() { assert.isAbove(oneSecondAgo, now, 'blah'); }, 'blah: expected ' + oneSecondAgo.toISOString() + ' to be above ' + now.toISOString()); err(function() { assert.isAbove(now, now, 'blah'); }, 'blah: expected ' + now.toISOString() + ' to be above ' + now.toISOString()); err(function() { assert.isAbove(null, now); }, 'expected null to be a number or a date'); err(function() { assert.isAbove(now, null, 'blah'); }, 'blah: the argument to above must be a date'); err(function() { assert.isAbove(now, 1, 'blah'); }, 'blah: the argument to above must be a date'); err(function() { assert.isAbove(1, now, 'blah'); }, 'blah: the argument to above must be a number'); }); it('atLeast', function() { assert.isAtLeast(5, 2, '5 should be above 2'); assert.isAtLeast(1, 1, '1 should be equal to 1'); assert.isAtLeast(5n, 2, '5 should be above 2'); assert.isAtLeast(1, 1n, '1 should be equal to 1'); err(function() { assert.isAtLeast(1, 3, 'blah'); }, 'blah: expected 1 to be at least 3'); err(function() { assert.isAtLeast(null, 1, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isAtLeast(1, null, 'blah'); }, 'blah: the argument to least must be a number'); }); it('atLeast (dates)', function() { var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); assert.isAtLeast(now, oneSecondAgo, 'Now should be above one second ago'); assert.isAtLeast(now, now, 'Now should be equal to now'); err(function() { assert.isAtLeast(now, oneSecondAfter, 'blah'); }, 'blah: expected ' + now.toISOString() + ' to be at least ' + oneSecondAfter.toISOString()); err(function() { assert.isAtLeast(null, now, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isAtLeast(now, null, 'blah'); }, 'blah: the argument to least must be a date'); err(function() { assert.isAtLeast(1, now, 'blah'); }, 'blah: the argument to least must be a number'); err(function() { assert.isAtLeast(now, 1, 'blah'); }, 'blah: the argument to least must be a date'); }); it('below', function() { assert.isBelow(2, 5, '2 should be below 5'); assert.isBelow(2, 5n, '2 should be below 5'); assert.isBelow(2n, 5, '2 should be below 5'); assert.isBelow(2n, 5n, '2 should be below 5'); err(function() { assert.isBelow(3, 1, 'blah'); }, 'blah: expected 3 to be below 1'); err(function() { assert.isBelow(1, 1); }, 'expected 1 to be below 1'); err(function() { assert.isBelow(null, 1, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isBelow(1, null, 'blah'); }, 'blah: the argument to below must be a number'); }); it('below (dates)', function() { var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); assert.isBelow(oneSecondAgo, now, 'One second ago should be below now'); err(function() { assert.isBelow(now, oneSecondAgo, 'blah'); }, 'blah: expected ' + now.toISOString() + ' to be below ' + oneSecondAgo.toISOString()); err(function() { assert.isBelow(now, now); }, 'expected ' + now.toISOString() + ' to be below ' + now.toISOString()); err(function() { assert.isBelow(null, now, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isBelow(now, null, 'blah'); }, 'blah: the argument to below must be a date'); err(function() { assert.isBelow(now, 1, 'blah'); }, 'blah: the argument to below must be a date'); err(function() { assert.isBelow(1, now, 'blah'); }, 'blah: the argument to below must be a number'); }); it('atMost', function() { assert.isAtMost(2, 5, '2 should be below 5'); assert.isAtMost(1, 1, '1 should be equal to 1'); assert.isAtMost(2n, 5, '2 should be below 5'); assert.isAtMost(1, 1n, '1 should be equal to 1'); err(function() { assert.isAtMost(3, 1, 'blah'); }, 'blah: expected 3 to be at most 1'); err(function() { assert.isAtMost(null, 1, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isAtMost(1, null, 'blah'); }, 'blah: the argument to most must be a number'); }); it('atMost (dates)', function() { var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); assert.isAtMost(oneSecondAgo, now, 'Now should be below one second ago'); assert.isAtMost(now, now, 'Now should be equal to now'); err(function() { assert.isAtMost(oneSecondAfter, now, 'blah'); }, 'blah: expected ' + oneSecondAfter.toISOString() + ' to be at most ' + now.toISOString()); err(function() { assert.isAtMost(null, now, 'blah'); }, 'blah: expected null to be a number or a date'); err(function() { assert.isAtMost(now, null, 'blah'); }, 'blah: the argument to most must be a date'); err(function() { assert.isAtMost(now, 1, 'blah'); }, 'blah: the argument to most must be a date'); err(function() { assert.isAtMost(1, now, 'blah'); }, 'blah: the argument to most must be a number'); }); it('iterable', function() { assert.isIterable([1, 2, 3]); assert.isIterable(new Map([[1, 'one'], [2, 'two'], [3, 'three']])); assert.isIterable(new Set([1, 2, 3])); assert.isIterable('hello'); err(function() { assert.isIterable(42); }, 'expected 42 to be an iterable'); err(function() { assert.isIterable(undefined); }, 'expected undefined to be an iterable'); err(function() { assert.isIterable(null); }, 'expected null to be an iterable'); err(function() { assert.isIterable(true); }, 'expected true to be an iterable'); err(function() { assert.isIterable({ key: 'value' }); }, 'expected { key: \'value\' } to be an iterable'); }); it('change', function() { var obj = { value: 10, str: 'foo' }, heroes = ['spiderman', 'superman'], fn = function() { obj.value += 5 }, fnDec = function() { obj.value -= 20 }, getterFn = function() { return obj.value }, bangFn = function() { obj.str += '!' }, smFn = function() { 'foo' + 'bar' }, batFn = function() { heroes.push('batman') }, lenFn = function() { return heroes.length }; assert.changes(fn, obj, 'value'); assert.changes(fn, getterFn, 'changes via getter function'); assert.changesBy(fn, obj, 'value', 5); assert.changesBy(fn, obj, 'value', -5); assert.changesBy(fn, getterFn, 5); assert.changesBy(fnDec, obj, 'value', 20); assert.doesNotChange(smFn, obj, 'value'); assert.doesNotChange(smFn, getterFn, 'value'); assert.changesButNotBy(fnDec, obj, 'value', 1); assert.changesButNotBy(fnDec, getterFn, 1); assert.changes(bangFn, obj, 'str'); assert.changesBy(batFn, lenFn, 1); assert.changesButNotBy(batFn, lenFn, 2); err(function () { assert.changes(smFn, obj, 'value', 'blah'); }, "blah: expected .value to change"); err(function () { assert.doesNotChange(fn, obj, 'value', 'blah'); }, "blah: expected .value to not change"); err(function () { assert.changes({}, obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { assert.changes(fn, {}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function () { assert.changesBy(fn, obj, 'value', 10, 'blah'); }, "blah: expected .value to change by 10"); err(function () { assert.changesButNotBy(fn, obj, 'value', 5, 'blah'); }, "blah: expected .value to not change by 5"); }); it('increase, decrease', function() { var obj = { value: 10, noop: null }, arr = ['one', 'two'], pFn = function() { arr.push('three') }, popFn = function() { arr.pop() }, lenFn = function() { return arr.length }, incFn = function() { obj.value += 2 }, decFn = function() { obj.value -= 3 }, getterFn = function() { return obj.value }, smFn = function() { obj.value += 0 }; assert.decreases(decFn, obj, 'value'); assert.decreases(decFn, getterFn, 'decreases via getter function'); assert.doesNotDecrease(smFn, obj, 'value'); assert.doesNotDecrease(smFn, getterFn, 'value'); assert.decreasesBy(decFn, obj, 'value', 3); assert.decreasesBy(decFn, getterFn, 3); assert.decreasesButNotBy(decFn, obj, 'value', 10); assert.decreasesButNotBy(decFn, getterFn, 10); assert.increases(incFn, obj, 'value'); assert.increases(incFn, getterFn, 'increases via getter function'); assert.doesNotIncrease(smFn, obj, 'value'); assert.doesNotIncrease(smFn, getterFn, 'value'); assert.increasesBy(incFn, obj, 'value', 2); assert.increasesBy(incFn, getterFn, 2); assert.increasesButNotBy(incFn, obj, 'value', 1); assert.increasesButNotBy(incFn, getterFn, 1); assert.decreases(popFn, lenFn); assert.doesNotDecrease(pFn, lenFn); assert.decreasesBy(popFn, lenFn, 1); assert.decreasesButNotBy(popFn, lenFn, 2); assert.increases(pFn, lenFn); assert.doesNotIncrease(popFn, lenFn); assert.increasesBy(pFn, lenFn, 1); assert.increasesButNotBy(pFn, lenFn, 2); err(function () { assert.increases(smFn, obj, 'value', 'blah'); }, "blah: expected .value to increase"); err(function () { assert.doesNotIncrease(incFn, obj, 'value', 'blah'); }, "blah: expected .value to not increase"); err(function () { assert.increases({}, obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { assert.increases(incFn, {}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function() { assert.increases(incFn, obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function () { assert.increasesBy(incFn, obj, 'value', 10, 'blah'); }, "blah: expected .value to increase by 10"); err(function () { assert.increasesButNotBy(incFn, obj, 'value', 2, 'blah'); }, "blah: expected .value to not increase by 2"); err(function () { assert.decreases(smFn, obj, 'value', 'blah'); }, "blah: expected .value to decrease"); err(function () { assert.doesNotDecrease(decFn, obj, 'value', 'blah'); }, "blah: expected .value to not decrease"); err(function () { assert.decreases({}, obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { assert.decreases(decFn, {}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function() { assert.decreases(decFn, obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function () { assert.decreasesBy(decFn, obj, 'value', 10, 'blah'); }, "blah: expected .value to decrease by 10"); err(function () { assert.decreasesButNotBy(decFn, obj, 'value', 3, 'blah'); }, "blah: expected .value to not decrease by 3"); }); it('isExtensible / extensible', function() { ['isExtensible', 'extensible'].forEach(function (isExtensible) { var nonExtensibleObject = Object.preventExtensions({}); assert[isExtensible]({}); err(function() { assert[isExtensible](nonExtensibleObject, 'blah'); }, 'blah: expected {} to be extensible'); // Making sure ES6-like Object.isExtensible response is respected for all primitive types err(function() { assert[isExtensible](42); }, 'expected 42 to be extensible'); err(function() { assert[isExtensible](null); }, 'expected null to be extensible'); err(function() { assert[isExtensible]('foo'); }, 'expected \'foo\' to be extensible'); err(function() { assert[isExtensible](false); }, 'expected false to be extensible'); err(function() { assert[isExtensible](undefined); }, 'expected undefined to be extensible'); var proxy = new Proxy({}, { isExtensible: function() { throw new TypeError(); } }); err(function() { // isExtensible should not suppress errors, thrown in proxy traps assert[isExtensible](proxy); }, { name: 'TypeError' }, true); }); }); it('isNotExtensible / notExtensible', function() { ['isNotExtensible', 'notExtensible'].forEach(function (isNotExtensible) { var nonExtensibleObject = Object.preventExtensions({}); assert[isNotExtensible](nonExtensibleObject); err(function() { assert[isNotExtensible]({}, 'blah'); }, 'blah: expected {} to not be extensible'); // Making sure ES6-like Object.isExtensible response is respected for all primitive types assert[isNotExtensible](42); assert[isNotExtensible](null); assert[isNotExtensible]('foo'); assert[isNotExtensible](false); assert[isNotExtensible](undefined); assert[isNotExtensible](Symbol()); var proxy = new Proxy({}, { isExtensible: function() { throw new TypeError(); } }); err(function() { // isNotExtensible should not suppress errors, thrown in proxy traps assert[isNotExtensible](proxy); }, { name: 'TypeError' }, true); }); }); it('isSealed / sealed', function() { ['isSealed', 'sealed'].forEach(function (isSealed) { var sealedObject = Object.seal({}); assert[isSealed](sealedObject); err(function() { assert[isSealed]({}, 'blah'); }, 'blah: expected {} to be sealed'); // Making sure ES6-like Object.isSealed response is respected for all primitive types assert[isSealed](42); assert[isSealed](null); assert[isSealed]('foo'); assert[isSealed](false); assert[isSealed](undefined); assert[isSealed](Symbol()); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isSealed will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // isSealed should not suppress errors, thrown in proxy traps assert[isSealed](proxy); }, { name: 'TypeError' }, true); }); }); it('isNotSealed / notSealed', function() { ['isNotSealed', 'notSealed'].forEach(function (isNotSealed) { var sealedObject = Object.seal({}); assert[isNotSealed]({}); err(function() { assert[isNotSealed](sealedObject, 'blah'); }, 'blah: expected {} to not be sealed'); // Making sure ES6-like Object.isSealed response is respected for all primitive types err(function() { assert[isNotSealed](42); }, 'expected 42 to not be sealed'); err(function() { assert[isNotSealed](null); }, 'expected null to not be sealed'); err(function() { assert[isNotSealed]('foo'); }, 'expected \'foo\' to not be sealed'); err(function() { assert[isNotSealed](false); }, 'expected false to not be sealed'); err(function() { assert[isNotSealed](undefined); }, 'expected undefined to not be sealed'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isSealed will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // isNotSealed should not suppress errors, thrown in proxy traps assert[isNotSealed](proxy); }, { name: 'TypeError' }, true); }); }); it('isFrozen / frozen', function() { ['isFrozen', 'frozen'].forEach(function (isFrozen) { var frozenObject = Object.freeze({}); assert[isFrozen](frozenObject); err(function() { assert[isFrozen]({}, 'blah'); }, 'blah: expected {} to be frozen'); // Making sure ES6-like Object.isFrozen response is respected for all primitive types assert[isFrozen](42); assert[isFrozen](null); assert[isFrozen]('foo'); assert[isFrozen](false); assert[isFrozen](undefined); assert[isFrozen](Symbol()); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isFrozen will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // isFrozen should not suppress errors, thrown in proxy traps assert[isFrozen](proxy); }, { name: 'TypeError' }, true); }); }); it('isNotFrozen / notFrozen', function() { ['isNotFrozen', 'notFrozen'].forEach(function (isNotFrozen) { var frozenObject = Object.freeze({}); assert[isNotFrozen]({}); err(function() { assert[isNotFrozen](frozenObject, 'blah'); }, 'blah: expected {} to not be frozen', true); // Making sure ES6-like Object.isFrozen response is respected for all primitive types err(function() { assert[isNotFrozen](42); }, 'expected 42 to not be frozen'); err(function() { assert[isNotFrozen](null); }, 'expected null to not be frozen'); err(function() { assert[isNotFrozen]('foo'); }, 'expected \'foo\' to not be frozen'); err(function() { assert[isNotFrozen](false); }, 'expected false to not be frozen'); err(function() { assert[isNotFrozen](undefined); }, 'expected undefined to not be frozen'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isFrozen will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // isNotFrozen should not suppress errors, thrown in proxy traps assert[isNotFrozen](proxy); }, { name: 'TypeError' }, true); }); }); it('isEmpty / empty', function() { ['isEmpty', 'empty'].forEach(function (isEmpty) { function FakeArgs() {}; FakeArgs.prototype.length = 0; assert[isEmpty](''); assert[isEmpty]([]); assert[isEmpty](new FakeArgs()); assert[isEmpty]({}); err(function(){ assert[isEmpty](new WeakMap(), 'blah'); }, "blah: .empty was passed a weak collection"); err(function(){ assert[isEmpty](new WeakSet(), 'blah'); }, "blah: .empty was passed a weak collection"); assert[isEmpty](new Map()); var map = new Map(); map.key = 'val'; assert[isEmpty](map); assert[isEmpty](new Set()); var set = new Set(); set.key = 'val'; assert[isEmpty](set); err(function(){ assert[isEmpty]('foo', 'blah'); }, "blah: expected \'foo\' to be empty"); err(function(){ assert[isEmpty](['foo']); }, "expected [ \'foo\' ] to be empty"); err(function(){ assert[isEmpty]({arguments: 0}); }, "expected { arguments: +0 } to be empty"); err(function(){ assert[isEmpty]({foo: 'bar'}); }, "expected { foo: \'bar\' } to be empty"); err(function(){ assert[isEmpty](null, 'blah'); }, "blah: .empty was passed non-string primitive null"); err(function(){ assert[isEmpty](undefined); }, ".empty was passed non-string primitive undefined"); err(function(){ assert[isEmpty](); }, ".empty was passed non-string primitive undefined"); err(function(){ assert[isEmpty](0); }, ".empty was passed non-string primitive +0"); err(function(){ assert[isEmpty](1); }, ".empty was passed non-string primitive 1"); err(function(){ assert[isEmpty](true); }, ".empty was passed non-string primitive true"); err(function(){ assert[isEmpty](false); }, ".empty was passed non-string primitive false"); err(function(){ assert[isEmpty](Symbol()); }, ".empty was passed non-string primitive Symbol()"); err(function(){ assert[isEmpty](Symbol.iterator); }, ".empty was passed non-string primitive Symbol(Symbol.iterator)"); err(function(){ assert[isEmpty](function() {}, 'blah'); }, "blah: .empty was passed a function"); if (FakeArgs.name === 'FakeArgs') { err(function(){ assert[isEmpty](FakeArgs); }, ".empty was passed a function FakeArgs"); } }); }); it('isNotEmpty / notEmpty', function() { ['isNotEmpty', 'notEmpty'].forEach(function (isNotEmpty) { function FakeArgs() {}; FakeArgs.prototype.length = 0; assert[isNotEmpty]('foo'); assert[isNotEmpty](['foo']); assert[isNotEmpty]({arguments: 0}); assert[isNotEmpty]({foo: 'bar'}); err(function(){ assert[isNotEmpty](new WeakMap(), 'blah'); }, "blah: .empty was passed a weak collection"); err(function(){ assert[isNotEmpty](new WeakSet(), 'blah'); }, "blah: .empty was passed a weak collection"); var map = new Map(); map.set('a', 1); assert[isNotEmpty](map); err(function(){ assert[isNotEmpty](new Map()); }, "expected Map{} not to be empty"); var set = new Set(); set.add(1); assert[isNotEmpty](set); err(function(){ assert[isNotEmpty](new Set()); }, "expected Set{} not to be empty"); err(function(){ assert[isNotEmpty]('', 'blah'); }, "blah: expected \'\' not to be empty"); err(function(){ assert[isNotEmpty]([]); }, "expected [] not to be empty"); err(function(){ assert[isNotEmpty](new FakeArgs()); }, "expected FakeArgs{} not to be empty"); err(function(){ assert[isNotEmpty]({}); }, "expected {} not to be empty"); err(function(){ assert[isNotEmpty](null, 'blah'); }, "blah: .empty was passed non-string primitive null"); err(function(){ assert[isNotEmpty](undefined); }, ".empty was passed non-string primitive undefined"); err(function(){ assert[isNotEmpty](); }, ".empty was passed non-string primitive undefined"); err(function(){ assert[isNotEmpty](0); }, ".empty was passed non-string primitive +0"); err(function(){ assert[isNotEmpty](1); }, ".empty was passed non-string primitive 1"); err(function(){ assert[isNotEmpty](true); }, ".empty was passed non-string primitive true"); err(function(){ assert[isNotEmpty](false); }, ".empty was passed non-string primitive false"); err(function(){ assert[isNotEmpty](Symbol()); }, ".empty was passed non-string primitive Symbol()"); err(function(){ assert[isNotEmpty](Symbol.iterator); }, ".empty was passed non-string primitive Symbol(Symbol.iterator)"); err(function(){ assert[isNotEmpty](function() {}, 'blah'); }, "blah: .empty was passed a function"); if (FakeArgs.name === 'FakeArgs') { err(function(){ assert[isNotEmpty](FakeArgs); }, ".empty was passed a function FakeArgs"); } }); }); it('showDiff true with actual and expected args', function() { try { new chai.Assertion().assert( 'one' === 'two' , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{act}' , 'one' , 'two' ); } catch(e) { assert.isTrue(e.showDiff); } }); it('showDiff false without expected and actual', function() { try { new chai.Assertion().assert( 'one' === 'two' , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{act}' , 'one' , 'two' , false ); } catch(e) { assert.isFalse(e.showDiff); } }); }); chaijs-chai-2a3ecff/test/auth/000077500000000000000000000000001505212005400163425ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/auth/.gitkeep000066400000000000000000000000001505212005400177610ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/bootstrap/000077500000000000000000000000001505212005400174165ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/bootstrap/index.js000066400000000000000000000036541505212005400210730ustar00rootroot00000000000000import * as chai from '../../index.js'; var isStackSupported = false; if (typeof Error.captureStackTrace !== 'undefined') { try { throw Error(); } catch (err) { if (typeof err.stack !== 'undefined') isStackSupported = true; } } /** * Validate that the given function throws an error. * * By default, also validate that the thrown error's stack trace doesn't contain * Chai implementation frames. Stack trace validation can be disabled by * providing a truthy `skipStackTest` argument. * * Optionally validate some additional properties of the error: * * If val is a string, validate val equals the error's .message * If val is a regex, validate val matches the error's .message * If val is an object, validate val's props are included in the error object * * @param {Function} function that's expected to throw an error * @param {Mixed} expected properties of the expected error * @param {Boolean} skipStackTest if truthy, don't validate stack trace */ export function globalErr(fn, val, skipStackTest) { if (chai.util.type(fn) !== 'Function') throw new chai.AssertionError('Invalid fn'); try { fn(); } catch (err) { if (isStackSupported && !skipStackTest) { chai.expect(err).to.have.property('stack') .that.has.string('globalErr') .but.does.not.match( /at [a-zA-Z]*(Getter|Wrapper|(\.)*assert)/, 'implementation frames not properly filtered from stack trace' ); } switch (chai.util.type(val).toLowerCase()) { case 'undefined': return; case 'string': return chai.expect(err.message).to.equal(val); case 'regexp': return chai.expect(err.message).to.match(val); case 'object': return Object.keys(val).forEach(function (key) { chai.expect(err).to.have.property(key).and.to.deep.equal(val[key]); }); } throw new chai.AssertionError('Invalid val'); } throw new chai.AssertionError('Expected an error'); }; chaijs-chai-2a3ecff/test/configuration.js000066400000000000000000000623271505212005400206200ustar00rootroot00000000000000import * as chai from '../index.js'; import {globalErr as err} from './bootstrap/index.js'; import '../register-should.js'; describe('configuration', function () { var assert = chai.assert; var expect = chai.expect; var origConfig; beforeEach(function() { // backup current config function clone(o) { return JSON.parse(JSON.stringify(o)); } origConfig = clone(chai.config); }); afterEach(function() { // restore config Object.keys(origConfig).forEach(function(key) { chai.config[key] = origConfig[key]; }); }); describe('includeStack', function() { // Skip tests if `Error.captureStackTrace` is unsupported if (typeof Error.captureStackTrace === 'undefined') return; try { throw Error(); } catch (err) { // Skip tests if `err.stack` is unsupported if (typeof err.stack === 'undefined') return; } // Create overwritten assertions that always fail before(function () { chai.util.addProperty(chai.Assertion.prototype, 'tmpProperty', function () {}); chai.util.overwriteProperty(chai.Assertion.prototype, 'tmpProperty', function () { return function () { this.assert(false); }; }); chai.util.addMethod(chai.Assertion.prototype, 'tmpMethod', function () {}); chai.util.overwriteMethod(chai.Assertion.prototype, 'tmpMethod', function () { return function () { this.assert(false); }; }); chai.util.addChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function () {}, function () {}); chai.util.overwriteChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function (_super) { return function () { this.assert(false); }; }, function () { return function () {}; }); }); // Delete overwritten assertions after(function () { delete chai.Assertion.prototype.tmpProperty; delete chai.Assertion.prototype.tmpMethod; delete chai.Assertion.prototype.tmpChainableMethod; }); describe('expect interface', function () { // Functions that always throw an error function badPropertyAssertion() { expect(42).to.be.false; } function badOverwrittenPropertyAssertion() { expect(42).tmpProperty; } function badMethodAssertion() { expect(42).to.equal(false); } function badOverwrittenMethodAssertion() { expect(42).tmpMethod(); } function badChainableMethodAssertion() { expect(42).to.be.a('string'); } function badOverwrittenChainableMethodAssertion() { expect(42).tmpChainableMethod(); } describe('when true', function () { describe('failed property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('propertyGetter'); expect(caughtErr.stack).to.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badPropertyAssertion'); }); }); describe('failed overwritten property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingPropertyGetter'); expect(caughtErr.stack).to.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenPropertyAssertion'); }); }); describe('failed method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('methodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badMethodAssertion'); }); }); describe('failed overwritten method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenMethodAssertion'); }); }); describe('failed chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('chainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badChainableMethodAssertion'); }); }); describe('failed overwritten chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingChainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenChainableMethodAssertion'); }); }); }); describe('when false', function () { describe('failed property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('propertyGetter'); expect(caughtErr.stack).to.not.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badPropertyAssertion'); }); }); describe('failed overwritten property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingPropertyGetter'); expect(caughtErr.stack).to.not.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenPropertyAssertion'); }); }); describe('failed method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('methodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badMethodAssertion'); }); }); describe('failed overwritten method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenMethodAssertion'); }); }); describe('failed chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('chainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badChainableMethodAssertion'); }); }); describe('failed overwritten chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingChainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenChainableMethodAssertion'); }); }); }); }); describe('should interface', function () { // Functions that always throw an error function badPropertyAssertion() { (42).should.be.false; } function badOverwrittenPropertyAssertion() { (42).should.tmpProperty; } function badMethodAssertion() { (42).should.equal(false); } function badOverwrittenMethodAssertion() { (42).should.tmpMethod(); } function badChainableMethodAssertion() { (42).should.be.a('string'); } function badOverwrittenChainableMethodAssertion() { (42).should.tmpChainableMethod(); } describe('when true', function () { describe('failed property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('propertyGetter'); expect(caughtErr.stack).to.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badPropertyAssertion'); }); }); describe('failed overwritten property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingPropertyGetter'); expect(caughtErr.stack).to.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenPropertyAssertion'); }); }); describe('failed method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('methodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badMethodAssertion'); }); }); describe('failed overwritten method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenMethodAssertion'); }); }); describe('failed chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('chainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badChainableMethodAssertion'); }); }); describe('failed overwritten chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = true; try { badOverwrittenChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should include Chai frames in stack trace', function () { expect(caughtErr.stack).to.contain('overwritingChainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenChainableMethodAssertion'); }); }); }); describe('when false', function () { describe('failed property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('propertyGetter'); expect(caughtErr.stack).to.not.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badPropertyAssertion'); }); }); describe('failed overwritten property assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenPropertyAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingPropertyGetter'); expect(caughtErr.stack).to.not.contain('proxyGetter'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenPropertyAssertion'); }); }); describe('failed method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('methodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badMethodAssertion'); }); }); describe('failed overwritten method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenMethodAssertion'); }); }); describe('failed chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('chainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badChainableMethodAssertion'); }); }); describe('failed overwritten chainable method assertions', function () { var caughtErr = '__PRETEST__'; before(function () { chai.config.includeStack = false; try { badOverwrittenChainableMethodAssertion(); } catch (err) { caughtErr = err; } }); it('should not include Chai frames in stack trace', function () { expect(caughtErr.stack).to.not.contain('overwritingChainableMethodWrapper'); }); it('should include user frames in stack trace', function () { expect(caughtErr.stack).to.contain('badOverwrittenChainableMethodAssertion'); }); }); }); }); }); describe('truncateThreshold', function() { it('is 20', function() { chai.config.truncateThreshold = 20; err(function() { assert.deepEqual({v: 'something longer than 20'}, {v: 'x'}); }, "expected { Object (v) } to deeply equal { v: 'x' }"); }); it('is 0', function() { chai.config.truncateThreshold = 0; err(function() { assert.deepEqual({v: 'something longer than 20'}, {v: 'x'}); }, "expected { v: 'something longer than 20' } to deeply equal { v: 'x' }"); }); }); describe('deprecated properties', function() { var origWarnFn; var warnings; beforeEach(function() { origWarnFn = console.warn; warnings = []; console.warn = function(message) { warnings.push(message); }; }); afterEach(function() { console.warn = origWarnFn; }); it('Assertion.includeStack warns that it is deprecated', function() { chai.Assertion.includeStack; assert.equal(warnings.length, 1); assert.equal(warnings[0], 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); chai.Assertion.includeStack = true; assert.equal(warnings.length, 2); assert.equal(warnings[1], 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); }); it('Assertion.includeStack is kept in sync with config.includeStack', function() { assert.equal(chai.Assertion.includeStack, chai.config.includeStack); chai.Assertion.includeStack = !chai.Assertion.includeStack; assert.equal(chai.Assertion.includeStack, chai.config.includeStack); chai.config.includeStack = !chai.config.includeStack; assert.equal(chai.Assertion.includeStack, chai.config.includeStack); }); it('Assertion.showDiff warns that it is deprecated', function() { chai.Assertion.showDiff; assert.equal(warnings.length, 1); assert.equal(warnings[0], 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); chai.Assertion.showDiff = true; assert.equal(warnings.length, 2); assert.equal(warnings[1], 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); }); it('Assertion.showDiff is kept in sync with config.showDiff', function() { assert.equal(chai.Assertion.showDiff, chai.config.showDiff); chai.Assertion.showDiff = !chai.Assertion.showDiff; assert.equal(chai.Assertion.showDiff, chai.config.showDiff); chai.config.showDiff = !chai.config.showDiff; assert.equal(chai.Assertion.showDiff, chai.config.showDiff); }); }); describe('useProxy', function() { var readNoExistentProperty = function() { expect(false).to.be.tue; // typo: tue should be true }; it('should have default value equal to true', function() { expect(chai.config.useProxy).to.be.true; }); describe('when true', function() { it('should use proxy unless user\'s environment doesn\'t support', function() { expect(readNoExistentProperty).to.throw('Invalid Chai property: tue'); }); }); describe('when false', function() { it('should not use proxy', function() { chai.config.useProxy = false; expect(readNoExistentProperty).to.not.throw('Invalid Chai property: tue'); }); }); }); describe('proxyExcludedKeys', function() { var readNoExistentProperty = function(prop) { return function() { var assertion = expect(false); expect(assertion).to.not.have.key(prop); assertion[prop]; } }; it('should have default value equal to `[\'then\', \'catch\', \'inspect\', \'toJSON\']`', function() { expect(chai.config.proxyExcludedKeys).to.be.deep.equal(['then', 'catch', 'inspect', 'toJSON']); }); it('should not throw when accessing non-existing `then` and `inspect` in an environment with proxy support', function() { // Since these will not throw if the environment does not support proxies we don't need any `if` clause here expect(readNoExistentProperty('then')).to.not.throw(); expect(readNoExistentProperty('inspect')).to.not.throw(); }); it('should throw for properties which are not on the `proxyExcludedKeys` Array in an environment with proxy support', function() { chai.config.proxyExcludedKeys = []; expect(readNoExistentProperty('then')).to.throw('Invalid Chai property: then'); expect(readNoExistentProperty('inspect')).to.throw('Invalid Chai property: inspect'); }); }); describe('deepEqual', function() { it('should use custom deepEqual function for deepEqual comparison', function(){ chai.config.deepEqual = (expected, actual) => { return chai.util.eql(expected, actual, { comparator: (expected, actual) => { // for non number comparison, use the default behavior if(typeof expected !== 'number') return null; // allow a difference of 10 between compared numbers return typeof actual === 'number' && Math.abs(actual - expected) < 10 } }) }; assert.deepEqual({v: 1}, {v: 10}); err(function() { assert.deepEqual({v: 1}, {v: 100}); }, "expected { v: 1 } to deeply equal { v: 100 }"); }) }) }); chaijs-chai-2a3ecff/test/display/000077500000000000000000000000001505212005400170465ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/display/errors.js000066400000000000000000000003331505212005400207170ustar00rootroot00000000000000import * as chai from '../../index.js'; var expect = chai.expect; chai.config.includeStack = true; describe('error display', function () { it('show error line', function () { expect(4).to.equal(2); }); }); chaijs-chai-2a3ecff/test/display/message.js000066400000000000000000000015311505212005400210300ustar00rootroot00000000000000import * as chai from '../../index.js' const expect = chai.expect var deepObj = { green: { tea: 'matcha' } , teas: [ 'chai' , 'matcha' , { tea: 'konacha' } ] }; var deepObj2 = { green: { tea: 'matcha' } , teas: [ 'chai' , 'oolong' , { tea: 'konacha' } ] }; chai.config.includeStack = true; describe('object display', function () { it('property', function () { deepObj.should.have.property('chai'); }); it('deep equal', function () { deepObj.should.deep.equal(deepObj2); }); it('deep equal no diff', function () { chai.config.showDiff = false; deepObj.should.deep.equal(deepObj2); chai.config.showDiff = true; }); }); describe('undefined/null display', function() { it('undefined for actual', function() { expect(undefined).to.equal(null); }); }); chaijs-chai-2a3ecff/test/expect.js000066400000000000000000004221101505212005400172270ustar00rootroot00000000000000import * as chai from '../index.js'; import {globalErr as err} from './bootstrap/index.js'; describe('expect', function () { var expect = chai.expect; it('assertion', function(){ expect('test').to.be.a('string'); expect('foo').to.equal('foo'); }); describe('safeguards', function () { before(function () { chai.util.addProperty(chai.Assertion.prototype, 'tmpProperty', function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteProperty(chai.Assertion.prototype, 'tmpProperty', function (_super) { return function () { _super.call(this); }; }); chai.util.addMethod(chai.Assertion.prototype, 'tmpMethod', function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteMethod(chai.Assertion.prototype, 'tmpMethod', function (_super) { return function () { _super.call(this); }; }); chai.util.addChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function () { new chai.Assertion(42).equal(42); }, function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function (_super) { return function () { _super.call(this); }; }, function (_super) { return function () { _super.call(this); }; }); }); after(function () { delete chai.Assertion.prototype.tmpProperty; delete chai.Assertion.prototype.tmpMethod; delete chai.Assertion.prototype.tmpChainableMethod; }); describe('proxify', function () { it('throws when invalid property follows expect', function () { err(function () { expect(42).pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows language chain', function () { err(function () { expect(42).to.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows property assertion', function () { err(function () { expect(42).ok.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows overwritten property assertion', function () { err(function () { expect(42).tmpProperty.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled method assertion', function () { err(function () { expect(42).equal.pizza; }, 'Invalid Chai property: equal.pizza. See docs for proper usage of "equal".', true); }); it('throws when invalid property follows called method assertion', function () { err(function () { expect(42).equal(42).pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled overwritten method assertion', function () { err(function () { expect(42).tmpMethod.pizza; }, 'Invalid Chai property: tmpMethod.pizza. See docs for proper usage of "tmpMethod".', true); }); it('throws when invalid property follows called overwritten method assertion', function () { err(function () { expect(42).tmpMethod().pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled chainable method assertion', function () { err(function () { expect(42).a.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows called chainable method assertion', function () { err(function () { expect(42).a('number').pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled overwritten chainable method assertion', function () { err(function () { expect(42).tmpChainableMethod.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows called overwritten chainable method assertion', function () { err(function () { expect(42).tmpChainableMethod().pizza; }, 'Invalid Chai property: pizza', true); }); it('doesn\'t throw if invalid property is excluded via config', function () { expect(function () { expect(42).then; }).to.not.throw(); }); }); describe('length guard', function () { var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); if (!fnLengthDesc.configurable) return; it('doesn\'t throw when `.length` follows `.expect`', function () { expect(function () { expect('foo').length; }).to.not.throw(); }); it('doesn\'t throw when `.length` follows language chain', function () { expect(function () { expect('foo').to.length; }).to.not.throw(); }); it('doesn\'t throw when `.length` follows property assertion', function () { expect(function () { expect('foo').ok.length; }).to.not.throw(); }); it('doesn\'t throw when `.length` follows overwritten property assertion', function () { expect(function () { expect('foo').tmpProperty.length; }).to.not.throw(); }); it('throws when `.length` follows uncalled method assertion', function () { err(function () { expect('foo').equal.length; }, 'Invalid Chai property: equal.length. See docs for proper usage of "equal".', true); }); it('doesn\'t throw when `.length` follows called method assertion', function () { expect(function () { expect('foo').equal('foo').length; }).to.not.throw(); }); it('throws when `.length` follows uncalled overwritten method assertion', function () { err(function () { expect('foo').tmpMethod.length; }, 'Invalid Chai property: tmpMethod.length. See docs for proper usage of "tmpMethod".', true); }); it('doesn\'t throw when `.length` follows called overwritten method assertion', function () { expect(function () { expect('foo').tmpMethod().length; }).to.not.throw(); }); it('throws when `.length` follows uncalled chainable method assertion', function () { err(function () { expect('foo').a.length; }, 'Invalid Chai property: a.length. Due to a compatibility issue, "length" cannot directly follow "a". Use "a.lengthOf" instead.', true); }); it('doesn\'t throw when `.length` follows called chainable method assertion', function () { expect(function () { expect('foo').a('string').length; }).to.not.throw(); }); it('throws when `.length` follows uncalled overwritten chainable method assertion', function () { err(function () { expect('foo').tmpChainableMethod.length; }, 'Invalid Chai property: tmpChainableMethod.length. Due to a compatibility issue, "length" cannot directly follow "tmpChainableMethod". Use "tmpChainableMethod.lengthOf" instead.', true); }); it('doesn\'t throw when `.length` follows called overwritten chainable method assertion', function () { expect(function () { expect('foo').tmpChainableMethod().length; }).to.not.throw(); }); }); }); it('no-op chains', function() { function test(chain) { // tests that chain exists expect(expect(1)[chain]).not.undefined; // tests methods expect(1)[chain].equal(1); // tests properties that assert expect(false)[chain].false; // tests not expect(false)[chain].not.true; // tests chainable methods expect([1, 2, 3])[chain].contains(1); } [ 'to', 'be', 'been', 'is' , 'and', 'has', 'have', 'with' , 'that', 'which', 'at', 'of' , 'same', 'but', 'does', 'still', 'also' ].forEach(test); }); describe("fail", function() { it('should accept a message as the 3rd argument', function () { err(function() { expect.fail(0, 1, 'this has failed'); }, /this has failed/); }); it('should accept a message as the only argument', function () { err(function() { expect.fail('this has failed'); }, /this has failed/); }); it('should produce a default message when called without any arguments', function () { err(function() { expect.fail(); }, /expect\.fail()/); }); }); it('true', function(){ expect(true).to.be.true; expect(false).to.not.be.true; expect(1).to.not.be.true; err(function(){ expect('test', 'blah').to.be.true; }, "blah: expected 'test' to be true") }); it('ok', function(){ expect(true).to.be.ok; expect(false).to.not.be.ok; expect(1).to.be.ok; expect(0).to.not.be.ok; err(function(){ expect('', 'blah').to.be.ok; }, "blah: expected '' to be truthy"); err(function(){ expect('test').to.not.be.ok; }, "expected 'test' to be falsy"); }); it('false', function(){ expect(false).to.be.false; expect(true).to.not.be.false; expect(0).to.not.be.false; err(function(){ expect('', 'blah').to.be.false; }, "blah: expected '' to be false") }); it('null', function(){ expect(null).to.be.null; expect(false).to.not.be.null; err(function(){ expect('', 'blah').to.be.null; }, "blah: expected '' to be null") }); it('undefined', function(){ expect(undefined).to.be.undefined; expect(null).to.not.be.undefined; err(function(){ expect('', 'blah').to.be.undefined; }, "blah: expected '' to be undefined") }); it('exist', function(){ var foo = 'bar' , bar; expect(foo).to.exist; expect(foo).to.exists; expect(bar).to.not.exist; expect(bar).to.not.exists; expect(0).to.exist; expect(false).to.exist; expect('').to.exist; err(function () { expect(bar, 'blah').to.exist; }, "blah: expected undefined to exist"); err(function () { expect(foo).to.not.exist(foo); }, "expected 'bar' to not exist"); }); it('arguments', function(){ var args = (function(){ return arguments; })(1,2,3); expect(args).to.be.arguments; expect([]).to.not.be.arguments; expect(args).to.be.an('arguments').and.be.arguments; expect([]).to.be.an('array').and.not.be.Arguments; err(function () { expect([], 'blah').to.be.arguments; }, "blah: expected [] to be arguments but got Array"); }); it('.equal()', function(){ var foo; expect(undefined).to.equal(foo); err(function(){ expect(undefined).to.equal(null); }, "expected undefined to equal null") }); it('typeof', function(){ expect('test').to.be.a('string'); err(function(){ expect('test').to.not.be.a('string'); }, "expected 'test' not to be a string"); (function () { expect(arguments).to.be.an('arguments'); })(1, 2); expect(5).to.be.a('number'); expect(new Number(1)).to.be.a('number'); expect(Number(1)).to.be.a('number'); expect(true).to.be.a('boolean'); expect(new Array()).to.be.a('array'); expect(new Object()).to.be.a('object'); expect({}).to.be.a('object'); expect([]).to.be.a('array'); expect(function() {}).to.be.a('function'); expect(null).to.be.a('null'); expect(Symbol()).to.be.a('symbol'); err(function(){ expect(5).to.not.be.a('number', 'blah'); }, "blah: expected 5 not to be a number"); err(function(){ expect(5, 'blah').to.not.be.a('number'); }, "blah: expected 5 not to be a number"); }); it('callable', function() { expect(function() {}).to.be.callable; expect(async function() {}).to.be.callable; expect(function*() {}).to.be.callable; expect(async function*() {}).to.be.callable; expect('foobar').to.not.be.callable; err(function(){ expect('foobar', 'blah').to.be.callable; }, "blah: expected 'foobar' to be a callable function"); err(function(){ expect(function() {}, 'blah').to.not.be.callable; }, "blah: expected [Function] not to be a callable function"); }); it('function', function() { expect(function() {}).to.be.a('function'); expect(async function() {}).to.be.a('function'); expect(function*() {}).to.be.a('function'); expect(async function*() {}).to.be.a('function'); expect('foobar').to.not.be.a('function'); err(function(){ expect('foobar').to.be.a('function', 'blah'); }, "blah: expected 'foobar' to be a function"); err(function(){ expect(function() {}).to.not.be.a('function', 'blah'); }, "blah: expected [Function] not to be a function"); err(function(){ expect(function() {}, 'blah').to.not.be.a('function'); }, "blah: expected [Function] not to be a function"); }) it('asyncFunction', function() { expect(async function() {}).to.be.a('AsyncFunction'); expect(async function*() {}).to.be.a('AsyncFunction'); err(function(){ expect('foobar').to.be.a('asyncfunction', 'blah'); }, "blah: expected 'foobar' to be an asyncfunction"); err(function(){ expect(async function() {}).to.not.be.a('asyncfunction', 'blah'); }, "blah: expected [AsyncFunction] not to be an asyncfunction"); err(function(){ expect(async function() {}, 'blah').to.not.be.a('asyncfunction'); }, "blah: expected [AsyncFunction] not to be an asyncfunction"); }) it('generatorFunction', function() { expect(function*() {}).to.be.a('generatorFunction'); expect(async function*() {}).to.be.a('generatorFunction'); err(function(){ expect('foobar').to.be.a('generatorfunction', 'blah'); }, "blah: expected 'foobar' to be a generatorfunction"); err(function(){ expect(function*() {}).to.not.be.a('generatorfunction', 'blah'); }, "blah: expected [GeneratorFunction] not to be a generatorfunction"); err(function(){ expect(function*() {}, 'blah').to.not.be.a('generatorfunction'); }, "blah: expected [GeneratorFunction] not to be a generatorfunction"); }) it('asyncGeneratorFunction', function() { expect(async function*() {}).to.be.a('asyncGeneratorFunction'); err(function(){ expect(async function() {}, 'blah').to.be.a('asyncgeneratorfunction'); }, "blah: expected [AsyncFunction] to be an asyncgeneratorfunction"); err(function(){ expect(async function*() {}, 'blah').to.not.be.a('asyncgeneratorfunction'); }, "blah: expected [AsyncGeneratorFunction] not to be an asyncgeneratorfunction"); }) it('instanceof', function(){ function Foo(){} expect(new Foo()).to.be.an.instanceof(Foo); // Normally, `instanceof` requires that the constructor be a function or an // object with a callable `@@hasInstance`. But in some older browsers such // as IE11, `instanceof` also accepts DOM-related interfaces such as // `HTMLElement`, despite being non-callable objects in those browsers. // See: https://github.com/chaijs/chai/issues/1000. if (typeof document !== 'undefined' && typeof document.createElement !== 'undefined' && typeof HTMLElement !== 'undefined') { expect(document.createElement('div')).to.be.an.instanceof(HTMLElement); } err(function(){ expect(new Foo()).to.an.instanceof(1, 'blah'); }, "blah: The instanceof assertion needs a constructor but Number was given."); err(function(){ expect(new Foo(), 'blah').to.an.instanceof(1); }, "blah: The instanceof assertion needs a constructor but Number was given."); err(function(){ expect(new Foo()).to.an.instanceof('batman'); }, "The instanceof assertion needs a constructor but String was given."); err(function(){ expect(new Foo()).to.an.instanceof({}); }, "The instanceof assertion needs a constructor but Object was given."); err(function(){ expect(new Foo()).to.an.instanceof(true); }, "The instanceof assertion needs a constructor but Boolean was given."); err(function(){ expect(new Foo()).to.an.instanceof(null); }, "The instanceof assertion needs a constructor but null was given."); err(function(){ expect(new Foo()).to.an.instanceof(undefined); }, "The instanceof assertion needs a constructor but undefined was given."); err(function(){ function Thing(){}; var t = new Thing(); Thing.prototype = 1337; expect(t).to.an.instanceof(Thing); }, 'The instanceof assertion needs a constructor but Function was given.', true) err(function(){ expect(new Foo()).to.an.instanceof(Symbol()); }, "The instanceof assertion needs a constructor but Symbol was given."); err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 3; }; expect(fakeInstanceB).to.be.an.instanceof(FakeConstructor); }, 'expected 4 to be an instance of an unnamed constructor') err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 4; }; expect(fakeInstanceB).to.not.be.an.instanceof(FakeConstructor); }, 'expected 4 to not be an instance of an unnamed constructor') err(function(){ expect(3).to.an.instanceof(Foo, 'blah'); }, "blah: expected 3 to be an instance of Foo"); err(function(){ expect(3, 'blah').to.an.instanceof(Foo); }, "blah: expected 3 to be an instance of Foo"); }); it('within(start, finish)', function(){ expect(5).to.be.within(5, 10); expect(5).to.be.within(3, 6); expect(5).to.be.within(3, 5); expect(5).to.not.be.within(1, 3); expect('foo').to.have.length.within(2, 4); expect('foo').to.have.lengthOf.within(2, 4); expect([ 1, 2, 3 ]).to.have.length.within(2, 4); expect([ 1, 2, 3 ]).to.have.lengthOf.within(2, 4); expect(5n).to.be.within(5, 10); expect(5).to.be.within(3n, 6); expect(5).to.be.within(3, 5n); err(function(){ expect(5).to.not.be.within(4, 6, 'blah'); }, "blah: expected 5 to not be within 4..6"); err(function(){ expect(5, 'blah').to.not.be.within(4, 6); }, "blah: expected 5 to not be within 4..6"); err(function(){ expect(10).to.be.within(50, 100, 'blah'); }, "blah: expected 10 to be within 50..100"); err(function () { expect('foo').to.have.length.within(5, 7, 'blah'); }, "blah: expected \'foo\' to have a length within 5..7"); err(function () { expect('foo', 'blah').to.have.length.within(5, 7); }, "blah: expected \'foo\' to have a length within 5..7"); err(function () { expect('foo').to.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected \'foo\' to have a length within 5..7"); err(function () { expect([ 1, 2, 3 ]).to.have.length.within(5, 7, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length within 5..7"); err(function () { expect([ 1, 2, 3 ]).to.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length within 5..7"); err(function () { expect(null).to.be.within(0, 1, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(null, 'blah').to.be.within(0, 1); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.within(null, 1, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { expect(1, 'blah').to.be.within(null, 1); }, "blah: the arguments to within must be numbers"); err(function () { expect(1).to.be.within(0, null, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { expect(1, 'blah').to.be.within(0, null); }, "blah: the arguments to within must be numbers"); err(function () { expect(null).to.not.be.within(0, 1, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.not.be.within(null, 1, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { expect(1).to.not.be.within(0, null, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { expect(1).to.have.length.within(5, 7, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1, 'blah').to.have.length.within(5, 7); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1).to.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected 1 to have property 'length'"); expect(new Map()).to.have.length.within(0, 0); expect(new Map()).to.have.lengthOf.within(0, 0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length.within(2, 4); expect(map).to.have.lengthOf.within(2, 4); err(function () { expect(map).to.have.length.within(5, 7, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size within 5..7"); err(function () { expect(map).to.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size within 5..7"); expect(new Set()).to.have.length.within(0, 0); expect(new Set()).to.have.lengthOf.within(0, 0); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length.within(2, 4); expect(set).to.have.lengthOf.within(2, 4); err(function () { expect(set).to.have.length.within(5, 7, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size within 5..7"); err(function () { expect(set).to.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size within 5..7"); }); it('within(start, finish) (dates)', function(){ var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); var nowISO = now.toISOString(); var beforeISO = oneSecondAgo.toISOString(); var afterISO = oneSecondAfter.toISOString(); expect(now).to.be.within(oneSecondAgo, oneSecondAfter); expect(now).to.be.within(now, oneSecondAfter); expect(now).to.be.within(now, now); expect(oneSecondAgo).to.not.be.within(now, oneSecondAfter); err(function(){ expect(now).to.not.be.within(now, oneSecondAfter, 'blah'); }, "blah: expected " + nowISO + " to not be within " + nowISO + ".." + afterISO); err(function(){ expect(now, 'blah').to.not.be.within(oneSecondAgo, oneSecondAfter); }, "blah: expected " + nowISO + " to not be within " + beforeISO + ".." + afterISO); err(function () { expect(now).to.have.length.within(5, 7, 'blah'); }, "blah: expected " + nowISO + " to have property 'length'"); err(function () { expect('foo').to.have.lengthOf.within(now, 7, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { expect(now).to.be.within(now, 1, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { expect(now).to.be.within(null, now, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { expect(now).to.be.within(now, undefined, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { expect(now, 'blah').to.be.within(1, now); }, "blah: the arguments to within must be dates"); err(function () { expect(now, 'blah').to.be.within(now, 1); }, "blah: the arguments to within must be dates"); err(function () { expect(null).to.not.be.within(now, oneSecondAfter, 'blah'); }, "blah: expected null to be a number or a date"); }); it('above(n)', function(){ expect(5).to.be.above(2); expect(5).to.be.greaterThan(2); expect(5).to.not.be.above(5); expect(5).to.not.be.above(6); expect('foo').to.have.length.above(2); expect('foo').to.have.lengthOf.above(2); expect([ 1, 2, 3 ]).to.have.length.above(2); expect([ 1, 2, 3 ]).to.have.lengthOf.above(2); err(function(){ expect(5).to.be.above(6, 'blah'); }, "blah: expected 5 to be above 6"); err(function(){ expect(5, 'blah').to.be.above(6); }, "blah: expected 5 to be above 6"); err(function(){ expect(10).to.not.be.above(6, 'blah'); }, "blah: expected 10 to be at most 6"); err(function () { expect('foo').to.have.length.above(4, 'blah'); }, "blah: expected \'foo\' to have a length above 4 but got 3"); err(function () { expect('foo', 'blah').to.have.length.above(4); }, "blah: expected \'foo\' to have a length above 4 but got 3"); err(function () { expect('foo').to.have.lengthOf.above(4, 'blah'); }, "blah: expected \'foo\' to have a length above 4 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.length.above(4, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length above 4 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.lengthOf.above(4, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length above 4 but got 3"); err(function () { expect(null).to.be.above(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(null, 'blah').to.be.above(0); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.above(null, 'blah'); }, "blah: the argument to above must be a number"); err(function () { expect(1, 'blah').to.be.above(null); }, "blah: the argument to above must be a number"); err(function () { expect(null).to.not.be.above(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.not.be.above(null, 'blah'); }, "blah: the argument to above must be a number"); err(function () { expect(1).to.have.length.above(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1, 'blah').to.have.length.above(0); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1).to.have.lengthOf.above(0, 'blah'); }, "blah: expected 1 to have property 'length'"); expect(new Map()).to.have.length.above(-1); expect(new Map()).to.have.lengthOf.above(-1); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length.above(2); expect(map).to.have.lengthOf.above(2); err(function () { expect(map).to.have.length.above(5, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size above 5 but got 3"); err(function () { expect(map).to.have.lengthOf.above(5, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size above 5 but got 3"); expect(new Set()).to.have.length.above(-1); expect(new Set()).to.have.lengthOf.above(-1); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length.above(2); expect(set).to.have.lengthOf.above(2); err(function () { expect(set).to.have.length.above(5, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size above 5 but got 3"); err(function () { expect(set).to.have.lengthOf.above(5, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size above 5 but got 3"); }); it('above(n) (dates)', function(){ var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); expect(now).to.be.above(oneSecondAgo); expect(now).to.be.greaterThan(oneSecondAgo); expect(now).to.not.be.above(now); expect(now).to.not.be.above(oneSecondAfter); err(function(){ expect(now).to.be.above(oneSecondAfter, 'blah'); }, "blah: expected " + now.toISOString() + " to be above " + oneSecondAfter.toISOString()); err(function(){ expect(10).to.not.be.above(6, 'blah'); }, "blah: expected 10 to be at most 6"); err(function () { expect(now).to.have.length.above(4, 'blah'); }, "blah: expected " + now.toISOString() + " to have property 'length'"); err(function () { expect([ 1, 2, 3 ]).to.have.length.above(now, 'blah'); }, "blah: the argument to above must be a number"); err(function () { expect(null).to.be.above(now, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(now).to.be.above(null, 'blah'); }, "blah: the argument to above must be a date"); err(function () { expect(null).to.have.length.above(0, 'blah'); }, "blah: Target cannot be null or undefined."); }); it('least(n)', function(){ expect(5).to.be.at.least(2); expect(5).to.be.at.least(5); expect(5).to.not.be.at.least(6); expect('foo').to.have.length.of.at.least(2); expect('foo').to.have.lengthOf.at.least(2); expect([ 1, 2, 3 ]).to.have.length.of.at.least(2); expect([ 1, 2, 3 ]).to.have.lengthOf.at.least(2); err(function(){ expect(5).to.be.at.least(6, 'blah'); }, "blah: expected 5 to be at least 6"); err(function(){ expect(5, 'blah').to.be.at.least(6); }, "blah: expected 5 to be at least 6"); err(function(){ expect(10).to.not.be.at.least(6, 'blah'); }, "blah: expected 10 to be below 6"); err(function () { expect('foo').to.have.length.of.at.least(4, 'blah'); }, "blah: expected \'foo\' to have a length at least 4 but got 3"); err(function () { expect('foo', 'blah').to.have.length.of.at.least(4); }, "blah: expected \'foo\' to have a length at least 4 but got 3"); err(function () { expect('foo').to.have.lengthOf.at.least(4, 'blah'); }, "blah: expected \'foo\' to have a length at least 4 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.length.of.at.least(4, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length at least 4 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.lengthOf.at.least(4, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length at least 4 but got 3"); err(function () { expect([ 1, 2, 3, 4 ]).to.not.have.length.of.at.least(4, 'blah'); }, "blah: expected [ 1, 2, 3, 4 ] to have a length below 4"); err(function () { expect([ 1, 2, 3, 4 ]).to.not.have.lengthOf.at.least(4, 'blah'); }, "blah: expected [ 1, 2, 3, 4 ] to have a length below 4"); err(function () { expect(null).to.be.at.least(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(null, 'blah').to.be.at.least(0); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.at.least(null, 'blah'); }, "blah: the argument to least must be a number"); err(function () { expect(1, 'blah').to.be.at.least(null); }, "blah: the argument to least must be a number"); err(function () { expect(null).to.not.be.at.least(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.not.be.at.least(null, 'blah'); }, "blah: the argument to least must be a number"); err(function () { expect(1).to.have.length.at.least(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1, 'blah').to.have.length.at.least(0); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1).to.have.lengthOf.at.least(0, 'blah'); }, "blah: expected 1 to have property 'length'"); expect(new Map()).to.have.length.of.at.least(0); expect(new Map()).to.have.lengthOf.at.least(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length.of.at.least(3); expect(map).to.have.lengthOf.at.least(3); err(function () { expect(map).to.have.length.of.at.least(4, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at least 4 but got 3"); err(function () { expect(map).to.have.lengthOf.at.least(4, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at least 4 but got 3"); expect(new Set()).to.have.length.of.at.least(0); expect(new Set()).to.have.lengthOf.at.least(0); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length.of.at.least(3); expect(set).to.have.lengthOf.at.least(3); err(function () { expect(set).to.have.length.of.at.least(4, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at least 4 but got 3"); err(function () { expect(set).to.have.lengthOf.at.least(4, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at least 4 but got 3"); }); it('below(n)', function(){ expect(2).to.be.below(5); expect(2).to.be.lessThan(5); expect(2).to.not.be.below(2); expect(2).to.not.be.below(1); expect('foo').to.have.length.below(4); expect('foo').to.have.lengthOf.below(4); expect([ 1, 2, 3 ]).to.have.length.below(4); expect([ 1, 2, 3 ]).to.have.lengthOf.below(4); err(function(){ expect(6).to.be.below(5, 'blah'); }, "blah: expected 6 to be below 5"); err(function(){ expect(6, 'blah').to.be.below(5); }, "blah: expected 6 to be below 5"); err(function(){ expect(6).to.not.be.below(10, 'blah'); }, "blah: expected 6 to be at least 10"); err(function () { expect('foo').to.have.length.below(2, 'blah'); }, "blah: expected \'foo\' to have a length below 2 but got 3"); err(function () { expect('foo', 'blah').to.have.length.below(2); }, "blah: expected \'foo\' to have a length below 2 but got 3"); err(function () { expect('foo').to.have.lengthOf.below(2, 'blah'); }, "blah: expected \'foo\' to have a length below 2 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.length.below(2, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length below 2 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.lengthOf.below(2, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length below 2 but got 3"); err(function () { expect(null).to.be.below(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(null, 'blah').to.be.below(0); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.below(null, 'blah'); }, "blah: the argument to below must be a number"); err(function () { expect(1, 'blah').to.be.below(null); }, "blah: the argument to below must be a number"); err(function () { expect(null).to.not.be.below(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.not.be.below(null, 'blah'); }, "blah: the argument to below must be a number"); err(function () { expect(1).to.have.length.below(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1, 'blah').to.have.length.below(0); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1).to.have.lengthOf.below(0, 'blah'); }, "blah: expected 1 to have property 'length'"); expect(new Map()).to.have.length.below(1); expect(new Map()).to.have.lengthOf.below(1); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length.below(4); expect(map).to.have.lengthOf.below(4); err(function () { expect(map).to.have.length.below(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size below 2 but got 3"); err(function () { expect(map).to.have.lengthOf.below(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size below 2 but got 3"); expect(new Set()).to.have.length.below(1); expect(new Set()).to.have.lengthOf.below(1); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length.below(4); expect(set).to.have.lengthOf.below(4); err(function () { expect(set).to.have.length.below(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size below 2 but got 3"); err(function () { expect(set).to.have.lengthOf.below(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size below 2 but got 3"); }); it('below(n) (dates)', function(){ var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); expect(now).to.be.below(oneSecondAfter); expect(oneSecondAgo).to.be.lessThan(now); expect(now).to.not.be.below(oneSecondAgo); expect(oneSecondAfter).to.not.be.below(oneSecondAgo); err(function(){ expect(now).to.be.below(oneSecondAgo, 'blah'); }, "blah: expected " + now.toISOString() + " to be below " + oneSecondAgo.toISOString()); err(function(){ expect(now).to.not.be.below(oneSecondAfter, 'blah'); }, "blah: expected " + now.toISOString() + " to be at least " + oneSecondAfter.toISOString()); err(function () { expect('foo').to.have.length.below(2, 'blah'); }, "blah: expected \'foo\' to have a length below 2 but got 3"); err(function () { expect(null).to.be.below(now, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.below(null, 'blah'); }, "blah: the argument to below must be a number"); err(function () { expect(now).to.not.be.below(null, 'blah'); }, "blah: the argument to below must be a date"); err(function () { expect(now).to.have.length.below(0, 'blah'); }, "blah: expected " + now.toISOString() + " to have property 'length'"); err(function () { expect('asdasd').to.have.length.below(now, 'blah'); }, "blah: the argument to below must be a number"); }); it('most(n)', function(){ expect(2).to.be.at.most(5); expect(2).to.be.at.most(2); expect(2).to.not.be.at.most(1); expect('foo').to.have.length.of.at.most(4); expect('foo').to.have.lengthOf.at.most(4); expect([ 1, 2, 3 ]).to.have.length.of.at.most(4); expect([ 1, 2, 3 ]).to.have.lengthOf.at.most(4); err(function(){ expect(6).to.be.at.most(5, 'blah'); }, "blah: expected 6 to be at most 5"); err(function(){ expect(6, 'blah').to.be.at.most(5); }, "blah: expected 6 to be at most 5"); err(function(){ expect(6).to.not.be.at.most(10, 'blah'); }, "blah: expected 6 to be above 10"); err(function () { expect('foo').to.have.length.of.at.most(2, 'blah'); }, "blah: expected \'foo\' to have a length at most 2 but got 3"); err(function () { expect('foo', 'blah').to.have.length.of.at.most(2); }, "blah: expected \'foo\' to have a length at most 2 but got 3"); err(function () { expect('foo').to.have.lengthOf.at.most(2, 'blah'); }, "blah: expected \'foo\' to have a length at most 2 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.length.of.at.most(2, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length at most 2 but got 3"); err(function () { expect([ 1, 2, 3 ]).to.have.lengthOf.at.most(2, 'blah'); }, "blah: expected [ 1, 2, 3 ] to have a length at most 2 but got 3"); err(function () { expect([ 1, 2 ]).to.not.have.length.of.at.most(2, 'blah'); }, "blah: expected [ 1, 2 ] to have a length above 2"); err(function () { expect([ 1, 2 ]).to.not.have.lengthOf.at.most(2, 'blah'); }, "blah: expected [ 1, 2 ] to have a length above 2"); err(function () { expect(null).to.be.at.most(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(null, 'blah').to.be.at.most(0); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.be.at.most(null, 'blah'); }, "blah: the argument to most must be a number"); err(function () { expect(1, 'blah').to.be.at.most(null); }, "blah: the argument to most must be a number"); err(function () { expect(null).to.not.be.at.most(0, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(1).to.not.be.at.most(null, 'blah'); }, "blah: the argument to most must be a number"); err(function () { expect(1).to.have.length.of.at.most(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1, 'blah').to.have.length.of.at.most(0); }, "blah: expected 1 to have property 'length'"); err(function () { expect(1).to.have.lengthOf.at.most(0, 'blah'); }, "blah: expected 1 to have property 'length'"); expect(new Map()).to.have.length.of.at.most(0); expect(new Map()).to.have.lengthOf.at.most(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length.of.at.most(3); expect(map).to.have.lengthOf.at.most(3); err(function () { expect(map).to.have.length.of.at.most(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at most 2 but got 3"); err(function () { expect(map).to.have.lengthOf.at.most(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at most 2 but got 3"); expect(new Set()).to.have.length.of.at.most(0); expect(new Set()).to.have.lengthOf.at.most(0); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length.of.at.most(3); expect(set).to.have.lengthOf.at.most(3); err(function () { expect(set).to.have.length.of.at.most(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at most 2 but got 3"); err(function () { expect(set).to.have.lengthOf.at.most(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at most 2 but got 3"); }); it('most(n) (dates)', function(){ var now = new Date(); var oneSecondBefore = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); var nowISO = now.toISOString(); var beforeISO = oneSecondBefore.toISOString(); var afterISO = oneSecondAfter.toISOString(); expect(now).to.be.at.most(oneSecondAfter); expect(now).to.be.at.most(now); expect(now).to.not.be.at.most(oneSecondBefore); err(function(){ expect(now).to.be.at.most(oneSecondBefore, 'blah'); }, "blah: expected " + nowISO + " to be at most " + beforeISO); err(function(){ expect(now).to.not.be.at.most(now, 'blah'); }, "blah: expected " + nowISO + " to be above " + nowISO); err(function () { expect(now).to.have.length.of.at.most(2, 'blah'); }, "blah: expected " + nowISO + " to have property 'length'"); err(function () { expect('foo', 'blah').to.have.length.of.at.most(now); }, "blah: the argument to most must be a number"); err(function () { expect([ 1, 2, 3 ]).to.not.have.length.of.at.most(now, 'blah'); }, "blah: the argument to most must be a number"); err(function () { expect(null).to.be.at.most(now, 'blah'); }, "blah: expected null to be a number or a date"); err(function () { expect(now, 'blah').to.be.at.most(null); }, "blah: the argument to most must be a date"); err(function () { expect(1).to.be.at.most(now, 'blah'); }, "blah: the argument to most must be a number"); err(function () { expect(now, 'blah').to.be.at.most(1); }, "blah: the argument to most must be a date"); err(function () { expect(now).to.not.be.at.most(undefined, 'blah'); }, "blah: the argument to most must be a date"); }); it('match(regexp)', function(){ expect('foobar').to.match(/^foo/) expect('foobar').to.matches(/^foo/) expect('foobar').to.not.match(/^bar/) err(function(){ expect('foobar').to.match(/^bar/i, 'blah') }, "blah: expected 'foobar' to match /^bar/i"); err(function(){ expect('foobar', 'blah').to.match(/^bar/i) }, "blah: expected 'foobar' to match /^bar/i"); err(function(){ expect('foobar').to.matches(/^bar/i, 'blah') }, "blah: expected 'foobar' to match /^bar/i"); err(function(){ expect('foobar').to.not.match(/^foo/i, 'blah') }, "blah: expected 'foobar' not to match /^foo/i"); }); it('lengthOf(n)', function(){ expect('test').to.have.length(4); expect('test').to.have.lengthOf(4); expect('test').to.not.have.length(3); expect('test').to.not.have.lengthOf(3); expect([1,2,3]).to.have.length(3); expect([1,2,3]).to.have.lengthOf(3); err(function(){ expect(4).to.have.length(3, 'blah'); }, 'blah: expected 4 to have property \'length\''); err(function(){ expect(4, 'blah').to.have.length(3); }, 'blah: expected 4 to have property \'length\''); err(function(){ expect(4).to.have.lengthOf(3, 'blah'); }, 'blah: expected 4 to have property \'length\''); err(function(){ expect('asd').to.not.have.length(3, 'blah'); }, "blah: expected 'asd' to not have a length of 3"); err(function(){ expect('asd').to.not.have.lengthOf(3, 'blah'); }, "blah: expected 'asd' to not have a length of 3"); expect(new Map()).to.have.length(0); expect(new Map()).to.have.lengthOf(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); expect(map).to.have.length(3); expect(map).to.have.lengthOf(3); err(function(){ expect(map).to.not.have.length(3, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to not have a size of 3"); err(function(){ expect(map).to.not.have.lengthOf(3, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to not have a size of 3"); expect(new Set()).to.have.length(0); expect(new Set()).to.have.lengthOf(0); var set = new Set(); set.add(1); set.add(2); set.add(3); expect(set).to.have.length(3); expect(set).to.have.lengthOf(3); err(function(){ expect(set).to.not.have.length(3, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to not have a size of 3"); err(function(){ expect(set).to.not.have.lengthOf(3, 'blah');; }, "blah: expected Set{ 1, 2, 3 } to not have a size of 3"); }); it('eql(val)', function(){ expect('test').to.eql('test'); expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); expect(1).to.eql(1); expect('4').to.not.eql(4); var sym = Symbol(); expect(sym).to.eql(sym); err(function(){ expect(4).to.eql(3, 'blah'); }, 'blah: expected 4 to deeply equal 3'); }); it('Buffer eql()', function () { if (typeof Buffer === 'undefined') return; expect(Buffer.from([ 1 ])).to.eql(Buffer.from([ 1 ])); err(function () { expect(Buffer.from([ 0 ])).to.eql(Buffer.from([ 1 ])); }, 'expected Buffer[ 0 ] to deeply equal Buffer[ 1 ]'); }); it('equal(val)', function(){ expect('test').to.equal('test'); expect(1).to.equal(1); var sym = Symbol(); expect(sym).to.equal(sym); err(function(){ expect(4).to.equal(3, 'blah'); }, 'blah: expected 4 to equal 3'); err(function(){ expect(4, 'blah').to.equal(3); }, 'blah: expected 4 to equal 3'); err(function(){ expect('4').to.equal(4, 'blah'); }, "blah: expected '4' to equal 4"); }); it('deep.equal(val)', function(){ expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); expect({ foo: 'bar' }).not.to.deep.equal({ foo: 'baz' }); err(function(){ expect({foo: 'bar'}).to.deep.equal({foo: 'baz'}, 'blah'); }, "blah: expected { foo: 'bar' } to deeply equal { foo: 'baz' }"); err(function(){ expect({foo: 'bar'}, 'blah').to.deep.equal({foo: 'baz'}); }, "blah: expected { foo: 'bar' } to deeply equal { foo: 'baz' }"); err(function(){ expect({foo: 'bar'}).to.not.deep.equal({foo: 'bar'}, 'blah'); }, "blah: expected { foo: 'bar' } to not deeply equal { foo: 'bar' }"); err(function(){ expect({foo: 'bar'}, 'blah').to.not.deep.equal({foo: 'bar'}); }, "blah: expected { foo: 'bar' } to not deeply equal { foo: 'bar' }"); }); it('deep.equal(/regexp/)', function(){ expect(/a/).to.deep.equal(/a/); expect(/a/).not.to.deep.equal(/b/); expect(/a/).not.to.deep.equal({}); expect(/a/g).to.deep.equal(/a/g); expect(/a/g).not.to.deep.equal(/b/g); expect(/a/i).to.deep.equal(/a/i); expect(/a/i).not.to.deep.equal(/b/i); expect(/a/m).to.deep.equal(/a/m); expect(/a/m).not.to.deep.equal(/b/m); }); it('deep.equal(Date)', function(){ var a = new Date(1, 2, 3) , b = new Date(4, 5, 6); expect(a).to.deep.equal(a); expect(a).not.to.deep.equal(b); expect(a).not.to.deep.equal({}); }); it('deep.equal(Symbol)', function () { var symb = Symbol('a'); var a = { [symb]: 'b' } , b = { [symb]: 'b' }; expect(a).to.deep.equal(a); expect(a).to.deep.equal(b); var symb2 = Symbol('c'); var c = { [symb]: { [symb2]: 'c' } } , d = { [symb]: { [symb2]: 'b' } }; expect(c).to.deep.equal(c); expect(d).to.not.deep.equal(c); var symb3 = Symbol('d'); var e = { [symb]: { [symb3]: 'b' } }; expect(d).to.not.deep.equal(e); var f = { [symb]: { [symb3]: 'b' } }; expect(e).to.deep.equal(f); }); it('empty', function(){ function FakeArgs() {}; FakeArgs.prototype.length = 0; expect('').to.be.empty; expect('foo').not.to.be.empty; expect([]).to.be.empty; expect(['foo']).not.to.be.empty; expect(new FakeArgs()).to.be.empty; expect({arguments: 0}).not.to.be.empty; expect({}).to.be.empty; expect({foo: 'bar'}).not.to.be.empty; err(function(){ expect(new WeakMap(), 'blah').not.to.be.empty; }, "blah: .empty was passed a weak collection"); err(function(){ expect(new WeakSet(), 'blah').not.to.be.empty; }, "blah: .empty was passed a weak collection"); expect(new Map()).to.be.empty; // Not using Map constructor args because not supported in IE 11. var map = new Map(); map.set('a', 1); expect(map).not.to.be.empty; err(function(){ expect(new Map()).not.to.be.empty; }, "expected Map{} not to be empty"); map = new Map(); map.key = 'val'; expect(map).to.be.empty; err(function(){ expect(map).not.to.be.empty; }, "expected Map{} not to be empty"); expect(new Set()).to.be.empty; // Not using Set constructor args because not supported in IE 11. var set = new Set(); set.add(1); expect(set).not.to.be.empty; err(function(){ expect(new Set()).not.to.be.empty; }, "expected Set{} not to be empty"); set = new Set(); set.key = 'val'; expect(set).to.be.empty; err(function(){ expect(set).not.to.be.empty; }, "expected Set{} not to be empty"); err(function(){ expect('', 'blah').not.to.be.empty; }, "blah: expected \'\' not to be empty"); err(function(){ expect('foo').to.be.empty; }, "expected \'foo\' to be empty"); err(function(){ expect([]).not.to.be.empty; }, "expected [] not to be empty"); err(function(){ expect(['foo']).to.be.empty; }, "expected [ \'foo\' ] to be empty"); err(function(){ expect(new FakeArgs()).not.to.be.empty; }, "expected FakeArgs{} not to be empty"); err(function(){ expect({arguments: 0}).to.be.empty; }, "expected { arguments: +0 } to be empty"); err(function(){ expect({}).not.to.be.empty; }, "expected {} not to be empty"); err(function(){ expect({foo: 'bar'}).to.be.empty; }, "expected { foo: \'bar\' } to be empty"); err(function(){ expect(null, 'blah').to.be.empty; }, "blah: .empty was passed non-string primitive null"); err(function(){ expect(undefined).to.be.empty; }, ".empty was passed non-string primitive undefined"); err(function(){ expect().to.be.empty; }, ".empty was passed non-string primitive undefined"); err(function(){ expect(null).to.not.be.empty; }, ".empty was passed non-string primitive null"); err(function(){ expect(undefined).to.not.be.empty; }, ".empty was passed non-string primitive undefined"); err(function(){ expect().to.not.be.empty; }, ".empty was passed non-string primitive undefined"); err(function(){ expect(0).to.be.empty; }, ".empty was passed non-string primitive +0"); err(function(){ expect(1).to.be.empty; }, ".empty was passed non-string primitive 1"); err(function(){ expect(true).to.be.empty; }, ".empty was passed non-string primitive true"); err(function(){ expect(false).to.be.empty; }, ".empty was passed non-string primitive false"); err(function(){ expect(Symbol()).to.be.empty; }, ".empty was passed non-string primitive Symbol()"); err(function(){ expect(Symbol.iterator).to.be.empty; }, ".empty was passed non-string primitive Symbol(Symbol.iterator)"); err(function(){ expect(function() {}, 'blah').to.be.empty; }, "blah: .empty was passed a function"); if (FakeArgs.name === 'FakeArgs') { err(function(){ expect(FakeArgs).to.be.empty; }, ".empty was passed a function FakeArgs"); } }); it('NaN', function() { expect(NaN).to.be.NaN; expect(undefined).not.to.be.NaN; expect(Infinity).not.to.be.NaN; expect('foo').not.to.be.NaN; expect({}).not.to.be.NaN; expect(4).not.to.be.NaN; expect([]).not.to.be.NaN; err(function(){ expect(NaN, 'blah').not.to.be.NaN; }, "blah: expected NaN not to be NaN"); err(function(){ expect(undefined).to.be.NaN; }, "expected undefined to be NaN"); err(function(){ expect(Infinity).to.be.NaN; }, "expected Infinity to be NaN"); err(function(){ expect('foo').to.be.NaN; }, "expected 'foo' to be NaN"); err(function(){ expect({}).to.be.NaN; }, "expected {} to be NaN"); err(function(){ expect(4).to.be.NaN; }, "expected 4 to be NaN"); err(function(){ expect([]).to.be.NaN; }, "expected [] to be NaN"); }); it('finite', function() { expect(4).to.be.finite; expect(-10).to.be.finite; err(function(){ expect(NaN, 'blah').to.be.finite; }, "blah: expected NaN to be a finite number"); err(function(){ expect(Infinity).to.be.finite; }, "expected Infinity to be a finite number"); err(function(){ expect('foo').to.be.finite; }, "expected \'foo\' to be a finite number"); err(function(){ expect([]).to.be.finite; }, "expected [] to be a finite number"); err(function(){ expect({}).to.be.finite; }, "expected {} to be a finite number"); }); it('property(name)', function(){ expect('test').to.have.property('length'); expect({a: 1}).to.have.property('toString'); expect(4).to.not.have.property('length'); expect({ 'foo.bar': 'baz' }) .to.have.property('foo.bar'); expect({ foo: { bar: 'baz' } }) .to.not.have.property('foo.bar'); // Properties with the value 'undefined' are still properties var obj = { foo: undefined }; Object.defineProperty(obj, 'bar', { get: function() { } }); expect(obj).to.have.property('foo'); expect(obj).to.have.property('bar'); expect({ 'foo.bar[]': 'baz'}) .to.have.property('foo.bar[]'); err(function(){ expect('asd').to.have.property('foo'); }, "expected 'asd' to have property 'foo'"); err(function(){ expect('asd', 'blah').to.have.property('foo'); }, "blah: expected 'asd' to have property 'foo'"); err(function(){ expect({ foo: { bar: 'baz' } }) .to.have.property('foo.bar'); }, "expected { foo: { bar: 'baz' } } to have property 'foo.bar'"); err(function() { expect({a: {b: 1}}).to.have.own.nested.property("a.b"); }, "The \"nested\" and \"own\" flags cannot be combined."); err(function() { expect({a: {b: 1}}, 'blah').to.have.own.nested.property("a.b"); }, "blah: The \"nested\" and \"own\" flags cannot be combined."); err(function () { expect(null, 'blah').to.have.property("a"); }, "blah: Target cannot be null or undefined."); err(function () { expect(undefined, 'blah').to.have.property("a"); }, "blah: Target cannot be null or undefined."); err(function () { expect({a:1}, 'blah').to.have.property(null) }, "blah: the argument to property must be a string, number, or symbol"); }); it('property(name, val)', function(){ expect('test').to.have.property('length', 4); expect('asd').to.have.property('constructor', String); expect({a: 1}).to.have.property('toString', Object.prototype.toString); expect('test').to.not.have.property('length', 3); expect('test').to.not.have.property('foo', 4); expect({a: {b: 1}}).to.not.have.property('a', {b: 1}); var deepObj = { green: { tea: 'matcha' } , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] }; expect(deepObj).to.have.nested.property('green.tea', 'matcha'); expect(deepObj).to.have.nested.property('teas[1]', 'matcha'); expect(deepObj).to.have.nested.property('teas[2].tea', 'konacha'); expect(deepObj).to.have.property('teas') .that.is.an('array') .with.nested.property('[2]') .that.deep.equals({tea: 'konacha'}); err(function(){ expect(deepObj).to.have.nested.property('teas[3]'); }, "expected { green: { tea: 'matcha' }, …(1) } to have nested property 'teas[3]'"); err(function(){ expect(deepObj).to.have.nested.property('teas[3]', 'bar'); }, "expected { green: { tea: 'matcha' }, …(1) } to have nested property 'teas[3]'"); err(function(){ expect(deepObj).to.have.nested.property('teas[3].tea', 'bar'); }, "expected { green: { tea: 'matcha' }, …(1) } to have nested property 'teas[3].tea'"); var arr = [ [ 'chai', 'matcha', 'konacha' ] , [ { tea: 'chai' } , { tea: 'matcha' } , { tea: 'konacha' } ] ]; expect(arr).to.have.nested.property('[0][1]', 'matcha'); expect(arr).to.have.nested.property('[1][2].tea', 'konacha'); err(function(){ expect(arr).to.have.nested.property('[2][1]'); }, "expected [ …(2) ] to have nested property '[2][1]'"); err(function(){ expect(arr).to.have.nested.property('[2][1]', 'none'); }, "expected [ …(2) ] to have nested property '[2][1]'"); err(function(){ expect(arr).to.have.nested.property('[0][3]', 'none'); }, "expected [ …(2) ] to have nested property '[0][3]'"); err(function(){ expect('asd').to.have.property('length', 4, 'blah'); }, "blah: expected 'asd' to have property 'length' of 4, but got 3"); err(function(){ expect('asd', 'blah').to.have.property('length', 4); }, "blah: expected 'asd' to have property 'length' of 4, but got 3"); err(function(){ expect('asd').to.not.have.property('length', 3, 'blah'); }, "blah: expected 'asd' to not have property 'length' of 3"); err(function(){ expect('asd').to.have.property('constructor', Number, 'blah'); }, "blah: expected 'asd' to have property 'constructor' of [Function Number], but got [Function String]"); err(function() { expect({a: {b: 1}}).to.have.own.nested.property("a.b", 1, 'blah'); }, "blah: The \"nested\" and \"own\" flags cannot be combined."); err(function() { expect({a: {b: 1}}, 'blah').to.have.own.nested.property("a.b", 1); }, "blah: The \"nested\" and \"own\" flags cannot be combined."); }); it('deep.property(name, val)', function () { var obj = {a: {b: 1}}; expect(obj).to.have.deep.property('a', {b: 1}); expect(obj).to.not.have.deep.property('a', {b: 7}); expect(obj).to.not.have.deep.property('a', {z: 1}); expect(obj).to.not.have.deep.property('z', {b: 1}); err(function () { expect(obj).to.have.deep.property('a', {b: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'a' of { b: 7 }, but got { b: 1 }"); err(function () { expect(obj).to.have.deep.property('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'z'"); err(function () { expect(obj).to.not.have.deep.property('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep property 'a' of { b: 1 }"); }); it('own.property(name)', function(){ expect('test').to.have.own.property('length'); expect('test').to.have.ownProperty('length'); expect('test').to.haveOwnProperty('length'); expect('test').to.not.have.own.property('iDontExist'); expect('test').to.not.have.ownProperty('iDontExist'); expect('test').to.not.haveOwnProperty('iDontExist'); expect({a: 1}).to.not.have.own.property('toString'); expect({a: 1}).to.not.have.ownProperty('toString'); expect({a: 1}).to.not.haveOwnProperty('toString'); expect({ length: 12 }).to.have.own.property('length'); expect({ length: 12 }).to.have.ownProperty('length'); expect({ length: 12 }).to.haveOwnProperty('length'); expect({ length: 12 }).to.not.have.own.property('iDontExist'); expect({ length: 12 }).to.not.have.ownProperty('iDontExist'); expect({ length: 12 }).to.not.haveOwnProperty('iDontExist'); // Chaining property's value expect('test').to.have.own.property('length').that.is.a('number'); expect('test').to.have.ownProperty('length').that.is.a('number'); expect('test').to.haveOwnProperty('length').that.is.a('number'); err(function(){ expect({ length: 12 }, 'blah').to.have.own.property('iDontExist'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }).to.not.have.own.property('length'); }, "expected { length: 12 } to not have own property 'length'"); err(function(){ expect({ length: 12 }, 'blah').to.have.ownProperty('iDontExist'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }).to.not.have.ownProperty('length'); }, "expected { length: 12 } to not have own property 'length'"); err(function(){ expect({ length: 12 }, 'blah').to.haveOwnProperty('iDontExist'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }).to.not.haveOwnProperty('length'); }, "expected { length: 12 } to not have own property 'length'"); }); it('own.property(name, value)', function(){ expect('test').to.have.own.property('length', 4); expect('test').to.have.ownProperty('length', 4); expect('test').to.haveOwnProperty('length', 4); expect('test').to.not.have.own.property('length', 1337); expect('test').to.not.have.ownProperty('length', 1337); expect('test').to.not.haveOwnProperty('length', 1337); expect({a: 1}).to.not.have.own.property('toString', Object.prototype.toString); expect({a: 1}).to.not.have.ownProperty('toString', Object.prototype.toString); expect({a: 1}).to.not.haveOwnProperty('toString', Object.prototype.toString); expect({a: {b: 1}}).to.not.have.own.property('a', {b: 1}); expect({a: {b: 1}}).to.not.have.ownProperty('a', {b: 1}); expect({a: {b: 1}}).to.not.haveOwnProperty('a', {b: 1}); expect({ length: 12 }).to.have.own.property('length', 12); expect({ length: 12 }).to.have.ownProperty('length', 12); expect({ length: 12 }).to.haveOwnProperty('length', 12); expect({ length: 12 }).to.not.have.own.property('length', 15); expect({ length: 12 }).to.not.have.ownProperty('length', 15); expect({ length: 12 }).to.not.haveOwnProperty('length', 15); // Chaining property's value expect('test').to.have.own.property('length', 4).that.is.a('number'); expect('test').to.have.ownProperty('length', 4).that.is.a('number'); expect('test').to.haveOwnProperty('length', 4).that.is.a('number'); var objNoProto = Object.create(null); objNoProto.a = 'a'; expect(objNoProto).to.have.own.property('a'); expect(objNoProto).to.have.ownProperty('a'); expect(objNoProto).to.haveOwnProperty('a'); err(function(){ expect({ length: 12 }).to.have.own.property('iDontExist', 12, 'blah'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }, 'blah').to.have.own.property('iDontExist', 12); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function() { expect({ length: 12 }).to.not.have.own.property('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { expect({ length: 12 }).to.have.own.property('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); err(function(){ expect({ length: 12 }).to.have.ownProperty('iDontExist', 12, 'blah'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }, 'blah').to.have.ownProperty('iDontExist', 12); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function() { expect({ length: 12 }).to.not.have.ownProperty('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { expect({ length: 12 }).to.have.ownProperty('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); err(function(){ expect({ length: 12 }).to.haveOwnProperty('iDontExist', 12, 'blah'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function(){ expect({ length: 12 }, 'blah').to.haveOwnProperty('iDontExist', 12); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function() { expect({ length: 12 }).to.not.haveOwnProperty('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { expect({ length: 12 }).to.haveOwnProperty('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); }); it('deep.own.property(name, val)', function () { var obj = {a: {b: 1}}; expect(obj).to.have.deep.own.property('a', {b: 1}); expect(obj).to.have.deep.ownProperty('a', {b: 1}); expect(obj).to.deep.haveOwnProperty('a', {b: 1}); expect(obj).to.not.have.deep.own.property('a', {z: 1}); expect(obj).to.not.have.deep.ownProperty('a', {z: 1}); expect(obj).to.not.deep.haveOwnProperty('a', {z: 1}); expect(obj).to.not.have.deep.own.property('a', {b: 7}); expect(obj).to.not.have.deep.ownProperty('a', {b: 7}); expect(obj).to.not.deep.haveOwnProperty('a', {b: 7}); expect(obj).to.not.have.deep.own.property('toString', Object.prototype.toString); expect(obj).to.not.have.deep.ownProperty('toString', Object.prototype.toString); expect(obj).to.not.deep.haveOwnProperty('toString', Object.prototype.toString); err(function () { expect(obj).to.have.deep.own.property('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { expect(obj).to.have.deep.own.property('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { expect(obj).to.not.have.deep.own.property('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); err(function () { expect(obj).to.have.deep.ownProperty('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { expect(obj).to.have.deep.ownProperty('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { expect(obj).to.not.have.deep.ownProperty('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); err(function () { expect(obj).to.deep.haveOwnProperty('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { expect(obj).to.deep.haveOwnProperty('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { expect(obj).to.not.deep.haveOwnProperty('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); }); it('nested.property(name)', function(){ expect({ 'foo.bar': 'baz'}) .to.not.have.nested.property('foo.bar'); expect({ foo: { bar: 'baz' } }) .to.have.nested.property('foo.bar'); expect({ 'foo': [1, 2, 3] }) .to.have.nested.property('foo[1]'); expect({ 'foo.bar[]': 'baz'}) .to.have.nested.property('foo\\.bar\\[\\]'); err(function(){ expect({ 'foo.bar': 'baz' }) .to.have.nested.property('foo.bar'); }, "expected { 'foo.bar': 'baz' } to have nested property 'foo.bar'"); err(function () { expect({a:1}, 'blah').to.have.nested.property({'a':'1'}); }, "blah: the argument to property must be a string when using nested syntax"); }); it('nested.property(name, val)', function(){ expect({ foo: { bar: 'baz' } }) .to.have.nested.property('foo.bar', 'baz'); expect({ foo: { bar: 'baz' } }) .to.not.have.nested.property('foo.bar', 'quux'); expect({ foo: { bar: 'baz' } }) .to.not.have.nested.property('foo.quux', 'baz'); expect({a: {b: {c: 1}}}).to.not.have.nested.property('a.b', {c: 1}); err(function(){ expect({ foo: { bar: 'baz' } }) .to.have.nested.property('foo.bar', 'quux', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to have nested property 'foo.bar' of 'quux', but got 'baz'"); err(function(){ expect({ foo: { bar: 'baz' } }) .to.not.have.nested.property('foo.bar', 'baz', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to not have nested property 'foo.bar' of 'baz'"); }); it('deep.nested.property(name, val)', function () { var obj = {a: {b: {c: 1}}}; expect(obj).to.have.deep.nested.property('a.b', {c: 1}); expect(obj).to.not.have.deep.nested.property('a.b', {c: 7}); expect(obj).to.not.have.deep.nested.property('a.b', {z: 1}); expect(obj).to.not.have.deep.nested.property('a.z', {c: 1}); err(function () { expect(obj).to.have.deep.nested.property('a.b', {c: 7}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.b' of { c: 7 }, but got { c: 1 }"); err(function () { expect(obj).to.have.deep.nested.property('a.z', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.z'"); err(function () { expect(obj).to.not.have.deep.nested.property('a.b', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to not have deep nested property 'a.b' of { c: 1 }"); }); it('ownPropertyDescriptor(name)', function(){ expect('test').to.have.ownPropertyDescriptor('length'); expect('test').to.haveOwnPropertyDescriptor('length'); expect('test').not.to.have.ownPropertyDescriptor('foo'); var obj = {}; var descriptor = { configurable: false, enumerable: true, writable: true, value: NaN }; Object.defineProperty(obj, 'test', descriptor); expect(obj).to.have.ownPropertyDescriptor('test', descriptor); err(function(){ expect(obj).not.to.have.ownPropertyDescriptor('test', descriptor, 'blah'); }, /^blah: expected the own property descriptor for 'test' on \{ test: NaN \} to not match \{ [^\}]+ \}$/); err(function(){ expect(obj, 'blah').not.to.have.ownPropertyDescriptor('test', descriptor); }, /^blah: expected the own property descriptor for 'test' on \{ test: NaN \} to not match \{ [^\}]+ \}$/); err(function(){ var wrongDescriptor = { configurable: false, enumerable: true, writable: false, value: NaN }; expect(obj).to.have.ownPropertyDescriptor('test', wrongDescriptor, 'blah'); }, /^blah: expected the own property descriptor for 'test' on \{ test: NaN \} to match \{ [^\}]+ \}, got \{ [^\}]+ \}$/); err(function(){ expect(obj).to.have.ownPropertyDescriptor('test2', 'blah'); }, "blah: expected { test: NaN } to have an own property descriptor for 'test2'"); err(function(){ expect(obj, 'blah').to.have.ownPropertyDescriptor('test2'); }, "blah: expected { test: NaN } to have an own property descriptor for 'test2'"); expect(obj).to.have.ownPropertyDescriptor('test').and.have.property('enumerable', true); }); it('string()', function(){ expect('foobar').to.have.string('bar'); expect('foobar').to.have.string('foo'); expect('foobar').to.not.have.string('baz'); err(function(){ expect(3).to.have.string('baz', 'blah'); }, "blah: expected 3 to be a string"); err(function(){ expect(3, 'blah').to.have.string('baz'); }, "blah: expected 3 to be a string"); err(function(){ expect('foobar').to.have.string('baz', 'blah'); }, "blah: expected 'foobar' to contain 'baz'"); err(function(){ expect('foobar', 'blah').to.have.string('baz'); }, "blah: expected 'foobar' to contain 'baz'"); err(function(){ expect('foobar').to.not.have.string('bar', 'blah'); }, "blah: expected 'foobar' to not contain 'bar'"); }); it('include()', function(){ expect(['foo', 'bar']).to.include('foo'); expect(['foo', 'bar']).to.include('foo'); expect(['foo', 'bar']).to.include('bar'); expect([1,2]).to.include(1); expect(['foo', 'bar']).to.not.include('baz'); expect(['foo', 'bar']).to.not.include(1); expect({a: 1}).to.include({'toString': Object.prototype.toString}); // .include should work with Error objects and objects with a custom // `@@toStringTag`. expect(new Error('foo')).to.include({message: 'foo'}); var customObj = {a: 1}; customObj[Symbol.toStringTag] = 'foo'; expect(customObj).to.include({a: 1}); var obj1 = {a: 1} , obj2 = {b: 2}; expect([obj1, obj2]).to.include(obj1); expect([obj1, obj2]).to.not.include({a: 1}); expect({foo: obj1, bar: obj2}).to.include({foo: obj1}); expect({foo: obj1, bar: obj2}).to.include({foo: obj1, bar: obj2}); expect({foo: obj1, bar: obj2}).to.not.include({foo: {a: 1}}); expect({foo: obj1, bar: obj2}).to.not.include({foo: obj1, bar: {b: 2}}); var map = new Map(); var val = [{a: 1}]; map.set('a', val); map.set('b', 2); map.set('c', -0); map.set('d', NaN); expect(map).to.include(val); expect(map).to.not.include([{a: 1}]); expect(map).to.include(2); expect(map).to.not.include(3); expect(map).to.include(0); expect(map).to.include(NaN); var set = new Set(); var val = [{a: 1}]; set.add(val); set.add(2); set.add(-0); set.add(NaN); expect(set).to.include(val); expect(set).to.not.include([{a: 1}]); expect(set).to.include(2); expect(set).to.not.include(3); if (set.has(0)) { // This test is skipped in IE11 because (contrary to spec) IE11 uses // SameValue instead of SameValueZero equality for sets. expect(set).to.include(0); } expect(set).to.include(NaN); var ws = new WeakSet(); var val = [{a: 1}]; ws.add(val); expect(ws).to.include(val); expect(ws).to.not.include([{a: 1}]); expect(ws).to.not.include({}); var sym1 = Symbol() , sym2 = Symbol() , sym3 = Symbol(); expect([sym1, sym2]).to.include(sym1); expect([sym1, sym2]).to.not.include(sym3); err(function(){ expect(['foo']).to.include('bar', 'blah'); }, "blah: expected [ 'foo' ] to include 'bar'"); err(function(){ expect(['foo'], 'blah').to.include('bar'); }, "blah: expected [ 'foo' ] to include 'bar'"); err(function(){ expect(['bar', 'foo']).to.not.include('foo', 'blah'); }, "blah: expected [ 'bar', 'foo' ] to not include 'foo'"); err(function(){ expect({a: 1}).to.include({b: 2}, 'blah'); }, "blah: expected { a: 1 } to have property 'b'"); err(function(){ expect({a: 1}, 'blah').to.include({b: 2}); }, "blah: expected { a: 1 } to have property 'b'"); err(function(){ expect({a:1,b:2}).to.not.include({b:2}); }, "expected { a: 1, b: 2 } to not have property 'b' of 2"); err(function () { expect([{a: 1}, {b: 2}]).to.include({a: 1}); }, "expected [ { a: 1 }, { b: 2 } ] to include { a: 1 }"); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; expect([obj1, obj2]).to.not.include(obj1); }, "expected [ { a: 1 }, { b: 2 } ] to not include { a: 1 }"); err(function () { expect({foo: {a: 1}, bar: {b: 2}}).to.include({foo: {a: 1}}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to have property 'foo' of { a: 1 }, but got { a: 1 }"); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; expect({foo: obj1, bar: obj2}).to.not.include({foo: obj1, bar: obj2}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to not have property 'foo' of { a: 1 }"); err(function(){ expect(true).to.include(true, 'blah'); }, "blah: the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function(){ expect(true, 'blah').to.include(true); }, "blah: the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function(){ expect(42.0).to.include(42); }, "the given combination of arguments (number and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ expect(null).to.include(42); }, "the given combination of arguments (null and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ expect(undefined).to.include(42); }, "the given combination of arguments (undefined and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ expect(true).to.not.include(true); }, "the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function(){ expect(42.0).to.not.include(42); }, "the given combination of arguments (number and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ expect(null).to.not.include(42); }, "the given combination of arguments (null and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ expect(undefined).to.not.include(42); }, "the given combination of arguments (undefined and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); }); it('deep.include()', function () { var obj1 = {a: 1} , obj2 = {b: 2}; expect([obj1, obj2]).to.deep.include({a: 1}); expect([obj1, obj2]).to.not.deep.include({a: 9}); expect([obj1, obj2]).to.not.deep.include({z: 1}); expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}}); expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}, bar: {b: 2}}); expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 9}}); expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {z: 1}}); expect({foo: obj1, bar: obj2}).to.not.deep.include({baz: {a: 1}}); expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 1}, bar: {b: 9}}); var map = new Map(); map.set(1, [{a: 1}]); expect(map).to.deep.include([{a: 1}]); var set = new Set(); set.add([{a: 1}]); expect(set).to.deep.include([{a: 1}]); err(function() { expect(new WeakSet()).to.deep.include({}, 'foo'); }, 'foo: unable to use .deep.include with WeakSet'); err(function () { expect([obj1, obj2]).to.deep.include({a: 9}, 'blah'); }, "blah: expected [ { a: 1 }, { b: 2 } ] to deep include { a: 9 }"); err(function () { expect([obj1, obj2], 'blah').to.deep.include({a: 9}); }, "blah: expected [ { a: 1 }, { b: 2 } ] to deep include { a: 9 }"); err(function () { expect([obj1, obj2], 'blah').to.not.deep.include({a: 1}); }, "blah: expected [ { a: 1 }, { b: 2 } ] to not deep include { a: 1 }"); err(function () { expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}, bar: {b: 9}}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to have deep property 'bar' of { b: 9 }, but got { b: 2 }"); err(function () { expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 1}, bar: {b: 2}}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }"); }); it('nested.include()', function () { expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); expect({a: {b: ['x', 'y']}}).to.not.nested.include({'a.b[1]': 'x'}); expect({a: {b: ['x', 'y']}}).to.not.nested.include({'a.c': 'y'}); expect({a: {b: [{x: 1}]}}).to.not.nested.include({'a.b[0]': {x: 1}}); expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); expect({'.a': {'[b]': 'x'}}).to.not.nested.include({'\\.a.\\[b\\]': 'y'}); err(function () { expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'x'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'"); err(function () { expect({a: {b: ['x', 'y']}}, 'blah').to.nested.include({'a.b[1]': 'x'}); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'"); err(function () { expect({a: {b: ['x', 'y']}}).to.nested.include({'a.c': 'y'}); }, "expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.c'"); err(function () { expect({a: {b: ['x', 'y']}}).to.not.nested.include({'a.b[1]': 'y'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'"); err(function () { expect({a: {b: ['x', 'y']}}, 'blah').to.not.nested.include({'a.b[1]': 'y'}); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'"); }); it('deep.nested.include()', function () { expect({a: {b: [{x: 1}]}}).to.deep.nested.include({'a.b[0]': {x: 1}}); expect({a: {b: [{x: 1}]}}).to.not.deep.nested.include({'a.b[0]': {y: 2}}); expect({a: {b: [{x: 1}]}}).to.not.deep.nested.include({'a.c': {x: 1}}); expect({'.a': {'[b]': {x: 1}}}) .to.deep.nested.include({'\\.a.\\[b\\]': {x: 1}}); expect({'.a': {'[b]': {x: 1}}}) .to.not.deep.nested.include({'\\.a.\\[b\\]': {y: 2}}); err(function () { expect({a: {b: [{x: 1}]}}).to.deep.nested.include({'a.b[0]': {y: 2}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }"); err(function () { expect({a: {b: [{x: 1}]}}, 'blah').to.deep.nested.include({'a.b[0]': {y: 2}}); }, "blah: expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }"); err(function () { expect({a: {b: [{x: 1}]}}).to.deep.nested.include({'a.c': {x: 1}}); }, "expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.c'"); err(function () { expect({a: {b: [{x: 1}]}}).to.not.deep.nested.include({'a.b[0]': {x: 1}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to not have deep nested property 'a.b[0]' of { x: 1 }"); err(function () { expect({a: {b: [{x: 1}]}}, 'blah').to.not.deep.nested.include({'a.b[0]': {x: 1}}); }, "blah: expected { a: { b: [ { x: 1 } ] } } to not have deep nested property 'a.b[0]' of { x: 1 }"); }); it('own.include()', function () { expect({a: 1}).to.own.include({a: 1}); expect({a: 1}).to.not.own.include({a: 3}); expect({a: 1}).to.not.own.include({'toString': Object.prototype.toString}); expect({a: {b: 2}}).to.not.own.include({a: {b: 2}}); err(function () { expect({a: 1}).to.own.include({a: 3}, 'blah'); }, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1"); err(function () { expect({a: 1}, 'blah').to.own.include({a: 3}); }, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1"); err(function () { expect({a: 1}).to.own.include({'toString': Object.prototype.toString}); }, "expected { a: 1 } to have own property 'toString'"); err(function () { expect({a: 1}).to.not.own.include({a: 1}, 'blah'); }, "blah: expected { a: 1 } to not have own property 'a' of 1"); err(function () { expect({a: 1}, 'blah').to.not.own.include({a: 1}); }, "blah: expected { a: 1 } to not have own property 'a' of 1"); }); it('deep.own.include()', function () { expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); expect({a: {b: 2}}).to.not.deep.own.include({a: {c: 3}}); expect({a: {b: 2}}) .to.not.deep.own.include({'toString': Object.prototype.toString}); err(function () { expect({a: {b: 2}}).to.deep.own.include({a: {c: 3}}, 'blah'); }, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }"); err(function () { expect({a: {b: 2}}, 'blah').to.deep.own.include({a: {c: 3}}); }, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }"); err(function () { expect({a: {b: 2}}).to.deep.own.include({'toString': Object.prototype.toString}); }, "expected { a: { b: 2 } } to have deep own property 'toString'"); err(function () { expect({a: {b: 2}}).to.not.deep.own.include({a: {b: 2}}, 'blah'); }, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }"); err(function () { expect({a: {b: 2}}, 'blah').to.not.deep.own.include({a: {b: 2}}); }, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }"); }); it('keys(array|Object|arguments)', function(){ expect({ foo: 1 }).to.have.keys(['foo']); expect({ foo: 1 }).have.keys({ 'foo': 6 }); expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']); expect({ foo: 1, bar: 2 }).to.have.keys('foo', 'bar'); expect({ foo: 1, bar: 2 }).have.keys({ 'foo': 6, 'bar': 7 }); expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar'); expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('bar', 'foo'); expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('baz'); expect({ foo: 1, bar: 2 }).contain.keys({ 'foo': 6 }); expect({ foo: 1, bar: 2 }).contain.keys({ 'bar': 7 }); expect({ foo: 1, bar: 2 }).contain.keys({ 'foo': 6 }); expect({ foo: 1, bar: 2 }).to.contain.keys('foo'); expect({ foo: 1, bar: 2 }).to.contain.keys('bar', 'foo'); expect({ foo: 1, bar: 2 }).to.contain.keys(['foo']); expect({ foo: 1, bar: 2 }).to.contain.keys(['bar']); expect({ foo: 1, bar: 2 }).to.contain.keys(['bar', 'foo']); expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); expect({ foo: 1, bar: 2 }).to.not.have.keys('baz'); expect({ foo: 1, bar: 2 }).to.not.have.keys('foo'); expect({ foo: 1, bar: 2 }).to.not.have.keys('foo', 'baz'); expect({ foo: 1, bar: 2 }).to.not.contain.keys('baz'); expect({ foo: 1, bar: 2 }).to.not.contain.keys('foo', 'baz'); expect({ foo: 1, bar: 2 }).to.not.contain.keys('baz', 'foo'); expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); expect({ foo: 1, bar: 2 }).to.contain.all.keys(['bar', 'foo']); expect({ foo: 1, bar: 2 }).contain.any.keys({ 'foo': 6 }); expect({ foo: 1, bar: 2 }).have.all.keys({ 'foo': 6, 'bar': 7 }); expect({ foo: 1, bar: 2 }).contain.all.keys({ 'bar': 7, 'foo': 6 }); expect({ foo: 1, bar: 2 }).to.not.have.any.keys('baz', 'abc', 'def'); expect({ foo: 1, bar: 2 }).to.not.have.any.keys('baz'); expect({ foo: 1, bar: 2 }).to.not.contain.any.keys('baz'); expect({ foo: 1, bar: 2 }).to.not.have.all.keys(['baz', 'foo']); expect({ foo: 1, bar: 2 }).to.not.contain.all.keys(['baz', 'foo']); expect({ foo: 1, bar: 2 }).not.have.all.keys({ 'baz': 8, 'foo': 7 }); expect({ foo: 1, bar: 2 }).not.contain.all.keys({ 'baz': 8, 'foo': 7 }); var enumProp1 = 'enumProp1' , enumProp2 = 'enumProp2' , nonEnumProp = 'nonEnumProp' , obj = {}; obj[enumProp1] = 'enumProp1'; obj[enumProp2] = 'enumProp2'; Object.defineProperty(obj, nonEnumProp, { enumerable: false, value: 'nonEnumProp' }); expect(obj).to.have.all.keys([enumProp1, enumProp2]); expect(obj).to.not.have.all.keys([enumProp1, enumProp2, nonEnumProp]); var sym1 = Symbol('sym1') , sym2 = Symbol('sym2') , sym3 = Symbol('sym3') , str = 'str' , obj = {}; obj[sym1] = 'sym1'; obj[sym2] = 'sym2'; obj[str] = 'str'; Object.defineProperty(obj, sym3, { enumerable: false, value: 'sym3' }); expect(obj).to.have.all.keys([sym1, sym2, str]); expect(obj).to.not.have.all.keys([sym1, sym2, sym3, str]); // Not using Map constructor args because not supported in IE 11. var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testMap = new Map(); testMap.set(aKey, 'aValue'); testMap.set(anotherKey, 'anotherValue'); expect(testMap).to.have.any.keys(aKey); expect(testMap).to.have.any.keys('thisDoesNotExist', 'thisToo', aKey); expect(testMap).to.have.all.keys(aKey, anotherKey); expect(testMap).to.contain.all.keys(aKey); expect(testMap).to.not.contain.all.keys(aKey, 'thisDoesNotExist'); expect(testMap).to.not.have.any.keys({iDoNot: 'exist'}); expect(testMap).to.not.have.any.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); expect(testMap).to.not.have.all.keys('thisDoesNotExist', 'thisToo', anotherKey); expect(testMap).to.have.any.keys([aKey]); expect(testMap).to.have.any.keys([20, 1, aKey]); expect(testMap).to.have.all.keys([aKey, anotherKey]); expect(testMap).to.not.have.any.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); expect(testMap).to.not.have.any.keys([20, 1, {13: 37}]); expect(testMap).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]); // Ensure the assertions above use strict equality err(function() { expect(testMap).to.have.any.keys({thisIs: 'anExampleObject'}); }); err(function() { expect(testMap).to.have.all.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); }); err(function() { expect(testMap).to.contain.all.keys({thisIs: 'anExampleObject'}); }); err(function() { expect(testMap).to.have.any.keys([{thisIs: 'anExampleObject'}]); }); err(function() { expect(testMap).to.have.all.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); }); // Using the same assertions as above but with `.deep` flag instead of using referential equality expect(testMap).to.have.any.deep.keys({thisIs: 'anExampleObject'}); expect(testMap).to.have.any.deep.keys('thisDoesNotExist', 'thisToo', {thisIs: 'anExampleObject'}); expect(testMap).to.contain.all.deep.keys({thisIs: 'anExampleObject'}); expect(testMap).to.not.contain.all.deep.keys({thisIs: 'anExampleObject'}, 'thisDoesNotExist'); expect(testMap).to.not.have.any.deep.keys({iDoNot: 'exist'}); expect(testMap).to.not.have.any.deep.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); expect(testMap).to.not.have.all.deep.keys('thisDoesNotExist', 'thisToo', {doingThisBecauseOf: 'referential equality'}); expect(testMap).to.have.any.deep.keys([{thisIs: 'anExampleObject'}]); expect(testMap).to.have.any.deep.keys([20, 1, {thisIs: 'anExampleObject'}]); expect(testMap).to.have.all.deep.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); expect(testMap).to.not.have.any.deep.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); expect(testMap).to.not.have.any.deep.keys([20, 1, {13: 37}]); expect(testMap).to.not.have.all.deep.keys([{thisIs: 'anExampleObject'}, {'iDoNot': 'exist'}]); var weirdMapKey1 = Object.create(null) , weirdMapKey2 = {toString: NaN} , weirdMapKey3 = [] , weirdMap = new Map(); weirdMap.set(weirdMapKey1, 'val1'); weirdMap.set(weirdMapKey2, 'val2'); expect(weirdMap).to.have.all.keys([weirdMapKey1, weirdMapKey2]); expect(weirdMap).to.not.have.all.keys([weirdMapKey1, weirdMapKey3]); var symMapKey1 = Symbol() , symMapKey2 = Symbol() , symMapKey3 = Symbol() , symMap = new Map(); symMap.set(symMapKey1, 'val1'); symMap.set(symMapKey2, 'val2'); expect(symMap).to.have.all.keys(symMapKey1, symMapKey2); expect(symMap).to.have.any.keys(symMapKey1, symMapKey3); expect(symMap).to.contain.all.keys(symMapKey2, symMapKey1); expect(symMap).to.contain.any.keys(symMapKey3, symMapKey1); expect(symMap).to.not.have.all.keys(symMapKey1, symMapKey3); expect(symMap).to.not.have.any.keys(symMapKey3); expect(symMap).to.not.contain.all.keys(symMapKey3, symMapKey1); expect(symMap).to.not.contain.any.keys(symMapKey3); var errMap = new Map(); errMap.set({ foo: 1 }); err(function(){ expect(errMap, 'blah').to.have.keys(); }, "blah: keys required"); err(function(){ expect(errMap).to.have.keys([]); }, "keys required"); err(function(){ expect(errMap).to.contain.keys(); }, "keys required"); err(function(){ expect(errMap).to.contain.keys([]); }, "keys required"); // Uncomment this after solving https://github.com/chaijs/chai/issues/662 // This should fail because of referential equality (this is a strict comparison) // err(function(){ // expect(new Map([[{foo: 1}, 'bar']])).to.contain.keys({ foo: 1 }); // }, 'expected [ [ { foo: 1 }, 'bar' ] ] to contain key { foo: 1 }'); // err(function(){ // expect(new Map([[{foo: 1}, 'bar']])).to.contain.deep.keys({ iDoNotExist: 0 }) // }, 'expected [ { foo: 1 } ] to deeply contain key { iDoNotExist: 0 }'); // Not using Set constructor args because not supported in IE 11. var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testSet = new Set(); testSet.add(aKey); testSet.add(anotherKey); expect(testSet).to.have.any.keys(aKey); expect(testSet).to.have.any.keys('thisDoesNotExist', 'thisToo', aKey); expect(testSet).to.have.all.keys(aKey, anotherKey); expect(testSet).to.contain.all.keys(aKey); expect(testSet).to.not.contain.all.keys(aKey, 'thisDoesNotExist'); expect(testSet).to.not.have.any.keys({iDoNot: 'exist'}); expect(testSet).to.not.have.any.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); expect(testSet).to.not.have.all.keys('thisDoesNotExist', 'thisToo', anotherKey); expect(testSet).to.have.any.keys([aKey]); expect(testSet).to.have.any.keys([20, 1, aKey]); expect(testSet).to.have.all.keys([aKey, anotherKey]); expect(testSet).to.not.have.any.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); expect(testSet).to.not.have.any.keys([20, 1, {13: 37}]); expect(testSet).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]); // Ensure the assertions above use strict equality err(function() { expect(testSet).to.have.any.keys({thisIs: 'anExampleObject'}); }); err(function() { expect(testSet).to.have.all.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); }); err(function() { expect(testSet).to.contain.all.keys({thisIs: 'anExampleObject'}); }); err(function() { expect(testSet).to.have.any.keys([{thisIs: 'anExampleObject'}]); }); err(function() { expect(testSet).to.have.all.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); }); // Using the same assertions as above but with `.deep` flag instead of using referential equality expect(testSet).to.have.any.deep.keys({thisIs: 'anExampleObject'}); expect(testSet).to.have.any.deep.keys('thisDoesNotExist', 'thisToo', {thisIs: 'anExampleObject'}); expect(testSet).to.contain.all.deep.keys({thisIs: 'anExampleObject'}); expect(testSet).to.not.contain.all.deep.keys({thisIs: 'anExampleObject'}, 'thisDoesNotExist'); expect(testSet).to.not.have.any.deep.keys({iDoNot: 'exist'}); expect(testSet).to.not.have.any.deep.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); expect(testSet).to.not.have.all.deep.keys('thisDoesNotExist', 'thisToo', {doingThisBecauseOf: 'referential equality'}); expect(testSet).to.have.any.deep.keys([{thisIs: 'anExampleObject'}]); expect(testSet).to.have.any.deep.keys([20, 1, {thisIs: 'anExampleObject'}]); expect(testSet).to.have.all.deep.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); expect(testSet).to.not.have.any.deep.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); expect(testSet).to.not.have.any.deep.keys([20, 1, {13: 37}]); expect(testSet).to.not.have.all.deep.keys([{thisIs: 'anExampleObject'}, {'iDoNot': 'exist'}]); var weirdSetKey1 = Object.create(null) , weirdSetKey2 = {toString: NaN} , weirdSetKey3 = [] , weirdSet = new Set(); weirdSet.add(weirdSetKey1); weirdSet.add(weirdSetKey2); expect(weirdSet).to.have.all.keys([weirdSetKey1, weirdSetKey2]); expect(weirdSet).to.not.have.all.keys([weirdSetKey1, weirdSetKey3]); var symSetKey1 = Symbol() , symSetKey2 = Symbol() , symSetKey3 = Symbol() , symSet = new Set(); symSet.add(symSetKey1); symSet.add(symSetKey2); expect(symSet).to.have.all.keys(symSetKey1, symSetKey2); expect(symSet).to.have.any.keys(symSetKey1, symSetKey3); expect(symSet).to.contain.all.keys(symSetKey2, symSetKey1); expect(symSet).to.contain.any.keys(symSetKey3, symSetKey1); expect(symSet).to.not.have.all.keys(symSetKey1, symSetKey3); expect(symSet).to.not.have.any.keys(symSetKey3); expect(symSet).to.not.contain.all.keys(symSetKey3, symSetKey1); expect(symSet).to.not.contain.any.keys(symSetKey3); var errSet = new Set(); errSet.add({ foo: 1}); err(function(){ expect(errSet, 'blah').to.have.keys(); }, "blah: keys required"); err(function(){ expect(errSet).to.have.keys([]); }, "keys required"); err(function(){ expect(errSet).to.contain.keys(); }, "keys required"); err(function(){ expect(errSet).to.contain.keys([]); }, "keys required"); // Uncomment this after solving https://github.com/chaijs/chai/issues/662 // This should fail because of referential equality (this is a strict comparison) // err(function(){ // expect(new Set([{foo: 1}])).to.contain.keys({ foo: 1 }); // }, 'expected [ { foo: 1 } ] to deeply contain key { foo: 1 }'); // err(function(){ // expect(new Set([{foo: 1}])).to.contain.deep.keys({ iDoNotExist: 0 }); // }, 'expected [ { foo: 1 } ] to deeply contain key { iDoNotExist: 0 }'); err(function(){ expect({ foo: 1 }, 'blah').to.have.keys(); }, "blah: keys required"); err(function(){ expect({ foo: 1 }).to.have.keys([]); }, "keys required"); err(function(){ expect({ foo: 1 }).to.not.have.keys([]); }, "keys required"); err(function(){ expect({ foo: 1 }).to.contain.keys([]); }, "keys required"); var mixedArgsMsg = 'blah: when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments' err(function(){ expect({}, 'blah').contain.keys(['a'], "b"); }, mixedArgsMsg); err(function(){ expect({}, 'blah').contain.keys({ 'a': 1 }, "b"); }, mixedArgsMsg); err(function(){ expect({ foo: 1 }, 'blah').to.have.keys(['bar']); }, "blah: expected { foo: 1 } to have key 'bar'"); err(function(){ expect({ foo: 1 }).to.have.keys(['bar', 'baz']); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ expect({ foo: 1 }).to.have.keys(['foo', 'bar', 'baz']); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ expect({ foo: 1 }).to.not.have.keys(['foo']); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ expect({ foo: 1 }).to.not.have.keys(['foo']); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ expect({ foo: 1, bar: 2 }).to.not.have.keys(['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ expect({ foo: 1, bar: 2 }).to.have.all.keys('foo'); }, "expected { foo: 1, bar: 2 } to have key 'foo'"); err(function(){ expect({ foo: 1 }).to.not.contain.keys(['foo']); }, "expected { foo: 1 } to not contain key 'foo'"); err(function(){ expect({ foo: 1 }).to.contain.keys('foo', 'bar'); }, "expected { foo: 1 } to contain keys 'foo', and 'bar'"); err(function() { expect({ foo: 1 }).to.have.any.keys('baz'); }, "expected { foo: 1 } to have key 'baz'"); err(function(){ expect({ foo: 1, bar: 2 }).to.not.have.all.keys(['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ expect({ foo: 1, bar: 2 }).to.not.have.any.keys(['foo', 'baz']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); // repeat previous tests with Object as arg. err(function(){ expect({ foo: 1 }, 'blah').have.keys({ 'bar': 1 }); }, "blah: expected { foo: 1 } to have key 'bar'"); err(function(){ expect({ foo: 1 }).have.keys({ 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ expect({ foo: 1 }).have.keys({ 'foo': 1, 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ expect({ foo: 1 }).not.have.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ expect({ foo: 1 }).not.have.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ expect({ foo: 1, bar: 2 }).not.have.keys({ 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ expect({ foo: 1 }).not.contain.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not contain key 'foo'"); err(function(){ expect({ foo: 1 }).contain.keys('foo', 'bar'); }, "expected { foo: 1 } to contain keys 'foo', and 'bar'"); err(function() { expect({ foo: 1 }).have.any.keys('baz'); }, "expected { foo: 1 } to have key 'baz'"); err(function(){ expect({ foo: 1, bar: 2 }).not.have.all.keys({ 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ expect({ foo: 1, bar: 2 }).not.have.any.keys({ 'foo': 1, 'baz': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); }); it('keys(array) will not mutate array (#359)', function () { var expected = [ 'b', 'a' ]; var original_order = [ 'b', 'a' ]; var obj = { "b": 1, "a": 1 }; expect(expected).deep.equal(original_order); expect(obj).keys(original_order); expect(expected).deep.equal(original_order); }); it('chaining', function(){ var tea = { name: 'chai', extras: ['milk', 'sugar', 'smile'] }; expect(tea).to.have.property('extras').with.lengthOf(3); expect(tea).to.have.property('extras').which.contains('smile'); err(function(){ expect(tea).to.have.property('extras').with.lengthOf(4); }, "expected [ 'milk', 'sugar', 'smile' ] to have a length of 4 but got 3"); expect(tea).to.be.a('object').and.have.property('name', 'chai'); var badFn = function () { throw new Error('testing'); }; expect(badFn).to.throw(Error).with.property('message', 'testing'); }); it('throw', function () { // See GH-45: some poorly-constructed custom errors don't have useful names // on either their constructor or their constructor prototype, but instead // only set the name inside the constructor itself. var PoorlyConstructedError = function () { this.name = 'PoorlyConstructedError'; }; PoorlyConstructedError.prototype = Object.create(Error.prototype); function CustomError(message) { this.name = 'CustomError'; this.message = message; } CustomError.prototype = Error.prototype; var specificError = new RangeError('boo'); var goodFn = function () { 1==1; } , badFn = function () { throw new Error('testing'); } , refErrFn = function () { throw new ReferenceError('hello'); } , ickyErrFn = function () { throw new PoorlyConstructedError(); } , specificErrFn = function () { throw specificError; } , customErrFn = function() { throw new CustomError('foo'); } , emptyErrFn = function () { throw new Error(); } , emptyStringErrFn = function () { throw new Error(''); }; expect(goodFn).to.not.throw(); expect(goodFn).to.not.throw(Error); expect(goodFn).to.not.throw(specificError); expect(badFn).to.throw(); expect(badFn).to.throw(Error); expect(badFn).to.not.throw(ReferenceError); expect(badFn).to.not.throw(specificError); expect(refErrFn).to.throw(); expect(refErrFn).to.throw(ReferenceError); expect(refErrFn).to.throw(Error); expect(refErrFn).to.not.throw(TypeError); expect(refErrFn).to.not.throw(specificError); expect(ickyErrFn).to.throw(); expect(ickyErrFn).to.throw(PoorlyConstructedError); expect(ickyErrFn).to.throw(Error); expect(ickyErrFn).to.not.throw(specificError); expect(specificErrFn).to.throw(specificError); expect(goodFn).to.not.throw('testing'); expect(goodFn).to.not.throw(/testing/); expect(badFn).to.throw(/testing/); expect(badFn).to.not.throw(/hello/); expect(badFn).to.throw('testing'); expect(badFn).to.not.throw('hello'); expect(emptyStringErrFn).to.throw(''); expect(emptyStringErrFn).to.not.throw('testing'); expect(badFn).to.throw(''); expect(badFn).to.throw(Error, /testing/); expect(badFn).to.throw(Error, 'testing'); expect(emptyErrFn).to.not.throw(Error, 'testing'); expect(badFn).to.not.throw(Error, 'I am the wrong error message'); expect(badFn).to.not.throw(TypeError, 'testing'); err(function(){ expect(goodFn, 'blah').to.throw(); }, /^blah: expected \[Function( goodFn)*\] to throw an error$/); err(function(){ expect(goodFn, 'blah').to.throw(ReferenceError); }, /^blah: expected \[Function( goodFn)*\] to throw ReferenceError$/); err(function(){ expect(goodFn, 'blah').to.throw(specificError); }, /^blah: expected \[Function( goodFn)*\] to throw 'RangeError: boo'$/); err(function(){ expect(badFn, 'blah').to.not.throw(); }, /^blah: expected \[Function( badFn)*\] to not throw an error but 'Error: testing' was thrown$/); err(function(){ expect(badFn, 'blah').to.throw(ReferenceError); }, /^blah: expected \[Function( badFn)*\] to throw 'ReferenceError' but 'Error: testing' was thrown$/); err(function(){ expect(badFn, 'blah').to.throw(specificError); }, /^blah: expected \[Function( badFn)*\] to throw 'RangeError: boo' but 'Error: testing' was thrown$/); err(function(){ expect(badFn, 'blah').to.not.throw(Error); }, /^blah: expected \[Function( badFn)*\] to not throw 'Error' but 'Error: testing' was thrown$/); err(function(){ expect(refErrFn, 'blah').to.not.throw(ReferenceError); }, /^blah: expected \[Function( refErrFn)*\] to not throw 'ReferenceError' but 'ReferenceError: hello' was thrown$/); err(function(){ expect(badFn, 'blah').to.throw(PoorlyConstructedError); }, /^blah: expected \[Function( badFn)*\] to throw 'PoorlyConstructedError' but 'Error: testing' was thrown$/); err(function(){ expect(ickyErrFn, 'blah').to.not.throw(PoorlyConstructedError); }, /^blah: (expected \[Function( ickyErrFn)*\] to not throw 'PoorlyConstructedError' but)(.*)(PoorlyConstructedError|\{ Object \()(.*)(was thrown)$/); err(function(){ expect(ickyErrFn, 'blah').to.throw(ReferenceError); }, /^blah: (expected \[Function( ickyErrFn)*\] to throw 'ReferenceError' but)(.*)(PoorlyConstructedError|\{ Object \()(.*)(was thrown)$/); err(function(){ expect(specificErrFn, 'blah').to.throw(new ReferenceError('eek')); }, /^blah: expected \[Function( specificErrFn)*\] to throw 'ReferenceError: eek' but 'RangeError: boo' was thrown$/); err(function(){ expect(specificErrFn, 'blah').to.not.throw(specificError); }, /^blah: expected \[Function( specificErrFn)*\] to not throw 'RangeError: boo'$/); err(function (){ expect(badFn, 'blah').to.not.throw(/testing/); }, /^blah: expected \[Function( badFn)*\] to throw error not matching \/testing\/$/); err(function () { expect(badFn, 'blah').to.throw(/hello/); }, /^blah: expected \[Function( badFn)*\] to throw error matching \/hello\/ but got 'testing'$/); err(function () { expect(badFn).to.throw(Error, /hello/, 'blah'); }, /^blah: expected \[Function( badFn)*\] to throw error matching \/hello\/ but got 'testing'$/); err(function () { expect(badFn, 'blah').to.throw(Error, /hello/); }, /^blah: expected \[Function( badFn)*\] to throw error matching \/hello\/ but got 'testing'$/); err(function () { expect(badFn).to.throw(Error, 'hello', 'blah'); }, /^blah: expected \[Function( badFn)*\] to throw error including 'hello' but got 'testing'$/); err(function () { expect(badFn, 'blah').to.throw(Error, 'hello'); }, /^blah: expected \[Function( badFn)*\] to throw error including 'hello' but got 'testing'$/); err(function () { expect(customErrFn, 'blah').to.not.throw(); }, /^blah: expected \[Function( customErrFn)*\] to not throw an error but 'CustomError: foo' was thrown$/); err(function(){ expect(badFn).to.not.throw(Error, 'testing', 'blah'); }, /^blah: expected \[Function( badFn)*\] to not throw 'Error' but 'Error: testing' was thrown$/); err(function(){ expect(badFn, 'blah').to.not.throw(Error, 'testing'); }, /^blah: expected \[Function( badFn)*\] to not throw 'Error' but 'Error: testing' was thrown$/); err(function(){ expect(emptyStringErrFn).to.not.throw(Error, '', 'blah'); }, /^blah: expected \[Function( emptyStringErrFn)*\] to not throw 'Error' but 'Error' was thrown$/); err(function(){ expect(emptyStringErrFn, 'blah').to.not.throw(Error, ''); }, /^blah: expected \[Function( emptyStringErrFn)*\] to not throw 'Error' but 'Error' was thrown$/); err(function(){ expect(emptyStringErrFn, 'blah').to.not.throw(''); }, /^blah: expected \[Function( emptyStringErrFn)*\] to throw error not including ''$/); err(function () { expect({}, 'blah').to.throw(); }, "blah: expected {} to be a function"); err(function () { expect({}).to.throw(Error, 'testing', 'blah'); }, "blah: expected {} to be a function"); }); it('respondTo', function(){ function Foo(){}; Foo.prototype.bar = function(){}; Foo.func = function() {}; var bar = {}; bar.foo = function(){}; expect(Foo).to.respondTo('bar'); expect(Foo).to.not.respondTo('foo'); expect(Foo).itself.to.respondTo('func'); expect(Foo).itself.not.to.respondTo('bar'); expect(bar).to.respondTo('foo'); err(function(){ expect(Foo).to.respondTo('baz', 'constructor'); }, /^(constructor: expected)(.*)(\[Function Foo\])(.*)(to respond to \'baz\')$/); err(function(){ expect(Foo, 'constructor').to.respondTo('baz'); }, /^(constructor: expected)(.*)(\[Function Foo\])(.*)(to respond to \'baz\')$/); err(function(){ expect(bar).to.respondTo('baz', 'object'); }, /^(object: expected)(.*)(\{ foo: \[Function\] \}|\{ Object \()(.*)(to respond to \'baz\')$/); err(function(){ expect(bar, 'object').to.respondTo('baz'); }, /^(object: expected)(.*)(\{ foo: \[Function\] \}|\{ Object \()(.*)(to respond to \'baz\')$/); }); it('satisfy', function(){ var matcher = function (num) { return num === 1; }; expect(1).to.satisfy(matcher); err(function(){ expect(2).to.satisfy(matcher, 'blah'); }, /^blah: expected 2 to satisfy \[Function( matcher)*\]$/); err(function(){ expect(2, 'blah').to.satisfy(matcher); }, /^blah: expected 2 to satisfy \[Function( matcher)*\]$/); }); it('closeTo', function(){ expect(1.5).to.be.closeTo(1.0, 0.5); expect(10).to.be.closeTo(20, 20); expect(-10).to.be.closeTo(20, 30); expect(10).to.be.closeTo(10, 0); expect(1682.6).to.be.closeTo(1682.7, 0.1); expect(1n).to.be.closeTo(2n, 1n); err(function(){ expect(2).to.be.closeTo(1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function(){ expect(2, 'blah').to.be.closeTo(1.0, 0.5); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function(){ expect(-10).to.be.closeTo(20, 29, 'blah'); }, "blah: expected -10 to be close to 20 +/- 29"); err(function() { expect([1.5]).to.be.closeTo(1.0, 0.5, 'blah'); }, "blah: expected [ 1.5 ] to be numeric"); err(function() { expect([1.5], 'blah').to.be.closeTo(1.0, 0.5); }, "blah: expected [ 1.5 ] to be numeric"); err(function() { expect(1.5).to.be.closeTo("1.0", 0.5, 'blah'); }, "blah: expected '1.0' to be numeric"); err(function() { expect(1.5, 'blah').to.be.closeTo("1.0", 0.5); }, "blah: expected '1.0' to be numeric"); err(function() { expect(1.5).to.be.closeTo(1.0, true, 'blah'); }, "blah: expected true to be numeric"); err(function() { expect(1.5, 'blah').to.be.closeTo(1.0, true); }, "blah: expected true to be numeric"); err(function() { expect(1.5, 'blah').to.be.closeTo(1.0); }, "blah: A `delta` value is required for `closeTo`"); }); it('approximately', function(){ expect(1.5).to.be.approximately(1.0, 0.5); expect(10).to.be.approximately(20, 20); expect(-10).to.be.approximately(20, 30); expect(10).to.be.approximately(10, 0); expect(1682.6).to.be.approximately(1682.7, 0.1); expect(1n).to.be.approximately(2n, 1n); err(function(){ expect(2).to.be.approximately(1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function(){ expect(-10).to.be.approximately(20, 29, 'blah'); }, "blah: expected -10 to be close to 20 +/- 29"); err(function() { expect([1.5]).to.be.approximately(1.0, 0.5); }, "expected [ 1.5 ] to be numeric"); err(function() { expect(1.5).to.be.approximately("1.0", 0.5); }, "expected '1.0' to be numeric"); err(function() { expect(1.5).to.be.approximately(1.0, true); }, "expected true to be numeric"); err(function() { expect(1.5).to.be.approximately(1.0); }, "A `delta` value is required for `closeTo`"); }); it('oneOf', function() { expect(1).to.be.oneOf([1, 2, 3]); expect('1').to.not.be.oneOf([1, 2, 3]); expect([3, [4]]).to.not.be.oneOf([1, 2, [3, 4]]); var threeFour = [3, [4]]; expect(threeFour).to.be.oneOf([1, 2, threeFour]); expect([]).to.be.deep.oneOf([[], '']); expect([1, 2]).to.contain.oneOf([4,2,5]); expect([3, 4]).to.not.contain.oneOf([2,1,5]); expect('The quick brown fox jumps over the lazy dog').to.contain.oneOf(['cat', 'dog', 'bird']); expect('The quick brown fox jumps over the lazy dog').to.not.contain.oneOf(['elephant', 'pigeon', 'lynx']); err(function () { expect(1).to.be.oneOf([2, 3], 'blah'); }, "blah: expected 1 to be one of [ 2, 3 ]"); err(function () { expect(1, 'blah').to.be.oneOf([2, 3]); }, "blah: expected 1 to be one of [ 2, 3 ]"); err(function () { expect(1).to.not.be.oneOf([1, 2, 3], 'blah'); }, "blah: expected 1 to not be one of [ 1, 2, 3 ]"); err(function () { expect(1, 'blah').to.not.be.oneOf([1, 2, 3]); }, "blah: expected 1 to not be one of [ 1, 2, 3 ]"); err(function () { expect(1).to.be.oneOf({}, 'blah'); }, "blah: expected {} to be an array"); err(function () { expect(1, 'blah').to.be.oneOf({}); }, "blah: expected {} to be an array"); }); it('include.members', function() { expect([1, 2, 3]).to.include.members([]); expect([1, 2, 3]).to.include.members([3, 2]); expect([1, 2, 3]).to.include.members([3, 2, 2]); expect([1, 2, 3]).to.not.include.members([8, 4]); expect([1, 2, 3]).to.not.include.members([1, 2, 3, 4]); expect([{a: 1}]).to.not.include.members([{a: 1}]); err(function() { expect([1, 2, 3]).to.include.members([2, 5], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to be a superset of [ 2, 5 ]'); err(function() { expect([1, 2, 3], 'blah').to.include.members([2, 5]); }, 'blah: expected [ 1, 2, 3 ] to be a superset of [ 2, 5 ]'); err(function() { expect([1, 2, 3]).to.not.include.members([2, 1]); }, 'expected [ 1, 2, 3 ] to not be a superset of [ 2, 1 ]'); }); it('same.members', function() { expect([5, 4]).to.have.same.members([5, 4]); expect([5, 4]).to.have.same.members([4, 5]); expect([5, 4, 4]).to.have.same.members([5, 4, 4]); expect(new Set([5, 4])).to.have.same.members([4, 5]); expect([5, 4]).to.not.have.same.members([]); expect([5, 4]).to.not.have.same.members([6, 3]); expect([5, 4]).to.not.have.same.members([5, 4, 2]); expect([5, 4]).to.not.have.same.members([5, 4, 4]); expect([5, 4, 4]).to.not.have.same.members([5, 4]); expect([5, 4, 4]).to.not.have.same.members([5, 4, 3]); expect([5, 4, 3]).to.not.have.same.members([5, 4, 4]); expect(new Set([5, 4])).to.not.have.same.members([4]); }); it('members', function() { expect([5, 4]).members([4, 5]); expect([5, 4]).members([5, 4]); expect([5, 4, 4]).members([5, 4, 4]); expect([5, 4]).not.members([]); expect([5, 4]).not.members([6, 3]); expect([5, 4]).not.members([5, 4, 2]); expect([5, 4]).not.members([5, 4, 4]); expect([5, 4, 4]).not.members([5, 4]); expect([5, 4, 4]).not.members([5, 4, 3]); expect([5, 4, 3]).not.members([5, 4, 4]); expect([{ id: 1 }]).not.members([{ id: 1 }]); err(function() { expect([1, 2, 3]).members([2, 1, 5], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to have the same members as [ 2, 1, 5 ]'); err(function() { expect([1, 2, 3], 'blah').members([2, 1, 5]); }, 'blah: expected [ 1, 2, 3 ] to have the same members as [ 2, 1, 5 ]'); err(function() { expect([1, 2, 3]).not.members([2, 1, 3]); }, 'expected [ 1, 2, 3 ] to not have the same members as [ 2, 1, 3 ]'); err(function () { expect({}).members([], 'blah'); }, 'blah: expected {} to be an iterable'); err(function () { expect({}, 'blah').members([]); }, 'blah: expected {} to be an iterable'); err(function () { expect([]).members({}, 'blah'); }, 'blah: expected {} to be an iterable'); err(function () { expect([], 'blah').members({}); }, 'blah: expected {} to be an iterable'); }); it('deep.members', function() { expect([{ id: 1 }]).deep.members([{ id: 1 }]); expect([{a: 1}, {b: 2}, {b: 2}]).deep.members([{a: 1}, {b: 2}, {b: 2}]); expect([{ id: 2 }]).not.deep.members([{ id: 1 }]); expect([{a: 1}, {b: 2}]).not.deep.members([{a: 1}, {b: 2}, {b: 2}]); expect([{a: 1}, {b: 2}, {b: 2}]).not.deep.members([{a: 1}, {b: 2}]); expect([{a: 1}, {b: 2}, {b: 2}]).not.deep.members([{a: 1}, {b: 2}, {c: 3}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.deep.members([{a: 1}, {b: 2}, {b: 2}]); err(function(){ expect([{ id: 1 }]).deep.members([{ id: 2 }], 'blah') }, 'blah: expected [ { id: 1 } ] to have the same members as [ { id: 2 } ]'); err(function(){ expect([{ id: 1 }], 'blah').deep.members([{ id: 2 }]) }, 'blah: expected [ { id: 1 } ] to have the same members as [ { id: 2 } ]'); }); it('include.deep.members', function() { expect([{a: 1}, {b: 2}, {c: 3}]).include.deep.members([{b: 2}, {a: 1}]); expect([{a: 1}, {b: 2}, {c: 3}]).include.deep.members([{b: 2}, {a: 1}, {a: 1}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.include.deep.members([{b: 2}, {a: 1}, {f: 5}]); err(function() { expect([{a: 1}, {b: 2}, {c: 3}]).include.deep.members([{b: 2}, {a: 1}, {f: 5}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be a superset of [ { b: 2 }, { a: 1 }, { f: 5 } ]'); err(function() { expect([{a: 1}, {b: 2}, {c: 3}], 'blah').include.deep.members([{b: 2}, {a: 1}, {f: 5}]); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be a superset of [ { b: 2 }, { a: 1 }, { f: 5 } ]'); }); it('ordered.members', function() { expect([1, 2, 3]).ordered.members([1, 2, 3]); expect([1, 2, 2]).ordered.members([1, 2, 2]); expect([1, 2, 3]).not.ordered.members([2, 1, 3]); expect([1, 2, 3]).not.ordered.members([1, 2]); expect([1, 2]).not.ordered.members([1, 2, 2]); expect([1, 2, 2]).not.ordered.members([1, 2]); expect([1, 2, 2]).not.ordered.members([1, 2, 3]); expect([1, 2, 3]).not.ordered.members([1, 2, 2]); err(function() { expect([1, 2, 3]).ordered.members([2, 1, 3], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to have the same ordered members as [ 2, 1, 3 ]'); err(function() { expect([1, 2, 3], 'blah').ordered.members([2, 1, 3]); }, 'blah: expected [ 1, 2, 3 ] to have the same ordered members as [ 2, 1, 3 ]'); err(function() { expect([1, 2, 3]).not.ordered.members([1, 2, 3]); }, 'expected [ 1, 2, 3 ] to not have the same ordered members as [ 1, 2, 3 ]'); }); it('include.ordered.members', function() { expect([1, 2, 3]).include.ordered.members([1, 2]); expect([1, 2, 3]).not.include.ordered.members([2, 1]); expect([1, 2, 3]).not.include.ordered.members([2, 3]); expect([1, 2, 3]).not.include.ordered.members([1, 2, 2]); err(function() { expect([1, 2, 3]).include.ordered.members([2, 1], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to be an ordered superset of [ 2, 1 ]'); err(function() { expect([1, 2, 3], 'blah').include.ordered.members([2, 1]); }, 'blah: expected [ 1, 2, 3 ] to be an ordered superset of [ 2, 1 ]'); err(function() { expect([1, 2, 3]).not.include.ordered.members([1, 2]); }, 'expected [ 1, 2, 3 ] to not be an ordered superset of [ 1, 2 ]'); }); it('deep.ordered.members', function() { expect([{a: 1}, {b: 2}, {c: 3}]).deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); expect([{a: 1}, {b: 2}, {b: 2}]).deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.deep.ordered.members([{b: 2}, {a: 1}, {c: 3}]); expect([{a: 1}, {b: 2}]).not.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); expect([{a: 1}, {b: 2}, {b: 2}]).not.deep.ordered.members([{a: 1}, {b: 2}]); expect([{a: 1}, {b: 2}, {b: 2}]).not.deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); err(function() { expect([{a: 1}, {b: 2}, {c: 3}]).deep.ordered.members([{b: 2}, {a: 1}, {c: 3}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to have the same ordered members as [ { b: 2 }, { a: 1 }, { c: 3 } ]'); err(function() { expect([{a: 1}, {b: 2}, {c: 3}], 'blah').deep.ordered.members([{b: 2}, {a: 1}, {c: 3}]); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to have the same ordered members as [ { b: 2 }, { a: 1 }, { c: 3 } ]'); err(function() { expect([{a: 1}, {b: 2}, {c: 3}]).not.deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); }, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not have the same ordered members as [ { a: 1 }, { b: 2 }, { c: 3 } ]'); }); it('include.deep.ordered.members', function() { expect([{a: 1}, {b: 2}, {c: 3}]).include.deep.ordered.members([{a: 1}, {b: 2}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.include.deep.ordered.members([{b: 2}, {a: 1}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.include.deep.ordered.members([{b: 2}, {c: 3}]); expect([{a: 1}, {b: 2}, {c: 3}]).not.include.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); err(function() { expect([{a: 1}, {b: 2}, {c: 3}]).include.deep.ordered.members([{b: 2}, {a: 1}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be an ordered superset of [ { b: 2 }, { a: 1 } ]'); err(function() { expect([{a: 1}, {b: 2}, {c: 3}], 'blah').include.deep.ordered.members([{b: 2}, {a: 1}]); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be an ordered superset of [ { b: 2 }, { a: 1 } ]'); err(function() { expect([{a: 1}, {b: 2}, {c: 3}]).not.include.deep.ordered.members([{a: 1}, {b: 2}]); }, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be an ordered superset of [ { a: 1 }, { b: 2 } ]'); }); it('iterable', function() { expect([1, 2, 3]).to.be.iterable; expect(new Map([[1, 'one'], [2, 'two'], [3, 'three']])).to.be.iterable; expect(new Set([1, 2, 3])).to.be.iterable; expect('hello').to.be.iterable; err(function() { expect(42).to.be.iterable; }, 'expected 42 to be an iterable'); err(function() { expect(undefined).to.be.iterable; }, 'expected undefined to be an iterable'); err(function() { expect(null).to.be.iterable; }, 'expected null to be an iterable'); err(function() { expect(true).to.be.iterable; }, 'expected true to be an iterable'); err(function() { expect({ key: 'value' }).to.be.iterable; }, 'expected { key: \'value\' } to be an iterable'); }) it('change', function() { var obj = { value: 10, str: 'foo' }, heroes = ['spiderman', 'superman'], fn = function() { obj.value += 5 }, decFn = function() { obj.value -= 20 }, sameFn = function() { 'foo' + 'bar' }, bangFn = function() { obj.str += '!' }, batFn = function() { heroes.push('batman') }, lenFn = function() { return heroes.length }; expect(fn).to.change(obj, 'value'); expect(fn).to.change(obj, 'value').by(5); expect(fn).to.change(obj, 'value').by(-5); expect(decFn).to.change(obj, 'value').by(20); expect(decFn).to.change(obj, 'value').but.not.by(21); expect(sameFn).to.not.change(obj, 'value'); expect(sameFn).to.not.change(obj, 'str'); expect(bangFn).to.change(obj, 'str'); expect(batFn).to.change(lenFn).by(1); expect(batFn).to.change(lenFn).but.not.by(2); err(function () { expect(sameFn).to.change(obj, 'value', 'blah'); }, "blah: expected .value to change"); err(function () { expect(sameFn, 'blah').to.change(obj, 'value'); }, "blah: expected .value to change"); err(function () { expect(fn).to.not.change(obj, 'value', 'blah'); }, "blah: expected .value to not change"); err(function () { expect({}).to.change(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { expect({}, 'blah').to.change(obj, 'value'); }, "blah: expected {} to be a function"); err(function () { expect(fn).to.change({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(fn, 'blah').to.change({}, 'badprop'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(fn, 'blah').to.change({}); }, "blah: expected {} to be a function"); err(function () { expect(fn).to.change(obj, 'value').by(10, 'blah'); }, "blah: expected .value to change by 10"); err(function () { expect(fn, 'blah').to.change(obj, 'value').by(10); }, "blah: expected .value to change by 10"); err(function () { expect(fn).to.change(obj, 'value').but.not.by(5, 'blah'); }, "blah: expected .value to not change by 5"); }); it('increase, decrease', function() { var obj = { value: 10, noop: null }, arr = ['one', 'two'], pFn = function() { arr.push('three') }, popFn = function() { arr.pop() }, nFn = function() { return null }, lenFn = function() { return arr.length }, incFn = function() { obj.value += 2 }, decFn = function() { obj.value -= 3 }, smFn = function() { obj.value += 0 }; expect(smFn).to.not.increase(obj, 'value'); expect(decFn).to.not.increase(obj, 'value'); expect(incFn).to.increase(obj, 'value'); expect(incFn).to.increase(obj, 'value').by(2); expect(incFn).to.increase(obj, 'value').but.not.by(1); expect(smFn).to.not.decrease(obj, 'value'); expect(incFn).to.not.decrease(obj, 'value'); expect(decFn).to.decrease(obj, 'value'); expect(decFn).to.decrease(obj, 'value').by(3); expect(decFn).to.decrease(obj, 'value').but.not.by(2); expect(popFn).to.not.increase(lenFn); expect(nFn).to.not.increase(lenFn); expect(pFn).to.increase(lenFn); expect(pFn).to.increase(lenFn).by(1); expect(pFn).to.increase(lenFn).but.not.by(2); expect(popFn).to.decrease(lenFn); expect(popFn).to.decrease(lenFn).by(1); expect(popFn).to.decrease(lenFn).but.not.by(2); expect(nFn).to.not.decrease(lenFn); expect(pFn).to.not.decrease(lenFn); err(function () { expect(smFn).to.increase(obj, 'value', 'blah'); }, "blah: expected .value to increase"); err(function () { expect(smFn, 'blah').to.increase(obj, 'value'); }, "blah: expected .value to increase"); err(function () { expect(incFn).to.not.increase(obj, 'value', 'blah'); }, "blah: expected .value to not increase"); err(function () { expect({}).to.increase(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { expect({}, 'blah').to.increase(obj, 'value'); }, "blah: expected {} to be a function"); err(function () { expect(incFn).to.increase({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(incFn, 'blah').to.increase({}, 'badprop'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(incFn, 'blah').to.increase({}); }, "blah: expected {} to be a function"); err(function() { expect(incFn).to.increase(obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function() { expect(incFn, 'blah').to.increase(obj, 'noop'); }, 'blah: expected null to be a number'); err(function () { expect(incFn).to.increase(obj, 'value').by(10, 'blah'); }, "blah: expected .value to increase by 10"); err(function () { expect(incFn, 'blah').to.increase(obj, 'value').by(10); }, "blah: expected .value to increase by 10"); err(function () { expect(incFn).to.increase(obj, 'value').but.not.by(2, 'blah'); }, "blah: expected .value to not increase by 2"); err(function () { expect(smFn).to.decrease(obj, 'value', 'blah'); }, "blah: expected .value to decrease"); err(function () { expect(smFn, 'blah').to.decrease(obj, 'value'); }, "blah: expected .value to decrease"); err(function () { expect(decFn).to.not.decrease(obj, 'value', 'blah'); }, "blah: expected .value to not decrease"); err(function () { expect({}).to.decrease(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { expect({}, 'blah').to.decrease(obj, 'value'); }, "blah: expected {} to be a function"); err(function () { expect(decFn).to.decrease({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(decFn, 'blah').to.decrease({}, 'badprop'); }, "blah: expected {} to have property 'badprop'"); err(function () { expect(decFn, 'blah').to.decrease({}); }, "blah: expected {} to be a function"); err(function() { expect(decFn).to.decrease(obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function() { expect(decFn, 'blah').to.decrease(obj, 'noop'); }, 'blah: expected null to be a number'); err(function () { expect(decFn).to.decrease(obj, 'value').by(10, 'blah'); }, "blah: expected .value to decrease by 10"); err(function () { expect(decFn, 'blah').to.decrease(obj, 'value').by(10); }, "blah: expected .value to decrease by 10"); err(function () { expect(decFn).to.decrease(obj, 'value').but.not.by(3, 'blah'); }, "blah: expected .value to not decrease by 3"); }); it('extensible', function() { var nonExtensibleObject = Object.preventExtensions({}); expect({}).to.be.extensible; expect(nonExtensibleObject).to.not.be.extensible; err(function() { expect(nonExtensibleObject, 'blah').to.be.extensible; }, 'blah: expected {} to be extensible'); err(function() { expect({}).to.not.be.extensible; }, 'expected {} to not be extensible'); // Making sure ES6-like Object.isExtensible response is respected for all primitive types expect(42).to.not.be.extensible; expect(null).to.not.be.extensible; expect('foo').to.not.be.extensible; expect(false).to.not.be.extensible; expect(undefined).to.not.be.extensible; expect(Symbol()).to.not.be.extensible; err(function() { expect(42).to.be.extensible; }, 'expected 42 to be extensible'); err(function() { expect(null).to.be.extensible; }, 'expected null to be extensible'); err(function() { expect('foo').to.be.extensible; }, 'expected \'foo\' to be extensible'); err(function() { expect(false).to.be.extensible; }, 'expected false to be extensible'); err(function() { expect(undefined).to.be.extensible; }, 'expected undefined to be extensible'); var proxy = new Proxy({}, { isExtensible: function() { throw new TypeError(); } }); err(function() { // .extensible should not suppress errors, thrown in proxy traps expect(proxy).to.be.extensible; }, { name: 'TypeError' }, true); }); it('sealed', function() { var sealedObject = Object.seal({}); expect(sealedObject).to.be.sealed; expect({}).to.not.be.sealed; err(function() { expect({}, 'blah').to.be.sealed; }, 'blah: expected {} to be sealed'); err(function() { expect(sealedObject).to.not.be.sealed; }, 'expected {} to not be sealed'); // Making sure ES6-like Object.isSealed response is respected for all primitive types expect(42).to.be.sealed; expect(null).to.be.sealed; expect('foo').to.be.sealed; expect(false).to.be.sealed; expect(undefined).to.be.sealed; expect(Symbol()).to.be.sealed; err(function() { expect(42).to.not.be.sealed; }, 'expected 42 to not be sealed'); err(function() { expect(null).to.not.be.sealed; }, 'expected null to not be sealed'); err(function() { expect('foo').to.not.be.sealed; }, 'expected \'foo\' to not be sealed'); err(function() { expect(false).to.not.be.sealed; }, 'expected false to not be sealed'); err(function() { expect(undefined).to.not.be.sealed; }, 'expected undefined to not be sealed'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isSealed will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // .sealed should not suppress errors, thrown in proxy traps expect(proxy).to.be.sealed; }, { name: 'TypeError' }, true); }); it('frozen', function() { var frozenObject = Object.freeze({}); expect(frozenObject).to.be.frozen; expect({}).to.not.be.frozen; err(function() { expect({}, 'blah').to.be.frozen; }, 'blah: expected {} to be frozen'); err(function() { expect(frozenObject).to.not.be.frozen; }, 'expected {} to not be frozen'); // Making sure ES6-like Object.isFrozen response is respected for all primitive types expect(42).to.be.frozen; expect(null).to.be.frozen; expect('foo').to.be.frozen; expect(false).to.be.frozen; expect(undefined).to.be.frozen; expect(Symbol()).to.be.frozen; err(function() { expect(42).to.not.be.frozen; }, 'expected 42 to not be frozen'); err(function() { expect(null).to.not.be.frozen; }, 'expected null to not be frozen'); err(function() { expect('foo').to.not.be.frozen; }, 'expected \'foo\' to not be frozen'); err(function() { expect(false).to.not.be.frozen; }, 'expected false to not be frozen'); err(function() { expect(undefined).to.not.be.frozen; }, 'expected undefined to not be frozen'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isFrozen will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // .frozen should not suppress errors, thrown in proxy traps expect(proxy).to.be.frozen; }, { name: 'TypeError' }, true); }); }); chaijs-chai-2a3ecff/test/globalErr.js000066400000000000000000000205011505212005400176460ustar00rootroot00000000000000import * as chai from '../index.js'; import {globalErr as err} from './bootstrap/index.js'; describe('globalErr', function () { var noop = function () {} , Err = chai.AssertionError , expect = chai.expect; it('should pass if string val equals error message', function () { err(function () { expect('cat').to.equal('dog') }, 'expected \'cat\' to equal \'dog\''); }); it('should pass if regex val matches error message', function () { err(function () { expect('cat').to.equal('dog') }, /expected 'cat' to equal 'dog'/); }); it('should pass if object val\'s props are included in error object', function () { err(function () { expect('cat').to.equal('dog'); }, { message: 'expected \'cat\' to equal \'dog\'' , expected: 'dog' , actual: 'cat' }); err(function () { expect({cat: 'meow'}).to.equal({dog: 'woof'}); }, { message: 'expected { cat: \'meow\' } to equal { dog: \'woof\' }' , expected: {dog: 'woof'} , actual: {cat: 'meow'} }); }); it('should throw if string val does not equal error message', function () { err(function () { err(function () { throw new Err('cat') }, 'dog'); }, { message: 'expected \'cat\' to equal \'dog\'' , expected: 'dog' , actual: 'cat' }); }); it('should pass operator if possible during none object comparison', function () { err(function () { expect('cat').to.equal('dog'); }, { message: 'expected \'cat\' to equal \'dog\'' , expected: 'dog' , actual: 'cat' , operator: 'strictEqual' }); err(function () { expect('cat').to.not.equal('cat'); }, { message: 'expected \'cat\' to not equal \'cat\'' , expected: 'cat' , actual: 'cat' , operator: 'notStrictEqual' }); }); it('should pass operator if possible during plain object comparison', function () { var val1 = { propVal1: 'val1' }; var val2 = { propVal2: 'val2' }; err(function () { expect(val1).to.equal(val2); }, { message: "expected { propVal1: 'val1' } to equal { propVal2: 'val2' }" , expected: val2 , actual: val1 , operator: 'deepStrictEqual' }); err(function () { expect(val1).to.not.equal(val1); }, { message: "expected { propVal1: 'val1' } to not equal { propVal1: 'val1' }" , expected: val1 , actual: val1 , operator: 'notDeepStrictEqual' }); }); it('should pass operator if possible during function comparison', function () { function f1 () { this.propF1 = 'propF1'; } function f2 () { this.propF2 = 'propF2'; } err(function () { expect(f1).to.equal(f2); }, { message: "expected [Function f1] to equal [Function f2]" , expected: f2 , actual: f1 , operator: 'deepStrictEqual' }); err(function () { expect(f1).to.not.equal(f1); }, { message: "expected [Function f1] to not equal [Function f1]" , expected: f1 , actual: f1 , operator: 'notDeepStrictEqual' }); }); it('should pass operator if possible during object comparison', function () { var val1 = [ 'string1' , 'string2' , 'string3' , 'string4' ]; var val2 = [ 'string5' , 'string6' , 'string7' , 'string8' ]; err(function () { expect(val1).to.equal(val2); }, { message: "expected [ 'string1', 'string2', …(2) ] to equal [ 'string5', 'string6', …(2) ]" , expected: val2 , actual: val1 , operator: 'deepStrictEqual' }); err(function () { expect(val1).to.not.equal(val1); }, { message: "expected [ 'string1', 'string2', …(2) ] to not equal [ 'string1', 'string2', …(2) ]" , expected: val1 , actual: val1 , operator: 'notDeepStrictEqual' }); }); it('should throw if regex val does not match error message', function () { err(function () { err(function () { throw new Err('cat') }, /dog/); }, 'expected \'cat\' to match /dog/'); }); it('should throw if object val\'s props are not included in error object', function () { err(function () { err(function () { throw new Err('cat') }, {text: 'cat'}); }, /expected AssertionError: cat to have property \'text\'/); err(function () { err(function () { throw new Err('cat') }, {message: 'dog'}); }, 'expected \'cat\' to deeply equal \'dog\'', true); }); it('should throw if fn does not throw', function () { err(function () { err(noop) }, 'Expected an error'); }); it('should throw if fn is invalid', function () { var vals = [ 'cat' , 42 , [] , new RegExp() , new Date() , null , undefined ]; vals.push(Symbol()); vals.push(new Map()); vals.push(new Set()); vals.push(new WeakMap()); vals.push(new WeakSet()); vals.push(new Promise(noop)); vals.forEach(function (val) { err(function () { err(val) }, 'Invalid fn') }); }); it('should throw if val is invalid', function () { var vals = [ 42 , [] , new Date() , noop , null ]; vals.push(Symbol()); vals.push(new Map()); vals.push(new WeakMap()); vals.push(new Set()); vals.push(new WeakSet()); vals.push(new Promise(noop)); vals.forEach(function (val) { err(function () { err(function () { throw new Err('Test error') }, val) }, 'Invalid val') }); }); describe('skipStackTest', function () { // Skip tests if `Error.captureStackTrace` is unsupported if (typeof Error.captureStackTrace === 'undefined') return; try { throw Error(); } catch (err) { // Skip tests if `err.stack` is unsupported if (typeof err.stack === 'undefined') return; } // Note: `.to.not.throw` isn't used for the assertions that aren't expected // to throw an error because it'll pollute the very same stack trace which // is being asserted on. Instead, if `err` throws an error, then Mocha will // use that error as the reason the test failed. describe('falsey', function () { it('should throw if "Getter" is in the stack trace', function () { err(function () { err(function fakeGetter () { throw Error('my stack trace contains a fake implementation frame'); }); }, /implementation frames not properly filtered from stack trace/, true); }); it('should throw if "Wrapper" is in the stack trace', function () { err(function () { err(function fakeWrapper () { throw Error('my stack trace contains a fake implementation frame'); }); }, /implementation frames not properly filtered from stack trace/, true); }); it('should throw if "assert" is in the stack trace', function () { err(function () { err(function assertFake () { throw Error('my stack trace contains a fake implementation frame'); }); }, /implementation frames not properly filtered from stack trace/, true); }); it('shouldn\'t throw if "Getter", "Wrapper", "assert" aren\'t in the stack trace', function () { err(function safeFnName () { throw Error('my stack trace doesn\'t contain implementation frames'); }); }); }); describe('truthy', function () { it('shouldn\'t throw if "Getter" is in the stack trace', function () { err(function fakeGetter () { throw Error('my stack trace contains a fake implementation frame'); }, undefined, true); }); it('shouldn\'t throw if "Wrapper" is in the stack trace', function () { err(function fakeWrapper () { throw Error('my stack trace contains a fake implementation frame'); }, undefined, true); }); it('shouldn\'t throw if "assert" is in the stack trace', function () { err(function assertFake () { throw Error('my stack trace contains a fake implementation frame'); }, undefined, true); }); it('shouldn\'t throw if "Getter", "Wrapper", "assert" aren\'t in the stack trace', function () { err(function safeFnName () { throw Error('my stack trace doesn\'t contain implementation frames'); }, undefined, true); }); }); }); }); chaijs-chai-2a3ecff/test/globalShould.js000066400000000000000000000005451505212005400203620ustar00rootroot00000000000000import * as chai from '../index.js'; describe('global should', function () { it('works', function () { var theGlobal = typeof window !== 'undefined' ? window : global; theGlobal.globalShould = chai.should(); try { globalShould.not.exist(undefined); } finally { delete theGlobal.globalShould; } }); }); chaijs-chai-2a3ecff/test/plugins.js000066400000000000000000000027661505212005400174330ustar00rootroot00000000000000import * as chai from '../index.js'; describe('plugins', function () { function plugin (chai) { if (chai.Assertion.prototype.testing) return; Object.defineProperty(chai.Assertion.prototype, 'testing', { get: function () { return 'successful'; } }); } it('basic usage', function () { chai.use(plugin); var expect = chai.expect; expect(expect('').testing).to.equal('successful'); }); it('double plugin', function () { chai.expect(function () { chai.use(plugin); }).to.not.throw(); }); it('nested plugin', function () { chai.use(function (chai) { chai.use(plugin); }); var expect = chai.expect; expect(expect('').testing).to.equal('successful'); }); it('chained plugin', function () { chai.use(function (chaiObj) { Object.defineProperty(chaiObj.Assertion.prototype, 'testing2', { get() { return 'bleep bloop'; } }); }).use(plugin); var expect = chai.expect; expect(expect('').testing).to.equal('successful'); expect(expect('').testing2).to.equal('bleep bloop'); }); it('.use detached from chai object', function () { function anotherPlugin (chai) { Object.defineProperty(chai.Assertion.prototype, 'moreTesting', { get: function () { return 'more success'; } }); } var use = chai.use; use(anotherPlugin); var expect = chai.expect; expect(expect('').moreTesting).to.equal('more success'); }); }); chaijs-chai-2a3ecff/test/should.js000066400000000000000000003310311505212005400172360ustar00rootroot00000000000000import * as chai from '../index.js'; import {globalErr as err} from './bootstrap/index.js'; describe('should', function() { var should = chai.Should(); it('assertion', function(){ 'test'.should.be.a('string'); should.equal('foo', 'foo'); should.not.equal('foo', 'bar'); }); describe('safeguards', function () { before(function () { chai.util.addProperty(chai.Assertion.prototype, 'tmpProperty', function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteProperty(chai.Assertion.prototype, 'tmpProperty', function (_super) { return function () { _super.call(this); }; }); chai.util.addMethod(chai.Assertion.prototype, 'tmpMethod', function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteMethod(chai.Assertion.prototype, 'tmpMethod', function (_super) { return function () { _super.call(this); }; }); chai.util.addChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function () { new chai.Assertion(42).equal(42); }, function () { new chai.Assertion(42).equal(42); }); chai.util.overwriteChainableMethod(chai.Assertion.prototype, 'tmpChainableMethod', function (_super) { return function () { _super.call(this); }; }, function (_super) { return function () { _super.call(this); }; }); }); after(function () { delete chai.Assertion.prototype.tmpProperty; delete chai.Assertion.prototype.tmpMethod; delete chai.Assertion.prototype.tmpChainableMethod; }); describe('proxify', function () { it('throws when invalid property follows should', function () { err(function () { (42).should.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows language chain', function () { err(function () { (42).should.to.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows property assertion', function () { err(function () { (42).should.ok.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows overwritten property assertion', function () { err(function () { (42).should.tmpProperty.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled method assertion', function () { err(function () { (42).should.equal.pizza; }, 'Invalid Chai property: equal.pizza. See docs for proper usage of "equal".', true); }); it('throws when invalid property follows called method assertion', function () { err(function () { (42).should.equal(42).pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled overwritten method assertion', function () { err(function () { (42).should.tmpMethod.pizza; }, 'Invalid Chai property: tmpMethod.pizza. See docs for proper usage of "tmpMethod".', true); }); it('throws when invalid property follows called overwritten method assertion', function () { err(function () { (42).should.tmpMethod().pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled chainable method assertion', function () { err(function () { (42).should.a.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows called chainable method assertion', function () { err(function () { (42).should.a('number').pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows uncalled overwritten chainable method assertion', function () { err(function () { (42).should.tmpChainableMethod.pizza; }, 'Invalid Chai property: pizza', true); }); it('throws when invalid property follows called overwritten chainable method assertion', function () { err(function () { (42).should.tmpChainableMethod().pizza; }, 'Invalid Chai property: pizza', true); }); it('doesn\'t throw if invalid property is excluded via config', function () { (function () { (42).should.then; }).should.not.throw(); }); }); describe('length guard', function () { var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); if (!fnLengthDesc.configurable) return; it('doesn\'t throw when `.length` follows `.should`', function () { (function () { ('foo').should.length; }).should.not.throw(); }); it('doesn\'t throw when `.length` follows language chain', function () { (function () { ('foo').should.to.length; }).should.not.throw(); }); it('doesn\'t throw when `.length` follows property assertion', function () { (function () { ('foo').should.ok.length; }).should.not.throw(); }); it('doesn\'t throw when `.length` follows overwritten property assertion', function () { (function () { ('foo').should.tmpProperty.length; }).should.not.throw(); }); it('throws when `.length` follows uncalled method assertion', function () { err(function () { ('foo').should.equal.length; }, 'Invalid Chai property: equal.length. See docs for proper usage of "equal".', true); }); it('doesn\'t throw when `.length` follows called method assertion', function () { (function () { ('foo').should.equal('foo').length; }).should.not.throw(); }); it('throws when `.length` follows uncalled overwritten method assertion', function () { err(function () { ('foo').should.tmpMethod.length; }, 'Invalid Chai property: tmpMethod.length. See docs for proper usage of "tmpMethod".', true); }); it('doesn\'t throw when `.length` follows called overwritten method assertion', function () { (function () { ('foo').should.tmpMethod().length; }).should.not.throw(); }); it('throws when `.length` follows uncalled chainable method assertion', function () { err(function () { ('foo').should.a.length; }, 'Invalid Chai property: a.length. Due to a compatibility issue, "length" cannot directly follow "a". Use "a.lengthOf" instead.', true); }); it('doesn\'t throw when `.length` follows called chainable method assertion', function () { (function () { ('foo').should.a('string').length; }).should.not.throw(); }); it('throws when `.length` follows uncalled overwritten chainable method assertion', function () { err(function () { ('foo').should.tmpChainableMethod.length; }, 'Invalid Chai property: tmpChainableMethod.length. Due to a compatibility issue, "length" cannot directly follow "tmpChainableMethod". Use "tmpChainableMethod.lengthOf" instead.', true); }); it('doesn\'t throw when `.length` follows called overwritten chainable method assertion', function () { (function () { ('foo').should.tmpChainableMethod().length; }).should.not.throw(); }); }); }); it('no-op chains', function() { function test(chain) { // tests that chain exists ((1).should[chain]).should.not.undefined; // tests methods (1).should[chain].equal(1); // tests properties that assert (false).should[chain].false; // tests not (false).should[chain].not.true; // tests chainable methods [1, 2, 3].should[chain].contains(1); } [ 'to', 'be', 'been', 'is' , 'and', 'has', 'have', 'with' , 'that', 'which', 'at', 'of' , 'same', 'but', 'does', 'still' ].forEach(test); }); describe("fail", function() { it('should accept a message as the 3rd argument', function () { err(function() { should.fail(0, 1, 'this has failed'); }, /this has failed/); }); it('should accept a message as the only argument', function () { err(function() { should.fail('this has failed'); }, /this has failed/); }); it('should produce a default message when called without any arguments', function () { err(function() { should.fail(); }, /should\.fail()/); }); }); it('root exist', function () { var foo = 'foo' , bar = undefined; should.exist(foo); should.not.exist(bar); should.exist(0); should.exist(false); should.exist(''); err(function () { should.exist(bar, 'blah'); }, "blah: expected undefined to exist"); err(function () { should.not.exist(foo, 'blah'); }, "blah: expected 'foo' to not exist"); }); it('root equal', function () { var value1 = 'value' , value2 = 'value' , foo = 'foo'; should.equal(value1, value2); should.not.equal(value1, foo); err(function () { should.equal(value1, foo, 'blah'); }, "blah: expected 'value' to equal 'foo'"); err(function () { should.not.equal(value1, value2, 'blah'); }, "blah: expected 'value' to not equal 'value'") }); it('root Throw', function () { should.Throw(function() { throw new Error('error!') }, Error, 'error!'); should.not.Throw(function () { }); err(function () { should.Throw(function () { throw new Error('error!') }, Error, 'needed user!', 'blah'); }, "blah: expected [Function] to throw error including 'needed user!' but got 'error!'"); err(function () { should.not.Throw(function () { throw new Error('error!') }, Error, 'error!', 'blah'); }, "blah: expected [Function] to not throw 'Error' but 'Error: error!' was thrown"); }); it('true', function(){ (true).should.be.true; false.should.not.be.true; (1).should.not.be.true;false false.should.have.been.false; err(function(){ 'test'.should.be.true; }, "expected 'test' to be true") }); it('ok', function(){ true.should.be.ok; false.should.not.be.ok; (1).should.be.ok; (0).should.not.be.ok; err(function(){ ''.should.be.ok; }, "expected '' to be truthy"); err(function(){ 'test'.should.not.be.ok; }, "expected 'test' to be falsy"); }); it('false', function(){ false.should.be.false; true.should.not.be.false; (0).should.not.be.false; err(function(){ ''.should.be.false; }, "expected '' to be false") }); it("callable", function () { (function () {}).should.be.callable; (async function () {}).should.be.callable; (function* () {}).should.be.callable; (async function* () {}).should.be.callable; true.should.not.be.callable; err(function () { "".should.be.callable; }, "expected '' to be a callable function"); }); it('null', function(){ (0).should.not.be.null; err(function(){ ''.should.be.null; }, "expected '' to be null") }); it('NaN', function(){ NaN.should.be.NaN; Infinity.should.not.be.NaN; 'foo'.should.not.be.NaN; ({}).should.not.be.NaN; should.not.equal(undefined, NaN); (4).should.not.be.NaN; err(function(){ NaN.should.not.be.NaN; }, "expected NaN not to be NaN"); err(function(){ Infinity.should.be.NaN; }, "expected Infinity to be NaN"); err(function(){ 'foo'.should.be.NaN; }, "expected 'foo' to be NaN"); err(function(){ ({}).should.be.NaN; }, "expected {} to be NaN"); err(function(){ should.equal(undefined, NaN); }, "expected undefined to equal NaN"); err(function(){ (4).should.be.NaN; }, "expected 4 to be NaN"); }); it('undefined', function(){ (0).should.not.be.undefined; err(function(){ ''.should.be.undefined; }, "expected '' to be undefined") }); it('arguments', function(){ var args = (function(){ return arguments; })(1,2,3); args.should.be.arguments; [].should.not.be.arguments; err(function () { [].should.be.arguments; }, "expected [] to be arguments but got Array"); }); it('".should" getter should unbox primitive values', function(){ function assert(value) { const AssertionObject = value.should; const type = typeof value; if (AssertionObject.__flags.object !== value) { throw new Error("value `"+ value.toString() +"` ("+ type +") wasn't unboxed"); } }; assert("a"); assert(0); assert(true); assert(false); assert(Symbol("a")); assert(BigInt(10)); }); it('.equal()', function(){ var foo; should.equal(undefined, foo); }); it('typeof', function(){ 'test'.should.be.a('string'); err(function(){ 'test'.should.not.be.a('string'); }, "expected 'test' not to be a string"); (5).should.be.a('number'); (new Number(1)).should.be.a('number'); Number(1).should.be.a('number'); (true).should.be.a('boolean'); (new Array()).should.be.a('array'); (new Object()).should.be.a('object'); ({}).should.be.a('object'); ([]).should.be.a('array'); (function() {}).should.be.a('function'); Symbol().should.be.a('symbol'); (5).should.be.a('number'); err(function(){ (5).should.not.be.a('number', 'blah'); }, "blah: expected 5 not to be a number"); }); it('instanceof', function(){ function Foo(){} new Foo().should.be.an.instanceof(Foo); // Normally, `instanceof` requires that the constructor be a function or an // object with a callable `@@hasInstance`. But in some older browsers such // as IE11, `instanceof` also accepts DOM-related interfaces such as // `HTMLElement`, despite being non-callable objects in those browsers. // See: https://github.com/chaijs/chai/issues/1000. if (typeof document !== 'undefined' && typeof document.createElement !== 'undefined' && typeof HTMLElement !== 'undefined') { document.createElement('div').should.be.an.instanceof(HTMLElement); } err(function(){ new Foo().should.be.an.instanceof(1, 'blah'); }, "blah: The instanceof assertion needs a constructor but Number was given."); err(function(){ new Foo().should.be.an.instanceof('batman'); }, "The instanceof assertion needs a constructor but String was given."); err(function(){ new Foo().should.be.an.instanceof({}); }, "The instanceof assertion needs a constructor but Object was given."); err(function(){ new Foo().should.be.an.instanceof(true); }, "The instanceof assertion needs a constructor but Boolean was given."); err(function(){ new Foo().should.be.an.instanceof(null); }, "The instanceof assertion needs a constructor but null was given."); err(function(){ new Foo().should.be.an.instanceof(undefined); }, "The instanceof assertion needs a constructor but undefined was given."); err(function(){ function Thing(){}; var t = new Thing(); Thing.prototype = 1337; t.should.be.an.instanceof(Thing); }, 'The instanceof assertion needs a constructor but Function was given.', true); err(function(){ new Foo().should.be.an.instanceof(Symbol()); }, "The instanceof assertion needs a constructor but Symbol was given."); err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 3; }; fakeInstanceB.should.be.an.instanceof(FakeConstructor); }, 'expected 4 to be an instance of an unnamed constructor'); err(function() { var FakeConstructor = {}; var fakeInstanceB = 4; FakeConstructor[Symbol.hasInstance] = function (val) { return val === 4; }; fakeInstanceB.should.not.be.an.instanceof(FakeConstructor); }, 'expected 4 to not be an instance of an unnamed constructor'); err(function(){ (3).should.an.instanceof(Foo, 'blah'); }, "blah: expected 3 to be an instance of Foo"); }); it('within(start, finish)', function(){ (5).should.be.within(5, 10); (5).should.be.within(3,6); (5).should.be.within(3,5); (5).should.not.be.within(1,3); err(function(){ (5).should.not.be.within(4,6, 'blah'); }, "blah: expected 5 to not be within 4..6"); err(function(){ (10).should.be.within(50,100, 'blah'); }, "blah: expected 10 to be within 50..100"); err(function(){ ({ foo: 1 }).should.have.length.within(50,100, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function(){ ({ foo: 1 }).should.have.lengthOf.within(50,100, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function () { ('string').should.be.within(0, 1, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.be.within(null, 1, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { (1).should.be.within(0, null, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { ('string').should.not.be.within(0, 1, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.not.be.within(null, 1, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { (1).should.not.be.within(0, null, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { (1).should.have.length.within(5,7, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { (1).should.have.lengthOf.within(5,7, 'blah'); }, "blah: expected 1 to have property 'length'"); (new Map()).should.have.length.within(0, 0); (new Map()).should.have.lengthOf.within(0, 0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length.within(2, 4); map.should.have.lengthOf.within(2, 4); err(function () { map.should.have.length.within(5, 7, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size within 5..7"); err(function () { map.should.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size within 5..7"); (new Set()).should.have.length.within(0, 0); (new Set()).should.have.lengthOf.within(0, 0); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length.within(2, 4); set.should.have.lengthOf.within(2, 4); err(function () { set.should.have.length.within(5, 7, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size within 5..7"); err(function () { set.should.have.lengthOf.within(5, 7, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size within 5..7"); }); it('within(start, finish) (dates)', function(){ var now = new Date(); var oneSecondBefore = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); var nowISO = now.toISOString(); var beforeISO = oneSecondBefore.toISOString(); var afterISO = oneSecondAfter.toISOString(); now.should.be.within(oneSecondBefore, oneSecondAfter); now.should.be.within(now, oneSecondAfter); now.should.be.within(now, now); oneSecondAfter.should.not.be.within(oneSecondAfter, oneSecondBefore); err(function(){ now.should.not.be.within(now, oneSecondAfter, 'blah'); }, "blah: expected " + nowISO + " to not be within " + nowISO + ".." + afterISO); err(function(){ oneSecondBefore.should.be.within(now, oneSecondAfter, 'blah'); }, "blah: expected " + beforeISO + " to be within " + nowISO + ".." + afterISO); err(function(){ ([]).should.have.length.within(now, 100, 'blah'); }, "blah: the arguments to within must be numbers"); err(function(){ now.should.have.lengthOf.within(50, now, 'blah'); }, "blah: expected " + nowISO + " to have property 'length'"); err(function () { now.should.have.length.within(5, 7); }, "expected " + nowISO + " to have property 'length'"); err(function () { (0).should.be.within(0, now, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { (1).should.be.within(now, 1, 'blah'); }, "blah: the arguments to within must be numbers"); err(function () { now.should.be.within(1, now, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { now.should.not.be.within(now, 1, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { now.should.not.be.within(null, now, 'blah'); }, "blah: the arguments to within must be dates"); err(function () { now.should.not.be.within(now, null, 'blah'); }, "blah: the arguments to within must be dates"); }); it('above(n)', function(){ (5).should.be.above(2); (5).should.be.greaterThan(2); (5).should.not.be.above(5); (5).should.not.be.above(6); err(function(){ (5).should.be.above(6, 'blah'); }, "blah: expected 5 to be above 6"); err(function(){ (10).should.not.be.above(6, 'blah'); }, "blah: expected 10 to be at most 6"); err(function(){ ({foo: 1}).should.have.length.above(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function(){ ({foo: 1}).should.have.lengthOf.above(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function () { ('string').should.be.above(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.be.above(null, 'blah'); }, "blah: the argument to above must be a number"); err(function () { ('string').should.not.be.above(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.not.be.above(null, 'blah'); }, "blah: the argument to above must be a number"); err(function () { (1).should.have.length.above(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { (1).should.have.lengthOf.above(0, 'blah'); }, "blah: expected 1 to have property 'length'"); (new Map()).should.have.length.above(-1); (new Map()).should.have.lengthOf.above(-1); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length.above(2); map.should.have.lengthOf.above(2); err(function () { map.should.have.length.above(5, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size above 5 but got 3"); err(function () { map.should.have.lengthOf.above(5, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size above 5 but got 3"); (new Set()).should.have.length.above(-1); (new Set()).should.have.lengthOf.above(-1); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length.above(2); set.should.have.lengthOf.above(2); err(function () { set.should.have.length.above(5, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size above 5 but got 3"); err(function () { set.should.have.lengthOf.above(5, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size above 5 but got 3"); }); it('above(n) (dates)', function(){ var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); now.should.be.above(oneSecondAgo); oneSecondAfter.should.be.greaterThan(now); now.should.not.be.above(oneSecondAfter); oneSecondAgo.should.not.be.above(oneSecondAfter); err(function(){ now.should.be.above(oneSecondAfter, 'blah'); }, "blah: expected " + now.toISOString() + " to be above " + oneSecondAfter.toISOString()); err(function(){ now.should.not.be.above(oneSecondAgo, 'blah'); }, "blah: expected " + now.toISOString() + " to be at most " + oneSecondAgo.toISOString()); err(function(){ now.should.have.length.above(3, 'blah'); }, "blah: expected " + now.toISOString() + " to have property 'length'"); err(function(){ ('string').should.have.length.above(now, 'blah'); }, "blah: the argument to above must be a number"); err(function () { now.should.be.above(1, 'blah'); }, "blah: the argument to above must be a date"); err(function () { now.should.be.above(null, 'blah'); }, "blah: the argument to above must be a date"); err(function () { (1).should.not.be.above(now, 'blah'); }, "blah: the argument to above must be a number"); err(function () { ([]).should.have.length.above(now, 'blah'); }, "blah: the argument to above must be a number"); }); it('least(n)', function(){ (5).should.be.at.least(5); (5).should.not.be.at.least(6); err(function(){ (5).should.be.at.least(6, 'blah'); }, "blah: expected 5 to be at least 6"); err(function(){ (10).should.not.be.at.least(6, 'blah'); }, "blah: expected 10 to be below 6"); err(function(){ ({foo: 1}).should.have.length.of.at.least(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function(){ ({foo: 1}).should.have.lengthOf.at.least(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function () { ('string').should.be.at.least(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.be.at.least(null, 'blah'); }, "blah: the argument to least must be a number"); err(function () { ('string').should.not.be.at.least(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.not.be.at.least(null, 'blah'); }, "blah: the argument to least must be a number"); (new Map()).should.have.length.of.at.least(0); (new Map()).should.have.lengthOf.at.least(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length.of.at.least(3); map.should.have.lengthOf.at.least(3); err(function () { map.should.have.length.of.at.least(4, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at least 4 but got 3"); err(function () { map.should.have.lengthOf.at.least(4, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at least 4 but got 3"); (new Set()).should.have.length.of.at.least(0); (new Set()).should.have.lengthOf.at.least(0); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length.of.at.least(3); set.should.have.lengthOf.at.least(3); err(function () { set.should.have.length.of.at.least(4, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at least 4 but got 3"); err(function () { set.should.have.lengthOf.at.least(4, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at least 4 but got 3"); }); it('below(n)', function(){ (2).should.be.below(5); (2).should.be.lessThan(5); (2).should.not.be.below(2); (2).should.not.be.below(1); err(function(){ (6).should.be.below(5, 'blah'); }, "blah: expected 6 to be below 5"); err(function(){ (6).should.not.be.below(10, 'blah'); }, "blah: expected 6 to be at least 10"); err(function(){ ({foo: 1}).should.have.length.below(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function(){ ({foo: 1}).should.have.lengthOf.below(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function () { ('string').should.be.below(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.be.below(null, 'blah'); }, "blah: the argument to below must be a number"); err(function () { ('string').should.not.be.below(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.not.be.below(null, 'blah'); }, "blah: the argument to below must be a number"); err(function () { (1).should.have.length.below(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { (1).should.have.lengthOf.below(0, 'blah'); }, "blah: expected 1 to have property 'length'"); (new Map()).should.have.length.below(1); (new Map()).should.have.lengthOf.below(1); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length.below(4); map.should.have.lengthOf.below(4); err(function () { map.should.have.length.below(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size below 2 but got 3"); err(function () { map.should.have.lengthOf.below(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size below 2 but got 3"); (new Set()).should.have.length.below(1); (new Set()).should.have.lengthOf.below(1); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length.below(4); set.should.have.lengthOf.below(4); err(function () { set.should.have.length.below(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size below 2 but got 3"); err(function () { set.should.have.lengthOf.below(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size below 2 but got 3"); }); it('below(n) (dates)', function(){ var now = new Date(); var oneSecondAgo = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); now.should.be.below(oneSecondAfter); oneSecondAgo.should.be.lessThan(now); now.should.not.be.below(oneSecondAgo); oneSecondAfter.should.not.be.below(oneSecondAgo); err(function(){ now.should.be.below(now, 'blah'); }, "blah: expected " + now.toISOString() + " to be below " + now.toISOString()); err(function(){ now.should.not.be.below(oneSecondAfter, 'blah'); }, "blah: expected " + now.toISOString() + " to be at least " + oneSecondAfter.toISOString()); err(function(){ now.should.have.length.below(3, 'blah'); }, "blah: expected " + now.toISOString() + " to have property 'length'"); err(function () { now.should.be.below(null, 'blah'); }, "blah: the argument to below must be a date"); err(function () { (1).should.not.be.below(now, 'blah'); }, "blah: the argument to below must be a number"); err(function () { now.should.not.be.below(1, 'blah'); }, "blah: the argument to below must be a date"); err(function () { now.should.not.be.below(null, 'blah'); }, "blah: the argument to below must be a date"); err(function () { ('string').should.have.length.below(now, 'blah'); }, "blah: the argument to below must be a number"); }); it('most(n)', function(){ (2).should.be.at.most(2); (2).should.not.be.at.most(1); err(function(){ (6).should.be.at.most(5, 'blah'); }, "blah: expected 6 to be at most 5"); err(function(){ (6).should.not.be.at.most(10, 'blah'); }, "blah: expected 6 to be above 10"); err(function(){ ({foo: 1}).should.have.length.of.at.most(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function(){ ({foo: 1}).should.have.lengthOf.at.most(3, 'blah'); }, "blah: expected { foo: 1 } to have property 'length'"); err(function () { ('string').should.be.at.most(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.be.at.most(null, 'blah'); }, "blah: the argument to most must be a number"); err(function () { ('string').should.not.be.at.most(0, 'blah'); }, "blah: expected 'string' to be a number or a date"); err(function () { (1).should.not.be.at.most(null, 'blah'); }, "blah: the argument to most must be a number"); err(function () { (1).should.have.length.of.at.most(0, 'blah'); }, "blah: expected 1 to have property 'length'"); err(function () { (1).should.have.lengthOf.at.most(0, 'blah'); }, "blah: expected 1 to have property 'length'"); (new Map()).should.have.length.of.at.most(0); (new Map()).should.have.lengthOf.at.most(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length.of.at.most(3); map.should.have.lengthOf.at.most(3); err(function () { map.should.have.length.of.at.most(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at most 2 but got 3"); err(function () { map.should.have.lengthOf.at.most(2, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to have a size at most 2 but got 3"); (new Set()).should.have.length.of.at.most(0); (new Set()).should.have.lengthOf.at.most(0); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length.of.at.most(3); set.should.have.lengthOf.at.most(3); err(function () { set.should.have.length.of.at.most(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at most 2 but got 3"); err(function () { set.should.have.lengthOf.at.most(2, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to have a size at most 2 but got 3"); }); it('most(n) (dates)', function(){ var now = new Date(); var oneSecondBefore = new Date(now.getTime() - 1000); var oneSecondAfter = new Date(now.getTime() + 1000); var nowISO = now.toISOString(); var beforeISO = oneSecondBefore.toISOString(); var afterISO = oneSecondAfter.toISOString(); now.should.be.at.most(now); now.should.be.at.most(oneSecondAfter); now.should.not.be.at.most(oneSecondBefore); err(function(){ now.should.be.at.most(oneSecondBefore, 'blah'); }, "blah: expected " + nowISO + " to be at most " + beforeISO); err(function(){ now.should.not.be.at.most(oneSecondAfter, 'blah'); }, "blah: expected " + nowISO + " to be above " + afterISO); err(function(){ ([]).should.have.length.of.at.most(now, 'blah'); }, "blah: the argument to most must be a number"); err(function(){ ('').should.not.have.lengthOf.at.most(now, 'blah'); }, "blah: the argument to most must be a number"); err(function () { now.should.have.length.of.at.most(0, 'blah'); }, "blah: expected " + nowISO + " to have property 'length'"); err(function () { now.should.not.have.lengthOf.at.most(0, 'blah'); }, "blah: expected " + nowISO + " to have property 'length'"); err(function () { now.should.be.at.most(0, 'blah'); }, "blah: the argument to most must be a date"); err(function () { now.should.be.at.most(null, 'blah'); }, "blah: the argument to most must be a date"); err(function () { (1).should.not.be.at.most(now, 'blah'); }, "blah: the argument to most must be a number"); err(function () { now.should.not.be.at.most(undefined); }, "the argument to most must be a date"); }); it('match(regexp)', function(){ 'foobar'.should.match(/^foo/) 'foobar'.should.not.match(/^bar/) err(function(){ 'foobar'.should.match(/^bar/i, 'blah') }, "blah: expected 'foobar' to match /^bar/i"); err(function(){ 'foobar'.should.not.match(/^foo/i, 'blah') }, "blah: expected 'foobar' not to match /^foo/i"); }); it('lengthOf(n)', function(){ 'test'.should.have.length(4); 'test'.should.have.lengthOf(4); 'test'.should.not.have.length(3); 'test'.should.not.have.lengthOf(3); [1,2,3].should.have.length(3); [1,2,3].should.have.lengthOf(3); err(function(){ (4).should.have.length(3, 'blah'); }, 'blah: expected 4 to have property \'length\''); err(function(){ (4).should.have.lengthOf(3, 'blah'); }, 'blah: expected 4 to have property \'length\''); err(function(){ 'asd'.should.not.have.length(3, 'blah'); }, "blah: expected 'asd' to not have a length of 3"); err(function(){ 'asd'.should.not.have.lengthOf(3, 'blah'); }, "blah: expected 'asd' to not have a length of 3"); (new Map()).should.have.length(0); (new Map()).should.have.lengthOf(0); var map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); map.should.have.length(3); map.should.have.lengthOf(3); err(function(){ map.should.not.have.length(3, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to not have a size of 3"); err(function(){ map.should.not.have.lengthOf(3, 'blah'); }, "blah: expected Map{ 'a' => 1, 'b' => 2, 'c' => 3 } to not have a size of 3"); (new Set()).should.have.length(0); (new Set()).should.have.lengthOf(0); var set = new Set(); set.add(1); set.add(2); set.add(3); set.should.have.length(3); set.should.have.lengthOf(3); err(function(){ set.should.not.have.length(3, 'blah'); }, "blah: expected Set{ 1, 2, 3 } to not have a size of 3"); err(function(){ set.should.not.have.lengthOf(3, 'blah');; }, "blah: expected Set{ 1, 2, 3 } to not have a size of 3"); }); it('eql(val)', function(){ var a = new Date(1, 2, 3) , b = new Date(4, 5, 6); a.should.eql(a); a.should.not.eql(b); a.should.not.eql({}); 'test'.should.eql('test'); ({ foo: 'bar' }).should.eql({ foo: 'bar' }); /a/.should.eql(/a/); /a/.should.not.eql(/b/); /a/.should.not.eql({}); /a/g.should.eql(/a/g); /a/g.should.not.eql(/b/g); /a/i.should.eql(/a/i); /a/i.should.not.eql(/b/i); /a/m.should.eql(/a/m); /a/m.should.not.eql(/b/m); (1).should.eql(1); '4'.should.not.eql(4); var sym = Symbol(); sym.should.eql(sym); err(function(){ (4).should.eql(3, 'blah'); }, 'blah: expected 4 to deeply equal 3'); }); it('equal(val)', function(){ 'test'.should.equal('test'); (1).should.equal(1); var sym = Symbol(); sym.should.equal(sym); err(function(){ (4).should.equal(3, 'blah'); }, 'blah: expected 4 to equal 3'); err(function(){ '4'.should.equal(4, 'blah'); }, "blah: expected '4' to equal 4"); }); it('deep.equal(val)', function(){ ({ foo: 'bar' }).should.deep.equal({ foo: 'bar' }); ({ foo: 'bar' }).should.not.deep.equal({ foo: 'baz' }); err(function(){ ({foo: 'bar'}).should.deep.equal({foo: 'baz'}, 'blah'); }, "blah: expected { foo: 'bar' } to deeply equal { foo: 'baz' }"); err(function(){ ({foo: 'bar'}).should.not.deep.equal({foo: 'bar'}, 'blah'); }, "blah: expected { foo: 'bar' } to not deeply equal { foo: 'bar' }"); }); it('empty', function(){ function FakeArgs() {}; FakeArgs.prototype.length = 0; ''.should.be.empty; 'foo'.should.not.be.empty; ([]).should.be.empty; (['foo']).should.not.be.empty; (new FakeArgs()).should.be.empty; ({arguments: 0}).should.not.be.empty; ({}).should.be.empty; ({foo: 'bar'}).should.not.be.empty; err(function(){ (new WeakMap()).should.not.be.empty; }, ".empty was passed a weak collection"); err(function(){ (new WeakSet()).should.not.be.empty; }, ".empty was passed a weak collection"); (new Map()).should.be.empty; // Not using Map constructor args because not supported in IE 11. var map = new Map(); map.set('a', 1); map.should.not.be.empty; err(function(){ (new Map()).should.not.be.empty; }, "expected Map{} not to be empty"); map = new Map(); map.key = 'val'; map.should.be.empty; err(function(){ map.should.not.be.empty; }, "expected Map{} not to be empty"); (new Set()).should.be.empty; // Not using Set constructor args because not supported in IE 11. var set = new Set(); set.add(1); set.should.not.be.empty; err(function(){ (new Set()).should.not.be.empty; }, "expected Set{} not to be empty"); set = new Set(); set.key = 'val'; set.should.be.empty; err(function(){ set.should.not.be.empty; }, "expected Set{} not to be empty"); err(function(){ ''.should.not.be.empty; }, "expected \'\' not to be empty"); err(function(){ 'foo'.should.be.empty; }, "expected \'foo\' to be empty"); err(function(){ ([]).should.not.be.empty; }, "expected [] not to be empty"); err(function(){ (['foo']).should.be.empty; }, "expected [ \'foo\' ] to be empty"); err(function(){ (new FakeArgs()).should.not.be.empty; }, "expected FakeArgs{} not to be empty"); err(function(){ ({arguments: 0}).should.be.empty; }, "expected { arguments: +0 } to be empty"); err(function(){ ({}).should.not.be.empty; }, "expected {} not to be empty"); err(function(){ ({foo: 'bar'}).should.be.empty; }, "expected { foo: \'bar\' } to be empty"); err(function(){ (0).should.be.empty; }, ".empty was passed non-string primitive +0"); err(function(){ (1).should.be.empty; }, ".empty was passed non-string primitive 1"); err(function(){ true.should.be.empty; }, ".empty was passed non-string primitive true"); err(function(){ false.should.be.empty; }, ".empty was passed non-string primitive false"); err(function(){ Symbol().should.be.empty; }, ".empty was passed non-string primitive Symbol()"); err(function(){ Symbol.iterator.should.be.empty; }, ".empty was passed non-string primitive Symbol(Symbol.iterator)"); err(function(){ (function() {}).should.be.empty; }, ".empty was passed a function"); if (FakeArgs.name === 'FakeArgs') { err(function(){ FakeArgs.should.be.empty; }, ".empty was passed a function FakeArgs"); } }); it('finite(value)', function() { (4).should.be.finite; (-10).should.be.finite; err(function(){ (NaN).should.be.finite; }, "expected NaN to be a finite number"); err(function(){ (Infinity).should.be.finite; }, "expected Infinity to be a finite number"); err(function(){ ('foo').should.be.finite; }, "expected \'foo\' to be a finite number"); err(function(){ ([]).should.be.finite; }, "expected [] to be a finite number"); err(function(){ ({}).should.be.finite; }, "expected {} to be a finite number"); }); it('property(name)', function(){ 'test'.should.have.property('length'); (4).should.not.have.property('length'); ({ 1: 1 }).should.have.property(1); ({ a: 1 }).should.have.property('toString'); err(function(){ 'asd'.should.have.property('foo'); }, "expected 'asd' to have property 'foo'"); err(function() { ({a: {b: 1}}).should.have.own.nested.property("a.b"); }, "The \"nested\" and \"own\" flags cannot be combined."); err(function () { ({a:1}).should.have.property(undefined); }, "the argument to property must be a string, number, or symbol"); }); it('property(name, val)', function(){ 'test'.should.have.property('length', 4); 'asd'.should.have.property('constructor', String); ({ 1: 1 }).should.have.property(1, 1); ({ a: 1 }).should.have.property('toString', Object.prototype.toString); 'test'.should.not.have.property('length', 3); 'test'.should.not.have.property('foo', 4); ({a: {b: 1}}).should.not.have.property('a', {b: 1}); err(function(){ 'asd'.should.have.property('length', 4, 'blah'); }, "blah: expected 'asd' to have property 'length' of 4, but got 3"); err(function(){ 'asd'.should.not.have.property('length', 3, 'blah'); }, "blah: expected 'asd' to not have property 'length' of 3"); err(function(){ 'asd'.should.have.property('constructor', Number, 'blah'); }, "blah: expected 'asd' to have property 'constructor' of [Function Number], but got [Function String]"); err(function() { ({a: {b: 1}}).should.have.own.nested.property("a.b", 1, 'blah'); }, "blah: The \"nested\" and \"own\" flags cannot be combined."); }); it('deep.property(name, val)', function () { var obj = {a: {b: 1}}; obj.should.have.deep.property('a', {b: 1}); obj.should.not.have.deep.property('a', {b: 7}); obj.should.not.have.deep.property('a', {z: 1}); obj.should.not.have.deep.property('z', {b: 1}); err(function () { obj.should.have.deep.property('a', {b: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'a' of { b: 7 }, but got { b: 1 }"); err(function () { obj.should.have.deep.property('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep property 'z'"); err(function () { obj.should.not.have.deep.property('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep property 'a' of { b: 1 }"); }); it('ownProperty(name)', function(){ 'test'.should.have.own.property('length'); 'test'.should.have.ownProperty('length'); 'test'.should.haveOwnProperty('length'); 'test'.should.not.have.own.property('iDontExist'); 'test'.should.not.have.ownProperty('iDontExist'); 'test'.should.not.haveOwnProperty('iDontExist'); ({ a: 1 }).should.not.have.own.property('toString'); ({ a: 1 }).should.not.have.ownProperty('toString'); ({ a: 1 }).should.not.haveOwnProperty('toString'); ({ length: 12 }).should.have.own.property('length'); ({ length: 12 }).should.have.ownProperty('length'); ({ length: 12 }).should.haveOwnProperty('length'); ({ length: 12 }).should.not.have.own.property('iDontExist'); ({ length: 12 }).should.not.have.ownProperty('iDontExist'); ({ length: 12 }).should.not.haveOwnProperty('iDontExist'); ({ 1: 1 }).should.have.ownProperty(1); var objNoHasOwnProperty = {hasOwnProperty: null}; objNoHasOwnProperty.a = 'a'; objNoHasOwnProperty.should.have.own.property('a'); objNoHasOwnProperty.should.have.ownProperty('a'); objNoHasOwnProperty.should.haveOwnProperty('a'); // Chaining property's value 'test'.should.have.own.property('length').that.is.a('number'); 'test'.should.have.ownProperty('length').that.is.a('number'); 'test'.should.haveOwnProperty('length').that.is.a('number'); err(function(){ ({ length: 12 }).should.have.own.property('iDontExist'); }, "expected { length: 12 } to have own property 'iDontExist'"); err(function(){ ({ length: 12 }).should.not.have.own.property('length'); }, "expected { length: 12 } to not have own property 'length'"); err(function(){ ({ length: 12 }).should.have.ownProperty('iDontExist'); }, "expected { length: 12 } to have own property 'iDontExist'"); err(function(){ ({ length: 12 }).should.not.have.ownProperty('length'); }, "expected { length: 12 } to not have own property 'length'"); err(function(){ ({ length: 12 }).should.haveOwnProperty('iDontExist'); }, "expected { length: 12 } to have own property 'iDontExist'"); err(function(){ ({ length: 12 }).should.not.haveOwnProperty('length'); }, "expected { length: 12 } to not have own property 'length'"); }); it('ownProperty(name, value)', function(){ 'test'.should.have.own.property('length', 4); 'test'.should.have.ownProperty('length', 4); 'test'.should.haveOwnProperty('length', 4); 'test'.should.not.have.own.property('length', 1337); 'test'.should.not.have.ownProperty('length', 1337); 'test'.should.not.haveOwnProperty('length', 1337); 'test'.should.not.have.own.property('toString', Object.prototype.toString); 'test'.should.not.have.ownProperty('toString', Object.prototype.toString); 'test'.should.not.haveOwnProperty('toString', Object.prototype.toString); ({a: {b: 1}}).should.not.have.own.property('a', {b: 1}); ({a: {b: 1}}).should.not.have.ownProperty('a', {b: 1}); ({a: {b: 1}}).should.not.haveOwnProperty('a', {b: 1}); ({ length: 12 }).should.have.own.property('length', 12); ({ length: 12 }).should.have.ownProperty('length', 12); ({ length: 12 }).should.haveOwnProperty('length', 12); ({ length: 12 }).should.not.have.own.property('length', 15); ({ length: 12 }).should.not.have.ownProperty('length', 15); ({ length: 12 }).should.not.haveOwnProperty('length', 15); // Chaining property's value 'test'.should.have.own.property('length', 4).that.is.a('number'); 'test'.should.have.ownProperty('length', 4).that.is.a('number'); 'test'.should.haveOwnProperty('length', 4).that.is.a('number'); err(function(){ ({ length: 12 }).should.have.own.property('iDontExist', 12, 'blah'); }, "blah: expected { length: 12 } to have own property 'iDontExist'"); err(function() { ({ length: 12 }).should.not.have.own.property('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { ({ length: 12 }).should.have.own.property('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); err(function(){ ({ length: 12 }).should.have.ownProperty('iDontExist', 12); }, "expected { length: 12 } to have own property 'iDontExist'"); err(function() { ({ length: 12 }).should.not.have.ownProperty('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { ({ length: 12 }).should.have.ownProperty('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); err(function(){ ({ length: 12 }).should.haveOwnProperty('iDontExist', 12); }, "expected { length: 12 } to have own property 'iDontExist'"); err(function() { ({ length: 12 }).should.not.haveOwnProperty('length', 12); }, "expected { length: 12 } to not have own property 'length' of 12"); err(function() { ({ length: 12 }).should.haveOwnProperty('length', 15); }, "expected { length: 12 } to have own property 'length' of 15, but got 12"); }); it('deep.own.property(name, val)', function () { var obj = {a: {b: 1}}; obj.should.have.deep.own.property('a', {b: 1}); obj.should.have.deep.ownProperty('a', {b: 1}); obj.should.deep.haveOwnProperty('a', {b: 1}); obj.should.not.have.deep.own.property('a', {z: 1}); obj.should.not.have.deep.ownProperty('a', {z: 1}); obj.should.not.deep.haveOwnProperty('a', {z: 1}); obj.should.not.have.deep.own.property('a', {b: 7}); obj.should.not.have.deep.ownProperty('a', {b: 7}); obj.should.not.deep.haveOwnProperty('a', {b: 7}); obj.should.not.have.deep.own.property('toString', Object.prototype.toString); obj.should.not.have.deep.ownProperty('toString', Object.prototype.toString); obj.should.not.deep.haveOwnProperty('toString', Object.prototype.toString); err(function () { obj.should.have.deep.own.property('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { obj.should.have.deep.own.property('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { obj.should.not.have.deep.own.property('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); err(function () { obj.should.have.deep.ownProperty('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { obj.should.have.deep.ownProperty('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { obj.should.not.have.deep.ownProperty('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); err(function () { obj.should.deep.haveOwnProperty('a', {z: 7}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'a' of { z: 7 }, but got { b: 1 }"); err(function () { obj.should.deep.haveOwnProperty('z', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to have deep own property 'z'"); err(function () { obj.should.not.deep.haveOwnProperty('a', {b: 1}, 'blah'); }, "blah: expected { a: { b: 1 } } to not have deep own property 'a' of { b: 1 }"); }); it('nested.property(name)', function(){ ({ 'foo.bar': 'baz'}).should.not.have.nested.property('foo.bar'); ({ foo: { bar: 'baz' } }).should.have.nested.property('foo.bar'); ({ 'foo': [1, 2, 3] }).should.have.nested.property('foo[1]'); ({ 'foo.bar[]': 'baz'}).should.have.nested.property('foo\\.bar\\[\\]'); ({a:1}).should.have.nested.property('a'); err(function(){ ({a:1}).should.have.nested.property({'a':'1'}); }, "the argument to property must be a string when using nested syntax"); err(function(){ ({ 'foo.bar': 'baz' }).should.have.nested.property('foo.bar'); }, "expected { 'foo.bar': 'baz' } to have nested property 'foo.bar'"); }); it('nested.property(name, val)', function(){ ({ foo: { bar: 'baz' } }).should.have.nested.property('foo.bar', 'baz'); ({ foo: { bar: 'baz' } }).should.not.have.nested.property('foo.bar', 'quux'); ({ foo: { bar: 'baz' } }).should.not.have.nested.property('foo.quux', 'baz'); ({a: {b: {c: 1}}}).should.not.have.nested.property('a.b', {c: 1}); err(function(){ ({ foo: { bar: 'baz' } }).should.have.nested.property('foo.bar', 'quux', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to have nested property 'foo.bar' of 'quux', but got 'baz'"); err(function(){ ({ foo: { bar: 'baz' } }).should.not.have.nested.property('foo.bar', 'baz', 'blah'); }, "blah: expected { foo: { bar: 'baz' } } to not have nested property 'foo.bar' of 'baz'"); }); it('deep.nested.property(name, val)', function () { var obj = {a: {b: {c: 1}}}; obj.should.have.deep.nested.property('a.b', {c: 1}); obj.should.not.have.deep.nested.property('a.b', {c: 7}); obj.should.not.have.deep.nested.property('a.b', {z: 1}); obj.should.not.have.deep.nested.property('a.z', {c: 1}); err(function () { obj.should.have.deep.nested.property('a.b', {c: 7}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.b' of { c: 7 }, but got { c: 1 }"); err(function () { obj.should.have.deep.nested.property('a.z', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to have deep nested property 'a.z'"); err(function () { obj.should.not.have.deep.nested.property('a.b', {c: 1}, 'blah'); }, "blah: expected { a: { b: { c: 1 } } } to not have deep nested property 'a.b' of { c: 1 }"); }); it('ownPropertyDescriptor(name)', function(){ 'test'.should.haveOwnPropertyDescriptor('length'); 'test'.should.have.ownPropertyDescriptor('length'); 'test'.should.not.have.ownPropertyDescriptor('foo'); ({ 1: 1 }).should.have.ownPropertyDescriptor(1); var obj = { }, obj2 = { }; var descriptor = { configurable: false, enumerable: true, writable: true, value: NaN }; Object.defineProperty(obj, 'test', descriptor); obj.should.haveOwnPropertyDescriptor('test', descriptor); Object.defineProperty(obj2, 1, descriptor); obj2.should.haveOwnPropertyDescriptor(1, descriptor); err(function(){ obj.should.not.haveOwnPropertyDescriptor('test', descriptor, 'blah'); }, /^blah: expected the own property descriptor for 'test' on \{ test: NaN \} to not match \{ [^\}]+ \}$/); err(function(){ var wrongDescriptor = { configurable: false, enumerable: true, writable: false, value: NaN }; obj.should.haveOwnPropertyDescriptor('test', wrongDescriptor, 'blah'); }, /^blah: expected the own property descriptor for 'test' on \{ test: NaN \} to match \{ [^\}]+ \}, got \{ [^\}]+ \}$/); err(function(){ obj.should.haveOwnPropertyDescriptor('test2', 'blah'); }, "blah: expected { test: NaN } to have an own property descriptor for 'test2'"); obj.should.have.ownPropertyDescriptor('test').and.have.property('enumerable', true); }); it('string()', function(){ 'foobar'.should.contain.string('bar'); 'foobar'.should.contain.string('foo'); 'foobar'.should.not.contain.string('baz'); err(function(){ (3).should.contain.string('baz', 'blah'); }, "blah: expected 3 to be a string"); err(function(){ 'foobar'.should.contain.string('baz', 'blah'); }, "blah: expected 'foobar' to contain 'baz'"); err(function(){ 'foobar'.should.not.contain.string('bar', 'blah'); }, "blah: expected 'foobar' to not contain 'bar'"); }); it('oneOf()', function(){ 'foo'.should.be.oneOf(['foo', 'bar']); 'bar'.should.be.oneOf(['foo', 'bar']); 'baz'.should.not.be.oneOf(['foo', 'bar']); 'baz'.should.not.be.oneOf([]); err(function () { (1).should.be.oneOf([2, 3], 'blah'); }, "blah: expected 1 to be one of [ 2, 3 ]"); err(function () { (1).should.not.be.oneOf([1, 2, 3], 'blah'); }, "blah: expected 1 to not be one of [ 1, 2, 3 ]"); err(function () { (1).should.be.oneOf({}, 'blah'); }, "blah: expected {} to be an array"); }); it('include()', function(){ ['foo', 'bar'].should.include('foo'); ['foo', 'bar'].should.contain('foo'); ['foo', 'bar'].should.include('bar'); [1,2].should.include(1); ['foo', 'bar'].should.not.include('baz'); ['foo', 'bar'].should.not.include(1); // .include should work with Error objects and objects with a custom // `@@toStringTag`. (new Error('foo')).should.include({message: 'foo'}); var customObj = {a: 1}; customObj[Symbol.toStringTag] = 'foo'; customObj.should.include({a: 1}); ({a: 1}).should.include({'toString': Object.prototype.toString}); var obj1 = {a: 1} , obj2 = {b: 2}; [obj1, obj2].should.include(obj1); [obj1, obj2].should.not.include({a: 1}); ({foo: obj1, bar: obj2}).should.include({foo: obj1}); ({foo: obj1, bar: obj2}).should.include({foo: obj1, bar: obj2}); ({foo: obj1, bar: obj2}).should.not.include({foo: {a: 1}}); ({foo: obj1, bar: obj2}).should.not.include({foo: obj1, bar: {b: 2}}); var map = new Map(); var val = [{a: 1}]; map.set('a', val); map.set('b', 2); map.set('c', -0); map.set('d', NaN); map.should.include(val); map.should.not.include([{a: 1}]); map.should.include(2); map.should.not.include(3); map.should.include(0); map.should.include(NaN); var set = new Set(); var val = [{a: 1}]; set.add(val); set.add(2); set.add(-0); set.add(NaN); set.should.include(val); set.should.not.include([{a: 1}]); set.should.include(2); set.should.not.include(3); if (set.has(0)) { // This test is skipped in IE11 because (contrary to spec) IE11 uses // SameValue instead of SameValueZero equality for sets. set.should.include(0); } set.should.include(NaN); var ws = new WeakSet(); var val = [{a: 1}]; ws.add(val); ws.should.include(val); ws.should.not.include([{a: 1}]); ws.should.not.include({}); var sym1 = Symbol() , sym2 = Symbol() , sym3 = Symbol(); [sym1, sym2].should.include(sym1); [sym1, sym2].should.not.include(sym3); err(function(){ ['foo'].should.include('bar', 'blah'); }, "blah: expected [ 'foo' ] to include 'bar'"); err(function(){ ['bar', 'foo'].should.not.include('foo', 'blah'); }, "blah: expected [ 'bar', 'foo' ] to not include 'foo'"); err(function(){ ({a:1}).should.include({b:2}, 'blah'); }, "blah: expected { a: 1 } to have property 'b'"); err(function () { [{a: 1}, {b: 2}].should.include({a: 1}); }, "expected [ { a: 1 }, { b: 2 } ] to include { a: 1 }"); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; [obj1, obj2].should.not.include(obj1); }, "expected [ { a: 1 }, { b: 2 } ] to not include { a: 1 }"); err(function () { ({foo: {a: 1}, bar: {b: 2}}).should.include({foo: {a: 1}}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to have property 'foo' of { a: 1 }, but got { a: 1 }"); err(function () { var obj1 = {a: 1} , obj2 = {b: 2}; ({foo: obj1, bar: obj2}).should.not.include({foo: obj1, bar: obj2}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to not have property 'foo' of { a: 1 }"); err(function(){ (true).should.include(true, 'blah'); }, "blah: the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function(){ (42).should.include(4); }, "the given combination of arguments (number and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); err(function(){ (true).should.not.include(true); }, "the given combination of arguments (boolean and boolean) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a boolean" ); err(function(){ (42).should.not.include(4); }, "the given combination of arguments (number and number) is invalid for this assertion. " + "You can use an array, a map, an object, a set, a string, or a weakset instead of a number" ); }); it('deep.include()', function () { var obj1 = {a: 1} , obj2 = {b: 2}; [obj1, obj2].should.deep.include({a: 1}); [obj1, obj2].should.not.deep.include({a: 9}); [obj1, obj2].should.not.deep.include({z: 1}); ({foo: obj1, bar: obj2}).should.deep.include({foo: {a: 1}}); ({foo: obj1, bar: obj2}).should.deep.include({foo: {a: 1}, bar: {b: 2}}); ({foo: obj1, bar: obj2}).should.not.deep.include({foo: {a: 9}}); ({foo: obj1, bar: obj2}).should.not.deep.include({foo: {z: 1}}); ({foo: obj1, bar: obj2}).should.not.deep.include({baz: {a: 1}}); ({foo: obj1, bar: obj2}).should.not.deep.include({foo: {a: 1}, bar: {b: 9}}); var map = new Map(); map.set(1, [{a: 1}]); map.should.deep.include([{a: 1}]); var set = new Set(); set.add([{a: 1}]); set.should.deep.include([{a: 1}]); err(function() { new WeakSet().should.deep.include({}, 'foo'); }, 'foo: unable to use .deep.include with WeakSet'); err(function () { [obj1, obj2].should.deep.include({a: 9}, 'blah'); }, "blah: expected [ { a: 1 }, { b: 2 } ] to deep include { a: 9 }"); err(function () { [obj1, obj2].should.not.deep.include({a: 1}); }, "expected [ { a: 1 }, { b: 2 } ] to not deep include { a: 1 }"); err(function () { ({foo: obj1, bar: obj2}).should.deep.include({foo: {a: 1}, bar: {b: 9}}); }, "expected { foo: { a: 1 }, bar: { b: 2 } } to have deep property 'bar' of { b: 9 }, but got { b: 2 }"); err(function () { ({foo: obj1, bar: obj2}).should.not.deep.include({foo: {a: 1}, bar: {b: 2}}, 'blah'); }, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }"); }); it('nested.include()', function () { ({a: {b: ['x', 'y']}}).should.nested.include({'a.b[1]': 'y'}); ({a: {b: ['x', 'y']}}).should.not.nested.include({'a.b[1]': 'x'}); ({a: {b: ['x', 'y']}}).should.not.nested.include({'a.c': 'y'}); ({a: {b: [{x: 1}]}}).should.not.nested.include({'a.b[0]': {x: 1}}); ({'.a': {'[b]': 'x'}}).should.nested.include({'\\.a.\\[b\\]': 'x'}); ({'.a': {'[b]': 'x'}}).should.not.nested.include({'\\.a.\\[b\\]': 'y'}); err(function () { ({a: {b: ['x', 'y']}}).should.nested.include({'a.b[1]': 'x'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'"); err(function () { ({a: {b: ['x', 'y']}}).should.nested.include({'a.c': 'y'}); }, "expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.c'"); err(function () { ({a: {b: ['x', 'y']}}).should.not.nested.include({'a.b[1]': 'y'}, 'blah'); }, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'"); }); it('deep.nested.include()', function () { ({a: {b: [{x: 1}]}}).should.deep.nested.include({'a.b[0]': {x: 1}}); ({a: {b: [{x: 1}]}}).should.not.deep.nested.include({'a.b[0]': {y: 2}}); ({a: {b: [{x: 1}]}}).should.not.deep.nested.include({'a.c': {x: 1}}); ({'.a': {'[b]': {x: 1}}}) .should.deep.nested.include({'\\.a.\\[b\\]': {x: 1}}); ({'.a': {'[b]': {x: 1}}}) .should.not.deep.nested.include({'\\.a.\\[b\\]': {y: 2}}); err(function () { ({a: {b: [{x: 1}]}}).should.deep.nested.include({'a.b[0]': {y: 2}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }"); err(function () { ({a: {b: [{x: 1}]}}).should.deep.nested.include({'a.c': {x: 1}}); }, "expected { a: { b: [ { x: 1 } ] } } to have deep nested property 'a.c'"); err(function () { ({a: {b: [{x: 1}]}}).should.not.deep.nested.include({'a.b[0]': {x: 1}}, 'blah'); }, "blah: expected { a: { b: [ { x: 1 } ] } } to not have deep nested property 'a.b[0]' of { x: 1 }"); }); it('own.include()', function () { ({a: 1}).should.own.include({a: 1}); ({a: 1}).should.not.own.include({a: 3}); ({a: 1}).should.not.own.include({'toString': Object.prototype.toString}); ({a: {b: 2}}).should.not.own.include({a: {b: 2}}); err(function () { ({a: 1}).should.own.include({a: 3}, 'blah'); }, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1"); err(function () { ({a: 1}).should.own.include({'toString': Object.prototype.toString}); }, "expected { a: 1 } to have own property 'toString'"); err(function () { ({a: 1}).should.not.own.include({a: 1}, 'blah'); }, "blah: expected { a: 1 } to not have own property 'a' of 1"); }); it('deep.own.include()', function () { ({a: {b: 2}}).should.deep.own.include({a: {b: 2}}); ({a: {b: 2}}).should.not.deep.own.include({a: {c: 3}}); ({a: {b: 2}}) .should.not.deep.own.include({'toString': Object.prototype.toString}); err(function () { ({a: {b: 2}}).should.deep.own.include({a: {c: 3}}, 'blah'); }, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }"); err(function () { ({a: {b: 2}}).should.deep.own.include({'toString': Object.prototype.toString}); }, "expected { a: { b: 2 } } to have deep own property 'toString'"); err(function () { ({a: {b: 2}}).should.not.deep.own.include({a: {b: 2}}, 'blah'); }, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }"); }); it('keys(array|Object|arguments)', function(){ ({ foo: 1 }).should.have.keys(['foo']); ({ foo: 1 }).should.have.keys({ 'foo': 6 }); ({ foo: 1, bar: 2 }).should.have.keys(['foo', 'bar']); ({ foo: 1, bar: 2 }).should.have.keys('foo', 'bar'); ({ foo: 1, bar: 2 }).should.have.keys({ 'foo': 6, 'bar': 7 }); ({ foo: 1, bar: 2, baz: 3 }).should.include.keys('foo', 'bar'); ({ foo: 1, bar: 2, baz: 3 }).should.contain.keys('bar', 'foo'); ({ foo: 1, bar: 2, baz: 3 }).should.contain.keys('baz'); ({ foo: 1, bar: 2 }).should.contain.keys('foo'); ({ foo: 1, bar: 2 }).should.contain.keys('bar', 'foo'); ({ foo: 1, bar: 2 }).should.contain.keys(['foo']); ({ foo: 1, bar: 2 }).should.contain.keys(['bar']); ({ foo: 1, bar: 2 }).should.contain.keys(['bar', 'foo']); ({ foo: 1, bar: 2 }).should.contain.keys({ 'foo': 6 }); ({ foo: 1, bar: 2 }).should.contain.keys({ 'bar': 7 }); ({ foo: 1, bar: 2 }).should.contain.keys({ 'foo': 6 }); ({ foo: 1, bar: 2 }).should.not.have.keys('baz'); ({ foo: 1, bar: 2 }).should.not.have.keys('foo'); ({ foo: 1, bar: 2 }).should.not.have.keys('foo', 'baz'); ({ foo: 1, bar: 2 }).should.not.contain.keys('baz'); ({ foo: 1, bar: 2 }).should.not.contain.keys('foo', 'baz'); ({ foo: 1, bar: 2 }).should.not.contain.keys('baz', 'foo'); ({ foo: 1, bar: 2 }).should.have.any.keys('foo', 'baz'); ({ foo: 1, bar: 2 }).should.have.any.keys('foo'); ({ foo: 1, bar: 2 }).should.contain.any.keys('bar', 'baz'); ({ foo: 1, bar: 2 }).should.contain.any.keys(['foo']); ({ foo: 1, bar: 2 }).should.have.all.keys(['bar', 'foo']); ({ foo: 1, bar: 2 }).should.contain.all.keys(['bar', 'foo']); ({ foo: 1, bar: 2 }).should.contain.any.keys({ 'foo': 6 }); ({ foo: 1, bar: 2 }).should.have.all.keys({ 'foo': 6, 'bar': 7 }); ({ foo: 1, bar: 2 }).should.contain.all.keys({ 'bar': 7, 'foo': 6 }); ({ foo: 1, bar: 2 }).should.not.have.any.keys('baz', 'abc', 'def'); ({ foo: 1, bar: 2 }).should.not.have.any.keys('baz'); ({ foo: 1, bar: 2 }).should.not.contain.any.keys('baz'); ({ foo: 1, bar: 2 }).should.not.have.all.keys(['baz', 'foo']); ({ foo: 1, bar: 2 }).should.not.contain.all.keys(['baz', 'foo']); ({ foo: 1, bar: 2 }).should.not.have.all.keys({ 'baz': 8, 'foo': 7 }); ({ foo: 1, bar: 2 }).should.not.contain.all.keys({ 'baz': 8, 'foo': 7 }); ({ 1: 1, 2: 2 }).should.have.keys(1, 2); ({ 1: 1, 2: 2 }).should.have.any.keys(1, 3); ({ 1: 1, 2: 2 }).should.contain.keys(1); var enumProp1 = 'enumProp1' , enumProp2 = 'enumProp2' , nonEnumProp = 'nonEnumProp' , obj = {}; obj[enumProp1] = 'enumProp1'; obj[enumProp2] = 'enumProp2'; Object.defineProperty(obj, nonEnumProp, { enumerable: false, value: 'nonEnumProp' }); obj.should.have.all.keys([enumProp1, enumProp2]); obj.should.not.have.all.keys([enumProp1, enumProp2, nonEnumProp]); var sym1 = Symbol('sym1') , sym2 = Symbol('sym2') , sym3 = Symbol('sym3') , str = 'str' , obj = {}; obj[sym1] = 'sym1'; obj[sym2] = 'sym2'; obj[str] = 'str'; Object.defineProperty(obj, sym3, { enumerable: false, value: 'sym3' }); obj.should.have.all.keys([sym1, sym2, str]); obj.should.not.have.all.keys([sym1, sym2, sym3, str]); // Not using Map constructor args because not supported in IE 11. var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testMap = new Map(); testMap.set(aKey, 'aValue'); testMap.set(anotherKey, 'anotherValue'); testMap.should.have.any.keys(aKey); testMap.should.have.any.keys('thisDoesNotExist', 'thisToo', aKey); testMap.should.have.all.keys(aKey, anotherKey); testMap.should.contain.all.keys(aKey); testMap.should.not.contain.all.keys(aKey, 'thisDoesNotExist'); testMap.should.not.have.any.keys({iDoNot: 'exist'}); testMap.should.not.have.all.keys('thisDoesNotExist', 'thisToo', anotherKey); testMap.should.have.any.keys([aKey]); testMap.should.have.any.keys([20, 1, aKey]); testMap.should.have.all.keys([aKey, anotherKey]); testMap.should.not.have.any.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); testMap.should.not.have.any.keys([20, 1, {13: 37}]); testMap.should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]); // Ensure the assertions above use strict equality err(function() { testMap.should.have.any.keys({thisIs: 'anExampleObject'}); }); err(function() { testMap.should.have.all.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); }); err(function() { testMap.should.contain.all.keys({thisIs: 'anExampleObject'}); }); err(function() { testMap.should.have.any.keys([{thisIs: 'anExampleObject'}]); }); err(function() { testMap.should.have.all.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); }); // Using the same assertions as above but with `.deep` flag instead of using referential equality testMap.should.have.any.deep.keys({thisIs: 'anExampleObject'}); testMap.should.have.any.deep.keys('thisDoesNotExist', 'thisToo', {thisIs: 'anExampleObject'}); testMap.should.contain.all.deep.keys({thisIs: 'anExampleObject'}); testMap.should.not.contain.all.deep.keys({thisIs: 'anExampleObject'}, 'thisDoesNotExist'); testMap.should.not.have.any.deep.keys({iDoNot: 'exist'}); testMap.should.not.have.all.deep.keys('thisDoesNotExist', 'thisToo', {doingThisBecauseOf: 'referential equality'}); testMap.should.have.any.deep.keys([{thisIs: 'anExampleObject'}]); testMap.should.have.any.deep.keys([20, 1, {thisIs: 'anExampleObject'}]); testMap.should.have.all.deep.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); testMap.should.not.have.any.deep.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); testMap.should.not.have.any.deep.keys([20, 1, {13: 37}]); var weirdMapKey1 = Object.create(null) , weirdMapKey2 = {toString: NaN} , weirdMapKey3 = [] , weirdMap = new Map(); weirdMap.set(weirdMapKey1, 'val1'); weirdMap.set(weirdMapKey2, 'val2'); weirdMap.should.have.all.keys([weirdMapKey1, weirdMapKey2]); weirdMap.should.not.have.all.keys([weirdMapKey1, weirdMapKey3]); var symMapKey1 = Symbol() , symMapKey2 = Symbol() , symMapKey3 = Symbol() , symMap = new Map(); symMap.set(symMapKey1, 'val1'); symMap.set(symMapKey2, 'val2'); symMap.should.have.all.keys(symMapKey1, symMapKey2); symMap.should.have.any.keys(symMapKey1, symMapKey3); symMap.should.contain.all.keys(symMapKey2, symMapKey1); symMap.should.contain.any.keys(symMapKey3, symMapKey1); symMap.should.not.have.all.keys(symMapKey1, symMapKey3); symMap.should.not.have.any.keys(symMapKey3); symMap.should.not.contain.all.keys(symMapKey3, symMapKey1); symMap.should.not.contain.any.keys(symMapKey3); var errMap = new Map(); errMap.set({ foo: 1 }); err(function(){ errMap.should.have.keys(); }, "keys required"); err(function(){ errMap.should.have.keys([]); }, "keys required"); err(function(){ errMap.should.contain.keys(); }, "keys required"); err(function(){ errMap.should.contain.keys([]); }, "keys required"); // Uncomment these after solving https://github.com/chaijs/chai/issues/662 // This should fail because of referential equality (this is a strict comparison) // err(function(){ // new Map([[{foo: 1}, 'bar']]).should.contain.keys({ foo: 1 }); // }, 'expected [ [ { foo: 1 }, 'bar' ] ] to contain key { foo: 1 }'); // err(function(){ // new Map([[{foo: 1}, 'bar']]).should.contain.deep.keys({ iDoNotExist: 0 }); // }, 'expected [ { foo: 1 } ] to deeply contain key { iDoNotExist: 0 }'); // Not using Set constructor args because not supported in IE 11. var aKey = {thisIs: 'anExampleObject'} , anotherKey = {doingThisBecauseOf: 'referential equality'} , testSet = new Set(); testSet.add(aKey); testSet.add(anotherKey); testSet.should.have.any.keys(aKey); testSet.should.have.any.keys('thisDoesNotExist', 'thisToo', aKey); testSet.should.have.all.keys(aKey, anotherKey); testSet.should.contain.all.keys(aKey); testSet.should.not.contain.all.keys(aKey, 'thisDoesNotExist'); testSet.should.not.have.any.keys({iDoNot: 'exist'}); testSet.should.not.have.any.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); testSet.should.not.have.all.keys('thisDoesNotExist', 'thisToo', anotherKey); testSet.should.have.any.keys([aKey]); testSet.should.have.any.keys([20, 1, aKey]); testSet.should.have.all.keys([aKey, anotherKey]); testSet.should.not.have.any.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); testSet.should.not.have.any.keys([20, 1, {13: 37}]); testSet.should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]); // Ensure the assertions above use strict equality err(function() { testSet.should.have.any.keys({thisIs: 'anExampleObject'}); }); err(function() { testSet.should.have.all.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); }); err(function() { testSet.should.contain.all.keys({thisIs: 'anExampleObject'}); }); err(function() { testSet.should.have.any.keys([{thisIs: 'anExampleObject'}]); }); err(function() { testSet.should.have.all.keys([{thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}]); }); // Using the same assertions as above but with `.deep` flag instead of using referential equality testSet.should.have.any.deep.keys({thisIs: 'anExampleObject'}); testSet.should.have.any.deep.keys('thisDoesNotExist', 'thisToo', {thisIs: 'anExampleObject'}); testSet.should.contain.all.deep.keys({thisIs: 'anExampleObject'}); testSet.should.not.contain.all.deep.keys({thisIs: 'anExampleObject'}, 'thisDoesNotExist'); testSet.should.not.have.any.deep.keys({iDoNot: 'exist'}); testSet.should.not.have.any.deep.keys('thisIsNotAkey', {iDoNot: 'exist'}, {33: 20}); testSet.should.not.have.all.deep.keys('thisDoesNotExist', 'thisToo', {anotherObj: 'foo'}); testSet.should.have.any.deep.keys([{thisIs: 'anExampleObject'}]); testSet.should.have.any.deep.keys([20, 1, {thisIs: 'anExampleObject'}]); testSet.should.have.all.deep.keys({thisIs: 'anExampleObject'}, {doingThisBecauseOf: 'referential equality'}); testSet.should.not.have.any.deep.keys([{13: 37}, 'thisDoesNotExist', 'thisToo']); testSet.should.not.have.any.deep.keys([20, 1, {13: 37}]); testSet.should.not.have.all.deep.keys([{thisIs: 'anExampleObject'}, {'iDoNot': 'exist'}]) var weirdSetKey1 = Object.create(null) , weirdSetKey2 = {toString: NaN} , weirdSetKey3 = [] , weirdSet = new Set(); weirdSet.add(weirdSetKey1); weirdSet.add(weirdSetKey2); weirdSet.should.have.all.keys([weirdSetKey1, weirdSetKey2]); weirdSet.should.not.have.all.keys([weirdSetKey1, weirdSetKey3]); var symSetKey1 = Symbol() , symSetKey2 = Symbol() , symSetKey3 = Symbol() , symSet = new Set(); symSet.add(symSetKey1); symSet.add(symSetKey2); symSet.should.have.all.keys(symSetKey1, symSetKey2); symSet.should.have.any.keys(symSetKey1, symSetKey3); symSet.should.contain.all.keys(symSetKey2, symSetKey1); symSet.should.contain.any.keys(symSetKey3, symSetKey1); symSet.should.not.have.all.keys(symSetKey1, symSetKey3); symSet.should.not.have.any.keys(symSetKey3); symSet.should.not.contain.all.keys(symSetKey3, symSetKey1); symSet.should.not.contain.any.keys(symSetKey3); var errSet = new Set(); errSet.add({ foo: 1 }); err(function(){ errSet.should.have.keys(); }, "keys required"); err(function(){ errSet.should.have.keys([]); }, "keys required"); err(function(){ errSet.should.contain.keys(); }, "keys required"); err(function(){ errSet.should.contain.keys([]); }, "keys required"); err(function(){ new Set([{foo: 1}]).should.contain.keys({ foo: 1 }); }, 'expected Set{ { foo: 1 } } to contain key { foo: 1 }'); err(function(){ new Set([{foo: 1}]).should.contain.deep.keys({ iDoNotExist: 0 }); }, 'expected Set{ { foo: 1 } } to deeply contain key { iDoNotExist: +0 }'); err(function(){ ({ foo: 1 }).should.have.keys(); }, "keys required"); err(function(){ ({ foo: 1 }).should.have.keys([]); }, "keys required"); err(function(){ ({ foo: 1 }).should.not.have.keys([]); }, "keys required"); err(function(){ ({ foo: 1 }).should.contain.keys([]); }, "keys required"); var mixedArgsMsg = 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments' err(function(){ ({}).should.contain.keys(['a'], "b"); }, mixedArgsMsg); err(function(){ ({}).should.contain.keys({ 'a': 1 }, "b"); }, mixedArgsMsg); err(function(){ ({ foo: 1 }).should.have.keys(['bar']); }, "expected { foo: 1 } to have key 'bar'"); err(function(){ ({ foo: 1 }).should.have.keys(['bar', 'baz']); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ ({ foo: 1 }).should.have.keys(['foo', 'bar', 'baz']); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ ({ foo: 1 }).should.not.have.keys(['foo']); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ ({ foo: 1 }).should.not.have.keys(['foo']); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.keys(['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ ({ foo: 1 }).should.not.contain.keys(['foo']); }, "expected { foo: 1 } to not contain key 'foo'"); err(function(){ ({ foo: 1 }).should.contain.keys('foo', 'bar'); }, "expected { foo: 1 } to contain keys 'foo', and 'bar'"); err(function() { ({ foo: 1 }).should.have.any.keys('baz'); }, "expected { foo: 1 } to have key 'baz'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.all.keys(['foo', 'bar']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.any.keys(['foo', 'baz']); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); // repeat previous tests with Object as arg. err(function(){ ({ foo: 1 }).should.have.keys({ 'bar': 1 }); }, "expected { foo: 1 } to have key 'bar'"); err(function(){ ({ foo: 1 }).should.have.keys({ 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'bar', and 'baz'"); err(function(){ ({ foo: 1 }).should.have.keys({ 'foo': 1, 'bar': 1, 'baz': 1}); }, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'"); err(function(){ ({ foo: 1 }).should.not.have.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ ({ foo: 1 }).should.not.have.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not have key 'foo'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.keys({ 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ ({ foo: 1 }).should.not.contain.keys({ 'foo': 1 }); }, "expected { foo: 1 } to not contain key 'foo'"); err(function(){ ({ foo: 1 }).should.contain.keys('foo', 'bar'); }, "expected { foo: 1 } to contain keys 'foo', and 'bar'"); err(function() { ({ foo: 1 }).should.have.any.keys('baz'); }, "expected { foo: 1 } to have key 'baz'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.all.keys({ 'foo': 1, 'bar': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'"); err(function(){ ({ foo: 1, bar: 2 }).should.not.have.any.keys({ 'foo': 1, 'baz': 1}); }, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'"); }); it('keys(array) will not mutate array (#359)', function () { var expected = [ 'b', 'a' ]; var original_order = [ 'b', 'a' ]; var obj = { "b": 1, "a": 1 }; expected.should.deep.equal(original_order); obj.should.keys(original_order); expected.should.deep.equal(original_order); }); it('throw', function () { // See GH-45: some poorly-constructed custom errors don't have useful names // on either their constructor or their constructor prototype, but instead // only set the name inside the constructor itself. var PoorlyConstructedError = function () { this.name = 'PoorlyConstructedError'; }; PoorlyConstructedError.prototype = Object.create(Error.prototype); function CustomError(message) { this.name = 'CustomError'; this.message = message; } CustomError.prototype = Error.prototype; var specificError = new RangeError('boo'); var goodFn = function () { 1==1; } , badFn = function () { throw new Error('testing'); } , stringErrFn = function () { throw 'testing'; } , refErrFn = function () { throw new ReferenceError('hello'); } , ickyErrFn = function () { throw new PoorlyConstructedError(); } , specificErrFn = function () { throw specificError; } , customErrFn = function () { throw new CustomError('foo'); } , emptyErrFn = function () { throw new Error(); } , emptyStringErrFn = function () { throw new Error(''); }; (goodFn).should.not.throw(); (goodFn).should.not.throw(Error); (goodFn).should.not.throw(specificError); (badFn).should.throw(); (badFn).should.throw(Error); (badFn).should.not.throw(ReferenceError); (badFn).should.not.throw(specificError); (stringErrFn).should.throw(); (stringErrFn).should.not.throw(ReferenceError); (stringErrFn).should.not.throw(specificError); (refErrFn).should.throw(); (refErrFn).should.throw(ReferenceError); (refErrFn).should.throw(Error); (refErrFn).should.not.throw(TypeError); (refErrFn).should.not.throw(specificError); (ickyErrFn).should.throw(); (ickyErrFn).should.throw(PoorlyConstructedError); (ickyErrFn).should.throw(Error); (ickyErrFn).should.not.throw(specificError); (specificErrFn).should.throw(specificError); (goodFn).should.not.throw('testing'); (goodFn).should.not.throw(/testing/); (badFn).should.throw(/testing/); (badFn).should.throw('testing'); (badFn).should.not.throw(/hello/); (badFn).should.not.throw('hello'); (emptyStringErrFn).should.throw(''); (emptyStringErrFn).should.not.throw('testing'); (badFn).should.throw(''); (badFn).should.throw(Error, /testing/); (badFn).should.throw(Error, 'testing'); (emptyErrFn).should.not.throw(Error, 'testing'); (stringErrFn).should.throw(/testing/); (stringErrFn).should.throw('testing'); (stringErrFn).should.not.throw(/hello/); (stringErrFn).should.not.throw('hello'); should.throw(badFn); should.throw(refErrFn, ReferenceError); should.throw(refErrFn, Error); should.throw(ickyErrFn, PoorlyConstructedError); should.throw(specificErrFn, specificError); should.not.throw(goodFn); should.not.throw(badFn, ReferenceError); should.not.throw(badFn, specificError); should.throw(badFn, Error, /testing/); should.throw(badFn, Error, 'testing'); (badFn).should.not.throw(Error, 'I am the wrong error message'); (badFn).should.not.throw(TypeError, 'testing'); err(function(){ (goodFn).should.throw(); }, /^expected \[Function( goodFn)*\] to throw an error$/); err(function(){ (goodFn).should.throw(ReferenceError); }, /^expected \[Function( goodFn)*\] to throw ReferenceError$/); err(function(){ (goodFn).should.throw(specificError); }, /^expected \[Function( goodFn)*\] to throw 'RangeError: boo'$/); err(function(){ (badFn).should.not.throw(); }, /^expected \[Function( badFn)*\] to not throw an error but 'Error: testing' was thrown$/); err(function(){ (badFn).should.throw(ReferenceError); }, /^expected \[Function( badFn)*\] to throw 'ReferenceError' but 'Error: testing' was thrown$/); err(function(){ (badFn).should.throw(specificError); }, /^expected \[Function( badFn)*\] to throw 'RangeError: boo' but 'Error: testing' was thrown$/); err(function(){ (badFn).should.not.throw(Error); }, /^expected \[Function( badFn)*\] to not throw 'Error' but 'Error: testing' was thrown$/); err(function(){ (stringErrFn).should.not.throw(); }, /^expected \[Function( stringErrFn)*\] to not throw an error but 'testing' was thrown$/); err(function(){ (stringErrFn).should.throw(ReferenceError); }, /^expected \[Function( stringErrFn)*\] to throw 'ReferenceError' but 'testing' was thrown$/); err(function(){ (stringErrFn).should.throw(specificError); }, /^expected \[Function( stringErrFn)*\] to throw 'RangeError: boo' but 'testing' was thrown$/); err(function(){ (stringErrFn).should.not.throw('testing'); }, /^expected \[Function( stringErrFn)*\] to throw error not including 'testing'$/); err(function(){ (refErrFn).should.not.throw(ReferenceError); }, /^expected \[Function( refErrFn)*\] to not throw 'ReferenceError' but 'ReferenceError: hello' was thrown$/); err(function(){ (badFn).should.throw(PoorlyConstructedError); }, /^expected \[Function( badFn)*\] to throw 'PoorlyConstructedError' but 'Error: testing' was thrown$/); err(function(){ (ickyErrFn).should.not.throw(PoorlyConstructedError); }, /^(expected \[Function( ickyErrFn)*\] to not throw 'PoorlyConstructedError' but)(.*)(PoorlyConstructedError|\{ Object \()(.*)(was thrown)$/); err(function(){ (ickyErrFn).should.throw(ReferenceError); }, /^(expected \[Function( ickyErrFn)*\] to throw 'ReferenceError' but)(.*)(PoorlyConstructedError|\{ Object \()(.*)(was thrown)$/); err(function(){ (specificErrFn).should.throw(new ReferenceError('eek')); }, /^expected \[Function( specificErrFn)*\] to throw 'ReferenceError: eek' but 'RangeError: boo' was thrown$/); err(function(){ (specificErrFn).should.not.throw(specificError); }, /^expected \[Function( specificErrFn)*\] to not throw 'RangeError: boo'$/); err(function (){ (badFn).should.not.throw(/testing/); }, /^expected \[Function( badFn)*\] to throw error not matching \/testing\/$/); err(function () { (badFn).should.throw(/hello/); }, /^expected \[Function( badFn)*\] to throw error matching \/hello\/ but got \'testing\'$/); err(function () { (badFn).should.throw(Error, /hello/, 'blah'); }, /^blah: expected \[Function( badFn)*\] to throw error matching \/hello\/ but got 'testing'$/); err(function () { (badFn).should.throw(Error, 'hello', 'blah'); }, /^blah: expected \[Function( badFn)*\] to throw error including 'hello' but got 'testing'$/); err(function () { (customErrFn).should.not.throw(); }, /^expected \[Function( customErrFn)*\] to not throw an error but 'CustomError: foo' was thrown$/); err(function(){ (badFn).should.not.throw(Error, 'testing'); }, /^expected \[Function( badFn)*\] to not throw 'Error' but 'Error: testing' was thrown$/); err(function(){ (emptyStringErrFn).should.not.throw(Error, ''); }, /^expected \[Function( emptyStringErrFn)*\] to not throw 'Error' but 'Error' was thrown$/); err(function(){ (emptyStringErrFn).should.not.throw(''); }, /^expected \[Function( emptyStringErrFn)*\] to throw error not including ''$/); err(function () { ({}).should.throw(); }, "expected {} to be a function"); err(function () { ({}).should.throw(Error, 'testing', 'blah'); }, "blah: expected {} to be a function"); }); it('respondTo', function(){ function Foo(){}; Foo.prototype.bar = function(){}; Foo.func = function(){}; var bar = {}; bar.foo = function(){}; Foo.should.respondTo('bar'); Foo.should.not.respondTo('foo'); Foo.should.itself.respondTo('func'); Foo.should.itself.not.respondTo('bar'); bar.should.respondTo('foo'); err(function(){ Foo.should.respondTo('baz', 'constructor'); }, /^(constructor: expected)(.*)(\[Function Foo\])(.*)(to respond to \'baz\')$/); err(function(){ bar.should.respondTo('baz', 'object'); }, /^(object: expected)(.*)(\{ foo: \[Function\] \}|\{ Object \()(.*)(to respond to \'baz\')$/); }); it('satisfy', function(){ var matcher = function (num){ return num === 1; }; (1).should.satisfy(matcher); err(function(){ (2).should.satisfy(matcher, 'blah'); }, /^blah: expected 2 to satisfy \[Function( matcher)*\]$/); }); it('closeTo', function(){ (1.5).should.be.closeTo(1.0, 0.5); (10).should.be.closeTo(20, 20); (-10).should.be.closeTo(20, 30); (10).should.be.closeTo(10, 0); (1682.6).should.be.closeTo(1682.7, 0.1); (1n).should.be.closeTo(2n, 1n); err(function(){ (2).should.be.closeTo(1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function() { [1.5].should.be.closeTo(1.0, 0.5, 'blah'); }, "blah: expected [ 1.5 ] to be numeric"); err(function() { (1.5).should.be.closeTo("1.0", 0.5, 'blah'); }, "blah: expected '1.0' to be numeric"); err(function() { (1.5).should.be.closeTo(1.0, true, 'blah'); }, "blah: expected true to be numeric"); err(function() { (1.5).should.be.closeTo(1.0, undefined, 'blah'); }, "blah: A `delta` value is required for `closeTo`"); }); it('approximately', function(){ (1.5).should.be.approximately(1.0, 0.5); (10).should.be.approximately(20, 20); (-10).should.be.approximately(20, 30); (10).should.be.approximately(10, 0); (1682.6).should.be.approximately(1682.7, 0.1); (1n).should.be.approximately(2n, 1n); err(function(){ (2).should.be.approximately(1.0, 0.5, 'blah'); }, "blah: expected 2 to be close to 1 +/- 0.5"); err(function() { [1.5].should.be.approximately(1.0, 0.5); }, "expected [ 1.5 ] to be numeric"); err(function() { (1.5).should.be.approximately("1.0", 0.5); }, "expected '1.0' to be numeric"); err(function() { (1.5).should.be.approximately(1.0, true); }, "expected true to be numeric"); err(function() { (1.5).should.be.approximately(1.0); }, "A `delta` value is required for `closeTo`"); }); it('include.members', function() { [1, 2, 3].should.include.members([3]); [1, 2, 3].should.include.members([]); [1, 2, 3].should.include.members([2, 1]); [1, 2, 3].should.include.members([2, 1, 1]); [1, 2, 3].should.not.include.members([999]); [].should.not.include.members([23]); [{a: 1}].should.not.include.members([{a: 1}]); err(function() { [].should.include.members([43], 'blah'); }, 'blah: expected [] to be a superset of [ 43 ]'); err(function() { [5, 2, 1].should.not.include.members([2]); }, 'expected [ 5, 2, 1 ] to not be a superset of [ 2 ]'); err(function() { 'foo'.should.include.members([12], 'blah'); }, "blah: expected 'foo' to be a superset of [ 12 ]"); err(function() { [1, 2, 3].should.include.members('o', 'blah'); }, "blah: expected [ 1, 2, 3 ] to be a superset of 'o'"); }); it('memberEquals', function() { [1, 2, 3].should.have.same.members([3, 2, 1]); [5, 4].should.have.same.members([5, 4]); [5, 4, 4].should.have.same.members([5, 4, 4]); [].should.have.same.members([]); (new Set([])).should.have.same.members(new Set([])); (new Set([1,2,3])).should.have.same.members(new Set([3,2,1])); [5, 4].should.not.have.same.members([5, 4, 4]); [5, 4, 4].should.not.have.same.members([5, 4]); [5, 4, 4].should.not.have.same.members([5, 4, 3]); [5, 4, 3].should.not.have.same.members([5, 4, 4]); [{a: 1}].should.not.have.same.members([{a: 1}]); (new Set([1,2,3])).should.not.have.same.members(new Set([2,1])); err(function() { [1, 2, 3].should.have.same.members([], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to have the same members as []'); err(function() { [1, 2, 3].should.have.same.members(4, 'blah'); }, 'blah: expected 4 to be an iterable'); }); it('deep.members', function() { [{ id: 1 }].should.have.deep.members([{ id: 1 }]); [{a: 1}, {b: 2}, {b: 2}].should.have.deep.members([{a: 1}, {b: 2}, {b: 2}]); [{ id: 2 }].should.not.have.deep.members([{ id: 1 }]); [{a: 1}, {b: 2}].should.not.have.deep.members([{a: 1}, {b: 2}, {b: 2}]); [{a: 1}, {b: 2}, {b: 2}].should.not.have.deep.members([{a: 1}, {b: 2}]); [{a: 1}, {b: 2}, {b: 2}].should.not.have.deep.members([{a: 1}, {b: 2}, {c: 3}]); [{a: 1}, {b: 2}, {c: 3}].should.not.have.deep.members([{a: 1}, {b: 2}, {b: 2}]); err(function(){ [{ id: 1 }].should.have.deep.members([{ id: 2 }], 'blah') }, 'blah: expected [ { id: 1 } ] to have the same members as [ { id: 2 } ]'); }); it('include.deep.members', function() { [{a: 1}, {b: 2}, {c: 3}].should.include.deep.members([{b: 2}, {a: 1}]); [{a: 1}, {b: 2}, {c: 3}].should.include.deep.members([{b: 2}, {a: 1}, {a: 1}]); [{a: 1}, {b: 2}, {c: 3}].should.not.include.deep.members([{b: 2}, {a: 1}, {f: 5}]); err(function() { [{a: 1}, {b: 2}, {c: 3}].should.include.deep.members([{b: 2}, {a: 1}, {f: 5}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be a superset of [ { b: 2 }, { a: 1 }, { f: 5 } ]'); }); it('ordered.members', function() { [1, 2, 3].should.ordered.members([1, 2, 3]); [1, 2, 2].should.ordered.members([1, 2, 2]); [1, 2, 3].should.not.ordered.members([2, 1, 3]); [1, 2, 3].should.not.ordered.members([1, 2]); [1, 2].should.not.ordered.members([1, 2, 2]); [1, 2, 2].should.not.ordered.members([1, 2]); [1, 2, 2].should.not.ordered.members([1, 2, 3]); [1, 2, 3].should.not.ordered.members([1, 2, 2]); err(function() { [1, 2, 3].should.ordered.members([2, 1, 3], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to have the same ordered members as [ 2, 1, 3 ]'); err(function() { [1, 2, 3].should.not.ordered.members([1, 2, 3]); }, 'expected [ 1, 2, 3 ] to not have the same ordered members as [ 1, 2, 3 ]'); }); it('include.ordered.members', function() { [1, 2, 3].should.include.ordered.members([1, 2]); [1, 2, 3].should.not.include.ordered.members([2, 1]); [1, 2, 3].should.not.include.ordered.members([2, 3]); [1, 2, 3].should.not.include.ordered.members([1, 2, 2]); err(function() { [1, 2, 3].should.include.ordered.members([2, 1], 'blah'); }, 'blah: expected [ 1, 2, 3 ] to be an ordered superset of [ 2, 1 ]'); err(function() { [1, 2, 3].should.not.include.ordered.members([1, 2]); }, 'expected [ 1, 2, 3 ] to not be an ordered superset of [ 1, 2 ]'); }); it('deep.ordered.members', function() { [{a: 1}, {b: 2}, {c: 3}].should.deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); [{a: 1}, {b: 2}, {b: 2}].should.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); [{a: 1}, {b: 2}, {c: 3}].should.not.deep.ordered.members([{b: 2}, {a: 1}, {c: 3}]); [{a: 1}, {b: 2}].should.not.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); [{a: 1}, {b: 2}, {b: 2}].should.not.deep.ordered.members([{a: 1}, {b: 2}]); [{a: 1}, {b: 2}, {b: 2}].should.not.deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); [{a: 1}, {b: 2}, {c: 3}].should.not.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); err(function() { [{a: 1}, {b: 2}, {c: 3}].should.deep.ordered.members([{b: 2}, {a: 1}, {c: 3}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to have the same ordered members as [ { b: 2 }, { a: 1 }, { c: 3 } ]'); err(function() { [{a: 1}, {b: 2}, {c: 3}].should.not.deep.ordered.members([{a: 1}, {b: 2}, {c: 3}]); }, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not have the same ordered members as [ { a: 1 }, { b: 2 }, { c: 3 } ]'); }); it('include.deep.ordered.members', function() { [{a: 1}, {b: 2}, {c: 3}].should.include.deep.ordered.members([{a: 1}, {b: 2}]); [{a: 1}, {b: 2}, {c: 3}].should.not.include.deep.ordered.members([{b: 2}, {a: 1}]); [{a: 1}, {b: 2}, {c: 3}].should.not.include.deep.ordered.members([{b: 2}, {c: 3}]); [{a: 1}, {b: 2}, {c: 3}].should.not.include.deep.ordered.members([{a: 1}, {b: 2}, {b: 2}]); err(function() { [{a: 1}, {b: 2}, {c: 3}].should.include.deep.ordered.members([{b: 2}, {a: 1}], 'blah'); }, 'blah: expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to be an ordered superset of [ { b: 2 }, { a: 1 } ]'); err(function() { [{a: 1}, {b: 2}, {c: 3}].should.not.include.deep.ordered.members([{a: 1}, {b: 2}]); }, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be an ordered superset of [ { a: 1 }, { b: 2 } ]'); }); it ('iterable', function() { ([1, 2, 3]).should.be.iterable; (new Map([[1, 'one'], [2, 'two'], [3, 'three']])).should.be.iterable; (new Set([1, 2, 3])).should.be.iterable; ('hello').should.be.iterable; err(function() { (42).should.be.iterable; }, 'expected 42 to be an iterable'); err(function() { (true).should.be.iterable; }, 'expected true to be an iterable'); err(function() { ({ key: 'value' }).should.be.iterable; }, 'expected { key: \'value\' } to be an iterable'); }) it('change', function() { var obj = { value: 10, str: 'foo' }, heroes = ['spiderman', 'superman'], fn = function() { obj.value += 5 }, sameFn = function() { obj.value += 0 }, decFn = function() { obj.value -= 20 }, bangFn = function() { obj.str += '!' }, batFn = function() { heroes.push('batman') }, lenFn = function() { return heroes.length }, noFn = function() { return null }; fn.should.change(obj, 'value'); fn.should.change(obj, 'value').by(5); fn.should.change(obj, 'value').by(-5); fn.should.change(obj, 'value').but.not.by(10); decFn.should.change(obj, 'value'); decFn.should.change(obj, 'value').by(20); decFn.should.change(obj, 'value').but.not.by(19); sameFn.should.not.change(obj, 'value'); sameFn.should.not.change(obj, 'str'); bangFn.should.change(obj, 'str'); batFn.should.change(lenFn); batFn.should.change(lenFn).by(1); batFn.should.change(lenFn).but.not.by(2); noFn.should.not.change(lenFn); err(function () { (sameFn).should.change(obj, 'value', 'blah'); }, "blah: expected .value to change"); err(function () { (fn).should.not.change(obj, 'value', 'blah'); }, "blah: expected .value to not change"); err(function () { ({}).should.change(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { (fn).should.change({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function () { (fn).should.change(obj, 'value').by(10, 'blah'); }, "blah: expected .value to change by 10"); err(function () { (fn).should.change(obj, 'value').but.not.by(5, 'blah'); }, "blah: expected .value to not change by 5"); }); it('increase, decrease', function() { var obj = { value: 10, noop: null }, arr = ['one', 'two'], pFn = function() { arr.push('three') }, popFn = function() { arr.pop() }, lenFn = function() { return arr.length }, nFn = function() { return null }, incFn = function() { obj.value += 2 }, decFn = function() { obj.value -= 3 }, smFn = function() { obj.value += 0 }; smFn.should.not.increase(obj, 'value'); decFn.should.not.increase(obj, 'value'); incFn.should.increase(obj, 'value'); incFn.should.increase(obj, 'value').by(2); incFn.should.increase(obj, 'value').but.not.by(1); smFn.should.not.decrease(obj, 'value'); incFn.should.not.decrease(obj, 'value'); decFn.should.decrease(obj, 'value'); decFn.should.decrease(obj, 'value').by(3); decFn.should.decrease(obj, 'value').but.not.by(2); nFn.should.not.increase(lenFn); nFn.should.not.decrease(lenFn); popFn.should.decrease(lenFn); popFn.should.not.increase(lenFn); pFn.should.increase(lenFn); pFn.should.not.decrease(lenFn); pFn.should.increase(lenFn).by(1); pFn.should.increase(lenFn).but.not.by(2); popFn.should.decrease(lenFn).by(1); popFn.should.decrease(lenFn).but.not.by(2); err(function () { (smFn).should.increase(obj, 'value', 'blah'); }, "blah: expected .value to increase"); err(function () { (incFn).should.not.increase(obj, 'value', 'blah'); }, "blah: expected .value to not increase"); err(function () { ({}).should.increase(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { (incFn).should.increase({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function() { (incFn).should.increase(obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function () { (incFn).should.increase(obj, 'value').by(10, 'blah'); }, "blah: expected .value to increase by 10"); err(function () { (incFn).should.increase(obj, 'value').but.not.by(2, 'blah'); }, "blah: expected .value to not increase by 2"); err(function () { (smFn).should.decrease(obj, 'value', 'blah'); }, "blah: expected .value to decrease"); err(function () { (decFn).should.not.decrease(obj, 'value', 'blah'); }, "blah: expected .value to not decrease"); err(function () { ({}).should.decrease(obj, 'value', 'blah'); }, "blah: expected {} to be a function"); err(function () { (decFn).should.decrease({}, 'badprop', 'blah'); }, "blah: expected {} to have property 'badprop'"); err(function() { (decFn).should.decrease(obj, 'noop', 'blah'); }, 'blah: expected null to be a number'); err(function () { (decFn).should.decrease(obj, 'value').by(10, 'blah'); }, "blah: expected .value to decrease by 10"); err(function () { (decFn).should.decrease(obj, 'value').but.not.by(3, 'blah'); }, "blah: expected .value to not decrease by 3"); }); it('extensible', function() { var nonExtensibleObject = Object.preventExtensions({}); ({}).should.be.extensible; nonExtensibleObject.should.not.be.extensible; err(function() { nonExtensibleObject.should.be.extensible; }, 'expected {} to be extensible'); err(function() { ({}).should.not.be.extensible; }, 'expected {} to not be extensible'); // Making sure ES6-like Object.isExtensible response is respected for all primitive types (42).should.not.be.extensible; 'foo'.should.not.be.extensible; false.should.not.be.extensible; Symbol().should.not.be.extensible; err(function() { (42).should.be.extensible; }, 'expected 42 to be extensible'); err(function() { 'foo'.should.be.extensible; }, 'expected \'foo\' to be extensible'); err(function() { false.should.be.extensible; }, 'expected false to be extensible'); var proxy = new Proxy({}, { isExtensible: function() { throw new TypeError(); } }); err(function() { // .extensible should not suppress errors, thrown in proxy traps proxy.should.be.extensible; }, { name: 'TypeError' }); }); it('sealed', function() { var sealedObject = Object.seal({}); sealedObject.should.be.sealed; ({}).should.not.be.sealed; err(function() { ({}).should.be.sealed; }, 'expected {} to be sealed'); err(function() { sealedObject.should.not.be.sealed; }, 'expected {} to not be sealed'); // Making sure ES6-like Object.isSealed response is respected for all primitive types (42).should.be.sealed; 'foo'.should.be.sealed; false.should.be.sealed; Symbol().should.be.sealed; err(function() { (42).should.not.be.sealed; }, 'expected 42 to not be sealed'); err(function() { 'foo'.should.not.be.sealed; }, 'expected \'foo\' to not be sealed'); err(function() { false.should.not.be.sealed; }, 'expected false to not be sealed'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isSealed will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // .sealed should not suppress errors, thrown in proxy traps proxy.should.be.sealed; }, { name: 'TypeError' }); }); it('frozen', function() { var frozenObject = Object.freeze({}); frozenObject.should.be.frozen; ({}).should.not.be.frozen; err(function() { ({}).should.be.frozen; }, 'expected {} to be frozen'); err(function() { frozenObject.should.not.be.frozen; }, 'expected {} to not be frozen'); // Making sure ES6-like Object.isFrozen response is respected for all primitive types (42).should.be.frozen; 'foo'.should.be.frozen; false.should.be.frozen; Symbol().should.be.frozen; err(function() { (42).should.not.be.frozen; }, 'expected 42 to not be frozen'); err(function() { 'foo'.should.not.be.frozen; }, 'expected \'foo\' to not be frozen'); err(function() { false.should.not.be.frozen; }, 'expected false to not be frozen'); var proxy = new Proxy({}, { ownKeys: function() { throw new TypeError(); } }); // Object.isFrozen will call ownKeys trap only if object is not extensible Object.preventExtensions(proxy); err(function() { // .frozen should not suppress errors, thrown in proxy traps proxy.should.be.frozen; }, { name: 'TypeError' }); }); }); chaijs-chai-2a3ecff/test/subset.js000066400000000000000000000126421505212005400172510ustar00rootroot00000000000000import * as chai from '../index.js'; describe('containsSubset', function () { const {assert, expect} = chai; const should = chai.Should(); describe('plain object', function () { var testedObject = { a: 'b', c: 'd' }; it('should pass for smaller object', function () { expect(testedObject).to.containSubset({ a: 'b' }); }); it('should pass for same object', function () { expect(testedObject).to.containSubset({ a: 'b', c: 'd' }); }); it('should pass for similar, but not the same object', function () { expect(testedObject).to.not.containSubset({ a: 'notB', c: 'd' }); }); }); describe('complex object', function () { var testedObject = { a: 'b', c: 'd', e: { foo: 'bar', baz: { qux: 'quux' } } }; it('should pass for smaller object', function () { expect(testedObject).to.containSubset({ a: 'b', e: { foo: 'bar' } }); }); it('should pass for smaller object', function () { expect(testedObject).to.containSubset({ e: { foo: 'bar', baz: { qux: 'quux' } } }); }); it('should pass for same object', function () { expect(testedObject).to.containSubset({ a: 'b', c: 'd', e: { foo: 'bar', baz: { qux: 'quux' } } }); }); it('should pass for similar, but not the same object', function () { expect(testedObject).to.not.containSubset({ e: { foo: 'bar', baz: { qux: 'notAQuux' } } }); }); it('should fail if comparing when comparing objects to dates', function () { expect(testedObject).to.not.containSubset({ e: new Date() }); }); }); describe('circular objects', function () { var object = {}; before(function () { object.arr = [object, object]; object.arr.push(object.arr); object.obj = object; }); it('should contain subdocument', function () { expect(object).to.containSubset({ arr: [{arr: []}, {arr: []}, [{arr: []}, {arr: []}]] }); }); it('should not contain similar object', function () { expect(object).to.not.containSubset({ arr: [{arr: ['just random field']}, {arr: []}, [{arr: []}, {arr: []}]] }); }); }); describe('object with compare function', function () { it('should pass when function returns true', function () { expect({a: 5}).to.containSubset({a: (a) => a}); }); it('should fail when function returns false', function () { expect({a: 5}).to.not.containSubset({a: (a) => !a}); }); it('should pass for function with no arguments', function () { expect({a: 5}).to.containSubset({a: () => true}); }); }); describe('comparison of non objects', function () { it('should fail if actual subset is null', function () { expect(null).to.not.containSubset({a: 1}); }); it('should fail if expected subset is not a object', function () { expect({a: 1}).to.not.containSubset(null); }); it('should not fail for same non-object (string) variables', function () { expect('string').to.containSubset('string'); }); }); describe('assert style of test', function () { it('should find subset', function () { assert.containsSubset({a: 1, b: 2}, {a: 1}); assert.containSubset({a: 1, b: 2}, {a: 1}); }); it('negated assert style should function', function () { assert.doesNotContainSubset({a: 1, b: 2}, {a: 3}); }); }); describe('should style of test', function () { const objectA = {a: 1, b: 2}; it('should find subset', function () { objectA.should.containSubset({a: 1}); }); it('negated should style should function', function () { objectA.should.not.containSubset({a: 3}); }); }); describe('comparison of dates', function () { it('should pass for the same date', function () { expect(new Date('2015-11-30')).to.containSubset(new Date('2015-11-30')); }); it('should pass for the same date if nested', function () { expect({a: new Date('2015-11-30')}).to.containSubset({ a: new Date('2015-11-30') }); }); it('should fail for a different date', function () { expect(new Date('2015-11-30')).to.not.containSubset( new Date('2012-02-22') ); }); it('should fail for a different date if nested', function () { expect({a: new Date('2015-11-30')}).to.not.containSubset({ a: new Date('2012-02-22') }); }); it('should fail for invalid expected date', function () { expect(new Date('2015-11-30')).to.not.containSubset( new Date('not valid date') ); }); it('should fail for invalid actual date', function () { expect(new Date('not valid actual date')).to.not.containSubset( new Date('not valid expected date') ); }); }); describe('cyclic objects', () => { it('should pass', () => { const child = {}; const parent = { children: [child] }; child.parent = parent; const myObject = { a: 1, b: 'two', c: parent }; expect(myObject).to.containSubset({ a: 1, c: parent }); }); }); }); chaijs-chai-2a3ecff/test/type-detect/000077500000000000000000000000001505212005400176305ustar00rootroot00000000000000chaijs-chai-2a3ecff/test/type-detect/deno-test.ts000066400000000000000000000003631505212005400221040ustar00rootroot00000000000000/* global Deno:readonly */ // @ts-nocheck import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; import typeDetect from '../index.ts'; Deno.test('type detect works', () => { assertEquals(typeDetect('hello'), 'string'); }); chaijs-chai-2a3ecff/test/type-detect/dom.js000066400000000000000000000251611505212005400207520ustar00rootroot00000000000000import * as chai from '../../index.js'; function assert (expr, msg) { if (!expr) { throw new Error(msg || 'Assertion Failed'); } } const type = chai.util.type function describeIf(condition) { return condition ? describe : describe.skip; } function itIf(condition) { return condition ? it : it.skip; } describeIf(typeof window !== 'undefined' && typeof window.document !== 'undefined')('DOM Specific', () => { it('window', () => { assert(type(window) === 'Window'); }); it('document', () => { assert(type(document) === 'HTMLDocument'); }); it('domparser', () => { assert(type(new DOMParser()) === 'DOMParser'); }); it('history', () => { assert(type(window.history) === 'History'); }); it('location', () => { assert(type(window.location) === 'Location'); }); it('attr', () => { const div = document.createElement('div'); div.setAttribute('id', 'foo'); assert(type(div.getAttributeNode('id')) === 'Attr'); }); describe('Events', () => { it('event', () => { assert(type(document.createEvent('Event')) === 'Event'); }); itIf(typeof HashChangeEvent !== 'undefined')('HashChangeEvent', () => { assert(type(new HashChangeEvent('')) === 'HashChangeEvent'); }); }); describe('Navigator', () => { it('navigator', () => { assert(type(window.navigator) === 'Navigator'); }); itIf(typeof navigator !== 'undefined' && 'geolocation' in navigator)('geolocation', () => { assert(type(navigator.geolocation) === 'Geolocation'); }); itIf(typeof navigator !== 'undefined' && 'connection' in navigator)('networkinformation', () => { assert(type(navigator.connection) === 'NetworkInformation'); }); itIf(typeof navigator !== 'undefined' && 'mediaDevices' in navigator)('mediadevices', () => { assert(type(navigator.mediaDevices) === 'MediaDevices'); }); itIf(typeof navigator !== 'undefined' && 'mimeTypes' in navigator)('mimetypearray', () => { assert(type(navigator.mimeTypes) === 'MimeTypeArray'); }); itIf(typeof navigator !== 'undefined' && 'nfc' in navigator)('nfc', () => { assert(type(navigator.nfc) === 'NFC'); }); itIf(typeof navigator !== 'undefined' && 'permissions' in navigator)('permissions', () => { assert(type(navigator.permissions) === 'Permissions'); }); itIf(typeof navigator !== 'undefined' && 'plugins' in navigator)('pluginarray', () => { assert(type(navigator.plugins) === 'PluginArray'); }); itIf(typeof navigator !== 'undefined' && 'plugins' in navigator && navigator.plugins.length)('plugin', () => { assert(type(navigator.plugins[0]) === 'Plugin'); }); itIf(typeof navigator !== 'undefined' && 'presentation' in navigator)('presentation', () => { assert(type(navigator.presentation) === 'Presentation'); }); itIf(typeof navigator !== 'undefined' && 'serviceworker' in navigator)('serviceworkercontainer', () => { assert(type(navigator.serviceworker) === 'ServiceWorkerContainer'); }); itIf(typeof navigator !== 'undefined' && 'services' in navigator)('serviceportcollection', () => { assert(type(navigator.services) === 'ServicePortCollection'); }); itIf(typeof navigator !== 'undefined' && 'storage' in navigator)('storagemanager', () => { assert(type(navigator.storage) === 'StorageManager'); }); itIf(typeof navigator !== 'undefined' && 'storageQuota' in navigator)('storagequota', () => { assert(type(navigator.storageQuota) === 'StorageQuota'); }); itIf(typeof navigator !== 'undefined' && 'usb' in navigator)('usb', () => { assert(type(navigator.usb) === 'USB'); }); }); describe('(HTMLElements)', () => { it('HTMLAreaElement', () => { assert(type(document.createElement('Area')) === 'HTMLAreaElement'); }); it('HTMLBRElement', () => { assert(type(document.createElement('BR')) === 'HTMLBRElement'); }); it('HTMLBaseElement', () => { assert(type(document.createElement('Base')) === 'HTMLBaseElement'); }); it('HTMLBodyElement', () => { assert(type(document.createElement('Body')) === 'HTMLBodyElement'); }); it('HTMLButtonElement', () => { assert(type(document.createElement('Button')) === 'HTMLButtonElement'); }); it('HTMLCanvasElement', () => { assert(type(document.createElement('Canvas')) === 'HTMLCanvasElement'); }); it('HTMLDListElement', () => { assert(type(document.createElement('DL')) === 'HTMLDListElement'); }); // not yet supported in Safari itIf(typeof HTMLDataListElement === 'function')('HTMLDataListElement', () => { assert(type(document.createElement('DataList')) === 'HTMLDataListElement'); }); it('HTMLDivElement', () => { assert(type(document.createElement('Div')) === 'HTMLDivElement'); }); it('HTMLFieldSetElement', () => { assert(type(document.createElement('FieldSet')) === 'HTMLFieldSetElement'); }); it('HTMLFormElement', () => { assert(type(document.createElement('Form')) === 'HTMLFormElement'); }); it('HTMLFrameSetElement', () => { assert(type(document.createElement('FrameSet')) === 'HTMLFrameSetElement'); }); it('HTMLHRElement', () => { assert(type(document.createElement('HR')) === 'HTMLHRElement'); }); it('HTMLHeadElement', () => { assert(type(document.createElement('Head')) === 'HTMLHeadElement'); }); it('HTMLHeadingElement', () => { assert(type(document.createElement('H1')) === 'HTMLHeadingElement'); assert(type(document.createElement('H2')) === 'HTMLHeadingElement'); assert(type(document.createElement('H3')) === 'HTMLHeadingElement'); assert(type(document.createElement('H4')) === 'HTMLHeadingElement'); assert(type(document.createElement('H5')) === 'HTMLHeadingElement'); assert(type(document.createElement('H6')) === 'HTMLHeadingElement'); }); it('HTMLHtmlElement', () => { assert(type(document.createElement('Html')) === 'HTMLHtmlElement'); }); it('HTMLIFrameElement', () => { assert(type(document.createElement('IFrame')) === 'HTMLIFrameElement'); }); it('HTMLImageElement', () => { assert(type(document.createElement('Img')) === 'HTMLImageElement'); }); it('HTMLInputElement', () => { assert(type(document.createElement('Input')) === 'HTMLInputElement'); }); it('HTMLLIElement', () => { assert(type(document.createElement('LI')) === 'HTMLLIElement'); }); it('HTMLLabelElement', () => { assert(type(document.createElement('Label')) === 'HTMLLabelElement'); }); it('HTMLLegendElement', () => { assert(type(document.createElement('Legend')) === 'HTMLLegendElement'); }); it('HTMLLinkElement', () => { assert(type(document.createElement('Link')) === 'HTMLLinkElement'); }); it('HTMLMapElement', () => { assert(type(document.createElement('Map')) === 'HTMLMapElement'); }); it('HTMLMetaElement', () => { assert(type(document.createElement('Meta')) === 'HTMLMetaElement'); }); itIf(typeof HTMLMeterElement !== 'undefined')('HTMLMeterElement', () => { assert(type(document.createElement('Meter')) === 'HTMLMeterElement'); }); it('HTMLModElement', () => { assert(type(document.createElement('Del')) === 'HTMLModElement'); }); it('HTMLOListElement', () => { assert(type(document.createElement('OL')) === 'HTMLOListElement'); }); it('HTMLOptGroupElement', () => { assert(type(document.createElement('OptGroup')) === 'HTMLOptGroupElement'); }); it('HTMLOptionElement', () => { assert(type(document.createElement('Option')) === 'HTMLOptionElement'); }); itIf(typeof HTMLOutputElement !== 'undefined')('HTMLOutputElement', () => { assert(type(document.createElement('Output')) === 'HTMLOutputElement'); }); it('HTMLParagraphElement', () => { assert(type(document.createElement('P')) === 'HTMLParagraphElement'); }); it('HTMLParamElement', () => { assert(type(document.createElement('Param')) === 'HTMLParamElement'); }); it('HTMLPreElement', () => { assert(type(document.createElement('Pre')) === 'HTMLPreElement'); }); itIf(typeof HTMLProgressElement !== 'undefined')('HTMLProgressElement', () => { assert(type(document.createElement('Progress')) === 'HTMLProgressElement'); }); it('HTMLQuoteElement', () => { assert(type(document.createElement('BlockQuote')) === 'HTMLQuoteElement'); assert(type(document.createElement('Q')) === 'HTMLQuoteElement'); }); it('HTMLScriptElement', () => { assert(type(document.createElement('Script')) === 'HTMLScriptElement'); }); it('HTMLSelectElement', () => { assert(type(document.createElement('Select')) === 'HTMLSelectElement'); }); it('HTMLSpanElement', () => { assert(type(document.createElement('Span')) === 'HTMLSpanElement'); }); it('HTMLStyleElement', () => { assert(type(document.createElement('Style')) === 'HTMLStyleElement'); }); it('HTMLTableCaptionElement', () => { assert(type(document.createElement('Caption')) === 'HTMLTableCaptionElement'); }); it('HTMLTableCellElement', () => { assert(type(document.createElement('TD')) === 'HTMLTableCellElement'); }); it('HTMLTableHeaderCellElement', () => { assert(type(document.createElement('TH')) === 'HTMLTableCellElement'); }); it('HTMLTableColElement', () => { assert(type(document.createElement('Col')) === 'HTMLTableColElement'); assert(type(document.createElement('ColGroup')) === 'HTMLTableColElement'); }); it('HTMLTableElement', () => { assert(type(document.createElement('Table')) === 'HTMLTableElement'); }); it('HTMLTableRowElement', () => { assert(type(document.createElement('TR')) === 'HTMLTableRowElement'); }); it('HTMLTableSectionElement', () => { assert(type(document.createElement('THead')) === 'HTMLTableSectionElement'); assert(type(document.createElement('TBody')) === 'HTMLTableSectionElement'); assert(type(document.createElement('TFoot')) === 'HTMLTableSectionElement'); }); it('HTMLTextAreaElement', () => { assert(type(document.createElement('TextArea')) === 'HTMLTextAreaElement'); }); it('HTMLTitleElement', () => { assert(type(document.createElement('Title')) === 'HTMLTitleElement'); }); it('HTMLUListElement', () => { assert(type(document.createElement('UL')) === 'HTMLUListElement'); }); it('HTMLUnknownElement', () => { assert(type(document.createElement('foobarbaz')) === 'HTMLUnknownElement'); }); }); }); chaijs-chai-2a3ecff/test/type-detect/index.js000066400000000000000000000166671505212005400213150ustar00rootroot00000000000000import * as chai from '../../index.js'; function assert (expr, msg) { if (!expr) { throw new Error(msg || 'Assertion Failed'); } } const type = chai.util.type describe('Generic', () => { it('array', () => { assert(type([]) === 'Array'); assert(type(new Array()) === 'Array'); }); it('regexp', () => { assert(type(/a-z/gi) === 'RegExp'); assert(type(new RegExp('a-z')) === 'RegExp'); }); it('function', () => { assert(type(() => {}) === 'Function'); }); it('arguments', function () { assert(type(arguments) === 'Arguments'); }); it('date', () => { assert(type(new Date()) === 'Date'); }); it('number', () => { assert(type(1) === 'Number'); assert(type(1.234) === 'Number'); assert(type(-1) === 'Number'); assert(type(-1.234) === 'Number'); assert(type(Infinity) === 'Number'); assert(type(NaN) === 'Number'); }); it('number objects', () => { assert(type(new Number(2)) === 'Number'); }); it('string', () => { assert(type('hello world') === 'String'); }); it('string objects', () => { assert(type(new String('hello')) === 'String'); }); it('null', () => { assert(type(null) === 'null'); assert(type(undefined) !== 'null'); }); it('undefined', () => { assert(type(undefined) === 'undefined'); assert(type(null) !== 'undefined'); }); it('object', () => { function Noop() {} assert(type({}) === 'Object'); assert(type(Noop) !== 'Object'); assert(type(new Noop()) === 'Object'); assert(type(new Object()) === 'Object'); assert(type(Object.create(null)) === 'Object'); assert(type(Object.create(Object.prototype)) === 'Object'); }); // See: https://github.com/chaijs/type-detect/pull/25 it('object with .undefined property getter', () => { const foo = {}; Object.defineProperty(foo, 'undefined', { get() { throw Error('Should never happen'); }, }); assert(type(foo) === 'Object'); }); it('boolean', () => { assert(type(true) === 'Boolean'); assert(type(false) === 'Boolean'); assert(type(!0) === 'Boolean'); }); it('boolean object', () => { assert(type(new Boolean()) === 'Boolean'); }); it('error', () => { assert(type(new Error()) === 'Error'); assert(type(new TypeError()) === 'Error'); assert(type(new EvalError()) === 'Error'); assert(type(new RangeError()) === 'Error'); assert(type(new ReferenceError()) === 'Error'); assert(type(new SyntaxError()) === 'Error'); assert(type(new TypeError()) === 'Error'); assert(type(new URIError()) === 'Error'); }); it('Math', () => { assert(type(Math) === 'Math'); }); it('JSON', () => { assert(type(JSON) === 'JSON'); }); describe('Stubbed ES2015 Types', () => { const originalObjectToString = Object.prototype.toString; function stubObjectToStringOnce(staticValue) { Object.prototype.toString = function () { // eslint-disable-line no-extend-native Object.prototype.toString = originalObjectToString; // eslint-disable-line no-extend-native return staticValue; }; } function Thing() {} it('map', () => { stubObjectToStringOnce('[object Map]'); assert(type(new Thing()) === 'Map'); }); it('weakmap', () => { stubObjectToStringOnce('[object WeakMap]'); assert(type(new Thing()) === 'WeakMap'); }); it('set', () => { stubObjectToStringOnce('[object Set]'); assert(type(new Thing()) === 'Set'); }); it('weakset', () => { stubObjectToStringOnce('[object WeakSet]'); assert(type(new Thing()) === 'WeakSet'); }); it('symbol', () => { stubObjectToStringOnce('[object Symbol]'); assert(type(new Thing()) === 'Symbol'); }); it('promise', () => { stubObjectToStringOnce('[object Promise]'); assert(type(new Thing()) === 'Promise'); }); it('int8array', () => { stubObjectToStringOnce('[object Int8Array]'); assert(type(new Thing()) === 'Int8Array'); }); it('uint8array', () => { stubObjectToStringOnce('[object Uint8Array]'); assert(type(new Thing()) === 'Uint8Array'); }); it('uint8clampedarray', () => { stubObjectToStringOnce('[object Uint8ClampedArray]'); assert(type(new Thing()) === 'Uint8ClampedArray'); }); it('int16array', () => { stubObjectToStringOnce('[object Int16Array]'); assert(type(new Thing()) === 'Int16Array'); }); it('uint16array', () => { stubObjectToStringOnce('[object Uint16Array]'); assert(type(new Thing()) === 'Uint16Array'); }); it('int32array', () => { stubObjectToStringOnce('[object Int32Array]'); assert(type(new Thing()) === 'Int32Array'); }); it('uint32array', () => { stubObjectToStringOnce('[object Uint32Array]'); assert(type(new Thing()) === 'Uint32Array'); }); it('float32array', () => { stubObjectToStringOnce('[object Float32Array]'); assert(type(new Thing()) === 'Float32Array'); }); it('float64array', () => { stubObjectToStringOnce('[object Float64Array]'); assert(type(new Thing()) === 'Float64Array'); }); it('dataview', () => { stubObjectToStringOnce('[object DataView]'); assert(type(new Thing()) === 'DataView'); }); it('arraybuffer', () => { stubObjectToStringOnce('[object ArrayBuffer]'); assert(type(new Thing()) === 'ArrayBuffer'); }); it('generatorfunction', () => { stubObjectToStringOnce('[object GeneratorFunction]'); assert(type(new Thing()) === 'GeneratorFunction'); }); it('generator', () => { stubObjectToStringOnce('[object Generator]'); assert(type(new Thing()) === 'Generator'); }); it('string iterator', () => { stubObjectToStringOnce('[object String Iterator]'); assert(type(new Thing()) === 'String Iterator'); }); it('array iterator', () => { stubObjectToStringOnce('[object Array Iterator]'); assert(type(new Thing()) === 'Array Iterator'); }); it('map iterator', () => { stubObjectToStringOnce('[object Map Iterator]'); assert(type(new Thing()) === 'Map Iterator'); }); it('set iterator', () => { stubObjectToStringOnce('[object Set Iterator]'); assert(type(new Thing()) === 'Set Iterator'); }); }); describe('@@toStringTag Sham', () => { const originalObjectToString = Object.prototype.toString; before(() => { const globalObject = typeof self === 'object' ? self : global; globalObject.Symbol = globalObject.Symbol || {}; if (!Symbol.toStringTag) { Symbol.toStringTag = '__@@toStringTag__'; } const test = {}; test[Symbol.toStringTag] = function () { return 'foo'; }; if (Object.prototype.toString(test) !== '[object foo]') { Object.prototype.toString = function () { // eslint-disable-line no-extend-native if (typeof this === 'object' && typeof this[Symbol.toStringTag] === 'function') { return `[object ${ this[Symbol.toStringTag]() }]`; } return originalObjectToString.call(this); }; } }); after(() => { Object.prototype.toString = originalObjectToString; // eslint-disable-line no-extend-native }); it('plain object', () => { const obj = {}; obj[Symbol.toStringTag] = function () { return 'Foo'; }; assert(type(obj) === 'Foo', 'type(obj) === "Foo"'); }); }); }); chaijs-chai-2a3ecff/test/type-detect/new-ecmascript-types.js000066400000000000000000000106061505212005400242540ustar00rootroot00000000000000import * as chai from '../../index.js'; function assert (expr, msg) { if (!expr) { throw new Error(msg || 'Assertion Failed'); } } const type = chai.util.type const symbolExists = typeof Symbol === 'function'; const setExists = typeof Set === 'function'; const mapExists = typeof Map === 'function'; let supportArrows = false; let supportGenerators = false; try { eval('function * foo () {}; foo'); // eslint-disable-line no-eval supportGenerators = true; } catch (error) { supportGenerators = false; } try { eval('() => {}'); // eslint-disable-line no-eval supportArrows = true; } catch (error) { supportArrows = false; } function itIf(condition) { return condition ? it : it.skip; } describe('ES2015 Specific', () => { itIf(symbolExists && typeof String.prototype[Symbol.iterator] === 'function')('string iterator', () => { assert(type(''[Symbol.iterator]()) === 'String Iterator'); }); itIf(symbolExists && typeof Array.prototype[Symbol.iterator] === 'function')('array iterator', () => { assert(type([][Symbol.iterator]()) === 'Array Iterator'); }); itIf(typeof Array.prototype.entries === 'function')('array iterator (entries)', () => { assert(type([].entries()) === 'Array Iterator'); }); itIf(mapExists)('map', () => { assert(type(new Map()) === 'Map'); }); itIf(symbolExists && mapExists && typeof Map.prototype[Symbol.iterator] === 'function')('map iterator', () => { assert(type(new Map()[Symbol.iterator]()) === 'Map Iterator'); }); itIf(mapExists && typeof Map.prototype.entries === 'function')('map iterator (entries)', () => { assert(type(new Map().entries()) === 'Map Iterator'); }); itIf(typeof WeakMap === 'function')('weakmap', () => { assert(type(new WeakMap()) === 'WeakMap'); }); itIf(setExists)('set', () => { assert(type(new Set()) === 'Set'); }); itIf(symbolExists && setExists && typeof Set.prototype[Symbol.iterator] === 'function')('set iterator', () => { assert(type(new Set()[Symbol.iterator]()) === 'Set Iterator'); }); itIf(setExists && typeof Set.prototype.entries === 'function')('set iterator', () => { assert(type(new Set().entries()) === 'Set Iterator'); }); itIf(typeof WeakSet === 'function')('weakset', () => { assert(type(new WeakSet()) === 'WeakSet'); }); itIf(typeof Symbol === 'function')('symbol', () => { assert(type(Symbol('foo')) === 'Symbol'); }); itIf(typeof Promise === 'function')('promise', () => { function noop() {} assert(type(new Promise(noop)) === 'Promise'); }); itIf(typeof Int8Array === 'function')('int8array', () => { assert(type(new Int8Array()) === 'Int8Array'); }); itIf(typeof Uint8Array === 'function')('uint8array', () => { assert(type(new Uint8Array()) === 'Uint8Array'); }); itIf(typeof Uint8ClampedArray === 'function')('uint8clampedarray', () => { assert(type(new Uint8ClampedArray()) === 'Uint8ClampedArray'); }); itIf(typeof Int16Array === 'function')('int16array', () => { assert(type(new Int16Array()) === 'Int16Array'); }); itIf(typeof Uint16Array === 'function')('uint16array', () => { assert(type(new Uint16Array()) === 'Uint16Array'); }); itIf(typeof Int32Array === 'function')('int32array', () => { assert(type(new Int32Array()) === 'Int32Array'); }); itIf(typeof Uint32Array === 'function')('uint32array', () => { assert(type(new Uint32Array()) === 'Uint32Array'); }); itIf(typeof Float32Array === 'function')('float32array', () => { assert(type(new Float32Array()) === 'Float32Array'); }); itIf(typeof Float64Array === 'function')('float64array', () => { assert(type(new Float64Array()) === 'Float64Array'); }); itIf(typeof DataView === 'function')('dataview', () => { const arrayBuffer = new ArrayBuffer(1); assert(type(new DataView(arrayBuffer)) === 'DataView'); }); itIf(typeof ArrayBuffer === 'function')('arraybuffer', () => { assert(type(new ArrayBuffer(1)) === 'ArrayBuffer'); }); itIf(supportArrows)('arrow function', () => { assert(type(eval('() => {}')) === 'Function'); // eslint-disable-line no-eval }); itIf(supportGenerators)('generator function', () => { assert(type(eval('function * foo () {}; foo')) === 'GeneratorFunction'); // eslint-disable-line no-eval }); itIf(supportGenerators)('generator', () => { assert(type(eval('(function * foo () {}())')) === 'Generator'); // eslint-disable-line no-eval }); }); chaijs-chai-2a3ecff/test/type-detect/node.js000066400000000000000000000010501505212005400211070ustar00rootroot00000000000000import * as chai from '../../index.js'; function assert (expr, msg) { if (!expr) { throw new Error(msg || 'Assertion Failed'); } } const type = chai.util.type const isNode = typeof process !== 'undefined' && typeof process.release === 'object' && process.release.name; function describeIf(condition) { return condition ? describe : describe.skip; } describeIf(isNode)('Node Specific', () => { it('global', () => { assert(type(global) === 'global'); }); it('process', () => { assert(type(process) === 'process'); }); }); chaijs-chai-2a3ecff/test/type-detect/tostringtag-extras.js000066400000000000000000000012341505212005400240370ustar00rootroot00000000000000import * as chai from '../../index.js'; function assert (expr, msg) { if (!expr) { throw new Error(msg || 'Assertion Failed'); } } const type = chai.util.type const symbolExists = typeof Symbol === 'function'; const symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; function describeIf(condition) { return condition ? describe : describe.skip; } describeIf(symbolToStringTagExists)('toStringTag extras', () => { it('supports toStringTag on arrays', () => { assert(type([]) === 'Array'); const arr = []; arr[Symbol.toStringTag] = 'foo'; assert(type(arr) === 'foo', 'type(arr) === "foo"'); }); }); chaijs-chai-2a3ecff/test/utilities.js000066400000000000000000001360111505212005400177540ustar00rootroot00000000000000import * as chai from '../index.js'; describe('utilities', function () { const expect = chai.expect; after(function() { // Some clean-up so we can run tests in a --watch delete chai.Assertion.prototype.eqqqual; delete chai.Assertion.prototype.result; delete chai.Assertion.prototype.doesnotexist; }); it('_obj', function () { var foo = 'bar' , test = expect(foo); expect(test).to.have.property('_obj', foo); var bar = 'baz'; test._obj = bar; expect(test).to.have.property('_obj', bar); test.equal(bar); }); it('transferFlags', function () { var foo = 'bar' , test = expect(foo).not; chai.use(function (_chai, utils) { var obj = {}; utils.transferFlags(test, obj); expect(utils.flag(obj, 'object')).to.equal(foo); expect(utils.flag(obj, 'negate')).to.equal(true); }); }); it('transferFlags, includeAll = false', function () { var foo = 'bar'; chai.use(function (_chai, utils) { var target = {}; var test = function() {}; var assertion = new chai.Assertion(target, "message", test, true); var flag = {}; utils.flag(assertion, 'flagMe', flag); utils.flag(assertion, 'negate', true); var obj = {}; utils.transferFlags(assertion, obj, false); expect(utils.flag(obj, 'object')).to.equal(undefined); expect(utils.flag(obj, 'message')).to.equal(undefined); expect(utils.flag(obj, 'ssfi')).to.equal(undefined); expect(utils.flag(obj, 'lockSsfi')).to.equal(undefined); expect(utils.flag(obj, 'negate')).to.equal(true); expect(utils.flag(obj, 'flagMe')).to.equal(flag); }); }); it('transferFlags, includeAll = true', function () { var foo = 'bar'; chai.use(function (_chai, utils) { var target = {}; var test = function() {}; var assertion = new chai.Assertion(target, "message", test, true); var flag = {}; utils.flag(assertion, 'flagMe', flag); utils.flag(assertion, 'negate', true); var obj = {}; utils.transferFlags(assertion, obj, true); expect(utils.flag(obj, 'object')).to.equal(target); expect(utils.flag(obj, 'message')).to.equal("message"); expect(utils.flag(obj, 'ssfi')).to.equal(test); expect(utils.flag(obj, 'lockSsfi')).to.equal(true); expect(utils.flag(obj, 'negate')).to.equal(true); expect(utils.flag(obj, 'flagMe')).to.equal(flag); }); }); describe('addMethod', function() { var assertionConstructor, utils; before(function() { chai.use(function(_chai, _utils) { utils = _utils; assertionConstructor = _chai.Assertion; expect(_chai.Assertion).to.not.respondTo('eqqqual'); _chai.Assertion.addMethod('eqqqual', function (str) { var object = utils.flag(this, 'object'); new _chai.Assertion(object).to.be.eql(str); }); _chai.Assertion.addMethod('result', function () { return 'result'; }) _chai.Assertion.addMethod('returnNewAssertion', function () { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); }); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.eqqqual; delete chai.Assertion.prototype.result; delete chai.Assertion.prototype.returnNewAssertion; delete chai.Assertion.prototype.checkFlags; }); it('addMethod', function () { expect(chai.Assertion).to.respondTo('eqqqual'); expect('spec').to.eqqqual('spec'); }); it('addMethod returning result', function () { expect(expect('foo').result()).to.equal('result'); }); it('addMethod returns new assertion with flags copied over', function () { var assertion1 = expect('foo'); var assertion2 = assertion1.to.returnNewAssertion(); // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a method to guarantee it's not a function's // `length`. Note: 'instanceof' cannot be used here because the test will // fail in IE 10 due to how addChainableMethod works without __proto__ // support. Therefore, test the constructor property of length instead. var anAssertion = expect([1, 2, 3]).to.be.an.instanceof(Array); expect(anAssertion.length.constructor).to.equal(assertionConstructor); var anotherAssertion = expect([1, 2, 3]).to.have.a.lengthOf(3).and.to.be.ok; expect(anotherAssertion.length.constructor).to.equal(assertionConstructor); }); it('addMethod sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect(1); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.eqqqual(1); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); it('addMethod doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect(1); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.eqqqual(1); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); describe('overwriteMethod', function () { var assertionConstructor, utils; before(function() { chai.config.includeStack = false; chai.use(function(_chai, _utils) { assertionConstructor = _chai.Assertion; utils = _utils; _chai.Assertion.addMethod('four', function() { this.assert(this._obj === 4, 'expected #{this} to be 4', 'expected #{this} to not be 4', 4); }); _chai.Assertion.overwriteMethod('four', function(_super) { return function() { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); if (typeof this._obj === 'string') { this.assert(this._obj === 'four', 'expected #{this} to be \'four\'', 'expected #{this} to not be \'four\'', 'four'); } else { _super.call(this); } } }); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.four; delete chai.Assertion.prototype.checkFlags; delete chai.Assertion.prototype.eqqqual; delete chai.Assertion.prototype.doesnotexist; delete chai.Assertion.prototype.doesnotexistfail; }); it('overwriteMethod', function () { chai.use(function (_chai, utils) { _chai.Assertion.addMethod('eqqqual', function (str) { var object = utils.flag(this, 'object'); new _chai.Assertion(object).to.be.eql(str); }); _chai.Assertion.overwriteMethod('eqqqual', function (_super) { return function (str) { var object = utils.flag(this, 'object'); if (object == 'cucumber' && str == 'cuke') { utils.flag(this, 'cucumber', true); } else { _super.apply(this, arguments); } }; }); }); var vege = expect('cucumber').to.eqqqual('cucumber'); expect(vege.__flags).to.not.have.property('cucumber'); var cuke = expect('cucumber').to.eqqqual('cuke'); expect(cuke.__flags).to.have.property('cucumber'); chai.use(function (_chai, _) { expect(_chai.Assertion).to.not.respondTo('doesnotexist'); _chai.Assertion.overwriteMethod('doesnotexist', function (_super) { expect(_super).to.be.a('function'); return function () { _.flag(this, 'doesnt', true); } }); }); var dne = expect('something').to.doesnotexist(); expect(dne.__flags).to.have.property('doesnt'); chai.use(function (_chai, _) { expect(_chai.Assertion).to.not.respondTo('doesnotexistfail'); _chai.Assertion.overwriteMethod('doesnotexistfail', function (_super) { expect(_super).to.be.a('function'); return function () { _.flag(this, 'doesnt', true); _super.apply(this, arguments); } }); }); var dneFail = expect('something'); var dneError; try { dneFail.doesnotexistfail(); } catch (e) { dneError = e; } expect(dneFail.__flags).to.have.property('doesnt'); expect(dneError.message).to.eql('doesnotexistfail is not a function'); }); it('overwriteMethod returning result', function () { chai.use(function (_chai, _) { _chai.Assertion.overwriteMethod('result', function (_super) { return function () { return 'result'; } }); }); expect(expect('foo').result()).to.equal('result'); }); it('calling _super has correct stack trace', function() { try { expect(5).to.be.four(); expect(false, 'should not get here because error thrown').to.be.ok; } catch (err) { // not all browsers support err.stack // Phantom does not include function names for getter exec if ('undefined' !== typeof err.stack && 'undefined' !== typeof Error.captureStackTrace) { expect(err.stack).to.include('utilities.js'); expect(err.stack).to.not.include('overwriteMethod'); } } }); it('overwritten behavior has correct stack trace', function() { try { expect('five').to.be.four(); expect(false, 'should not get here because error thrown').to.be.ok; } catch (err) { // not all browsers support err.stack // Phantom does not include function names for getter exec if ('undefined' !== typeof err.stack && 'undefined' !== typeof Error.captureStackTrace) { expect(err.stack).to.include('utilities.js'); expect(err.stack).to.not.include('overwriteMethod'); } } }); it('should return a new assertion with flags copied over', function () { var assertion1 = expect('four'); var assertion2 = assertion1.four(); // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a method to guarantee it is not a function's `length` expect('four').to.be.a.four().length.above(2); // Ensure that foo returns an Assertion (not a function) expect(expect('four').four()).to.be.an.instanceOf(assertionConstructor); }); it('overwriteMethod sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect(4); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.four(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); it('overwriteMethod doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect(4); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.four(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); describe('addProperty', function() { var assertionConstructor = chai.Assertion; var utils; before(function() { chai.use(function (_chai, _utils) { utils = _utils; assertionConstructor = _chai.Assertion; _chai.Assertion.addProperty('tea', function () { utils.flag(this, 'tea', 'chai'); }); _chai.Assertion.addProperty('result', function () { return 'result'; }) _chai.Assertion.addProperty('thing', function () { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); }); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.tea; delete chai.Assertion.prototype.thing; delete chai.Assertion.prototype.checkFlags; delete chai.Assertion.prototype.result; }); it('addProperty', function () { var assert = expect('chai').to.be.tea; expect(assert.__flags.tea).to.equal('chai'); }); it('addProperty returning result', function () { expect(expect('foo').result).to.equal('result'); }); it('addProperty returns a new assertion with flags copied over', function () { var assertion1 = expect('foo'); var assertion2 = assertion1.is.thing; // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // If it is, calling length on it should return an assertion, not a function expect([1, 2, 3]).to.be.an.instanceof(Array); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a property to guarantee it is not a function's `length` expect([1, 2, 3]).to.be.a.thing.with.length.above(2); expect([1, 2, 3]).to.be.an.instanceOf(Array).and.have.length.below(4); expect(expect([1, 2, 3]).be).to.be.an.instanceOf(assertionConstructor); expect(expect([1, 2, 3]).thing).to.be.an.instanceOf(assertionConstructor); }); it('addProperty sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect(1); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.to.be.tea; var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); it('addProperty doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect(1); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.to.be.tea; var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); describe('overwriteProperty', function () { var assertionConstructor, utils; before(function() { chai.config.includeStack = false; chai.use(function(_chai, _utils) { assertionConstructor = _chai.Assertion; utils = _utils; _chai.Assertion.addProperty('tea', function () { utils.flag(this, 'tea', 'chai'); }); _chai.Assertion.overwriteProperty('tea', function (_super) { return function () { var act = utils.flag(this, 'object'); if (act === 'matcha') { utils.flag(this, 'tea', 'matcha'); } else { _super.call(this); } } }); _chai.Assertion.overwriteProperty('result', function (_super) { return function () { return 'result'; } }); _chai.Assertion.addProperty('four', function() { this.assert(this._obj === 4, 'expected #{this} to be 4', 'expected #{this} to not be 4', 4); }); _chai.Assertion.overwriteProperty('four', function(_super) { return function() { if (typeof this._obj === 'string') { this.assert(this._obj === 'four', 'expected #{this} to be \'four\'', 'expected #{this} to not be \'four\'', 'four'); } else { _super.call(this); } } }); _chai.Assertion.addProperty('foo'); _chai.Assertion.overwriteProperty('foo', function (_super) { return function blah () { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); _super.call(this); }; }); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.tea; delete chai.Assertion.prototype.four; delete chai.Assertion.prototype.result; delete chai.Assertion.prototype.foo; delete chai.Assertion.prototype.checkFlags }); it('overwriteProperty', function () { var matcha = expect('matcha').to.be.tea; expect(matcha.__flags.tea).to.equal('matcha'); var assert = expect('something').to.be.tea; expect(assert.__flags.tea).to.equal('chai'); }); it('overwriteProperty returning result', function () { expect(expect('foo').result).to.equal('result'); }); it('calling _super has correct stack trace', function() { try { expect(5).to.be.four; expect(false, 'should not get here because error thrown').to.be.ok; } catch (err) { // not all browsers support err.stack // Phantom does not include function names for getter exec if ('undefined' !== typeof err.stack && 'undefined' !== typeof Error.captureStackTrace) { expect(err.stack).to.include('utilities.js'); expect(err.stack).to.not.include('overwriteProperty'); } } }); it('overwritten behavior has correct stack trace', function() { try { expect('five').to.be.four; expect(false, 'should not get here because error thrown').to.be.ok; } catch (err) { // not all browsers support err.stack // Phantom does not include function names for getter exec if ('undefined' !== typeof err.stack && 'undefined' !== typeof Error.captureStackTrace) { expect(err.stack).to.include('utilities.js'); expect(err.stack).to.not.include('overwriteProperty'); } } }); it('should return new assertion with flags copied over', function() { var assertion1 = expect('foo'); var assertion2 = assertion1.is.foo; // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // If it is, calling length on it should return an assertion, not a function expect([1, 2, 3]).to.be.an.foo.length.below(1000); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a property to guarantee it is not a function's `length` expect([1, 2, 3]).to.be.a.foo.with.length.above(2); expect([1, 2, 3]).to.be.an.instanceOf(Array).and.have.length.below(4); expect(expect([1, 2, 3]).be).to.be.an.instanceOf(assertionConstructor); expect(expect([1, 2, 3]).foo).to.be.an.instanceOf(assertionConstructor); }); describe('when useProxy is false', function () { before(function () { chai.config.useProxy = false; }); after(function () { chai.config.useProxy = true; }); it('overwriteProperty sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect(4); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.to.be.four; var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); }); it('overwriteProperty doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect(4); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.to.be.four; var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); it('getMessage', function () { chai.use(function (_chai, _) { expect(_.getMessage({}, [])).to.equal(''); expect(_.getMessage({}, [null, null, null])).to.equal(''); var obj = {}; _.flag(obj, 'message', 'foo'); expect(_.getMessage(obj, [])).to.contain('foo'); }); }); it('getMessage passed message as function', function () { chai.use(function (_chai, _) { var obj = {}; var msg = function() { return "expected a to eql b"; } var negateMsg = function() { return "expected a not to eql b"; } expect(_.getMessage(obj, [null, msg, negateMsg])).to.equal("expected a to eql b"); _.flag(obj, 'negate', true); expect(_.getMessage(obj, [null, msg, negateMsg])).to.equal("expected a not to eql b"); }); }); it('getMessage template tag substitution', function () { chai.use(function (_chai, _) { var objName = 'trojan horse'; var actualValue = 'an actual value'; var expectedValue = 'an expected value'; [ // known template tags { template: 'one #{this} two', expected: 'one \'' + objName + '\' two' }, { template: 'one #{act} two', expected: 'one \'' + actualValue + '\' two' }, { template: 'one #{exp} two', expected: 'one \'' + expectedValue + '\' two' }, // unknown template tag { template: 'one #{unknown} two', expected: 'one #{unknown} two' }, // repeated template tag { template: '#{this}#{this}', expected: '\'' + objName + '\'\'' + objName + '\'' }, // multiple template tags in different order { template: '#{this}#{act}#{exp}#{act}#{this}', expected: '\'' + objName + '\'\'' + actualValue + '\'\'' + expectedValue + '\'\'' + actualValue + '\'\'' + objName + '\'' }, // immune to string.prototype.replace() `$` substitution { objName: '-$$-', template: '#{this}', expected: '\'-$$-\'' }, { actualValue: '-$$-', template: '#{act}', expected: '\'-$$-\'' }, { expectedValue: '-$$-', template: '#{exp}', expected: '\'-$$-\'' } ].forEach(function (config) { config.objName = config.objName || objName; config.actualValue = config.actualValue || actualValue; config.expectedValue = config.expectedValue || expectedValue; var obj = {_obj: config.actualValue}; _.flag(obj, 'object', config.objName); expect(_.getMessage(obj, [null, config.template, null, config.expectedValue])).to.equal(config.expected); }); }); }); it('inspect with custom stylize-calling inspect()s', function () { chai.use(function (_chai, _) { var obj = { outer: { inspect: function (depth, options) { return options.stylize('Object content', 'string'); } } }; expect(_.inspect(obj)).to.equal('{ outer: Object content }'); }); }); it('inspect with custom object-returning inspect()s', function () { chai.use(function (_chai, _) { var obj = { outer: { inspect: function () { return { foo: 'bar' }; } } }; expect(_.inspect(obj)).to.equal('{ outer: { foo: \'bar\' } }'); }); }); it('inspect negative zero', function () { chai.use(function (_chai, _) { expect(_.inspect(-0)).to.equal('-0'); expect(_.inspect([-0])).to.equal('[ -0 ]'); expect(_.inspect({ hp: -0 })).to.equal('{ hp: -0 }'); }); }); it('inspect Symbol', function () { chai.use(function (_chai, _) { expect(_.inspect(Symbol())).to.equal('Symbol()'); expect(_.inspect(Symbol('cat'))).to.equal('Symbol(cat)'); }); }); it('inspect BigInt', function () { chai.use(function (_chai, _) { expect(_.inspect(BigInt(0))).to.equal('0n'); expect(_.inspect(BigInt(1234))).to.equal('1234n'); expect(_.inspect(BigInt(-1234))).to.equal('-1234n'); }); }); it('inspect every kind of available TypedArray', function () { chai.use(function (_chai, _) { var arr = [1, 2, 3] , exp = 'Array[ 1, 2, 3 ]' , isNode = true; if (typeof window !== 'undefined') { isNode = false; } // Checks if engine supports common TypedArrays if ((!isNode && 'Int8Array' in window) || isNode && typeof 'Int8Array' !== undefined) { // Typed array inspections should work as array inspections do expect(_.inspect(new Int8Array(arr))).to.include(exp); expect(_.inspect(new Uint8Array(arr))).to.include(exp); expect(_.inspect(new Int16Array(arr))).to.include(exp); expect(_.inspect(new Uint16Array(arr))).to.include(exp); expect(_.inspect(new Int32Array(arr))).to.include(exp); expect(_.inspect(new Uint32Array(arr))).to.include(exp); expect(_.inspect(new Float32Array(arr))).to.include(exp); } // These ones may not be available alongside the others above if ((!isNode && 'Uint8ClampedArray' in window) || isNode && typeof 'Uint8ClampedArray' !== undefined) { expect(_.inspect(new Uint8ClampedArray(arr))).to.include(exp); } if ((!isNode && 'Float64Array' in window) || isNode && typeof 'Float64Array' !== undefined) { expect(_.inspect(new Float64Array(arr))).to.include(exp); } }); }); it('inspect an assertion', function () { chai.use(function (_chai, _) { var assertion = expect(1); var anInspectFn = function() { return _.inspect(assertion); }; expect(anInspectFn).to.not.throw(); }); }); it('truncate long TypedArray', function () { chai.use(function (_chai, _) { var arr = [] , exp = 'Int8Array[ 1, 2, 3, 4, 5, 6, 7, …(993) ]' , isNode = true; // Filling arr with lots of elements for (var i = 1; i <= 1000; i++) { arr.push(i); } if (typeof window !== 'undefined') { isNode = false; } if ((!isNode && 'Int8Array' in window) || isNode && typeof 'Int8Array' !== undefined) { expect(_.inspect(new Int8Array(arr))).to.include(exp); } }); }); describe('addChainableMethod', function() { var assertionConstructor, utils; before(function() { chai.use(function (_chai, _utils) { assertionConstructor = _chai.Assertion; utils = _utils; _chai.Assertion.addChainableMethod('x', function () { new chai.Assertion(this._obj).to.be.equal('x'); } , function () { if (this._obj === Object(this._obj)) { this._obj.__x = 'X!' } } ); _chai.Assertion.addChainableMethod('foo', function(str) { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); var obj = utils.flag(this, 'object'); new _chai.Assertion(obj).to.be.equal(str); }); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.x; delete chai.Assertion.prototype.foo; delete chai.Assertion.prototype.checkFlags; }); it('addChainableMethod', function () { expect("foo").x.to.equal("foo"); expect("x").x(); expect(function () { expect("foo").x(); }).to.throw(chai.AssertionError); // Verify whether the original Function properties are present. // see https://github.com/chaijs/chai/commit/514dd6ce4#commitcomment-2593383 var propertyDescriptor = Object.getOwnPropertyDescriptor(chai.Assertion.prototype, "x"); expect(propertyDescriptor.get).to.have.property("call", Function.prototype.call); expect(propertyDescriptor.get).to.have.property("apply", Function.prototype.apply); expect(propertyDescriptor.get()).to.have.property("call", Function.prototype.call); expect(propertyDescriptor.get()).to.have.property("apply", Function.prototype.apply); var obj = {}; expect(obj).x.to.be.ok; expect(obj).to.have.property('__x', 'X!'); }); it('addChainableMethod should return a new assertion with flags copied over', function () { chai.config.proxyExcludedKeys.push('nodeType'); var assertion1 = expect('bar'); var assertion2 = assertion1.foo('bar'); // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a method to guarantee it is not a function's `length` expect('bar').to.be.a.foo('bar').length.above(2); // Ensure that foo returns an Assertion (not a function) expect(expect('bar').foo('bar')).to.be.an.instanceOf(assertionConstructor); }); it('addChainableMethod sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect('x'); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.to.be.x(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); it('addChainableMethod doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect('x'); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.to.be.x(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); describe('overwriteChainableMethod', function() { var assertionConstructor; var utils; before(function() { chai.use(function (_chai, _utils) { assertionConstructor = _chai.Assertion; utils = _utils; _chai.Assertion.addChainableMethod('x', function () { new chai.Assertion(this._obj).to.be.equal('x'); } , function () { if (this._obj === Object(this._obj)) { this._obj.__x = 'X!' } } ); _chai.Assertion.overwriteChainableMethod('x', function(_super) { return function() { utils.flag(this, 'mySpecificFlag', 'value1'); utils.flag(this, 'ultraSpecificFlag', 'value2'); if (utils.flag(this, 'marked')) { new chai.Assertion(this._obj).to.be.equal('spot'); } else { _super.apply(this, arguments); } }; } , function(_super) { return function() { utils.flag(this, 'message', 'x marks the spot'); _super.apply(this, arguments); }; } ); _chai.Assertion.addMethod('checkFlags', function() { this.assert( utils.flag(this, 'mySpecificFlag') === 'value1' && utils.flag(this, 'ultraSpecificFlag') === 'value2' && utils.flag(this, 'message') === 'x marks the spot' , 'expected assertion to have specific flags' , "this doesn't matter" ); }); }); }); after(function() { delete chai.Assertion.prototype.x; delete chai.Assertion.prototype.checkFlags; }); it('overwriteChainableMethod', function () { // Make sure the original behavior of 'x' remains the same expect('foo').x.to.equal("foo"); expect("x").x(); expect(function () { expect("foo").x(); }).to.throw(chai.AssertionError); var obj = {}; expect(obj).x.to.be.ok; expect(obj).to.have.property('__x', 'X!'); // Test the new behavior of 'x' var assertion = expect('foo').x.to.be.ok; expect(utils.flag(assertion, 'message')).to.equal('x marks the spot'); expect(function () { var assertion = expect('x'); utils.flag(assertion, 'marked', true); assertion.x() }).to.throw(chai.AssertionError); }); it('should return a new assertion with flags copied over', function () { var assertion1 = expect('x'); var assertion2 = assertion1.x(); chai.config.proxyExcludedKeys.push('nodeType'); // Checking if a new assertion was returned expect(assertion1).to.not.be.equal(assertion2); // Check if flags were copied assertion2.checkFlags(); // Checking if it's really an instance of an Assertion expect(assertion2).to.be.instanceOf(assertionConstructor); // Test chaining `.length` after a method to guarantee it is not a function's `length` expect('x').to.be.x().length.above(0); // Ensure that foo returns an Assertion (not a function) expect(expect('x').x()).to.be.an.instanceOf(assertionConstructor); if (typeof Object.setPrototypeOf === 'function') { expect(expect('x').x).to.be.an.instanceOf(assertionConstructor); } }); it('overwriteChainableMethod sets `ssfi` when `lockSsfi` isn\'t set', function () { var origAssertion = expect('x'); var origSsfi = utils.flag(origAssertion, 'ssfi'); var newAssertion = origAssertion.to.be.x(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.not.equal(newSsfi); }); it('overwriteChainableMethod doesn\'t set `ssfi` when `lockSsfi` is set', function () { var origAssertion = expect('x'); var origSsfi = utils.flag(origAssertion, 'ssfi'); utils.flag(origAssertion, 'lockSsfi', true); var newAssertion = origAssertion.to.be.x(); var newSsfi = utils.flag(newAssertion, 'ssfi'); expect(origSsfi).to.equal(newSsfi); }); }); it('compareByInspect', function () { chai.use(function (_chai, _) { var cbi = _.compareByInspect; // "'c" is less than "'d" expect(cbi('cat', 'dog')).to.equal(-1); expect(cbi('dog', 'cat')).to.equal(1); expect(cbi('cat', 'cat')).to.equal(1); // "{ cat: [ [ 'dog', 1" is less than "{ cat [ [ 'dog', 2" expect(cbi({'cat': [['dog', 1]]}, {'cat': [['dog', 2]]})).to.equal(-1); expect(cbi({'cat': [['dog', 2]]}, {'cat': [['dog', 1]]})).to.equal(1); // "Symbol(c" is less than "Symbol(d" expect(cbi(Symbol('cat'), Symbol('dog'))).to.equal(-1); expect(cbi(Symbol('dog'), Symbol('cat'))).to.equal(1); }); }); describe('getOwnEnumerablePropertySymbols', function () { var gettem; beforeEach(function () { chai.use(function (_chai, _) { gettem = _.getOwnEnumerablePropertySymbols; }); }); it('returns an empty array if no symbols', function () { var obj = {} , cat = 'cat'; obj[cat] = 42; expect(gettem(obj)).to.not.include(cat); }); it('returns enumerable symbols only', function () { var cat = Symbol('cat') , dog = Symbol('dog') , frog = Symbol('frog') , cow = 'cow' , obj = {}; obj[cat] = 'meow'; obj[dog] = 'woof'; Object.defineProperty(obj, frog, { enumerable: false, value: 'ribbit' }); obj[cow] = 'moo'; expect(gettem(obj)).to.have.same.members([cat, dog]); }); }); describe('getOwnEnumerableProperties', function () { var gettem; beforeEach(function () { chai.use(function (_chai, _) { gettem = _.getOwnEnumerableProperties; }); }); it('returns enumerable property names if no symbols', function () { var cat = 'cat' , dog = 'dog' , frog = 'frog' , obj = {}; obj[cat] = 'meow' obj[dog] = 'woof'; Object.defineProperty(obj, frog, { enumerable: false, value: 'ribbit' }); expect(gettem(obj)).to.have.same.members([cat, dog]); }); it('returns enumerable property names and symbols', function () { var cat = Symbol('cat') , dog = Symbol('dog') , frog = Symbol('frog') , bird = 'bird' , cow = 'cow' , obj = {}; obj[cat] = 'meow'; obj[dog] = 'woof'; obj[bird] = 'chirp'; Object.defineProperty(obj, frog, { enumerable: false, value: 'ribbit' }); Object.defineProperty(obj, cow, { enumerable: false, value: 'moo' }); expect(gettem(obj)).to.have.same.members([cat, dog, bird]); }); }); describe('proxified object', function () { var proxify; beforeEach(function () { chai.use(function (_chai, _) { proxify = _.proxify; }); }); it('returns property value if an existing property is read', function () { var pizza = proxify({mushrooms: 42}); expect(pizza.mushrooms).to.equal(42); }); it('returns property value if an existing property is read when nonChainableMethodName is set', function () { var bake = function () {}; bake.numPizzas = 2; var bakeProxy = proxify(bake, 'bake'); expect(bakeProxy.numPizzas).to.equal(2); }); it('throws invalid property error if a non-existent property is read', function () { var pizza = proxify({}); expect(function () { pizza.mushrooms; }).to.throw('Invalid Chai property: mushrooms'); }); it('throws invalid use error if a non-existent property is read when nonChainableMethodName is set', function () { var bake = proxify(function () {}, 'bake'); expect(function () { bake.numPizzas; }).to.throw('Invalid Chai property: bake.numPizzas. See docs for proper usage of "bake".'); }); it('suggests a fix if a non-existent prop looks like a typo', function () { var pizza = proxify({foo: 1, bar: 2, baz: 3}); expect(function () { pizza.phoo; }).to.throw('Invalid Chai property: phoo. Did you mean "foo"?'); }); it('doesn\'t take exponential time to find string distances', function () { var pizza = proxify({veryLongPropertyNameWithLotsOfLetters: 1}); expect(function () { pizza.extremelyLongPropertyNameWithManyLetters; }).to.throw( 'Invalid Chai property: extremelyLongPropertyNameWithManyLetters' ); }); it('doesn\'t suggest properties from Object.prototype', function () { var pizza = proxify({string: 5}); expect(function () { pizza.tostring; }).to.throw('Invalid Chai property: tostring. Did you mean "string"?'); }); it('doesn\'t suggest internally properties', function () { var pizza = proxify({flags: 5, __flags: 6}); expect(function () { pizza.___flags; // 3 underscores; closer to '__flags' than 'flags' }).to.throw('Invalid Chai property: ___flags. Did you mean "flags"?'); }); // .then is excluded from property validation for promise support it('doesn\'t throw error if non-existent `then` is read', function () { var pizza = proxify({}); expect(function () { pizza.then; }).to.not.throw(); }); }); describe('addLengthGuard', function () { var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); if (!fnLengthDesc.configurable) return; var addLengthGuard; beforeEach(function () { chai.use(function (_chai, _) { addLengthGuard = _.addLengthGuard; }); }); it('throws invalid use error if `.length` is read when `methodName` is defined and `isChainable` is false', function () { var hoagie = addLengthGuard({}, 'hoagie', false); expect(function () { hoagie.length; }).to.throw('Invalid Chai property: hoagie.length. See docs for proper usage of "hoagie".'); }); it('throws incompatible `.length` error if `.length` is read when `methodName` is defined and `isChainable` is true', function () { var hoagie = addLengthGuard({}, 'hoagie', true); expect(function () { hoagie.length; }).to.throw('Invalid Chai property: hoagie.length. Due to a compatibility issue, "length" cannot directly follow "hoagie". Use "hoagie.lengthOf" instead.'); }); }); describe("isProxyEnabled", function () { var origUseProxy, isProxyEnabled; before(function () { chai.use(function (_chai, _) { isProxyEnabled = _.isProxyEnabled; }); origUseProxy = chai.config.useProxy; }); beforeEach(function () { chai.config.useProxy = true; }); after(function () { chai.config.useProxy = origUseProxy; }); it("returns true if Proxy and Reflect are defined, and useProxy is true", function () { expect(isProxyEnabled()).to.be.true; }); it("returns false if Proxy and Reflect are defined, and useProxy is false", function () { chai.config.useProxy = false; expect(isProxyEnabled()).to.be.false; }); }); describe('getOperator', function() { it('Must return operator if the "operator" flag is set', function() { chai.use(function(_chai, _) { expect(_.getOperator({}, [])).to.equal(undefined); expect(_.getOperator({}, [null, null, null])).to.equal(undefined); var obj = {}; _.flag(obj, 'operator', 'my-operator'); expect(_.getOperator(obj, [])).to.equal('my-operator'); }); }); it('Must return undefined if message is partial assertions', function() { chai.use(function(_chai, _) { expect( _.getOperator({}, [null, 'to have the same ordered', null, 'test']) ).to.equal(undefined); }); }); it('Must return deepStrictEqual if "expected" is a object and assertion is for equal', function() { chai.use(function(_chai, _) { var expected = Object.create({ dummyProperty1: 'dummyProperty1', dummyProperty2: 'dummyProperty2', dummyProperty3: 'dummyProperty3' }); var obj = {}; _.flag(obj, 'negate', false); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('deepStrictEqual'); }); }); it('Must return deepStrictEqual if "expected" is a function and assertion is for equal', function() { chai.use(function(_chai, _) { function expected () { this.prop = 'prop'; } var obj = {}; _.flag(obj, 'negate', false); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('deepStrictEqual'); }); }); it('Must return deepStrictEqual if "expected" is an array and assertion is for equal', function() { chai.use(function(_chai, _) { var expected = [ 'item 1' ]; var obj = {}; _.flag(obj, 'negate', false); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('deepStrictEqual'); }); }); it('Must return strictEqual if "expected" is a string and assertion is for equal', function() { chai.use(function(_chai, _) { var expected = 'someString'; var obj = {}; _.flag(obj, 'negate', false); expect( _.getOperator(obj, [ null, 'expect #{this} equal to #{exp}', 'expect #{this} not equal to #{exp}', expected ]) ).to.equal('strictEqual'); }); }); it('Must return notDeepStrictEqual if "expected" is a object and assertion is for inequality', function() { chai.use(function(_chai, _) { var expected = Object.create({ dummyProperty1: 'dummyProperty1', dummyProperty2: 'dummyProperty2', dummyProperty3: 'dummyProperty3' }); var obj = {}; _.flag(obj, 'negate', true); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('notDeepStrictEqual'); }); }); it('Must return notDeepStrictEqual if "expected" is a function and assertion is for inequality', function() { chai.use(function(_chai, _) { function expected () { this.prop = 'prop'; } var obj = {}; _.flag(obj, 'negate', true); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('notDeepStrictEqual'); }); }); it('Must return notDeepStrictEqual if "expected" is an array and assertion is for inequality', function() { chai.use(function(_chai, _) { var expected = [ 'item 1' ]; var obj = {}; _.flag(obj, 'negate', true); expect( _.getOperator(obj, [ null, 'expect #{this} deep equal to #{exp}', 'expect #{this} not deep equal to #{exp}', expected ]) ).to.equal('notDeepStrictEqual'); }); }); it('Must return notStrictEqual if "expected" is a string and assertion is for inequality', function() { chai.use(function(_chai, _) { var expected = 'someString'; var obj = {}; _.flag(obj, 'negate', true); expect( _.getOperator(obj, [ null, 'expect #{this} equal to #{exp}', 'expect #{this} not equal to #{exp}', expected ]) ).to.equal('notStrictEqual'); }); }); }); }); chaijs-chai-2a3ecff/test/virtual-machines.js000066400000000000000000000014661505212005400212210ustar00rootroot00000000000000import vm from 'node:vm'; import * as chai from '../index.js'; const {assert} = chai; const vmContext = {assert}; vm.createContext(vmContext); /** * Run the code in a virtual context * * @param {string} code Code to run */ function runCodeInVm(code) { vm.runInContext(code, vmContext); } describe('node virtual machines', function () { it('throws', function() { const shouldNotThrow = [ `assert.throws(function() { throw ''; }, /^$/);`, `assert.throws(function() { throw new Error('bleepbloop'); });`, `assert.throws(function() { throw new Error(''); });`, `assert.throws(function() { throw new Error('swoosh'); }, /swoosh/);` ]; for (const code of shouldNotThrow) { assert.doesNotThrow( () => { runCodeInVm(code); } ); } }); }); chaijs-chai-2a3ecff/tsconfig.json000066400000000000000000000005571505212005400171400ustar00rootroot00000000000000{ "compilerOptions": { "target": "esnext", "module": "nodenext", "moduleResolution": "nodenext", "types": [], "checkJs": true, "noEmit": true, "isolatedModules": true, "forceConsistentCasingInFileNames": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true }, "include": [ "lib/**/*.js" ] } chaijs-chai-2a3ecff/web-test-runner.config.js000066400000000000000000000007021505212005400212640ustar00rootroot00000000000000import { fromRollup } from "@web/dev-server-rollup"; import rollupCommonjs from "@rollup/plugin-commonjs"; const commonjs = fromRollup(rollupCommonjs); export default { nodeResolve: true, files: [ "test/*.js", "!test/virtual-machines.js" ], plugins: [ commonjs({ include: [ // the commonjs plugin is slow, list the required packages explicitly: "**/node_modules/type-detect/**/*", ], }), ], };