From 704e58ec381cd7dd43048bd01f3e690b259160bd Mon Sep 17 00:00:00 2001 From: Lev Roskoshin Date: Sun, 22 Jun 2025 17:36:57 +0200 Subject: [PATCH 1/5] feat: add bun support --- README.md | 36 +++++++++++++++++++++++++++++++-- package.json | 6 ++++++ src/index.ts | 1 + src/test/bun.ts | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ yarn.lock | 13 ++++++++++++ 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 src/test/bun.ts diff --git a/README.md b/README.md index 0bff10f..f4ae41a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # test-utils -This package contains useful testing utilities, such as unit test matchers (for jest and chai) and other useful functions, such as `randomAddress`. +This package contains useful testing utilities, such as unit test matchers (for jest, chai, and bun) and other useful functions, such as `randomAddress`. ## Installation @@ -14,11 +14,43 @@ npm i --save-dev @ton/test-utils ## Usage -To use the test matchers, just install either jest or chai and import this package like so: +To use the test matchers, just install either jest, chai, or bun and import this package like so: ```typescript import "@ton/test-utils"; ``` +### Examples + +#### Jest +```typescript +import { expect } from '@jest/globals'; +import "@ton/test-utils"; + +test('cell comparison', () => { + expect(cell1).toEqualCell(cell2); +}); +``` + +#### Chai +```typescript +import { expect } from 'chai'; +import "@ton/test-utils"; + +it('cell comparison', () => { + expect(cell1).to.equalCell(cell2); +}); +``` + +#### Bun +```typescript +import { expect, test } from 'bun:test'; +import "@ton/test-utils"; + +test('cell comparison', () => { + expect(cell1).toEqualCell(cell2); +}); +``` + ### Transaction matcher notice The transaction matcher (`.toHaveTransaction`) can only perform matching on transactions with descriptions of type `generic`. When matching an array of transactions, all transactions of other types will be filtered out. When matching a single transaction of non-generic type, an exception will be thrown. diff --git a/package.json b/package.json index f8e7123..77351dd 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@ton/toolchain": "the-ton-tech/toolchain#v1.4.0", "@types/chai": "^4.3.4", "@types/jest": "^29.4.4", + "bun-types": "^1.0.0", "chai": "^4.3.7", "eslint": "^9.28.0", "jest": "^29.5.0", @@ -28,12 +29,16 @@ "peerDependencies": { "@jest/globals": "*", "@ton/core": ">=0.49.2", + "bun-types": "*", "chai": "*" }, "peerDependenciesMeta": { "@jest/globals": { "optional": true }, + "bun-types": { + "optional": true + }, "chai": { "optional": true } @@ -46,6 +51,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --max-warnings 0 --fix", "test": "jest", + "test:bun": "bun test", "build": "rm -rf dist && tsc" }, "packageManager": "yarn@3.6.1" diff --git a/src/index.ts b/src/index.ts index 844bc86..da4bafc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ export { contractsMeta, ContractsMeta } from './utils/ContractsMeta'; import './test/jest'; import './test/chai'; +import './test/bun'; export { prettifyTransaction, PrettyTransaction } from './utils/pretty-transaction'; diff --git a/src/test/bun.ts b/src/test/bun.ts new file mode 100644 index 0000000..4e5f1e9 --- /dev/null +++ b/src/test/bun.ts @@ -0,0 +1,54 @@ +import type { MatcherFunction } from 'expect'; +import { Address, Cell, Slice } from '@ton/core'; + +import { FlatTransactionComparable, compareTransactionForTest } from './transaction'; +import { CompareResult } from './interface'; +import { compareAddressForTest, compareCellForTest, compareSliceForTest } from './comparisons'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function wrapComparer(comparer: (subject: any, cmp: T) => CompareResult): MatcherFunction<[cmp: T]> { + return function (actual, cmp) { + const result = comparer(actual, cmp); + return { + pass: result.pass, + message: () => { + if (result.pass) { + return result.negMessage(); + } else { + return result.posMessage(); + } + }, + }; + }; +} + +const toHaveTransaction = wrapComparer(compareTransactionForTest); +const toEqualCell = wrapComparer(compareCellForTest); +const toEqualAddress = wrapComparer(compareAddressForTest); +const toEqualSlice = wrapComparer(compareSliceForTest); + +try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const bunTest = require('bun:test'); + + if (bunTest && bunTest.expect) + bunTest.expect.extend({ + toHaveTransaction, + toEqualCell, + toEqualAddress, + toEqualSlice, + }); + // eslint-disable-next-line no-empty +} catch (_) {} + +interface TonMatchers { + toHaveTransaction(cmp: FlatTransactionComparable): T; + toEqualCell(cell: Cell): T; + toEqualAddress(address: Address): T; + toEqualSlice(slice: Slice): T; +} + +// @ts-ignore: Module 'bun:test' is only available in bun environment +declare module 'bun:test' { + interface Matchers extends TonMatchers {} +} diff --git a/yarn.lock b/yarn.lock index 23e7a58..8e6862a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1017,6 +1017,7 @@ __metadata: "@ton/toolchain": "the-ton-tech/toolchain#v1.4.0" "@types/chai": ^4.3.4 "@types/jest": ^29.4.4 + bun-types: ^1.0.0 chai: ^4.3.7 eslint: ^9.28.0 jest: ^29.5.0 @@ -1026,10 +1027,13 @@ __metadata: peerDependencies: "@jest/globals": "*" "@ton/core": ">=0.49.2" + bun-types: "*" chai: "*" peerDependenciesMeta: "@jest/globals": optional: true + bun-types: + optional: true chai: optional: true languageName: unknown @@ -1772,6 +1776,15 @@ __metadata: languageName: node linkType: hard +"bun-types@npm:^1.0.0": + version: 1.2.15 + resolution: "bun-types@npm:1.2.15" + dependencies: + "@types/node": "*" + checksum: 33f55e374332281b7d73b28f75c82d97a3c3d9e942281d143697e2d96636650b24954c5048a20ce0d312a432506445fa938d28e58d8748d72b4c8bad086d2b77 + languageName: node + linkType: hard + "cacache@npm:^17.0.0": version: 17.1.3 resolution: "cacache@npm:17.1.3" From 75f6ac5f7a466fb87d353e9e38918134bb4b6df0 Mon Sep 17 00:00:00 2001 From: Lev Roskoshin Date: Sun, 22 Jun 2025 18:03:52 +0200 Subject: [PATCH 2/5] chore: fix linting --- src/test/bun.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/bun.ts b/src/test/bun.ts index 4e5f1e9..29a7020 100644 --- a/src/test/bun.ts +++ b/src/test/bun.ts @@ -48,7 +48,8 @@ interface TonMatchers { toEqualSlice(slice: Slice): T; } -// @ts-ignore: Module 'bun:test' is only available in bun environment +// @ts-expect-error: Module 'bun:test' is only available in bun environment declare module 'bun:test' { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface Matchers extends TonMatchers {} } From e06f47de387dfa5e629d305692677b0945eb6052 Mon Sep 17 00:00:00 2001 From: Lev Roskoshin Date: Sun, 22 Jun 2025 18:09:26 +0200 Subject: [PATCH 3/5] chore: update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6644d0b..4e5a1a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added +- **feat**: Add support for the Bun.js test runner. + +### Changed +- **docs**: Updated `README.md` with examples and instructions for using the Bun matchers. + ## [0.7.0] - 2025-06-02 - Add address, opcode and errors description in `toHaveTransaction` method From 36b79b070b7b2ed9fc3c376827acee43bf50c744 Mon Sep 17 00:00:00 2001 From: krigga Date: Mon, 4 Aug 2025 22:15:58 +1000 Subject: [PATCH 4/5] chore: change bun types package feat: add toThrowExitCode bun matcher --- package.json | 6 +++--- src/test/bun.ts | 42 +++++++++++++++++++++++++++++------------- yarn.lock | 25 ++++++++++++++++++------- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index f1fe06c..08a26bf 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,9 @@ "@ton/core": "^0.49.2", "@ton/crypto": "^3.2.0", "@ton/toolchain": "the-ton-tech/toolchain#v1.4.0", + "@types/bun": "^1.2.19", "@types/chai": "^4.3.4", "@types/jest": "^29.4.4", - "bun-types": "^1.0.0", "chai": "^4.3.7", "eslint": "^9.28.0", "jest": "^29.5.0", @@ -29,14 +29,14 @@ "peerDependencies": { "@jest/globals": "*", "@ton/core": ">=0.49.2", - "bun-types": "*", + "@types/bun": ">=1.0.0", "chai": "*" }, "peerDependenciesMeta": { "@jest/globals": { "optional": true }, - "bun-types": { + "@types/bun": { "optional": true }, "chai": { diff --git a/src/test/bun.ts b/src/test/bun.ts index 29a7020..fe931c0 100644 --- a/src/test/bun.ts +++ b/src/test/bun.ts @@ -4,21 +4,30 @@ import { Address, Cell, Slice } from '@ton/core'; import { FlatTransactionComparable, compareTransactionForTest } from './transaction'; import { CompareResult } from './interface'; import { compareAddressForTest, compareCellForTest, compareSliceForTest } from './comparisons'; +import { compareThrownExitCodeForTest } from './exitCode'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function wrapComparer(comparer: (subject: any, cmp: T) => CompareResult): MatcherFunction<[cmp: T]> { +function extractResult(result: CompareResult) { + return { + pass: result.pass, + message: () => { + if (result.pass) { + return result.negMessage(); + } else { + return result.posMessage(); + } + }, + }; +} + +function wrapComparer( + comparer: (subject: unknown, cmp: T) => CompareResult | Promise, +): MatcherFunction<[cmp: T]> { return function (actual, cmp) { const result = comparer(actual, cmp); - return { - pass: result.pass, - message: () => { - if (result.pass) { - return result.negMessage(); - } else { - return result.posMessage(); - } - }, - }; + if (result instanceof Promise) { + return result.then(extractResult); + } + return extractResult(result); }; } @@ -26,6 +35,7 @@ const toHaveTransaction = wrapComparer(compareTransactionForTest); const toEqualCell = wrapComparer(compareCellForTest); const toEqualAddress = wrapComparer(compareAddressForTest); const toEqualSlice = wrapComparer(compareSliceForTest); +const toThrowExitCode = wrapComparer(compareThrownExitCodeForTest); try { // eslint-disable-next-line @typescript-eslint/no-require-imports @@ -37,6 +47,7 @@ try { toEqualCell, toEqualAddress, toEqualSlice, + toThrowExitCode, }); // eslint-disable-next-line no-empty } catch (_) {} @@ -46,9 +57,14 @@ interface TonMatchers { toEqualCell(cell: Cell): T; toEqualAddress(address: Address): T; toEqualSlice(slice: Slice): T; + + /** + * @example + * await expect(() => blockchain.runGetMethod(contract.address, 'test')).toThrowExitCode(11); + */ + toThrowExitCode(exitCode: number): Promise; } -// @ts-expect-error: Module 'bun:test' is only available in bun environment declare module 'bun:test' { // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface Matchers extends TonMatchers {} diff --git a/yarn.lock b/yarn.lock index 8e6862a..5f99e16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1015,9 +1015,9 @@ __metadata: "@ton/core": ^0.49.2 "@ton/crypto": ^3.2.0 "@ton/toolchain": "the-ton-tech/toolchain#v1.4.0" + "@types/bun": ^1.2.19 "@types/chai": ^4.3.4 "@types/jest": ^29.4.4 - bun-types: ^1.0.0 chai: ^4.3.7 eslint: ^9.28.0 jest: ^29.5.0 @@ -1027,12 +1027,12 @@ __metadata: peerDependencies: "@jest/globals": "*" "@ton/core": ">=0.49.2" - bun-types: "*" + "@types/bun": ">=1.0.0" chai: "*" peerDependenciesMeta: "@jest/globals": optional: true - bun-types: + "@types/bun": optional: true chai: optional: true @@ -1104,6 +1104,15 @@ __metadata: languageName: node linkType: hard +"@types/bun@npm:^1.2.19": + version: 1.2.19 + resolution: "@types/bun@npm:1.2.19" + dependencies: + bun-types: 1.2.19 + checksum: 175d73e404bd5ee336ce2e392c2632195938d8258692193161df5b865c665b0e835521f144d12d450519349ba14e2821bf0e142d8714cb3886f4f9f0672af87a + languageName: node + linkType: hard + "@types/chai@npm:^4.3.4": version: 4.3.4 resolution: "@types/chai@npm:4.3.4" @@ -1776,12 +1785,14 @@ __metadata: languageName: node linkType: hard -"bun-types@npm:^1.0.0": - version: 1.2.15 - resolution: "bun-types@npm:1.2.15" +"bun-types@npm:1.2.19": + version: 1.2.19 + resolution: "bun-types@npm:1.2.19" dependencies: "@types/node": "*" - checksum: 33f55e374332281b7d73b28f75c82d97a3c3d9e942281d143697e2d96636650b24954c5048a20ce0d312a432506445fa938d28e58d8748d72b4c8bad086d2b77 + peerDependencies: + "@types/react": ^19 + checksum: 646e2cb9a74ffbd2b103324d215da2db998a8075b512a3847acceb7042ffa0c9f66288a536af3788d44cc4ca54b2ba2292bb2f034c875d1f7efe1e18ff20c11b languageName: node linkType: hard From 616d4a3f26fbc21d84026257a0bf57545e0dc3db Mon Sep 17 00:00:00 2001 From: krigga Date: Mon, 4 Aug 2025 22:48:13 +1000 Subject: [PATCH 5/5] chore: update typescript --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 08a26bf..809b91e 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "eslint": "^9.28.0", "jest": "^29.5.0", "ts-jest": "^29.0.5", - "typescript": "^4.9.5" + "typescript": "^5.9.2" }, "peerDependencies": { "@jest/globals": "*", diff --git a/yarn.lock b/yarn.lock index 5f99e16..02c0d79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1023,7 +1023,7 @@ __metadata: jest: ^29.5.0 node-inspect-extracted: ^2.0.0 ts-jest: ^29.0.5 - typescript: ^4.9.5 + typescript: ^5.9.2 peerDependencies: "@jest/globals": "*" "@ton/core": ">=0.49.2" @@ -5858,23 +5858,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^4.9.5": - version: 4.9.5 - resolution: "typescript@npm:4.9.5" +"typescript@npm:^5.9.2": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db + checksum: f619cf6773cfe31409279711afd68cdf0859780006c50bc2a7a0c3227f85dea89a3b97248846326f3a17dad72ea90ec27cf61a8387772c680b2252fd02d8497b languageName: node linkType: hard -"typescript@patch:typescript@^4.9.5#~builtin": - version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=289587" +"typescript@patch:typescript@^5.9.2#~builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#~builtin::version=5.9.2&hash=14eedb" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 1f8f3b6aaea19f0f67cba79057674ba580438a7db55057eb89cc06950483c5d632115c14077f6663ea76fd09fce3c190e6414bb98582ec80aa5a4eaf345d5b68 + checksum: e42a701947325500008334622321a6ad073f842f5e7d5e7b588a6346b31fdf51d56082b9ce5cef24312ecd3e48d6c0d4d44da7555f65e2feec18cf62ec540385 languageName: node linkType: hard