-
Notifications
You must be signed in to change notification settings - Fork 8k
/
map_column.test.ts
157 lines (136 loc) · 6.35 KB
/
map_column.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { of } from 'rxjs';
import { Datatable } from '../../../expression_types';
import { mapColumn, MapColumnArguments } from '../map_column';
import { emptyTable, functionWrapper, testTable } from './utils';
const pricePlusTwo = (datatable: Datatable) => of(datatable.rows[0].price + 2);
describe('mapColumn', () => {
const fn = functionWrapper(mapColumn);
const runFn = (input: Datatable, args: MapColumnArguments) =>
fn(input, args) as Promise<Datatable>;
it('returns a datatable with a new column with the values from mapping a function over each row in a datatable', async () => {
const arbitraryRowIndex = 2;
const result = await runFn(testTable, {
id: 'pricePlusTwo',
name: 'pricePlusTwo',
expression: pricePlusTwo,
});
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([
...testTable.columns,
{
id: 'pricePlusTwo',
name: 'pricePlusTwo',
meta: { type: 'number', params: { id: 'number' } },
},
]);
expect(result.columns[result.columns.length - 1]).toHaveProperty('name', 'pricePlusTwo');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('pricePlusTwo');
});
it('allows the id arg to be optional, looking up by name instead', async () => {
const result = await runFn(testTable, { name: 'name label', expression: pricePlusTwo });
const nameColumnIndex = result.columns.findIndex(({ name }) => name === 'name label');
const arbitraryRowIndex = 4;
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(testTable.columns.length);
expect(result.columns[nameColumnIndex]).toHaveProperty('id', 'name');
expect(result.columns[nameColumnIndex]).toHaveProperty('name', 'name label');
expect(result.columns[nameColumnIndex].meta).toHaveProperty('type', 'number');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('name', 202);
expect(result.rows[arbitraryRowIndex]).not.toHaveProperty('name label');
});
it('allows a duplicate name when the ids are different', async () => {
const result = await runFn(testTable, {
id: 'new',
name: 'name label',
expression: pricePlusTwo,
});
const nameColumnIndex = result.columns.findIndex(({ id }) => id === 'new');
const arbitraryRowIndex = 4;
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(testTable.columns.length + 1);
expect(result.columns[nameColumnIndex]).toHaveProperty('id', 'new');
expect(result.columns[nameColumnIndex]).toHaveProperty('name', 'name label');
expect(result.columns[nameColumnIndex].meta).toHaveProperty('type', 'number');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('new', 202);
});
it('adds a column to empty tables', async () => {
const result = await runFn(emptyTable, { name: 'name', expression: pricePlusTwo });
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(1);
expect(result.columns[0]).toHaveProperty('name', 'name');
expect(result.columns[0].meta).toHaveProperty('type', 'null');
});
it('should assign specific id, different from name, when id arg is passed for new columns', async () => {
const result = await runFn(emptyTable, { name: 'name', id: 'myid', expression: pricePlusTwo });
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(1);
expect(result.columns[0]).toHaveProperty('name', 'name');
expect(result.columns[0]).toHaveProperty('id', 'myid');
expect(result.columns[0].meta).toHaveProperty('type', 'null');
});
it('should copy over the meta information from the specified column', async () => {
const result = await runFn(
{
...testTable,
columns: [
...testTable.columns,
// add a new entry
{
id: 'myId',
name: 'myName',
meta: { type: 'date', params: { id: 'number', params: { digits: 2 } } },
},
],
rows: testTable.rows.map((row) => ({ ...row, myId: Date.now() })),
},
{ name: 'name', copyMetaFrom: 'myId', expression: pricePlusTwo }
);
const nameColumnIndex = result.columns.findIndex(({ name }) => name === 'name');
expect(result.type).toBe('datatable');
expect(result.columns[nameColumnIndex]).toEqual({
id: 'name',
name: 'name',
meta: { type: 'date', params: { id: 'number', params: { digits: 2 } } },
});
});
it('should be resilient if the references column for meta information does not exists', async () => {
const result = await runFn(emptyTable, {
name: 'name',
copyMetaFrom: 'time',
expression: pricePlusTwo,
});
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(1);
expect(result.columns[0]).toHaveProperty('name', 'name');
expect(result.columns[0]).toHaveProperty('id', 'name');
expect(result.columns[0].meta).toHaveProperty('type', 'null');
});
it('should correctly infer the type fromt he first row if the references column for meta information does not exists', async () => {
const result = await runFn(
{ ...emptyTable, rows: [...emptyTable.rows, { value: 5 }] },
{ name: 'value', copyMetaFrom: 'time', expression: pricePlusTwo }
);
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(1);
expect(result.columns[0]).toHaveProperty('name', 'value');
expect(result.columns[0]).toHaveProperty('id', 'value');
expect(result.columns[0].meta).toHaveProperty('type', 'number');
});
describe('expression', () => {
it('maps null values to the new column', async () => {
const result = await runFn(testTable, { name: 'empty' });
const emptyColumnIndex = result.columns.findIndex(({ name }) => name === 'empty');
const arbitraryRowIndex = 8;
expect(result.columns[emptyColumnIndex]).toHaveProperty('name', 'empty');
expect(result.columns[emptyColumnIndex].meta).toHaveProperty('type', 'null');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('empty', null);
});
});
});