Skip to content

Commit dc971cc

Browse files
committed
add and update tests
1 parent 39cc3de commit dc971cc

File tree

5 files changed

+324
-91
lines changed

5 files changed

+324
-91
lines changed

Diff for: tensorboard/webapp/runs/views/runs_table/BUILD

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ tf_ng_module(
6464
"runs_table_component.ts",
6565
"runs_table_container.ts",
6666
"runs_table_module.ts",
67+
"sorting_utils.ts",
6768
],
6869
assets = [
6970
":regex_edit_dialog_styles",
@@ -131,6 +132,7 @@ tf_ts_library(
131132
"regex_edit_dialog_test.ts",
132133
"runs_data_table_test.ts",
133134
"runs_table_test.ts",
135+
"sorting_utils_test.ts",
134136
],
135137
deps = [
136138
":runs_table",

Diff for: tensorboard/webapp/runs/views/runs_table/runs_table_container.ts

+1-85
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ import {
7070
ColumnHeader,
7171
FilterAddedEvent,
7272
SortingInfo,
73-
SortingOrder,
7473
TableData,
7574
} from '../../../widgets/data_table/types';
7675
import {
@@ -101,6 +100,7 @@ import {
101100
getPotentialHparamColumns,
102101
} from '../../../metrics/views/main_view/common_selectors';
103102
import {runsTableFullScreenToggled} from '../../../core/actions';
103+
import {sortTableDataItems} from './sorting_utils';
104104

105105
const getRunsLoading = createSelector<
106106
State,
@@ -182,90 +182,6 @@ function sortRunTableItems(
182182
return sortedItems;
183183
}
184184

185-
function parseNumericPrefix(value: string | number) {
186-
if (typeof value === 'number') {
187-
return value;
188-
}
189-
const numbers = new Set('0123456789'.split(''));
190-
191-
for (let i = 0; i < value.length; i++) {
192-
if (!numbers.has(value[i])) {
193-
if (i === 0) return;
194-
return parseInt(value.slice(0, i));
195-
}
196-
}
197-
198-
return;
199-
}
200-
201-
const POTENTIALLY_NUMERIC = new Set(['string', 'number']);
202-
203-
function sortTableDataItems(
204-
items: TableData[],
205-
sort: SortingInfo
206-
): TableData[] {
207-
const sortedItems = [...items];
208-
209-
sortedItems.sort((a, b) => {
210-
let aValue = a[sort.name];
211-
let bValue = b[sort.name];
212-
213-
if (sort.name === 'experimentAlias') {
214-
aValue = (aValue as ExperimentAlias).aliasNumber;
215-
bValue = (bValue as ExperimentAlias).aliasNumber;
216-
}
217-
218-
if (aValue === bValue) {
219-
return 0;
220-
}
221-
222-
if (aValue === undefined || bValue === undefined) {
223-
return bValue === undefined ? -1 : 1;
224-
}
225-
226-
if (
227-
POTENTIALLY_NUMERIC.has(typeof aValue) &&
228-
POTENTIALLY_NUMERIC.has(typeof bValue)
229-
) {
230-
const aPrefix = parseNumericPrefix(aValue as string | number);
231-
const bPrefix = parseNumericPrefix(bValue as string | number);
232-
if (aPrefix === undefined || bPrefix === undefined) {
233-
return bPrefix === undefined ? -1 : 1;
234-
}
235-
if (aPrefix !== undefined && bPrefix !== undefined) {
236-
if (aPrefix === bPrefix) {
237-
const aPostfix =
238-
aValue.toString().slice(aPrefix.toString().length) || undefined;
239-
const bPostfix =
240-
bValue.toString().slice(bPrefix.toString().length) || undefined;
241-
if (!aPrefix || !bPostfix) {
242-
return !bPostfix ? -1 : 1;
243-
}
244-
return orderFromLocalComparison(aPostfix, bPostfix);
245-
}
246-
247-
return orderFromLocalComparison(aPrefix, bPrefix);
248-
}
249-
}
250-
251-
return orderFromLocalComparison(aValue, bValue);
252-
});
253-
return sortedItems;
254-
255-
function orderFromLocalComparison(
256-
a: TableData[string] | undefined,
257-
b: TableData[string] | undefined
258-
) {
259-
if (a === undefined) {
260-
return sort.order === SortingOrder.ASCENDING ? -1 : 1;
261-
}
262-
if (b === undefined) {
263-
return sort.order === SortingOrder.ASCENDING ? 1 : -1;
264-
}
265-
return a < b === (sort.order === SortingOrder.ASCENDING) ? -1 : 1;
266-
}
267-
}
268-
269185
function matchFilter(
270186
filter: DiscreteFilter | IntervalFilter,
271187
value: number | DiscreteHparamValue | undefined

Diff for: tensorboard/webapp/runs/views/runs_table/runs_table_test.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -3595,7 +3595,7 @@ describe('runs_table', () => {
35953595
).toBeFalse();
35963596
});
35973597

3598-
it('sorts scarce values with undefined values always below defined ones.', () => {
3598+
it('sorts scarce values with undefined values as maximum.', () => {
35993599
store.overrideSelector(getRunsTableSortingInfo, {
36003600
name: 'scarce',
36013601
order: SortingOrder.ASCENDING,
@@ -3622,15 +3622,15 @@ describe('runs_table', () => {
36223622
store.refreshState();
36233623
fixture.detectChanges();
36243624

3625-
expect(runsDataTable.componentInstance.data[0]['scarce']).toEqual(
3625+
expect(
3626+
runsDataTable.componentInstance.data[0]['scarce']
3627+
).toBeUndefined();
3628+
expect(runsDataTable.componentInstance.data[1]['scarce']).toEqual(
36263629
'ccc'
36273630
);
3628-
expect(runsDataTable.componentInstance.data[1]['scarce']).toEqual(
3631+
expect(runsDataTable.componentInstance.data[2]['scarce']).toEqual(
36293632
'aaa'
36303633
);
3631-
expect(
3632-
runsDataTable.componentInstance.data[2]['scarce']
3633-
).toBeUndefined();
36343634
});
36353635

36363636
it('sorts experiment alias by alias number.', () => {
+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {
2+
SortingInfo,
3+
SortingOrder,
4+
TableData,
5+
} from '../../../widgets/data_table/types';
6+
import {ExperimentAlias} from '../../../experiments/types';
7+
8+
export function parseNumericPrefix(value: string | number) {
9+
if (typeof value === 'number') {
10+
return isNaN(value) ? undefined : value;
11+
}
12+
13+
if (!isNaN(parseInt(value))) {
14+
return parseInt(value);
15+
}
16+
17+
for (let i = 0; i < value.length; i++) {
18+
if (isNaN(parseInt(value[i]))) {
19+
if (i === 0) return;
20+
return parseInt(value.slice(0, i));
21+
}
22+
}
23+
24+
return;
25+
}
26+
27+
const POTENTIALLY_NUMERIC = new Set(['string', 'number']);
28+
29+
export function sortTableDataItems(
30+
items: TableData[],
31+
sort: SortingInfo
32+
): TableData[] {
33+
const sortedItems = [...items];
34+
35+
sortedItems.sort((a, b) => {
36+
let aValue = a[sort.name];
37+
let bValue = b[sort.name];
38+
39+
if (sort.name === 'experimentAlias') {
40+
aValue = (aValue as ExperimentAlias).aliasNumber;
41+
bValue = (bValue as ExperimentAlias).aliasNumber;
42+
}
43+
44+
if (aValue === bValue) {
45+
return 0;
46+
}
47+
48+
if (aValue === undefined || bValue === undefined) {
49+
return orderFromLocalComparison(aValue, bValue);
50+
}
51+
52+
if (
53+
POTENTIALLY_NUMERIC.has(typeof aValue) &&
54+
POTENTIALLY_NUMERIC.has(typeof bValue)
55+
) {
56+
const aPrefix = parseNumericPrefix(aValue as string | number);
57+
const bPrefix = parseNumericPrefix(bValue as string | number);
58+
// Show runs with numbers prior to runs without numbers
59+
if (
60+
(aPrefix === undefined || bPrefix === undefined) &&
61+
aPrefix !== bPrefix
62+
) {
63+
return orderFromLocalComparison(aPrefix, bPrefix);
64+
}
65+
if (aPrefix !== undefined && bPrefix !== undefined) {
66+
if (aPrefix === bPrefix) {
67+
const aPostfix =
68+
aValue.toString().slice(aPrefix.toString().length) || undefined;
69+
const bPostfix =
70+
bValue.toString().slice(bPrefix.toString().length) || undefined;
71+
return orderFromLocalComparison(aPostfix, bPostfix);
72+
}
73+
74+
return orderFromLocalComparison(aPrefix, bPrefix);
75+
}
76+
}
77+
78+
return orderFromLocalComparison(aValue, bValue);
79+
});
80+
return sortedItems;
81+
82+
function orderFromLocalComparison(
83+
a: TableData[string] | undefined,
84+
b: TableData[string] | undefined
85+
) {
86+
if (a === b) {
87+
return 0;
88+
}
89+
90+
if (a === undefined) {
91+
return sort.order === SortingOrder.ASCENDING ? 1 : -1;
92+
}
93+
if (b === undefined) {
94+
return sort.order === SortingOrder.ASCENDING ? -1 : 1;
95+
}
96+
97+
return a < b === (sort.order === SortingOrder.ASCENDING) ? -1 : 1;
98+
}
99+
}

0 commit comments

Comments
 (0)