diff --git a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx
index bf3667388..53e061568 100644
--- a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx
+++ b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx
@@ -21,6 +21,46 @@ function renderWithRoute(component: ReactElement) {
});
}
+describe('RevisionRowExpandable for student-t testVersion', () => {
+ it('should display median difference and percentage when both median values are present', async () => {
+ const { testCompareData } = getTestData();
+ // testCompareData[0]: base_median_value=704.84, new_median_value=712.44, unit='ms'
+ // expected difference: 7.6, percentage: 1.08
+ renderWithRoute(
+ ,
+ );
+
+ const header = await screen.findByText(/Difference of medians/);
+ const medianBox = header.closest('div');
+ expect(medianBox).toHaveTextContent('1.08%');
+ expect(medianBox).toHaveTextContent('7.6 ms');
+ });
+
+ it('should not display median difference when median values are absent', async () => {
+ const { testCompareData } = getTestData();
+ const noMedians = {
+ ...testCompareData[0],
+ base_median_value: 0,
+ new_median_value: 0,
+ };
+
+ renderWithRoute(
+ ,
+ );
+
+ await screen.findByText(/Difference of means/);
+ expect(screen.queryByText(/Difference of medians/)).not.toBeInTheDocument();
+ });
+});
+
describe('RevisionRowExpandable for mann-whitney-u testVersion', () => {
it('should display ModeInterpretation for mann-whitney-u', async () => {
const { mockMannWhitneyResultData } = getTestData();
diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
index b095553c6..2d0538e89 100644
--- a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
+++ b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
@@ -67,8 +67,7 @@ exports[`Results View Should display Base, New and Common graphs with replicates
Comparison result
- :
-
+ :
(
lower
@@ -460,8 +459,7 @@ exports[`Results View Should display Base, New and Common graphs with tooltips 1
Comparison result
- :
-
+ :
(
lower
diff --git a/src/common/testVersions/index.ts b/src/common/testVersions/index.ts
index 8c61c882e..54ac054c2 100644
--- a/src/common/testVersions/index.ts
+++ b/src/common/testVersions/index.ts
@@ -12,6 +12,10 @@ export interface TestVersionStrategy {
newAvg: number | null;
};
renderColumns(result: CombinedResultsItemType): ReactNode;
+ renderExpandedLeft(result: CombinedResultsItemType): ReactNode;
+ getComparisonResult(result: CombinedResultsItemType): string;
+ renderExpandedRight(result: CombinedResultsItemType): ReactNode;
+ renderExpandedBottom(result: CombinedResultsItemType): ReactNode;
}
// Registry mapping each TestVersion to its concrete strategy.
diff --git a/src/common/testVersions/mannWhitney.tsx b/src/common/testVersions/mannWhitney.tsx
index 034915734..1ee055949 100644
--- a/src/common/testVersions/mannWhitney.tsx
+++ b/src/common/testVersions/mannWhitney.tsx
@@ -2,6 +2,10 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown';
import ThumbUpIcon from '@mui/icons-material/ThumbUp';
import Box from '@mui/material/Box';
+import { MannWhitneyCompareMetrics } from '../../components/CompareResults/MannWhitneyCompareMetrics';
+import { ModeInterpretation } from '../../components/CompareResults/ModeInterpretation';
+import PValCliffsDeltaComp from '../../components/CompareResults/PValCliffsDeltaComp';
+import { StatisticsWarnings } from '../../components/CompareResults/StatisticsWarnings';
import {
CombinedResultsItemType,
MannWhitneyResultsItem,
@@ -202,6 +206,53 @@ export const mannWhitneyStrategy = {
};
},
+ renderExpandedLeft() {
+ return null;
+ },
+
+ getComparisonResult(result: CombinedResultsItemType) {
+ return capitalize(
+ (result as MannWhitneyResultsItem).direction_of_change ?? '',
+ );
+ },
+
+ renderExpandedRight(result: CombinedResultsItemType) {
+ const mwResult = result as MannWhitneyResultsItem;
+ const { cles, cles_direction } = mwResult.cles ?? {
+ cles: '',
+ cles_direction: '',
+ };
+ const { cliffs_delta, cliffs_interpretation } = mwResult;
+ const pValue = mwResult.mann_whitney_test?.pvalue;
+ const p_value_cles = mwResult.mann_whitney_test?.interpretation
+ ? capitalize(mwResult.mann_whitney_test.interpretation)
+ : '';
+
+ return (
+ <>
+
+
+ >
+ );
+ },
+
+ renderExpandedBottom(result: CombinedResultsItemType) {
+ const mwResult = result as MannWhitneyResultsItem;
+ return (
+
+
+
+
+ );
+ },
+
renderColumns(result: CombinedResultsItemType) {
const { cliffs_delta, direction_of_change, mann_whitney_test, cles } =
result as MannWhitneyResultsItem;
diff --git a/src/common/testVersions/studentT.tsx b/src/common/testVersions/studentT.tsx
index cc6276301..29e8749d3 100644
--- a/src/common/testVersions/studentT.tsx
+++ b/src/common/testVersions/studentT.tsx
@@ -5,8 +5,11 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown';
import ThumbUpIcon from '@mui/icons-material/ThumbUp';
import Box from '@mui/material/Box';
+import Distribution from '../../components/CompareResults/Distribution';
+import { Strings } from '../../resources/Strings';
import { CombinedResultsItemType, CompareResultsItem } from '../../types/state';
import { TableConfig } from '../../types/types';
+import { formatNumber } from '../../utils/format';
import { getPlatformShortName } from '../../utils/platform';
import {
determineStatus,
@@ -154,6 +157,82 @@ export const studentTStrategy = {
};
},
+ renderExpandedLeft(result: CombinedResultsItemType) {
+ return ;
+ },
+
+ getComparisonResult(result: CombinedResultsItemType) {
+ return (result as CompareResultsItem).new_is_better ? 'better' : 'worse';
+ },
+
+ renderExpandedRight(result: CombinedResultsItemType) {
+ const {
+ delta_percentage: deltaPercent,
+ delta_value: delta,
+ confidence_text: confidenceText,
+ confidence: confidenceValue,
+ base_median_value: baseMedian,
+ new_median_value: newMedian,
+ base_measurement_unit: baseUnit,
+ new_measurement_unit: newUnit,
+ } = result as CompareResultsItem;
+
+ const deltaUnit = baseUnit || newUnit || '';
+ const formatTwoDigits = new Intl.NumberFormat('en-US', {
+ maximumFractionDigits: 2,
+ });
+ const medianDifference =
+ baseMedian && newMedian
+ ? formatTwoDigits.format(newMedian - baseMedian)
+ : '';
+ const medianPercentage =
+ baseMedian && newMedian
+ ? formatTwoDigits.format(((newMedian - baseMedian) / baseMedian) * 100)
+ : '';
+
+ const { confidenceNote } = Strings.components.expandableRow;
+
+ return (
+ <>
+
+ Difference of means: {deltaPercent}% ({formatNumber(delta)}
+ {deltaUnit ? ' ' + deltaUnit : null})
+
+ {newMedian && baseMedian ? (
+
+ Difference of medians: {medianPercentage}% (
+ {medianDifference}
+ {deltaUnit ? ' ' + deltaUnit : null})
+
+ ) : null}
+ {confidenceText ? (
+
+
+ Confidence: {confidenceText}
+ {confidenceValue ? ' ' + `(${confidenceValue})` : null}
+
+
+ **Note: {confidenceNote}{' '}
+
+
+ ) : (
+
+ Confidence: Not available{' '}
+
+ )}
+ >
+ );
+ },
+
+ renderExpandedBottom() {
+ return null;
+ },
+
renderColumns(result: CombinedResultsItemType) {
const {
is_improvement: improvement,
diff --git a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx
index c89f4bc34..3bed1c25d 100644
--- a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx
+++ b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx
@@ -1,22 +1,16 @@
import { Box } from '@mui/material';
-import { MANN_WHITNEY_U } from '../../common/constants';
import { MannWhitneyResultsItem } from '../../types/state';
-import { TestVersion } from '../../types/types';
import { getModeInterpretation } from '../../utils/helpers';
const METRIC_HEADERS = ['Metric', 'Base', 'New', 'Interpretation'];
-interface MannWhitneyCompareMetricsProps {
- result: MannWhitneyResultsItem;
- testVersion: TestVersion;
-}
-
export const MannWhitneyCompareMetrics = ({
result,
- testVersion,
-}: MannWhitneyCompareMetricsProps) => {
- if (!result || testVersion !== MANN_WHITNEY_U) {
+}: {
+ result: MannWhitneyResultsItem;
+}) => {
+ if (!result) {
return null;
}
diff --git a/src/components/CompareResults/ModeInterpretation.tsx b/src/components/CompareResults/ModeInterpretation.tsx
index dcb10f47e..59f08bf62 100644
--- a/src/components/CompareResults/ModeInterpretation.tsx
+++ b/src/components/CompareResults/ModeInterpretation.tsx
@@ -1,17 +1,13 @@
import { Box } from '@mui/material';
-import { MANN_WHITNEY_U } from '../../common/constants';
import { MannWhitneyResultsItem } from '../../types/state';
-import { TestVersion } from '../../types/types';
export const ModeInterpretation = ({
result,
- testVersion,
}: {
result: MannWhitneyResultsItem;
- testVersion: TestVersion;
}) => {
- if (!result || !result.silverman_kde || testVersion !== MANN_WHITNEY_U) {
+ if (!result || !result.silverman_kde) {
return null;
}
diff --git a/src/components/CompareResults/RevisionRowExpandable.tsx b/src/components/CompareResults/RevisionRowExpandable.tsx
index d31e4b27c..0a8697abd 100644
--- a/src/components/CompareResults/RevisionRowExpandable.tsx
+++ b/src/components/CompareResults/RevisionRowExpandable.tsx
@@ -4,31 +4,13 @@ import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import CommonGraph from './CommonGraph';
-import Distribution from './Distribution';
-import { ModeInterpretation } from './ModeInterpretation';
-import { MANN_WHITNEY_U, STUDENT_T } from '../../common/constants';
+import { getStrategy } from '../../common/testVersions';
import { Strings } from '../../resources/Strings';
import { Spacing } from '../../styles';
-import type {
- CombinedResultsItemType,
- CompareResultsItem,
- MannWhitneyResultsItem,
-} from '../../types/state';
+import type { CombinedResultsItemType } from '../../types/state';
import { TestVersion } from '../../types/types';
-import { formatNumber } from './../../utils/format';
-import { MannWhitneyCompareMetrics } from './MannWhitneyCompareMetrics';
-import PValCliffsDeltaComp from './PValCliffsDeltaComp';
-import { StatisticsWarnings } from './StatisticsWarnings';
-import { capitalize } from '../../utils/helpers';
-const strings = Strings.components.expandableRow;
-const { singleRun, confidenceNote } = strings;
-
-const numberFormatterTwoDigits = new Intl.NumberFormat('en-US', {
- maximumFractionDigits: 2,
-});
-const formatNumberTwoDigits = (value: number) =>
- numberFormatterTwoDigits.format(value);
+const { singleRun } = Strings.components.expandableRow;
function RevisionRowExpandable(props: RevisionRowExpandableProps) {
const { result, id, testVersion } = props;
@@ -39,31 +21,15 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) {
base_runs_replicates: baseRunsReplicates,
new_runs_replicates: newRunsReplicates,
platform,
- delta_percentage: deltaPercent,
- delta_value: delta,
- confidence_text: confidenceText,
- confidence: confidenceValue,
- base_median_value: baseMedian,
- new_median_value: newMedian,
- base_measurement_unit: baseUnit,
- new_measurement_unit: newUnit,
- base_app: baseApplication,
- new_app: newApplication,
more_runs_are_needed: moreRunsAreNeeded,
lower_is_better: lowerIsBetter,
- new_is_better: newIsBetter,
+ base_app: baseApplication,
+ new_app: newApplication,
+ base_measurement_unit: baseUnit,
+ new_measurement_unit: newUnit,
} = result;
- const unit = baseUnit || newUnit;
- const deltaUnit = unit ? `${unit}` : '';
- let medianDifference = '';
- let medianPercentage = '';
- if (baseMedian && newMedian) {
- medianDifference = formatNumberTwoDigits(newMedian - baseMedian);
- medianPercentage = formatNumberTwoDigits(
- ((newMedian - baseMedian) / baseMedian) * 100,
- );
- }
+ const strategy = getStrategy(testVersion);
const baseValues =
baseRunsReplicates && baseRunsReplicates.length
@@ -73,31 +39,6 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) {
const newValues =
newRunsReplicates && newRunsReplicates.length ? newRunsReplicates : newRuns;
- const renderPValCliffsDeltaComp = (result: MannWhitneyResultsItem) => {
- if (testVersion === MANN_WHITNEY_U && result) {
- const { cles, cles_direction } = result?.cles ?? {
- cles: '',
- cles_direction: '',
- };
- const { cliffs_delta, cliffs_interpretation } = result;
- const pValue = result?.mann_whitney_test?.pvalue;
- const p_value_cles = result?.mann_whitney_test?.interpretation
- ? capitalize(result.mann_whitney_test.interpretation)
- : '';
- return (
-
- );
- }
- return;
- };
-
return (
- {/******* student t test rendering **************/}
- {testVersion === STUDENT_T && (
-
- )}
+ {strategy.renderExpandedLeft(result)}
@@ -149,80 +87,14 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) {
)}
- Comparison result:{' '}
- {testVersion === MANN_WHITNEY_U
- ? capitalize(
- (result as MannWhitneyResultsItem).direction_of_change ??
- '',
- )
- : newIsBetter
- ? 'better'
- : 'worse'}{' '}
+ Comparison result: {strategy.getComparisonResult(result)}{' '}
({lowerIsBetter ? 'lower' : 'higher'} is better)
- {/******* student t test rendering **************/}
- {testVersion === STUDENT_T && (
- <>
-
- Difference of means: {deltaPercent}% (
- {formatNumber(delta)}
- {deltaUnit ? ' ' + deltaUnit : null})
-
- {newMedian && baseMedian ? (
-
- Difference of medians: {medianPercentage}% (
- {medianDifference}
- {deltaUnit ? ' ' + deltaUnit : null})
-
- ) : null}
- {confidenceText ? (
-
-
- Confidence: {confidenceText}
- {confidenceValue ? ' ' + `(${confidenceValue})` : null}
-
-
- **Note: {confidenceNote}{' '}
-
-
- ) : (
-
- Confidence: Not available{' '}
-
- )}
- >
- )}
- {/******* mann-whitney rendering **************/}
- {renderPValCliffsDeltaComp(result as MannWhitneyResultsItem)}
-
+ {strategy.renderExpandedRight(result)}
-
- {/******* mann-whitney rendering **************/}
-
-
-
-
-
+ {strategy.renderExpandedBottom(result)}
);
diff --git a/src/components/CompareResults/StatisticsWarnings.tsx b/src/components/CompareResults/StatisticsWarnings.tsx
index bc43aad86..513de1b6b 100644
--- a/src/components/CompareResults/StatisticsWarnings.tsx
+++ b/src/components/CompareResults/StatisticsWarnings.tsx
@@ -1,19 +1,14 @@
import { Warning } from '@mui/icons-material';
import { Box } from '@mui/system';
-import { MANN_WHITNEY_U } from '../../common/constants';
import { Colors } from '../../styles';
import { MannWhitneyResultsItem } from '../../types/state';
-import { TestVersion } from '../../types/types';
export const StatisticsWarnings = ({
result,
- testVersion,
}: {
result: MannWhitneyResultsItem;
- testVersion: TestVersion;
}) => {
- if (testVersion !== MANN_WHITNEY_U) return null;
const componentStyles = {
backgroundColor: 'transparent',
marginTop: 2,