Skip to content

Commit c1c2702

Browse files
committed
Fix nullable fields
1 parent 8f918cd commit c1c2702

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

src/datasource.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,16 @@ export const parseValues = (values: any[], type: FieldType): any[] => {
218218
// For time field, values are expected to be numbers representing a Unix
219219
// epoch in milliseconds.
220220

221-
if (values.every(value => typeof value === 'string')) {
222-
return values.map(_ => (_ !== null ? parseISO(_).valueOf() : null));
221+
if (values.filter(_ => _).every(value => typeof value === 'string')) {
222+
return values.map(_ => (_ !== null ? parseISO(_).valueOf() : _));
223223
}
224224

225-
if (values.every(value => typeof value === 'number')) {
225+
if (values.filter(_ => _).every(value => typeof value === 'number')) {
226226
const ms = 1_000_000_000_000;
227227

228228
// If there are no "big" numbers, assume seconds.
229-
if (values.every(_ => _ < ms)) {
230-
return values.map(_ => _ * 1000.0);
229+
if (values.filter(_ => _).every(_ => _ < ms)) {
230+
return values.map(_ => (_ !== null ? _ * 1000.0 : _));
231231
}
232232

233233
// ... otherwise assume milliseconds.
@@ -236,13 +236,17 @@ export const parseValues = (values: any[], type: FieldType): any[] => {
236236

237237
throw new Error('Unsupported time property');
238238
case FieldType.string:
239-
return values.every(_ => typeof _ === 'string') ? values : values.map(_ => _.toString());
239+
return values.every(_ => typeof _ === 'string') ? values : values.map(_ => (_ !== null ? _.toString() : _));
240240
case FieldType.number:
241-
return values.every(_ => typeof _ === 'number') ? values : values.map(_ => parseFloat(_));
241+
return values.every(_ => typeof _ === 'number') ? values : values.map(_ => (_ !== null ? parseFloat(_) : _));
242242
case FieldType.boolean:
243243
return values.every(_ => typeof _ === 'boolean')
244244
? values
245245
: values.map(_ => {
246+
if (_ === null) {
247+
return _;
248+
}
249+
246250
switch (_.toString()) {
247251
case '0':
248252
case 'false':
@@ -255,7 +259,7 @@ export const parseValues = (values: any[], type: FieldType): any[] => {
255259
case 'True':
256260
return true;
257261
default:
258-
throw new Error('Found non-boolean values in a field of type boolean');
262+
throw new Error('Found non-boolean values in a field of type boolean: ' + _.toString());
259263
}
260264
});
261265
default:

src/parseValues.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,32 @@ test('parse booleans from strings', () => {
4141
expect(parseValues(values, FieldType.string)).toStrictEqual(['false', 'true', 'false']);
4242
expect(parseValues(values, FieldType.time)).toStrictEqual([NaN, NaN, NaN]);
4343
});
44+
45+
test('parse nullable strings', () => {
46+
const values = ['foo', 'bar', null];
47+
48+
expect(() => parseValues(values, FieldType.boolean)).toThrow();
49+
expect(parseValues(values, FieldType.number)).toStrictEqual([NaN, NaN, null]);
50+
expect(parseValues(values, FieldType.string)).toStrictEqual(['foo', 'bar', null]);
51+
expect(parseValues(values, FieldType.time)).toStrictEqual([NaN, NaN, null]);
52+
});
53+
54+
test('parse nullable numbers', () => {
55+
const values = [2005, null, 2006];
56+
57+
expect(() => parseValues(values, FieldType.boolean)).toThrow();
58+
expect(parseValues(values, FieldType.number)).toStrictEqual([2005, null, 2006]);
59+
expect(parseValues(values, FieldType.string)).toStrictEqual(['2005', null, '2006']);
60+
61+
// Numbers are assumed to be epoch time in seconds.
62+
expect(parseValues(values, FieldType.time)).toStrictEqual([2005000, null, 2006000]);
63+
});
64+
65+
test('parse nullable booleans', () => {
66+
const values = [null, true, false];
67+
68+
expect(parseValues(values, FieldType.boolean)).toStrictEqual([null, true, false]);
69+
expect(parseValues(values, FieldType.number)).toStrictEqual([null, NaN, NaN]);
70+
expect(parseValues(values, FieldType.string)).toStrictEqual([null, 'true', 'false']);
71+
expect(() => parseValues(values, FieldType.time)).toThrow();
72+
});

0 commit comments

Comments
 (0)