mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Refactor the root of the TraceTimelineViewer
folder to TS (#59748)
This commit is contained in:
parent
9d767b78d4
commit
0dffbcbca7
@ -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"]
|
||||
]
|
||||
}`
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
@ -93,7 +93,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
};
|
||||
};
|
||||
|
||||
type Props = {
|
||||
export type Props = {
|
||||
color: string;
|
||||
onClick?: (evt: React.MouseEvent<any>) => void;
|
||||
viewEnd: number;
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
@ -290,7 +290,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
|
||||
};
|
||||
});
|
||||
|
||||
type SpanBarRowProps = {
|
||||
export type SpanBarRowProps = {
|
||||
className?: string;
|
||||
theme: GrafanaTheme2;
|
||||
color: string;
|
||||
|
@ -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');
|
@ -71,7 +71,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
|
||||
};
|
||||
});
|
||||
|
||||
type SpanDetailRowProps = {
|
||||
export type SpanDetailRowProps = {
|
||||
color: string;
|
||||
columnDivision: number;
|
||||
detailState: DetailState;
|
||||
|
@ -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);
|
||||
});
|
@ -67,7 +67,7 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2) => {
|
||||
};
|
||||
});
|
||||
|
||||
type TProps = {
|
||||
export type TProps = {
|
||||
childrenVisible?: boolean;
|
||||
onClick?: () => void;
|
||||
span: TraceSpan;
|
||||
|
@ -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', () => {
|
@ -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 = {
|
||||
|
@ -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' });
|
@ -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;
|
||||
|
@ -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', () => {
|
Loading…
Reference in New Issue
Block a user