mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Convert VirtualizedTraceView.test.tsx to RTL (#61589)
* Chore: Convert VirtualizedTraceView.test.tsx to RTL * Don't need to change shared component Co-authored-by: André Pereira <adrapereira@gmail.com>
This commit is contained in:
@@ -7,9 +7,6 @@ exports[`no enzyme tests`] = {
|
|||||||
value: `{
|
value: `{
|
||||||
"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/TraceTimelineViewer/VirtualizedTraceView.test.tsx:3891071965": [
|
|
||||||
[13, 42, 13, "RegExp match", "2409514259"]
|
|
||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { styleMixins, useStyles2 } from '../../themes';
|
|||||||
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
|
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
|
||||||
import { getPropertiesForVariant } from '../Button';
|
import { getPropertiesForVariant } from '../Button';
|
||||||
import { Icon } from '../Icon/Icon';
|
import { Icon } from '../Icon/Icon';
|
||||||
import { Tooltip } from '../Tooltip/Tooltip';
|
import { Tooltip } from '../Tooltip';
|
||||||
|
|
||||||
type CommonProps = {
|
type CommonProps = {
|
||||||
/** Icon name */
|
/** Icon name */
|
||||||
|
|||||||
@@ -11,86 +11,44 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// 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, mount, ShallowWrapper } from 'enzyme';
|
import { render, screen } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TNil } from 'src/types';
|
import { Trace } from 'src/types/trace';
|
||||||
import { Trace, TraceSpan } from 'src/types/trace';
|
|
||||||
|
|
||||||
import traceGenerator from '../demo/trace-generators';
|
import traceGenerator from '../demo/trace-generators';
|
||||||
import transformTraceData from '../model/transform-trace-data';
|
import transformTraceData from '../model/transform-trace-data';
|
||||||
|
|
||||||
import ListView from './ListView';
|
|
||||||
import SpanBarRow, { SpanBarRowProps } from './SpanBarRow';
|
|
||||||
import DetailState from './SpanDetail/DetailState';
|
|
||||||
import SpanDetailRow, { SpanDetailRowProps } from './SpanDetailRow';
|
|
||||||
import SpanTreeOffset from './SpanTreeOffset';
|
import SpanTreeOffset from './SpanTreeOffset';
|
||||||
import VirtualizedTraceView, {
|
import VirtualizedTraceView, { VirtualizedTraceViewProps } from './VirtualizedTraceView';
|
||||||
DEFAULT_HEIGHTS,
|
|
||||||
UnthemedVirtualizedTraceView,
|
|
||||||
VirtualizedTraceViewProps,
|
|
||||||
} from './VirtualizedTraceView';
|
|
||||||
|
|
||||||
jest.mock('./SpanTreeOffset');
|
jest.mock('./SpanTreeOffset');
|
||||||
|
|
||||||
|
const trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 2 }))!;
|
||||||
|
const topOfExploreViewRef = jest.fn();
|
||||||
|
let props = {
|
||||||
|
childrenHiddenIDs: new Set(),
|
||||||
|
childrenToggle: jest.fn(),
|
||||||
|
clearShouldScrollToFirstUiFindMatch: jest.fn(),
|
||||||
|
currentViewRangeTime: [0.25, 0.75],
|
||||||
|
detailLogItemToggle: jest.fn(),
|
||||||
|
detailLogsToggle: jest.fn(),
|
||||||
|
detailProcessToggle: jest.fn(),
|
||||||
|
detailStates: new Map(),
|
||||||
|
detailTagsToggle: jest.fn(),
|
||||||
|
detailToggle: jest.fn(),
|
||||||
|
findMatchesIDs: null,
|
||||||
|
registerAccessors: jest.fn(),
|
||||||
|
scrollToFirstVisibleSpan: jest.fn(),
|
||||||
|
setSpanNameColumnWidth: jest.fn(),
|
||||||
|
setTrace: jest.fn(),
|
||||||
|
shouldScrollToFirstUiFindMatch: false,
|
||||||
|
spanNameColumnWidth: 0.5,
|
||||||
|
trace,
|
||||||
|
uiFind: 'uiFind',
|
||||||
|
topOfExploreViewRef,
|
||||||
|
} as unknown as VirtualizedTraceViewProps;
|
||||||
|
|
||||||
describe('<VirtualizedTraceViewImpl>', () => {
|
describe('<VirtualizedTraceViewImpl>', () => {
|
||||||
let wrapper: ShallowWrapper<VirtualizedTraceViewProps, {}, UnthemedVirtualizedTraceView>;
|
|
||||||
let instance: UnthemedVirtualizedTraceView;
|
|
||||||
|
|
||||||
const trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 10 }))!;
|
|
||||||
const topOfExploreViewRef = jest.fn();
|
|
||||||
const props = {
|
|
||||||
childrenHiddenIDs: new Set(),
|
|
||||||
childrenToggle: jest.fn(),
|
|
||||||
clearShouldScrollToFirstUiFindMatch: jest.fn(),
|
|
||||||
currentViewRangeTime: [0.25, 0.75],
|
|
||||||
detailLogItemToggle: jest.fn(),
|
|
||||||
detailLogsToggle: jest.fn(),
|
|
||||||
detailProcessToggle: jest.fn(),
|
|
||||||
detailStates: new Map(),
|
|
||||||
detailTagsToggle: jest.fn(),
|
|
||||||
detailToggle: jest.fn(),
|
|
||||||
findMatchesIDs: null,
|
|
||||||
registerAccessors: jest.fn(),
|
|
||||||
scrollToFirstVisibleSpan: jest.fn(),
|
|
||||||
setSpanNameColumnWidth: jest.fn(),
|
|
||||||
setTrace: jest.fn(),
|
|
||||||
shouldScrollToFirstUiFindMatch: false,
|
|
||||||
spanNameColumnWidth: 0.5,
|
|
||||||
trace,
|
|
||||||
uiFind: 'uiFind',
|
|
||||||
topOfExploreViewRef,
|
|
||||||
} as unknown as VirtualizedTraceViewProps;
|
|
||||||
|
|
||||||
function expandRow(rowIndex: number) {
|
|
||||||
const detailStates = new Map();
|
|
||||||
const detailState = new DetailState();
|
|
||||||
detailStates.set(trace.spans[rowIndex].spanID, detailState);
|
|
||||||
wrapper.setProps({ detailStates });
|
|
||||||
return detailState;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addSpansAndCollapseTheirParent(newSpanID = 'some-id') {
|
|
||||||
const childrenHiddenIDs = new Set([newSpanID]);
|
|
||||||
const spans = [
|
|
||||||
trace.spans[0],
|
|
||||||
// this span is condidered to have collapsed children
|
|
||||||
{ spanID: newSpanID, depth: 1, traceID: trace.traceID },
|
|
||||||
// these two "spans" are children and should be hidden
|
|
||||||
{ depth: 2 },
|
|
||||||
{ depth: 3 },
|
|
||||||
...trace.spans.slice(1),
|
|
||||||
] as TraceSpan[];
|
|
||||||
const _trace = { ...trace, spans };
|
|
||||||
wrapper.setProps({ childrenHiddenIDs, trace: _trace });
|
|
||||||
return spans;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(() => {
|
beforeEach(() => {
|
||||||
jest.mocked(SpanTreeOffset).mockReturnValue(<div />);
|
jest.mocked(SpanTreeOffset).mockReturnValue(<div />);
|
||||||
Object.keys(props).forEach((key) => {
|
Object.keys(props).forEach((key) => {
|
||||||
@@ -98,344 +56,71 @@ describe('<VirtualizedTraceViewImpl>', () => {
|
|||||||
(props[key as keyof VirtualizedTraceViewProps] as jest.Mock).mockReset();
|
(props[key as keyof VirtualizedTraceViewProps] as jest.Mock).mockReset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
wrapper = shallow(<VirtualizedTraceView {...(props as unknown as VirtualizedTraceViewProps)} />)
|
});
|
||||||
.dive()
|
|
||||||
.dive();
|
it('renders service name, operation name and duration for each span', () => {
|
||||||
instance = wrapper.instance();
|
render(<VirtualizedTraceView {...props} />);
|
||||||
|
expect(screen.getAllByText(trace.services[0].name)).toBeTruthy();
|
||||||
|
|
||||||
|
if (trace.services.length > 1) {
|
||||||
|
expect(screen.getAllByText(trace.services[1].name)).toBeTruthy();
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(screen.getAllByText(trace.spans[0].operationName)).toBeTruthy();
|
||||||
|
expect(screen.getAllByText(trace.spans[1].operationName)).toBeTruthy();
|
||||||
|
|
||||||
|
let durationSpan0 = trace.spans[0].duration;
|
||||||
|
|
||||||
|
if (trace.spans[0].duration >= 1_000_000) {
|
||||||
|
durationSpan0 = Math.floor(trace.spans[0].duration / 1000000);
|
||||||
|
} else if (trace.spans[0].duration >= 1000) {
|
||||||
|
durationSpan0 = Math.floor(trace.spans[0].duration / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
let durationSpan1 = trace.spans[1].duration;
|
||||||
|
|
||||||
|
if (trace.spans[1].duration >= 1_000_000) {
|
||||||
|
durationSpan1 = Math.floor(trace.spans[1].duration / 1000000);
|
||||||
|
} else if (trace.spans[1].duration >= 1000) {
|
||||||
|
durationSpan1 = Math.floor(trace.spans[1].duration / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(screen.getAllByText(durationSpan0, { exact: false })).toBeTruthy();
|
||||||
|
expect(screen.getAllByText(durationSpan1, { exact: false })).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders without exploding', () => {
|
it('renders without exploding', () => {
|
||||||
expect(wrapper).toBeDefined();
|
render(<VirtualizedTraceView {...props} />);
|
||||||
|
expect(screen.getByTestId('ListView')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTitle('Scroll to top')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders when a trace is not set', () => {
|
it('renders when a trace is not set', () => {
|
||||||
wrapper.setProps({ trace: null as unknown as Trace });
|
props = { ...props, trace: null as unknown as Trace };
|
||||||
expect(wrapper).toBeDefined();
|
render(<VirtualizedTraceView {...props} />);
|
||||||
|
expect(screen.getByTestId('ListView')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTitle('Scroll to top')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a ListView', () => {
|
it('renders ListView', () => {
|
||||||
expect(wrapper.find(ListView)).toBeDefined();
|
render(<VirtualizedTraceView {...props} />);
|
||||||
|
expect(screen.getByTestId('ListView')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders scrollToTopButton', () => {
|
it('renders scrollToTopButton', () => {
|
||||||
expect(wrapper.find({ title: 'Scroll to top' }).exists()).toBeTruthy();
|
render(<VirtualizedTraceView {...props} />);
|
||||||
|
expect(
|
||||||
|
screen.getByRole('button', {
|
||||||
|
name: /Scroll to top/i,
|
||||||
|
})
|
||||||
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the trace for global state.traceTimeline', () => {
|
it('sets the trace for global state.traceTimeline', () => {
|
||||||
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 traceID = 'some-other-id';
|
||||||
const _trace = { ...trace, traceID };
|
const _trace = { ...trace, traceID };
|
||||||
wrapper.setProps({ trace: _trace });
|
props = { ...props, trace: _trace };
|
||||||
|
render(<VirtualizedTraceView {...props} />);
|
||||||
expect(jest.mocked(props.setTrace).mock.calls).toEqual([[_trace, props.uiFind]]);
|
expect(jest.mocked(props.setTrace).mock.calls).toEqual([[_trace, props.uiFind]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('props.registerAccessors', () => {
|
|
||||||
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 = () => {};
|
|
||||||
const getTopRowIndexVisible = () => {};
|
|
||||||
lv = {
|
|
||||||
getViewHeight: () => {},
|
|
||||||
getBottomVisibleIndex: getBottomRowIndexVisible,
|
|
||||||
getTopVisibleIndex: getTopRowIndexVisible,
|
|
||||||
getRowPosition: () => {},
|
|
||||||
} as unknown as ListView;
|
|
||||||
expectedArg = {
|
|
||||||
getBottomRowIndexVisible,
|
|
||||||
getTopRowIndexVisible,
|
|
||||||
getViewHeight: lv.getViewHeight,
|
|
||||||
getRowPosition: lv.getRowPosition,
|
|
||||||
getViewRange: instance.getViewRange,
|
|
||||||
getSearchedSpanIDs: instance.getSearchedSpanIDs,
|
|
||||||
getCollapsedChildren: instance.getCollapsedChildren,
|
|
||||||
mapRowIndexToSpanIndex: instance.mapRowIndexToSpanIndex,
|
|
||||||
mapSpanIndexToRowIndex: instance.mapSpanIndexToRowIndex,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('invokes when the listView is set', () => {
|
|
||||||
expect(jest.mocked(props.registerAccessors).mock.calls.length).toBe(0);
|
|
||||||
instance.setListView(lv);
|
|
||||||
expect(jest.mocked(props.registerAccessors).mock.calls).toEqual([[expectedArg]]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('invokes when registerAccessors changes', () => {
|
|
||||||
const registerAccessors = jest.fn();
|
|
||||||
instance.setListView(lv);
|
|
||||||
wrapper.setProps({ registerAccessors });
|
|
||||||
expect(registerAccessors.mock.calls).toEqual([[expectedArg]]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the current view range via getViewRange()', () => {
|
|
||||||
expect(instance.getViewRange()).toBe(props.currentViewRangeTime);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns findMatchesIDs via getSearchedSpanIDs()', () => {
|
|
||||||
const findMatchesIDs: Set<string> = new Set();
|
|
||||||
wrapper.setProps({ findMatchesIDs });
|
|
||||||
expect(instance.getSearchedSpanIDs()).toBe(findMatchesIDs);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns childrenHiddenIDs via getCollapsedChildren()', () => {
|
|
||||||
const childrenHiddenIDs: Set<string> = new Set();
|
|
||||||
wrapper.setProps({ childrenHiddenIDs });
|
|
||||||
expect(instance.getCollapsedChildren()).toBe(childrenHiddenIDs);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('mapRowIndexToSpanIndex() maps row index to span index', () => {
|
|
||||||
it('works when nothing is collapsed or expanded', () => {
|
|
||||||
const i = trace.spans.length - 1;
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(i)).toBe(i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a span is expanded', () => {
|
|
||||||
expandRow(1);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(0)).toBe(0);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(1)).toBe(1);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(2)).toBe(1);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(3)).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a parent span is collapsed', () => {
|
|
||||||
addSpansAndCollapseTheirParent();
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(0)).toBe(0);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(1)).toBe(1);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(2)).toBe(4);
|
|
||||||
expect(instance.mapRowIndexToSpanIndex(3)).toBe(5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('mapSpanIndexToRowIndex() maps span index to row index', () => {
|
|
||||||
it('works when nothing is collapsed or expanded', () => {
|
|
||||||
const i = trace.spans.length - 1;
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(i)).toBe(i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a span is expanded', () => {
|
|
||||||
expandRow(1);
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(0)).toBe(0);
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(1)).toBe(1);
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(2)).toBe(3);
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(3)).toBe(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a parent span is collapsed', () => {
|
|
||||||
addSpansAndCollapseTheirParent();
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(0)).toBe(0);
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(1)).toBe(1);
|
|
||||||
expect(() => instance.mapSpanIndexToRowIndex(2)).toThrow();
|
|
||||||
expect(() => instance.mapSpanIndexToRowIndex(3)).toThrow();
|
|
||||||
expect(instance.mapSpanIndexToRowIndex(4)).toBe(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getKeyFromIndex() generates a "key" from a row index', () => {
|
|
||||||
function verify(input: number, output: string) {
|
|
||||||
expect(instance.getKeyFromIndex(input)).toBe(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('works when nothing is expanded or collapsed', () => {
|
|
||||||
verify(0, `${trace.spans[0].traceID}--${trace.spans[0].spanID}--bar`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when rows are expanded', () => {
|
|
||||||
expandRow(1);
|
|
||||||
verify(1, `${trace.spans[1].traceID}--${trace.spans[1].spanID}--bar`);
|
|
||||||
verify(2, `${trace.spans[1].traceID}--${trace.spans[1].spanID}--detail`);
|
|
||||||
verify(3, `${trace.spans[2].traceID}--${trace.spans[2].spanID}--bar`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a parent span is collapsed', () => {
|
|
||||||
const spans = addSpansAndCollapseTheirParent();
|
|
||||||
verify(1, `${spans[1].traceID}--${spans[1].spanID}--bar`);
|
|
||||||
verify(2, `${spans[4].traceID}--${spans[4].spanID}--bar`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getIndexFromKey() converts a "key" to the corresponding row index', () => {
|
|
||||||
function verify(input: string, output: number) {
|
|
||||||
expect(instance.getIndexFromKey(input)).toBe(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('works when nothing is expanded or collapsed', () => {
|
|
||||||
verify(`${trace.traceID}--${trace.spans[0].spanID}--bar`, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when rows are expanded', () => {
|
|
||||||
expandRow(1);
|
|
||||||
verify(`${trace.spans[1].traceID}--${trace.spans[1].spanID}--bar`, 1);
|
|
||||||
verify(`${trace.spans[1].traceID}--${trace.spans[1].spanID}--detail`, 2);
|
|
||||||
verify(`${trace.spans[2].traceID}--${trace.spans[2].spanID}--bar`, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works when a parent span is collapsed', () => {
|
|
||||||
const spans = addSpansAndCollapseTheirParent();
|
|
||||||
verify(`${spans[1].traceID}--${spans[1].spanID}--bar`, 1);
|
|
||||||
verify(`${spans[4].traceID}--${spans[4].spanID}--bar`, 2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getRowHeight()', () => {
|
|
||||||
it('returns the expected height for non-detail rows', () => {
|
|
||||||
expect(instance.getRowHeight(0)).toBe(DEFAULT_HEIGHTS.bar);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the expected height for detail rows that do not have logs', () => {
|
|
||||||
expandRow(0);
|
|
||||||
expect(instance.getRowHeight(1)).toBe(DEFAULT_HEIGHTS.detail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the expected height for detail rows that do have logs', () => {
|
|
||||||
const logs = [
|
|
||||||
{
|
|
||||||
timestamp: Date.now(),
|
|
||||||
fields: traceGenerator.tags(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const altTrace = updateSpan(trace, 0, { logs });
|
|
||||||
expandRow(0);
|
|
||||||
wrapper.setProps({ trace: altTrace });
|
|
||||||
expect(instance.getRowHeight(1)).toBe(DEFAULT_HEIGHTS.detailWithLogs);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('renderRow()', () => {
|
|
||||||
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!);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
rowWrapper.containsMatchingElement(
|
|
||||||
<SpanBarRow
|
|
||||||
{...({
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders a SpanBarRow with a RPC span if the row is collapsed and a client span', () => {
|
|
||||||
const clientTags = [{ key: 'span.kind', value: 'client' }, ...trace.spans[0].tags];
|
|
||||||
const serverTags = [{ key: 'span.kind', value: 'server' }, ...trace.spans[1].tags];
|
|
||||||
let altTrace = updateSpan(trace, 0, { tags: clientTags });
|
|
||||||
altTrace = updateSpan(altTrace, 1, { tags: serverTags });
|
|
||||||
const childrenHiddenIDs = new Set([altTrace.spans[0].spanID]);
|
|
||||||
wrapper.setProps({ childrenHiddenIDs, trace: altTrace });
|
|
||||||
|
|
||||||
const rowWrapper = mount(instance.renderRow('some-key', {}, 0, {})!);
|
|
||||||
const spanBarRow = rowWrapper.find(SpanBarRow);
|
|
||||||
expect(spanBarRow.length).toBe(1);
|
|
||||||
expect(spanBarRow.prop('rpc')).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders a SpanDetailRow when it is a detail', () => {
|
|
||||||
const detailState = expandRow(1);
|
|
||||||
const span = trace.spans[1];
|
|
||||||
const row = instance.renderRow('some-key', {}, 2, {});
|
|
||||||
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,
|
|
||||||
} as unknown as SpanDetailRowProps)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
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 clientTags = [
|
|
||||||
{ key: 'span.kind', value: 'client' },
|
|
||||||
{ key: 'peer.service', value: externServiceName },
|
|
||||||
...leafSpan!.tags,
|
|
||||||
];
|
|
||||||
const altTrace = updateSpan(trace, leafSpanIndex, { tags: clientTags });
|
|
||||||
wrapper.setProps({ trace: altTrace });
|
|
||||||
const rowWrapper = mount(instance.renderRow('some-key', {}, leafSpanIndex, {})!);
|
|
||||||
const spanBarRow = rowWrapper.find(SpanBarRow);
|
|
||||||
expect(spanBarRow.length).toBe(1);
|
|
||||||
expect(spanBarRow.prop('noInstrumentedServer')).not.toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('shouldScrollToFirstUiFindMatch', () => {
|
|
||||||
const propsWithTrueShouldScrollToFirstUiFindMatch = { ...props, shouldScrollToFirstUiFindMatch: true };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.mocked(props.scrollToFirstVisibleSpan).mockReset();
|
|
||||||
jest.mocked(props.clearShouldScrollToFirstUiFindMatch).mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls props.scrollToFirstVisibleSpan if shouldScrollToFirstUiFindMatch is true', () => {
|
|
||||||
expect(props.scrollToFirstVisibleSpan).not.toHaveBeenCalled();
|
|
||||||
expect(props.clearShouldScrollToFirstUiFindMatch).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
wrapper.setProps(propsWithTrueShouldScrollToFirstUiFindMatch);
|
|
||||||
expect(props.scrollToFirstVisibleSpan).toHaveBeenCalledTimes(1);
|
|
||||||
expect(props.clearShouldScrollToFirstUiFindMatch).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('shouldComponentUpdate', () => {
|
|
||||||
it('returns true if props.shouldScrollToFirstUiFindMatch changes to true', () => {
|
|
||||||
expect(wrapper.instance().shouldComponentUpdate(propsWithTrueShouldScrollToFirstUiFindMatch)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns true if props.shouldScrollToFirstUiFindMatch changes to false and another props change', () => {
|
|
||||||
const propsWithOtherDifferenceAndTrueshouldScrollToFirstUiFindMatch = {
|
|
||||||
...propsWithTrueShouldScrollToFirstUiFindMatch,
|
|
||||||
clearShouldScrollToFirstUiFindMatch: () => {},
|
|
||||||
};
|
|
||||||
wrapper.setProps(propsWithOtherDifferenceAndTrueshouldScrollToFirstUiFindMatch);
|
|
||||||
expect(wrapper.instance().shouldComponentUpdate(props)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if props.shouldScrollToFirstUiFindMatch changes to false and no other props change', () => {
|
|
||||||
wrapper.setProps(propsWithTrueShouldScrollToFirstUiFindMatch);
|
|
||||||
expect(wrapper.instance().shouldComponentUpdate(props)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if all props are unchanged', () => {
|
|
||||||
expect(wrapper.instance().shouldComponentUpdate(props)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user