Skip to content

Commit

Permalink
Merge pull request #212 from ar-io/PE-6689-remove-jest
Browse files Browse the repository at this point in the history
chore(test): remove jest and use native node test runner
  • Loading branch information
dtfiedler authored Sep 25, 2024
2 parents 3379c3f + 3e7915e commit 515e76a
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 1,545 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"root": true,
"plugins": ["@typescript-eslint", "jest", "prettier", "header"],
"plugins": ["@typescript-eslint", "prettier", "header"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ jobs:
- run: yarn ${{ matrix.command }}

test:
strategy:
matrix:
suite: [unit, web, esm, cjs]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -48,16 +51,22 @@ jobs:
run: yarn --immutable --immutable-cache

- name: Run tests
run: yarn test
run: yarn test:${{ matrix.suite }}

- name: Upload coverage
if: matrix.suite == 'unit'
uses: codecov/codecov-action@v4.0.1
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

notify:
needs: [build, test]
if: success()
runs-on: ubuntu-latest
steps:
- name: Send Slack notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_TITLE: ${{ job.status == 'success' && 'Build / E2E tests succeeded!' || 'Build / E2E tests failed!' }}
SLACK_COLOR: ${{ job.status == 'success' && 'good' || 'danger' }}
SLACK_TITLE: 'Build / E2E tests succeeded!'
SLACK_COLOR: 'good'
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
20 changes: 0 additions & 20 deletions jest.config.mjs

This file was deleted.

16 changes: 6 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@
"format": "prettier --check .",
"format:fix": "prettier --write .",
"test": "yarn test:unit && yarn test:e2e",
"test:cjs": "cd ./tests/e2e/cjs && yarn && yarn test",
"test:esm": "cd ./tests/e2e/esm && yarn && yarn test",
"test:web": "cd ./tests/e2e/web && yarn && yarn test",
"test:unit": "jest --config=jest.config.mjs",
"test:cjs": "yarn test:link && cd ./tests/e2e/cjs && yarn && yarn test",
"test:esm": "yarn test:link && cd ./tests/e2e/esm && yarn && yarn test",
"test:web": "yarn test:link && cd ./tests/e2e/web && yarn && yarn test",
"test:unit": "NODE_OPTIONS=\"--import=./register.mjs\" node --test tests/unit/**.test.ts",
"test:link": "yarn build && yarn link",
"test:e2e": "yarn test:link && yarn test:cjs && yarn test:esm && yarn test:web",
"test:e2e": "yarn test:cjs && yarn test:esm && yarn test:web",
"prepare": "husky install",
"example:esm": "cd examples/esm && yarn && node index.mjs",
"example:cjs": "yarn test:link && cd examples/cjs && yarn && node index.cjs",
Expand All @@ -86,7 +86,6 @@
"@semantic-release/git": "^10.0.1",
"@semantic-release/npm": "^11.0.3",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.12",
"@types/sinon": "^10.0.15",
"@typescript-eslint/eslint-plugin": "^5.62.0",
Expand All @@ -101,22 +100,19 @@
"eslint-config-standard-with-typescript": "^37.0.0",
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.28.0",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
"http-server": "^14.1.1",
"husky": "^8.0.3",
"jest": "^29.7.0",
"lint-staged": "^15.2.2",
"markdown-toc-gen": "^1.0.1",
"prettier": "^3.0.2",
"rimraf": "^5.0.1",
"semantic-release": "^21.0.7",
"sinon": "^15.2.0",
"testcontainers": "^10.13.1",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.1",
"ts-node": "^10.9.2",
"typescript": "^5.1.6",
"vite-plugin-node-polyfills": "^0.22.0"
},
Expand Down
4 changes: 4 additions & 0 deletions register.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';

register('ts-node/esm', pathToFileURL('./'));
5 changes: 3 additions & 2 deletions tests/e2e/web/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@testing-library/jest-dom';
import { act, render, screen, waitFor } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import { act } from 'react';
import { DockerComposeEnvironment, Wait } from 'testcontainers';
import { beforeAll, describe, expect, it } from 'vitest';

Expand All @@ -17,7 +18,7 @@ describe('ESM browser validation', () => {
.withBuild()
.withWaitStrategy('ao-cu-1', Wait.forHttp('/', 6363))
.up(['ao-cu']);
});
}, 120_000);
it('should load the app and SDK', async () => {
await act(async () => render(<App />));

Expand Down
61 changes: 32 additions & 29 deletions tests/e2e/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,38 @@ function App() {
const [registryLoaded, setRegistryLoaded] = useState<boolean>(false);

useEffect(() => {
io.getInfo()
.then((state: any) => {
setContract(`\`\`\`json\n${JSON.stringify(state, null, 2)}`);
setIoContractSuccess(true);
})
.catch((error: any) => {
console.error(error);
setIoContractSuccess(false);
setContract('Error loading contract state');
})
.finally(() => {
setLoaded(true);
});
antRegistry
.accessControlList({
address: ANT_REGISTRY_ID,
})
.then((affiliatedAnts: { Owned: string[]; Controlled: string[] }) => {
setAnts(`\`\`\`json\n${JSON.stringify(affiliatedAnts, null, 2)}`);
setAntRegistrySuccess(true);
})
.catch((error: any) => {
console.error(error);
setAntRegistrySuccess(false);
setAnts('Error loading affiliated ants');
})
.finally(() => {
setRegistryLoaded(true);
});
Promise.all([
io
.getInfo()
.then((state: any) => {
setContract(`\`\`\`json\n${JSON.stringify(state, null, 2)}`);
setIoContractSuccess(true);
})
.catch((error: any) => {
console.error(error);
setIoContractSuccess(false);
setContract('Error loading contract state');
})
.finally(() => {
setLoaded(true);
}),
antRegistry
.accessControlList({
address: ANT_REGISTRY_ID,
})
.then((affiliatedAnts: { Owned: string[]; Controlled: string[] }) => {
setAnts(`\`\`\`json\n${JSON.stringify(affiliatedAnts, null, 2)}`);
setAntRegistrySuccess(true);
})
.catch((error: any) => {
console.error(error);
setAntRegistrySuccess(false);
setAnts('Error loading affiliated ants');
})
.finally(() => {
setRegistryLoaded(true);
}),
]);
}, []);

return (
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/ant.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import assert from 'node:assert';
import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';

import { isAoANTState } from '../../src/utils/ao';
import { isAoANTState } from '../../src/utils/ao.js';

const testAoANTState = {
Name: 'TestToken',
Expand Down
94 changes: 64 additions & 30 deletions tests/unit/b64.test.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,68 @@
import { fromB64Url, toB64Url } from '../../src/utils/base64';
import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';

describe('b64utils', () => {
it.each([
'hello+_world_+',
'hello/_world/_',
'', // empty string
'hello', // single character
'hello123456', // alphanumeric string
'123456', // numeric string
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/', // all base64 characters
'aGVsbG8=',
])(
'should properly convert a buffer to base64url string',
async (str: string) => {
const input = Buffer.from(str, 'base64');
const expected = input.toString('base64url');
expect(toB64Url(input)).toEqual(expected);
},
);
import { fromB64Url, toB64Url } from '../../src/utils/base64.js';

it.each([
'aGVsbG8', // missing padding character
'YQ==', // single character
'aGVsbG8gMTIzNDU2', // alphanumeric string
'MTIzNDU2', // numeric string
'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotLUVy', // all base64url characters
'', // empty string
])('should properly convert a base64 string to a buffer', async (str) => {
const b64url = Buffer.from(str).toString('base64url');
const expected = Buffer.from(b64url, 'base64url');
expect(fromB64Url(b64url)).toEqual(expected);
describe('b64utils', () => {
it('should convert various strings to base64url and back', () => {
const testStrings = [
'Hello, World!',
'Test123!@#',
'Base64URLEncoding',
'Special_Chars+/',
'',
'A',
'1234567890',
];
for (const str of testStrings) {
const encoded = toB64Url(Buffer.from(str));
const decoded = Buffer.from(fromB64Url(encoded)).toString();
assert.strictEqual(decoded, str, `Failed for string: ${str}`);
}
});
it('should convert various buffers to base64url and back', () => {
const testBuffers = [
Buffer.from('Hello, World!'),
Buffer.from([0, 1, 2, 3, 4, 5]),
Buffer.from('Test123!@#'),
Buffer.from('Base64URLEncoding'),
Buffer.from('Special_Chars+/'),
Buffer.alloc(0),
Buffer.from('A'),
Buffer.from('1234567890'),
];
for (const buf of testBuffers) {
const encoded = toB64Url(buf);
const decoded = fromB64Url(encoded);
assert.deepStrictEqual(
decoded,
buf,
`Failed for buffer: ${buf.toString()}`,
);
}
});
it('should handle edge cases for base64url conversion', () => {
const edgeCases = [
'',
'A',
'AA',
'AAA',
'====',
'===',
'==',
'=',
'A===',
'AA==',
'AAA=',
];
for (const testCase of edgeCases) {
const encoded = toB64Url(Buffer.from(testCase));
const decoded = Buffer.from(fromB64Url(encoded)).toString();
assert.strictEqual(
decoded,
testCase,
`Failed for edge case: ${testCase}`,
);
}
});
});
Loading

0 comments on commit 515e76a

Please sign in to comment.