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
16 changes: 6 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,28 @@
"now-build": "npm run build"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
},
"devDependencies": {
"@rc-component/father-plugin": "^2.1.3",
"@rc-component/np": "^1.0.4",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^12.1.5",
"@types/enzyme": "^3.10.5",
"@testing-library/react": "^13.4.0",
"@types/jest": "^30.0.0",
"@types/node": "^24.10.1",
"@types/react": "^18.0.8",
"@types/react-dom": "^18.0.3",
"@types/warning": "^3.0.0",
"cheerio": "1.0.0-rc.12",
"dumi": "^2.2.17",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.15.6",
"eslint": "^8.56.0",
"eslint-plugin-unicorn": "^55.0.0",
"father": "^4.4.0",
"glob": "^7.1.6",
"rc-animate": "^2.9.1",
"rc-test": "^7.0.15",
"react": "16.14.0",
"react-dom": "16.14.0",
"rc-test": "^7.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.0.0"
},
"dependencies": {
Expand Down
139 changes: 83 additions & 56 deletions tests/list.test.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,67 @@
import '@testing-library/jest-dom';
import { _rs as onLibResize } from '@rc-component/resize-observer/lib/utils/observerUtil';
import { act, fireEvent, render } from '@testing-library/react';
import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import List from '../src';
import Filler from '../src/Filler';
import { spyElementPrototypes } from './utils/domHook';

function genData(count) {
return new Array(count).fill(null).map((_, id) => ({ id }));
}

describe('List.Basic', () => {
function genList(props) {
let node = (
<List component="ul" itemKey="id" {...props}>
{({ id }) => <li>{id}</li>}
</List>
);
function genNode(props) {
return (
<List component="ul" itemKey="id" {...props}>
{({ id }) => <li>{id}</li>}
</List>
);
}

function genList(props) {
return render(genNode(props));
}

function getHolder(container) {
return container.querySelector('.rc-virtual-list-holder');
}

return mount(node);
}
function getInner(container) {
return container.querySelector('.rc-virtual-list-holder-inner');
}

function getFiller(container) {
return getInner(container).parentElement;
}

function getOffsetY(container) {
const { transform } = getInner(container).style;
return Number(transform.match(/translateY\((\d+)px\)/)?.[1] || 0);
}

describe('List.Basic', () => {
describe('raw', () => {
it('without height', () => {
const wrapper = genList({ data: genData(1) });
expect(wrapper.find(Filler).props().offset).toBeFalsy();
const { container } = genList({ data: genData(1) });
expect(getFiller(container)).not.toHaveStyle({ height: '1px' });
expect(getInner(container).style.transform).toEqual('');
});

describe('height over itemHeight', () => {
it('full height', () => {
const wrapper = genList({ data: genData(1), itemHeight: 1, height: 999 });
expect(wrapper.find(Filler).props().offset).toBeFalsy();
expect(wrapper.find('ul').props().style).toEqual(expect.objectContaining({ height: 999 }));
const { container } = genList({ data: genData(1), itemHeight: 1, height: 999 });
expect(getFiller(container).style.height).toEqual('');
expect(getHolder(container)).toHaveStyle({ height: '999px' });
});

it('without full height', () => {
const wrapper = genList({
const { container } = genList({
data: genData(1),
itemHeight: 1,
height: 999,
fullHeight: false,
});
expect(wrapper.find(Filler).props().offset).toBeFalsy();
expect(wrapper.find('ul').props().style).toEqual(
expect.objectContaining({ maxHeight: 999 }),
);
expect(getFiller(container).style.height).toEqual('');
expect(getHolder(container)).toHaveStyle({ maxHeight: '999px' });
});
});
});
Expand Down Expand Up @@ -81,18 +99,21 @@ describe('List.Basic', () => {

// scroll to top
scrollTop = 0;
const wrapper = genList({ itemHeight: 20, height: 100, data: genData(100), onVisibleChange });
expect(wrapper.find(Filler).props().height).toEqual(2000);
expect(wrapper.find(Filler).props().offsetY).toEqual(0);
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
onVisibleChange,
});
expect(getFiller(container)).toHaveStyle({ height: '2000px' });
expect(getOffsetY(container)).toEqual(0);
onVisibleChange.mockReset();

// scrollTop to end
scrollTop = 2000 - 100;
wrapper.find('ul').simulate('scroll', {
scrollTop,
});
expect(wrapper.find(Filler).props().height).toEqual(2000);
expect(wrapper.find(Filler).props().offsetY + wrapper.find('li').length * 20).toEqual(2000);
fireEvent.scroll(getHolder(container));
expect(getFiller(container)).toHaveStyle({ height: '2000px' });
expect(getOffsetY(container) + container.querySelectorAll('li').length * 20).toEqual(2000);

expect(onVisibleChange.mock.calls[0][0]).toHaveLength(6);
expect(onVisibleChange.mock.calls[0][1]).toHaveLength(100);
Expand Down Expand Up @@ -132,39 +153,44 @@ describe('List.Basic', () => {

it('raw to virtual', () => {
let data = genData(5);
const wrapper = genList({ itemHeight: 20, height: 100, data });
const { container, rerender } = genList({ itemHeight: 20, height: 100, data });

expect(wrapper.find('li')).toHaveLength(5);
expect(container.querySelectorAll('li')).toHaveLength(5);

data = genData(10);
wrapper.setProps({ data });
expect(wrapper.find('li').length < data.length).toBeTruthy();
rerender(genNode({ itemHeight: 20, height: 100, data }));
expect(container.querySelectorAll('li').length < data.length).toBeTruthy();
});

it('virtual to raw', () => {
let data = genData(10);
const wrapper = genList({ itemHeight: 20, height: 100, data });
expect(wrapper.find('li').length < data.length).toBeTruthy();
const { container, rerender } = genList({ itemHeight: 20, height: 100, data });
expect(container.querySelectorAll('li').length < data.length).toBeTruthy();

data = data.slice(0, 2);
wrapper.setProps({ data });
expect(wrapper.find('li')).toHaveLength(2);
rerender(genNode({ itemHeight: 20, height: 100, data }));
expect(container.querySelectorAll('li')).toHaveLength(2);

// Should not crash if data count change
data = data.slice(0, 1);
wrapper.setProps({ data });
expect(wrapper.find('li')).toHaveLength(1);
rerender(genNode({ itemHeight: 20, height: 100, data }));
expect(container.querySelectorAll('li')).toHaveLength(1);
});
});

it('`virtual` is false', () => {
const wrapper = genList({ itemHeight: 20, height: 100, data: genData(100), virtual: false });
expect(wrapper.find('li')).toHaveLength(100);
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
virtual: false,
});
expect(container.querySelectorAll('li')).toHaveLength(100);
});

it('Should not crash when height change makes virtual scroll to be raw scroll', () => {
const wrapper = genList({ itemHeight: 20, height: 40, data: genData(3) });
wrapper.setProps({ height: 1000 });
const { rerender } = genList({ itemHeight: 20, height: 40, data: genData(3) });
rerender(genNode({ itemHeight: 20, height: 1000, data: genData(3) }));
});

describe('should collect height', () => {
Expand Down Expand Up @@ -192,24 +218,25 @@ describe('List.Basic', () => {
});

it('work', async () => {
const wrapper = genList({ itemHeight: 20, height: 40, data: genData(3) });
wrapper.find('Filler').find('ResizeObserver').props().onResize({ offsetHeight: 0 });
expect(collected).toBeFalsy();
const { container } = genList({ itemHeight: 20, height: 40, data: genData(3) });
collected = false;

// Wait for collection
await act(async () => {
await new Promise((resolve) => {
setTimeout(resolve, 10);
});
onLibResize([
{
target: getInner(container),
},
]);

await Promise.resolve();
});

wrapper.find('Filler').find('ResizeObserver').props().onResize({ offsetHeight: 100 });
expect(collected).toBeTruthy();
});
});

it('innerProps', () => {
const wrapper = genList({
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
Expand All @@ -220,12 +247,12 @@ describe('List.Basic', () => {
},
});

expect(wrapper.find('div#my_list').prop('role')).toEqual('listbox');
expect(container.querySelector('div#my_list')).toHaveAttribute('role', 'listbox');
});

it('nativeElement', () => {
const ref = React.createRef();
const wrapper = genList({ data: genData(1), ref });
expect(ref.current.nativeElement).toBe(wrapper.getDOMNode());
const { container } = genList({ data: genData(1), ref });
expect(ref.current.nativeElement).toBe(container.firstChild);
});
});
24 changes: 9 additions & 15 deletions tests/mock.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { render } from '@testing-library/react';
import React from 'react';
import { mount } from 'enzyme';
import MockList from '../src/mock';
import Filler from '../src/Filler';

describe('MockList', () => {
it('correct render', () => {
const wrapper = mount(
const { container } = render(
<MockList data={[0, 1, 2]} itemKey={id => id}>
{id => <span>{id}</span>}
</MockList>,
);

expect(wrapper.find(Filler).length).toBeTruthy();

for (let i = 0; i < 3; i += 1) {
expect(
wrapper
.find('Item')
.at(i)
.key(),
).toBe(String(i));
}

expect(wrapper.find('List')).toHaveLength(1);
expect(container.querySelector('.rc-virtual-list-holder-inner')).toBeTruthy();
expect(Array.from(container.querySelectorAll('span')).map(node => node.textContent)).toEqual([
'0',
'1',
'2',
]);
expect(container.querySelector('.rc-virtual-list')).toBeTruthy();
});
});
29 changes: 9 additions & 20 deletions tests/props.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { render } from '@testing-library/react';
import React from 'react';
import { mount } from 'enzyme';
import List from '../src';

describe('Props', () => {
Expand All @@ -10,44 +10,33 @@ describe('Props', () => {
}
}

const wrapper = mount(
const { container } = render(
<List data={[{ id: 903 }, { id: 1128 }]} itemKey={item => item.id}>
{({ id }) => <ItemComponent>{id}</ItemComponent>}
</List>,
);

expect(
wrapper
.find('Item')
.at(0)
.key(),
).toBe('903');

expect(
wrapper
.find('Item')
.at(1)
.key(),
).toBe('1128');
expect(container.textContent).toEqual('9031128');
});

it('prefixCls', () => {
const wrapper = mount(
const { container } = render(
<List data={[0]} itemKey={id => id} prefixCls="prefix">
{id => <div>{id}</div>}
</List>,
);

expect(wrapper.find('.prefix-holder-inner').length).toBeTruthy();
expect(container.querySelector('.prefix-holder-inner')).toBeTruthy();
});

it('offsetX in renderFn', () => {
let scrollLeft;
mount(
render(
<List data={[0]} itemKey={id => id} prefixCls="prefix">
{(id, _, { offsetX }) => {
{(id, _, { offsetX }) => {
scrollLeft = offsetX;
return <div>{id}</div>}}
return <div>{id}</div>;
}}
</List>,
);

Expand Down
Loading
Loading