@v4fire/client
Version:
V4Fire client core library
302 lines (245 loc) • 8.17 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
/**
* @file Test cases of the component `itemsFactory` prop.
*/
import test from 'tests/config/unit/test';
import type { ComponentItemFactory, ComponentItem, ShouldPerform, VirtualScrollState } from 'base/b-virtual-scroll-new/interface';
import { createTestHelpers } from 'base/b-virtual-scroll-new/test/api/helpers';
import type { VirtualScrollTestHelpers } from 'base/b-virtual-scroll-new/test/api/helpers/interface';
test.describe('<b-virtual-scroll-new> rendering via itemsFactory', () => {
let
component: VirtualScrollTestHelpers['component'],
provider: VirtualScrollTestHelpers['provider'],
state: VirtualScrollTestHelpers['state'];
test.beforeEach(async ({demoPage, page}) => {
await demoPage.goto();
({component, provider, state} = await createTestHelpers(page));
await provider.start();
});
test.describe('returned items with type `item` is equal to the provided data', () => {
test('should render all of the items that were returned from `itemsFactory`', async () => {
const
chunkSize = 12;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const itemsFactory = await component.mockFn<ComponentItemFactory<{i: number}>>((state) => {
const data = state.lastLoadedData;
return data.map((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'item',
children: [],
props: {
'data-index': item.i
}
}));
});
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender: () => true,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(chunkSize);
await test.expect(component.childList).toHaveCount(chunkSize);
});
});
test.describe('In additional `item`, `separator` was also returned', () => {
test('should render both', async () => {
const
chunkSize = 12;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const separator = {
item: 'b-button',
key: '',
children: {
default: 'ima button'
},
props: {
id: 'button'
},
type: 'separator'
};
const itemsFactory = await component.mockFn((state: VirtualScrollState, ctx, separator) => {
const
data = <Array<{i: number}>>state.lastLoadedData;
const items = data.map((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'item',
children: [],
props: {
'data-index': item.i
}
}));
if (items.length > 0) {
items.push(separator);
}
return items;
}, separator);
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender: () => true,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(chunkSize + 1);
await test.expect(component.container.locator('#button')).toBeVisible();
await test.expect(component.childList).toHaveCount(chunkSize + 1);
});
});
test.describe('returned items with type `item` is less than the provided data', () => {
test('should render items that were returned from `itemsFactory`', async () => {
const
chunkSize = 12,
renderedChunkSize = chunkSize - 2;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const itemsFactory = await component.mockFn<ComponentItemFactory<{i: number}>>((state) => {
const data = state.lastLoadedData;
const items = data.map<ComponentItem>((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'item',
children: [],
props: {
'data-index': item.i
}
}));
items.length -= 2;
return items;
});
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender: () => true,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(renderedChunkSize);
await test.expect(component.childList).toHaveCount(renderedChunkSize);
});
});
test.describe('returned item with type `item` is more than the provided data', () => {
test('should render items that were returned from `itemsFactory`', async () => {
const
chunkSize = 12,
renderedChunkSize = chunkSize * 2;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const itemsFactory = await component.mockFn<ComponentItemFactory<{i: number}>>((state) => {
const data = state.lastLoadedData;
const items = data.map<ComponentItem>((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'item',
children: [],
props: {
'data-index': item.i
}
}));
return [...items, ...items];
});
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender: () => true,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(renderedChunkSize);
await test.expect(component.childList).toHaveCount(renderedChunkSize);
});
});
test.describe('The items of type `item` were not returned, but the items of type `separator` were returned in the same quantity as the loaded data.', () => {
test('should render separators that were returned from `itemsFactory`', async () => {
const
chunkSize = 12;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const itemsFactory = await component.mockFn<ComponentItemFactory<{i: number}>>((state) => {
const data = state.lastLoadedData;
return data.map((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'separator',
children: [],
props: {
'data-index': item.i
}
}));
});
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender: () => true,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(chunkSize);
await test.expect(component.childList).toHaveCount(chunkSize);
});
});
test.describe('`itemsFactory` returns twice as much data as the `chunkSize`', () => {
test('should render twice as much items as the `chunkSize`', async () => {
const
chunkSize = 12;
provider
.responseOnce(200, {data: state.data.addData(chunkSize)})
.responseOnce(200, {data: state.data.addData(chunkSize)})
.responseOnce(200, {data: state.data.addData(chunkSize)})
.response(200, {data: state.data.addData(0)});
const shouldPerformDataRender = await component.mockFn<ShouldPerform>(
({isInitialRender, remainingItems: remainingItems}) => isInitialRender || remainingItems === 0
);
const itemsFactory = await component.mockFn<ComponentItemFactory<{i: number}>>((state) => {
const data = state.lastLoadedData;
const items = data.map<ComponentItem>((item) => ({
item: 'section',
key: Object.cast(undefined),
type: 'item',
children: [],
props: {
'data-index': item.i
}
}));
return [...items, ...items];
});
await component
.withDefaultPaginationProviderProps({chunkSize})
.withProps({
itemsFactory,
shouldPerformDataRender,
chunkSize
})
.build();
await component.waitForChildCountEqualsTo(chunkSize * 2);
await component.scrollToBottom();
await component.waitForChildCountEqualsTo(chunkSize * 2 * 2);
await component.scrollToBottom();
await component.waitForChildCountEqualsTo(chunkSize * 3 * 2);
await component.scrollToBottom();
await component.waitForChildCountEqualsTo(chunkSize * 3 * 2);
await test.expect(component.childList).toHaveCount(chunkSize * 3 * 2);
});
});
});