Chore: Refactor the root of the TraceTimelineViewer folder to TS (#59748)

This commit is contained in:
Hamas Shafiq 2023-01-03 15:45:28 +00:00 committed by GitHub
parent 9d767b78d4
commit 0dffbcbca7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 153 additions and 121 deletions

View File

@ -20,8 +20,8 @@ exports[`no enzyme tests`] = {
"packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.tsx:3450948735": [
[15, 31, 13, "RegExp match", "2409514259"]
],
"packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js:551014442": [
[13, 26, 13, "RegExp match", "2409514259"]
"packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.tsx:3891071965": [
[13, 42, 13, "RegExp match", "2409514259"]
]
}`
};

View File

@ -18,7 +18,7 @@ import React from 'react';
import { selectors } from '@grafana/e2e-selectors';
import SpanBar from './SpanBar';
import SpanBar, { Props } from './SpanBar';
describe('<SpanBar>', () => {
const shortLabel = 'omg-so-awesome';
@ -32,7 +32,7 @@ describe('<SpanBar>', () => {
viewEnd: 1,
viewStart: 0,
theme: {},
getViewedBounds: (s) => {
getViewedBounds: (s: number) => {
// Log entries
if (s === 10) {
return { start: 0.1, end: 0.1 };
@ -76,7 +76,7 @@ describe('<SpanBar>', () => {
};
it('renders without exploding', async () => {
render(<SpanBar {...props} />);
render(<SpanBar {...(props as unknown as Props)} />);
expect(screen.getByText(shortLabel)).toBeInTheDocument();
expect(screen.queryByText(longLabel)).not.toBeInTheDocument();
@ -91,7 +91,7 @@ describe('<SpanBar>', () => {
it('log markers count', () => {
// 3 log entries, two grouped together with the same timestamp
render(<SpanBar {...props} />);
render(<SpanBar {...(props as unknown as Props)} />);
expect(screen.getAllByTestId('SpanBar--logMarker')).toHaveLength(2);
});
});

View File

@ -93,7 +93,7 @@ const getStyles = (theme: GrafanaTheme2) => {
};
};
type Props = {
export type Props = {
color: string;
onClick?: (evt: React.MouseEvent<any>) => void;
viewEnd: number;

View File

@ -15,10 +15,12 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { SpanLinks } from 'src/types/links';
import { TraceSpan } from 'src/types/trace';
import { NONE, DURATION, TAG } from '../settings/SpanBarSettings';
import SpanBarRow from './SpanBarRow';
import SpanBarRow, { SpanBarRowProps } from './SpanBarRow';
describe('<SpanBarRow>', () => {
const spanID = 'some-id';
@ -62,11 +64,11 @@ describe('<SpanBarRow>', () => {
});
it('renders without exploding', () => {
expect(() => render(<SpanBarRow {...props} />)).not.toThrow();
expect(() => render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />)).not.toThrow();
});
it('escalates detail toggling', async () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
const { onDetailToggled } = props;
expect(onDetailToggled.mock.calls.length).toBe(0);
await userEvent.click(screen.getByTestId('span-view'));
@ -74,7 +76,7 @@ describe('<SpanBarRow>', () => {
});
it('escalates children toggling', async () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
const { onChildrenToggled } = props;
expect(onChildrenToggled.mock.calls.length).toBe(0);
await userEvent.click(screen.getByTestId('icon-wrapper'));
@ -82,7 +84,7 @@ describe('<SpanBarRow>', () => {
});
it('render references button', () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
const newSpan = Object.assign({}, props.span);
const span = Object.assign(newSpan, {
references: [
@ -103,22 +105,24 @@ describe('<SpanBarRow>', () => {
},
},
],
});
}) as unknown as TraceSpan;
render(
<SpanBarRow
{...props}
{...(props as unknown as SpanBarRowProps)}
span={span}
createSpanLink={() => ({
traceLinks: [{ href: 'href' }, { href: 'href' }],
})}
createSpanLink={() =>
({
traceLinks: [{ href: 'href' }, { href: 'href' }],
} as SpanLinks)
}
/>
);
expect(screen.getAllByTestId('SpanLinksMenu')).toHaveLength(1);
});
it('render referenced to by single span', () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
const span = Object.assign(
{
subsidiarilyReferencedBy: [
@ -133,21 +137,23 @@ describe('<SpanBarRow>', () => {
],
},
props.span
);
) as unknown as TraceSpan;
render(
<SpanBarRow
{...props}
{...(props as unknown as SpanBarRowProps)}
span={span}
createSpanLink={() => ({
traceLinks: [{ content: 'This span is referenced by another span', href: 'href' }],
})}
createSpanLink={() =>
({
traceLinks: [{ content: 'This span is referenced by another span', href: 'href' }],
} as SpanLinks)
}
/>
);
expect(screen.getByRole('link', { name: 'This span is referenced by another span' })).toBeInTheDocument();
});
it('render referenced to by multiple span', () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
const span = Object.assign(
{
subsidiarilyReferencedBy: [
@ -170,14 +176,16 @@ describe('<SpanBarRow>', () => {
],
},
props.span
);
) as unknown as TraceSpan;
render(
<SpanBarRow
{...props}
{...(props as unknown as SpanBarRowProps)}
span={span}
createSpanLink={() => ({
traceLinks: [{ href: 'href' }, { href: 'href' }],
})}
createSpanLink={() =>
({
traceLinks: [{ href: 'href' }, { href: 'href' }],
} as SpanLinks)
}
/>
);
expect(screen.getAllByTestId('SpanLinksMenu')).toHaveLength(1);
@ -185,7 +193,7 @@ describe('<SpanBarRow>', () => {
describe('render span bar label', () => {
it('with default value', () => {
render(<SpanBarRow {...props} />);
render(<SpanBarRow {...(props as unknown as SpanBarRowProps)} />);
expect(screen.getByText('(9ms)')).toBeInTheDocument();
});
@ -198,7 +206,7 @@ describe('<SpanBarRow>', () => {
},
props
);
render(<SpanBarRow {...testProps} />);
render(<SpanBarRow {...(testProps as unknown as SpanBarRowProps)} />);
expect(screen.queryByText('(9ms)')).not.toBeInTheDocument();
});
@ -211,7 +219,7 @@ describe('<SpanBarRow>', () => {
},
props
);
render(<SpanBarRow {...testProps} />);
render(<SpanBarRow {...(testProps as unknown as SpanBarRowProps)} />);
expect(screen.getByText('(9ms)')).toBeInTheDocument();
});
@ -236,7 +244,7 @@ describe('<SpanBarRow>', () => {
},
}
);
render(<SpanBarRow {...testProps} />);
render(<SpanBarRow {...(testProps as unknown as SpanBarRowProps)} />);
expect(screen.getByText('(tag-value)')).toBeInTheDocument();
});
@ -263,7 +271,7 @@ describe('<SpanBarRow>', () => {
},
}
);
render(<SpanBarRow {...testProps} />);
render(<SpanBarRow {...(testProps as unknown as SpanBarRowProps)} />);
expect(screen.getByText('(process-value)')).toBeInTheDocument();
});
});

View File

@ -290,7 +290,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
};
});
type SpanBarRowProps = {
export type SpanBarRowProps = {
className?: string;
theme: GrafanaTheme2;
color: string;

View File

@ -19,7 +19,7 @@ import React from 'react';
import { createTheme } from '@grafana/data';
import DetailState from './SpanDetail/DetailState';
import { UnthemedSpanDetailRow } from './SpanDetailRow';
import { UnthemedSpanDetailRow, SpanDetailRowProps } from './SpanDetailRow';
const testSpan = {
spanID: 'testSpanID',
@ -30,7 +30,7 @@ const testSpan = {
tags: [{ key: 'tag-key', value: 'tag-value' }],
},
};
const setup = (propOverrides) => {
const setup = (propOverrides?: SpanDetailRowProps) => {
const props = {
color: 'some-color',
columnDivision: 0.5,
@ -48,7 +48,7 @@ const setup = (propOverrides) => {
theme: createTheme(),
...propOverrides,
};
return render(<UnthemedSpanDetailRow {...props} />);
return render(<UnthemedSpanDetailRow {...(props as SpanDetailRowProps)} />);
};
describe('SpanDetailRow tests', () => {
@ -58,7 +58,7 @@ describe('SpanDetailRow tests', () => {
it('calls toggle on click', async () => {
const mockToggle = jest.fn();
setup({ onDetailToggled: mockToggle });
setup({ onDetailToggled: mockToggle } as unknown as SpanDetailRowProps);
expect(mockToggle).not.toHaveBeenCalled();
const detailRow = screen.getByTestId('detail-row-expanded-accent');

View File

@ -71,7 +71,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
};
});
type SpanDetailRowProps = {
export type SpanDetailRowProps = {
color: string;
columnDivision: number;
detailState: DetailState;

View File

@ -15,12 +15,13 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { TraceSpan } from 'src/types/trace';
import { createTheme } from '@grafana/data';
import spanAncestorIdsSpy from '../utils/span-ancestor-ids';
import SpanTreeOffset, { getStyles } from './SpanTreeOffset';
import SpanTreeOffset, { getStyles, TProps } from './SpanTreeOffset';
jest.mock('../utils/span-ancestor-ids');
@ -29,11 +30,11 @@ describe('SpanTreeOffset', () => {
const parentSpanID = 'parentSpanID';
const rootSpanID = 'rootSpanID';
const specialRootID = 'root';
let props;
let props: TProps;
beforeEach(() => {
// Mock implementation instead of Mock return value so that each call returns a new array (like normal)
spanAncestorIdsSpy.mockImplementation(() => [parentSpanID, rootSpanID]);
jest.mocked(spanAncestorIdsSpy).mockImplementation(() => [parentSpanID, rootSpanID]);
props = {
addHoverIndentGuideId: jest.fn(),
hoverIndentGuideIds: new Set(),
@ -41,13 +42,13 @@ describe('SpanTreeOffset', () => {
span: {
hasChildren: false,
spanID: ownSpanID,
},
};
} as TraceSpan,
} as unknown as TProps;
});
describe('.SpanTreeOffset--indentGuide', () => {
it('renders only one SpanTreeOffset--indentGuide for entire trace if span has no ancestors', () => {
spanAncestorIdsSpy.mockReturnValue([]);
jest.mocked(spanAncestorIdsSpy).mockReturnValue([]);
render(<SpanTreeOffset {...props} />);
const indentGuide = screen.getByTestId('SpanTreeOffset--indentGuide');
expect(indentGuide).toBeInTheDocument();
@ -75,7 +76,7 @@ describe('SpanTreeOffset', () => {
it('calls props.addHoverIndentGuideId on mouse enter', async () => {
render(<SpanTreeOffset {...props} />);
const span = document.querySelector(`[data-ancestor-id=${parentSpanID}]`);
await userEvent.hover(span);
await userEvent.hover(span!);
expect(props.addHoverIndentGuideId).toHaveBeenCalledTimes(1);
expect(props.addHoverIndentGuideId).toHaveBeenCalledWith(parentSpanID);
});
@ -83,7 +84,7 @@ describe('SpanTreeOffset', () => {
it('calls props.removeHoverIndentGuideId on mouse leave', async () => {
render(<SpanTreeOffset {...props} />);
const span = document.querySelector(`[data-ancestor-id=${parentSpanID}]`);
await userEvent.unhover(span);
await userEvent.unhover(span!);
expect(props.removeHoverIndentGuideId).toHaveBeenCalledTimes(1);
expect(props.removeHoverIndentGuideId).toHaveBeenCalledWith(parentSpanID);
});

View File

@ -67,7 +67,7 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2) => {
};
});
type TProps = {
export type TProps = {
childrenVisible?: boolean;
onClick?: () => void;
span: TraceSpan;

View File

@ -11,26 +11,32 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { shallow, mount } from 'enzyme';
import { shallow, mount, ShallowWrapper } from 'enzyme';
import React from 'react';
import { TNil } from 'src/types';
import { Trace, TraceSpan } from 'src/types/trace';
import traceGenerator from '../demo/trace-generators';
import transformTraceData from '../model/transform-trace-data';
import ListView from './ListView';
import SpanBarRow from './SpanBarRow';
import SpanBarRow, { SpanBarRowProps } from './SpanBarRow';
import DetailState from './SpanDetail/DetailState';
import SpanDetailRow from './SpanDetailRow';
import SpanDetailRow, { SpanDetailRowProps } from './SpanDetailRow';
import SpanTreeOffset from './SpanTreeOffset';
import VirtualizedTraceView, { DEFAULT_HEIGHTS } from './VirtualizedTraceView';
import VirtualizedTraceView, {
DEFAULT_HEIGHTS,
UnthemedVirtualizedTraceView,
VirtualizedTraceViewProps,
} from './VirtualizedTraceView';
jest.mock('./SpanTreeOffset');
describe('<VirtualizedTraceViewImpl>', () => {
let wrapper;
let instance;
let wrapper: ShallowWrapper<VirtualizedTraceViewProps, {}, UnthemedVirtualizedTraceView>;
let instance: UnthemedVirtualizedTraceView;
const trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 10 }));
const trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 10 }))!;
const topOfExploreViewRef = jest.fn();
const props = {
childrenHiddenIDs: new Set(),
@ -53,9 +59,9 @@ describe('<VirtualizedTraceViewImpl>', () => {
trace,
uiFind: 'uiFind',
topOfExploreViewRef,
};
} as unknown as VirtualizedTraceViewProps;
function expandRow(rowIndex) {
function expandRow(rowIndex: number) {
const detailStates = new Map();
const detailState = new DetailState();
detailStates.set(trace.spans[rowIndex].spanID, detailState);
@ -73,26 +79,26 @@ describe('<VirtualizedTraceViewImpl>', () => {
{ depth: 2 },
{ depth: 3 },
...trace.spans.slice(1),
];
] as TraceSpan[];
const _trace = { ...trace, spans };
wrapper.setProps({ childrenHiddenIDs, trace: _trace });
return spans;
}
function updateSpan(srcTrace, spanIndex, update) {
function updateSpan(srcTrace: Trace, spanIndex: number, update: Partial<TraceSpan>) {
const span = { ...srcTrace.spans[spanIndex], ...update };
const spans = [...srcTrace.spans.slice(0, spanIndex), span, ...srcTrace.spans.slice(spanIndex + 1)];
return { ...srcTrace, spans };
}
beforeEach(() => {
SpanTreeOffset.mockReturnValue(<div />);
jest.mocked(SpanTreeOffset).mockReturnValue(<div />);
Object.keys(props).forEach((key) => {
if (typeof props[key] === 'function') {
props[key].mockReset();
if (typeof props[key as keyof VirtualizedTraceViewProps] === 'function') {
(props[key as keyof VirtualizedTraceViewProps] as jest.Mock).mockReset();
}
});
wrapper = shallow(<VirtualizedTraceView {...props} />)
wrapper = shallow(<VirtualizedTraceView {...(props as unknown as VirtualizedTraceViewProps)} />)
.dive()
.dive();
instance = wrapper.instance();
@ -103,7 +109,7 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
it('renders when a trace is not set', () => {
wrapper.setProps({ trace: null });
wrapper.setProps({ trace: null as unknown as Trace });
expect(wrapper).toBeDefined();
});
@ -116,17 +122,28 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
it('sets the trace for global state.traceTimeline', () => {
expect(props.setTrace.mock.calls).toEqual([[trace, props.uiFind]]);
props.setTrace.mockReset();
expect(jest.mocked(props.setTrace).mock.calls).toEqual([[trace, props.uiFind]]);
expect(jest.mocked(props.setTrace).mock.calls).toEqual([[trace, props.uiFind]]);
jest.mocked(props.setTrace).mockReset();
const traceID = 'some-other-id';
const _trace = { ...trace, traceID };
wrapper.setProps({ trace: _trace });
expect(props.setTrace.mock.calls).toEqual([[_trace, props.uiFind]]);
expect(jest.mocked(props.setTrace).mock.calls).toEqual([[_trace, props.uiFind]]);
});
describe('props.registerAccessors', () => {
let lv;
let expectedArg;
let lv: ListView;
let expectedArg: {
getBottomRowIndexVisible: () => void;
getTopRowIndexVisible: () => void;
getViewHeight: () => number;
getRowPosition: (index: number) => { height: number; y: number };
getViewRange: () => [number, number];
getSearchedSpanIDs: () => Set<string> | TNil;
getCollapsedChildren: () => Set<string>;
mapRowIndexToSpanIndex: (index: number) => number;
mapSpanIndexToRowIndex: (index: number) => number;
};
beforeEach(() => {
const getBottomRowIndexVisible = () => {};
@ -136,7 +153,7 @@ describe('<VirtualizedTraceViewImpl>', () => {
getBottomVisibleIndex: getBottomRowIndexVisible,
getTopVisibleIndex: getTopRowIndexVisible,
getRowPosition: () => {},
};
} as unknown as ListView;
expectedArg = {
getBottomRowIndexVisible,
getTopRowIndexVisible,
@ -151,9 +168,9 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
it('invokes when the listView is set', () => {
expect(props.registerAccessors.mock.calls.length).toBe(0);
expect(jest.mocked(props.registerAccessors).mock.calls.length).toBe(0);
instance.setListView(lv);
expect(props.registerAccessors.mock.calls).toEqual([[expectedArg]]);
expect(jest.mocked(props.registerAccessors).mock.calls).toEqual([[expectedArg]]);
});
it('invokes when registerAccessors changes', () => {
@ -169,13 +186,13 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
it('returns findMatchesIDs via getSearchedSpanIDs()', () => {
const findMatchesIDs = new Set();
const findMatchesIDs: Set<string> = new Set();
wrapper.setProps({ findMatchesIDs });
expect(instance.getSearchedSpanIDs()).toBe(findMatchesIDs);
});
it('returns childrenHiddenIDs via getCollapsedChildren()', () => {
const childrenHiddenIDs = new Set();
const childrenHiddenIDs: Set<string> = new Set();
wrapper.setProps({ childrenHiddenIDs });
expect(instance.getCollapsedChildren()).toBe(childrenHiddenIDs);
});
@ -228,7 +245,7 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
describe('getKeyFromIndex() generates a "key" from a row index', () => {
function verify(input, output) {
function verify(input: number, output: string) {
expect(instance.getKeyFromIndex(input)).toBe(output);
}
@ -251,7 +268,7 @@ describe('<VirtualizedTraceViewImpl>', () => {
});
describe('getIndexFromKey() converts a "key" to the corresponding row index', () => {
function verify(input, output) {
function verify(input: string, output: number) {
expect(instance.getIndexFromKey(input)).toBe(output);
}
@ -301,23 +318,25 @@ describe('<VirtualizedTraceViewImpl>', () => {
it('renders a SpanBarRow when it is not a detail', () => {
const span = trace.spans[1];
const row = instance.renderRow('some-key', {}, 1, {});
const rowWrapper = shallow(row);
const rowWrapper = shallow(row!);
expect(
rowWrapper.containsMatchingElement(
<SpanBarRow
clippingLeft={instance.getClipping().left}
clippingRight={instance.getClipping().right}
columnDivision={props.spanNameColumnWidth}
isChildrenExpanded
isDetailExpanded={false}
isMatchingFilter={false}
numTicks={5}
onDetailToggled={props.detailToggle}
onChildrenToggled={props.childrenToggle}
rpc={undefined}
showErrorIcon={false}
span={span}
{...({
clippingLeft: instance.getClipping().left,
clippingRight: instance.getClipping().right,
columnDivision: props.spanNameColumnWidth,
isChildrenExpanded: true,
isDetailExpanded: false,
isMatchingFilter: false,
numTicks: 5,
onDetailToggled: props.detailToggle,
onChildrenToggled: props.childrenToggle,
rpc: undefined,
showErrorIcon: false,
span: span,
} as unknown as SpanBarRowProps)}
/>
)
).toBe(true);
@ -331,7 +350,7 @@ describe('<VirtualizedTraceViewImpl>', () => {
const childrenHiddenIDs = new Set([altTrace.spans[0].spanID]);
wrapper.setProps({ childrenHiddenIDs, trace: altTrace });
const rowWrapper = mount(instance.renderRow('some-key', {}, 0, {}));
const rowWrapper = mount(instance.renderRow('some-key', {}, 0, {})!);
const spanBarRow = rowWrapper.find(SpanBarRow);
expect(spanBarRow.length).toBe(1);
expect(spanBarRow.prop('rpc')).toBeDefined();
@ -341,18 +360,20 @@ describe('<VirtualizedTraceViewImpl>', () => {
const detailState = expandRow(1);
const span = trace.spans[1];
const row = instance.renderRow('some-key', {}, 2, {});
const rowWrapper = shallow(row);
const rowWrapper = shallow(row!);
expect(
rowWrapper.containsMatchingElement(
<SpanDetailRow
columnDivision={props.spanNameColumnWidth}
onDetailToggled={props.detailToggle}
detailState={detailState}
logItemToggle={props.detailLogItemToggle}
logsToggle={props.detailLogsToggle}
processToggle={props.detailProcessToggle}
span={span}
tagsToggle={props.detailTagsToggle}
{...({
columnDivision: props.spanNameColumnWidth,
onDetailToggled: props.detailToggle,
detailState: detailState,
logItemToggle: props.detailLogItemToggle,
logsToggle: props.detailLogsToggle,
processToggle: props.detailProcessToggle,
span: span,
tagsToggle: props.detailTagsToggle,
} as unknown as SpanDetailRowProps)}
/>
)
).toBe(true);
@ -361,15 +382,15 @@ describe('<VirtualizedTraceViewImpl>', () => {
it('renders a SpanBarRow with a client span and no instrumented server span', () => {
const externServiceName = 'externalServiceTest';
const leafSpan = trace.spans.find((span) => !span.hasChildren);
const leafSpanIndex = trace.spans.indexOf(leafSpan);
const leafSpanIndex = trace.spans.indexOf(leafSpan!);
const clientTags = [
{ key: 'span.kind', value: 'client' },
{ key: 'peer.service', value: externServiceName },
...leafSpan.tags,
...leafSpan!.tags,
];
const altTrace = updateSpan(trace, leafSpanIndex, { tags: clientTags });
wrapper.setProps({ trace: altTrace });
const rowWrapper = mount(instance.renderRow('some-key', {}, leafSpanIndex, {}));
const rowWrapper = mount(instance.renderRow('some-key', {}, leafSpanIndex, {})!);
const spanBarRow = rowWrapper.find(SpanBarRow);
expect(spanBarRow.length).toBe(1);
expect(spanBarRow.prop('noInstrumentedServer')).not.toBeNull();
@ -380,8 +401,8 @@ describe('<VirtualizedTraceViewImpl>', () => {
const propsWithTrueShouldScrollToFirstUiFindMatch = { ...props, shouldScrollToFirstUiFindMatch: true };
beforeEach(() => {
props.scrollToFirstVisibleSpan.mockReset();
props.clearShouldScrollToFirstUiFindMatch.mockReset();
jest.mocked(props.scrollToFirstVisibleSpan).mockReset();
jest.mocked(props.clearShouldScrollToFirstUiFindMatch).mockReset();
});
it('calls props.scrollToFirstVisibleSpan if shouldScrollToFirstUiFindMatch is true', () => {

View File

@ -117,7 +117,7 @@ type TVirtualizedTraceViewOwnProps = {
topOfViewRefType?: TopOfViewRefType;
};
type VirtualizedTraceViewProps = TVirtualizedTraceViewOwnProps & TExtractUiFindFromStateReturn & TTraceTimeline;
export type VirtualizedTraceViewProps = TVirtualizedTraceViewOwnProps & TExtractUiFindFromStateReturn & TTraceTimeline;
// export for tests
export const DEFAULT_HEIGHTS = {

View File

@ -21,7 +21,7 @@ import { createTheme } from '@grafana/data';
import traceGenerator from '../demo/trace-generators';
import transformTraceData from '../model/transform-trace-data';
import TraceTimelineViewer from './index';
import TraceTimelineViewer, { TProps } from './index';
jest.mock('@grafana/runtime', () => {
return {
@ -62,11 +62,11 @@ describe('<TraceTimelineViewer>', () => {
};
it('it does not explode', () => {
expect(() => render(<TraceTimelineViewer {...props} />)).not.toThrow();
expect(() => render(<TraceTimelineViewer {...(props as unknown as TProps)} />)).not.toThrow();
});
it('it sets up actions', async () => {
render(<TraceTimelineViewer {...props} />);
render(<TraceTimelineViewer {...(props as unknown as TProps)} />);
const expandOne = screen.getByRole('button', { name: 'Expand +1' });
const collapseOne = screen.getByRole('button', { name: 'Collapse +1' });

View File

@ -71,7 +71,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
};
});
type TProps = TExtractUiFindFromStateReturn & {
export type TProps = TExtractUiFindFromStateReturn & {
registerAccessors: (accessors: Accessors) => void;
findMatchesIDs: Set<string> | TNil;
scrollToFirstVisibleSpan: () => void;

View File

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { TraceSpan } from 'src/types/trace';
import traceGenerator from '../demo/trace-generators';
import {
@ -22,7 +24,6 @@ import {
isServerSpan,
spanContainsErredSpan,
spanHasTag,
formatNumber,
} from './utils';
describe('TraceTimelineViewer/utils', () => {
@ -58,11 +59,11 @@ describe('TraceTimelineViewer/utils', () => {
describe('spanHasTag() and variants', () => {
it('returns true iff the key/value pair is found', () => {
const tags = traceGenerator.tags();
tags.push({ key: 'span.kind', value: 'server' });
expect(spanHasTag('span.kind', 'client', { tags })).toBe(false);
expect(spanHasTag('span.kind', 'client', { tags })).toBe(false);
expect(spanHasTag('span.kind', 'server', { tags })).toBe(true);
const span = traceGenerator.span;
span.tags = [{ key: 'span.kind', value: 'server' }];
expect(spanHasTag('span.kind', 'client', span)).toBe(false);
expect(spanHasTag('span.kind', 'client', span)).toBe(false);
expect(spanHasTag('span.kind', 'server', span)).toBe(true);
});
const spanTypeTestCases = [
@ -75,7 +76,7 @@ describe('TraceTimelineViewer/utils', () => {
spanTypeTestCases.forEach((testCase) => {
const msg = `${testCase.name}() is true only when a ${testCase.key}=${testCase.value} tag is present`;
it(msg, () => {
const span = { tags: traceGenerator.tags() };
const span = { tags: traceGenerator.tags() } as TraceSpan;
expect(testCase.fn(span)).toBe(false);
span.tags.push(testCase);
expect(testCase.fn(span)).toBe(true);
@ -86,7 +87,8 @@ describe('TraceTimelineViewer/utils', () => {
describe('spanContainsErredSpan()', () => {
it('returns true only when a descendant has an error tag', () => {
const errorTag = { key: 'error', type: 'bool', value: true };
const getTags = (withError) => (withError ? traceGenerator.tags().concat(errorTag) : traceGenerator.tags());
const getTags = (withError: number) =>
withError ? traceGenerator.tags().concat(errorTag) : traceGenerator.tags();
// Using a string to generate the test spans. Each line results in a span. The
// left number indicates whether or not the generated span has a descendant
@ -114,7 +116,7 @@ describe('TraceTimelineViewer/utils', () => {
const spans = config.map((line) => ({
depth: line.length,
tags: getTags(+line.slice(-1)),
}));
})) as TraceSpan[];
expectations.forEach((target, i) => {
// include the index in the expect condition to know which span failed
@ -126,7 +128,7 @@ describe('TraceTimelineViewer/utils', () => {
});
describe('findServerChildSpan()', () => {
let spans;
let spans: TraceSpan[];
beforeEach(() => {
spans = [
@ -135,7 +137,7 @@ describe('TraceTimelineViewer/utils', () => {
{ depth: 1, tags: [{ key: 'span.kind', value: 'server' }] },
{ depth: 1, tags: [{ key: 'span.kind', value: 'third-kind' }] },
{ depth: 1, tags: [{ key: 'span.kind', value: 'server' }] },
];
] as TraceSpan[];
});
it('returns falsy if the frist span is not a client', () => {