add duckdb-ui-client & other ts pkgs (#10)
* add duckdb-ui-client & other ts pkgs * workflow fixes * fix working dir * no sparse checkout; specify package.json path * path to pnpm-lock.yaml * add check & build test * workflow step descriptions * use comments & names * one more naming tweak
This commit is contained in:
49
ts/pkgs/duckdb-data-values/test/DuckDBArrayValue.test.ts
Normal file
49
ts/pkgs/duckdb-data-values/test/DuckDBArrayValue.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBArrayValue } from '../src/DuckDBArrayValue';
|
||||
import { DuckDBMapValue } from '../src/DuckDBMapValue';
|
||||
|
||||
suite('DuckDBArrayValue', () => {
|
||||
test('should render an empty array to the correct string', () => {
|
||||
expect(new DuckDBArrayValue([]).toString()).toStrictEqual('[]');
|
||||
});
|
||||
test('should render a single element array to the correct string', () => {
|
||||
expect(new DuckDBArrayValue([123]).toString()).toStrictEqual('[123]');
|
||||
});
|
||||
test('should render a multi-element array to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBArrayValue(['abc', null, true, '']).toString(),
|
||||
).toStrictEqual(`['abc', NULL, true, '']`);
|
||||
});
|
||||
test('should render an array with nested arrays to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBArrayValue([
|
||||
new DuckDBArrayValue([]),
|
||||
null,
|
||||
new DuckDBArrayValue([123, null, 'xyz']),
|
||||
]).toString(),
|
||||
).toStrictEqual(`[[], NULL, [123, NULL, 'xyz']]`);
|
||||
});
|
||||
test('toJson array with basic values', () => {
|
||||
expect(new DuckDBArrayValue([123, 'abc', null]).toJson()).toStrictEqual([
|
||||
123,
|
||||
'abc',
|
||||
null,
|
||||
]);
|
||||
});
|
||||
test('toJson array with complex values', () => {
|
||||
expect(
|
||||
new DuckDBArrayValue([
|
||||
new DuckDBMapValue([
|
||||
{ key: 'foo', value: 123 },
|
||||
{ key: 'bar', value: 'abc' },
|
||||
]),
|
||||
new DuckDBArrayValue([123, null, 'xyz']),
|
||||
null,
|
||||
]).toJson(),
|
||||
).toStrictEqual([
|
||||
{ "'foo'": 123, "'bar'": 'abc' },
|
||||
[123, null, 'xyz'],
|
||||
null,
|
||||
]);
|
||||
});
|
||||
});
|
||||
33
ts/pkgs/duckdb-data-values/test/DuckDBBitValue.test.ts
Normal file
33
ts/pkgs/duckdb-data-values/test/DuckDBBitValue.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBBitValue } from '../src/DuckDBBitValue';
|
||||
|
||||
suite('DuckDBBitValue', () => {
|
||||
test('should render an empty byte array to the correct string', () => {
|
||||
expect(new DuckDBBitValue(new Uint8Array([])).toString()).toStrictEqual('');
|
||||
});
|
||||
test('should render bit string with no padding to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBitValue(new Uint8Array([0x00, 0xf1, 0xe2, 0xd3])).toString(),
|
||||
).toStrictEqual('111100011110001011010011');
|
||||
});
|
||||
test('should render bit string with padding to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBitValue(new Uint8Array([0x03, 0xf1, 0xe2, 0xd3])).toString(),
|
||||
).toStrictEqual('100011110001011010011');
|
||||
});
|
||||
test('should round-trip bit string with no padding', () => {
|
||||
expect(
|
||||
DuckDBBitValue.fromString('111100011110001011010011').toString(),
|
||||
).toStrictEqual('111100011110001011010011');
|
||||
});
|
||||
test('should round-trip bit string with padding', () => {
|
||||
expect(
|
||||
DuckDBBitValue.fromString('100011110001011010011').toString(),
|
||||
).toStrictEqual('100011110001011010011');
|
||||
});
|
||||
test('toJson', () => {
|
||||
expect(
|
||||
DuckDBBitValue.fromString('100011110001011010011').toJson(),
|
||||
).toStrictEqual('100011110001011010011');
|
||||
});
|
||||
});
|
||||
92
ts/pkgs/duckdb-data-values/test/DuckDBBlobValue.test.ts
Normal file
92
ts/pkgs/duckdb-data-values/test/DuckDBBlobValue.test.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBBlobValue } from '../src/DuckDBBlobValue';
|
||||
|
||||
suite('DuckDBBlobValue', () => {
|
||||
test('should render an empty byte array to the correct string', () => {
|
||||
expect(new DuckDBBlobValue(new Uint8Array([])).toString()).toStrictEqual(
|
||||
'',
|
||||
);
|
||||
});
|
||||
test('should render a byte array to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([0x41, 0x42, 0x43, 0x31, 0x32, 0x33]),
|
||||
).toString(),
|
||||
).toStrictEqual('ABC123');
|
||||
});
|
||||
test('should render a byte array containing single-digit non-printables to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual(
|
||||
'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0A\\x0B\\x0C\\x0D\\x0E\\x0F',
|
||||
);
|
||||
});
|
||||
test('should render a byte array containing double-digit non-printables to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual(
|
||||
'\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1A\\x1B\\x1C\\x1D\\x1E\\x1F',
|
||||
);
|
||||
});
|
||||
test('should render a byte array containing min printables (including single and double quotes) to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||
0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual(' !\\x22#$%&\\x27()*+,-./');
|
||||
});
|
||||
test('should render a byte array containing max printables (including backspace) to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
|
||||
0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual('pqrstuvwxyz{|}~\\x7F');
|
||||
});
|
||||
test('should render a byte array containing high non-printables to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
|
||||
0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual(
|
||||
'\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8A\\x8B\\x8C\\x8D\\x8E\\x8F',
|
||||
);
|
||||
});
|
||||
test('should render a byte array containing max non-printables to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
|
||||
0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual(
|
||||
'\\xF0\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF7\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF',
|
||||
);
|
||||
});
|
||||
test('toJson', () => {
|
||||
expect(
|
||||
new DuckDBBlobValue(
|
||||
new Uint8Array([0x41, 0x42, 0x43, 0x31, 0x32, 0x33]),
|
||||
).toJson(),
|
||||
).toStrictEqual('ABC123');
|
||||
});
|
||||
});
|
||||
18
ts/pkgs/duckdb-data-values/test/DuckDBDateValue.test.ts
Normal file
18
ts/pkgs/duckdb-data-values/test/DuckDBDateValue.test.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBDateValue } from '../src/DuckDBDateValue';
|
||||
|
||||
suite('DuckDBDateValue', () => {
|
||||
test('should render a normal date value to the correct string', () => {
|
||||
expect(new DuckDBDateValue(19643).toString()).toStrictEqual('2023-10-13');
|
||||
});
|
||||
test('should render the max date value to the correct string', () => {
|
||||
expect(new DuckDBDateValue(2 ** 31 - 2).toString()).toStrictEqual(
|
||||
'5881580-07-10',
|
||||
);
|
||||
});
|
||||
test('should render the min date value to the correct string', () => {
|
||||
expect(new DuckDBDateValue(-(2 ** 31) + 2).toString()).toStrictEqual(
|
||||
'5877642-06-25 (BC)',
|
||||
);
|
||||
});
|
||||
});
|
||||
150
ts/pkgs/duckdb-data-values/test/DuckDBDecimalValue.test.ts
Normal file
150
ts/pkgs/duckdb-data-values/test/DuckDBDecimalValue.test.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBDecimalValue } from '../src/DuckDBDecimalValue';
|
||||
|
||||
suite('DuckDBDecimalValue', () => {
|
||||
test('should render a scaled value of zero with a scale of zero to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(0n, 0).toString()).toStrictEqual('0');
|
||||
});
|
||||
test('should render a small positive scaled value with a scale of zero to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(7n, 0).toString()).toStrictEqual('7');
|
||||
});
|
||||
test('should render a small negative scaled value with a scale of zero to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(-7n, 0).toString()).toStrictEqual('-7');
|
||||
});
|
||||
test('should render a large positive scaled value with a scale of zero to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(987654321098765432109876543210n, 0).toString(),
|
||||
).toStrictEqual('987654321098765432109876543210');
|
||||
});
|
||||
test('should render a large negative scaled value with a scale of zero to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(-987654321098765432109876543210n, 0).toString(),
|
||||
).toStrictEqual('-987654321098765432109876543210');
|
||||
});
|
||||
test('should render the maximum positive scaled value with a scale of zero to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(
|
||||
99999999999999999999999999999999999999n,
|
||||
0,
|
||||
).toString(),
|
||||
).toStrictEqual('99999999999999999999999999999999999999');
|
||||
});
|
||||
test('should render the maximum negative scaled value with a scale of zero to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(
|
||||
-99999999999999999999999999999999999999n,
|
||||
0,
|
||||
).toString(),
|
||||
).toStrictEqual('-99999999999999999999999999999999999999');
|
||||
});
|
||||
|
||||
test('should render a scaled value of zero with a non-zero scale to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(0n, 3).toString()).toStrictEqual('0.000');
|
||||
});
|
||||
test('should render a small positive scaled value with a non-zero scale to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(12345n, 3).toString()).toStrictEqual(
|
||||
'12.345',
|
||||
);
|
||||
});
|
||||
test('should render a small negative scaled value with a non-zero scale to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(-12345n, 3).toString()).toStrictEqual(
|
||||
'-12.345',
|
||||
);
|
||||
});
|
||||
test('should render a large positive scaled value with a non-zero scale to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(987654321098765432109876543210n, 10).toString(),
|
||||
).toStrictEqual('98765432109876543210.9876543210');
|
||||
});
|
||||
test('should render a large negative scaled value with a non-zero scale to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(-987654321098765432109876543210n, 10).toString(),
|
||||
).toStrictEqual('-98765432109876543210.9876543210');
|
||||
});
|
||||
test('should render leading and trailing zeros in the fractional part of value greater than one correctly', () => {
|
||||
expect(new DuckDBDecimalValue(120034500n, 7).toString()).toStrictEqual(
|
||||
'12.0034500',
|
||||
);
|
||||
});
|
||||
test('should render leading and trailing zeros in the fractional part of value less than negative one correctly', () => {
|
||||
expect(new DuckDBDecimalValue(-120034500n, 7).toString()).toStrictEqual(
|
||||
'-12.0034500',
|
||||
);
|
||||
});
|
||||
test('should render leading and trailing zeros in the fractional part of value between zero and one correctly', () => {
|
||||
expect(new DuckDBDecimalValue(34500n, 7).toString()).toStrictEqual(
|
||||
'0.0034500',
|
||||
);
|
||||
});
|
||||
test('should render leading and trailing zeros in the fractional part of value between zero and negative one correctly', () => {
|
||||
expect(new DuckDBDecimalValue(-34500n, 7).toString()).toStrictEqual(
|
||||
'-0.0034500',
|
||||
);
|
||||
});
|
||||
test('should render a small positive scaled value with a the maximum scale to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(1n, 38).toString()).toStrictEqual(
|
||||
'0.00000000000000000000000000000000000001',
|
||||
);
|
||||
});
|
||||
test('should render a small negative scaled value with a the maximum scale to the correct string', () => {
|
||||
expect(new DuckDBDecimalValue(-1n, 38).toString()).toStrictEqual(
|
||||
'-0.00000000000000000000000000000000000001',
|
||||
);
|
||||
});
|
||||
test('should render the maximum positive scaled value with a the maximum scale to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(
|
||||
99999999999999999999999999999999999999n,
|
||||
38,
|
||||
).toString(),
|
||||
).toStrictEqual('0.99999999999999999999999999999999999999');
|
||||
});
|
||||
test('should render the maximum negative scaled value with a the maximum scale to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(
|
||||
-99999999999999999999999999999999999999n,
|
||||
38,
|
||||
).toString(),
|
||||
).toStrictEqual('-0.99999999999999999999999999999999999999');
|
||||
});
|
||||
|
||||
test('should render a locale string with grouping by default', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(9876543210n, 0).toLocaleString(),
|
||||
).toStrictEqual('9,876,543,210');
|
||||
});
|
||||
|
||||
test('should render a European locale with . for grouping', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(9876543210n, 0).toLocaleString('de-DE'),
|
||||
).toStrictEqual('9.876.543.210');
|
||||
});
|
||||
|
||||
test('should render a locale string with a specified minimum fraction digits', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(12345n, 3).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 5,
|
||||
}),
|
||||
).toStrictEqual('12.34500');
|
||||
});
|
||||
|
||||
test('should render a locale string with a specified maximum fraction digits', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(12345n, 3).toLocaleString(undefined, {
|
||||
maximumFractionDigits: 1,
|
||||
}),
|
||||
).toStrictEqual('12.3');
|
||||
});
|
||||
|
||||
test('should render a decimal with a large whole part and fractional part in a European locale with the correct grouping and decimal', () => {
|
||||
expect(
|
||||
new DuckDBDecimalValue(98765432109876543210n, 10).toLocaleString(
|
||||
'de-DE',
|
||||
{
|
||||
useGrouping: true,
|
||||
maximumFractionDigits: 5,
|
||||
},
|
||||
),
|
||||
).toStrictEqual('9.876.543.210,98765');
|
||||
});
|
||||
});
|
||||
219
ts/pkgs/duckdb-data-values/test/DuckDBIntervalValue.test.ts
Normal file
219
ts/pkgs/duckdb-data-values/test/DuckDBIntervalValue.test.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBIntervalValue } from '../src/DuckDBIntervalValue';
|
||||
|
||||
const MICROS_IN_SEC = 1000000n;
|
||||
const MICROS_IN_MIN = 60n * MICROS_IN_SEC;
|
||||
const MICROS_IN_HR = 60n * MICROS_IN_MIN;
|
||||
const MAX_INT32 = 2n ** 31n - 1n;
|
||||
|
||||
suite('DuckDBIntervalValue', () => {
|
||||
test('should render an empty interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 0, 0n).toString()).toStrictEqual(
|
||||
'00:00:00',
|
||||
);
|
||||
});
|
||||
|
||||
test('should render a one month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(1, 0, 0n).toString()).toStrictEqual(
|
||||
'1 month',
|
||||
);
|
||||
});
|
||||
test('should render a negative one month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(-1, 0, 0n).toString()).toStrictEqual(
|
||||
'-1 months',
|
||||
);
|
||||
});
|
||||
test('should render a two month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(2, 0, 0n).toString()).toStrictEqual(
|
||||
'2 months',
|
||||
);
|
||||
});
|
||||
test('should render a negative two month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(-2, 0, 0n).toString()).toStrictEqual(
|
||||
'-2 months',
|
||||
);
|
||||
});
|
||||
test('should render a one year interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(12, 0, 0n).toString()).toStrictEqual(
|
||||
'1 year',
|
||||
);
|
||||
});
|
||||
test('should render a negative one year interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(-12, 0, 0n).toString()).toStrictEqual(
|
||||
'-1 years',
|
||||
);
|
||||
});
|
||||
test('should render a two year interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(24, 0, 0n).toString()).toStrictEqual(
|
||||
'2 years',
|
||||
);
|
||||
});
|
||||
test('should render a negative two year interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(-24, 0, 0n).toString()).toStrictEqual(
|
||||
'-2 years',
|
||||
);
|
||||
});
|
||||
test('should render a two year, three month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(24 + 3, 0, 0n).toString()).toStrictEqual(
|
||||
'2 years 3 months',
|
||||
);
|
||||
});
|
||||
test('should render a negative two year, three month interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(-(24 + 3), 0, 0n).toString()).toStrictEqual(
|
||||
'-2 years -3 months',
|
||||
);
|
||||
});
|
||||
|
||||
test('should render a one day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 1, 0n).toString()).toStrictEqual('1 day');
|
||||
});
|
||||
test('should render a negative one day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, -1, 0n).toString()).toStrictEqual(
|
||||
'-1 days',
|
||||
);
|
||||
});
|
||||
test('should render a two day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 2, 0n).toString()).toStrictEqual(
|
||||
'2 days',
|
||||
);
|
||||
});
|
||||
test('should render a negative two day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, -2, 0n).toString()).toStrictEqual(
|
||||
'-2 days',
|
||||
);
|
||||
});
|
||||
test('should render a 30 day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 30, 0n).toString()).toStrictEqual(
|
||||
'30 days',
|
||||
);
|
||||
});
|
||||
test('should render a 365 day interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 365, 0n).toString()).toStrictEqual(
|
||||
'365 days',
|
||||
);
|
||||
});
|
||||
|
||||
test('should render a one microsecond interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 0, 1n).toString()).toStrictEqual(
|
||||
'00:00:00.000001',
|
||||
);
|
||||
});
|
||||
test('should render a negative one microsecond interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 0, -1n).toString()).toStrictEqual(
|
||||
'-00:00:00.000001',
|
||||
);
|
||||
});
|
||||
test('should render a large microsecond interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 0, 987654n).toString()).toStrictEqual(
|
||||
'00:00:00.987654',
|
||||
);
|
||||
});
|
||||
test('should render a large negative microsecond interval to the correct string', () => {
|
||||
expect(new DuckDBIntervalValue(0, 0, -987654n).toString()).toStrictEqual(
|
||||
'-00:00:00.987654',
|
||||
);
|
||||
});
|
||||
test('should render a one second interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, MICROS_IN_SEC).toString(),
|
||||
).toStrictEqual('00:00:01');
|
||||
});
|
||||
test('should render a negative one second interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -MICROS_IN_SEC).toString(),
|
||||
).toStrictEqual('-00:00:01');
|
||||
});
|
||||
test('should render a 59 second interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, 59n * MICROS_IN_SEC).toString(),
|
||||
).toStrictEqual('00:00:59');
|
||||
});
|
||||
test('should render a -59 second interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -59n * MICROS_IN_SEC).toString(),
|
||||
).toStrictEqual('-00:00:59');
|
||||
});
|
||||
test('should render a one minute interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, MICROS_IN_MIN).toString(),
|
||||
).toStrictEqual('00:01:00');
|
||||
});
|
||||
test('should render a negative one minute interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -MICROS_IN_MIN).toString(),
|
||||
).toStrictEqual('-00:01:00');
|
||||
});
|
||||
test('should render a 59 minute interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, 59n * MICROS_IN_MIN).toString(),
|
||||
).toStrictEqual('00:59:00');
|
||||
});
|
||||
test('should render a -59 minute interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -59n * MICROS_IN_MIN).toString(),
|
||||
).toStrictEqual('-00:59:00');
|
||||
});
|
||||
test('should render a one hour interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('01:00:00');
|
||||
});
|
||||
test('should render a negative one hour interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('-01:00:00');
|
||||
});
|
||||
test('should render a 24 hour interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, 24n * MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('24:00:00');
|
||||
});
|
||||
test('should render a -24 hour interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -24n * MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('-24:00:00');
|
||||
});
|
||||
test('should render a very large interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, MAX_INT32 * MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('2147483647:00:00');
|
||||
});
|
||||
test('should render a very large negative interval to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, -MAX_INT32 * MICROS_IN_HR).toString(),
|
||||
).toStrictEqual('-2147483647:00:00');
|
||||
});
|
||||
test('should render a very large interval with microseconds to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(0, 0, MAX_INT32 * MICROS_IN_HR + 1n).toString(),
|
||||
).toStrictEqual('2147483647:00:00.000001');
|
||||
});
|
||||
test('should render a very large negative interval with microseconds to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(
|
||||
0,
|
||||
0,
|
||||
-(MAX_INT32 * MICROS_IN_HR + 1n),
|
||||
).toString(),
|
||||
).toStrictEqual('-2147483647:00:00.000001');
|
||||
});
|
||||
|
||||
test('should render a interval with multiple parts to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(
|
||||
24 + 3,
|
||||
5,
|
||||
7n * MICROS_IN_HR + 11n * MICROS_IN_MIN + 13n * MICROS_IN_SEC + 17n,
|
||||
).toString(),
|
||||
).toStrictEqual('2 years 3 months 5 days 07:11:13.000017');
|
||||
});
|
||||
test('should render a negative interval with multiple parts to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBIntervalValue(
|
||||
-(24 + 3),
|
||||
-5,
|
||||
-(7n * MICROS_IN_HR + 11n * MICROS_IN_MIN + 13n * MICROS_IN_SEC + 17n),
|
||||
).toString(),
|
||||
).toStrictEqual('-2 years -3 months -5 days -07:11:13.000017');
|
||||
});
|
||||
});
|
||||
45
ts/pkgs/duckdb-data-values/test/DuckDBListValue.test.ts
Normal file
45
ts/pkgs/duckdb-data-values/test/DuckDBListValue.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBMapValue } from '../src';
|
||||
import { DuckDBListValue } from '../src/DuckDBListValue';
|
||||
|
||||
suite('DuckDBListValue', () => {
|
||||
test('should render an empty list to the correct string', () => {
|
||||
expect(new DuckDBListValue([]).toString()).toStrictEqual('[]');
|
||||
});
|
||||
test('should render a single element list to the correct string', () => {
|
||||
expect(new DuckDBListValue([123]).toString()).toStrictEqual('[123]');
|
||||
});
|
||||
test('should render a multi-element list to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBListValue(['abc', null, true, '']).toString(),
|
||||
).toStrictEqual(`['abc', NULL, true, '']`);
|
||||
});
|
||||
test('should render a list with nested lists to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBListValue([
|
||||
new DuckDBListValue([]),
|
||||
null,
|
||||
new DuckDBListValue([123, null, 'xyz']),
|
||||
]).toString(),
|
||||
).toStrictEqual(`[[], NULL, [123, NULL, 'xyz']]`);
|
||||
});
|
||||
test('toJson with complex values', () => {
|
||||
expect(
|
||||
new DuckDBListValue([
|
||||
new DuckDBMapValue([
|
||||
{ key: 'foo', value: 123 },
|
||||
{ key: 'bar', value: 'abc' },
|
||||
]),
|
||||
null,
|
||||
new DuckDBMapValue([
|
||||
{ key: 'foo', value: null },
|
||||
{ key: 'bar', value: 'xyz' },
|
||||
]),
|
||||
]).toJson(),
|
||||
).toStrictEqual([
|
||||
{ "'foo'": 123, "'bar'": 'abc' },
|
||||
null,
|
||||
{ "'foo'": null, "'bar'": 'xyz' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
77
ts/pkgs/duckdb-data-values/test/DuckDBMapValue.test.ts
Normal file
77
ts/pkgs/duckdb-data-values/test/DuckDBMapValue.test.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBListValue } from '../src/DuckDBListValue';
|
||||
import { DuckDBMapValue } from '../src/DuckDBMapValue';
|
||||
|
||||
suite('DuckDBMapValue', () => {
|
||||
test('should render an empty map to the correct string', () => {
|
||||
expect(new DuckDBMapValue([]).toString()).toStrictEqual('{}');
|
||||
});
|
||||
test('should render a single-entry map to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([{ key: 'x', value: 1 }]).toString(),
|
||||
).toStrictEqual(`{'x': 1}`);
|
||||
});
|
||||
test('should render a multi-entry map to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([
|
||||
{ key: 1, value: 42.001 },
|
||||
{ key: 5, value: -32.1 },
|
||||
{ key: 3, value: null },
|
||||
]).toString(),
|
||||
).toStrictEqual(`{1: 42.001, 5: -32.1, 3: NULL}`);
|
||||
});
|
||||
test('should render a multi-entry map with complex key types to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([
|
||||
{
|
||||
key: new DuckDBListValue(['a', 'b']),
|
||||
value: new DuckDBListValue([1.1, 2.2]),
|
||||
},
|
||||
{
|
||||
key: new DuckDBListValue(['c', 'd']),
|
||||
value: new DuckDBListValue([3.3, 4.4]),
|
||||
},
|
||||
]).toString(),
|
||||
).toStrictEqual(`{['a', 'b']: [1.1, 2.2], ['c', 'd']: [3.3, 4.4]}`);
|
||||
});
|
||||
test('should render a map with nested maps to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([
|
||||
{ key: new DuckDBMapValue([]), value: new DuckDBMapValue([]) },
|
||||
{
|
||||
key: new DuckDBMapValue([{ key: 'key1', value: 'value1' }]),
|
||||
value: new DuckDBMapValue([
|
||||
{ key: 1, value: 42.001 },
|
||||
{ key: 5, value: -32.1 },
|
||||
{ key: 3, value: null },
|
||||
]),
|
||||
},
|
||||
]).toString(),
|
||||
).toStrictEqual(
|
||||
`{{}: {}, {'key1': 'value1'}: {1: 42.001, 5: -32.1, 3: NULL}}`,
|
||||
);
|
||||
});
|
||||
test('toJson basics', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([
|
||||
{ key: 'a', value: 1 },
|
||||
{ key: 'b', value: 2 },
|
||||
{ key: 'c', value: 3 },
|
||||
]).toJson(),
|
||||
).toStrictEqual({ "'a'": 1, "'b'": 2, "'c'": 3 });
|
||||
});
|
||||
test('toJson with complex keys and values', () => {
|
||||
expect(
|
||||
new DuckDBMapValue([
|
||||
{
|
||||
key: new DuckDBListValue(['a', 'b']),
|
||||
value: new DuckDBListValue([1.1, 2.2]),
|
||||
},
|
||||
{
|
||||
key: new DuckDBListValue(['c', 'd']),
|
||||
value: new DuckDBListValue([3.3, 4.4]),
|
||||
},
|
||||
]).toJson(),
|
||||
).toStrictEqual({ "['a', 'b']": [1.1, 2.2], "['c', 'd']": [3.3, 4.4] });
|
||||
});
|
||||
});
|
||||
110
ts/pkgs/duckdb-data-values/test/DuckDBStructValue.test.ts
Normal file
110
ts/pkgs/duckdb-data-values/test/DuckDBStructValue.test.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBMapValue } from '../src/DuckDBMapValue';
|
||||
import { DuckDBStructValue } from '../src/DuckDBStructValue';
|
||||
|
||||
suite('DuckDBStructValue', () => {
|
||||
test('should render an empty struct to the correct string', () => {
|
||||
expect(new DuckDBStructValue([]).toString()).toStrictEqual('{}');
|
||||
});
|
||||
test('should render a single-entry struct to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([{ key: 'x', value: 1 }]).toString(),
|
||||
).toStrictEqual(`{'x': 1}`);
|
||||
});
|
||||
test('should render a multi-entry struct to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'x', value: 1 },
|
||||
{ key: 'y', value: 2 },
|
||||
{ key: 'z', value: 3 },
|
||||
]).toString(),
|
||||
).toStrictEqual(`{'x': 1, 'y': 2, 'z': 3}`);
|
||||
});
|
||||
test('should render a multi-entry struct with different value types to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'key1', value: 'string' },
|
||||
{ key: 'key2', value: 1 },
|
||||
{ key: 'key3', value: 12.345 },
|
||||
{ key: 'key0', value: null },
|
||||
]).toString(),
|
||||
).toStrictEqual(
|
||||
`{'key1': 'string', 'key2': 1, 'key3': 12.345, 'key0': NULL}`,
|
||||
);
|
||||
});
|
||||
test('should render a multi-entry struct with empty keys to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: '', value: 2 },
|
||||
{ key: '', value: 1 },
|
||||
{ key: '', value: 3 },
|
||||
]).toString(),
|
||||
).toStrictEqual(`{'': 2, '': 1, '': 3}`);
|
||||
});
|
||||
test('should render a struct with nested structs to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'empty_struct', value: new DuckDBStructValue([]) },
|
||||
{
|
||||
key: 'struct',
|
||||
value: new DuckDBStructValue([
|
||||
{ key: 'key1', value: 'string' },
|
||||
{ key: 'key2', value: 1 },
|
||||
{ key: 'key3', value: 12.345 },
|
||||
]),
|
||||
},
|
||||
]).toString(),
|
||||
).toStrictEqual(
|
||||
`{'empty_struct': {}, 'struct': {'key1': 'string', 'key2': 1, 'key3': 12.345}}`,
|
||||
);
|
||||
});
|
||||
test('toJson with simple keys and values', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'x', value: 1 },
|
||||
{ key: 'y', value: 2 },
|
||||
{ key: 'z', value: 3 },
|
||||
]).toJson(),
|
||||
).toStrictEqual({ "'x'": 1, "'y'": 2, "'z'": 3 });
|
||||
});
|
||||
test('toJson with nested struct values', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'empty_struct', value: new DuckDBStructValue([]) },
|
||||
{
|
||||
key: 'struct',
|
||||
value: new DuckDBStructValue([
|
||||
{ key: 'key1', value: 'string' },
|
||||
{ key: 'key2', value: 1 },
|
||||
{ key: 'key3', value: 12.345 },
|
||||
]),
|
||||
},
|
||||
]).toJson(),
|
||||
).toStrictEqual({
|
||||
"'empty_struct'": {},
|
||||
"'struct'": { "'key1'": 'string', "'key2'": 1, "'key3'": 12.345 },
|
||||
});
|
||||
});
|
||||
test('toJson with nested complex values', () => {
|
||||
expect(
|
||||
new DuckDBStructValue([
|
||||
{ key: 'empty_struct', value: new DuckDBStructValue([]) },
|
||||
{
|
||||
key: 'struct',
|
||||
value: new DuckDBStructValue([
|
||||
{
|
||||
key: 'key1',
|
||||
value: new DuckDBMapValue([
|
||||
{ key: 'foo', value: null },
|
||||
{ key: 'bar', value: 'xyz' },
|
||||
]),
|
||||
},
|
||||
]),
|
||||
},
|
||||
]).toJson(),
|
||||
).toStrictEqual({
|
||||
"'empty_struct'": {},
|
||||
"'struct'": { "'key1'": { "'foo'": null, "'bar'": 'xyz' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
60
ts/pkgs/duckdb-data-values/test/DuckDBTimeTZValue.test.ts
Normal file
60
ts/pkgs/duckdb-data-values/test/DuckDBTimeTZValue.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimeTZValue } from '../src/DuckDBTimeTZValue';
|
||||
|
||||
suite('DuckDBTimeTZValue', () => {
|
||||
test('should render a normal time value with a positive offset to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimeTZValue(
|
||||
((12n * 60n + 34n) * 60n + 56n) * 1000000n + 789012n,
|
||||
(13 * 60 + 24) * 60 + 57,
|
||||
).toString(),
|
||||
).toStrictEqual('12:34:56.789012+13:24:57');
|
||||
});
|
||||
test('should render a normal time value with millisecond precision with an offset in minutes to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimeTZValue(
|
||||
((12n * 60n + 34n) * 60n + 56n) * 1000000n + 789000n,
|
||||
(13 * 60 + 24) * 60,
|
||||
).toString(),
|
||||
).toStrictEqual('12:34:56.789+13:24');
|
||||
});
|
||||
test('should render a normal time value with second precision with an offset in hours to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimeTZValue(
|
||||
((12n * 60n + 34n) * 60n + 56n) * 1000000n,
|
||||
(13 * 60 + 0) * 60,
|
||||
).toString(),
|
||||
).toStrictEqual('12:34:56+13');
|
||||
});
|
||||
test('should render a zero time value with a zero offset to the correct string', () => {
|
||||
expect(new DuckDBTimeTZValue(0n, 0).toString()).toStrictEqual(
|
||||
'00:00:00+00',
|
||||
);
|
||||
});
|
||||
test('should render the max value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimeTZValue(
|
||||
((24n * 60n + 0n) * 60n + 0n) * 1000000n,
|
||||
-((15 * 60 + 59) * 60 + 59),
|
||||
).toString(),
|
||||
).toStrictEqual('24:00:00-15:59:59');
|
||||
});
|
||||
test('should render the min value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimeTZValue(0n, (15 * 60 + 59) * 60 + 59).toString(),
|
||||
).toStrictEqual('00:00:00+15:59:59');
|
||||
});
|
||||
test('should construct the correct value from bits', () => {
|
||||
expect(DuckDBTimeTZValue.fromBits(0n).toString()).toStrictEqual(
|
||||
'00:00:00+15:59:59',
|
||||
);
|
||||
});
|
||||
test('should construct the correct value from bits', () => {
|
||||
expect(
|
||||
DuckDBTimeTZValue.fromBits(
|
||||
(BigInt.asUintN(40, ((24n * 60n + 0n) * 60n + 0n) * 1000000n) << 24n) |
|
||||
BigInt.asUintN(24, (31n * 60n + 59n) * 60n + 58n),
|
||||
).toString(),
|
||||
).toStrictEqual('24:00:00-15:59:59');
|
||||
});
|
||||
});
|
||||
18
ts/pkgs/duckdb-data-values/test/DuckDBTimeValue.test.ts
Normal file
18
ts/pkgs/duckdb-data-values/test/DuckDBTimeValue.test.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimeValue } from '../src/DuckDBTimeValue';
|
||||
|
||||
suite('DuckDBTimeValue', () => {
|
||||
test('should render a normal time value to the correct string', () => {
|
||||
expect(new DuckDBTimeValue(45296000000n).toString()).toStrictEqual(
|
||||
'12:34:56',
|
||||
);
|
||||
});
|
||||
test('should render the max time value to the correct string', () => {
|
||||
expect(new DuckDBTimeValue(86399999999n).toString()).toStrictEqual(
|
||||
'23:59:59.999999',
|
||||
);
|
||||
});
|
||||
test('should render the min time value to the correct string', () => {
|
||||
expect(new DuckDBTimeValue(0n).toString()).toStrictEqual('00:00:00');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimestampMicrosecondsValue } from '../src/DuckDBTimestampMicrosecondsValue';
|
||||
|
||||
suite('DuckDBTimestampMicrosecondsValue', () => {
|
||||
test('should render a normal timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(1612325106007800n).toString(),
|
||||
).toStrictEqual('2021-02-03 04:05:06.0078');
|
||||
});
|
||||
test('should render a zero timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampMicrosecondsValue(0n).toString()).toStrictEqual(
|
||||
'1970-01-01 00:00:00',
|
||||
);
|
||||
});
|
||||
test('should render a negative timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampMicrosecondsValue(-7n).toString()).toStrictEqual(
|
||||
'1969-12-31 23:59:59.999993',
|
||||
);
|
||||
});
|
||||
test('should render a large positive timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(2353318271999999000n).toString(),
|
||||
).toStrictEqual('76543-09-08 23:59:59.999');
|
||||
});
|
||||
test('should render a large negative (AD) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(-58261244276543211n).toString(),
|
||||
).toStrictEqual('0123-10-11 01:02:03.456789');
|
||||
});
|
||||
test('should render a large negative (BC) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(-65992661876543211n).toString(),
|
||||
).toStrictEqual('0123-10-11 (BC) 01:02:03.456789');
|
||||
});
|
||||
test('should render the max timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(9223372036854775806n).toString(),
|
||||
).toStrictEqual('294247-01-10 04:00:54.775806');
|
||||
});
|
||||
test('should render the min timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(-9223372022400000000n).toString(),
|
||||
).toStrictEqual('290309-12-22 (BC) 00:00:00');
|
||||
});
|
||||
test('should render the positive infinity timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(9223372036854775807n).toString(),
|
||||
).toStrictEqual('infinity');
|
||||
});
|
||||
test('should render the negative infinity timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMicrosecondsValue(-9223372036854775807n).toString(),
|
||||
).toStrictEqual('-infinity');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimestampMillisecondsValue } from '../src/DuckDBTimestampMillisecondsValue';
|
||||
|
||||
suite('DuckDBTimestampMillisecondsValue', () => {
|
||||
test('should render a normal timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(1612325106007n).toString(),
|
||||
).toStrictEqual('2021-02-03 04:05:06.007');
|
||||
});
|
||||
test('should render a zero timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampMillisecondsValue(0n).toString()).toStrictEqual(
|
||||
'1970-01-01 00:00:00',
|
||||
);
|
||||
});
|
||||
test('should render a negative timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampMillisecondsValue(-7n).toString()).toStrictEqual(
|
||||
'1969-12-31 23:59:59.993',
|
||||
);
|
||||
});
|
||||
test('should render a large positive timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(2353318271999999n).toString(),
|
||||
).toStrictEqual('76543-09-08 23:59:59.999');
|
||||
});
|
||||
test('should render a large negative (AD) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(-58261244276544n).toString(),
|
||||
).toStrictEqual('0123-10-11 01:02:03.456');
|
||||
});
|
||||
test('should render a large negative (BC) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(-65992661876544n).toString(),
|
||||
).toStrictEqual('0123-10-11 (BC) 01:02:03.456');
|
||||
});
|
||||
test('should render the max timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(9223372036854775n).toString(),
|
||||
).toStrictEqual('294247-01-10 04:00:54.775');
|
||||
});
|
||||
test('should render the min timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampMillisecondsValue(-9223372022400000n).toString(),
|
||||
).toStrictEqual('290309-12-22 (BC) 00:00:00');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimestampNanosecondsValue } from '../src/DuckDBTimestampNanosecondsValue';
|
||||
|
||||
suite('DuckDBTimestampNanosecondsValue', () => {
|
||||
test('should render a normal timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(1612325106007891000n).toString(),
|
||||
).toStrictEqual('2021-02-03 04:05:06.007891');
|
||||
});
|
||||
test('should render a zero timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampNanosecondsValue(0n).toString()).toStrictEqual(
|
||||
'1970-01-01 00:00:00',
|
||||
);
|
||||
});
|
||||
test('should render a negative timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(-7000n).toString(),
|
||||
).toStrictEqual('1969-12-31 23:59:59.999993');
|
||||
});
|
||||
test('should render a large positive timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(8857641599999123000n).toString(),
|
||||
).toStrictEqual('2250-09-08 23:59:59.999123');
|
||||
});
|
||||
test('should render a large negative timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(-8495881076543211000n).toString(),
|
||||
).toStrictEqual('1700-10-11 01:02:03.456789');
|
||||
});
|
||||
test('should render the max timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(9223372036854775806n).toString(),
|
||||
).toStrictEqual('2262-04-11 23:47:16.854775');
|
||||
});
|
||||
test('should render the min timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampNanosecondsValue(-9223372036854775806n).toString(),
|
||||
).toStrictEqual('1677-09-21 00:12:43.145225');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimestampSecondsValue } from '../src/DuckDBTimestampSecondsValue';
|
||||
|
||||
suite('DuckDBTimestampSecondsValue', () => {
|
||||
test('should render a normal timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(1612325106n).toString(),
|
||||
).toStrictEqual('2021-02-03 04:05:06');
|
||||
});
|
||||
test('should render a zero timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampSecondsValue(0n).toString()).toStrictEqual(
|
||||
'1970-01-01 00:00:00',
|
||||
);
|
||||
});
|
||||
test('should render a negative timestamp value to the correct string', () => {
|
||||
expect(new DuckDBTimestampSecondsValue(-7n).toString()).toStrictEqual(
|
||||
'1969-12-31 23:59:53',
|
||||
);
|
||||
});
|
||||
test('should render a large positive timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(2353318271999n).toString(),
|
||||
).toStrictEqual('76543-09-08 23:59:59');
|
||||
});
|
||||
test('should render a large negative (AD) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(-58261244277n).toString(),
|
||||
).toStrictEqual('0123-10-11 01:02:03');
|
||||
});
|
||||
test('should render a large negative (BC) timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(-65992661877n).toString(),
|
||||
).toStrictEqual('0123-10-11 (BC) 01:02:03');
|
||||
});
|
||||
test('should render the max timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(9223372036854n).toString(),
|
||||
).toStrictEqual('294247-01-10 04:00:54');
|
||||
});
|
||||
test('should render the min timestamp value to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampSecondsValue(-9223372022400n).toString(),
|
||||
).toStrictEqual('290309-12-22 (BC) 00:00:00');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBTimestampTZValue } from '../src/DuckDBTimestampTZValue';
|
||||
|
||||
suite('DuckDBTimestampTZValue', () => {
|
||||
test('should render a timestamp tz value with no timezone offset to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampTZValue(1612325106007800n).toDuckDBString(),
|
||||
).toStrictEqual('2021-02-03 04:05:06.0078+00'); // defaults to UTC
|
||||
});
|
||||
test('should render a timestamp tz value with a zero timezone offset to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampTZValue(1612325106007800n).toDuckDBString({
|
||||
timezoneOffsetInMinutes: 0,
|
||||
}),
|
||||
).toStrictEqual('2021-02-03 04:05:06.0078+00');
|
||||
});
|
||||
test('should render a timestamp tz value with a positive timezone offset to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampTZValue(1612325106007800n).toDuckDBString({
|
||||
timezoneOffsetInMinutes: 300,
|
||||
}),
|
||||
).toStrictEqual('2021-02-03 09:05:06.0078+05');
|
||||
});
|
||||
test('should render a timestamp tz value with a negative timezone offset to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampTZValue(1612325106007800n).toDuckDBString({
|
||||
timezoneOffsetInMinutes: -300,
|
||||
}),
|
||||
).toStrictEqual('2021-02-02 23:05:06.0078-05');
|
||||
});
|
||||
test('should render a timestamp tz value with a timezone offset containing minutes to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBTimestampTZValue(1612325106007800n).toDuckDBString({
|
||||
timezoneOffsetInMinutes: 330,
|
||||
}),
|
||||
).toStrictEqual('2021-02-03 09:35:06.0078+05:30');
|
||||
});
|
||||
});
|
||||
49
ts/pkgs/duckdb-data-values/test/DuckDBUUIDValue.test.ts
Normal file
49
ts/pkgs/duckdb-data-values/test/DuckDBUUIDValue.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBUUIDValue } from '../src/DuckDBUUIDValue';
|
||||
|
||||
suite('DuckDBUUIDValue', () => {
|
||||
test('should render all zero bytes to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBUUIDValue(
|
||||
new Uint8Array([
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual('00000000-0000-0000-0000-000000000000');
|
||||
});
|
||||
test('should render all max bytes to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBUUIDValue(
|
||||
new Uint8Array([
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual('ffffffff-ffff-ffff-ffff-ffffffffffff');
|
||||
});
|
||||
test('should render arbitrary bytes to the correct string', () => {
|
||||
expect(
|
||||
new DuckDBUUIDValue(
|
||||
new Uint8Array([
|
||||
0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0xfe, 0xdc, 0xba,
|
||||
0x98, 0x76, 0x54, 0x32, 0x10,
|
||||
]),
|
||||
).toString(),
|
||||
).toStrictEqual('f0e1d2c3-b4a5-9687-fedc-ba9876543210');
|
||||
});
|
||||
test('should render a uint128 to the correct string', () => {
|
||||
expect(
|
||||
DuckDBUUIDValue.fromUint128(
|
||||
0xf0e1d2c3b4a59687fedcba9876543210n,
|
||||
).toString(),
|
||||
).toStrictEqual('f0e1d2c3-b4a5-9687-fedc-ba9876543210');
|
||||
});
|
||||
test('should render a stored hugeint to the correct string', () => {
|
||||
expect(
|
||||
DuckDBUUIDValue.fromStoredHugeint(
|
||||
0x70e1d2c3b4a59687fedcba9876543210n, // note the flipped MSB
|
||||
).toString(),
|
||||
).toStrictEqual('f0e1d2c3-b4a5-9687-fedc-ba9876543210');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { getVarIntFromBytes } from '../../src/conversion/getVarIntFromBytes';
|
||||
|
||||
suite('getVarIntFromBytes', () => {
|
||||
test('should return correct value for varint representation of 0', () => {
|
||||
expect(
|
||||
getVarIntFromBytes(new Uint8Array([0x80, 0x00, 0x01, 0x00])),
|
||||
).toEqual(0n);
|
||||
});
|
||||
test('should return correct value for varint representation of 1', () => {
|
||||
expect(
|
||||
getVarIntFromBytes(new Uint8Array([0x80, 0x00, 0x01, 0x01])),
|
||||
).toEqual(1n);
|
||||
});
|
||||
test('should return correct value for varint representation of -1', () => {
|
||||
expect(
|
||||
getVarIntFromBytes(new Uint8Array([0x7f, 0xff, 0xfe, 0xfe])),
|
||||
).toEqual(-1n);
|
||||
});
|
||||
test('should return correct value for max varint', () => {
|
||||
// max VARINT = max IEEE double = 2^1023 * (1 + (1 − 2^−52)) ~= 1.7976931348623157 * 10^308
|
||||
// Note that the storage format supports much larger than this, but DuckDB specifies this max to support conversion to/from DOUBLE.
|
||||
expect(
|
||||
getVarIntFromBytes(
|
||||
// prettier-ignore
|
||||
new Uint8Array([0x80, 0x00, 0x80,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
]),
|
||||
),
|
||||
).toEqual(
|
||||
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368n,
|
||||
);
|
||||
});
|
||||
test('should return correct value for min varint', () => {
|
||||
// min VARINT = -max VARINT
|
||||
expect(
|
||||
getVarIntFromBytes(
|
||||
// prettier-ignore
|
||||
new Uint8Array([0x7F, 0xFF, 0x7F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
]),
|
||||
),
|
||||
).toEqual(
|
||||
-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368n,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { expect, suite, test } from 'vitest';
|
||||
import { DuckDBListValue } from '../../src';
|
||||
import { jsonFromDuckDBValue } from '../../src/conversion/jsonFromDuckDBValue';
|
||||
|
||||
suite('jsonFromDuckDBValue', () => {
|
||||
test('null', () => {
|
||||
expect(jsonFromDuckDBValue(null)).toBe(null);
|
||||
});
|
||||
test('boolean', () => {
|
||||
expect(jsonFromDuckDBValue(true)).toBe(true);
|
||||
});
|
||||
test('number', () => {
|
||||
expect(jsonFromDuckDBValue(42)).toBe(42);
|
||||
});
|
||||
test('bigint', () => {
|
||||
expect(jsonFromDuckDBValue(12345n)).toBe('12345');
|
||||
});
|
||||
test('string', () => {
|
||||
expect(jsonFromDuckDBValue('foo')).toBe('foo');
|
||||
});
|
||||
test('special', () => {
|
||||
expect(jsonFromDuckDBValue(new DuckDBListValue([1, 2, 3]))).toStrictEqual([
|
||||
1, 2, 3,
|
||||
]);
|
||||
});
|
||||
});
|
||||
6
ts/pkgs/duckdb-data-values/test/tsconfig.json
Normal file
6
ts/pkgs/duckdb-data-values/test/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.test.json",
|
||||
"references": [
|
||||
{ "path": "../src" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user