Skip to content

Commit 7002ac4

Browse files
committed
Add a filter option to conformance page
1 parent efa9762 commit 7002ac4

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 {
@@ -25,7 +26,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
2526
);
2627

2728
// Refs
28-
const activeResults = React.useRef<undefined | ResultInfo>();
29+
const activeResults = React.useRef<undefined | ResultInfo>(undefined);
2930

3031
// History handling
3132
const history = useHistory<ConformanceState>();
@@ -96,6 +97,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
9697
newPath,
9798
props.state.ecmaScriptVersion,
9899
props.state.sortOption,
100+
props.state.filterOption,
99101
),
100102
);
101103
};
@@ -111,6 +113,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
111113
slicedPath,
112114
props.state.ecmaScriptVersion,
113115
props.state.sortOption,
116+
props.state.filterOption,
114117
),
115118
);
116119
};
@@ -124,6 +127,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
124127
props.state.testPath,
125128
nulledFlag,
126129
props.state.sortOption,
130+
props.state.filterOption,
127131
),
128132
);
129133
};
@@ -140,6 +144,21 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
140144
);
141145
};
142146

147+
// Sets the filter option.
148+
//
149+
// This filters the tests shown in the selection cards and tests grid
150+
const setFilterOption = (option: string) => {
151+
pushStateToHistory(
152+
createState(
153+
props.state.version,
154+
props.state.testPath,
155+
props.state.ecmaScriptVersion,
156+
props.state.sortOption,
157+
option as FilterOption,
158+
),
159+
);
160+
};
161+
143162
// Sets a selected test.
144163
const setSelectedTest = (test: string | undefined) => {
145164
pushStateToHistory(
@@ -148,6 +167,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
148167
props.state.testPath,
149168
props.state.ecmaScriptVersion,
150169
props.state.sortOption,
170+
props.state.filterOption,
151171
test,
152172
),
153173
);
@@ -170,6 +190,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
170190
sliceNavToIndex={sliceNavToIndex}
171191
setEcmaScriptFlag={setEcmaScriptFlag}
172192
setSortOption={setSortOption}
193+
setFilterOption={setFilterOption}
173194
/>
174195
{currentSuite ? (
175196
<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

@@ -21,6 +22,13 @@ export type SortOption = {
2122
callback: (a: SuiteResult, b: SuiteResult) => number;
2223
};
2324

25+
export enum FilterOption {
26+
None = "none",
27+
Passed = "passed",
28+
Failed = "failed",
29+
Ignored = "ignored",
30+
}
31+
2432
// The below types are specific to test result types.
2533

2634
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,
@@ -17,6 +18,7 @@ export function createState(
1718
testPath?: string[],
1819
ecmaScriptVersion?: string,
1920
sortOption?: string,
21+
filterOption?: FilterOption,
2022
selectedTest?: string,
2123
): ConformanceState {
2224
testPath = testPath ? testPath : [version.tagName];
@@ -27,6 +29,7 @@ export function createState(
2729
testPath,
2830
ecmaScriptVersion,
2931
sortOption,
32+
filterOption,
3033
selectedTest,
3134
};
3235
}

0 commit comments

Comments
 (0)