@metamask/snaps-jest 8.9.0 → 8.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -1
- package/dist/global.cjs.map +1 -1
- package/dist/global.d.cts +9 -3
- package/dist/global.d.cts.map +1 -1
- package/dist/global.d.mts +9 -3
- package/dist/global.d.mts.map +1 -1
- package/dist/global.mjs.map +1 -1
- package/dist/helpers.cjs +2 -1
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.mjs +2 -1
- package/dist/helpers.mjs.map +1 -1
- package/dist/matchers.cjs +72 -14
- package/dist/matchers.cjs.map +1 -1
- package/dist/matchers.d.cts +15 -5
- package/dist/matchers.d.cts.map +1 -1
- package/dist/matchers.d.mts +15 -5
- package/dist/matchers.d.mts.map +1 -1
- package/dist/matchers.mjs +73 -15
- package/dist/matchers.mjs.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [8.11.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Mock `eth_chainId` and `net_version` calls automatically ([#3017](https://github.com/MetaMask/snaps/pull/3017))
|
|
15
|
+
|
|
16
|
+
## [8.10.0]
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Allow unit testing of expanded-view notifications ([#2956](https://github.com/MetaMask/snaps/pull/2956))
|
|
21
|
+
- Add `onBackgroundEvent` alias ([#2974](https://github.com/MetaMask/snaps/pull/2974))
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Bump MetaMask dependencies ([#2946](https://github.com/MetaMask/snaps/pull/2946))
|
|
26
|
+
|
|
10
27
|
## [8.9.0]
|
|
11
28
|
|
|
12
29
|
### Added
|
|
@@ -313,7 +330,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
313
330
|
- The version of the package no longer needs to match the version of all other
|
|
314
331
|
MetaMask Snaps packages.
|
|
315
332
|
|
|
316
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.
|
|
333
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.11.0...HEAD
|
|
334
|
+
[8.11.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.10.0...@metamask/snaps-jest@8.11.0
|
|
335
|
+
[8.10.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.9.0...@metamask/snaps-jest@8.10.0
|
|
317
336
|
[8.9.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.8.1...@metamask/snaps-jest@8.9.0
|
|
318
337
|
[8.8.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.8.0...@metamask/snaps-jest@8.8.1
|
|
319
338
|
[8.8.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.7.1...@metamask/snaps-jest@8.8.0
|
package/dist/global.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.cjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":";AAAA,oNAAoN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars, @typescript-eslint/no-namespace */\n\nimport type {\n EnumToUnion,\n NotificationType,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\n\ninterface SnapsMatchers {\n /**\n * Assert that the response is a JSON-RPC response with the given result. This\n * is equivalent to calling `expect(response.result).toStrictEqual(result)`.\n *\n * @param response - The expected response result.\n * @throws If the response is not a JSON-RPC response with the given result.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWith('bar');\n */\n toRespondWith(response: unknown): void;\n\n /**\n * Assert that the response is a JSON-RPC response with the given error. This\n * is equivalent to calling `expect(response.error).toStrictEqual(error)`.\n *\n * @param error - The expected response error.\n * @throws If the response is not a JSON-RPC response with the given error.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWithError({\n * code: -32601,\n * message: 'The method does not exist / is not available.',\n * stack: expect.any(String),\n * data: { method: 'foo', cause: null },\n * });\n */\n toRespondWithError(error: unknown): void;\n\n /**\n * Assert that the Snap sent a notification with the expected message, and\n * optionally the expected notification type. This is equivalent to calling\n * `expect(response.notifications).toContainEqual({ message, type })`.\n *\n * @param message - The expected notification message.\n * @param type - The expected notification type, i.e., 'inApp' or 'native'
|
|
1
|
+
{"version":3,"file":"global.cjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":";AAAA,oNAAoN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars, @typescript-eslint/no-namespace */\n\nimport type {\n EnumToUnion,\n NotificationType,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\n\ninterface SnapsMatchers {\n /**\n * Assert that the response is a JSON-RPC response with the given result. This\n * is equivalent to calling `expect(response.result).toStrictEqual(result)`.\n *\n * @param response - The expected response result.\n * @throws If the response is not a JSON-RPC response with the given result.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWith('bar');\n */\n toRespondWith(response: unknown): void;\n\n /**\n * Assert that the response is a JSON-RPC response with the given error. This\n * is equivalent to calling `expect(response.error).toStrictEqual(error)`.\n *\n * @param error - The expected response error.\n * @throws If the response is not a JSON-RPC response with the given error.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWithError({\n * code: -32601,\n * message: 'The method does not exist / is not available.',\n * stack: expect.any(String),\n * data: { method: 'foo', cause: null },\n * });\n */\n toRespondWithError(error: unknown): void;\n\n /**\n * Assert that the Snap sent a notification with the expected message, and\n * optionally the expected notification type. This is equivalent to calling\n * `expect(response.notifications).toContainEqual({ message, type })`.\n *\n * @param message - The expected notification message.\n * @param type - The expected notification type, i.e., 'inApp' or 'native'.\n * @param title - The title of an expanded notification.\n * @param content - The content of an expanded notification.\n * @param footerLink - The footer link of an expanded notification (if it exists).\n * @throws If the snap did not send a notification with the expected message.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toSendNotification('bar', NotificationType.InApp);\n */\n toSendNotification(\n message: string,\n type: EnumToUnion<NotificationType>,\n title?: string,\n content?: JSXElement,\n footerLink?: { text: string; href: string },\n ): void;\n\n /**\n * Assert that the Snap rendered the expected component. This is equivalent to\n * calling `expect(interface.content).toStrictEqual(component)`.\n *\n * @param component - The expected rendered component.\n * @throws If the snap did not render the expected component.\n * @example\n * const response = request({ method: 'foo' });\n * const ui = await response.getInterface();\n * expect(ui).toRender(panel([heading('Hello, world!')]));\n */\n toRender(component: ComponentOrElement): void;\n}\n\n// Extend the `expect` interface with the new matchers. This is used when\n// importing `expect` from `@jest/globals`.\ndeclare module 'expect' {\n interface AsymmetricMatchers extends SnapsMatchers {}\n\n // Ideally we would use `Matchers<Result>` instead of `Matchers<R>`, but\n // TypeScript doesn't allow this:\n // TS2428: All declarations of 'Matchers' must have identical type parameters.\n interface Matchers<R> extends SnapsMatchers {}\n}\n\n// Extend the Jest global namespace with the new matchers. This is used when\n// using the global `expect` function.\ndeclare global {\n namespace jest {\n // Ideally we would use `Matchers<Result>` instead of `Matchers<R>`, but\n // TypeScript doesn't allow this:\n // TS2428: All declarations of 'Matchers' must have identical type parameters.\n interface Matchers<R> extends SnapsMatchers {}\n }\n}\n"]}
|
package/dist/global.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EnumToUnion, NotificationType, ComponentOrElement } from "@metamask/snaps-sdk";
|
|
2
|
+
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
2
3
|
interface SnapsMatchers {
|
|
3
4
|
/**
|
|
4
5
|
* Assert that the response is a JSON-RPC response with the given result. This
|
|
@@ -33,14 +34,19 @@ interface SnapsMatchers {
|
|
|
33
34
|
* `expect(response.notifications).toContainEqual({ message, type })`.
|
|
34
35
|
*
|
|
35
36
|
* @param message - The expected notification message.
|
|
36
|
-
* @param type - The expected notification type, i.e., 'inApp' or 'native'.
|
|
37
|
-
*
|
|
37
|
+
* @param type - The expected notification type, i.e., 'inApp' or 'native'.
|
|
38
|
+
* @param title - The title of an expanded notification.
|
|
39
|
+
* @param content - The content of an expanded notification.
|
|
40
|
+
* @param footerLink - The footer link of an expanded notification (if it exists).
|
|
38
41
|
* @throws If the snap did not send a notification with the expected message.
|
|
39
42
|
* @example
|
|
40
43
|
* const response = await request({ method: 'foo' });
|
|
41
44
|
* expect(response).toSendNotification('bar', NotificationType.InApp);
|
|
42
45
|
*/
|
|
43
|
-
toSendNotification(message: string, type
|
|
46
|
+
toSendNotification(message: string, type: EnumToUnion<NotificationType>, title?: string, content?: JSXElement, footerLink?: {
|
|
47
|
+
text: string;
|
|
48
|
+
href: string;
|
|
49
|
+
}): void;
|
|
44
50
|
/**
|
|
45
51
|
* Assert that the Snap rendered the expected component. This is equivalent to
|
|
46
52
|
* calling `expect(interface.content).toStrictEqual(component)`.
|
package/dist/global.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.d.cts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EACnB,4BAA4B;
|
|
1
|
+
{"version":3,"file":"global.d.cts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EACnB,4BAA4B;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAE1D,UAAU,aAAa;IACrB;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAEvC;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,EACnC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,UAAU,EACpB,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC1C,IAAI,CAAC;IAER;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC/C;AAID,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,kBAAmB,SAAQ,aAAa;KAAG;IAKrD,UAAU,QAAQ,CAAC,CAAC,CAAE,SAAQ,aAAa;KAAG;CAC/C;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QAIb,UAAU,QAAQ,CAAC,CAAC,CAAE,SAAQ,aAAa;SAAG;KAC/C;CACF"}
|
package/dist/global.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EnumToUnion, NotificationType, ComponentOrElement } from "@metamask/snaps-sdk";
|
|
2
|
+
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
2
3
|
interface SnapsMatchers {
|
|
3
4
|
/**
|
|
4
5
|
* Assert that the response is a JSON-RPC response with the given result. This
|
|
@@ -33,14 +34,19 @@ interface SnapsMatchers {
|
|
|
33
34
|
* `expect(response.notifications).toContainEqual({ message, type })`.
|
|
34
35
|
*
|
|
35
36
|
* @param message - The expected notification message.
|
|
36
|
-
* @param type - The expected notification type, i.e., 'inApp' or 'native'.
|
|
37
|
-
*
|
|
37
|
+
* @param type - The expected notification type, i.e., 'inApp' or 'native'.
|
|
38
|
+
* @param title - The title of an expanded notification.
|
|
39
|
+
* @param content - The content of an expanded notification.
|
|
40
|
+
* @param footerLink - The footer link of an expanded notification (if it exists).
|
|
38
41
|
* @throws If the snap did not send a notification with the expected message.
|
|
39
42
|
* @example
|
|
40
43
|
* const response = await request({ method: 'foo' });
|
|
41
44
|
* expect(response).toSendNotification('bar', NotificationType.InApp);
|
|
42
45
|
*/
|
|
43
|
-
toSendNotification(message: string, type
|
|
46
|
+
toSendNotification(message: string, type: EnumToUnion<NotificationType>, title?: string, content?: JSXElement, footerLink?: {
|
|
47
|
+
text: string;
|
|
48
|
+
href: string;
|
|
49
|
+
}): void;
|
|
44
50
|
/**
|
|
45
51
|
* Assert that the Snap rendered the expected component. This is equivalent to
|
|
46
52
|
* calling `expect(interface.content).toStrictEqual(component)`.
|
package/dist/global.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.d.mts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EACnB,4BAA4B;
|
|
1
|
+
{"version":3,"file":"global.d.mts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EACnB,4BAA4B;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAE1D,UAAU,aAAa;IACrB;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAEvC;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,EACnC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,UAAU,EACpB,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC1C,IAAI,CAAC;IAER;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC/C;AAID,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,kBAAmB,SAAQ,aAAa;KAAG;IAKrD,UAAU,QAAQ,CAAC,CAAC,CAAE,SAAQ,aAAa;KAAG;CAC/C;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QAIb,UAAU,QAAQ,CAAC,CAAC,CAAE,SAAQ,aAAa;SAAG;KAC/C;CACF"}
|
package/dist/global.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.mjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,oNAAoN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars, @typescript-eslint/no-namespace */\n\nimport type {\n EnumToUnion,\n NotificationType,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\n\ninterface SnapsMatchers {\n /**\n * Assert that the response is a JSON-RPC response with the given result. This\n * is equivalent to calling `expect(response.result).toStrictEqual(result)`.\n *\n * @param response - The expected response result.\n * @throws If the response is not a JSON-RPC response with the given result.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWith('bar');\n */\n toRespondWith(response: unknown): void;\n\n /**\n * Assert that the response is a JSON-RPC response with the given error. This\n * is equivalent to calling `expect(response.error).toStrictEqual(error)`.\n *\n * @param error - The expected response error.\n * @throws If the response is not a JSON-RPC response with the given error.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWithError({\n * code: -32601,\n * message: 'The method does not exist / is not available.',\n * stack: expect.any(String),\n * data: { method: 'foo', cause: null },\n * });\n */\n toRespondWithError(error: unknown): void;\n\n /**\n * Assert that the Snap sent a notification with the expected message, and\n * optionally the expected notification type. This is equivalent to calling\n * `expect(response.notifications).toContainEqual({ message, type })`.\n *\n * @param message - The expected notification message.\n * @param type - The expected notification type, i.e., 'inApp' or 'native'
|
|
1
|
+
{"version":3,"file":"global.mjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,oNAAoN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars, @typescript-eslint/no-namespace */\n\nimport type {\n EnumToUnion,\n NotificationType,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\n\ninterface SnapsMatchers {\n /**\n * Assert that the response is a JSON-RPC response with the given result. This\n * is equivalent to calling `expect(response.result).toStrictEqual(result)`.\n *\n * @param response - The expected response result.\n * @throws If the response is not a JSON-RPC response with the given result.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWith('bar');\n */\n toRespondWith(response: unknown): void;\n\n /**\n * Assert that the response is a JSON-RPC response with the given error. This\n * is equivalent to calling `expect(response.error).toStrictEqual(error)`.\n *\n * @param error - The expected response error.\n * @throws If the response is not a JSON-RPC response with the given error.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toRespondWithError({\n * code: -32601,\n * message: 'The method does not exist / is not available.',\n * stack: expect.any(String),\n * data: { method: 'foo', cause: null },\n * });\n */\n toRespondWithError(error: unknown): void;\n\n /**\n * Assert that the Snap sent a notification with the expected message, and\n * optionally the expected notification type. This is equivalent to calling\n * `expect(response.notifications).toContainEqual({ message, type })`.\n *\n * @param message - The expected notification message.\n * @param type - The expected notification type, i.e., 'inApp' or 'native'.\n * @param title - The title of an expanded notification.\n * @param content - The content of an expanded notification.\n * @param footerLink - The footer link of an expanded notification (if it exists).\n * @throws If the snap did not send a notification with the expected message.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toSendNotification('bar', NotificationType.InApp);\n */\n toSendNotification(\n message: string,\n type: EnumToUnion<NotificationType>,\n title?: string,\n content?: JSXElement,\n footerLink?: { text: string; href: string },\n ): void;\n\n /**\n * Assert that the Snap rendered the expected component. This is equivalent to\n * calling `expect(interface.content).toStrictEqual(component)`.\n *\n * @param component - The expected rendered component.\n * @throws If the snap did not render the expected component.\n * @example\n * const response = request({ method: 'foo' });\n * const ui = await response.getInterface();\n * expect(ui).toRender(panel([heading('Hello, world!')]));\n */\n toRender(component: ComponentOrElement): void;\n}\n\n// Extend the `expect` interface with the new matchers. This is used when\n// importing `expect` from `@jest/globals`.\ndeclare module 'expect' {\n interface AsymmetricMatchers extends SnapsMatchers {}\n\n // Ideally we would use `Matchers<Result>` instead of `Matchers<R>`, but\n // TypeScript doesn't allow this:\n // TS2428: All declarations of 'Matchers' must have identical type parameters.\n interface Matchers<R> extends SnapsMatchers {}\n}\n\n// Extend the Jest global namespace with the new matchers. This is used when\n// using the global `expect` function.\ndeclare global {\n namespace jest {\n // Ideally we would use `Matchers<Result>` instead of `Matchers<R>`, but\n // TypeScript doesn't allow this:\n // TS2428: All declarations of 'Matchers' must have identical type parameters.\n interface Matchers<R> extends SnapsMatchers {}\n }\n}\n"]}
|
package/dist/helpers.cjs
CHANGED
|
@@ -52,7 +52,7 @@ function getOptions(snapId, options) {
|
|
|
52
52
|
*/
|
|
53
53
|
async function installSnap(snapId, options = {}) {
|
|
54
54
|
const resolvedOptions = getOptions(snapId, options);
|
|
55
|
-
const { request, onTransaction, sendTransaction, onSignature, onCronjob, runCronjob, onHomePage, onSettingsPage, onKeyringRequest, onInstall, onUpdate, onNameLookup, mockJsonRpc, close, } = await (0, internals_1.getEnvironment)().installSnap(...resolvedOptions);
|
|
55
|
+
const { request, onTransaction, sendTransaction, onSignature, onCronjob, runCronjob, onBackgroundEvent, onHomePage, onSettingsPage, onKeyringRequest, onInstall, onUpdate, onNameLookup, mockJsonRpc, close, } = await (0, internals_1.getEnvironment)().installSnap(...resolvedOptions);
|
|
56
56
|
return {
|
|
57
57
|
request,
|
|
58
58
|
onTransaction,
|
|
@@ -60,6 +60,7 @@ async function installSnap(snapId, options = {}) {
|
|
|
60
60
|
onSignature,
|
|
61
61
|
onCronjob,
|
|
62
62
|
runCronjob,
|
|
63
|
+
onBackgroundEvent,
|
|
63
64
|
onHomePage,
|
|
64
65
|
onSettingsPage,
|
|
65
66
|
onKeyringRequest,
|
package/dist/helpers.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AAGA,uDAAgD;AAChD,2CAAqD;AAErD,qDAAyD;AAEzD,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAU,EAAE,SAAS,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,SAAS,UAAU,CAKjB,MAAiE,EACjE,OAA6C;IAE7C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3B,CAAC;AAqGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACI,KAAK,UAAU,WAAW,CAK/B,MAAsD,EACtD,UAAgD,EAAE;IAElD,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,EACJ,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACX,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,KAAK,GACN,GAAG,MAAM,IAAA,0BAAc,GAAE,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC,CAAC;IAE3D,OAAO;QACL,OAAO;QACP,aAAa;QACb,eAAe;QACf,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;QACV,cAAc;QACd,gBAAgB;QAChB,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAClC,IAAA,qBAAO,EACL,uIAAuI,CACxI,CAAC;YAEF,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AAGA,uDAAgD;AAChD,2CAAqD;AAErD,qDAAyD;AAEzD,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAU,EAAE,SAAS,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,SAAS,UAAU,CAKjB,MAAiE,EACjE,OAA6C;IAE7C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3B,CAAC;AAqGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACI,KAAK,UAAU,WAAW,CAK/B,MAAsD,EACtD,UAAgD,EAAE;IAElD,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,EACJ,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACX,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,KAAK,GACN,GAAG,MAAM,IAAA,0BAAc,GAAE,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC,CAAC;IAE3D,OAAO;QACL,OAAO;QACP,aAAa;QACb,eAAe;QACf,WAAW;QACX,SAAS;QACT,UAAU;QACV,iBAAiB;QACjB,UAAU;QACV,cAAc;QACd,gBAAgB;QAChB,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAClC,IAAA,qBAAO,EACL,uIAAuI,CACxI,CAAC;YAEF,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAnDD,kCAmDC","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { InstallSnapOptions, Snap } from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger, getEnvironment } from './internals';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Get the options for {@link installSnap}.\n *\n * @param snapId - The ID of the Snap, or the options.\n * @param options - The options, if any.\n * @returns The options.\n */\nfunction getOptions<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId | Partial<InstallSnapOptions<Service>> | undefined,\n options: Partial<InstallSnapOptions<Service>>,\n): [SnapId | undefined, Partial<InstallSnapOptions<Service>>] {\n if (typeof snapId === 'object') {\n return [undefined, snapId];\n }\n\n return [snapId, options];\n}\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(options: Partial<InstallSnapOptions<Service>>): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId,\n options?: Partial<InstallSnapOptions<Service>>,\n): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n const {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onBackgroundEvent,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n\n return {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onBackgroundEvent,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close: async () => {\n log('Closing execution service.');\n logInfo(\n 'Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.',\n );\n\n await close();\n },\n };\n}\n"]}
|
package/dist/helpers.mjs
CHANGED
|
@@ -49,7 +49,7 @@ function getOptions(snapId, options) {
|
|
|
49
49
|
*/
|
|
50
50
|
export async function installSnap(snapId, options = {}) {
|
|
51
51
|
const resolvedOptions = getOptions(snapId, options);
|
|
52
|
-
const { request, onTransaction, sendTransaction, onSignature, onCronjob, runCronjob, onHomePage, onSettingsPage, onKeyringRequest, onInstall, onUpdate, onNameLookup, mockJsonRpc, close, } = await getEnvironment().installSnap(...resolvedOptions);
|
|
52
|
+
const { request, onTransaction, sendTransaction, onSignature, onCronjob, runCronjob, onBackgroundEvent, onHomePage, onSettingsPage, onKeyringRequest, onInstall, onUpdate, onNameLookup, mockJsonRpc, close, } = await getEnvironment().installSnap(...resolvedOptions);
|
|
53
53
|
return {
|
|
54
54
|
request,
|
|
55
55
|
onTransaction,
|
|
@@ -57,6 +57,7 @@ export async function installSnap(snapId, options = {}) {
|
|
|
57
57
|
onSignature,
|
|
58
58
|
onCronjob,
|
|
59
59
|
runCronjob,
|
|
60
|
+
onBackgroundEvent,
|
|
60
61
|
onHomePage,
|
|
61
62
|
onSettingsPage,
|
|
62
63
|
onKeyringRequest,
|
package/dist/helpers.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,8BAA8B;AAChD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AAErD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,8BAAoB;AAEzD,MAAM,GAAG,GAAG,kBAAkB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,SAAS,UAAU,CAKjB,MAAiE,EACjE,OAA6C;IAE7C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3B,CAAC;AAqGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAK/B,MAAsD,EACtD,UAAgD,EAAE;IAElD,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,EACJ,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACX,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,KAAK,GACN,GAAG,MAAM,cAAc,EAAE,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC,CAAC;IAE3D,OAAO;QACL,OAAO;QACP,aAAa;QACb,eAAe;QACf,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;QACV,cAAc;QACd,gBAAgB;QAChB,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAClC,OAAO,CACL,uIAAuI,CACxI,CAAC;YAEF,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { InstallSnapOptions, Snap } from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger, getEnvironment } from './internals';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Get the options for {@link installSnap}.\n *\n * @param snapId - The ID of the Snap, or the options.\n * @param options - The options, if any.\n * @returns The options.\n */\nfunction getOptions<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId | Partial<InstallSnapOptions<Service>> | undefined,\n options: Partial<InstallSnapOptions<Service>>,\n): [SnapId | undefined, Partial<InstallSnapOptions<Service>>] {\n if (typeof snapId === 'object') {\n return [undefined, snapId];\n }\n\n return [snapId, options];\n}\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(options: Partial<InstallSnapOptions<Service>>): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId,\n options?: Partial<InstallSnapOptions<Service>>,\n): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n const {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n\n return {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close: async () => {\n log('Closing execution service.');\n logInfo(\n 'Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.',\n );\n\n await close();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,8BAA8B;AAChD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AAErD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,8BAAoB;AAEzD,MAAM,GAAG,GAAG,kBAAkB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,SAAS,UAAU,CAKjB,MAAiE,EACjE,OAA6C;IAE7C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3B,CAAC;AAqGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAK/B,MAAsD,EACtD,UAAgD,EAAE;IAElD,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,EACJ,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACX,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,KAAK,GACN,GAAG,MAAM,cAAc,EAAE,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC,CAAC;IAE3D,OAAO;QACL,OAAO;QACP,aAAa;QACb,eAAe;QACf,WAAW;QACX,SAAS;QACT,UAAU;QACV,iBAAiB;QACjB,UAAU;QACV,cAAc;QACd,gBAAgB;QAChB,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAClC,OAAO,CACL,uIAAuI,CACxI,CAAC;YAEF,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { InstallSnapOptions, Snap } from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger, getEnvironment } from './internals';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Get the options for {@link installSnap}.\n *\n * @param snapId - The ID of the Snap, or the options.\n * @param options - The options, if any.\n * @returns The options.\n */\nfunction getOptions<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId | Partial<InstallSnapOptions<Service>> | undefined,\n options: Partial<InstallSnapOptions<Service>>,\n): [SnapId | undefined, Partial<InstallSnapOptions<Service>>] {\n if (typeof snapId === 'object') {\n return [undefined, snapId];\n }\n\n return [snapId, options];\n}\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(options: Partial<InstallSnapOptions<Service>>): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId,\n options?: Partial<InstallSnapOptions<Service>>,\n): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n const {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onBackgroundEvent,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n\n return {\n request,\n onTransaction,\n sendTransaction,\n onSignature,\n onCronjob,\n runCronjob,\n onBackgroundEvent,\n onHomePage,\n onSettingsPage,\n onKeyringRequest,\n onInstall,\n onUpdate,\n onNameLookup,\n mockJsonRpc,\n close: async () => {\n log('Closing execution service.');\n logInfo(\n 'Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.',\n );\n\n await close();\n },\n };\n}\n"]}
|
package/dist/matchers.cjs
CHANGED
|
@@ -87,24 +87,82 @@ exports.toRespondWithError = toRespondWithError;
|
|
|
87
87
|
* is intended to be used with the `expect` global.
|
|
88
88
|
*
|
|
89
89
|
* @param actual - The actual response.
|
|
90
|
-
* @param
|
|
91
|
-
* @param
|
|
90
|
+
* @param expectedMessage - The expected notification message.
|
|
91
|
+
* @param expectedType - The expected notification type.
|
|
92
|
+
* @param expectedTitle - The expected notification title.
|
|
93
|
+
* @param expectedContent - The expected notification JSX content.
|
|
94
|
+
* @param expectedFooterLink - The expected footer link object.
|
|
92
95
|
* @returns The status and message.
|
|
93
96
|
*/
|
|
94
|
-
const toSendNotification = function (actual,
|
|
97
|
+
const toSendNotification = function (actual, expectedMessage, expectedType, expectedTitle, expectedContent, expectedFooterLink) {
|
|
95
98
|
assertActualIsSnapResponse(actual, 'toSendNotification');
|
|
96
99
|
const { notifications } = actual;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
let jsxContent;
|
|
101
|
+
if ('getInterface' in actual) {
|
|
102
|
+
jsxContent = actual.getInterface().content;
|
|
103
|
+
}
|
|
104
|
+
const notificationValidator = (notification) => {
|
|
105
|
+
const { type, message, title, footerLink } = notification;
|
|
106
|
+
if (!this.equals(message, expectedMessage)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (expectedType && type !== expectedType) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (title && !this.equals(title, expectedTitle)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (jsxContent && !this.equals(jsxContent, expectedContent)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (footerLink && !this.equals(footerLink, expectedFooterLink)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
};
|
|
123
|
+
const pass = notifications.some(notificationValidator);
|
|
124
|
+
const transformedNotifications = notifications.map((notification) => {
|
|
125
|
+
return {
|
|
126
|
+
...notification,
|
|
127
|
+
// Ok to cast here as the function returns if the param is falsy
|
|
128
|
+
content: (0, snaps_utils_1.serialiseJsx)(jsxContent),
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
const message = () => {
|
|
132
|
+
let testMessage = pass
|
|
133
|
+
? `${this.utils.matcherHint('.not.toSendNotification')}\n\n`
|
|
134
|
+
: `${this.utils.matcherHint('.toSendNotification')}\n\n`;
|
|
135
|
+
const { title, type, message: notifMessage, footerLink, content, } = transformedNotifications[0];
|
|
136
|
+
testMessage += `Expected message: ${this.utils.printExpected(expectedMessage)}\n`;
|
|
137
|
+
if (expectedType) {
|
|
138
|
+
testMessage += `Expected type: ${this.utils.printExpected(expectedType)}\n`;
|
|
139
|
+
}
|
|
140
|
+
if (title) {
|
|
141
|
+
testMessage += `Expected title: ${this.utils.printExpected(expectedTitle)}\n`;
|
|
142
|
+
// We want to check if the expected content is actually JSX content, otherwise `serialiseJsx` won't return something useful.
|
|
143
|
+
if ((0, superstruct_1.is)(expectedContent, jsx_1.JSXElementStruct)) {
|
|
144
|
+
testMessage += `Expected content: ${this.utils.printExpected((0, snaps_utils_1.serialiseJsx)(expectedContent))}\n`;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
testMessage += `Expected content: ${this.utils.printExpected(expectedContent)}\n`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (footerLink) {
|
|
151
|
+
testMessage += `Expected footer link: ${this.utils.printExpected(expectedFooterLink)}\n`;
|
|
152
|
+
}
|
|
153
|
+
testMessage += `Received message: ${this.utils.printExpected(notifMessage)}\n`;
|
|
154
|
+
if (expectedType) {
|
|
155
|
+
testMessage += `Received type: ${this.utils.printReceived(type)}\n`;
|
|
156
|
+
}
|
|
157
|
+
if (title) {
|
|
158
|
+
testMessage += `Received title: ${this.utils.printReceived(title)}\n`;
|
|
159
|
+
testMessage += `Received content: ${this.utils.printReceived((0, snaps_utils_1.serialiseJsx)(content))}\n`;
|
|
160
|
+
}
|
|
161
|
+
if (footerLink) {
|
|
162
|
+
testMessage += `Received footer link: ${this.utils.printReceived(footerLink)}\n`;
|
|
163
|
+
}
|
|
164
|
+
return testMessage;
|
|
165
|
+
};
|
|
108
166
|
return { message, pass };
|
|
109
167
|
};
|
|
110
168
|
exports.toSendNotification = toSendNotification;
|
package/dist/matchers.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.cjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-invalid-this */\n\n// Note: Because this file imports from `@jest/globals`, it can only be used in\n// a Jest environment. This is why it's not exported from the index file.\n\nimport type { MatcherFunction } from '@jest/expect';\nimport { expect } from '@jest/globals';\nimport type {\n NotificationType,\n EnumToUnion,\n ComponentOrElement,\n Component,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport type { SnapResponse } from '@metamask/snaps-simulation';\nimport {\n InterfaceStruct,\n SnapResponseStruct,\n} from '@metamask/snaps-simulation';\nimport {\n getJsxElementFromComponent,\n serialiseJsx,\n} from '@metamask/snaps-utils';\nimport { is } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\nimport type { MatcherHintOptions } from 'jest-matcher-utils';\nimport {\n EXPECTED_COLOR,\n diff,\n matcherErrorMessage,\n matcherHint,\n printReceived,\n printWithType,\n RECEIVED_COLOR,\n} from 'jest-matcher-utils';\n\n/**\n * Ensure that the actual value is a response from the `request` function.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertActualIsSnapResponse(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is SnapResponse {\n if (!is(actual, SnapResponseStruct)) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR(\n 'received',\n )} value must be a response from the \\`request\\` function`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Ensure that the actual value is a response from the `request` function, and\n * that it has a `ui` property.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertHasInterface(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is { content: JSXElement } {\n if (!is(actual, InterfaceStruct) || !actual.content) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR('received')} value must have a \\`content\\` property`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Check if a JSON-RPC response matches the expected value. This matcher is\n * intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected response.\n * @returns The status and message.\n */\nexport const toRespondWith: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWith');\n\n const { response } = actual;\n if (hasProperty(response, 'error')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected response: ${this.utils.printExpected(expected)}\\n` +\n `Received error: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.result, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass };\n};\n\nexport const toRespondWithError: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWithError');\n\n const { response } = actual;\n if (hasProperty(response, 'result')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected error: ${this.utils.printExpected(expected)}\\n` +\n `Received result: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.error, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass };\n};\n\n/**\n * Check if the snap sent a notification with the expected message. This matcher\n * is intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected notification message.\n * @param type - The expected notification type.\n * @returns The status and message.\n */\nexport const toSendNotification: MatcherFunction<\n [expected: string, type?: EnumToUnion<NotificationType> | undefined]\n> = function (actual, expected, type) {\n assertActualIsSnapResponse(actual, 'toSendNotification');\n\n const { notifications } = actual;\n const pass = notifications.some(\n (notification) =>\n this.equals(notification.message, expected) &&\n (type === undefined || notification.type === type),\n );\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toSendNotification')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Expected type: ${this.utils.printExpected(type)}\\n` +\n `Received: ${this.utils.printReceived(notifications)}`\n : () =>\n `${this.utils.matcherHint('.toSendNotification')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Expected type: ${this.utils.printExpected(type)}\\n` +\n `Received: ${this.utils.printReceived(notifications)}`;\n\n return { message, pass };\n};\n\nconst toRenderLegacy: MatcherFunction<[expected: Component]> = function (\n actual,\n expected,\n) {\n assertHasInterface(actual, 'toRender');\n\n const { content } = actual;\n const expectedElement = getJsxElementFromComponent(expected);\n const pass = this.equals(content, expectedElement);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(expectedElement, content) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n};\n\nexport const toRender: MatcherFunction<[expected: ComponentOrElement]> =\n function (actual, expected) {\n assertHasInterface(actual, 'toRender');\n\n if (!isJSXElementUnsafe(expected)) {\n return toRenderLegacy.call(this, actual, expected);\n }\n\n const { content } = actual;\n const pass = this.equals(content, expected);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(\n serialiseJsx(expected),\n serialiseJsx(content),\n ) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n };\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"matchers.cjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-invalid-this */\n\n// Note: Because this file imports from `@jest/globals`, it can only be used in\n// a Jest environment. This is why it's not exported from the index file.\n\nimport type { MatcherFunction } from '@jest/expect';\nimport { expect } from '@jest/globals';\nimport type {\n EnumToUnion,\n ComponentOrElement,\n Component,\n NotificationType,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement, SnapNode } from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe, JSXElementStruct } from '@metamask/snaps-sdk/jsx';\nimport type { SnapResponse } from '@metamask/snaps-simulation';\nimport {\n InterfaceStruct,\n SnapResponseStruct,\n} from '@metamask/snaps-simulation';\nimport {\n getJsxElementFromComponent,\n serialiseJsx,\n} from '@metamask/snaps-utils';\nimport { is } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\nimport type { MatcherHintOptions } from 'jest-matcher-utils';\nimport {\n EXPECTED_COLOR,\n diff,\n matcherErrorMessage,\n matcherHint,\n printReceived,\n printWithType,\n RECEIVED_COLOR,\n} from 'jest-matcher-utils';\n\n/**\n * Ensure that the actual value is a response from the `request` function.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertActualIsSnapResponse(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is SnapResponse {\n if (!is(actual, SnapResponseStruct)) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR(\n 'received',\n )} value must be a response from the \\`request\\` function`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Ensure that the actual value is a response from the `request` function, and\n * that it has a `ui` property.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertHasInterface(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is { content: JSXElement } {\n if (!is(actual, InterfaceStruct) || !actual.content) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR('received')} value must have a \\`content\\` property`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Check if a JSON-RPC response matches the expected value. This matcher is\n * intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected response.\n * @returns The status and message.\n */\nexport const toRespondWith: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWith');\n\n const { response } = actual;\n if (hasProperty(response, 'error')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected response: ${this.utils.printExpected(expected)}\\n` +\n `Received error: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.result, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass };\n};\n\nexport const toRespondWithError: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWithError');\n\n const { response } = actual;\n if (hasProperty(response, 'result')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected error: ${this.utils.printExpected(expected)}\\n` +\n `Received result: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.error, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass };\n};\n\n/**\n * Check if the snap sent a notification with the expected message. This matcher\n * is intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expectedMessage - The expected notification message.\n * @param expectedType - The expected notification type.\n * @param expectedTitle - The expected notification title.\n * @param expectedContent - The expected notification JSX content.\n * @param expectedFooterLink - The expected footer link object.\n * @returns The status and message.\n */\nexport const toSendNotification: MatcherFunction<\n [\n expectedMessage: string,\n expectedType?: EnumToUnion<NotificationType> | undefined,\n expectedTitle?: string | undefined,\n expectedContent?: JSXElement | undefined,\n expectedFooterLink?: { text: string; href: string } | undefined,\n ]\n> = function (\n actual,\n expectedMessage,\n expectedType,\n expectedTitle,\n expectedContent,\n expectedFooterLink,\n) {\n assertActualIsSnapResponse(actual, 'toSendNotification');\n\n const { notifications } = actual;\n let jsxContent: JSXElement | undefined;\n\n if ('getInterface' in actual) {\n jsxContent = actual.getInterface().content;\n }\n\n const notificationValidator = (\n notification: SnapResponse['notifications'][number],\n ) => {\n const { type, message, title, footerLink } = notification as Record<\n string,\n unknown\n >;\n\n if (!this.equals(message, expectedMessage)) {\n return false;\n }\n\n if (expectedType && type !== expectedType) {\n return false;\n }\n\n if (title && !this.equals(title, expectedTitle)) {\n return false;\n }\n\n if (jsxContent && !this.equals(jsxContent, expectedContent)) {\n return false;\n }\n\n if (footerLink && !this.equals(footerLink, expectedFooterLink)) {\n return false;\n }\n\n return true;\n };\n\n const pass = notifications.some(notificationValidator);\n\n const transformedNotifications = notifications.map((notification) => {\n return {\n ...notification,\n // Ok to cast here as the function returns if the param is falsy\n content: serialiseJsx(jsxContent as SnapNode),\n };\n });\n\n const message = () => {\n let testMessage = pass\n ? `${this.utils.matcherHint('.not.toSendNotification')}\\n\\n`\n : `${this.utils.matcherHint('.toSendNotification')}\\n\\n`;\n\n const {\n title,\n type,\n message: notifMessage,\n footerLink,\n content,\n } = transformedNotifications[0];\n\n testMessage += `Expected message: ${this.utils.printExpected(\n expectedMessage,\n )}\\n`;\n\n if (expectedType) {\n testMessage += `Expected type: ${this.utils.printExpected(\n expectedType,\n )}\\n`;\n }\n\n if (title) {\n testMessage += `Expected title: ${this.utils.printExpected(\n expectedTitle,\n )}\\n`;\n\n // We want to check if the expected content is actually JSX content, otherwise `serialiseJsx` won't return something useful.\n if (is(expectedContent, JSXElementStruct)) {\n testMessage += `Expected content: ${this.utils.printExpected(\n serialiseJsx(expectedContent),\n )}\\n`;\n } else {\n testMessage += `Expected content: ${this.utils.printExpected(\n expectedContent,\n )}\\n`;\n }\n }\n\n if (footerLink) {\n testMessage += `Expected footer link: ${this.utils.printExpected(\n expectedFooterLink,\n )}\\n`;\n }\n\n testMessage += `Received message: ${this.utils.printExpected(\n notifMessage,\n )}\\n`;\n\n if (expectedType) {\n testMessage += `Received type: ${this.utils.printReceived(type)}\\n`;\n }\n\n if (title) {\n testMessage += `Received title: ${this.utils.printReceived(title)}\\n`;\n testMessage += `Received content: ${this.utils.printReceived(\n serialiseJsx(content),\n )}\\n`;\n }\n\n if (footerLink) {\n testMessage += `Received footer link: ${this.utils.printReceived(\n footerLink,\n )}\\n`;\n }\n\n return testMessage;\n };\n\n return { message, pass };\n};\n\nconst toRenderLegacy: MatcherFunction<[expected: Component]> = function (\n actual,\n expected,\n) {\n assertHasInterface(actual, 'toRender');\n\n const { content } = actual;\n const expectedElement = getJsxElementFromComponent(expected);\n const pass = this.equals(content, expectedElement);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(expectedElement, content) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n};\n\nexport const toRender: MatcherFunction<[expected: ComponentOrElement]> =\n function (actual, expected) {\n assertHasInterface(actual, 'toRender');\n\n if (!isJSXElementUnsafe(expected)) {\n return toRenderLegacy.call(this, actual, expected);\n }\n\n const { content } = actual;\n const pass = this.equals(content, expected);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(\n serialiseJsx(expected),\n serialiseJsx(content),\n ) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n };\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n});\n"]}
|
package/dist/matchers.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MatcherFunction } from "@jest/expect";
|
|
2
|
-
import type {
|
|
2
|
+
import type { EnumToUnion, ComponentOrElement, NotificationType } from "@metamask/snaps-sdk";
|
|
3
|
+
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
3
4
|
import type { Json } from "@metamask/utils";
|
|
4
5
|
/**
|
|
5
6
|
* Check if a JSON-RPC response matches the expected value. This matcher is
|
|
@@ -16,13 +17,22 @@ export declare const toRespondWithError: MatcherFunction<[expected: Json]>;
|
|
|
16
17
|
* is intended to be used with the `expect` global.
|
|
17
18
|
*
|
|
18
19
|
* @param actual - The actual response.
|
|
19
|
-
* @param
|
|
20
|
-
* @param
|
|
20
|
+
* @param expectedMessage - The expected notification message.
|
|
21
|
+
* @param expectedType - The expected notification type.
|
|
22
|
+
* @param expectedTitle - The expected notification title.
|
|
23
|
+
* @param expectedContent - The expected notification JSX content.
|
|
24
|
+
* @param expectedFooterLink - The expected footer link object.
|
|
21
25
|
* @returns The status and message.
|
|
22
26
|
*/
|
|
23
27
|
export declare const toSendNotification: MatcherFunction<[
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
expectedMessage: string,
|
|
29
|
+
expectedType?: EnumToUnion<NotificationType> | undefined,
|
|
30
|
+
expectedTitle?: string | undefined,
|
|
31
|
+
expectedContent?: JSXElement | undefined,
|
|
32
|
+
expectedFooterLink?: {
|
|
33
|
+
text: string;
|
|
34
|
+
href: string;
|
|
35
|
+
} | undefined
|
|
26
36
|
]>;
|
|
27
37
|
export declare const toRender: MatcherFunction<[expected: ComponentOrElement]>;
|
|
28
38
|
//# sourceMappingURL=matchers.d.cts.map
|
package/dist/matchers.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.d.cts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"matchers.d.cts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAElB,gBAAgB,EACjB,4BAA4B;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAY,gCAAgC;AAYpE,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AA8D5C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CA4B3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CA4BhE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C;IACE,eAAe,EAAE,MAAM;IACvB,YAAY,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,SAAS;IACxD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS;IAClC,eAAe,CAAC,EAAE,UAAU,GAAG,SAAS;IACxC,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;CAChE,CAkIF,CAAC;AAgCF,eAAO,MAAM,QAAQ,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAgClE,CAAC"}
|
package/dist/matchers.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MatcherFunction } from "@jest/expect";
|
|
2
|
-
import type {
|
|
2
|
+
import type { EnumToUnion, ComponentOrElement, NotificationType } from "@metamask/snaps-sdk";
|
|
3
|
+
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
3
4
|
import type { Json } from "@metamask/utils";
|
|
4
5
|
/**
|
|
5
6
|
* Check if a JSON-RPC response matches the expected value. This matcher is
|
|
@@ -16,13 +17,22 @@ export declare const toRespondWithError: MatcherFunction<[expected: Json]>;
|
|
|
16
17
|
* is intended to be used with the `expect` global.
|
|
17
18
|
*
|
|
18
19
|
* @param actual - The actual response.
|
|
19
|
-
* @param
|
|
20
|
-
* @param
|
|
20
|
+
* @param expectedMessage - The expected notification message.
|
|
21
|
+
* @param expectedType - The expected notification type.
|
|
22
|
+
* @param expectedTitle - The expected notification title.
|
|
23
|
+
* @param expectedContent - The expected notification JSX content.
|
|
24
|
+
* @param expectedFooterLink - The expected footer link object.
|
|
21
25
|
* @returns The status and message.
|
|
22
26
|
*/
|
|
23
27
|
export declare const toSendNotification: MatcherFunction<[
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
expectedMessage: string,
|
|
29
|
+
expectedType?: EnumToUnion<NotificationType> | undefined,
|
|
30
|
+
expectedTitle?: string | undefined,
|
|
31
|
+
expectedContent?: JSXElement | undefined,
|
|
32
|
+
expectedFooterLink?: {
|
|
33
|
+
text: string;
|
|
34
|
+
href: string;
|
|
35
|
+
} | undefined
|
|
26
36
|
]>;
|
|
27
37
|
export declare const toRender: MatcherFunction<[expected: ComponentOrElement]>;
|
|
28
38
|
//# sourceMappingURL=matchers.d.mts.map
|
package/dist/matchers.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.d.mts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"matchers.d.mts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAElB,gBAAgB,EACjB,4BAA4B;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAY,gCAAgC;AAYpE,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AA8D5C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CA4B3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CA4BhE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAC9C;IACE,eAAe,EAAE,MAAM;IACvB,YAAY,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,SAAS;IACxD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS;IAClC,eAAe,CAAC,EAAE,UAAU,GAAG,SAAS;IACxC,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;CAChE,CAkIF,CAAC;AAgCF,eAAO,MAAM,QAAQ,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAgClE,CAAC"}
|
package/dist/matchers.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-invalid-this */
|
|
2
2
|
import $jestglobals from "@jest/globals";
|
|
3
3
|
const { expect } = $jestglobals;
|
|
4
|
-
import { isJSXElementUnsafe } from "@metamask/snaps-sdk/jsx";
|
|
4
|
+
import { isJSXElementUnsafe, JSXElementStruct } from "@metamask/snaps-sdk/jsx";
|
|
5
5
|
import { InterfaceStruct, SnapResponseStruct } from "@metamask/snaps-simulation";
|
|
6
6
|
import { getJsxElementFromComponent, serialiseJsx } from "@metamask/snaps-utils";
|
|
7
7
|
import { is } from "@metamask/superstruct";
|
|
@@ -83,24 +83,82 @@ export const toRespondWithError = function (actual, expected) {
|
|
|
83
83
|
* is intended to be used with the `expect` global.
|
|
84
84
|
*
|
|
85
85
|
* @param actual - The actual response.
|
|
86
|
-
* @param
|
|
87
|
-
* @param
|
|
86
|
+
* @param expectedMessage - The expected notification message.
|
|
87
|
+
* @param expectedType - The expected notification type.
|
|
88
|
+
* @param expectedTitle - The expected notification title.
|
|
89
|
+
* @param expectedContent - The expected notification JSX content.
|
|
90
|
+
* @param expectedFooterLink - The expected footer link object.
|
|
88
91
|
* @returns The status and message.
|
|
89
92
|
*/
|
|
90
|
-
export const toSendNotification = function (actual,
|
|
93
|
+
export const toSendNotification = function (actual, expectedMessage, expectedType, expectedTitle, expectedContent, expectedFooterLink) {
|
|
91
94
|
assertActualIsSnapResponse(actual, 'toSendNotification');
|
|
92
95
|
const { notifications } = actual;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
let jsxContent;
|
|
97
|
+
if ('getInterface' in actual) {
|
|
98
|
+
jsxContent = actual.getInterface().content;
|
|
99
|
+
}
|
|
100
|
+
const notificationValidator = (notification) => {
|
|
101
|
+
const { type, message, title, footerLink } = notification;
|
|
102
|
+
if (!this.equals(message, expectedMessage)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (expectedType && type !== expectedType) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
if (title && !this.equals(title, expectedTitle)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (jsxContent && !this.equals(jsxContent, expectedContent)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (footerLink && !this.equals(footerLink, expectedFooterLink)) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
};
|
|
119
|
+
const pass = notifications.some(notificationValidator);
|
|
120
|
+
const transformedNotifications = notifications.map((notification) => {
|
|
121
|
+
return {
|
|
122
|
+
...notification,
|
|
123
|
+
// Ok to cast here as the function returns if the param is falsy
|
|
124
|
+
content: serialiseJsx(jsxContent),
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
const message = () => {
|
|
128
|
+
let testMessage = pass
|
|
129
|
+
? `${this.utils.matcherHint('.not.toSendNotification')}\n\n`
|
|
130
|
+
: `${this.utils.matcherHint('.toSendNotification')}\n\n`;
|
|
131
|
+
const { title, type, message: notifMessage, footerLink, content, } = transformedNotifications[0];
|
|
132
|
+
testMessage += `Expected message: ${this.utils.printExpected(expectedMessage)}\n`;
|
|
133
|
+
if (expectedType) {
|
|
134
|
+
testMessage += `Expected type: ${this.utils.printExpected(expectedType)}\n`;
|
|
135
|
+
}
|
|
136
|
+
if (title) {
|
|
137
|
+
testMessage += `Expected title: ${this.utils.printExpected(expectedTitle)}\n`;
|
|
138
|
+
// We want to check if the expected content is actually JSX content, otherwise `serialiseJsx` won't return something useful.
|
|
139
|
+
if (is(expectedContent, JSXElementStruct)) {
|
|
140
|
+
testMessage += `Expected content: ${this.utils.printExpected(serialiseJsx(expectedContent))}\n`;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
testMessage += `Expected content: ${this.utils.printExpected(expectedContent)}\n`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (footerLink) {
|
|
147
|
+
testMessage += `Expected footer link: ${this.utils.printExpected(expectedFooterLink)}\n`;
|
|
148
|
+
}
|
|
149
|
+
testMessage += `Received message: ${this.utils.printExpected(notifMessage)}\n`;
|
|
150
|
+
if (expectedType) {
|
|
151
|
+
testMessage += `Received type: ${this.utils.printReceived(type)}\n`;
|
|
152
|
+
}
|
|
153
|
+
if (title) {
|
|
154
|
+
testMessage += `Received title: ${this.utils.printReceived(title)}\n`;
|
|
155
|
+
testMessage += `Received content: ${this.utils.printReceived(serialiseJsx(content))}\n`;
|
|
156
|
+
}
|
|
157
|
+
if (footerLink) {
|
|
158
|
+
testMessage += `Received footer link: ${this.utils.printReceived(footerLink)}\n`;
|
|
159
|
+
}
|
|
160
|
+
return testMessage;
|
|
161
|
+
};
|
|
104
162
|
return { message, pass };
|
|
105
163
|
};
|
|
106
164
|
const toRenderLegacy = function (actual, expected) {
|
package/dist/matchers.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.mjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-invalid-this */\n\n// Note: Because this file imports from `@jest/globals`, it can only be used in\n// a Jest environment. This is why it's not exported from the index file.\n\nimport type { MatcherFunction } from '@jest/expect';\nimport { expect } from '@jest/globals';\nimport type {\n NotificationType,\n EnumToUnion,\n ComponentOrElement,\n Component,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport type { SnapResponse } from '@metamask/snaps-simulation';\nimport {\n InterfaceStruct,\n SnapResponseStruct,\n} from '@metamask/snaps-simulation';\nimport {\n getJsxElementFromComponent,\n serialiseJsx,\n} from '@metamask/snaps-utils';\nimport { is } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\nimport type { MatcherHintOptions } from 'jest-matcher-utils';\nimport {\n EXPECTED_COLOR,\n diff,\n matcherErrorMessage,\n matcherHint,\n printReceived,\n printWithType,\n RECEIVED_COLOR,\n} from 'jest-matcher-utils';\n\n/**\n * Ensure that the actual value is a response from the `request` function.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertActualIsSnapResponse(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is SnapResponse {\n if (!is(actual, SnapResponseStruct)) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR(\n 'received',\n )} value must be a response from the \\`request\\` function`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Ensure that the actual value is a response from the `request` function, and\n * that it has a `ui` property.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertHasInterface(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is { content: JSXElement } {\n if (!is(actual, InterfaceStruct) || !actual.content) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR('received')} value must have a \\`content\\` property`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Check if a JSON-RPC response matches the expected value. This matcher is\n * intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected response.\n * @returns The status and message.\n */\nexport const toRespondWith: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWith');\n\n const { response } = actual;\n if (hasProperty(response, 'error')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected response: ${this.utils.printExpected(expected)}\\n` +\n `Received error: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.result, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass };\n};\n\nexport const toRespondWithError: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWithError');\n\n const { response } = actual;\n if (hasProperty(response, 'result')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected error: ${this.utils.printExpected(expected)}\\n` +\n `Received result: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.error, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass };\n};\n\n/**\n * Check if the snap sent a notification with the expected message. This matcher\n * is intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected notification message.\n * @param type - The expected notification type.\n * @returns The status and message.\n */\nexport const toSendNotification: MatcherFunction<\n [expected: string, type?: EnumToUnion<NotificationType> | undefined]\n> = function (actual, expected, type) {\n assertActualIsSnapResponse(actual, 'toSendNotification');\n\n const { notifications } = actual;\n const pass = notifications.some(\n (notification) =>\n this.equals(notification.message, expected) &&\n (type === undefined || notification.type === type),\n );\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toSendNotification')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Expected type: ${this.utils.printExpected(type)}\\n` +\n `Received: ${this.utils.printReceived(notifications)}`\n : () =>\n `${this.utils.matcherHint('.toSendNotification')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Expected type: ${this.utils.printExpected(type)}\\n` +\n `Received: ${this.utils.printReceived(notifications)}`;\n\n return { message, pass };\n};\n\nconst toRenderLegacy: MatcherFunction<[expected: Component]> = function (\n actual,\n expected,\n) {\n assertHasInterface(actual, 'toRender');\n\n const { content } = actual;\n const expectedElement = getJsxElementFromComponent(expected);\n const pass = this.equals(content, expectedElement);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(expectedElement, content) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n};\n\nexport const toRender: MatcherFunction<[expected: ComponentOrElement]> =\n function (actual, expected) {\n assertHasInterface(actual, 'toRender');\n\n if (!isJSXElementUnsafe(expected)) {\n return toRenderLegacy.call(this, actual, expected);\n }\n\n const { content } = actual;\n const pass = this.equals(content, expected);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(\n serialiseJsx(expected),\n serialiseJsx(content),\n ) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n };\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"matchers.mjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-invalid-this */\n\n// Note: Because this file imports from `@jest/globals`, it can only be used in\n// a Jest environment. This is why it's not exported from the index file.\n\nimport type { MatcherFunction } from '@jest/expect';\nimport { expect } from '@jest/globals';\nimport type {\n EnumToUnion,\n ComponentOrElement,\n Component,\n NotificationType,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement, SnapNode } from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe, JSXElementStruct } from '@metamask/snaps-sdk/jsx';\nimport type { SnapResponse } from '@metamask/snaps-simulation';\nimport {\n InterfaceStruct,\n SnapResponseStruct,\n} from '@metamask/snaps-simulation';\nimport {\n getJsxElementFromComponent,\n serialiseJsx,\n} from '@metamask/snaps-utils';\nimport { is } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\nimport type { MatcherHintOptions } from 'jest-matcher-utils';\nimport {\n EXPECTED_COLOR,\n diff,\n matcherErrorMessage,\n matcherHint,\n printReceived,\n printWithType,\n RECEIVED_COLOR,\n} from 'jest-matcher-utils';\n\n/**\n * Ensure that the actual value is a response from the `request` function.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertActualIsSnapResponse(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is SnapResponse {\n if (!is(actual, SnapResponseStruct)) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR(\n 'received',\n )} value must be a response from the \\`request\\` function`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Ensure that the actual value is a response from the `request` function, and\n * that it has a `ui` property.\n *\n * @param actual - The actual value.\n * @param matcherName - The name of the matcher.\n * @param options - The matcher options.\n */\nfunction assertHasInterface(\n actual: unknown,\n matcherName: string,\n options?: MatcherHintOptions,\n): asserts actual is { content: JSXElement } {\n if (!is(actual, InterfaceStruct) || !actual.content) {\n throw new Error(\n matcherErrorMessage(\n matcherHint(matcherName, undefined, undefined, options),\n `${RECEIVED_COLOR('received')} value must have a \\`content\\` property`,\n printWithType('Received', actual, printReceived),\n ),\n );\n }\n}\n\n/**\n * Check if a JSON-RPC response matches the expected value. This matcher is\n * intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expected - The expected response.\n * @returns The status and message.\n */\nexport const toRespondWith: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWith');\n\n const { response } = actual;\n if (hasProperty(response, 'error')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected response: ${this.utils.printExpected(expected)}\\n` +\n `Received error: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.result, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWith')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass };\n};\n\nexport const toRespondWithError: MatcherFunction<[expected: Json]> = function (\n actual,\n expected,\n) {\n assertActualIsSnapResponse(actual, 'toRespondWithError');\n\n const { response } = actual;\n if (hasProperty(response, 'result')) {\n const message = () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected error: ${this.utils.printExpected(expected)}\\n` +\n `Received result: ${this.utils.printReceived(response.result)}`;\n\n return { message, pass: false };\n }\n\n const pass = this.equals(response.error, expected);\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`\n : () =>\n `${this.utils.matcherHint('.toRespondWithError')}\\n\\n` +\n `Expected: ${this.utils.printExpected(expected)}\\n` +\n `Received: ${this.utils.printReceived(response.error)}`;\n\n return { message, pass };\n};\n\n/**\n * Check if the snap sent a notification with the expected message. This matcher\n * is intended to be used with the `expect` global.\n *\n * @param actual - The actual response.\n * @param expectedMessage - The expected notification message.\n * @param expectedType - The expected notification type.\n * @param expectedTitle - The expected notification title.\n * @param expectedContent - The expected notification JSX content.\n * @param expectedFooterLink - The expected footer link object.\n * @returns The status and message.\n */\nexport const toSendNotification: MatcherFunction<\n [\n expectedMessage: string,\n expectedType?: EnumToUnion<NotificationType> | undefined,\n expectedTitle?: string | undefined,\n expectedContent?: JSXElement | undefined,\n expectedFooterLink?: { text: string; href: string } | undefined,\n ]\n> = function (\n actual,\n expectedMessage,\n expectedType,\n expectedTitle,\n expectedContent,\n expectedFooterLink,\n) {\n assertActualIsSnapResponse(actual, 'toSendNotification');\n\n const { notifications } = actual;\n let jsxContent: JSXElement | undefined;\n\n if ('getInterface' in actual) {\n jsxContent = actual.getInterface().content;\n }\n\n const notificationValidator = (\n notification: SnapResponse['notifications'][number],\n ) => {\n const { type, message, title, footerLink } = notification as Record<\n string,\n unknown\n >;\n\n if (!this.equals(message, expectedMessage)) {\n return false;\n }\n\n if (expectedType && type !== expectedType) {\n return false;\n }\n\n if (title && !this.equals(title, expectedTitle)) {\n return false;\n }\n\n if (jsxContent && !this.equals(jsxContent, expectedContent)) {\n return false;\n }\n\n if (footerLink && !this.equals(footerLink, expectedFooterLink)) {\n return false;\n }\n\n return true;\n };\n\n const pass = notifications.some(notificationValidator);\n\n const transformedNotifications = notifications.map((notification) => {\n return {\n ...notification,\n // Ok to cast here as the function returns if the param is falsy\n content: serialiseJsx(jsxContent as SnapNode),\n };\n });\n\n const message = () => {\n let testMessage = pass\n ? `${this.utils.matcherHint('.not.toSendNotification')}\\n\\n`\n : `${this.utils.matcherHint('.toSendNotification')}\\n\\n`;\n\n const {\n title,\n type,\n message: notifMessage,\n footerLink,\n content,\n } = transformedNotifications[0];\n\n testMessage += `Expected message: ${this.utils.printExpected(\n expectedMessage,\n )}\\n`;\n\n if (expectedType) {\n testMessage += `Expected type: ${this.utils.printExpected(\n expectedType,\n )}\\n`;\n }\n\n if (title) {\n testMessage += `Expected title: ${this.utils.printExpected(\n expectedTitle,\n )}\\n`;\n\n // We want to check if the expected content is actually JSX content, otherwise `serialiseJsx` won't return something useful.\n if (is(expectedContent, JSXElementStruct)) {\n testMessage += `Expected content: ${this.utils.printExpected(\n serialiseJsx(expectedContent),\n )}\\n`;\n } else {\n testMessage += `Expected content: ${this.utils.printExpected(\n expectedContent,\n )}\\n`;\n }\n }\n\n if (footerLink) {\n testMessage += `Expected footer link: ${this.utils.printExpected(\n expectedFooterLink,\n )}\\n`;\n }\n\n testMessage += `Received message: ${this.utils.printExpected(\n notifMessage,\n )}\\n`;\n\n if (expectedType) {\n testMessage += `Received type: ${this.utils.printReceived(type)}\\n`;\n }\n\n if (title) {\n testMessage += `Received title: ${this.utils.printReceived(title)}\\n`;\n testMessage += `Received content: ${this.utils.printReceived(\n serialiseJsx(content),\n )}\\n`;\n }\n\n if (footerLink) {\n testMessage += `Received footer link: ${this.utils.printReceived(\n footerLink,\n )}\\n`;\n }\n\n return testMessage;\n };\n\n return { message, pass };\n};\n\nconst toRenderLegacy: MatcherFunction<[expected: Component]> = function (\n actual,\n expected,\n) {\n assertHasInterface(actual, 'toRender');\n\n const { content } = actual;\n const expectedElement = getJsxElementFromComponent(expected);\n const pass = this.equals(content, expectedElement);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(expectedElement, content) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${this.utils.printExpected(expectedElement)}\\n\\n` +\n `Received:\\n${this.utils.printReceived(content)}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n};\n\nexport const toRender: MatcherFunction<[expected: ComponentOrElement]> =\n function (actual, expected) {\n assertHasInterface(actual, 'toRender');\n\n if (!isJSXElementUnsafe(expected)) {\n return toRenderLegacy.call(this, actual, expected);\n }\n\n const { content } = actual;\n const pass = this.equals(content, expected);\n\n // This is typed as `string | null`, but in practice it's always a string.\n // The function only returns `null` if both the expected and actual values\n // are numbers, bigints, or booleans, which is never the case here.\n const difference = diff(\n serialiseJsx(expected),\n serialiseJsx(content),\n ) as string;\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`\n : () =>\n `${this.utils.matcherHint('.toRender')}\\n\\n` +\n `Expected:\\n${EXPECTED_COLOR(serialiseJsx(expected))}\\n\\n` +\n `Received:\\n${RECEIVED_COLOR(serialiseJsx(content))}` +\n `\\n\\nDifference:\\n\\n${difference}`;\n\n return { message, pass };\n };\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-jest",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.11.0",
|
|
4
4
|
"description": "A Jest preset for end-to-end testing MetaMask Snaps, including a Jest environment, and a set of Jest matchers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"@jest/environment": "^29.5.0",
|
|
61
61
|
"@jest/expect": "^29.5.0",
|
|
62
62
|
"@jest/globals": "^29.5.0",
|
|
63
|
-
"@metamask/snaps-controllers": "^9.
|
|
64
|
-
"@metamask/snaps-sdk": "^6.
|
|
65
|
-
"@metamask/snaps-simulation": "^1.
|
|
63
|
+
"@metamask/snaps-controllers": "^9.17.0",
|
|
64
|
+
"@metamask/snaps-sdk": "^6.15.0",
|
|
65
|
+
"@metamask/snaps-simulation": "^2.1.0",
|
|
66
66
|
"@metamask/superstruct": "^3.1.0",
|
|
67
|
-
"@metamask/utils": "^
|
|
67
|
+
"@metamask/utils": "^11.0.1",
|
|
68
68
|
"express": "^4.18.2",
|
|
69
69
|
"jest-environment-node": "^29.5.0",
|
|
70
70
|
"jest-matcher-utils": "^29.5.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@metamask/eslint-config-jest": "^12.1.0",
|
|
79
79
|
"@metamask/eslint-config-nodejs": "^12.1.0",
|
|
80
80
|
"@metamask/eslint-config-typescript": "^12.1.0",
|
|
81
|
-
"@metamask/snaps-utils": "^8.
|
|
81
|
+
"@metamask/snaps-utils": "^8.8.0",
|
|
82
82
|
"@swc/core": "1.3.78",
|
|
83
83
|
"@swc/jest": "^0.2.26",
|
|
84
84
|
"@ts-bridge/cli": "^0.6.1",
|