From 2721cb8dee8dca4211af8cf2db984e54e89cafb3 Mon Sep 17 00:00:00 2001 From: HJY <1398145450@qq.com> Date: Thu, 19 Sep 2024 10:39:27 +0800 Subject: [PATCH] feat: add format util unit and add pre-commit unit check (#8427) --- CONTRIBUTING_CN.md | 4 +-- web/.husky/pre-commit | 27 ++++++++++++++++++ web/README.md | 6 +++- web/utils/format.spec.ts | 61 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 web/utils/format.spec.ts diff --git a/CONTRIBUTING_CN.md b/CONTRIBUTING_CN.md index 7cd2bb60eb..310c55090a 100644 --- a/CONTRIBUTING_CN.md +++ b/CONTRIBUTING_CN.md @@ -36,7 +36,7 @@ | 被团队成员标记为高优先级的功能 | 高优先级 | | 在 [community feedback board](https://github.com/langgenius/dify/discussions/categories/feedbacks) 内反馈的常见功能请求 | 中等优先级 | | 非核心功能和小幅改进 | 低优先级 | - | 有价值当不紧急 | 未来功能 | + | 有价值但不紧急 | 未来功能 | ### 其他任何事情(例如 bug 报告、性能优化、拼写错误更正): * 立即开始编码。 @@ -138,7 +138,7 @@ Dify 的后端使用 Python 编写,使用 [Flask](https://flask.palletsproject ├── models // 描述数据模型和 API 响应的形状 ├── public // 如 favicon 等元资源 ├── service // 定义 API 操作的形状 -├── test +├── test ├── types // 函数参数和返回值的描述 └── utils // 共享的实用函数 ``` diff --git a/web/.husky/pre-commit b/web/.husky/pre-commit index 6df8b24b61..d9290e1853 100755 --- a/web/.husky/pre-commit +++ b/web/.husky/pre-commit @@ -51,5 +51,32 @@ if $web_modified; then echo "Running ESLint on web module" cd ./web || exit 1 npx lint-staged + + echo "Running unit tests check" + modified_files=$(git diff --cached --name-only -- utils | grep -v '\.spec\.ts$' || true) + + if [ -n "$modified_files" ]; then + for file in $modified_files; do + test_file="${file%.*}.spec.ts" + echo "Checking for test file: $test_file" + + # check if the test file exists + if [ -f "../$test_file" ]; then + echo "Detected changes in $file, running corresponding unit tests..." + npm run test "../$test_file" + + if [ $? -ne 0 ]; then + echo "Unit tests failed. Please fix the errors before committing." + exit 1 + fi + echo "Unit tests for $file passed." + else + echo "Warning: $file does not have a corresponding test file." + fi + + done + echo "All unit tests for modified web/utils files have passed." + fi + cd ../ fi diff --git a/web/README.md b/web/README.md index 867d822e27..a84ef21007 100644 --- a/web/README.md +++ b/web/README.md @@ -18,6 +18,10 @@ yarn install --frozen-lockfile Then, configure the environment variables. Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Modify the values of these environment variables according to your requirements: +```bash +cp .env.example .env.local +``` + ``` # For production release, change this to PRODUCTION NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT @@ -78,7 +82,7 @@ If your IDE is VSCode, rename `web/.vscode/settings.example.json` to `web/.vscod We start to use [Jest](https://jestjs.io/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) for Unit Testing. -You can create a test file with a suffix of `.spec` beside the file that to be tested. For example, if you want to test a file named `util.ts`. The test file name should be `util.spec.ts`. +You can create a test file with a suffix of `.spec` beside the file that to be tested. For example, if you want to test a file named `util.ts`. The test file name should be `util.spec.ts`. Run test: diff --git a/web/utils/format.spec.ts b/web/utils/format.spec.ts new file mode 100644 index 0000000000..f349efa4e4 --- /dev/null +++ b/web/utils/format.spec.ts @@ -0,0 +1,61 @@ +import { formatFileSize, formatNumber, formatTime } from './format' +describe('formatNumber', () => { + test('should correctly format integers', () => { + expect(formatNumber(1234567)).toBe('1,234,567') + }) + test('should correctly format decimals', () => { + expect(formatNumber(1234567.89)).toBe('1,234,567.89') + }) + test('should correctly handle string input', () => { + expect(formatNumber('1234567')).toBe('1,234,567') + }) + test('should correctly handle zero', () => { + expect(formatNumber(0)).toBe(0) + }) + test('should correctly handle negative numbers', () => { + expect(formatNumber(-1234567)).toBe('-1,234,567') + }) + test('should correctly handle empty input', () => { + expect(formatNumber('')).toBe('') + }) +}) +describe('formatFileSize', () => { + test('should return the input if it is falsy', () => { + expect(formatFileSize(0)).toBe(0) + }) + test('should format bytes correctly', () => { + expect(formatFileSize(500)).toBe('500.00B') + }) + test('should format kilobytes correctly', () => { + expect(formatFileSize(1500)).toBe('1.46KB') + }) + test('should format megabytes correctly', () => { + expect(formatFileSize(1500000)).toBe('1.43MB') + }) + test('should format gigabytes correctly', () => { + expect(formatFileSize(1500000000)).toBe('1.40GB') + }) + test('should format terabytes correctly', () => { + expect(formatFileSize(1500000000000)).toBe('1.36TB') + }) + test('should format petabytes correctly', () => { + expect(formatFileSize(1500000000000000)).toBe('1.33PB') + }) +}) +describe('formatTime', () => { + test('should return the input if it is falsy', () => { + expect(formatTime(0)).toBe(0) + }) + test('should format seconds correctly', () => { + expect(formatTime(30)).toBe('30.00 sec') + }) + test('should format minutes correctly', () => { + expect(formatTime(90)).toBe('1.50 min') + }) + test('should format hours correctly', () => { + expect(formatTime(3600)).toBe('1.00 h') + }) + test('should handle large numbers', () => { + expect(formatTime(7200)).toBe('2.00 h') + }) +})