Add napcat-test package and Vitest setup

Introduces the napcat-test package with initial SHA-1 stream tests, configuration files, and scripts for running tests. Updates root package.json to include test commands and Vitest dependencies, and adds Vitest configuration at the root and package level for test environment setup.
This commit is contained in:
手瓜一十雪 2025-11-15 16:05:09 +08:00
parent 0f033b0ac8
commit ef63812391
7 changed files with 152 additions and 2 deletions

View File

@ -9,16 +9,20 @@
"build:framework": "pnpm --filter napcat-framework run build || exit 1",
"build:webui": "pnpm --filter napcat-webui-frontend run build || exit 1",
"dev:shell": "pnpm --filter napcat-develop run dev || exit 1",
"typecheck": "pnpm -r --if-present run typecheck"
"typecheck": "pnpm -r --if-present run typecheck",
"test": "pnpm --filter napcat-test run test",
"test:ui": "pnpm --filter napcat-test run test:ui"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^16.0.3",
"@vitejs/plugin-react-swc": "^4.2.2",
"@vitest/ui": "^4.0.9",
"inversify": "^7.10.4",
"reflect-metadata": "^0.2.2",
"typescript": "^5.3.0",
"vite": "^6.4.1",
"vite-plugin-cp": "^6.0.3"
"vite-plugin-cp": "^6.0.3",
"vitest": "^4.0.9"
},
"dependencies": {
"express": "^5.0.0",

View File

@ -0,0 +1,3 @@
# NapCat-Test
## 测试方向
测试过程不涉及账号登录

View File

@ -0,0 +1,16 @@
{
"name": "napcat-test",
"version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui"
},
"devDependencies": {
"vitest": "^4.0.9"
},
"dependencies": {
"napcat-core": "workspace:*"
}
}

View File

@ -0,0 +1,87 @@
import { describe, it, expect } from 'vitest';
import crypto from 'crypto';
import { Sha1Stream } from 'napcat-core/packet/utils/crypto/sha1Stream';
describe('Sha1Stream', () => {
it('should compute correct SHA-1 hash for empty string', () => {
const sha1Stream = new Sha1Stream();
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update('').digest();
expect(hash).toEqual(expected);
});
it('should compute correct SHA-1 hash for simple string', () => {
const testData = 'Hello, World!';
const sha1Stream = new Sha1Stream();
sha1Stream.update(Buffer.from(testData));
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update(testData).digest();
expect(hash).toEqual(expected);
});
it('should compute correct SHA-1 hash for binary data', () => {
const testData = Buffer.from([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
const sha1Stream = new Sha1Stream();
sha1Stream.update(testData);
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update(testData).digest();
expect(hash).toEqual(expected);
});
it('should handle multiple update calls', () => {
const part1 = 'Hello';
const part2 = ', World!';
const sha1Stream = new Sha1Stream();
sha1Stream.update(Buffer.from(part1));
sha1Stream.update(Buffer.from(part2));
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update(part1 + part2).digest();
expect(hash).toEqual(expected);
});
it('should handle large data correctly', () => {
const testData = crypto.randomBytes(1024 * 10); // 10KB random data
const sha1Stream = new Sha1Stream();
sha1Stream.update(testData);
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update(testData).digest();
expect(hash).toEqual(expected);
});
it('should produce consistent results for same input', () => {
const testData = 'Consistent test data';
const sha1Stream1 = new Sha1Stream();
sha1Stream1.update(Buffer.from(testData));
const hash1 = sha1Stream1.final();
const sha1Stream2 = new Sha1Stream();
sha1Stream2.update(Buffer.from(testData));
const hash2 = sha1Stream2.final();
expect(hash1).toEqual(hash2);
});
it('should handle edge case with exact block size', () => {
// SHA-1 block size is 64 bytes
const testData = 'a'.repeat(64);
const sha1Stream = new Sha1Stream();
sha1Stream.update(Buffer.from(testData));
const hash = sha1Stream.final();
const expected = crypto.createHash('sha1').update(testData).digest();
expect(hash).toEqual(expected);
});
it('should handle random data correctly', () => {
// Run multiple random tests (reduced from 100000 to 100 for performance)
for (let i = 0; i < 100; i++) {
const randomLength = Math.floor(Math.random() * 1024);
const randomData = crypto.randomBytes(randomLength);
const sha1Stream = new Sha1Stream();
sha1Stream.update(randomData);
const hash = sha1Stream.final();
const expectedDigest = crypto.createHash('sha1').update(randomData).digest();
expect(hash).toEqual(expectedDigest);
}
});
});

View File

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"include": [
"*.ts",
"**/*.ts"
],
"exclude": [
"node_modules",
"dist"
]
}

View File

@ -0,0 +1,14 @@
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';
export default defineConfig({
test: {
environment: 'node',
globals: true,
},
resolve: {
alias: {
'@': resolve(__dirname, '../../'),
},
},
});

15
vitest.config.ts Normal file
View File

@ -0,0 +1,15 @@
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';
export default defineConfig({
test: {
environment: 'node',
globals: true,
include: ['packages/napcat-test/**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
resolve: {
alias: {
'@': resolve(__dirname, 'packages'),
},
},
});