15 changed files with 7461 additions and 8 deletions
@ -0,0 +1,6 @@ |
|||
module.exports = function (api) { |
|||
api.cache(true); |
|||
return { |
|||
presets: ['babel-preset-expo'], |
|||
}; |
|||
}; |
|||
@ -0,0 +1,9 @@ |
|||
module.exports = { |
|||
preset: 'jest-expo', |
|||
transformIgnorePatterns: [ |
|||
'node_modules/(?!((jest-)?react-native|@react-native|expo(nent)?|@expo(nent)?|expo-|@expo-|@expo/|@react-navigation|react-native-svg|@react-native-async-storage))', |
|||
], |
|||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], |
|||
testMatch: ['**/__tests__/**/*.(test|spec).(ts|tsx|js)'], |
|||
collectCoverageFrom: ['src/**/*.{ts,tsx}', 'app/**/*.{ts,tsx}'], |
|||
}; |
|||
@ -0,0 +1,13 @@ |
|||
import { colors } from '../theme'; |
|||
|
|||
describe('设计令牌 colors', () => { |
|||
it('主色为品牌蓝 #2C83FD', () => { |
|||
expect(colors.primary).toBe('#2C83FD'); |
|||
}); |
|||
it('success 为唯一绿色 token #10B981', () => { |
|||
expect(colors.success).toBe('#10B981'); |
|||
}); |
|||
it('阴影色已收敛到 token,不再硬编码 #000', () => { |
|||
expect(colors.shadow).toBe('#000000'); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,28 @@ |
|||
import { JOB_LEVEL_LABEL, SALARY_RANGES, MAX_RETRY_COUNT } from '../constants'; |
|||
|
|||
describe('JOB_LEVEL_LABEL', () => { |
|||
it('岗位等级映射中文标签', () => { |
|||
expect(JOB_LEVEL_LABEL.excellent).toBe('优秀'); |
|||
expect(JOB_LEVEL_LABEL.good).toBe('良好'); |
|||
expect(JOB_LEVEL_LABEL.medium).toBe('中等'); |
|||
}); |
|||
}); |
|||
|
|||
describe('SALARY_RANGES', () => { |
|||
it('首项为不限(max 为 Infinity)', () => { |
|||
expect(SALARY_RANGES[0]).toEqual({ |
|||
label: '不限', |
|||
min: 0, |
|||
max: Number.POSITIVE_INFINITY, |
|||
}); |
|||
}); |
|||
it('包含 10-20K 区间', () => { |
|||
expect(SALARY_RANGES).toContainEqual({ label: '10-20K', min: 10, max: 20 }); |
|||
}); |
|||
}); |
|||
|
|||
describe('MAX_RETRY_COUNT', () => { |
|||
it('请求失败自动重试 3 次', () => { |
|||
expect(MAX_RETRY_COUNT).toBe(3); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,35 @@ |
|||
import { computeSalaryResult } from '../api/api'; |
|||
|
|||
describe('computeSalaryResult(薪资计算器业务规则)', () => { |
|||
it('低薪且五险一金+起征点覆盖时个税为 0', () => { |
|||
const input = { |
|||
monthlyGross: 5000, |
|||
bonusMonths: 0, |
|||
socialBase: 5000, |
|||
providentFundRate: 0.12, |
|||
specialDeduction: 0, |
|||
}; |
|||
const r = computeSalaryResult(input as any); |
|||
// monthlySocial = 5000*(0.08+0.02+0.005+0.12) = 1125
|
|||
expect(r.monthlySocial).toBe(1125); |
|||
// taxable = max(0, 5000-1125-5000) = 0 → 个税 0
|
|||
expect(r.monthlyTax).toBe(0); |
|||
// monthlyNet = 5000 - 1125 = 3875
|
|||
expect(r.monthlyNet).toBe(3875); |
|||
expect(r.annualGross).toBe(60000); |
|||
expect(r.annualNet).toBe(46500); |
|||
}); |
|||
|
|||
it('含年终奖时月度税前合计摊入', () => { |
|||
const input = { |
|||
monthlyGross: 10000, |
|||
bonusMonths: 2, |
|||
socialBase: 10000, |
|||
providentFundRate: 0.12, |
|||
specialDeduction: 0, |
|||
}; |
|||
const r = computeSalaryResult(input as any); |
|||
// monthlyTotal = 10000 * (1 + 2/12) = 11666.67 → 四舍五入 11667
|
|||
expect(r.monthlyTotal).toBe(11667); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,31 @@ |
|||
import { formatThousands, formatCurrency, formatViews } from '../utils'; |
|||
|
|||
describe('formatThousands', () => { |
|||
it('千分位格式化 12846 → "12,846"', () => { |
|||
expect(formatThousands(12846)).toBe('12,846'); |
|||
}); |
|||
it('不足千位原样返回', () => { |
|||
expect(formatThousands(123)).toBe('123'); |
|||
}); |
|||
}); |
|||
|
|||
describe('formatCurrency', () => { |
|||
it('默认 0 位小数 30000 → "30,000"', () => { |
|||
expect(formatCurrency(30000)).toBe('30,000'); |
|||
}); |
|||
it('指定 2 位小数补齐', () => { |
|||
expect(formatCurrency(12345.6, 2)).toBe('12,345.60'); |
|||
}); |
|||
}); |
|||
|
|||
describe('formatViews', () => { |
|||
it('≥1万 → 万单位', () => { |
|||
expect(formatViews(23000)).toBe('2.3万'); |
|||
}); |
|||
it('整万去掉 .0', () => { |
|||
expect(formatViews(20000)).toBe('2万'); |
|||
}); |
|||
it('<1万返回原数字', () => { |
|||
expect(formatViews(8500)).toBe('8500'); |
|||
}); |
|||
}); |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue