Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/rc-form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import arrayTreeFilter from 'array-tree-filter';
import Form, { Field } from 'rc-field-form';
import Form, { Field } from '@rc-component/form';
import '../assets/index.less';
import type { CascaderProps } from '../src';
import Cascader from '../src';
Expand Down
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
module.exports = {
setupFiles: ['./tests/setup.js'],
snapshotSerializers: [require.resolve('enzyme-to-json/serializer')],
};
24 changes: 10 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,25 @@
"coverage": "father test --coverage",
"tsc": "bunx tsc --noEmit",
"deploy": "UMI_ENV=gh npm run build && gh-pages -d dist",
"lint": "eslint src/ examples/ --ext .tsx,.ts,.jsx,.jsx",
"lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.jsx",
"now-build": "npm run build",
"prepublishOnly": "npm run compile && rc-np",
"lint:tsc": "tsc -p tsconfig.json --noEmit",
"start": "dumi dev",
"test": "rc-test"
},
"dependencies": {
"@rc-component/select": "~1.2.0",
"@rc-component/tree": "~1.0.0",
"@rc-component/util": "^1.3.0",
"@rc-component/select": "~1.3.0",
"@rc-component/tree": "~1.1.0",
"@rc-component/util": "^1.4.0",
"clsx": "^2.1.1"
},
"devDependencies": {
"@rc-component/father-plugin": "^2.0.2",
"@rc-component/form": "^1.4.0",
"@rc-component/np": "^1.0.3",
"@rc-component/trigger": "^3.0.0",
"@testing-library/react": "^12.1.5",
"@types/enzyme": "^3.1.15",
"@testing-library/react": "^16.3.0",
"@types/jest": "^29.4.0",
"@types/node": "^24.5.2",
"@types/react": "^19.0.0",
Expand All @@ -65,9 +65,6 @@
"core-js": "^3.40.0",
"cross-env": "^7.0.0",
"dumi": "^2.1.10",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.15.6",
"enzyme-to-json": "^3.2.1",
"eslint": "^8.54.0",
"eslint-plugin-jest": "^28.8.3",
"eslint-plugin-unicorn": "^56.0.1",
Expand All @@ -76,14 +73,13 @@
"glob": "^7.1.6",
"less": "^4.2.0",
"prettier": "^3.1.0",
"rc-field-form": "^1.44.0",
"rc-test": "^7.1.2",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"typescript": "^5.3.2"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
Comment on lines +82 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Bumping the peerDependencies for react and react-dom to >=18.0.0 is a significant breaking change. However, the devDependencies in this project are still using React 16 ("react": "^16.0.0", "react-dom": "^16.0.0"). This means the project's tests are running against a version of React that no longer satisfies the new peer dependency requirement.

To ensure compatibility, the library must be tested against the versions of React it claims to support. Please update the devDependencies to use React 18 and adjust the testing infrastructure accordingly. For example, enzyme-adapter-react-16 is not compatible with React 18 and will need to be replaced or updated.

}
}
7 changes: 6 additions & 1 deletion src/OptionList/useKeyboard.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { RefOptionListProps } from '@rc-component/select/lib/OptionList';
import KeyCode from '@rc-component/util/lib/KeyCode';
import * as React from 'react';
import type { DefaultOptionType, InternalFieldNames, LegacyKey, SingleValueType } from '../Cascader';
import type {
DefaultOptionType,
InternalFieldNames,
LegacyKey,
SingleValueType,
} from '../Cascader';
import { SEARCH_MARK } from '../hooks/useSearchOptions';
import { getFullPathKeys, toPathKey } from '../utils/commonUtil';

Expand Down
8 changes: 4 additions & 4 deletions tests/__snapshots__/search.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Cascader.Search should correct render Cascader with same field name of label and value 1`] = `
[
<div>
<div
class="rc-cascader rc-cascader-single rc-cascader-open rc-cascader-show-search"
>
Expand All @@ -26,7 +26,7 @@ exports[`Cascader.Search should correct render Cascader with same field name of
value="z"
/>
</div>
</div>,
</div>
<div
class="rc-cascader-dropdown rc-cascader-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
Expand Down Expand Up @@ -68,6 +68,6 @@ exports[`Cascader.Search should correct render Cascader with same field name of
</ul>
</div>
</div>
</div>,
]
</div>
</div>
`;
112 changes: 67 additions & 45 deletions tests/checkable.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fireEvent, render } from '@testing-library/react';
import React from 'react';
import Cascader from '../src';
import { addressOptions } from './demoOptions';
import { mount } from './enzyme';
import { clickOption } from './util';

describe('Cascader.Checkable', () => {
const options = [
Expand Down Expand Up @@ -34,15 +34,16 @@ describe('Cascader.Checkable', () => {

it('customize', () => {
const onChange = jest.fn();
const wrapper = mount(<Cascader options={options} onChange={onChange} open checkable />);
const { container } = render(<Cascader options={options} onChange={onChange} open checkable />);

expect(wrapper.exists('.rc-cascader-checkbox')).toBeTruthy();
expect(wrapper.exists('.rc-cascader-checkbox-checked')).toBeFalsy();
expect(wrapper.exists('.rc-cascader-checkbox-indeterminate')).toBeFalsy();
expect(container.querySelector('.rc-cascader-checkbox')).toBeTruthy();
expect(container.querySelector('.rc-cascader-checkbox-checked')).toBeFalsy();
expect(container.querySelector('.rc-cascader-checkbox-indeterminate')).toBeFalsy();

// Check light
wrapper.find('.rc-cascader-checkbox').first().simulate('click');
expect(wrapper.exists('.rc-cascader-checkbox-checked')).toBeTruthy();
const checkboxes = container.querySelectorAll('.rc-cascader-checkbox');
fireEvent.click(checkboxes[0]);
expect(container.querySelector('.rc-cascader-checkbox-checked')).toBeTruthy();
expect(onChange).toHaveBeenCalledWith(
[['light']],
[[expect.objectContaining({ value: 'light' })]],
Expand All @@ -51,13 +52,17 @@ describe('Cascader.Checkable', () => {
onChange.mockReset();

// Open bamboo > little
wrapper.clickOption(0, 1);
wrapper.clickOption(1, 0);
clickOption(container, 0, 1); // Click bamboo
clickOption(container, 1, 0); // Click little

// Check cards
wrapper.clickOption(2, 1);
expect(wrapper.find('.rc-cascader-checkbox-indeterminate')).toHaveLength(2);
expect(wrapper.exists('.rc-cascader-checkbox-indeterminate')).toBeTruthy();
// Check cards (index 1 in third menu)
clickOption(container, 2, 1); // Click cards

const indeterminateCheckboxes = container.querySelectorAll(
'.rc-cascader-checkbox-indeterminate',
);
expect(indeterminateCheckboxes).toHaveLength(2);
expect(container.querySelector('.rc-cascader-checkbox-indeterminate')).toBeTruthy();
expect(onChange).toHaveBeenCalledWith(
[
// Light
Expand All @@ -77,10 +82,15 @@ describe('Cascader.Checkable', () => {
],
);

// Check fish
wrapper.clickOption(2, 0);
expect(wrapper.find('.rc-cascader-checkbox-indeterminate')).toHaveLength(0);
expect(wrapper.find('.rc-cascader-checkbox-checked')).toHaveLength(5);
// Check fish (index 0 in third menu)
clickOption(container, 2, 0); // Click fish

const finalIndeterminateCheckboxes = container.querySelectorAll(
'.rc-cascader-checkbox-indeterminate',
);
expect(finalIndeterminateCheckboxes).toHaveLength(0);
const checkedCheckboxes = container.querySelectorAll('.rc-cascader-checkbox-checked');
expect(checkedCheckboxes).toHaveLength(5);
expect(onChange).toHaveBeenCalledWith(
[
// Light
Expand All @@ -98,22 +108,23 @@ describe('Cascader.Checkable', () => {
});
it('click checkbox invoke one onChange', () => {
const onChange = jest.fn();
const wrapper = mount(<Cascader options={options} onChange={onChange} open checkable />);
const { container } = render(<Cascader options={options} onChange={onChange} open checkable />);

expect(wrapper.exists('.rc-cascader-checkbox')).toBeTruthy();
expect(wrapper.exists('.rc-cascader-checkbox-checked')).toBeFalsy();
expect(wrapper.exists('.rc-cascader-checkbox-indeterminate')).toBeFalsy();
expect(container.querySelector('.rc-cascader-checkbox')).toBeTruthy();
expect(container.querySelector('.rc-cascader-checkbox-checked')).toBeFalsy();
expect(container.querySelector('.rc-cascader-checkbox-indeterminate')).toBeFalsy();

// Check checkbox
wrapper.find('.rc-cascader-checkbox').first().simulate('click');
expect(wrapper.exists('.rc-cascader-checkbox-checked')).toBeTruthy();
const checkboxes = container.querySelectorAll('.rc-cascader-checkbox');
fireEvent.click(checkboxes[0]);
expect(container.querySelector('.rc-cascader-checkbox-checked')).toBeTruthy();
expect(onChange).toHaveBeenCalledTimes(1);
});

it('merge checked options', () => {
const onChange = jest.fn();

const wrapper = mount(
const { container } = render(
<Cascader
checkable
open
Expand All @@ -138,48 +149,51 @@ describe('Cascader.Checkable', () => {
);

// Open parent
wrapper.find('.rc-cascader-menu-item-content').first().simulate('click');
clickOption(container, 0, 0);

// Check child1
wrapper.find('span.rc-cascader-checkbox').at(1).simulate('click');
const checkboxes = container.querySelectorAll('span.rc-cascader-checkbox');
fireEvent.click(checkboxes[1]);
expect(onChange).toHaveBeenCalledWith([['parent', 'child1']], expect.anything());

// Check child2
onChange.mockReset();
wrapper.find('span.rc-cascader-checkbox').at(2).simulate('click');
fireEvent.click(checkboxes[2]);
expect(onChange).toHaveBeenCalledWith([['parent']], expect.anything());

// Uncheck child1
onChange.mockReset();
wrapper.find('span.rc-cascader-checkbox').at(1).simulate('click');
fireEvent.click(checkboxes[1]);
expect(onChange).toHaveBeenCalledWith([['parent', 'child2']], expect.anything());
});

// https://github.com/ant-design/ant-design/issues/33302
it('should not display checkbox when children is empty', () => {
const wrapper = mount(
const { container } = render(
<Cascader checkable options={[]}>
<input readOnly />
</Cascader>,
);
wrapper.find('input').simulate('click');
const menus = wrapper.find('.rc-cascader-menu');
expect(menus.find('.rc-cascader-checkbox').length).toBe(0);
const input = container.querySelector('input');
fireEvent.click(input!);
const checkboxes = container.querySelectorAll('.rc-cascader-checkbox');
expect(checkboxes.length).toBe(0);
});

it('should work with custom checkable', () => {
const wrapper = mount(
const { container } = render(
<Cascader
checkable={<span className="my-custom-checkbox">0</span>}
open
options={addressOptions}
/>,
);
expect(wrapper.find('.my-custom-checkbox')).toHaveLength(3);
const customCheckboxes = container.querySelectorAll('.my-custom-checkbox');
expect(customCheckboxes).toHaveLength(3);
});

it('should be correct expression with disableCheckbox', () => {
const wrapper = mount(
const { container } = render(
<Cascader
checkable={true}
open
Expand All @@ -206,22 +220,30 @@ describe('Cascader.Checkable', () => {
);

// disabled className
wrapper.find('.rc-cascader-menu-item').simulate('click');
expect(wrapper.find('.rc-cascader-menu-item')).toHaveLength(4);
expect(wrapper.find('.rc-cascader-checkbox-disabled')).toHaveLength(1);
const menuItems = container.querySelectorAll('.rc-cascader-menu-item');
fireEvent.click(menuItems[0]);

// After clicking, we should have the parent item and its children
const updatedMenuItems = container.querySelectorAll('.rc-cascader-menu-item');
expect(updatedMenuItems).toHaveLength(4);
const disabledCheckboxes = container.querySelectorAll('.rc-cascader-checkbox-disabled');
expect(disabledCheckboxes).toHaveLength(1);

// click disableCkeckbox
wrapper.find('.rc-cascader-menu-item').at(1).simulate('click');
expect(wrapper.find('.rc-cascader-checkbox-checked')).toHaveLength(0);
fireEvent.click(updatedMenuItems[1]);
const checkedCheckboxes = container.querySelectorAll('.rc-cascader-checkbox-checked');
expect(checkedCheckboxes).toHaveLength(0);

// click disableMenuItem
wrapper.find('.rc-cascader-checkbox-disabled').simulate('click');
expect(wrapper.find('.rc-cascader-checkbox-checked')).toHaveLength(0);
fireEvent.click(disabledCheckboxes[0]);
expect(checkedCheckboxes).toHaveLength(0);

// Check all children except disableCheckbox When the parent checkbox is checked
expect(wrapper.find('.rc-cascader-checkbox')).toHaveLength(4);
wrapper.find('.rc-cascader-checkbox').first().simulate('click');
expect(wrapper.find('.rc-cascader-checkbox-checked')).toHaveLength(3);
const allCheckboxes = container.querySelectorAll('.rc-cascader-checkbox');
expect(allCheckboxes).toHaveLength(4);
fireEvent.click(allCheckboxes[0]);
const finalCheckedCheckboxes = container.querySelectorAll('.rc-cascader-checkbox-checked');
expect(finalCheckedCheckboxes).toHaveLength(3);
});

it('should not merge disabled options', () => {
Expand Down
19 changes: 0 additions & 19 deletions tests/enzyme.ts

This file was deleted.

Loading
Loading