Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch testing from Jest to Vitest [DRAFT] #233

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions packages/cashc/jest.config.js

This file was deleted.

2 changes: 0 additions & 2 deletions packages/cashc/jest.setup.js

This file was deleted.

10 changes: 4 additions & 6 deletions packages/cashc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,15 @@
"antlr": "antlr -Dlanguage=TypeScript -visitor -no-listener src/grammar/CashScript.g4",
"postantlr": "find src/grammar -type f -name 'CashScriptVisitor.ts' | xargs sed -i '' 's|\\(import .* \".*/.*\\)\";|\\1\\.js\";|g'",
"build": "yarn clean && yarn compile",
"build:test": "yarn clean:test && yarn compile:test && cpy './test/**/*.cash' ./dist-test/test",
"build:test": "vitest",
"clean": "rm -rf ./dist",
"clean:test": "rm -rf ./dist-test",
"compile": "tsc -p tsconfig.build.json",
"compile:test": "tsc -p tsconfig.test.json",
"lint": "eslint . --ext .ts --ignore-path ../../.eslintignore",
"prepare": "yarn build",
"prepublishOnly": "yarn test && yarn lint",
"pretest": "yarn build:test",
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
"test": "vitest"
},
"dependencies": {
"@bitauth/libauth": "^3.0.0",
Expand All @@ -56,14 +55,13 @@
"semver": "^7.5.4"
},
"devDependencies": {
"@jest/globals": "^29.4.1",
"@types/node": "^18.11.18",
"@types/semver": "^7.3.4",
"cpy-cli": "^4.2.0",
"eslint": "^8.54.0",
"jest": "^29.4.1",
"typescript": "^5.5.4",
"url-join": "^5.0.0"
"url-join": "^5.0.0",
"vitest": "^2.1.4"
},
"gitHead": "bf02a4b641d5d03c035d052247a545109c17b708"
}
3 changes: 2 additions & 1 deletion packages/cashc/test/ast/Location.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ describe('Location', () => {
const f = ast.contract.functions[0];

expect(f.location).toBeDefined();
expect((f.location).text(code)).toEqual('function hello(sig s, pubkey pk) {\n require(checkSig(s, pk));\n }');
// Replace all whitespace with a single space to avoid test failures caused by minor formatting differences in Vitest.
expect((f.location).text(code).replace(/\s+/g, ' ')).toEqual('function hello(sig s, pubkey pk) { require(checkSig(s, pk)); }');
});

const wrap = (code: string): string => {
Expand Down
6 changes: 0 additions & 6 deletions packages/cashc/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
{
"extends": "../../tsconfig.build.json",

"compilerOptions": {
"outDir": "./dist-test",
},

"include": [
"src/**/*",
"test/**/*",
],
}
9 changes: 9 additions & 0 deletions packages/cashc/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
globals: true,
environment: 'node',
root: './test',
},
});
10 changes: 0 additions & 10 deletions packages/cashscript/jest.config.js

This file was deleted.

8 changes: 0 additions & 8 deletions packages/cashscript/jest.setup.js

This file was deleted.

8 changes: 3 additions & 5 deletions packages/cashscript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"scripts": {
"build": "yarn clean && yarn compile",
"build:test": "yarn clean:test && yarn compile:test",
"build:test": "vitest",
"clean": "rm -rf ./dist",
"clean:test": "rm -rf ./dist-test",
"compile": "tsc -p tsconfig.build.json",
Expand All @@ -40,7 +40,7 @@
"prepare": "yarn build",
"prepublishOnly": "yarn test && yarn lint",
"pretest": "yarn build:test",
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
"test": "vitest"
},
"dependencies": {
"@bitauth/libauth": "^3.0.0",
Expand All @@ -52,12 +52,10 @@
"pako": "^2.1.0"
},
"devDependencies": {
"@jest/globals": "^29.4.1",
"@psf/bch-js": "^6.8.0",
"@types/pako": "^2.0.3",
"eslint": "^8.54.0",
"jest": "^29.4.1",
"typescript": "^5.5.4"
"vitest": "^2.1.4"
},
"gitHead": "bf02a4b641d5d03c035d052247a545109c17b708"
}
68 changes: 35 additions & 33 deletions packages/cashscript/src/test/JestExtensions.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { MatcherContext } from '@jest/expect';
import { SyncExpectationResult } from 'expect';
import { vi } from 'vitest';
import { Transaction } from '../index.js';

export {};

declare global {
namespace jest {
// eslint-disable-next-line
interface Matchers<R> {
namespace Vi {
interface Assertion {
toLog(value?: RegExp | string): Promise<void>;
toFailRequireWith(value: RegExp | string): Promise<void>;
toFailRequire(): Promise<void>;
Expand All @@ -17,67 +15,71 @@ declare global {

expect.extend({
async toLog(
this: MatcherContext,
transaction: Transaction,
match?: RegExp | string,
): Promise<SyncExpectationResult> {
const loggerSpy = jest.spyOn(console, 'log');
) {
const loggerSpy = vi.spyOn(console, 'log');

// silence actual stdout output
// Silence actual stdout output
loggerSpy.mockImplementation(() => {});
try { await transaction.debug(); } catch {}

// We concatenate all the logs into a single string - if no logs are present, we set received to undefined
const receivedBase = loggerSpy.mock.calls.reduce((acc, [log]) => `${acc}\n${log}`, '').trim();
// Concatenate all logs into a single string - if no logs are present, set received to undefined
const receivedBase = loggerSpy.mock.calls.reduce((acc: string, call: any[]) => {
const log = typeof call[0] === 'string' ? call[0] : '';
return `${acc}\n${log}`;
}, '').trim();

const received = receivedBase === '' ? undefined : receivedBase;

const matcherHint = this.utils.matcherHint('toLog', 'received', 'expected', { isNot: this.isNot });
const expectedText = `Expected: ${this.isNot ? 'not ' : ''}${this.utils.printExpected(match)}`;
const receivedText = `Received: ${this.utils.printReceived(received)}`;
const message = (): string => `${matcherHint}\n\n${expectedText}\n${receivedText}`;

try {
expect(loggerSpy).toBeCalledWith(match ? expect.stringMatching(match) : expect.anything());
} catch (e) {
return { message, pass: false };
}
const pass = loggerSpy.mock.calls.some((call: any[]) => {
const log = typeof call[0] === 'string' ? call[0] : '';
return match ? expect.stringMatching(match).asymmetricMatch(log) : true;
});

loggerSpy.mockClear();

return { message, pass: true };
return { message, pass };
},
});

expect.extend({
async toFailRequireWith(
this: MatcherContext,
transaction: Transaction,
match: RegExp | string,
): Promise<SyncExpectationResult> {
) {
// Normalize multiline strings by replacing all whitespace and line breaks with single spaces
const normalizeMultiline = (str: string): string => str.replace(/\s+/g, ' ').trim();

try {
await transaction.debug();


// If no error is thrown, test fails as the require statement did not trigger
const matcherHint = this.utils.matcherHint('.toFailRequireWith', undefined, match.toString(), { isNot: this.isNot });
const message = (): string => `${matcherHint}\n\nContract function did not fail a require statement.`;
return { message, pass: false };
} catch (transactionError: any) {
const matcherHint = this.utils.matcherHint('toFailRequireWith', 'received', 'expected', { isNot: this.isNot });
const expectedText = `Expected pattern: ${this.isNot ? 'not ' : ''}${this.utils.printExpected(match)}`;
const receivedText = `Received string: ${this.utils.printReceived(transactionError?.message ?? '')}`;

// Normalize both expected and received strings to avoid issues from line breaks and extra spaces
const normalizedExpected = normalizeMultiline(typeof match === 'string' ? match : match.toString());
const normalizedReceived = normalizeMultiline(transactionError?.message ?? '');

const expectedText = `Expected pattern: ${this.isNot ? 'not ' : ''}${this.utils.printExpected(normalizedExpected)}`;
const receivedText = `Received string: ${this.utils.printReceived(normalizedReceived)}`;
const message = (): string => `${matcherHint}\n\n${expectedText}\n${receivedText}`;

try {
expect(transactionError?.message ?? '').toMatch(match);
return { message, pass: true };
} catch {
return { message, pass: false };
}
// Check if the normalized expected string is included in the normalized received string
const pass = normalizedReceived.includes(normalizedExpected);

return { message, pass };
}
},
async toFailRequire(
this: MatcherContext,
transaction: Transaction,
): Promise<SyncExpectationResult> {
) {
try {
await transaction.debug();
const message = (): string => 'Contract function did not fail a require statement.';
Expand Down
4 changes: 0 additions & 4 deletions packages/cashscript/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{
"extends": "../../tsconfig.build.json",

"compilerOptions": {
"outDir": "./dist-test",
},

"include": [
"src/**/*",
"test/**/*",
Expand Down
10 changes: 10 additions & 0 deletions packages/cashscript/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
globals: true,
environment: 'node',
root: './test',
testTimeout: 50000, // Set global timeout to 50 seconds
},
});
10 changes: 0 additions & 10 deletions packages/utils/jest.config.js

This file was deleted.

Empty file removed packages/utils/jest.setup.js
Empty file.
9 changes: 4 additions & 5 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
"scripts": {
"build": "yarn clean && yarn compile",
"build:test": "yarn clean:test && yarn compile:test",
"build:test": "yarn build && vitest",
"clean": "rm -rf ./dist",
"clean:test": "rm -rf ./dist-test",
"compile": "tsc -p tsconfig.build.json",
Expand All @@ -37,16 +37,15 @@
"prepare": "yarn build",
"prepublishOnly": "yarn test && yarn lint",
"pretest": "yarn build:test",
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
"test": "vitest"
},
"dependencies": {
"@bitauth/libauth": "^3.0.0"
},
"devDependencies": {
"@jest/globals": "^29.4.1",
"eslint": "^8.54.0",
"jest": "^29.4.1",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"vitest": "^2.1.4"
},
"gitHead": "bf02a4b641d5d03c035d052247a545109c17b708"
}
4 changes: 0 additions & 4 deletions packages/utils/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{
"extends": "../../tsconfig.build.json",

"compilerOptions": {
"outDir": "./dist-test",
},

"include": [
"src/**/*",
"test/**/*",
Expand Down
9 changes: 9 additions & 0 deletions packages/utils/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
globals: true,
environment: 'node',
root: './test',
},
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"cashscript": ["cashscript/src"],
"@cashscript/utils": ["utils/src"],
},
"types": ["vitest/globals"],
},
}
Loading