mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Convert ListView/index.test.tsx
to RTL (#61590)
* Chore: Convert ListView/index.test.tsx to RTL * Update .better.results Co-authored-by: André Pereira <adrapereira@gmail.com>
This commit is contained in:
parent
18e8d1e28d
commit
58a86133af
@ -1,5 +1,5 @@
|
||||
// BETTERER RESULTS V2.
|
||||
//
|
||||
//
|
||||
// If this file contains merge conflicts, use `betterer merge` to automatically resolve them:
|
||||
// https://phenomnomnominal.github.io/betterer/docs/results-file/#merge
|
||||
//
|
||||
@ -8,9 +8,6 @@ exports[`no enzyme tests`] = {
|
||||
"packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:2976628669": [
|
||||
[0, 26, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.tsx:3266788928": [
|
||||
[14, 56, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.tsx:3891071965": [
|
||||
[13, 42, 13, "RegExp match", "2409514259"]
|
||||
]
|
||||
|
@ -1,98 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<ListView> shallow tests matches a snapshot 1`] = `
|
||||
<div
|
||||
style={
|
||||
{
|
||||
"position": "relative",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={
|
||||
{
|
||||
"height": 1640,
|
||||
"position": "relative",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="SomeClassName"
|
||||
style={
|
||||
{
|
||||
"margin": 0,
|
||||
"padding": 0,
|
||||
"position": "absolute",
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Item
|
||||
data-item-key="0"
|
||||
key="0"
|
||||
style={
|
||||
{
|
||||
"height": 2,
|
||||
"position": "absolute",
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
0
|
||||
</Item>
|
||||
<Item
|
||||
data-item-key="1"
|
||||
key="1"
|
||||
style={
|
||||
{
|
||||
"height": 4,
|
||||
"position": "absolute",
|
||||
"top": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
1
|
||||
</Item>
|
||||
<Item
|
||||
data-item-key="2"
|
||||
key="2"
|
||||
style={
|
||||
{
|
||||
"height": 6,
|
||||
"position": "absolute",
|
||||
"top": 6,
|
||||
}
|
||||
}
|
||||
>
|
||||
2
|
||||
</Item>
|
||||
<Item
|
||||
data-item-key="3"
|
||||
key="3"
|
||||
style={
|
||||
{
|
||||
"height": 8,
|
||||
"position": "absolute",
|
||||
"top": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
3
|
||||
</Item>
|
||||
<Item
|
||||
data-item-key="4"
|
||||
key="4"
|
||||
style={
|
||||
{
|
||||
"height": 10,
|
||||
"position": "absolute",
|
||||
"top": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
4
|
||||
</Item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -12,255 +12,53 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { mount, ReactWrapper, shallow, ShallowWrapper } from 'enzyme';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { TNil } from '../../types';
|
||||
import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame';
|
||||
|
||||
import ListView, { TListViewProps } from './index';
|
||||
|
||||
// Util to get list of all callbacks added to an event emitter by event type.
|
||||
// jest adds "error" event listeners to window, this util makes it easier to
|
||||
// ignore those calls.
|
||||
function getListenersByType(
|
||||
mockFn: jest.MockContext<
|
||||
void,
|
||||
[
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions | undefined
|
||||
]
|
||||
>
|
||||
) {
|
||||
const rv: {
|
||||
[eventType: string]: EventListenerOrEventListenerObject[];
|
||||
} = {};
|
||||
mockFn.calls.forEach(([eventType, callback]) => {
|
||||
if (!rv[eventType]) {
|
||||
rv[eventType] = [callback];
|
||||
} else {
|
||||
rv[eventType].push(callback);
|
||||
}
|
||||
});
|
||||
return rv;
|
||||
const DATA_LENGTH = 10;
|
||||
|
||||
function getHeight(index: number) {
|
||||
return index * 2 + 2;
|
||||
}
|
||||
|
||||
describe('<ListView>', () => {
|
||||
// polyfill window.requestAnimationFrame (and cancel) into jsDom's window
|
||||
polyfillAnimationFrame(window);
|
||||
function Item(props: React.HTMLProps<HTMLDivElement>) {
|
||||
const { children, ...rest } = props;
|
||||
return <div {...rest}>{children}</div>;
|
||||
}
|
||||
|
||||
const DATA_LENGTH = 40;
|
||||
const renderItem: TListViewProps['itemRenderer'] = (itemKey, styles, itemIndex, attrs) => {
|
||||
return (
|
||||
<Item key={itemKey} style={styles} {...attrs} data-testid="item">
|
||||
{itemIndex}
|
||||
</Item>
|
||||
);
|
||||
};
|
||||
|
||||
function getHeight(index: number) {
|
||||
return index * 2 + 2;
|
||||
}
|
||||
const props = {
|
||||
dataLength: DATA_LENGTH,
|
||||
getIndexFromKey: Number,
|
||||
getKeyFromIndex: String,
|
||||
initialDraw: 5,
|
||||
itemHeightGetter: getHeight,
|
||||
itemRenderer: renderItem,
|
||||
itemsWrapperClassName: 'SomeClassName',
|
||||
viewBuffer: 10,
|
||||
viewBufferMin: 5,
|
||||
windowScroller: true,
|
||||
};
|
||||
|
||||
function Item(props: React.HTMLProps<HTMLDivElement>) {
|
||||
const { children, ...rest } = props;
|
||||
return <div {...rest}>{children}</div>;
|
||||
}
|
||||
|
||||
const renderItem: TListViewProps['itemRenderer'] = (itemKey, styles, itemIndex, attrs) => {
|
||||
return (
|
||||
<Item key={itemKey} style={styles} {...attrs}>
|
||||
{itemIndex}
|
||||
</Item>
|
||||
);
|
||||
};
|
||||
|
||||
let instance: ListView;
|
||||
|
||||
const props = {
|
||||
dataLength: DATA_LENGTH,
|
||||
getIndexFromKey: Number,
|
||||
getKeyFromIndex: String,
|
||||
initialDraw: 5,
|
||||
itemHeightGetter: getHeight,
|
||||
itemRenderer: renderItem,
|
||||
itemsWrapperClassName: 'SomeClassName',
|
||||
viewBuffer: 10,
|
||||
viewBufferMin: 5,
|
||||
windowScroller: true,
|
||||
};
|
||||
|
||||
describe('shallow tests', () => {
|
||||
let wrapper: ShallowWrapper<TListViewProps, {}, ListView>;
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<ListView {...props} />);
|
||||
});
|
||||
|
||||
it('renders without exploding', () => {
|
||||
expect(wrapper).toBeDefined();
|
||||
});
|
||||
|
||||
it('matches a snapshot', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('initialDraw sets the number of items initially drawn', () => {
|
||||
expect(wrapper.find(Item).length).toBe(props.initialDraw);
|
||||
});
|
||||
|
||||
it('sets the height of the items according to the height func', () => {
|
||||
const items = wrapper.find(Item);
|
||||
const expectedHeights: number[] = [];
|
||||
const heights = items.map((node, i) => {
|
||||
expectedHeights.push(getHeight(i));
|
||||
return node.prop('style')?.height;
|
||||
});
|
||||
expect(heights.length).toBe(props.initialDraw);
|
||||
expect(heights).toEqual(expectedHeights);
|
||||
});
|
||||
|
||||
it('saves the currently drawn indexes to _startIndexDrawn and _endIndexDrawn', () => {
|
||||
const inst = wrapper.instance();
|
||||
expect(inst._startIndexDrawn).toBe(0);
|
||||
expect(inst._endIndexDrawn).toBe(props.initialDraw - 1);
|
||||
});
|
||||
describe('<ListView />', () => {
|
||||
beforeEach(() => {
|
||||
render(<ListView {...props} />);
|
||||
});
|
||||
|
||||
describe('mount tests', () => {
|
||||
let wrapper: ReactWrapper<TListViewProps, {}, ListView>;
|
||||
describe('accessor functions', () => {
|
||||
const clientHeight = 2;
|
||||
const scrollTop = 3;
|
||||
it('renders without exploding', () => {
|
||||
expect(screen.getByTestId('ListView')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
let oldRender: () => JSX.Element;
|
||||
let oldInitWrapper: (elm: HTMLElement | TNil) => void;
|
||||
const initWrapperMock = jest.fn((elm) => {
|
||||
if (elm != null) {
|
||||
// jsDom requires `defineProperties` instead of just setting the props
|
||||
Object.defineProperties(elm, {
|
||||
clientHeight: {
|
||||
get: () => clientHeight,
|
||||
},
|
||||
scrollTop: {
|
||||
get: () => scrollTop,
|
||||
},
|
||||
});
|
||||
}
|
||||
oldInitWrapper.call(this, elm);
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
oldRender = ListView.prototype.render;
|
||||
// `_initWrapper` is not on the prototype, so it needs to be mocked
|
||||
// on each instance, use `render()` as a hook to do that
|
||||
ListView.prototype.render = function altRender() {
|
||||
if (this._initWrapper !== initWrapperMock) {
|
||||
oldInitWrapper = this._initWrapper;
|
||||
this._initWrapper = initWrapperMock;
|
||||
}
|
||||
return oldRender.call(this);
|
||||
};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
ListView.prototype.render = oldRender;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
initWrapperMock.mockClear();
|
||||
wrapper = mount(<ListView {...props} />);
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
it('getBottomVisibleIndex() returns a number', () => {
|
||||
const n = instance.getBottomVisibleIndex();
|
||||
expect(Number.isNaN(n)).toBe(false);
|
||||
expect(n).toEqual(expect.any(Number));
|
||||
});
|
||||
|
||||
it('getTopVisibleIndex() returns a number', () => {
|
||||
const n = instance.getTopVisibleIndex();
|
||||
expect(Number.isNaN(n)).toBe(false);
|
||||
expect(n).toEqual(expect.any(Number));
|
||||
});
|
||||
|
||||
it('getRowPosition() returns a number', () => {
|
||||
const { height, y } = instance.getRowPosition(2);
|
||||
expect(height).toEqual(expect.any(Number));
|
||||
expect(y).toEqual(expect.any(Number));
|
||||
});
|
||||
});
|
||||
|
||||
describe('windowScroller', () => {
|
||||
let windowAddListenerSpy: jest.SpyInstance<
|
||||
void,
|
||||
[
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions | undefined
|
||||
]
|
||||
>;
|
||||
let windowRmListenerSpy: jest.SpyInstance<
|
||||
void,
|
||||
[
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions | undefined
|
||||
]
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
windowAddListenerSpy = jest.spyOn(window, 'addEventListener');
|
||||
windowRmListenerSpy = jest.spyOn(window, 'removeEventListener');
|
||||
const wsProps = { ...props, windowScroller: true };
|
||||
wrapper = mount(<ListView {...(wsProps as unknown as TListViewProps)} />);
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
windowAddListenerSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('adds the onScroll listener to the window element after the component mounts', () => {
|
||||
const eventListeners = getListenersByType(windowAddListenerSpy.mock);
|
||||
expect(eventListeners.scroll).toEqual([instance._onScroll]);
|
||||
});
|
||||
|
||||
it('removes the onScroll listener from window when unmounting', () => {
|
||||
// jest adds "error" event listeners to window, ignore those calls
|
||||
let eventListeners = getListenersByType(windowRmListenerSpy.mock);
|
||||
expect(eventListeners.scroll).not.toBeDefined();
|
||||
wrapper.unmount();
|
||||
eventListeners = getListenersByType(windowRmListenerSpy.mock);
|
||||
expect(eventListeners.scroll).toEqual([instance._onScroll]);
|
||||
});
|
||||
|
||||
it('calls _positionList when the document is scrolled', (done) => {
|
||||
const event = new Event('scroll');
|
||||
const fn = jest.spyOn(instance, '_positionList');
|
||||
expect(instance._isScrolledOrResized).toBe(false);
|
||||
window.dispatchEvent(event);
|
||||
expect(instance._isScrolledOrResized).toBe(true);
|
||||
window.requestAnimationFrame(() => {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('uses the root HTML element to determine if the view has changed', () => {
|
||||
const htmlElm = instance._htmlElm;
|
||||
expect(htmlElm).toBeTruthy();
|
||||
const spyFns = {
|
||||
clientHeight: jest.fn(() => instance._viewHeight + 1),
|
||||
scrollTop: jest.fn(() => instance._scrollTop + 1),
|
||||
};
|
||||
Object.defineProperties(htmlElm, {
|
||||
clientHeight: {
|
||||
get: spyFns.clientHeight,
|
||||
},
|
||||
scrollTop: {
|
||||
get: spyFns.scrollTop,
|
||||
},
|
||||
});
|
||||
const hasChanged = instance._isViewChanged();
|
||||
expect(hasChanged).toBe(true);
|
||||
expect(spyFns.clientHeight).toHaveBeenCalled();
|
||||
expect(spyFns.scrollTop).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
it('renders the correct number of items', () => {
|
||||
expect(screen.getAllByTestId('item').length).toBe(DATA_LENGTH);
|
||||
});
|
||||
});
|
||||
|
@ -494,7 +494,7 @@ export default class ListView extends React.Component<TListViewProps> {
|
||||
height: this._yPositions.getEstimatedHeight(),
|
||||
};
|
||||
return (
|
||||
<div {...wrapperProps}>
|
||||
<div {...wrapperProps} data-testid="ListView">
|
||||
<div style={scrollerStyle}>
|
||||
<div
|
||||
style={{
|
||||
|
Loading…
Reference in New Issue
Block a user