Skip to content

Commit 4d588df

Browse files
committed
add jest
1 parent 4c589d6 commit 4d588df

21 files changed

+342
-11
lines changed

jest.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'jsdom',
4+
moduleNameMapper: {
5+
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
6+
},
7+
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
8+
};

jest.setup.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import '@testing-library/jest-dom';
2+
3+
Object.defineProperty(window, 'matchMedia', {
4+
writable: true,
5+
value: jest.fn().mockImplementation(query => ({
6+
matches: false,
7+
media: query,
8+
onchange: null,
9+
addListener: jest.fn(), // 旧版 API
10+
removeListener: jest.fn(), // 旧版 API
11+
addEventListener: jest.fn(), // 新版 API
12+
removeEventListener: jest.fn(), // 新版 API
13+
dispatchEvent: jest.fn(),
14+
})),
15+
});

jest/Form.test.tsx

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import '@testing-library/jest-dom';
2+
import React,{act} from 'react';
3+
import {fireEvent, render, screen} from '@testing-library/react';
4+
import MyForm from "./MyForm";
5+
6+
test('Form set/get Value Test', () => {
7+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
8+
9+
render(<MyForm />);
10+
11+
const setValue = screen.getByRole('button', {name: 'setValue'});
12+
expect(setValue).toBeInTheDocument();
13+
14+
act(() => {
15+
fireEvent.click(setValue);
16+
});
17+
18+
const getValue = screen.getByRole('button', {name: 'getValue'});
19+
expect(getValue).toBeInTheDocument();
20+
21+
act(() => {
22+
fireEvent.click(getValue);
23+
});
24+
25+
expect(consoleSpy).toHaveBeenCalledWith('test');
26+
consoleSpy.mockRestore();
27+
});
28+
29+
test('Form validate Test 1 ', async () => {
30+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
31+
32+
render(<MyForm />);
33+
34+
const setValue = screen.getByRole('button', {name: 'setValue'});
35+
expect(setValue).toBeInTheDocument();
36+
37+
await act(async () => {
38+
fireEvent.click(setValue);
39+
});
40+
41+
const validate = screen.getByRole('button', {name: 'validate'});
42+
expect(validate).toBeInTheDocument();
43+
44+
await act(async () => {
45+
fireEvent.click(validate);
46+
});
47+
48+
expect(consoleSpy).toHaveBeenCalledWith("true");
49+
consoleSpy.mockRestore();
50+
});
51+
52+
test('Form validate Test 2 ', async () => {
53+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
54+
55+
render(<MyForm />);
56+
57+
const validate = screen.getByRole('button', {name: 'validate'});
58+
expect(validate).toBeInTheDocument();
59+
60+
await act(async () => {
61+
fireEvent.click(validate);
62+
});
63+
64+
expect(consoleSpy).toHaveBeenCalledWith("false");
65+
consoleSpy.mockRestore();
66+
});
67+
68+
69+
test('Form getFieldProps Test', async () => {
70+
71+
render(<MyForm />);
72+
73+
const getTest = screen.getByRole('button', {name: 'getTest'});
74+
expect(getTest).toBeInTheDocument();
75+
76+
await act(async () => {
77+
fireEvent.click(getTest);
78+
});
79+
80+
});
81+
82+
83+
test('Form submit Test', async () => {
84+
85+
render(<MyForm />);
86+
87+
const submit = screen.getByRole('button', {name: 'submit'});
88+
expect(submit).toBeInTheDocument();
89+
90+
await act(async () => {
91+
fireEvent.click(submit);
92+
});
93+
94+
});

jest/MyForm.tsx

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {Form, FormInput} from "../src";
2+
import React from "react";
3+
import {ValidateUtils} from "@codingapi/ui-framework";
4+
5+
const MyForm = () => {
6+
7+
const form = Form.useForm();
8+
9+
return (
10+
<div>
11+
<Form
12+
form={form}
13+
onFinish={async (values)=>{
14+
console.log(values);
15+
}}
16+
>
17+
<FormInput
18+
name={"test"}
19+
label={"test"}
20+
validateFunction={ValidateUtils.validateNotEmpty}
21+
/>
22+
</Form>
23+
24+
<button
25+
role={"button"}
26+
aria-label={"getValue"}
27+
onClick={() => {
28+
const value = form.getFieldValue('test');
29+
console.log(value);
30+
}}
31+
>get value</button>
32+
33+
<button
34+
role={"button"}
35+
aria-label={"setValue"}
36+
onClick={() => {
37+
form.setFieldValue('test', 'test');
38+
}}
39+
>set value</button>
40+
41+
42+
<button
43+
role={"button"}
44+
aria-label={"validate"}
45+
onClick={async () => {
46+
const result = await form.validate();
47+
console.log(result ? "true" : "false");
48+
}}
49+
>validate</button>
50+
51+
52+
<button
53+
role={"button"}
54+
aria-label={"getTest"}
55+
onClick={() => {
56+
const field = form.getFieldProps('test');
57+
console.log(field);
58+
}}
59+
>getTest</button>
60+
61+
62+
<button
63+
role={"button"}
64+
aria-label={"submit"}
65+
onClick={async () => {
66+
await form.submit();
67+
}}
68+
>submit</button>
69+
</div>
70+
)
71+
}
72+
73+
export default MyForm;

jest/map.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import '@testing-library/jest-dom';
2+
3+
4+
test("map", () => {
5+
const map = new Map();
6+
map.set('key', 'value');
7+
expect(map.get('key')).toBe('value');
8+
expect(map.has('key')).toBe(true);
9+
expect(map.size).toBe(1);
10+
map.delete('key');
11+
expect(map.has('key')).toBe(false);
12+
expect(map.size).toBe(0);
13+
})

package.json

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codingapi/form-mobile",
3-
"version": "0.0.3",
3+
"version": "0.0.16",
44
"description": "A UI Framework built with React and TypeScript",
55
"keywords": [
66
"ui",
@@ -35,13 +35,15 @@
3535
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
3636
},
3737
"dependencies": {
38-
"@codingapi/ui-framework": "^0.0.12",
38+
"@codingapi/ui-framework": "^0.0.17",
3939
"antd-mobile": "^5.39.0"
4040
},
4141
"scripts": {
4242
"clean": "rm -rf dist",
4343
"build": "yarn clean && rollup -c --bundleConfigAsCjs",
44-
"push": "yarn build && yarn publish --access public"
44+
"push": "yarn build && yarn publish --access public",
45+
"test": "jest",
46+
"test:watch": "jest --watch"
4547
},
4648
"eslintConfig": {
4749
"extends": [
@@ -64,15 +66,24 @@
6466
"@rollup/plugin-alias": "^5.1.1",
6567
"@rollup/plugin-commonjs": "^25.0.7",
6668
"@rollup/plugin-node-resolve": "^15.2.3",
69+
"@testing-library/dom": "^10.4.0",
70+
"@testing-library/jest-dom": "^6.6.3",
71+
"@testing-library/react": "^16.3.0",
72+
"@types/jest": "^29.5.14",
6773
"@types/react": "^18.3.5",
6874
"@types/react-dom": "^18.3.0",
75+
"babel-jest": "^29.7.0",
76+
"identity-obj-proxy": "^3.0.0",
77+
"jest": "^29.7.0",
78+
"jest-environment-jsdom": "^29.7.0",
6979
"postcss": "^8.4.32",
7080
"rollup": "^4.9.1",
7181
"rollup-plugin-delete": "^2.0.0",
7282
"rollup-plugin-peer-deps-external": "^2.2.4",
7383
"rollup-plugin-postcss": "^4.0.2",
7484
"rollup-plugin-typescript2": "^0.36.0",
7585
"sass": "^1.87.0",
86+
"ts-jest": "^29.3.2",
7687
"typescript": "^5.6.2"
7788
}
7889
}

src/Form/captcha.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ export const FormCaptcha: React.FC<FormItemProps> = (props) => {
1818
}
1919

2020
useEffect(() => {
21+
formContext?.addFormField(
22+
{
23+
type: 'captcha',
24+
props: props
25+
}
26+
);
2127
reloadCaptcha();
2228
}, [])
2329

src/Form/cascader.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ export const FormCascader: React.FC<FormItemProps> = (props) => {
3838
}
3939

4040
useEffect(() => {
41+
formContext?.addFormField(
42+
{
43+
type: 'cascader',
44+
props: props
45+
}
46+
);
4147
reloadOptions();
4248
}, []);
4349

src/Form/checkbox.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export const FormCheckbox: React.FC<FormItemProps> = (props) => {
3434
}
3535

3636
useEffect(() => {
37+
formContext?.addFormField(
38+
{
39+
type: 'checkbox',
40+
props: props
41+
}
42+
);
3743
reloadOptions();
3844
}, []);
3945

src/Form/date.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, {useEffect} from "react";
22
import {FormItemProps} from "@codingapi/ui-framework";
33
import {DatePicker, Form} from "antd-mobile";
44
import {RightOutline} from "antd-mobile-icons";
@@ -33,6 +33,15 @@ export const FormDate: React.FC<FormItemProps> = (props) => {
3333
const precision = props.datePrecision || "day";
3434
const [visible, setVisible] = React.useState(false);
3535

36+
useEffect(() => {
37+
formContext?.addFormField(
38+
{
39+
type: 'date',
40+
props: props
41+
}
42+
);
43+
}, []);
44+
3645
return (
3746
<Form.Item
3847
name={props.name}

src/Form/input.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, {useEffect} from "react";
22
import {FormItemProps} from "@codingapi/ui-framework";
33
import {Form, Input} from "antd-mobile";
44
import {formFieldInit} from "./common";
@@ -9,6 +9,15 @@ export const FormInput: React.FC<FormItemProps> = (props) => {
99
const inputType = props.inputType || "text";
1010
const {formContext, rules} = formFieldInit(props);
1111

12+
useEffect(() => {
13+
formContext?.addFormField(
14+
{
15+
type: 'input',
16+
props: props
17+
}
18+
);
19+
}, []);
20+
1221
return (
1322
<Form.Item
1423
name={props.name}

src/Form/password.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, {useEffect} from "react";
22
import {FormInstance, FormItemProps} from "@codingapi/ui-framework";
33
import {Form, Input} from "antd-mobile";
44
import {EyeInvisibleOutline, EyeOutline} from "antd-mobile-icons";
@@ -40,6 +40,15 @@ export const FormPassword: React.FC<FormItemProps> = (props) => {
4040

4141
const {formContext, rules} = formFieldInit(props);
4242

43+
useEffect(() => {
44+
formContext?.addFormField(
45+
{
46+
type: 'password',
47+
props: props
48+
}
49+
);
50+
}, []);
51+
4352
return (
4453
<Form.Item
4554
name={props.name}

src/Form/radio.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export const FormRadio: React.FC<FormItemProps> = (props) => {
2020
}
2121

2222
useEffect(() => {
23+
formContext?.addFormField(
24+
{
25+
type: 'radio',
26+
props: props
27+
}
28+
);
2329
reloadOptions();
2430
}, []);
2531

0 commit comments

Comments
 (0)