mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
209 lines
6.6 KiB
TypeScript
209 lines
6.6 KiB
TypeScript
import {LightFlamegraphTheme} from 'sentry/utils/profiling/flamegraph/flamegraphTheme';
|
|
import {transformMatrixBetweenRect} from 'sentry/utils/profiling/gl/utils';
|
|
import {
|
|
getIntervalTimeAtX,
|
|
GridRenderer,
|
|
} from 'sentry/utils/profiling/renderers/gridRenderer';
|
|
import {computeInterval, Rect} from 'sentry/utils/profiling/speedscope';
|
|
|
|
describe('getIntervalTimeAtX', () => {
|
|
beforeEach(() => {
|
|
window.devicePixelRatio = 1;
|
|
});
|
|
|
|
it('when origin is at 0', () => {
|
|
const configView = new Rect(0, 0, 10, 10);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(getIntervalTimeAtX(logicalToConfig, 500)).toBe(5);
|
|
});
|
|
|
|
it('when origin is offset', () => {
|
|
const configView = new Rect(5, 0, 10, 10);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(getIntervalTimeAtX(logicalToConfig, 500)).toBe(10);
|
|
});
|
|
|
|
it('high dpr - when origin is at 0', () => {
|
|
window.devicePixelRatio = 2;
|
|
const configView = new Rect(0, 0, 10, 10);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(getIntervalTimeAtX(logicalToConfig, 500)).toBe(10);
|
|
});
|
|
|
|
it('high dpr - when origin is offset', () => {
|
|
window.devicePixelRatio = 2;
|
|
|
|
const configView = new Rect(5, 0, 10, 10);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToPhysical = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(getIntervalTimeAtX(logicalToPhysical, 500)).toBe(15);
|
|
});
|
|
});
|
|
|
|
describe('computeInterval', () => {
|
|
beforeEach(() => {
|
|
window.devicePixelRatio = 1;
|
|
});
|
|
it('computes intervals when origin is 0', () => {
|
|
const configView = new Rect(0, 0, 100, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(computeInterval(configView, logicalToConfig, getIntervalTimeAtX)).toEqual([
|
|
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
|
|
]);
|
|
});
|
|
|
|
it('computes intervals when origin is offset', () => {
|
|
const configView = new Rect(50, 0, 50, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(computeInterval(configView, logicalToConfig, getIntervalTimeAtX)).toEqual([
|
|
50, 60, 70, 80, 90, 100,
|
|
]);
|
|
});
|
|
|
|
it('readjust intervals *5 when they are too small', () => {
|
|
const configView = new Rect(60, 0, 40, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(computeInterval(configView, logicalToConfig, getIntervalTimeAtX)).toEqual([
|
|
60, 65, 70, 75, 80, 85, 90, 95, 100,
|
|
]);
|
|
});
|
|
|
|
it('readjust intervals *2 when they are too small', () => {
|
|
const configView = new Rect(80, 0, 20, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(computeInterval(configView, logicalToConfig, getIntervalTimeAtX)).toEqual([
|
|
80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100,
|
|
]);
|
|
});
|
|
|
|
it('supports fractions', () => {
|
|
const configView = new Rect(0, 0, 3, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const logicalToConfig = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
expect(computeInterval(configView, logicalToConfig, getIntervalTimeAtX)).toEqual([
|
|
0, 0.5, 1, 1.5, 2, 2.5, 3,
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('gridRenderer', () => {
|
|
it('draws each interval line', () => {
|
|
// Mock the width of the measured text, we dont actually care if this is accurate or not
|
|
const WIDTH = 20;
|
|
|
|
const context: Partial<CanvasRenderingContext2D> = {
|
|
fillText: jest.fn(),
|
|
fillRect: jest.fn(),
|
|
strokeRect: jest.fn(),
|
|
measureText: jest.fn().mockReturnValue({width: WIDTH}),
|
|
};
|
|
const canvas: Partial<HTMLCanvasElement> = {
|
|
getContext: jest.fn().mockReturnValue(context),
|
|
};
|
|
|
|
const renderer = new GridRenderer(
|
|
canvas as HTMLCanvasElement,
|
|
LightFlamegraphTheme,
|
|
jest.fn().mockImplementation(n => n + 'ms')
|
|
);
|
|
|
|
const configView = new Rect(0, 0, 10, 100);
|
|
const physicalSpace = new Rect(0, 0, 1000, 1000);
|
|
const logicalSpace = physicalSpace.scale(
|
|
1 / window.devicePixelRatio,
|
|
1 / window.devicePixelRatio
|
|
);
|
|
|
|
const configViewToPhysicalSpace = transformMatrixBetweenRect(
|
|
configView,
|
|
physicalSpace
|
|
);
|
|
|
|
const logicalSpaceToConfigView = transformMatrixBetweenRect(logicalSpace, configView);
|
|
|
|
renderer.draw(
|
|
configView,
|
|
physicalSpace,
|
|
configViewToPhysicalSpace,
|
|
logicalSpaceToConfigView
|
|
);
|
|
|
|
// Labels should be 0 - 10
|
|
expect(context.fillRect).toHaveBeenCalledTimes(3);
|
|
|
|
// @ts-expect-error this is a mock
|
|
for (let i = 0; i < context.fillText.mock.calls.length; i++) {
|
|
// @ts-expect-error this is a mock
|
|
expect(context.fillText.mock.calls[i][0]).toEqual(i + 'ms');
|
|
// @ts-expect-error this is a mock
|
|
expect(context.fillText.mock.calls[i][1]).toEqual(
|
|
i * 100 - LightFlamegraphTheme.SIZES.LABEL_FONT_PADDING - WIDTH
|
|
);
|
|
// @ts-expect-error this is a mock
|
|
// First 3 draw calls are for the horizontal line, the rest are verticals
|
|
expect(context.strokeRect.mock.calls[i][0]).toEqual(i * 100 - 1);
|
|
}
|
|
});
|
|
});
|