Skip to content

Commit f5173c9

Browse files
committed
Add a filter option to conformance page
1 parent 66dedb3 commit f5173c9

File tree

8 files changed

+151
-27
lines changed

8 files changed

+151
-27
lines changed

src/components/conformance/ResultsDisplay/components/SuiteDataContainer/cards/TestGrid/index.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
TestResult,
66
SuiteResult,
77
ConformanceState,
8+
FilterOption,
89
} from "@site/src/components/conformance/types";
910
import Heading from "@theme/Heading";
1011
import styles from "./styles.module.css";
@@ -32,6 +33,7 @@ export default function TestsGrid(props: TestsGridProps): JSX.Element {
3233
<Grid
3334
tests={props.suite.tests}
3435
esFlag={props.state.ecmaScriptVersion}
36+
filterOption={props.state.filterOption}
3537
selectTest={props.selectTest}
3638
setHoverValue={(name) => setHoverName(name)}
3739
/>
@@ -44,16 +46,31 @@ export default function TestsGrid(props: TestsGridProps): JSX.Element {
4446
type GridProps = {
4547
tests: TestResult[];
4648
esFlag: string | null;
49+
filterOption: FilterOption;
4750
selectTest: (test: string) => void;
4851
setHoverValue: (test: string | undefined) => void;
4952
};
5053

54+
function applyFilter(filter: FilterOption, outcome: TestOutcome): boolean {
55+
switch (filter) {
56+
case FilterOption.Passed:
57+
return outcome == TestOutcome.Passed;
58+
case FilterOption.Ignored:
59+
return outcome == TestOutcome.Ignored;
60+
case FilterOption.Failed:
61+
return outcome == TestOutcome.Failed || outcome == TestOutcome.Panic;
62+
default:
63+
return true;
64+
}
65+
}
66+
5167
function Grid(props: GridProps): JSX.Element {
5268
return (
5369
<>
5470
{props.esFlag
5571
? props.tests
5672
.filter((test) => test.edition <= SpecEdition[props.esFlag])
73+
.filter((test) => applyFilter(props.filterOption, test.result))
5774
.map((test) => {
5875
return (
5976
<GridItem
@@ -64,16 +81,18 @@ function Grid(props: GridProps): JSX.Element {
6481
/>
6582
);
6683
})
67-
: props.tests.map((test) => {
68-
return (
69-
<GridItem
70-
key={test.strict ? test.name + "-strict" : test.name}
71-
test={test}
72-
selectTest={props.selectTest}
73-
setHoverValue={props.setHoverValue}
74-
/>
75-
);
76-
})}
84+
: props.tests
85+
.filter((test) => applyFilter(props.filterOption, test.result))
86+
.map((test) => {
87+
return (
88+
<GridItem
89+
key={test.strict ? test.name + "-strict" : test.name}
90+
test={test}
91+
selectTest={props.selectTest}
92+
setHoverValue={props.setHoverValue}
93+
/>
94+
);
95+
})}
7796
</>
7897
);
7998
}

src/components/conformance/ResultsDisplay/components/SuiteDataContainer/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ type SuiteDataProps = {
1515
setSelectedTest: (string) => void;
1616
};
1717

18-
export default function SuiteDataContainer(props: SuiteDataProps): JSX.Element {
18+
export default function SuiteDataContainer(
19+
props: SuiteDataProps,
20+
): JSX.Element {
1921
// Set the user's selected test to be displayed in the ViewPort.
2022
const selectTest = (testName: string) => {
2123
props.setSelectedTest(testName);

src/components/conformance/ResultsDisplay/components/SuiteDisplay/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ type SuiteDisplayProps = {
1616
setSelectedTest: (string) => void;
1717
};
1818

19-
export default function SuiteDisplay(props: SuiteDisplayProps): JSX.Element {
19+
export default function SuiteDisplay(
20+
props: SuiteDisplayProps,
21+
): JSX.Element {
2022
return (
2123
<div className={styles.suiteDisplay}>
2224
{props.currentSuite.suites ? (

src/components/conformance/ResultsDisplay/components/SuiteSelector/index.tsx

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import {
33
ConformanceState,
4+
FilterOption,
45
SortOption,
56
SuiteResult,
67
TestStats,
@@ -35,6 +36,7 @@ export default function SuiteSelector(props: SelectorProps): JSX.Element {
3536
key={suite.name}
3637
suite={suite}
3738
esFlag={props.state.ecmaScriptVersion}
39+
filterOption={props.state.filterOption ?? FilterOption.None}
3840
navigateToSuite={props.navigateToSuite}
3941
/>
4042
);
@@ -46,6 +48,7 @@ export default function SuiteSelector(props: SelectorProps): JSX.Element {
4648
type SuiteItemProps = {
4749
suite: SuiteResult;
4850
esFlag: string | null;
51+
filterOption: FilterOption;
4952
navigateToSuite: (string) => void;
5053
};
5154

@@ -64,26 +67,48 @@ function SuiteItem(props: SuiteItemProps): JSX.Element {
6467
? (props.suite.versionedStats?.[props.esFlag] ?? props.suite.stats)
6568
: props.suite.stats
6669
}
70+
filterOption={props.filterOption}
6771
/>
6872
</div>
6973
);
7074
}
7175

72-
function SuiteStatistics(props): JSX.Element {
76+
type StatProps = {
77+
testResults: TestStats;
78+
filterOption: FilterOption;
79+
};
80+
81+
function SuiteStatistics({
82+
testResults,
83+
filterOption,
84+
}: StatProps): JSX.Element {
85+
const [filter, setFilter] = React.useState(filterOption);
86+
87+
React.useEffect(() => {
88+
setFilter(filterOption);
89+
}, [filterOption]);
90+
91+
let passed =
92+
filter == FilterOption.None || filter == FilterOption.Passed
93+
? testResults.passed
94+
: 0;
95+
96+
let ignored =
97+
filter == FilterOption.None || filter == FilterOption.Ignored
98+
? testResults.ignored
99+
: 0;
100+
101+
let failed =
102+
filter == FilterOption.None || filter == FilterOption.Failed
103+
? `${testResults.total - testResults.passed - testResults.ignored} (${testResults.panic}\u26A0)`
104+
: 0;
105+
73106
return (
74107
<div className={styles.suiteCardResults}>
75108
<p>
76-
<span style={{ color: "var(--ifm-color-success)" }}>
77-
{props.testResults.passed}{" "}
78-
</span>
79-
/{" "}
80-
<span style={{ color: "var(--ifm-color-warning)" }}>
81-
{props.testResults.ignored}{" "}
82-
</span>
83-
/{" "}
84-
<span
85-
style={{ color: "var(--ifm-color-danger)" }}
86-
>{`${props.testResults.total - props.testResults.passed - props.testResults.ignored} (${props.testResults.panic}\u26A0)`}</span>
109+
<span style={{ color: "var(--ifm-color-success)" }}>{passed} </span>/{" "}
110+
<span style={{ color: "var(--ifm-color-warning)" }}>{ignored} </span>/{" "}
111+
<span style={{ color: "var(--ifm-color-danger)" }}>{failed}</span>
87112
</p>
88113
</div>
89114
);

src/components/conformance/ResultsDisplay/index.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
VersionItem,
66
SuiteResult,
77
ConformanceState,
8+
FilterOption,
89
} from "@site/src/components/conformance/types";
910
import ResultNavigation from "./nav";
1011
import {
@@ -27,7 +28,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
2728
);
2829

2930
// Refs
30-
const activeResults = React.useRef<undefined | ResultInfo>();
31+
const activeResults = React.useRef<undefined | ResultInfo>(undefined);
3132

3233
// History handling
3334
const history = useHistory<ConformanceState>();
@@ -103,6 +104,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
103104
newPath,
104105
props.state.ecmaScriptVersion,
105106
props.state.sortOption,
107+
props.state.filterOption,
106108
),
107109
);
108110
};
@@ -119,6 +121,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
119121
slicedPath,
120122
props.state.ecmaScriptVersion,
121123
props.state.sortOption,
124+
props.state.filterOption,
122125
),
123126
);
124127
};
@@ -137,6 +140,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
137140
props.state.testPath,
138141
nulledFlag,
139142
props.state.sortOption,
143+
props.state.filterOption,
140144
),
141145
);
142146
};
@@ -158,6 +162,21 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
158162
);
159163
};
160164

165+
// Sets the filter option.
166+
//
167+
// This filters the tests shown in the selection cards and tests grid
168+
const setFilterOption = (option: string) => {
169+
pushStateToHistory(
170+
createState(
171+
props.state.version,
172+
props.state.testPath,
173+
props.state.ecmaScriptVersion,
174+
props.state.sortOption,
175+
option as FilterOption,
176+
),
177+
);
178+
};
179+
161180
// Sets a selected test.
162181
const setSelectedTest = (test: string | undefined) => {
163182
pushStateToHistory(
@@ -167,6 +186,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
167186
props.state.testPath,
168187
props.state.ecmaScriptVersion,
169188
props.state.sortOption,
189+
props.state.filterOption,
170190
test,
171191
),
172192
);
@@ -189,6 +209,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
189209
sliceNavToIndex={sliceNavToIndex}
190210
setEcmaScriptFlag={setEcmaScriptFlag}
191211
setSortOption={setSortOption}
212+
setFilterOption={setFilterOption}
192213
/>
193214
{currentSuite ? (
194215
<SuiteDisplay

src/components/conformance/ResultsDisplay/nav.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { ConformanceState, SpecEdition } from "../types";
2+
import { ConformanceState, FilterOption, SpecEdition } from "../types";
33

44
import styles from "./styles.module.css";
55
import Link from "@docusaurus/Link";
@@ -11,9 +11,12 @@ type ResultsNavProps = {
1111
sliceNavToIndex: (number) => void;
1212
setEcmaScriptFlag: (string) => void;
1313
setSortOption: (string) => void;
14+
setFilterOption: (string) => void;
1415
};
1516

16-
export default function ResultNavigation(props: ResultsNavProps): JSX.Element {
17+
export default function ResultNavigation(
18+
props: ResultsNavProps,
19+
): JSX.Element {
1720
return (
1821
<div className={styles.resultsNav}>
1922
<div className={styles.navSection}>
@@ -25,6 +28,10 @@ export default function ResultNavigation(props: ResultsNavProps): JSX.Element {
2528
sortValue={props.state.sortOption}
2629
setSortOption={props.setSortOption}
2730
/>
31+
<FilterDropdown
32+
filterOption={props.state.filterOption}
33+
setFilterOption={props.setFilterOption}
34+
/>
2835
</div>
2936
<div className={styles.navSection}>
3037
<NavBreadCrumbs
@@ -168,3 +175,40 @@ function SortingDropdown(props: SortProps): JSX.Element {
168175
</div>
169176
);
170177
}
178+
179+
type FilterProps = {
180+
filterOption: FilterOption;
181+
setFilterOption: (string) => void;
182+
};
183+
184+
function FilterDropdown(props: FilterProps): JSX.Element {
185+
const [filterValue, setFilterValue] = React.useState<string>(
186+
props.filterOption ?? FilterOption.None,
187+
);
188+
189+
React.useEffect(() => {
190+
setFilterValue(props.filterOption);
191+
}, [props.filterOption]);
192+
193+
const handlefilterSelection = (e) => {
194+
setFilterValue(e.target.value);
195+
props.setFilterOption(e.target.value);
196+
};
197+
198+
return (
199+
<div className={styles.dropdownContainer}>
200+
<Heading as="h4" style={{ padding: "0.125rem 0.5rem", height: "5" }}>
201+
Filter:
202+
</Heading>
203+
<select value={filterValue} onChange={handlefilterSelection}>
204+
{Object.values(FilterOption).map((key) => {
205+
return (
206+
<option key={key} value={key}>
207+
{key}
208+
</option>
209+
);
210+
})}
211+
</select>
212+
</div>
213+
);
214+
}

src/components/conformance/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type ConformanceState = {
77
testPath: string[];
88
ecmaScriptVersion: string | undefined;
99
sortOption: string;
10+
filterOption: FilterOption;
1011
selectedTest: string | undefined;
1112
};
1213

@@ -27,6 +28,13 @@ export type SortOption = {
2728
callback: (a: SuiteResult, b: SuiteResult) => number;
2829
};
2930

31+
export enum FilterOption {
32+
None = "none",
33+
Passed = "passed",
34+
Failed = "failed",
35+
Ignored = "ignored",
36+
}
37+
3038
// The below types are specific to test result types.
3139

3240
export type ResultInfo = {

src/components/conformance/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
ConformanceState,
3+
FilterOption,
34
ResultInfo,
45
SortOption,
56
SpecEdition,
@@ -69,6 +70,7 @@ export function createState(
6970
testPath?: string[],
7071
ecmaScriptVersion?: string,
7172
sortOption?: string,
73+
filterOption?: FilterOption,
7274
selectedTest?: string,
7375
): ConformanceState {
7476
testPath = testPath ? testPath : [version.tagName];
@@ -79,6 +81,7 @@ export function createState(
7981
testPath,
8082
ecmaScriptVersion,
8183
sortOption,
84+
filterOption,
8285
selectedTest,
8386
};
8487
}

0 commit comments

Comments
 (0)