@metamask/snaps-jest 9.2.0 → 9.4.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 CHANGED
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [9.4.0]
11
+
12
+ ### Added
13
+
14
+ - Add support for `snap_startTrace` and `snap_endTrace` ([#3547](https://github.com/MetaMask/snaps/pull/3547))
15
+ - Add support for `snap_trackError` ([#3546](https://github.com/MetaMask/snaps/pull/3546))
16
+ - Add support for `snap_trackEvent` ([#3546](https://github.com/MetaMask/snaps/pull/3546))
17
+
18
+ ## [9.3.0]
19
+
20
+ ### Added
21
+
22
+ - Add Snap metadata to simulated accounts ([#3528](https://github.com/MetaMask/snaps/pull/3528))
23
+
10
24
  ## [9.2.0]
11
25
 
12
26
  ### Added
@@ -397,7 +411,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
397
411
  - The version of the package no longer needs to match the version of all other
398
412
  MetaMask Snaps packages.
399
413
 
400
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.2.0...HEAD
414
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.4.0...HEAD
415
+ [9.4.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.3.0...@metamask/snaps-jest@9.4.0
416
+ [9.3.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.2.0...@metamask/snaps-jest@9.3.0
401
417
  [9.2.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.1.0...@metamask/snaps-jest@9.2.0
402
418
  [9.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@9.0.0...@metamask/snaps-jest@9.1.0
403
419
  [9.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-jest@8.16.0...@metamask/snaps-jest@9.0.0
@@ -1 +1 @@
1
- {"version":3,"file":"global.cjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":";AAAA,sNAAsN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-object-type, @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 * @param footerLink.text - The text of the footer link.\n * @param footerLink.href - The href of the footer link.\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"]}
1
+ {"version":3,"file":"global.cjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":";AAAA,sNAAsN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-object-type, @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 * @param footerLink.text - The text of the footer link.\n * @param footerLink.href - The href of the footer link.\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 * Assert that the Snap tracked an error with the expected parameters. This\n * is equivalent to calling\n * `expect(response.tracked.errors).toContainEqual(error)`.\n *\n * @param error - The expected error parameters.\n * @throws If the snap did not track an error with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrackError({\n * name: 'Error',\n * message: 'This is an error.',\n * });\n */\n toTrackError(error?: unknown): void;\n\n /**\n * Assert that the Snap tracked an event with the expected parameters. This\n * is equivalent to calling\n * `expect(response.tracked.events).toContainEqual(event)`.\n *\n * @param event - The expected event parameters.\n * @throws If the snap did not track an event with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrackEvent({\n * event: 'bar',\n * properties: { baz: 'qux' },\n * sensitiveProperties: { quux: 'corge' },\n * });\n */\n toTrackEvent(event?: unknown): void;\n\n /**\n * Assert that the Snap started and ended a trace with the expected\n * parameters. This is equivalent to calling\n * `expect(response.tracked.traces).toContainEqual(span)`.\n *\n * @param trace - The expected trace parameters.\n * @throws If the snap did not end a trace with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrace({\n * name: 'My Trace',\n * });\n */\n toTrace(trace?: unknown): 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
@@ -61,6 +61,51 @@ interface SnapsMatchers {
61
61
  * expect(ui).toRender(panel([heading('Hello, world!')]));
62
62
  */
63
63
  toRender(component: ComponentOrElement): void;
64
+ /**
65
+ * Assert that the Snap tracked an error with the expected parameters. This
66
+ * is equivalent to calling
67
+ * `expect(response.tracked.errors).toContainEqual(error)`.
68
+ *
69
+ * @param error - The expected error parameters.
70
+ * @throws If the snap did not track an error with the expected parameters.
71
+ * @example
72
+ * const response = await request({ method: 'foo' });
73
+ * expect(response).toTrackError({
74
+ * name: 'Error',
75
+ * message: 'This is an error.',
76
+ * });
77
+ */
78
+ toTrackError(error?: unknown): void;
79
+ /**
80
+ * Assert that the Snap tracked an event with the expected parameters. This
81
+ * is equivalent to calling
82
+ * `expect(response.tracked.events).toContainEqual(event)`.
83
+ *
84
+ * @param event - The expected event parameters.
85
+ * @throws If the snap did not track an event with the expected parameters.
86
+ * @example
87
+ * const response = await request({ method: 'foo' });
88
+ * expect(response).toTrackEvent({
89
+ * event: 'bar',
90
+ * properties: { baz: 'qux' },
91
+ * sensitiveProperties: { quux: 'corge' },
92
+ * });
93
+ */
94
+ toTrackEvent(event?: unknown): void;
95
+ /**
96
+ * Assert that the Snap started and ended a trace with the expected
97
+ * parameters. This is equivalent to calling
98
+ * `expect(response.tracked.traces).toContainEqual(span)`.
99
+ *
100
+ * @param trace - The expected trace parameters.
101
+ * @throws If the snap did not end a trace with the expected parameters.
102
+ * @example
103
+ * const response = await request({ method: 'foo' });
104
+ * expect(response).toTrace({
105
+ * name: 'My Trace',
106
+ * });
107
+ */
108
+ toTrace(trace?: unknown): void;
64
109
  }
65
110
  declare module 'expect' {
66
111
  interface AsymmetricMatchers extends SnapsMatchers {
@@ -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;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;;;;;;;;;;;;;;;;OAgBG;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"}
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;;;;;;;;;;;;;;;;OAgBG;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;IAE9C;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;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
@@ -61,6 +61,51 @@ interface SnapsMatchers {
61
61
  * expect(ui).toRender(panel([heading('Hello, world!')]));
62
62
  */
63
63
  toRender(component: ComponentOrElement): void;
64
+ /**
65
+ * Assert that the Snap tracked an error with the expected parameters. This
66
+ * is equivalent to calling
67
+ * `expect(response.tracked.errors).toContainEqual(error)`.
68
+ *
69
+ * @param error - The expected error parameters.
70
+ * @throws If the snap did not track an error with the expected parameters.
71
+ * @example
72
+ * const response = await request({ method: 'foo' });
73
+ * expect(response).toTrackError({
74
+ * name: 'Error',
75
+ * message: 'This is an error.',
76
+ * });
77
+ */
78
+ toTrackError(error?: unknown): void;
79
+ /**
80
+ * Assert that the Snap tracked an event with the expected parameters. This
81
+ * is equivalent to calling
82
+ * `expect(response.tracked.events).toContainEqual(event)`.
83
+ *
84
+ * @param event - The expected event parameters.
85
+ * @throws If the snap did not track an event with the expected parameters.
86
+ * @example
87
+ * const response = await request({ method: 'foo' });
88
+ * expect(response).toTrackEvent({
89
+ * event: 'bar',
90
+ * properties: { baz: 'qux' },
91
+ * sensitiveProperties: { quux: 'corge' },
92
+ * });
93
+ */
94
+ toTrackEvent(event?: unknown): void;
95
+ /**
96
+ * Assert that the Snap started and ended a trace with the expected
97
+ * parameters. This is equivalent to calling
98
+ * `expect(response.tracked.traces).toContainEqual(span)`.
99
+ *
100
+ * @param trace - The expected trace parameters.
101
+ * @throws If the snap did not end a trace with the expected parameters.
102
+ * @example
103
+ * const response = await request({ method: 'foo' });
104
+ * expect(response).toTrace({
105
+ * name: 'My Trace',
106
+ * });
107
+ */
108
+ toTrace(trace?: unknown): void;
64
109
  }
65
110
  declare module 'expect' {
66
111
  interface AsymmetricMatchers extends SnapsMatchers {
@@ -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;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;;;;;;;;;;;;;;;;OAgBG;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"}
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;;;;;;;;;;;;;;;;OAgBG;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;IAE9C;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;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"}
@@ -1 +1 @@
1
- {"version":3,"file":"global.mjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,sNAAsN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-object-type, @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 * @param footerLink.text - The text of the footer link.\n * @param footerLink.href - The href of the footer link.\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"]}
1
+ {"version":3,"file":"global.mjs","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,sNAAsN","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-empty-object-type, @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 * @param footerLink.text - The text of the footer link.\n * @param footerLink.href - The href of the footer link.\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 * Assert that the Snap tracked an error with the expected parameters. This\n * is equivalent to calling\n * `expect(response.tracked.errors).toContainEqual(error)`.\n *\n * @param error - The expected error parameters.\n * @throws If the snap did not track an error with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrackError({\n * name: 'Error',\n * message: 'This is an error.',\n * });\n */\n toTrackError(error?: unknown): void;\n\n /**\n * Assert that the Snap tracked an event with the expected parameters. This\n * is equivalent to calling\n * `expect(response.tracked.events).toContainEqual(event)`.\n *\n * @param event - The expected event parameters.\n * @throws If the snap did not track an event with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrackEvent({\n * event: 'bar',\n * properties: { baz: 'qux' },\n * sensitiveProperties: { quux: 'corge' },\n * });\n */\n toTrackEvent(event?: unknown): void;\n\n /**\n * Assert that the Snap started and ended a trace with the expected\n * parameters. This is equivalent to calling\n * `expect(response.tracked.traces).toContainEqual(span)`.\n *\n * @param trace - The expected trace parameters.\n * @throws If the snap did not end a trace with the expected parameters.\n * @example\n * const response = await request({ method: 'foo' });\n * expect(response).toTrace({\n * name: 'My Trace',\n * });\n */\n toTrace(trace?: unknown): 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
@@ -131,16 +131,18 @@ const getPseudoRandomUuid = (0, internals_1.getPseudoRandomUuidGenerator)();
131
131
  * @param options.assets - The assets associated with the account, in CAIP
132
132
  * format. If not provided, it will default to an empty array.
133
133
  * @param options.selected - Whether the account is selected by default.
134
+ * @param options.owned - Whether the account is owned by the snap.
134
135
  * @param options.id - The ID of the account. If not provided, a pseudo-random
135
136
  * UUID will be generated.
136
137
  * @returns A mock account object with the specified properties.
137
138
  */
138
- function getMockAccount({ address, assets = [], selected = false, id = getPseudoRandomUuid(), scopes = (0, internals_1.getScopesFromAssets)(assets), }) {
139
+ function getMockAccount({ address, assets = [], selected = false, owned = false, id = getPseudoRandomUuid(), scopes = (0, internals_1.getScopesFromAssets)(assets), }) {
139
140
  return {
140
141
  address,
141
142
  id,
142
143
  scopes,
143
144
  selected,
145
+ owned,
144
146
  assets,
145
147
  };
146
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AAYA,uDAAgD;AAChD,2CAA6D;AAO7D,qDAKqB;AAErB,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;IAEpD,wEAAwE;IACxE,WAAW;IACX,sDAAsD;IACtD,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,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,KAAK,GACN,GAAG,MAAM,IAAA,0BAAc,GAAE,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC,CAAC;IAC3D,qDAAqD;IAErD,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,OAAO;QACP,YAAY;QACZ,iBAAiB;QACjB,eAAe;QACf,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;AA9DD,kCA8DC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CACjC,OAA0B;IAE1B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACpC,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,EAAE,CAAoB;QAC1E,SAAS,EAAE,OAAO,CAAC,EAAE;KACtB,CAAC;AACJ,CAAC;AARD,kDAQC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAC/B,EAAiB,EACjB,MAA8C;IAE9C,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAEzB,IAAA,cAAM,EAAC,KAAK,EAAE,kBAAkB,EAAE,mCAAmC,CAAC,CAAC;IAEvE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAE/B,OAAO;QACL,KAAK,EAAE,EAAE;QACT,MAAM;QACN,IAAI;KACL,CAAC;AACJ,CAAC;AAfD,8CAeC;AAED;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,IAAA,wCAA4B,GAAE,CAAC;AAgE3D;;;;;;;;;;;;;GAaG;AACH,SAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,MAAM,GAAG,EAAE,EACX,QAAQ,GAAG,KAAK,EAChB,EAAE,GAAG,mBAAmB,EAAE,EAC1B,MAAM,GAAG,IAAA,+BAAmB,EAAC,MAAM,CAAC,GACd;IACtB,OAAO;QACL,OAAO;QACP,EAAE;QACF,MAAM;QACN,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC;AAdD,wCAcC","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type {\n AccountSelectorState,\n AssetSelectorState,\n SnapId,\n} from '@metamask/snaps-sdk';\nimport type {\n InstallSnapOptions,\n SimulationAccount,\n SimulationAsset,\n Snap,\n} from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n} from '@metamask/utils';\n\nimport {\n rootLogger,\n getEnvironment,\n getPseudoRandomUuidGenerator,\n getScopesFromAssets,\n} 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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n /* eslint-disable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n /* eslint-enable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\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\n/**\n * Get the state of an AccountSelector based on a {@link SimulationAccount}.\n *\n * @param account - The {@link SimulationAccount} to get the state from.\n * @returns The state of the AccountSelector.\n */\nexport function getStateFromAccount(\n account: SimulationAccount,\n): AccountSelectorState {\n const { address, scopes } = account;\n return {\n addresses: scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[],\n accountId: account.id,\n };\n}\n\n/**\n * Get the state of an AssetSelector based on a {@link SimulationAsset}.\n *\n * @param id - The Asset id as a CAIP-19 asset type.\n * @param assets - The {@link SimulationAsset} to get the state from.\n * @returns The state of the AssetSelector.\n */\nexport function getStateFromAsset(\n id: CaipAssetType,\n assets: Record<CaipAssetType, SimulationAsset>,\n): AssetSelectorState {\n const asset = assets[id];\n\n assert(asset, `Asset with ID \"${id}\" not found in simulation assets.`);\n\n const { symbol, name } = asset;\n\n return {\n asset: id,\n symbol,\n name,\n };\n}\n\n/**\n * Generate a pseudo-random UUID.\n *\n * @returns A pseudo-random UUID string.\n */\nconst getPseudoRandomUuid = getPseudoRandomUuidGenerator();\n\n/**\n * The base options for the {@link getMockAccount} function.\n */\nexport type BaseMockAccountOptions = {\n /**\n * The address of the account.\n */\n address: string;\n\n /**\n * The ID of the account. If not provided, a pseudo-random UUID will be\n * generated.\n */\n id?: string;\n\n /**\n * Whether the account is selected by default.\n */\n selected?: boolean;\n};\n\n/**\n * Options for creating a mock account with assets or scopes. If `scopes` are\n * not provided, they will be derived from the `assets`.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithAssets = BaseMockAccountOptions & {\n /**\n * The assets associated with the account. These should be in CAIP format.\n */\n assets: CaipAssetType[];\n\n /**\n * The scopes associated with the account. If not provided, they will be\n * derived from the `assets`.\n */\n scopes?: CaipChainId[];\n};\n\n/**\n * Options for creating a mock account with scopes, and optionally assets.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithScopes = BaseMockAccountOptions & {\n /**\n * The scopes associated with the account. These should be in CAIP format.\n */\n scopes: CaipChainId[];\n\n /**\n * The assets associated with the account. If not provided, it will default\n * to an empty array.\n */\n assets?: CaipAssetType[];\n};\n\nexport type GetMockAccountOptions =\n | MockAccountOptionsWithAssets\n | MockAccountOptionsWithScopes;\n\n/**\n * Get a mock account object for testing purposes.\n *\n * @param options - The options for creating the mock account.\n * @param options.address - The address of the account.\n * @param options.scopes - The scopes associated with the account, in CAIP\n * format. If not provided, they will be derived from the `assets`.\n * @param options.assets - The assets associated with the account, in CAIP\n * format. If not provided, it will default to an empty array.\n * @param options.selected - Whether the account is selected by default.\n * @param options.id - The ID of the account. If not provided, a pseudo-random\n * UUID will be generated.\n * @returns A mock account object with the specified properties.\n */\nexport function getMockAccount({\n address,\n assets = [],\n selected = false,\n id = getPseudoRandomUuid(),\n scopes = getScopesFromAssets(assets),\n}: GetMockAccountOptions): SimulationAccount {\n return {\n address,\n id,\n scopes,\n selected,\n assets,\n };\n}\n"]}
1
+ {"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type {\n AccountSelectorState,\n AssetSelectorState,\n SnapId,\n} from '@metamask/snaps-sdk';\nimport type {\n InstallSnapOptions,\n SimulationAccount,\n SimulationAsset,\n Snap,\n} from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n} from '@metamask/utils';\n\nimport {\n rootLogger,\n getEnvironment,\n getPseudoRandomUuidGenerator,\n getScopesFromAssets,\n} 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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n /* eslint-disable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n /* eslint-enable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\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\n/**\n * Get the state of an AccountSelector based on a {@link SimulationAccount}.\n *\n * @param account - The {@link SimulationAccount} to get the state from.\n * @returns The state of the AccountSelector.\n */\nexport function getStateFromAccount(\n account: SimulationAccount,\n): AccountSelectorState {\n const { address, scopes } = account;\n return {\n addresses: scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[],\n accountId: account.id,\n };\n}\n\n/**\n * Get the state of an AssetSelector based on a {@link SimulationAsset}.\n *\n * @param id - The Asset id as a CAIP-19 asset type.\n * @param assets - The {@link SimulationAsset} to get the state from.\n * @returns The state of the AssetSelector.\n */\nexport function getStateFromAsset(\n id: CaipAssetType,\n assets: Record<CaipAssetType, SimulationAsset>,\n): AssetSelectorState {\n const asset = assets[id];\n\n assert(asset, `Asset with ID \"${id}\" not found in simulation assets.`);\n\n const { symbol, name } = asset;\n\n return {\n asset: id,\n symbol,\n name,\n };\n}\n\n/**\n * Generate a pseudo-random UUID.\n *\n * @returns A pseudo-random UUID string.\n */\nconst getPseudoRandomUuid = getPseudoRandomUuidGenerator();\n\n/**\n * The base options for the {@link getMockAccount} function.\n */\nexport type BaseMockAccountOptions = {\n /**\n * The address of the account.\n */\n address: string;\n\n /**\n * The ID of the account. If not provided, a pseudo-random UUID will be\n * generated.\n */\n id?: string;\n\n /**\n * Whether the account is selected by default.\n */\n selected?: boolean;\n\n /**\n * Whether the account is owned by the snap.\n */\n owned?: boolean;\n};\n\n/**\n * Options for creating a mock account with assets or scopes. If `scopes` are\n * not provided, they will be derived from the `assets`.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithAssets = BaseMockAccountOptions & {\n /**\n * The assets associated with the account. These should be in CAIP format.\n */\n assets: CaipAssetType[];\n\n /**\n * The scopes associated with the account. If not provided, they will be\n * derived from the `assets`.\n */\n scopes?: CaipChainId[];\n};\n\n/**\n * Options for creating a mock account with scopes, and optionally assets.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithScopes = BaseMockAccountOptions & {\n /**\n * The scopes associated with the account. These should be in CAIP format.\n */\n scopes: CaipChainId[];\n\n /**\n * The assets associated with the account. If not provided, it will default\n * to an empty array.\n */\n assets?: CaipAssetType[];\n};\n\nexport type GetMockAccountOptions =\n | MockAccountOptionsWithAssets\n | MockAccountOptionsWithScopes;\n\n/**\n * Get a mock account object for testing purposes.\n *\n * @param options - The options for creating the mock account.\n * @param options.address - The address of the account.\n * @param options.scopes - The scopes associated with the account, in CAIP\n * format. If not provided, they will be derived from the `assets`.\n * @param options.assets - The assets associated with the account, in CAIP\n * format. If not provided, it will default to an empty array.\n * @param options.selected - Whether the account is selected by default.\n * @param options.owned - Whether the account is owned by the snap.\n * @param options.id - The ID of the account. If not provided, a pseudo-random\n * UUID will be generated.\n * @returns A mock account object with the specified properties.\n */\nexport function getMockAccount({\n address,\n assets = [],\n selected = false,\n owned = false,\n id = getPseudoRandomUuid(),\n scopes = getScopesFromAssets(assets),\n}: GetMockAccountOptions): SimulationAccount {\n return {\n address,\n id,\n scopes,\n selected,\n owned,\n assets,\n };\n}\n"]}
@@ -119,6 +119,10 @@ export type BaseMockAccountOptions = {
119
119
  * Whether the account is selected by default.
120
120
  */
121
121
  selected?: boolean;
122
+ /**
123
+ * Whether the account is owned by the snap.
124
+ */
125
+ owned?: boolean;
122
126
  };
123
127
  /**
124
128
  * Options for creating a mock account with assets or scopes. If `scopes` are
@@ -164,9 +168,10 @@ export type GetMockAccountOptions = MockAccountOptionsWithAssets | MockAccountOp
164
168
  * @param options.assets - The assets associated with the account, in CAIP
165
169
  * format. If not provided, it will default to an empty array.
166
170
  * @param options.selected - Whether the account is selected by default.
171
+ * @param options.owned - Whether the account is owned by the snap.
167
172
  * @param options.id - The ID of the account. If not provided, a pseudo-random
168
173
  * UUID will be generated.
169
174
  * @returns A mock account object with the specified properties.
170
175
  */
171
- export declare function getMockAccount({ address, assets, selected, id, scopes, }: GetMockAccountOptions): SimulationAccount;
176
+ export declare function getMockAccount({ address, assets, selected, owned, id, scopes, }: GetMockAccountOptions): SimulationAccount;
172
177
  //# sourceMappingURL=helpers.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,oCAAoC;AAC5E,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,EACP,4BAA4B;AAC7B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,IAAI,EACL,mCAAmC;AAGpC,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACZ,wBAAwB;AAiCzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAClD,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAElD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;AAkGjB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,oBAAoB,CAMtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,GAC7C,kBAAkB,CAYpB;AASD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,MAAW,EACX,QAAgB,EAChB,EAA0B,EAC1B,MAAoC,GACrC,EAAE,qBAAqB,GAAG,iBAAiB,CAQ3C"}
1
+ {"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,oCAAoC;AAC5E,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,EACP,4BAA4B;AAC7B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,IAAI,EACL,mCAAmC;AAGpC,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACZ,wBAAwB;AAiCzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAClD,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAElD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;AAkGjB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,oBAAoB,CAMtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,GAC7C,kBAAkB,CAYpB;AASD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,MAAW,EACX,QAAgB,EAChB,KAAa,EACb,EAA0B,EAC1B,MAAoC,GACrC,EAAE,qBAAqB,GAAG,iBAAiB,CAS3C"}
@@ -119,6 +119,10 @@ export type BaseMockAccountOptions = {
119
119
  * Whether the account is selected by default.
120
120
  */
121
121
  selected?: boolean;
122
+ /**
123
+ * Whether the account is owned by the snap.
124
+ */
125
+ owned?: boolean;
122
126
  };
123
127
  /**
124
128
  * Options for creating a mock account with assets or scopes. If `scopes` are
@@ -164,9 +168,10 @@ export type GetMockAccountOptions = MockAccountOptionsWithAssets | MockAccountOp
164
168
  * @param options.assets - The assets associated with the account, in CAIP
165
169
  * format. If not provided, it will default to an empty array.
166
170
  * @param options.selected - Whether the account is selected by default.
171
+ * @param options.owned - Whether the account is owned by the snap.
167
172
  * @param options.id - The ID of the account. If not provided, a pseudo-random
168
173
  * UUID will be generated.
169
174
  * @returns A mock account object with the specified properties.
170
175
  */
171
- export declare function getMockAccount({ address, assets, selected, id, scopes, }: GetMockAccountOptions): SimulationAccount;
176
+ export declare function getMockAccount({ address, assets, selected, owned, id, scopes, }: GetMockAccountOptions): SimulationAccount;
172
177
  //# sourceMappingURL=helpers.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.mts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,oCAAoC;AAC5E,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,EACP,4BAA4B;AAC7B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,IAAI,EACL,mCAAmC;AAGpC,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACZ,wBAAwB;AAiCzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAClD,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAElD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;AAkGjB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,oBAAoB,CAMtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,GAC7C,kBAAkB,CAYpB;AASD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,MAAW,EACX,QAAgB,EAChB,EAA0B,EAC1B,MAAoC,GACrC,EAAE,qBAAqB,GAAG,iBAAiB,CAQ3C"}
1
+ {"version":3,"file":"helpers.d.mts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,oCAAoC;AAC5E,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,EACP,4BAA4B;AAC7B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,IAAI,EACL,mCAAmC;AAGpC,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACZ,wBAAwB;AAiCzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAClD,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,WAAW,CAC/B,OAAO,SAAS,KACd,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,YAAY,CAAC,OAAO,wBAAwB,CAAC,EAElD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;AAkGjB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,oBAAoB,CAMtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,GAC7C,kBAAkB,CAYpB;AASD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG;IAClE;;OAEG;IACH,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,MAAW,EACX,QAAgB,EAChB,KAAa,EACb,EAA0B,EAC1B,MAAoC,GACrC,EAAE,qBAAqB,GAAG,iBAAiB,CAS3C"}
package/dist/helpers.mjs CHANGED
@@ -125,16 +125,18 @@ const getPseudoRandomUuid = getPseudoRandomUuidGenerator();
125
125
  * @param options.assets - The assets associated with the account, in CAIP
126
126
  * format. If not provided, it will default to an empty array.
127
127
  * @param options.selected - Whether the account is selected by default.
128
+ * @param options.owned - Whether the account is owned by the snap.
128
129
  * @param options.id - The ID of the account. If not provided, a pseudo-random
129
130
  * UUID will be generated.
130
131
  * @returns A mock account object with the specified properties.
131
132
  */
132
- export function getMockAccount({ address, assets = [], selected = false, id = getPseudoRandomUuid(), scopes = getScopesFromAssets(assets), }) {
133
+ export function getMockAccount({ address, assets = [], selected = false, owned = false, id = getPseudoRandomUuid(), scopes = getScopesFromAssets(assets), }) {
133
134
  return {
134
135
  address,
135
136
  id,
136
137
  scopes,
137
138
  selected,
139
+ owned,
138
140
  assets,
139
141
  };
140
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type {\n AccountSelectorState,\n AssetSelectorState,\n SnapId,\n} from '@metamask/snaps-sdk';\nimport type {\n InstallSnapOptions,\n SimulationAccount,\n SimulationAsset,\n Snap,\n} from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n} from '@metamask/utils';\n\nimport {\n rootLogger,\n getEnvironment,\n getPseudoRandomUuidGenerator,\n getScopesFromAssets,\n} 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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n /* eslint-disable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n /* eslint-enable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\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\n/**\n * Get the state of an AccountSelector based on a {@link SimulationAccount}.\n *\n * @param account - The {@link SimulationAccount} to get the state from.\n * @returns The state of the AccountSelector.\n */\nexport function getStateFromAccount(\n account: SimulationAccount,\n): AccountSelectorState {\n const { address, scopes } = account;\n return {\n addresses: scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[],\n accountId: account.id,\n };\n}\n\n/**\n * Get the state of an AssetSelector based on a {@link SimulationAsset}.\n *\n * @param id - The Asset id as a CAIP-19 asset type.\n * @param assets - The {@link SimulationAsset} to get the state from.\n * @returns The state of the AssetSelector.\n */\nexport function getStateFromAsset(\n id: CaipAssetType,\n assets: Record<CaipAssetType, SimulationAsset>,\n): AssetSelectorState {\n const asset = assets[id];\n\n assert(asset, `Asset with ID \"${id}\" not found in simulation assets.`);\n\n const { symbol, name } = asset;\n\n return {\n asset: id,\n symbol,\n name,\n };\n}\n\n/**\n * Generate a pseudo-random UUID.\n *\n * @returns A pseudo-random UUID string.\n */\nconst getPseudoRandomUuid = getPseudoRandomUuidGenerator();\n\n/**\n * The base options for the {@link getMockAccount} function.\n */\nexport type BaseMockAccountOptions = {\n /**\n * The address of the account.\n */\n address: string;\n\n /**\n * The ID of the account. If not provided, a pseudo-random UUID will be\n * generated.\n */\n id?: string;\n\n /**\n * Whether the account is selected by default.\n */\n selected?: boolean;\n};\n\n/**\n * Options for creating a mock account with assets or scopes. If `scopes` are\n * not provided, they will be derived from the `assets`.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithAssets = BaseMockAccountOptions & {\n /**\n * The assets associated with the account. These should be in CAIP format.\n */\n assets: CaipAssetType[];\n\n /**\n * The scopes associated with the account. If not provided, they will be\n * derived from the `assets`.\n */\n scopes?: CaipChainId[];\n};\n\n/**\n * Options for creating a mock account with scopes, and optionally assets.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithScopes = BaseMockAccountOptions & {\n /**\n * The scopes associated with the account. These should be in CAIP format.\n */\n scopes: CaipChainId[];\n\n /**\n * The assets associated with the account. If not provided, it will default\n * to an empty array.\n */\n assets?: CaipAssetType[];\n};\n\nexport type GetMockAccountOptions =\n | MockAccountOptionsWithAssets\n | MockAccountOptionsWithScopes;\n\n/**\n * Get a mock account object for testing purposes.\n *\n * @param options - The options for creating the mock account.\n * @param options.address - The address of the account.\n * @param options.scopes - The scopes associated with the account, in CAIP\n * format. If not provided, they will be derived from the `assets`.\n * @param options.assets - The assets associated with the account, in CAIP\n * format. If not provided, it will default to an empty array.\n * @param options.selected - Whether the account is selected by default.\n * @param options.id - The ID of the account. If not provided, a pseudo-random\n * UUID will be generated.\n * @returns A mock account object with the specified properties.\n */\nexport function getMockAccount({\n address,\n assets = [],\n selected = false,\n id = getPseudoRandomUuid(),\n scopes = getScopesFromAssets(assets),\n}: GetMockAccountOptions): SimulationAccount {\n return {\n address,\n id,\n scopes,\n selected,\n assets,\n };\n}\n"]}
1
+ {"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type {\n AccountSelectorState,\n AssetSelectorState,\n SnapId,\n} from '@metamask/snaps-sdk';\nimport type {\n InstallSnapOptions,\n SimulationAccount,\n SimulationAsset,\n Snap,\n} from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n} from '@metamask/utils';\n\nimport {\n rootLogger,\n getEnvironment,\n getPseudoRandomUuidGenerator,\n getScopesFromAssets,\n} 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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\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 (\n ...args: any[]\n ) => InstanceType<typeof AbstractExecutionService>,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n /* eslint-disable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\n mockJsonRpc,\n close,\n } = await getEnvironment().installSnap(...resolvedOptions);\n /* eslint-enable @typescript-eslint/unbound-method */\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 onStart,\n onNameLookup,\n onProtocolRequest,\n onClientRequest,\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\n/**\n * Get the state of an AccountSelector based on a {@link SimulationAccount}.\n *\n * @param account - The {@link SimulationAccount} to get the state from.\n * @returns The state of the AccountSelector.\n */\nexport function getStateFromAccount(\n account: SimulationAccount,\n): AccountSelectorState {\n const { address, scopes } = account;\n return {\n addresses: scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[],\n accountId: account.id,\n };\n}\n\n/**\n * Get the state of an AssetSelector based on a {@link SimulationAsset}.\n *\n * @param id - The Asset id as a CAIP-19 asset type.\n * @param assets - The {@link SimulationAsset} to get the state from.\n * @returns The state of the AssetSelector.\n */\nexport function getStateFromAsset(\n id: CaipAssetType,\n assets: Record<CaipAssetType, SimulationAsset>,\n): AssetSelectorState {\n const asset = assets[id];\n\n assert(asset, `Asset with ID \"${id}\" not found in simulation assets.`);\n\n const { symbol, name } = asset;\n\n return {\n asset: id,\n symbol,\n name,\n };\n}\n\n/**\n * Generate a pseudo-random UUID.\n *\n * @returns A pseudo-random UUID string.\n */\nconst getPseudoRandomUuid = getPseudoRandomUuidGenerator();\n\n/**\n * The base options for the {@link getMockAccount} function.\n */\nexport type BaseMockAccountOptions = {\n /**\n * The address of the account.\n */\n address: string;\n\n /**\n * The ID of the account. If not provided, a pseudo-random UUID will be\n * generated.\n */\n id?: string;\n\n /**\n * Whether the account is selected by default.\n */\n selected?: boolean;\n\n /**\n * Whether the account is owned by the snap.\n */\n owned?: boolean;\n};\n\n/**\n * Options for creating a mock account with assets or scopes. If `scopes` are\n * not provided, they will be derived from the `assets`.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithAssets = BaseMockAccountOptions & {\n /**\n * The assets associated with the account. These should be in CAIP format.\n */\n assets: CaipAssetType[];\n\n /**\n * The scopes associated with the account. If not provided, they will be\n * derived from the `assets`.\n */\n scopes?: CaipChainId[];\n};\n\n/**\n * Options for creating a mock account with scopes, and optionally assets.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithScopes = BaseMockAccountOptions & {\n /**\n * The scopes associated with the account. These should be in CAIP format.\n */\n scopes: CaipChainId[];\n\n /**\n * The assets associated with the account. If not provided, it will default\n * to an empty array.\n */\n assets?: CaipAssetType[];\n};\n\nexport type GetMockAccountOptions =\n | MockAccountOptionsWithAssets\n | MockAccountOptionsWithScopes;\n\n/**\n * Get a mock account object for testing purposes.\n *\n * @param options - The options for creating the mock account.\n * @param options.address - The address of the account.\n * @param options.scopes - The scopes associated with the account, in CAIP\n * format. If not provided, they will be derived from the `assets`.\n * @param options.assets - The assets associated with the account, in CAIP\n * format. If not provided, it will default to an empty array.\n * @param options.selected - Whether the account is selected by default.\n * @param options.owned - Whether the account is owned by the snap.\n * @param options.id - The ID of the account. If not provided, a pseudo-random\n * UUID will be generated.\n * @returns A mock account object with the specified properties.\n */\nexport function getMockAccount({\n address,\n assets = [],\n selected = false,\n owned = false,\n id = getPseudoRandomUuid(),\n scopes = getScopesFromAssets(assets),\n}: GetMockAccountOptions): SimulationAccount {\n return {\n address,\n id,\n scopes,\n selected,\n owned,\n assets,\n };\n}\n"]}
package/dist/matchers.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  // Note: Because this file imports from `@jest/globals`, it can only be used in
3
3
  // a Jest environment. This is why it's not exported from the index file.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.toRender = exports.toSendNotification = exports.toRespondWithError = exports.toRespondWith = void 0;
5
+ exports.toTrace = exports.toTrackEvent = exports.toTrackError = exports.toRender = exports.toSendNotification = exports.toRespondWithError = exports.toRespondWith = void 0;
6
6
  const globals_1 = require("@jest/globals");
7
7
  const jsx_1 = require("@metamask/snaps-sdk/jsx");
8
8
  const snaps_simulation_1 = require("@metamask/snaps-simulation");
@@ -213,10 +213,79 @@ function (actual, expected) {
213
213
  return { message, pass };
214
214
  };
215
215
  exports.toRender = toRender;
216
+ const toTrackError = function (actual, errorData) {
217
+ assertActualIsSnapResponse(actual, 'toTrackError');
218
+ const errorValidator = (error) => {
219
+ if (!errorData) {
220
+ // If no error data is provided, we just check for the existence of an
221
+ // error.
222
+ return true;
223
+ }
224
+ return this.equals(error, errorData);
225
+ };
226
+ const { errors } = actual.tracked;
227
+ const pass = errors.some(errorValidator);
228
+ const message = pass
229
+ ? () => `${this.utils.matcherHint('.not.toTrackError')}\n\n` +
230
+ `Expected not to track error with data: ${this.utils.printExpected(errorData)}\n` +
231
+ `Received errors: ${this.utils.printReceived(errors)}`
232
+ : () => `${this.utils.matcherHint('.toTrackError')}\n\n` +
233
+ `Expected to track error with data: ${this.utils.printExpected(errorData)}\n` +
234
+ `Received errors: ${this.utils.printReceived(errors)}`;
235
+ return { message, pass };
236
+ };
237
+ exports.toTrackError = toTrackError;
238
+ const toTrackEvent = function (actual, eventData) {
239
+ assertActualIsSnapResponse(actual, 'toTrackEvent');
240
+ const eventValidator = (event) => {
241
+ if (!eventData) {
242
+ // If no event data is provided, we just check for the existence of an
243
+ // event.
244
+ return true;
245
+ }
246
+ return this.equals(event, eventData);
247
+ };
248
+ const { events } = actual.tracked;
249
+ const pass = events.some(eventValidator);
250
+ const message = pass
251
+ ? () => `${this.utils.matcherHint('.not.toTrackEvent')}\n\n` +
252
+ `Expected not to track event with data: ${this.utils.printExpected(eventData)}\n` +
253
+ `Received events: ${this.utils.printReceived(events)}`
254
+ : () => `${this.utils.matcherHint('.toTrackEvent')}\n\n` +
255
+ `Expected to track event with data: ${this.utils.printExpected(eventData)}\n` +
256
+ `Received events: ${this.utils.printReceived(events)}`;
257
+ return { message, pass };
258
+ };
259
+ exports.toTrackEvent = toTrackEvent;
260
+ const toTrace = function (actual, traceData) {
261
+ assertActualIsSnapResponse(actual, 'toTrace');
262
+ const traceValidator = (trace) => {
263
+ if (!traceData) {
264
+ // If no trace data is provided, we just check for the existence of a
265
+ // trace.
266
+ return true;
267
+ }
268
+ return this.equals(trace, traceData);
269
+ };
270
+ const { traces } = actual.tracked;
271
+ const pass = traces.some(traceValidator);
272
+ const message = pass
273
+ ? () => `${this.utils.matcherHint('.not.toTrace')}\n\n` +
274
+ `Expected not to trace with data: ${this.utils.printExpected(traceData)}\n` +
275
+ `Received traces: ${this.utils.printReceived(traces)}`
276
+ : () => `${this.utils.matcherHint('.toTrace')}\n\n` +
277
+ `Expected to trace with data: ${this.utils.printExpected(traceData)}\n` +
278
+ `Received traces: ${this.utils.printReceived(traces)}`;
279
+ return { message, pass };
280
+ };
281
+ exports.toTrace = toTrace;
216
282
  globals_1.expect.extend({
217
283
  toRespondWith: exports.toRespondWith,
218
284
  toRespondWithError: exports.toRespondWithError,
219
285
  toSendNotification: exports.toSendNotification,
220
286
  toRender: exports.toRender,
287
+ toTrackError: exports.toTrackError,
288
+ toTrackEvent: exports.toTrackEvent,
289
+ toTrace: exports.toTrace,
221
290
  });
222
291
  //# sourceMappingURL=matchers.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.cjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["// 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 // This should not return a promise.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\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":["// 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 TrackableError,\n TraceRequest,\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 // This should not return a promise.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\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\nexport const toTrackError: MatcherFunction<\n [errorData?: Partial<TrackableError>]\n> = function (actual, errorData) {\n assertActualIsSnapResponse(actual, 'toTrackError');\n\n const errorValidator = (error: SnapResponse['tracked']['errors'][number]) => {\n if (!errorData) {\n // If no error data is provided, we just check for the existence of an\n // error.\n return true;\n }\n\n return this.equals(error, errorData);\n };\n\n const { errors } = actual.tracked;\n const pass = errors.some(errorValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrackError')}\\n\\n` +\n `Expected not to track error with data: ${this.utils.printExpected(\n errorData,\n )}\\n` +\n `Received errors: ${this.utils.printReceived(errors)}`\n : () =>\n `${this.utils.matcherHint('.toTrackError')}\\n\\n` +\n `Expected to track error with data: ${this.utils.printExpected(\n errorData,\n )}\\n` +\n `Received errors: ${this.utils.printReceived(errors)}`;\n\n return { message, pass };\n};\n\nexport const toTrackEvent: MatcherFunction<[eventData?: Json | undefined]> =\n function (actual, eventData) {\n assertActualIsSnapResponse(actual, 'toTrackEvent');\n\n const eventValidator = (\n event: SnapResponse['tracked']['events'][number],\n ) => {\n if (!eventData) {\n // If no event data is provided, we just check for the existence of an\n // event.\n return true;\n }\n\n return this.equals(event, eventData);\n };\n\n const { events } = actual.tracked;\n const pass = events.some(eventValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrackEvent')}\\n\\n` +\n `Expected not to track event with data: ${this.utils.printExpected(\n eventData,\n )}\\n` +\n `Received events: ${this.utils.printReceived(events)}`\n : () =>\n `${this.utils.matcherHint('.toTrackEvent')}\\n\\n` +\n `Expected to track event with data: ${this.utils.printExpected(\n eventData,\n )}\\n` +\n `Received events: ${this.utils.printReceived(events)}`;\n\n return { message, pass };\n };\n\nexport const toTrace: MatcherFunction<[traceData?: TraceRequest]> = function (\n actual,\n traceData,\n) {\n assertActualIsSnapResponse(actual, 'toTrace');\n\n const traceValidator = (trace: SnapResponse['tracked']['traces'][number]) => {\n if (!traceData) {\n // If no trace data is provided, we just check for the existence of a\n // trace.\n return true;\n }\n\n return this.equals(trace, traceData);\n };\n\n const { traces } = actual.tracked;\n const pass = traces.some(traceValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrace')}\\n\\n` +\n `Expected not to trace with data: ${this.utils.printExpected(\n traceData,\n )}\\n` +\n `Received traces: ${this.utils.printReceived(traces)}`\n : () =>\n `${this.utils.matcherHint('.toTrace')}\\n\\n` +\n `Expected to trace with data: ${this.utils.printExpected(\n traceData,\n )}\\n` +\n `Received traces: ${this.utils.printReceived(traces)}`;\n\n return { message, pass };\n};\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n toTrackError,\n toTrackEvent,\n toTrace,\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { MatcherFunction } from "@jest/expect";
2
- import type { EnumToUnion, ComponentOrElement, NotificationType } from "@metamask/snaps-sdk";
2
+ import type { EnumToUnion, ComponentOrElement, NotificationType, TrackableError, TraceRequest } from "@metamask/snaps-sdk";
3
3
  import type { JSXElement } from "@metamask/snaps-sdk/jsx";
4
4
  import type { Json } from "@metamask/utils";
5
5
  /**
@@ -35,4 +35,9 @@ export declare const toSendNotification: MatcherFunction<[
35
35
  } | undefined
36
36
  ]>;
37
37
  export declare const toRender: MatcherFunction<[expected: ComponentOrElement]>;
38
+ export declare const toTrackError: MatcherFunction<[
39
+ errorData?: Partial<TrackableError>
40
+ ]>;
41
+ export declare const toTrackEvent: MatcherFunction<[eventData?: Json | undefined]>;
42
+ export declare const toTrace: MatcherFunction<[traceData?: TraceRequest]>;
38
43
  //# sourceMappingURL=matchers.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.d.cts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAGA,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,CAkClE,CAAC"}
1
+ {"version":3,"file":"matchers.d.cts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAElB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACb,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,CAkClE,CAAC;AAEJ,eAAO,MAAM,YAAY,EAAE,eAAe,CACxC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;CAAC,CAgCtC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,CAkCtE,CAAC;AAEJ,eAAO,MAAM,OAAO,EAAE,eAAe,CAAC,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAkC/D,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { MatcherFunction } from "@jest/expect";
2
- import type { EnumToUnion, ComponentOrElement, NotificationType } from "@metamask/snaps-sdk";
2
+ import type { EnumToUnion, ComponentOrElement, NotificationType, TrackableError, TraceRequest } from "@metamask/snaps-sdk";
3
3
  import type { JSXElement } from "@metamask/snaps-sdk/jsx";
4
4
  import type { Json } from "@metamask/utils";
5
5
  /**
@@ -35,4 +35,9 @@ export declare const toSendNotification: MatcherFunction<[
35
35
  } | undefined
36
36
  ]>;
37
37
  export declare const toRender: MatcherFunction<[expected: ComponentOrElement]>;
38
+ export declare const toTrackError: MatcherFunction<[
39
+ errorData?: Partial<TrackableError>
40
+ ]>;
41
+ export declare const toTrackEvent: MatcherFunction<[eventData?: Json | undefined]>;
42
+ export declare const toTrace: MatcherFunction<[traceData?: TraceRequest]>;
38
43
  //# sourceMappingURL=matchers.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.d.mts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAGA,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,CAkClE,CAAC"}
1
+ {"version":3,"file":"matchers.d.mts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB;AAEpD,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAElB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACb,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,CAkClE,CAAC;AAEJ,eAAO,MAAM,YAAY,EAAE,eAAe,CACxC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;CAAC,CAgCtC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,CAkCtE,CAAC;AAEJ,eAAO,MAAM,OAAO,EAAE,eAAe,CAAC,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAkC/D,CAAC"}
package/dist/matchers.mjs CHANGED
@@ -207,10 +207,76 @@ function (actual, expected) {
207
207
  `\n\nDifference:\n\n${difference}`;
208
208
  return { message, pass };
209
209
  };
210
+ export const toTrackError = function (actual, errorData) {
211
+ assertActualIsSnapResponse(actual, 'toTrackError');
212
+ const errorValidator = (error) => {
213
+ if (!errorData) {
214
+ // If no error data is provided, we just check for the existence of an
215
+ // error.
216
+ return true;
217
+ }
218
+ return this.equals(error, errorData);
219
+ };
220
+ const { errors } = actual.tracked;
221
+ const pass = errors.some(errorValidator);
222
+ const message = pass
223
+ ? () => `${this.utils.matcherHint('.not.toTrackError')}\n\n` +
224
+ `Expected not to track error with data: ${this.utils.printExpected(errorData)}\n` +
225
+ `Received errors: ${this.utils.printReceived(errors)}`
226
+ : () => `${this.utils.matcherHint('.toTrackError')}\n\n` +
227
+ `Expected to track error with data: ${this.utils.printExpected(errorData)}\n` +
228
+ `Received errors: ${this.utils.printReceived(errors)}`;
229
+ return { message, pass };
230
+ };
231
+ export const toTrackEvent = function (actual, eventData) {
232
+ assertActualIsSnapResponse(actual, 'toTrackEvent');
233
+ const eventValidator = (event) => {
234
+ if (!eventData) {
235
+ // If no event data is provided, we just check for the existence of an
236
+ // event.
237
+ return true;
238
+ }
239
+ return this.equals(event, eventData);
240
+ };
241
+ const { events } = actual.tracked;
242
+ const pass = events.some(eventValidator);
243
+ const message = pass
244
+ ? () => `${this.utils.matcherHint('.not.toTrackEvent')}\n\n` +
245
+ `Expected not to track event with data: ${this.utils.printExpected(eventData)}\n` +
246
+ `Received events: ${this.utils.printReceived(events)}`
247
+ : () => `${this.utils.matcherHint('.toTrackEvent')}\n\n` +
248
+ `Expected to track event with data: ${this.utils.printExpected(eventData)}\n` +
249
+ `Received events: ${this.utils.printReceived(events)}`;
250
+ return { message, pass };
251
+ };
252
+ export const toTrace = function (actual, traceData) {
253
+ assertActualIsSnapResponse(actual, 'toTrace');
254
+ const traceValidator = (trace) => {
255
+ if (!traceData) {
256
+ // If no trace data is provided, we just check for the existence of a
257
+ // trace.
258
+ return true;
259
+ }
260
+ return this.equals(trace, traceData);
261
+ };
262
+ const { traces } = actual.tracked;
263
+ const pass = traces.some(traceValidator);
264
+ const message = pass
265
+ ? () => `${this.utils.matcherHint('.not.toTrace')}\n\n` +
266
+ `Expected not to trace with data: ${this.utils.printExpected(traceData)}\n` +
267
+ `Received traces: ${this.utils.printReceived(traces)}`
268
+ : () => `${this.utils.matcherHint('.toTrace')}\n\n` +
269
+ `Expected to trace with data: ${this.utils.printExpected(traceData)}\n` +
270
+ `Received traces: ${this.utils.printReceived(traces)}`;
271
+ return { message, pass };
272
+ };
210
273
  expect.extend({
211
274
  toRespondWith,
212
275
  toRespondWithError,
213
276
  toSendNotification,
214
277
  toRender,
278
+ toTrackError,
279
+ toTrackEvent,
280
+ toTrace,
215
281
  });
216
282
  //# sourceMappingURL=matchers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.mjs","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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","sourcesContent":["// 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 // This should not return a promise.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\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":["// 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 TrackableError,\n TraceRequest,\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 // This should not return a promise.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\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\nexport const toTrackError: MatcherFunction<\n [errorData?: Partial<TrackableError>]\n> = function (actual, errorData) {\n assertActualIsSnapResponse(actual, 'toTrackError');\n\n const errorValidator = (error: SnapResponse['tracked']['errors'][number]) => {\n if (!errorData) {\n // If no error data is provided, we just check for the existence of an\n // error.\n return true;\n }\n\n return this.equals(error, errorData);\n };\n\n const { errors } = actual.tracked;\n const pass = errors.some(errorValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrackError')}\\n\\n` +\n `Expected not to track error with data: ${this.utils.printExpected(\n errorData,\n )}\\n` +\n `Received errors: ${this.utils.printReceived(errors)}`\n : () =>\n `${this.utils.matcherHint('.toTrackError')}\\n\\n` +\n `Expected to track error with data: ${this.utils.printExpected(\n errorData,\n )}\\n` +\n `Received errors: ${this.utils.printReceived(errors)}`;\n\n return { message, pass };\n};\n\nexport const toTrackEvent: MatcherFunction<[eventData?: Json | undefined]> =\n function (actual, eventData) {\n assertActualIsSnapResponse(actual, 'toTrackEvent');\n\n const eventValidator = (\n event: SnapResponse['tracked']['events'][number],\n ) => {\n if (!eventData) {\n // If no event data is provided, we just check for the existence of an\n // event.\n return true;\n }\n\n return this.equals(event, eventData);\n };\n\n const { events } = actual.tracked;\n const pass = events.some(eventValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrackEvent')}\\n\\n` +\n `Expected not to track event with data: ${this.utils.printExpected(\n eventData,\n )}\\n` +\n `Received events: ${this.utils.printReceived(events)}`\n : () =>\n `${this.utils.matcherHint('.toTrackEvent')}\\n\\n` +\n `Expected to track event with data: ${this.utils.printExpected(\n eventData,\n )}\\n` +\n `Received events: ${this.utils.printReceived(events)}`;\n\n return { message, pass };\n };\n\nexport const toTrace: MatcherFunction<[traceData?: TraceRequest]> = function (\n actual,\n traceData,\n) {\n assertActualIsSnapResponse(actual, 'toTrace');\n\n const traceValidator = (trace: SnapResponse['tracked']['traces'][number]) => {\n if (!traceData) {\n // If no trace data is provided, we just check for the existence of a\n // trace.\n return true;\n }\n\n return this.equals(trace, traceData);\n };\n\n const { traces } = actual.tracked;\n const pass = traces.some(traceValidator);\n\n const message = pass\n ? () =>\n `${this.utils.matcherHint('.not.toTrace')}\\n\\n` +\n `Expected not to trace with data: ${this.utils.printExpected(\n traceData,\n )}\\n` +\n `Received traces: ${this.utils.printReceived(traces)}`\n : () =>\n `${this.utils.matcherHint('.toTrace')}\\n\\n` +\n `Expected to trace with data: ${this.utils.printExpected(\n traceData,\n )}\\n` +\n `Received traces: ${this.utils.printReceived(traces)}`;\n\n return { message, pass };\n};\n\nexpect.extend({\n toRespondWith,\n toRespondWithError,\n toSendNotification,\n toRender,\n toTrackError,\n toTrackEvent,\n toTrace,\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-jest",
3
- "version": "9.2.0",
3
+ "version": "9.4.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": "^14.0.0",
64
- "@metamask/snaps-sdk": "^9.0.0",
65
- "@metamask/snaps-simulation": "^3.2.0",
63
+ "@metamask/snaps-controllers": "^14.2.0",
64
+ "@metamask/snaps-sdk": "^9.3.0",
65
+ "@metamask/snaps-simulation": "^3.4.0",
66
66
  "@metamask/superstruct": "^3.2.1",
67
- "@metamask/utils": "^11.4.0",
67
+ "@metamask/utils": "^11.4.2",
68
68
  "express": "^5.1.0",
69
69
  "jest-environment-node": "^29.5.0",
70
70
  "jest-matcher-utils": "^29.5.0",
@@ -74,7 +74,7 @@
74
74
  "@jest/types": "^29.6.3",
75
75
  "@lavamoat/allow-scripts": "^3.3.4",
76
76
  "@metamask/auto-changelog": "^5.0.2",
77
- "@metamask/snaps-utils": "^11.0.0",
77
+ "@metamask/snaps-utils": "^11.3.0",
78
78
  "@swc/core": "1.11.31",
79
79
  "@swc/jest": "^0.2.38",
80
80
  "@ts-bridge/cli": "^0.6.1",