{"id":19080939,"url":"https://github.com/linuxwolf/expecto","last_synced_at":"2026-05-16T00:05:08.439Z","repository":{"id":65248987,"uuid":"589026290","full_name":"linuxwolf/expecto","owner":"linuxwolf","description":"An assertion library with an \"expect\" style interface, inspired by Chai's and built for Deno.","archived":false,"fork":false,"pushed_at":"2024-06-06T13:20:41.000Z","size":161,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-02T21:55:37.462Z","etag":null,"topics":["assertions","bdd","deno","testing","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linuxwolf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-14T20:22:41.000Z","updated_at":"2024-06-06T13:20:21.000Z","dependencies_parsed_at":"2023-02-15T18:31:22.886Z","dependency_job_id":"133399ea-2c14-4d73-a4e9-3d9eeedf1152","html_url":"https://github.com/linuxwolf/expecto","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxwolf%2Fexpecto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxwolf%2Fexpecto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxwolf%2Fexpecto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxwolf%2Fexpecto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linuxwolf","download_url":"https://codeload.github.com/linuxwolf/expecto/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240131737,"owners_count":19752727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assertions","bdd","deno","testing","typescript"],"created_at":"2024-11-09T02:26:13.679Z","updated_at":"2026-05-16T00:05:08.355Z","avatar_url":"https://github.com/linuxwolf.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EXPECTO!\n\nAn assertion library with an \"expect\" style interface, inspired by [Chai's](https://www.chaijs.com/api/bdd/) and built for [Deno](https://deno.land).  This is not a one-for-one clone of Chai; rather it is the subset that the authors find most useful with semantics the authors find most intuitive.\n\nIt wraps the value under test to provide a collection of properties and methods for chaining assertions.\n\n```typescript\nimport { expect } from \"https://deno.land/x/expecto@v0.1.0/mod/index.ts\";\n\nDeno.test(() =\u003e {\n    expect(42).to.equal(42);\n\n    expect({foo: \"foo value\"}).to.deep.equal({foo: \"foo value\"});\n});\n\n```\n\n- [INSTALLING](#installing)\n- [USING](#using)\n  - [Predicates and Prepositions](#predicates-and-prepositions)\n  - [Flags](#flags)\n    - [`deep` flag](#deep-flag)\n    - [`not` flag](#not-flag)\n  - [`Core` (**std**)](#core-std)\n    - [`equal(expected [, message ])` / `equals(expected [, message ])` check](#equalexpected--message---equalsexpected--message--check)\n    - [`throw([ errorType [, message ] ])` check](#throw-errortype--message---check)\n  - [`Typing` (**std**)](#typing-std)\n    - [`exist([ msg ])` / `exists([ msg ])` check](#exist-msg---exists-msg--check)\n    - [`undefined([ msg ])` check](#undefined-msg--check)\n    - [`null([ msg ])` check](#null-msg--check)\n    - [`true([ msg ])` check](#true-msg--check)\n    - [`false([ msg ])` check](#false-msg--check)\n    - [`NaN([ msg ])` check](#nan-msg--check)\n    - [`typeOf(type [, msg ])` check](#typeoftype--msg--check)\n    - [`instanceOf(instancClass [, msg ])` check](#instanceofinstancclass--msg--check)\n  - [`Membership` (**std**)](#membership-std)\n    - [`empty([ message ])` check](#empty-message--check)\n    - [`any` flag](#any-flag)\n    - [`all` flag](#all-flag)\n    - [`members([ expected[] [, message ] ])` check](#members-expected--message---check)\n    - [`own` flag](#own-flag)\n    - [`property(name [, message ])` check](#propertyname--message--check)\n  - [`Stringed ` (**std**)](#stringed--std)\n    - [`substring(sub [, message ])` check](#substringsub--message--check)\n    - [`startsWith(sub [, message])` check](#startswithsub--message-check)\n    - [`endsWith(sub [, message ])` check](#endswithsub--message--check)\n  - [`Promised` (**std**)](#promised-std)\n    - [`eventually` modifier](#eventually-modifier)\n    - [`rejected([ msg ])` check](#rejected-msg--check)\n    - [`rejectedWith([ errorType [, msg ] ])` check](#rejectedwith-errortype--msg---check)\n  - [`Mocked` (**mock**)](#mocked-mock)\n    - [`called([ count [, msg ] ])` check](#called-count--msg---check)\n    - [`calledWith(args [, msg ])` check](#calledwithargs--msg--check)\n- [EXTENDING](#extending)\n  - [Performing Checks](#performing-checks)\n  - [Helpers](#helpers)\n\n## INSTALLING\n\nInstall like most Deno dependencies, by importing the module(s).\n\n```typescript\nimport { expect } from \"https://deno.land/x/expecto@v0.1.0/mod/index.ts\";\n```\n\nAlthough **NOT RECOMMENDED**, it can be imported unversioned.\n\n```typescript\nimport { expect } from \"https://deno.land/x/expecto/mod.index.ts\";\n```\n\nThere are a handful of entrypoints:\n\n* `mod/index.ts` (**std**) — This is the standard setup; exports `expect` and `use`, as well as the `AssertionError` class in use.  Without any calls to `use()`, the Expecto returned by `expect()` is initialized with the `core`, `typing`, `membership`, and `promised` assertions.\n* `mod/mocked.ts` (**mock**) — This exports the (default) `mocked` assertion mixin that can be applied via `use`.  It also exports `mock` which is the [std/testing/mock](https://deno.land/std/testing/mock.ts) implementation it depends on.  **NOTE** that this requires `mod/index.ts`.\n\nIn addition, the following are useful to extend Expecto:\n\n* `mod/mixin.ts` — exports helper types and utilities for creating custom mixins.\n\n## USING\n\nAssertions are made by calling `expect()` with the value under test (`actual`) then chaining properties for assertion checks.\n\nAdditional checks and properties can be made available with `use()`.\n\n```typescript\nuse(mocked);\nuse(customMixin);\n\nDeno.test(() =\u003e {\n    const spied = mocked.spy(nestedFunc);\n\n    const result = topFunc();\n    expect(result).to.customCheck();\n    expect(spied).to.be.called(1).and.calledWith([\"foo\", \"bar\"]);\n});\n```\n\n### Predicates and Prepositions\n\nThe following predicates only return the current instance of `Expecto`; they assist with the readility of assertions.\n\n* `a` / `an`\n* `also`\n* `and`\n* `be`\n* `been`\n* `does`\n* `has` / `have`\n* `is`\n* `of`\n* `that`\n* `to`\n* `which`\n* `with`\n\n### Flags\n\nThe following \"flag\" properties are used to modify the assertion that follows them.  There are two built-in flags, and mixins can provide others.\n\nSome important notes:\n\n* Not all modifiers are supported by all assertions\n* Once an assertion is processed in a chain, all previously-set flags are cleared\n\n#### `deep` flag\n\nModifies the succeeding check to perform a deep check instead of a strict or shallow check.\n\n```typescript\nexpect({foo: \"foo value\"}).to.deep.equal({foo: \"foo value\"});\n```\n\nMultiple instances of `deep` before a check behave as if it were only one specified.\n\n#### `not` flag\n\nModifies the succeeding check to be negated.\n\n```typescript\nexpect(() =\u003e { doStuff() }).to.not.throw();\n```\n\nAs with English, two `not`s before an assertion cancel each other out:\n\n```typescript\nexpect(() =\u003e { throw new Error() }).to.not.not.throw(); // NOT RECOMMENDED!\n```\n\n### `Core` (**std**)\n\n#### `equal(expected [, message ])` / `equals(expected [, message ])` check\n\nCompares that `actual` strictly equals (`===`) the given value.\n\n```typescript\nexpect(42).to.equal(42);\nexpect(someObj).to.equal(anotherObj);\n```\n\n**NOTE** that `equal()` and `equals()` have identical behavior; use whichever makes the most grammatical sense.\n\n```typescript\nexpect(42).to.equal(42);\nexpect(someObject).which.equals(anotherObj);\n```\n\nIf `deep` is applied beforehand, then a comprehensive equality check is performed instead.\n\n```typescript\nexpect(someObj).to.deep.equal({foo: \"foo value\"});\n```\n\nIf `not` is applied beforehand, then the check is negated (strictly or deeply).\n\n```typescript\nexpect(someObj).to.not.equal(anotherObj);\nexpect(someObj).to.not.deep.equal({bar: \"far value\"});\n```\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect(someObj).to.equal(anotherObj, \"objects aren't the same\");\nexpect(someObj).to.not.equal(diffObj, \"shouldn't match, but do\");\n```\n\n#### `throw([ errorType [, message ] ])` check\n\nChecks that `actual` throws an error when invoked:\n\n```typescript\nexpect(() =\u003e throw new Error(\"oops\")).to.throw();\n```\n\nA class derived from `Error` can be provided as the first argument, to check if the thrown error is an instance of that class.\n\n```typescript\nexpect(() =\u003e throw new TypeError(\"bad type\")).to.throw(TypeError);\n```\n\nIf the check succeeds, the returned `Expecto` has the thrown error instance as its `actual`, so that further checks can be made on the error.\n\n```typescript\nexpect(() =\u003e throw new Error(\"oops\")).to.throw().with.property(\"message\").to.have.substring(\"oops\");\n```\n\nA custom message can be provided as the last argument, which is used if the check fails.\n\n```typescript\nexpect(() =\u003e throw new TypeError(\"oops\")).to.throw(RangeError, \"oops\");\n```\n\nIf `not` is applied beforehand, the check is negated (and `actual` is unchanged).\n\n```typescript\nexpect(() =\u003e {}).to.not.throw();\n```\n\nThis means, if an error type is provided, the check can succeed if `actual` throws a different error type.\n\n```typescript\nexpect(() =\u003e throw new TypeError(\"oops\")).to.not.throw(RangeError); // NOT RECOMMENDED\n```\n\nIf `actual` is not a function, a `TypeError` is thrown instead of an `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).to.throw();      // throws TypeError\nexpect(42).to.not.throw();  // still throws TypeError\n```\n\n### `Typing` (**std**)\n\n#### `exist([ msg ])` / `exists([ msg ])` check\n\nChecks that `actual` exists: is not `null` nor `undefined`.\n\n```typescript\nexpect(someValue).to.exist();\n```\n\n**NOTE** that `equal()` and `equals()` have identical behavior; use whichever makes the most grammatical sense.\n\n```typescript\nexpect(someValue).to.exist();\nexpect(somevalue).exists();\n```\n\nA custom message can be provied, which is used if the check fails.\n\n```typescript\nexpect(null).to.exist(\"does not exist!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(null).to.not.exist();\nexpect(undefined).to.not.exist();\n```\n\n#### `undefined([ msg ])` check\n\nChecks that `actual` is `undefined`.\n\n```typescript\nexpect(someValue).to.be.undefined();\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(\"something\").to.be.undefined(\"is actually defined!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(42).to.not.be.undefined();\nexpect(null).to.no.be.undefined();\n```\n\n#### `null([ msg ])` check\n\nChecks that `actual` is `null`.\n\n```typescript\nexpect(someValue).to.be.null();\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(\"some value\").to.be.null(\"is not null\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(42).to.not.be.null();\nexpect(undefined).to.not.be.null();\n```\n\n#### `true([ msg ])` check\n\nChecks that `actual` is the boolean `true`.\n\n```typescript\nexpect(someValue).to.be.true();\n```\n\nIt is not enough to be truthy, only `true` will pass.\n\n```typescript\nexpect(true).to.be.true();            // SUCCEEDS\nexpect(\"some value\").to.be.true();    // FAILS\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(false).to.be.true(\"isn't true\");\nexpect(\"some value\").to.be.true(\"isn't true, either\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(false).to.not.be.true();\nexpect(\"some value\").to.not.be.true();\n```\n#### `false([ msg ])` check\n\nChecks that `actual` is the boolean `false`.\n\n```typescript\nexpect(someValue).to.be.false();\n```\n\nIf it not enough to be falsy, only `false` will pass.\n\n```typescript\nexpect(false).to.be.false();  // SUCCEEDS\nexpect(\"\").to.be.false();     // FAILS\nexpect(null).to.be.false();   // FAILS\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(true).to.be.false(\"isn't false\");\nexpect(undefined).to.be.false(\"isn't false, either\");\n```\n\nIf `not` is applied beforeuand, it negates the check.\n\n```typescript\nexpect(true).to.not.be.false;\nexpect(\"\").to.not.be.false;\n```\n\n#### `NaN([ msg ])` check\n\nChecks that `actual` is a number and is `NaN`.  This check is necessary since `NaN !== NaN` in Javascript/Typescript!\n\n```typescript\nexpect(someNumber).is.NaN();  // SUCCEEDS if someNumber is NaN\n\nexpect(NaN).to.equal(NaN);    // ALWAYS FAILS!\n```\n\nThe check fails (throws `AssertionError`) if `actual` is not a number.\n\n```typescript\nexpect(\"some string\").is.NaN();   // FAILS with AssertionError\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(42).to.be.NaN(\"is not not-a-number\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(42).is.not.NaN();\n```\n\n#### `typeOf(type [, msg ])` check\n\nChecks that `actual` is of the given type, where `typing` is one of:\n\n* `bigint`\n* `boolean`\n* `number`\n* `object`\n* `string`\n\n```typescript\nexpect(someValue).is.a.typeOf(\"string\");\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nexpect(42).is.a.typeOf(\"string\", \"not a string!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(42).to.not.be.a.typeOf(\"string\");\n```\n\n#### `instanceOf(instancClass [, msg ])` check\n\nChecks that `actual` is an instance of the given class.\n\n```typescript\nexpect(someValue).is.an.instanceOf(SomeClass);\n```\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect(new Date()).is.an.instanceOf(RegExp, \"not a Regexp!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(new Date()).to.not.be.an.instanceOf(RegExp);\n```\n\n### `Membership` (**std**)\n\n#### `empty([ message ])` check\n\nChecks that `actual` is empty.\n\n```typescript\nexpect(someArray).is.empty();\nexpect(someStr).is.empty();\n```\n\nThe specific behavior depends on what type `actual` is:\n\n* `Set`/`Map` — checks `.size` is 0\n* `Array`/Typed Array (e.g., `Uint8Array`) — checks `.length` is 0\n* `ArrayBuffer` — checks `.byteLength` is 0\n* `string` — checks `.length` is 0\n* `object` — checks that it has no properties\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect([\"foo\", \"bar\"]).is.empty(\"has stuff!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect([\"foo\", \"bar\"]).is.not.empty();\n```\n\nIf `actual` does not meet one of the above criteria, a `TypeError` is thrown instead of `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).is.empty();      // throws TypeError\nexpect(42).is.not.empty();  // still throws TypeError\n```\n\n#### `any` flag\n\nModifies the succeeding check to only require one of the members to be present, on a membership check.\n\n```typescript\nexpect([\"foo\", \"bar\"]).to.have.any.members([\"foo\", \"baz\", \"flag\"]);\n```\n\nThis flag cancels the `all` flag.\n\n#### `all` flag\n\nModifies the succeeding check to require all of the members to be present, on a membership check.\n\n```typescript\nexpect([\"foo\", \"bar\"]).to.have.all.memebers([\"foo\", \"bar\"]);\n```\n\nNote that, for `members()`, this is its default behavior; it has no effect other than readability.\n\nThis flag cancels the `any` flag.\n\n#### `members([ expected[] [, message ] ])` check\n\nChecks that `actual` is in possession of all of the given members.  The exact behavior depends on the type of `actual`:\n\n* **`Map\u003cK, V\u003e`**: checks that all of the given members are keys on `actual`\n\n    ```typescript\n    const someValue = new Map();\n    someValue.set(\"foo\", \"foo value\");\n    someValue.set(\"bar\", \"bar value\");\n\n    ....\n\n    expect(someValue).to.have.members([\"foo\", \"bar\"])\n    ```\n\n* **`Set\u003cV\u003e`**: checks that all of the given members are contained in Set `actual`\n\n    ```typescript\n    const someValue = new Set();\n    someValue.add(\"foo\");\n    someValue.add(\"bar\");\n\n    ....\n\n    expect(someValue).to.have.members([\"foo\", \"bar\"]);\n    ```\n\n* **`Array\u003cV\u003e`**: checks that all of the given members are elements in the array `actual`\n\n    ```typescript\n    const someValue = [\"foo\", \"bar\"];\n\n    ....\n\n    expect(someValue).to.have.members([\"foo\", \"bar\"]);\n    ```\n\n* **`Object`**: checks that all of the given members are properties on `actual`\n\n    ```typescript\n    const someValue = {\n        foo: \"foo value\",\n        bar: \"bar balue\",\n    }\n\n    ....\n\n    expect(someValue).to.have.members([\"foo\", \"bar\"]);\n    ```\n\nIf `any` is applied beforehand, it checks that **any _one_** of the values is present.\n\n```typescript\nconst someValue = [\"foo\", \"bar\"];\n\n....\n\nexpect(someValue).to.have.any.members([\"foo\", \"baz\"]);  // SUCCEEDS\nexpect(someValue).to.have.any.members([\"baz\", \"flag\"]); // FAILS\n```\n\nBy default a strict comparison is used. If `deep` is applied beforehand, a comprehensive equality comparison is used.\n\n```typescript\nconst someValue = new Set([\n    { foo: \"foo value\" },\n    { bar: \"bar value\" },\n]);\n\n....\n\nexpect(someValue).to.have.deep.members([\n    { foo: \"foo value\" },\n    { bar: \"bar value\" },\n]);\n```\n\nIf `not` is applied beforehand, the check is negated.\n\n```typescript\nexpect({\n    foo: \"foo value\",\n    bar: \"bar value\",\n}).to.not.have.members([ \"car\", \"par\" ]);\n```\n\n#### `own` flag\n\nModifies the succeeding check to expect `actual` to own the property.\n\n```typescript\nexpect({foo: \"foo value\"}).to.have.own.property(\"foo\");\n```\n\n#### `property(name [, message ])` check\n\nChecks that `actual` is an object which has the given property.\n\n```typescript\nexpect(someValue).to.have.property(\"foo\");\n```\n\nIf `own` is applied beforehand, the check only succeeds if `actual` has the property directly and not from its prototype chain.\n\n```typescript\nexpect(someValue).to.have.own.property(\"foo\");\n```\n\nIf the check succeeds, the returned `Expecto` has the property's value as its `actual`, so that further checks can be made on the property.\n\n```typescript\nexpect(someValue).to.have.property(\"foo\").to.be.a.typeOf(\"string\").which.equals(\"foo value\")\n```\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect({foo: \"foo value\"}).to.have.property(\"bar\", \"no bar!!\");\n```\n\nIf `not` is applied beforehand, it negates the check (and `actual` is unchanged).\n\n```typescript\nexpect({foo: \"foo value\"}).to.not.have.property(\"bar\");\n```\n\n### `Stringed ` (**std**)\n\n#### `substring(sub [, message ])` check\n\nChecks that `actual` is a string that contains the given substring.\n\n```typescript\nexpect(someStr).to.have.substring(\"a string\");\n```\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect(\"some string value\").to.have.substring(\"this value\", \"substring missing\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(\"some string value\").to.not.have.substring(\"this value\");\n```\n\nIf `actual` is not a string, a `TypeError` is thrown instead of `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).to.have.substring(\"42\");         // throws TypeError\nexpect(42).to.not.have.substring(\"foo\");    // still throws TypeError\n```\n\n#### `startsWith(sub [, message])` check\n\nChecks that `actual` is a string that starts with the given substring.\n\n```typescript\nexpect(someStr).startsWith(\"LOG:\");\n```\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect(\"some string value\").startsWith(\"LOG:\", \"not the prefix\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(\"some string value\").to.not.startsWith(\"LOG:\");\n```\n\nIf `actual` is not a string, a `TypeError` is thrown instead of `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).startsWith(\"4\");         // throws TypeError\nexpect(42).to.not.startsWith(\"2\");  // sill throws TypeError\n```\n\n#### `endsWith(sub [, message ])` check\n\nChecks that `actual` is a string that ends with the given substring.\n\n```typescript\nexpect(someSt).endsWith(\"suffix\");\n```\n\nA custom message can be provided, which will be used if the check fails.\n\n```typescript\nexpect(\"some string value\").endsWith(\"suffix\", \"missing suffix\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(\"some string value\").to.not.endsWith(\"suffix\");\n```\n\nIf `actual` is not a string, a `TypeError` is thrown instead of `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).endsWith(\"2\");           // throws TypeError\nexpect(42).to.not.endsWith(\"4\");    // still throws TypeError\n```\n\n### `Promised` (**std**)\n\n#### `eventually` modifier\n\nTreats `actual` as a promise and defers all modifiers and checks until that promise is fulfilled.\n\nThe returned `Expecto` is essentially a thenable Proxy; all the predicates, flags, and checks applied after `eventually` are resolved when the `Execpto` is resolved (e.g., by `await`ing).\n\n```typescript\nawait expect(somePromise).to.eventually.be.a.typeOf(\"string\").which.equal(\"fulfilled!\");\n```\n\nThe ordering of the chain is maintained, just deferred.\n\n#### `rejected([ msg ])` check\n\nChecks that `actual` is a promise that is rejected, asynchronously.  Like `.eventually`, the `Expecto` returned by this check is a thenable Proxy.  The check will actually be performed once the promise is fulfilled (e.g., by `await`ing).\n\n```typescript\nawait expect(somePromsie).to.be.rejected();\n```\n\nA custom message can be provided, which is used if the check fails.\n\n```typescript\nawait expect(Promise.reolve(42)).to.be.rejected(\"was not rejected\");\n```\n\nIf the check succeeds, the returned `Expecto` has the rejection reason as its `actual`, so that further checks can be made on the error.\n\n```typescript\nconst somePromise = Promise.reject(new Error(\"oops!\"));\n\n....\n\nawait expect(somePromise).to.be.rejected().with.property(\"message\").that.has.substring(\"oops!\");\n```\n\nIf `not` is applied beforehand, it negates the check; `actual` is changed the resolved value.\n\n```typescript\nconst somePromise = Promise.resolve(\"some string\");\n\n....\n\nawait expect(somePromise).to.not.be.rejected().and.is.typeOf(\"string\");\n```\n\n#### `rejectedWith([ errorType [, msg ] ])` check\n\nChecks that `actual` is a promise that is rejected, asynchronously.  Like `.eventually`, the `Expecto` returned by this check is a thenable Proxy.  The check will actually be performed once the promise is fulfilled (e.g., by `await`ing).\n\n```typescript\nawait expect(somePromise).to.be.rejectedWith();\n```\n\nIf the check succeeds, the returned `Expecto` has the rejection reason as its `actual`, so that further checks can be made on the error.\n\n```typescript\nawait expect(somePromise).to.be.rejectedWith().with.property(\"message\").that.has.substring(\"oops\");\n```\n\nA class can be provided as the first argument, to check if the thrown errorr is an instance of that class.\n\n```typescript\nawait expect(() =\u003e Promise.reject(new TypeError(\"wrong type\"))).to.be.rejectedWith(TypeError);\n```\n\nA custom message can be provided as the last argument, which is used if the check fails.\n\n```typescript\nawait expect(() =\u003e Promise.reject(new RangeError(\"out of bounds\"))).to.be.rejectedWith(TypeError, \"not a type error!\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nawait expect(Promise.resolve(\"some string\")).to.not.be.rejectedWith();\n```\n\n**Note** this means the check succeeds if the promise successfully resolved _**or**_ was rejected with a different error!\n\n### `Mocked` (**mock**)\n\n#### `called([ count [, msg ] ])` check\n\nChecks that `actual` is a Spy or Stub and was called.\n\n```typescript\nexpect(someSpy).to.have.been.called();\n```\n\nA count can be provided in the first argument, that checks the spy was called that number of times.\n\n```typescript\nsomeSpy();\nsomeSpy();\n\n....\n\nexpect(someSpy).to.have.been.called(2);\n```\n\nA custom message can be provided as the last argument, which is used if the check fails.\n\n```typescript\nexpect(someSpy).to.have.been.called(undefined, \"spy never called\");\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(someSpy).to.have.not.been.called();\n```\n\n**NOTE** the negated check can succeed if a count is provided to `called()` and the spy is called a different number of times (e.g., called 5 times but checking for `.called(3)`)!\n\nIf `actual` is not a Spy or Stub, a `TypeError` is thrown istead of an `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).to.have.been.called();                   // throws TypeError\nexpect(\"some string\").to.have.not.been.called();    // still throws TypeError\n```\n\n#### `calledWith(args [, msg ])` check\n\nChecks that `actual` is a Spy or Stub that was called with the given arguments.\n\n```typescript\nexpect(someSpy).to.have.been.calledWith([\"foo\", \"bar\"]);\n```\n\nIf `actual` was called multiple times, this check succeeds if at least one of those calls included the given arguments.  By default this check performs a strict (===) equality check over the arguments.\n\nIf `deep` is applied beforehand, a comprehensive equality check of the arguments is performed.\n\n```typescript\nsomeSpy({\n    \"foo\": \"foo value\",\n    \"bar\": \"bar value\",\n});\n\nexpect(someSpy).to.have.been.calledWith([ {\"foo\": \"foo value\", \"bar\": \"bar value\" }]);      // fails\nexpect(someSpy).to.have.been.deep.calledWith([ {\"foo\": \"foo value\", \"bar\": \"bar value\" }]); // succeeds\n```\n\nIf `not` is applied beforehand, it negates the check.\n\n```typescript\nexpect(someSpy).to.not.have.been.calledWith([\"foo\", \"bar\"]);\n```\n\nIf `actual` is not a Spy or Stub, a `TypeError` is thrown istead of an `AssertionError`.  This occurs regardless if `not` is applied.\n\n```typescript\nexpect(42).to.have.been.calledWith([]);                 // throws TypeError\nexpect(\"some string\").to.have.not.been.calledWith([]);  // still throws TypeError\n```\n\n## EXTENDING\n\nExpecto can be extended with additional checks and/or flags using the mixin pattern.\n\nGet started by importing `mod/mixin.ts` module to access the symbols and utilities for developing your own mixins.\n\nTo add a custom mixin to Expecto, implement a factory function that takes the current Expecto-derived class and returns a new Expecto-derived class.\n\n```typescript\nimport type { CheckDetails, ExpectoConstructor } from \"https://deno.land/x/expecto/mod/mixin.ts\";\n\nimport { meetsExpectations } from \"./custom.ts\";\n\nexport function customMixin\u003cTargetType, BaseType extends ExpectoConstructor\u003cTargetType\u003e\u003e(Base: BaseType) {\n    return class CustomMixin extends Base {\n        constructor(...args: any[]) {\n            super(...args);\n        }\n\n        cusomCheck(): this {\n            let result = meetsExpectations(this.actual);\n            this.check(result, {\n                positiveOp: \"does not meet expectations\",\n                negativeOp: \"meets expectations\",\n            } as CheckDetails)\n            return this;\n        }\n    };\n}\n\n\n### Performing Checks\n\nThe assertion check is performed using `.check(result: boolean, details: CheckDetails)`; `result` is the result to verify, and `details` provides the following:\n\n* `expected`: `unknown` (*OPTIONAL*) — What `actual` is expected to be\n* `positiveOp`: `string` — The operation description if a positive (not `.not`) test fails\n* `negativeOp`: `string` — The operation description if a negatved (`.not`) test fails\n* `message`: `string` (*OPTIONAL*) — The messge—in its entirety—to use if the test fails\n\nThe `.check()` method—by default—tests if `result` is truthy, and throws an `AssertionError` if it is not.  If the `not` flag is applied, it instead tests if `result` is falsy, and throws an `AssertionError` if it is not.  If `message` is not provided, the rest of `details` is used to construct the error message.\n\n### Helpers\n\nThe following protected members are available to mixins to aid in checks:\n\n* `.flags(): string[]` — Retrieves a snapshot of currently-set flags on this Expecto.  A flag is set if its name is in the returned array.\n* `.hasFlag(flag: string): boolean` — Returns `true` if the given flag is set.\n* `.setFlag(flag: string)` — Sets the given flag, including it in the values returned by `flags()`.\n* `.unsetFlag(flag: string)`— Removes the given flag, excluding it in the values returned by `flags()`.\n* `.toggleFlag(flag: string): boolean` — Toggles the given flag; sets it if it was not before, or unsets it if it was; retursn the current state (`true` for set, `false` otherwise).\n* `.create\u003cT\u003e(actual: T): this` — Creates a new Expecto of the same type as this Expecto, using `actual` as the target value and with all the flags currently set on this Expecto.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinuxwolf%2Fexpecto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinuxwolf%2Fexpecto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinuxwolf%2Fexpecto/lists"}