Skip to content

Commit d7f3d83

Browse files
committed
refactor: cleanup filters.ts
1 parent 580761d commit d7f3d83

2 files changed

Lines changed: 96 additions & 92 deletions

File tree

benchexec/tablegenerator/react-table/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"@typescript-eslint/no-unused-vars": [
6565
"error",
6666
{
67+
"varsIgnorePattern": "^_",
6768
"argsIgnorePattern": "^_"
6869
}
6970
]

benchexec/tablegenerator/react-table/src/utils/filters.ts

Lines changed: 95 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,30 @@ type Matcher = {
104104
diff?: DiffMatcherItem[];
105105
} & Record<string, ToolMatcher | IdMatcher | DiffMatcherItem[] | undefined>;
106106

107+
type IntermediateStatusColumn = ToolColumn & {
108+
type: "status";
109+
categories: Record<string, true>;
110+
statuses: Record<string, true>;
111+
idx: number;
112+
};
113+
114+
type IntermediateTextColumn = ToolColumn & {
115+
type: "text";
116+
distincts: Record<string, true>;
117+
idx: number;
118+
};
119+
120+
type IntermediateNumericColumn = ToolColumn & {
121+
min: number;
122+
max: number;
123+
idx: number;
124+
};
125+
126+
type IntermediateColumn =
127+
| IntermediateStatusColumn
128+
| IntermediateTextColumn
129+
| IntermediateNumericColumn;
130+
107131
const asRecord = (value: unknown): value is Record<string, unknown> =>
108132
typeof value === "object" && value !== null;
109133

@@ -126,80 +150,80 @@ const getFilterableData = ({ tools, rows }: Dataset) => {
126150
const { tool: toolName, date, niceName } = tool;
127151
const name = `${toolName} ${date} ${niceName}`;
128152

129-
const columns = tool.columns.map((col, colIdx) => {
130-
if (!col) {
131-
return undefined;
132-
}
133-
if (col.type === "status") {
134-
statusIdx = colIdx;
153+
const columns = tool.columns.map(
154+
(col, colIdx): IntermediateColumn | undefined => {
155+
if (!col) {
156+
return undefined;
157+
}
158+
if (col.type === "status") {
159+
statusIdx = colIdx;
160+
return {
161+
...col,
162+
type: "status",
163+
categories: {},
164+
statuses: {},
165+
idx: colIdx,
166+
};
167+
}
168+
if (col.type === "text") {
169+
return {
170+
...col,
171+
type: "text",
172+
distincts: {},
173+
idx: colIdx,
174+
};
175+
}
135176
return {
136177
...col,
137-
categories: {} as Record<string, true>,
138-
statuses: {} as Record<string, true>,
178+
min: Infinity,
179+
max: -Infinity,
139180
idx: colIdx,
140181
};
141-
}
142-
if (col.type === "text") {
143-
return { ...col, distincts: {} as Record<string, true>, idx: colIdx };
144-
}
145-
return { ...col, min: Infinity, max: -Infinity, idx: colIdx };
146-
});
182+
},
183+
);
147184

148185
if (!isNil(statusIdx)) {
149186
const current = columns[statusIdx];
150-
if (current) {
187+
if (current && current.type === "status") {
151188
// NOTE (JS->TS): Added defensive check because columns entries may be undefined.
152189
columns[statusIdx] = {
153190
...current,
154-
categories: {} as Record<string, true>,
155-
statuses: {} as Record<string, true>,
191+
categories: {},
192+
statuses: {},
156193
};
157194
}
158195
}
159196

160-
for (const row of rows) {
197+
rows.forEach((row) => {
161198
const result = row.results[idx];
162199
// convention as of writing this commit is to postfix categories with a space character
163200
if (!isNil(statusIdx)) {
164-
const statusCol = columns[statusIdx];
165-
if (statusCol && "categories" in statusCol) {
166-
(statusCol.categories as Record<string, true>)[
167-
`${result.category} `
168-
] = true;
201+
const statusCol = columns[statusIdx] as
202+
| IntermediateStatusColumn
203+
| undefined;
204+
if (statusCol) {
205+
statusCol.categories[`${result.category} `] = true;
169206
}
170207
}
171208

172-
for (const colIdxStr in result.values) {
173-
// NOTE (JS->TS): Convert for..in string keys to numbers for safe array indexing.
174-
const colIdx = Number(colIdxStr);
175-
176-
const col = result.values[colIdx];
209+
result.values.forEach((col, colIdx) => {
177210
const { raw } = col;
178211
const filterCol = columns[colIdx];
179212
if (!filterCol || isNil(raw)) {
180-
continue;
213+
return;
181214
}
182215

183216
if (filterCol.type === "status") {
184-
(filterCol as { statuses: Record<string, true> }).statuses[
185-
String(raw)
186-
] = true;
217+
(filterCol as IntermediateStatusColumn).statuses[String(raw)] = true;
187218
} else if (filterCol.type === "text") {
188-
(filterCol as { distincts: Record<string, true> }).distincts[
189-
String(raw)
190-
] = true;
191-
} else {
192-
(filterCol as { min: number; max: number }).min = Math.min(
193-
(filterCol as { min: number }).min,
194-
Number(raw),
195-
);
196-
(filterCol as { min: number; max: number }).max = Math.max(
197-
(filterCol as { max: number }).max,
198-
Number(raw),
199-
);
219+
(filterCol as IntermediateTextColumn).distincts[String(raw)] = true;
220+
} else if ("min" in filterCol && "max" in filterCol) {
221+
const numCol = filterCol as IntermediateNumericColumn;
222+
numCol.min = Math.min(numCol.min, Number(raw));
223+
numCol.max = Math.max(numCol.max, Number(raw));
200224
}
201-
}
202-
}
225+
});
226+
});
203227

204228
return {
205229
name,
@@ -208,29 +232,25 @@ const getFilterableData = ({ tools, rows }: Dataset) => {
208232
return undefined;
209233
}
210234

211-
const colRec = c as Record<string, unknown>;
212-
const distincts = colRec.distincts as Record<string, true> | undefined;
213-
const categories = colRec.categories as
214-
| Record<string, true>
215-
| undefined;
216-
const statuses = colRec.statuses as Record<string, true> | undefined;
217-
218-
const rest = { ...colRec };
235+
const { idx: _idx, ...rest } = c;
219236

220-
// NOTE (JS->TS): Explicitly remove internal aggregation fields instead of
221-
// using unused destructuring bindings to satisfy ESLint no-unused-vars rule.
222-
delete (rest as Record<string, unknown>).distincts;
223-
delete (rest as Record<string, unknown>).categories;
224-
delete (rest as Record<string, unknown>).statuses;
225-
226-
if (distincts) {
227-
return { ...rest, distincts: Object.keys(distincts) };
228-
}
229-
if (categories) {
237+
if (c.type === "status") {
238+
const statusCol = c as IntermediateStatusColumn;
239+
const { categories, statuses, ...restOfCol } = statusCol;
240+
void restOfCol;
230241
return {
231242
...rest,
232243
categories: Object.keys(categories),
233-
statuses: Object.keys(statuses ?? {}),
244+
statuses: Object.keys(statuses),
245+
};
246+
}
247+
if (c.type === "text") {
248+
const textCol = c as IntermediateTextColumn;
249+
const { distincts, ...restOfCol } = textCol;
250+
void restOfCol;
251+
return {
252+
...rest,
253+
distincts: Object.keys(distincts),
234254
};
235255
}
236256
return rest;
@@ -243,10 +263,7 @@ const getFilterableData = ({ tools, rows }: Dataset) => {
243263
const applyNumericFilter = (
244264
filter: { id: string; value: string },
245265
row: Record<string, unknown>,
246-
cell: unknown,
247266
) => {
248-
void cell;
249-
250267
// NOTE (JS->TS): Pass explicit default value for compatibility with typed signature.
251268
const raw = getRawOrDefault(row[filter.id] as unknown, undefined);
252269
if (raw === undefined) {
@@ -275,10 +292,7 @@ const applyNumericFilter = (
275292
const applyTextFilter = (
276293
filter: { id: string; value: string },
277294
row: Record<string, unknown>,
278-
cell: unknown,
279295
) => {
280-
void cell;
281-
282296
// NOTE (JS->TS): Pass explicit default value for compatibility with typed signature.
283297
const raw = getRawOrDefault(row[filter.id] as unknown, undefined);
284298
if (raw === undefined) {
@@ -464,40 +478,29 @@ const applyMatcher = (matcher: Matcher) => (data: TableRow[]) => {
464478
const columnIdx = Number(columnKey);
465479

466480
for (const filter of columnFilters) {
467-
if (!asRecord(filter)) {
468-
continue;
469-
}
470-
471-
const value = filter.value;
472-
const min = filter.min;
473-
const max = filter.max;
474-
const category = filter.category;
475-
const status = filter.status;
476-
477-
if (!isNil(min) && !isNil(max)) {
481+
if ("min" in filter && "max" in filter) {
478482
const rawValue = row.results[toolIdx]?.values[columnIdx]?.raw;
479483
if (isNil(rawValue)) {
480484
columnPass = false;
481485
continue;
482486
}
483487
const num = Number(rawValue);
484-
columnPass =
485-
columnPass || (num >= Number(min) && num <= Number(max));
486-
} else if (!isNil(category)) {
488+
columnPass = columnPass || (num >= filter.min && num <= filter.max);
489+
} else if ("category" in filter) {
487490
categoryPass =
488-
row.results[toolIdx]?.category === String(category) ||
491+
row.results[toolIdx]?.category === String(filter.category) ||
489492
categoryPass;
490493
columnPass = categoryPass && statusPass;
491-
} else if (!isNil(status)) {
494+
} else if ("status" in filter) {
492495
const emptyRowPass =
493496
row.results[toolIdx]?.category === "empty" &&
494-
String(status) === statusForEmptyRows;
497+
String(filter.status) === statusForEmptyRows;
495498
statusPass =
496-
row.results[toolIdx]?.values[columnIdx]?.raw === status ||
499+
row.results[toolIdx]?.values[columnIdx]?.raw === filter.status ||
497500
statusPass ||
498501
emptyRowPass;
499502
columnPass = categoryPass && statusPass;
500-
} else {
503+
} else if ("value" in filter) {
501504
const rawValue = row.results[toolIdx]?.values[columnIdx]?.raw;
502505
if (isNil(rawValue)) {
503506
columnPass = false;
@@ -506,8 +509,8 @@ const applyMatcher = (matcher: Matcher) => (data: TableRow[]) => {
506509
const rawStr = String(rawValue);
507510
columnPass =
508511
columnPass ||
509-
String(value) === rawStr ||
510-
rawStr.includes(String(value));
512+
String(filter.value) === rawStr ||
513+
rawStr.includes(String(filter.value));
511514
}
512515

513516
if (columnPass) {

0 commit comments

Comments
 (0)