Skip to content

Commit

Permalink
Migrate pactjs-cli from jest to vitest + msw
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Oct 10, 2023
1 parent 6cf0c27 commit afe12dd
Show file tree
Hide file tree
Showing 9 changed files with 454 additions and 92 deletions.
1 change: 1 addition & 0 deletions packages/tools/pactjs-cli/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ require('@rushstack/eslint-config/patch/modern-module-resolution');
module.exports = {
extends: ['@kadena-dev/eslint-config/profile/lib'],
parserOptions: { tsconfigRootDir: __dirname },
ignorePatterns: ['vitest.config.ts'],
};
6 changes: 0 additions & 6 deletions packages/tools/pactjs-cli/jest.config.cjs

This file was deleted.

8 changes: 4 additions & 4 deletions packages/tools/pactjs-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"lint:fmt": "prettier . --cache --check",
"lint:pkg": "lint-package",
"lint:src": "eslint src --ext .js,.ts",
"test": "jest"
"test": "vitest"
},
"dependencies": {
"@kadena/pactjs-generator": "workspace:*",
Expand All @@ -46,14 +46,14 @@
"@microsoft/api-extractor": "^7.37.0",
"@rushstack/eslint-config": "~3.3.0",
"@types/debug": "~4.1.7",
"@types/jest": "^29.5.3",
"@types/mkdirp": "~1.0.2",
"@types/node": "^18.17.14",
"@types/rimraf": "~3.0.2",
"eslint": "^8.45.0",
"jest": "^29.7.0",
"msw": "^1.3.2",
"prettier": "~3.0.0",
"prettier-plugin-packagejson": "^2.4.5",
"typescript": "5.2.2"
"typescript": "5.2.2",
"vitest": "^0.34.6"
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
jest.mock('fs');
jest.mock('../../utils/retrieveContractFromChain');

import { retrieveContractFromChain } from '../../utils/retrieveContractFromChain';
import * as RCFC from '../../utils/retrieveContractFromChain';
import { retrieveContract } from '../retrieve-contract';

import { Command } from 'commander';
import { writeFileSync } from 'fs';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import path from 'path';

const mockedWriteFileSync = writeFileSync as jest.MockedFunction<
typeof writeFileSync
>;
mockedWriteFileSync.mockImplementation(
mockedWriteFileSync as jest.MockedFunction<typeof writeFileSync>,
);
const restHandlers = [
rest.post(
'https://api.chainweb.com/chainweb/0.0/mainnet01/chain/8/pact/api/v1/local',
(req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({ result: { data: { code: 'some pactCode' } } }),
);
},
),
];

const mockedRetrieveContractFromChain =
retrieveContractFromChain as jest.MockedFunction<
typeof retrieveContractFromChain
>;
mockedRetrieveContractFromChain.mockImplementation(
mockedRetrieveContractFromChain as jest.MockedFunction<
typeof retrieveContractFromChain
>,
);

import { retrieveContract } from '../retrieve-contract';
vi.mock('fs', () => ({ writeFileSync: vi.fn() }));

import { Command } from 'commander';
const server = setupServer(...restHandlers);
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

const createAndRunProgram = async (): Promise<void> => {
const program = new Command('retrieve-contract');
Expand All @@ -41,31 +40,26 @@ const createAndRunProgram = async (): Promise<void> => {
};

describe('retrieve-contract', () => {
afterAll(() => {
jest.restoreAllMocks();
});

it('calls retrieveContractFromChain', async () => {
mockedRetrieveContractFromChain.mockResolvedValue('some code');
mockedWriteFileSync.mockReturnValue();
const spy = vi.spyOn(RCFC, 'retrieveContractFromChain');

await createAndRunProgram();

expect(mockedRetrieveContractFromChain.mock.calls[0]).toEqual([
expect(spy).toHaveBeenCalledWith(
'free.crankk01',
'https://api.chainweb.com/chainweb/0.0/mainnet01/chain/8/pact',
0,
'mainnet',
]);
);
});

it('writes the contract to file', async () => {
mockedRetrieveContractFromChain.mockResolvedValue('some code');
mockedWriteFileSync.mockReturnValue();
await createAndRunProgram();

expect(mockedWriteFileSync.mock.calls[0][0]).toContain(
path.join('some', 'path', 'to', 'contract.pact'),
expect(writeFileSync).toBeCalledWith(
path.resolve('some', 'path', 'to', 'contract.pact'),
'some pactCode',
'utf8',
);
expect(mockedWriteFileSync.mock.calls[0][1]).toEqual('some code');
});
});
40 changes: 18 additions & 22 deletions packages/tools/pactjs-cli/src/utils/tests/callLocal.test.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
jest.mock('cross-fetch');
import { callLocal } from '../callLocal';

import fetch, { Response } from 'cross-fetch';
import { rest } from 'msw';
import { setupServer } from 'msw/node';

const mockedFetch = fetch as jest.MockedFunction<typeof fetch>;
const restHandlers = [
rest.post('https://json-api.chainweb.com/api/v1/local', (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ json: 'some json' }));
}),
rest.post('https://text-api.chainweb.com/api/v1/local', (req, res, ctx) => {
return res(ctx.status(200), ctx.text('some text'));
}),
];

describe('callLocal', () => {
it('returns the correct jsonResponse on success', async () => {
const response = new Response();

response.json = jest.fn().mockReturnValue({ json: 'some json' });
response.text = jest.fn().mockReturnValue('some text');
response.clone = jest.fn().mockImplementation(() => response);
const server = setupServer(...restHandlers);

mockedFetch.mockResolvedValue(response);

const result = await callLocal('https://api.chainweb.com', 'body');
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('callLocal', () => {
it('returns the correct jsonResponse on success', async () => {
const result = await callLocal('https://json-api.chainweb.com', 'body');
expect(result.jsonResponse).toEqual({ json: 'some json' });
});

it('returns the correct textResponse on success', async () => {
const response = new Response();

response.text = jest.fn().mockReturnValue('some text');
response.clone = jest.fn().mockImplementation(() => response);

mockedFetch.mockResolvedValue(response);

const result = await callLocal('https://api.chainweb.com', 'body');

const result = await callLocal('https://text-api.chainweb.com', 'body');
expect(result.textResponse).toBe('some text');
});
});
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
jest.mock('../callLocal.ts');

import { callLocal } from '../callLocal';
import { retrieveContractFromChain } from '../retrieveContractFromChain';

const mockedCallLocal = callLocal as jest.MockedFunction<typeof callLocal>;
import { rest } from 'msw';
import { setupServer } from 'msw/node';

describe('retrieveContractFromChain', () => {
afterAll(() => {
mockedCallLocal.mockRestore();
});
const restHandlers = [
rest.post(
'https://api.chainweb.com/chainweb/0.0/mainnet01/chain/8/pact/api/v1/local',
(req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({ result: { data: { code: 'some pactCode' } } }),
);
},
),
];

it('returns the pactCode on success', async () => {
mockedCallLocal.mockResolvedValue({
textResponse: 'some pactText',
jsonResponse: { result: { data: { code: 'some pactCode' } } },
response: { status: 200 } as Response,
});
const server = setupServer(...restHandlers);
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('retrieveContractFromChain', () => {
it('returns the pactCode on success', async () => {
const result = await retrieveContractFromChain(
'free.crankk01',
'https://api.chainweb.com/chainweb/0.0/mainnet01/chain/8/pact',
Expand Down
2 changes: 1 addition & 1 deletion packages/tools/pactjs-cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"extends": "./node_modules/@kadena-dev/heft-rig/tsconfig-base.json",
"compilerOptions": {
"resolveJsonModule": true,
"types": ["jest", "node"]
"types": ["vitest/globals", "node"]
}
}
8 changes: 8 additions & 0 deletions packages/tools/pactjs-cli/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
include: ['src/**/*.test.ts'],
globals: true,
},
});
Loading

0 comments on commit afe12dd

Please sign in to comment.