Chore: Refactor the packages/jaeger-ui-components/src/TracePageHeader folder to TS (#59722)
This commit is contained in:
+4
-4
@@ -8,11 +8,11 @@ exports[`no enzyme tests`] = {
|
|||||||
"packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:2976628669": [
|
"packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:2976628669": [
|
||||||
[0, 26, 13, "RegExp match", "2409514259"]
|
[0, 26, 13, "RegExp match", "2409514259"]
|
||||||
],
|
],
|
||||||
"packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js:1676554632": [
|
"packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.tsx:793800575": [
|
||||||
[14, 19, 13, "RegExp match", "2409514259"]
|
[14, 35, 13, "RegExp match", "2409514259"]
|
||||||
],
|
],
|
||||||
"packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js:186764954": [
|
"packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.tsx:596989456": [
|
||||||
[14, 19, 13, "RegExp match", "2409514259"]
|
[14, 35, 13, "RegExp match", "2409514259"]
|
||||||
],
|
],
|
||||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js:1734982398": [
|
"packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js:1734982398": [
|
||||||
[14, 26, 13, "RegExp match", "2409514259"]
|
[14, 26, 13, "RegExp match", "2409514259"]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@testing-library/user-event": "14.4.3",
|
"@testing-library/user-event": "14.4.3",
|
||||||
"@types/classnames": "^2.2.7",
|
"@types/classnames": "^2.2.7",
|
||||||
"@types/deep-freeze": "^0.1.1",
|
"@types/deep-freeze": "^0.1.1",
|
||||||
|
"@types/enzyme": "3.10.12",
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
"@types/jest": "29.2.3",
|
"@types/jest": "29.2.3",
|
||||||
"@types/lodash": "4.14.187",
|
"@types/lodash": "4.14.187",
|
||||||
|
|||||||
+3
-3
@@ -12,12 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { render, screen, within } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import GraphTicks from './GraphTicks';
|
import GraphTicks, { GraphTicksProps } from './GraphTicks';
|
||||||
|
|
||||||
const setup = (propOverrides) => {
|
const setup = (propOverrides?: GraphTicksProps) => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
items: [
|
items: [
|
||||||
{ valueWidth: 100, valueOffset: 25, serviceName: 'a' },
|
{ valueWidth: 100, valueOffset: 25, serviceName: 'a' },
|
||||||
@@ -27,7 +27,7 @@ const getStyles = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type GraphTicksProps = {
|
export type GraphTicksProps = {
|
||||||
numTicks: number;
|
numTicks: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -15,19 +15,19 @@
|
|||||||
import { render, screen, fireEvent, within } from '@testing-library/react';
|
import { render, screen, fireEvent, within } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Scrubber from './Scrubber';
|
import Scrubber, { ScrubberProps } from './Scrubber';
|
||||||
|
|
||||||
describe('<Scrubber>', () => {
|
describe('<Scrubber>', () => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
position: 0,
|
position: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let rerender;
|
let rerender: (arg0: JSX.Element) => void;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
({ rerender } = render(
|
({ rerender } = render(
|
||||||
<svg>
|
<svg>
|
||||||
<Scrubber {...defaultProps} />
|
<Scrubber {...(defaultProps as ScrubberProps)} />
|
||||||
</svg>
|
</svg>
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
@@ -45,7 +45,7 @@ describe('<Scrubber>', () => {
|
|||||||
it('calculates the correct x% for a timestamp', () => {
|
it('calculates the correct x% for a timestamp', () => {
|
||||||
rerender(
|
rerender(
|
||||||
<svg>
|
<svg>
|
||||||
<Scrubber {...defaultProps} position={0.5} />
|
<Scrubber {...(defaultProps as ScrubberProps)} position={0.5} />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
const line = screen.getByTestId('scrubber-component-line');
|
const line = screen.getByTestId('scrubber-component-line');
|
||||||
@@ -72,7 +72,7 @@ export const getStyles = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type ScrubberProps = {
|
export type ScrubberProps = {
|
||||||
isDragging: boolean;
|
isDragging: boolean;
|
||||||
position: number;
|
position: number;
|
||||||
onMouseDown: (evt: React.MouseEvent<any>) => void;
|
onMouseDown: (evt: React.MouseEvent<any>) => void;
|
||||||
|
|||||||
+45
-42
@@ -12,22 +12,23 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createTheme } from '@grafana/data';
|
import { createTheme } from '@grafana/data';
|
||||||
|
|
||||||
import { EUpdateTypes } from '../../utils/DraggableManager';
|
import { ViewRangeTime } from '../../TraceTimelineViewer/types';
|
||||||
|
import DraggableManager, { DraggingUpdate, EUpdateTypes } from '../../utils/DraggableManager';
|
||||||
import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame';
|
import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame';
|
||||||
|
|
||||||
import GraphTicks from './GraphTicks';
|
import GraphTicks from './GraphTicks';
|
||||||
import Scrubber from './Scrubber';
|
import Scrubber, { ScrubberProps } from './Scrubber';
|
||||||
import ViewingLayer, { dragTypes, getStyles } from './ViewingLayer';
|
import ViewingLayer, { dragTypes, getStyles, ViewingLayerProps, UnthemedViewingLayer } from './ViewingLayer';
|
||||||
|
|
||||||
function getViewRange(viewStart, viewEnd) {
|
function getViewRange(viewStart: number, viewEnd: number) {
|
||||||
return {
|
return {
|
||||||
time: {
|
time: {
|
||||||
current: [viewStart, viewEnd],
|
current: [viewStart, viewEnd] as [number, number],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -35,8 +36,8 @@ function getViewRange(viewStart, viewEnd) {
|
|||||||
describe('<SpanGraph>', () => {
|
describe('<SpanGraph>', () => {
|
||||||
polyfillAnimationFrame(window);
|
polyfillAnimationFrame(window);
|
||||||
|
|
||||||
let props;
|
let props: ViewingLayerProps;
|
||||||
let wrapper;
|
let wrapper: ShallowWrapper<ViewingLayerProps, {}, UnthemedViewingLayer>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
props = {
|
props = {
|
||||||
@@ -45,7 +46,8 @@ describe('<SpanGraph>', () => {
|
|||||||
updateNextViewRangeTime: jest.fn(),
|
updateNextViewRangeTime: jest.fn(),
|
||||||
updateViewRangeTime: jest.fn(),
|
updateViewRangeTime: jest.fn(),
|
||||||
viewRange: getViewRange(0, 1),
|
viewRange: getViewRange(0, 1),
|
||||||
};
|
} as unknown as ViewingLayerProps;
|
||||||
|
|
||||||
wrapper = shallow(<ViewingLayer {...props} />)
|
wrapper = shallow(<ViewingLayer {...props} />)
|
||||||
.dive()
|
.dive()
|
||||||
.dive();
|
.dive();
|
||||||
@@ -57,11 +59,12 @@ describe('<SpanGraph>', () => {
|
|||||||
wrapper = shallow(<ViewingLayer {...props} />)
|
wrapper = shallow(<ViewingLayer {...props} />)
|
||||||
.dive()
|
.dive()
|
||||||
.dive();
|
.dive();
|
||||||
|
|
||||||
wrapper.instance()._setRoot({
|
wrapper.instance()._setRoot({
|
||||||
getBoundingClientRect() {
|
getBoundingClientRect() {
|
||||||
return { left: 10, width: 100 };
|
return { left: 10, width: 100 };
|
||||||
},
|
},
|
||||||
});
|
} as SVGElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws if _root is not set', () => {
|
it('throws if _root is not set', () => {
|
||||||
@@ -105,81 +108,81 @@ describe('<SpanGraph>', () => {
|
|||||||
describe('reframe', () => {
|
describe('reframe', () => {
|
||||||
it('handles mousemove', () => {
|
it('handles mousemove', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
wrapper.instance()._handleReframeMouseMove({ value });
|
wrapper.instance()._handleReframeMouseMove({ value } as DraggingUpdate);
|
||||||
const calls = props.updateNextViewRangeTime.mock.calls;
|
const calls = jest.mocked(props.updateNextViewRangeTime).mock.calls;
|
||||||
expect(calls).toEqual([[{ cursor: value }]]);
|
expect(calls).toEqual([[{ cursor: value }]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles mouseleave', () => {
|
it('handles mouseleave', () => {
|
||||||
wrapper.instance()._handleReframeMouseLeave();
|
wrapper.instance()._handleReframeMouseLeave();
|
||||||
const calls = props.updateNextViewRangeTime.mock.calls;
|
const calls = jest.mocked(props.updateNextViewRangeTime).mock.calls;
|
||||||
expect(calls).toEqual([[{ cursor: null }]]);
|
expect(calls).toEqual([[{ cursor: null }]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('drag update', () => {
|
describe('drag update', () => {
|
||||||
it('handles sans anchor', () => {
|
it('handles sans anchor', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
wrapper.instance()._handleReframeDragUpdate({ value });
|
wrapper.instance()._handleReframeDragUpdate({ value } as DraggingUpdate);
|
||||||
const calls = props.updateNextViewRangeTime.mock.calls;
|
const calls = jest.mocked(props.updateNextViewRangeTime).mock.calls;
|
||||||
expect(calls).toEqual([[{ reframe: { anchor: value, shift: value } }]]);
|
expect(calls).toEqual([[{ reframe: { anchor: value, shift: value } }]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles the existing anchor', () => {
|
it('handles the existing anchor', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
const anchor = 0.1;
|
const anchor = 0.1;
|
||||||
const time = { ...props.viewRange.time, reframe: { anchor } };
|
const time = { ...props.viewRange.time, reframe: { anchor } } as ViewRangeTime;
|
||||||
props = { ...props, viewRange: { time } };
|
props = { ...props, viewRange: { time } };
|
||||||
wrapper = shallow(<ViewingLayer {...props} />)
|
wrapper = shallow(<ViewingLayer {...props} />)
|
||||||
.dive()
|
.dive()
|
||||||
.dive();
|
.dive();
|
||||||
wrapper.instance()._handleReframeDragUpdate({ value });
|
wrapper.instance()._handleReframeDragUpdate({ value } as DraggingUpdate);
|
||||||
const calls = props.updateNextViewRangeTime.mock.calls;
|
const calls = jest.mocked(props.updateNextViewRangeTime).mock.calls;
|
||||||
expect(calls).toEqual([[{ reframe: { anchor, shift: value } }]]);
|
expect(calls).toEqual([[{ reframe: { anchor, shift: value } }]]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('drag end', () => {
|
describe('drag end', () => {
|
||||||
let manager;
|
let manager: DraggableManager;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
manager = { resetBounds: jest.fn() };
|
manager = { resetBounds: jest.fn() } as unknown as DraggableManager;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles sans anchor', () => {
|
it('handles sans anchor', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
wrapper.instance()._handleReframeDragEnd({ manager, value });
|
wrapper.instance()._handleReframeDragEnd({ manager, value } as DraggingUpdate);
|
||||||
expect(manager.resetBounds.mock.calls).toEqual([[]]);
|
expect((manager.resetBounds as jest.Mock).mock.calls).toEqual([[]]);
|
||||||
const calls = props.updateViewRangeTime.mock.calls;
|
const calls = (props.updateViewRangeTime as jest.Mock).mock.calls;
|
||||||
expect(calls).toEqual([[value, value, 'minimap']]);
|
expect(calls).toEqual([[value, value, 'minimap']]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles dragged left (anchor is greater)', () => {
|
it('handles dragged left (anchor is greater)', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
const anchor = 0.6;
|
const anchor = 0.6;
|
||||||
const time = { ...props.viewRange.time, reframe: { anchor } };
|
const time = { ...props.viewRange.time, reframe: { anchor } } as ViewRangeTime;
|
||||||
props = { ...props, viewRange: { time } };
|
props = { ...props, viewRange: { time } };
|
||||||
wrapper = shallow(<ViewingLayer {...props} />)
|
wrapper = shallow(<ViewingLayer {...props} />)
|
||||||
.dive()
|
.dive()
|
||||||
.dive();
|
.dive();
|
||||||
wrapper.instance()._handleReframeDragEnd({ manager, value });
|
wrapper.instance()._handleReframeDragEnd({ manager, value } as DraggingUpdate);
|
||||||
|
|
||||||
expect(manager.resetBounds.mock.calls).toEqual([[]]);
|
expect((manager.resetBounds as jest.Mock).mock.calls).toEqual([[]]);
|
||||||
const calls = props.updateViewRangeTime.mock.calls;
|
const calls = (props.updateViewRangeTime as jest.Mock).mock.calls;
|
||||||
expect(calls).toEqual([[value, anchor, 'minimap']]);
|
expect(calls).toEqual([[value, anchor, 'minimap']]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles dragged right (anchor is less)', () => {
|
it('handles dragged right (anchor is less)', () => {
|
||||||
const value = 0.5;
|
const value = 0.5;
|
||||||
const anchor = 0.4;
|
const anchor = 0.4;
|
||||||
const time = { ...props.viewRange.time, reframe: { anchor } };
|
const time = { ...props.viewRange.time, reframe: { anchor } } as ViewRangeTime;
|
||||||
props = { ...props, viewRange: { time } };
|
props = { ...props, viewRange: { time } };
|
||||||
wrapper = shallow(<ViewingLayer {...props} />)
|
wrapper = shallow(<ViewingLayer {...props} />)
|
||||||
.dive()
|
.dive()
|
||||||
.dive();
|
.dive();
|
||||||
wrapper.instance()._handleReframeDragEnd({ manager, value });
|
wrapper.instance()._handleReframeDragEnd({ manager, value } as DraggingUpdate);
|
||||||
|
|
||||||
expect(manager.resetBounds.mock.calls).toEqual([[]]);
|
expect((manager.resetBounds as jest.Mock).mock.calls).toEqual([[]]);
|
||||||
const calls = props.updateViewRangeTime.mock.calls;
|
const calls = (props.updateViewRangeTime as jest.Mock).mock.calls;
|
||||||
expect(calls).toEqual([[anchor, value, 'minimap']]);
|
expect(calls).toEqual([[anchor, value, 'minimap']]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -187,12 +190,12 @@ describe('<SpanGraph>', () => {
|
|||||||
|
|
||||||
describe('scrubber', () => {
|
describe('scrubber', () => {
|
||||||
it('prevents the cursor from being drawn on scrubber mouseover', () => {
|
it('prevents the cursor from being drawn on scrubber mouseover', () => {
|
||||||
wrapper.instance()._handleScrubberEnterLeave({ type: EUpdateTypes.MouseEnter });
|
wrapper.instance()._handleScrubberEnterLeave({ type: EUpdateTypes.MouseEnter } as DraggingUpdate);
|
||||||
expect(wrapper.state('preventCursorLine')).toBe(true);
|
expect(wrapper.state('preventCursorLine')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prevents the cursor from being drawn on scrubber mouseleave', () => {
|
it('prevents the cursor from being drawn on scrubber mouseleave', () => {
|
||||||
wrapper.instance()._handleScrubberEnterLeave({ type: EUpdateTypes.MouseLeave });
|
wrapper.instance()._handleScrubberEnterLeave({ type: EUpdateTypes.MouseLeave } as DraggingUpdate);
|
||||||
expect(wrapper.state('preventCursorLine')).toBe(false);
|
expect(wrapper.state('preventCursorLine')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -203,7 +206,7 @@ describe('<SpanGraph>', () => {
|
|||||||
event: { stopPropagation },
|
event: { stopPropagation },
|
||||||
type: EUpdateTypes.DragStart,
|
type: EUpdateTypes.DragStart,
|
||||||
};
|
};
|
||||||
wrapper.instance()._handleScrubberDragUpdate(update);
|
wrapper.instance()._handleScrubberDragUpdate(update as unknown as DraggingUpdate);
|
||||||
expect(stopPropagation.mock.calls).toEqual([[]]);
|
expect(stopPropagation.mock.calls).toEqual([[]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -229,7 +232,7 @@ describe('<SpanGraph>', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
cases.forEach((_case) => {
|
cases.forEach((_case) => {
|
||||||
instance._handleScrubberDragUpdate(_case.dragUpdate);
|
instance._handleScrubberDragUpdate(_case.dragUpdate as DraggingUpdate);
|
||||||
expect(props.updateNextViewRangeTime).lastCalledWith(_case.viewRangeUpdate);
|
expect(props.updateNextViewRangeTime).lastCalledWith(_case.viewRangeUpdate);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -261,9 +264,9 @@ describe('<SpanGraph>', () => {
|
|||||||
const { manager } = _case.dragUpdate;
|
const { manager } = _case.dragUpdate;
|
||||||
wrapper.setState({ preventCursorLine: true });
|
wrapper.setState({ preventCursorLine: true });
|
||||||
expect(wrapper.state('preventCursorLine')).toBe(true);
|
expect(wrapper.state('preventCursorLine')).toBe(true);
|
||||||
instance._handleScrubberDragEnd(_case.dragUpdate);
|
instance._handleScrubberDragEnd(_case.dragUpdate as unknown as DraggingUpdate);
|
||||||
expect(wrapper.state('preventCursorLine')).toBe(false);
|
expect(wrapper.state('preventCursorLine')).toBe(false);
|
||||||
expect(manager.resetBounds.mock.calls).toEqual([[]]);
|
expect((manager.resetBounds as jest.Mock).mock.calls).toEqual([[]]);
|
||||||
expect(props.updateViewRangeTime).lastCalledWith(..._case.viewRangeUpdate, 'minimap');
|
expect(props.updateViewRangeTime).lastCalledWith(..._case.viewRangeUpdate, 'minimap');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -315,7 +318,7 @@ describe('<SpanGraph>', () => {
|
|||||||
|
|
||||||
const leftBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`);
|
const leftBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`);
|
||||||
expect(leftBox.length).toBe(1);
|
expect(leftBox.length).toBe(1);
|
||||||
const width = Number(leftBox.prop('width').slice(0, -1));
|
const width = Number(leftBox.prop('width')?.toString().slice(0, -1));
|
||||||
const x = leftBox.prop('x');
|
const x = leftBox.prop('x');
|
||||||
expect(Math.round(width)).toBe(20);
|
expect(Math.round(width)).toBe(20);
|
||||||
expect(x).toBe(0);
|
expect(x).toBe(0);
|
||||||
@@ -329,17 +332,17 @@ describe('<SpanGraph>', () => {
|
|||||||
|
|
||||||
const rightBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`);
|
const rightBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`);
|
||||||
expect(rightBox.length).toBe(1);
|
expect(rightBox.length).toBe(1);
|
||||||
const width = Number(rightBox.prop('width').slice(0, -1));
|
const width = Number(rightBox.prop('width')?.toString().slice(0, -1));
|
||||||
const x = Number(rightBox.prop('x').slice(0, -1));
|
const x = Number(rightBox.prop('x')?.toString().slice(0, -1));
|
||||||
expect(Math.round(width)).toBe(20);
|
expect(Math.round(width)).toBe(20);
|
||||||
expect(x).toBe(80);
|
expect(x).toBe(80);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders handles for the timeRangeFilter', () => {
|
it('renders handles for the timeRangeFilter', () => {
|
||||||
const [viewStart, viewEnd] = props.viewRange.time.current;
|
const [viewStart, viewEnd] = props.viewRange.time.current;
|
||||||
let scrubber = <Scrubber position={viewStart} />;
|
let scrubber = <Scrubber {...({ position: viewStart } as ScrubberProps)} />;
|
||||||
expect(wrapper.containsMatchingElement(scrubber)).toBeTruthy();
|
expect(wrapper.containsMatchingElement(scrubber)).toBeTruthy();
|
||||||
scrubber = <Scrubber position={viewEnd} />;
|
scrubber = <Scrubber {...({ position: viewEnd } as ScrubberProps)} />;
|
||||||
expect(wrapper.containsMatchingElement(scrubber)).toBeTruthy();
|
expect(wrapper.containsMatchingElement(scrubber)).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -89,7 +89,7 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
type ViewingLayerProps = {
|
export type ViewingLayerProps = {
|
||||||
height: number;
|
height: number;
|
||||||
numTicks: number;
|
numTicks: number;
|
||||||
updateViewRangeTime: TUpdateViewRangeTimeFunction;
|
updateViewRangeTime: TUpdateViewRangeTimeFunction;
|
||||||
|
|||||||
+7
-7
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import traceGenerator from '../../demo/trace-generators';
|
import traceGenerator from '../../demo/trace-generators';
|
||||||
@@ -21,9 +21,9 @@ import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnim
|
|||||||
|
|
||||||
import CanvasSpanGraph from './CanvasSpanGraph';
|
import CanvasSpanGraph from './CanvasSpanGraph';
|
||||||
import TickLabels from './TickLabels';
|
import TickLabels from './TickLabels';
|
||||||
import ViewingLayer from './ViewingLayer';
|
import ViewingLayer, { ViewingLayerProps, UnthemedViewingLayer } from './ViewingLayer';
|
||||||
|
|
||||||
import SpanGraph from './index';
|
import SpanGraph, { SpanGraphProps } from './index';
|
||||||
|
|
||||||
describe('<SpanGraph>', () => {
|
describe('<SpanGraph>', () => {
|
||||||
polyfillAnimationFrame(window);
|
polyfillAnimationFrame(window);
|
||||||
@@ -39,10 +39,10 @@ describe('<SpanGraph>', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let wrapper;
|
let wrapper: ShallowWrapper<ViewingLayerProps, {}, UnthemedViewingLayer>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(<SpanGraph {...props} />);
|
wrapper = shallow(<SpanGraph {...(props as unknown as SpanGraphProps)} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a <CanvasSpanGraph />', () => {
|
it('renders a <CanvasSpanGraph />', () => {
|
||||||
@@ -54,7 +54,7 @@ describe('<SpanGraph>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns a <div> if a trace is not provided', () => {
|
it('returns a <div> if a trace is not provided', () => {
|
||||||
wrapper = shallow(<SpanGraph {...props} trace={null} />);
|
wrapper = shallow(<SpanGraph {...({ ...props, trace: null } as unknown as SpanGraphProps)} />);
|
||||||
expect(wrapper.matchesElement(<div />)).toBeTruthy();
|
expect(wrapper.matchesElement(<div />)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ describe('<SpanGraph>', () => {
|
|||||||
|
|
||||||
it('passes items to CanvasSpanGraph', () => {
|
it('passes items to CanvasSpanGraph', () => {
|
||||||
const canvasGraph = wrapper.find(CanvasSpanGraph).first();
|
const canvasGraph = wrapper.find(CanvasSpanGraph).first();
|
||||||
const items = trace.spans.map((span) => ({
|
const items = trace?.spans.map((span) => ({
|
||||||
valueOffset: span.relativeStartTime,
|
valueOffset: span.relativeStartTime,
|
||||||
valueWidth: span.duration,
|
valueWidth: span.duration,
|
||||||
serviceName: span.process.serviceName,
|
serviceName: span.process.serviceName,
|
||||||
@@ -27,7 +27,7 @@ import ViewingLayer from './ViewingLayer';
|
|||||||
const DEFAULT_HEIGHT = 60;
|
const DEFAULT_HEIGHT = 60;
|
||||||
const TIMELINE_TICK_INTERVAL = 4;
|
const TIMELINE_TICK_INTERVAL = 4;
|
||||||
|
|
||||||
type SpanGraphProps = {
|
export type SpanGraphProps = {
|
||||||
height?: number;
|
height?: number;
|
||||||
trace: Trace;
|
trace: Trace;
|
||||||
viewRange: ViewRange;
|
viewRange: ViewRange;
|
||||||
|
|||||||
+25
-16
@@ -15,7 +15,6 @@
|
|||||||
import { range as _range } from 'lodash';
|
import { range as _range } from 'lodash';
|
||||||
|
|
||||||
import renderIntoCanvas, {
|
import renderIntoCanvas, {
|
||||||
BG_COLOR,
|
|
||||||
ITEM_ALPHA,
|
ITEM_ALPHA,
|
||||||
MIN_ITEM_HEIGHT,
|
MIN_ITEM_HEIGHT,
|
||||||
MAX_TOTAL_HEIGHT,
|
MAX_TOTAL_HEIGHT,
|
||||||
@@ -24,8 +23,10 @@ import renderIntoCanvas, {
|
|||||||
MAX_ITEM_HEIGHT,
|
MAX_ITEM_HEIGHT,
|
||||||
} from './render-into-canvas';
|
} from './render-into-canvas';
|
||||||
|
|
||||||
|
const BG_COLOR = '#FFFFFF';
|
||||||
|
|
||||||
const getCanvasWidth = () => window.innerWidth * 2;
|
const getCanvasWidth = () => window.innerWidth * 2;
|
||||||
const getBgFillRect = (items) => ({
|
const getBgFillRect = (items?: Array<{ valueWidth: number; valueOffset: number; serviceName: string }>) => ({
|
||||||
fillStyle: BG_COLOR,
|
fillStyle: BG_COLOR,
|
||||||
height: !items || items.length < MIN_TOTAL_HEIGHT ? MIN_TOTAL_HEIGHT : Math.min(MAX_TOTAL_HEIGHT, items.length),
|
height: !items || items.length < MIN_TOTAL_HEIGHT ? MIN_TOTAL_HEIGHT : Math.min(MAX_TOTAL_HEIGHT, items.length),
|
||||||
width: getCanvasWidth(),
|
width: getCanvasWidth(),
|
||||||
@@ -37,12 +38,15 @@ describe('renderIntoCanvas()', () => {
|
|||||||
const basicItem = { valueWidth: 100, valueOffset: 50, serviceName: 'some-name' };
|
const basicItem = { valueWidth: 100, valueOffset: 50, serviceName: 'some-name' };
|
||||||
|
|
||||||
class CanvasContext {
|
class CanvasContext {
|
||||||
|
fillStyle: undefined;
|
||||||
|
fillRectAccumulator: Array<{ fillStyle: undefined; height: number; width: number; x: number; y: number }> = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.fillStyle = undefined;
|
this.fillStyle = undefined;
|
||||||
this.fillRectAccumulator = [];
|
this.fillRectAccumulator = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
fillRect(x, y, width, height) {
|
fillRect(x: number, y: number, width: number, height: number) {
|
||||||
const fillStyle = this.fillStyle;
|
const fillStyle = this.fillStyle;
|
||||||
this.fillRectAccumulator.push({
|
this.fillRectAccumulator.push({
|
||||||
fillStyle,
|
fillStyle,
|
||||||
@@ -55,6 +59,11 @@ describe('renderIntoCanvas()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Canvas {
|
class Canvas {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
contexts: CanvasContext[];
|
||||||
|
getContext: jest.Mock;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.contexts = [];
|
this.contexts = [];
|
||||||
this.height = NaN;
|
this.height = NaN;
|
||||||
@@ -71,13 +80,13 @@ describe('renderIntoCanvas()', () => {
|
|||||||
|
|
||||||
function getColorFactory() {
|
function getColorFactory() {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const inputOutput = [];
|
const inputOutput: Array<{ input: string; output: [number, number, number] }> = [];
|
||||||
function getFakeColor(str) {
|
function getFakeColor(str: string) {
|
||||||
const rv = [i, i, i];
|
const rv: [number, number, number] = [i, i, i];
|
||||||
i++;
|
i++;
|
||||||
inputOutput.push({
|
inputOutput.push({
|
||||||
input: str,
|
input: str,
|
||||||
output: rv.slice(),
|
output: rv.slice() as [number, number, number],
|
||||||
});
|
});
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -88,7 +97,7 @@ describe('renderIntoCanvas()', () => {
|
|||||||
it('sets the width', () => {
|
it('sets the width', () => {
|
||||||
const canvas = new Canvas();
|
const canvas = new Canvas();
|
||||||
expect(canvas.width !== canvas.width).toBe(true);
|
expect(canvas.width !== canvas.width).toBe(true);
|
||||||
renderIntoCanvas(canvas, [basicItem], 150, getColorFactory());
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, [basicItem], 150, getColorFactory(), BG_COLOR);
|
||||||
expect(canvas.width).toBe(getCanvasWidth());
|
expect(canvas.width).toBe(getCanvasWidth());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -96,18 +105,18 @@ describe('renderIntoCanvas()', () => {
|
|||||||
it('sets the height', () => {
|
it('sets the height', () => {
|
||||||
const canvas = new Canvas();
|
const canvas = new Canvas();
|
||||||
expect(canvas.height !== canvas.height).toBe(true);
|
expect(canvas.height !== canvas.height).toBe(true);
|
||||||
renderIntoCanvas(canvas, [basicItem], 150, getColorFactory());
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, [basicItem], 150, getColorFactory(), BG_COLOR);
|
||||||
expect(canvas.height).toBe(MIN_TOTAL_HEIGHT);
|
expect(canvas.height).toBe(MIN_TOTAL_HEIGHT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('draws the background', () => {
|
it('draws the background', () => {
|
||||||
const expectedDrawing = [getBgFillRect()];
|
const expectedDrawing = [getBgFillRect()];
|
||||||
const canvas = new Canvas();
|
const canvas = new Canvas();
|
||||||
const items = [];
|
const items: Array<{ valueWidth: number; valueOffset: number; serviceName: string }> = [];
|
||||||
const totalValueWidth = 4000;
|
const totalValueWidth = 4000;
|
||||||
const getFillColor = getColorFactory();
|
const getFillColor = getColorFactory();
|
||||||
renderIntoCanvas(canvas, items, totalValueWidth, getFillColor);
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, items, totalValueWidth, getFillColor, BG_COLOR);
|
||||||
expect(canvas.getContext.mock.calls).toEqual([['2d', { alpha: false }]]);
|
expect((canvas.getContext as jest.Mock).mock.calls).toEqual([['2d', { alpha: false }]]);
|
||||||
expect(canvas.contexts.length).toBe(1);
|
expect(canvas.contexts.length).toBe(1);
|
||||||
expect(canvas.contexts[0].fillRectAccumulator).toEqual(expectedDrawing);
|
expect(canvas.contexts[0].fillRectAccumulator).toEqual(expectedDrawing);
|
||||||
});
|
});
|
||||||
@@ -141,7 +150,7 @@ describe('renderIntoCanvas()', () => {
|
|||||||
];
|
];
|
||||||
const canvas = new Canvas();
|
const canvas = new Canvas();
|
||||||
const getFillColor = getColorFactory();
|
const getFillColor = getColorFactory();
|
||||||
renderIntoCanvas(canvas, items, totalValueWidth, getFillColor);
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, items, totalValueWidth, getFillColor, BG_COLOR);
|
||||||
expect(getFillColor.inputOutput).toEqual(expectedColors);
|
expect(getFillColor.inputOutput).toEqual(expectedColors);
|
||||||
expect(canvas.getContext.mock.calls).toEqual([['2d', { alpha: false }]]);
|
expect(canvas.getContext.mock.calls).toEqual([['2d', { alpha: false }]]);
|
||||||
expect(canvas.contexts.length).toBe(1);
|
expect(canvas.contexts.length).toBe(1);
|
||||||
@@ -157,7 +166,7 @@ describe('renderIntoCanvas()', () => {
|
|||||||
items.push(basicItem);
|
items.push(basicItem);
|
||||||
}
|
}
|
||||||
expect(canvas.height !== canvas.height).toBe(true);
|
expect(canvas.height !== canvas.height).toBe(true);
|
||||||
renderIntoCanvas(canvas, items, 150, getColorFactory());
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, items, 150, getColorFactory(), BG_COLOR);
|
||||||
expect(canvas.height).toBe(items.length);
|
expect(canvas.height).toBe(items.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,9 +196,9 @@ describe('renderIntoCanvas()', () => {
|
|||||||
];
|
];
|
||||||
const canvas = new Canvas();
|
const canvas = new Canvas();
|
||||||
const getFillColor = getColorFactory();
|
const getFillColor = getColorFactory();
|
||||||
renderIntoCanvas(canvas, items, totalValueWidth, getFillColor);
|
renderIntoCanvas(canvas as unknown as HTMLCanvasElement, items, totalValueWidth, getFillColor, BG_COLOR);
|
||||||
expect(getFillColor.inputOutput).toEqual(expectedColors);
|
expect(getFillColor.inputOutput).toEqual(expectedColors);
|
||||||
expect(canvas.getContext.mock.calls).toEqual([['2d', { alpha: false }]]);
|
expect((canvas.getContext as jest.Mock).mock.calls).toEqual([['2d', { alpha: false }]]);
|
||||||
expect(canvas.contexts.length).toBe(1);
|
expect(canvas.contexts.length).toBe(1);
|
||||||
expect(canvas.contexts[0].fillRectAccumulator).toEqual(expectedDrawings);
|
expect(canvas.contexts[0].fillRectAccumulator).toEqual(expectedDrawings);
|
||||||
});
|
});
|
||||||
+8
-9
@@ -16,9 +16,8 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createTheme } from '@grafana/data';
|
import { createTheme } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
|
||||||
|
|
||||||
import TracePageSearchBar, { getStyles } from './TracePageSearchBar';
|
import TracePageSearchBar, { getStyles, TracePageSearchBarProps } from './TracePageSearchBar';
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
forwardedRef: React.createRef(),
|
forwardedRef: React.createRef(),
|
||||||
@@ -30,8 +29,8 @@ const defaultProps = {
|
|||||||
describe('<TracePageSearchBar>', () => {
|
describe('<TracePageSearchBar>', () => {
|
||||||
describe('truthy textFilter', () => {
|
describe('truthy textFilter', () => {
|
||||||
it('renders UiFindInput with correct props', () => {
|
it('renders UiFindInput with correct props', () => {
|
||||||
render(<TracePageSearchBar {...defaultProps} />);
|
render(<TracePageSearchBar {...(defaultProps as unknown as TracePageSearchBarProps)} />);
|
||||||
expect(screen.getByPlaceholderText('Find...')['value']).toEqual('value');
|
expect((screen.getByPlaceholderText('Find...') as HTMLInputElement)['value']).toEqual('value');
|
||||||
const suffix = screen.getByLabelText('Search bar suffix');
|
const suffix = screen.getByLabelText('Search bar suffix');
|
||||||
const theme = createTheme();
|
const theme = createTheme();
|
||||||
expect(suffix['className']).toBe(getStyles(theme).TracePageSearchBarSuffix);
|
expect(suffix['className']).toBe(getStyles(theme).TracePageSearchBarSuffix);
|
||||||
@@ -39,13 +38,13 @@ describe('<TracePageSearchBar>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders buttons', () => {
|
it('renders buttons', () => {
|
||||||
render(<TracePageSearchBar {...defaultProps} />);
|
render(<TracePageSearchBar {...(defaultProps as unknown as TracePageSearchBarProps)} />);
|
||||||
const nextResButton = screen.queryByRole('button', { name: 'Next results button' });
|
const nextResButton = screen.queryByRole('button', { name: 'Next results button' });
|
||||||
const prevResButton = screen.queryByRole('button', { name: 'Prev results button' });
|
const prevResButton = screen.queryByRole('button', { name: 'Prev results button' });
|
||||||
expect(nextResButton).toBeInTheDocument();
|
expect(nextResButton).toBeInTheDocument();
|
||||||
expect(prevResButton).toBeInTheDocument();
|
expect(prevResButton).toBeInTheDocument();
|
||||||
expect(nextResButton['disabled']).toBe(false);
|
expect((nextResButton as HTMLButtonElement)['disabled']).toBe(false);
|
||||||
expect(prevResButton['disabled']).toBe(false);
|
expect((prevResButton as HTMLButtonElement)['disabled']).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('only shows navigable buttons when navigable is true', () => {
|
it('only shows navigable buttons when navigable is true', () => {
|
||||||
@@ -53,7 +52,7 @@ describe('<TracePageSearchBar>', () => {
|
|||||||
...defaultProps,
|
...defaultProps,
|
||||||
navigable: false,
|
navigable: false,
|
||||||
};
|
};
|
||||||
render(<TracePageSearchBar {...props} />);
|
render(<TracePageSearchBar {...(props as unknown as TracePageSearchBarProps)} />);
|
||||||
expect(screen.queryByRole('button', { name: 'Next results button' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Next results button' })).not.toBeInTheDocument();
|
||||||
expect(screen.queryByRole('button', { name: 'Prev results button' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Prev results button' })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -65,7 +64,7 @@ describe('<TracePageSearchBar>', () => {
|
|||||||
...defaultProps,
|
...defaultProps,
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
};
|
};
|
||||||
render(<TracePageSearchBar {...props} />);
|
render(<TracePageSearchBar {...(props as unknown as TracePageSearchBarProps)} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render suffix', () => {
|
it('does not render suffix', () => {
|
||||||
@@ -69,7 +69,7 @@ export const getStyles = (theme: GrafanaTheme2) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type TracePageSearchBarProps = {
|
export type TracePageSearchBarProps = {
|
||||||
navigable: boolean;
|
navigable: boolean;
|
||||||
searchValue: string;
|
searchValue: string;
|
||||||
setSearch: (value: string) => void;
|
setSearch: (value: string) => void;
|
||||||
|
|||||||
@@ -4966,6 +4966,7 @@ __metadata:
|
|||||||
"@testing-library/user-event": 14.4.3
|
"@testing-library/user-event": 14.4.3
|
||||||
"@types/classnames": ^2.2.7
|
"@types/classnames": ^2.2.7
|
||||||
"@types/deep-freeze": ^0.1.1
|
"@types/deep-freeze": ^0.1.1
|
||||||
|
"@types/enzyme": 3.10.12
|
||||||
"@types/hoist-non-react-statics": ^3.3.1
|
"@types/hoist-non-react-statics": ^3.3.1
|
||||||
"@types/jest": 29.2.3
|
"@types/jest": 29.2.3
|
||||||
"@types/lodash": 4.14.187
|
"@types/lodash": 4.14.187
|
||||||
|
|||||||
Reference in New Issue
Block a user