hyparquet/test/convert.test.js

143 lines
5.2 KiB
JavaScript
Raw Normal View History

2024-02-26 20:20:48 +00:00
import { describe, expect, it } from 'vitest'
2024-05-13 16:22:55 +00:00
import { convert, parseFloat16 } from '../src/convert.js'
2024-02-26 20:20:48 +00:00
/**
* @typedef {import('../src/types.js').SchemaElement} SchemaElement
*/
describe('convert function', () => {
const name = 'name'
it('returns the same data if converted_type is undefined', () => {
const data = [1, 2, 3]
const schemaElement = { name }
expect(convert(data, schemaElement)).toEqual(data)
})
2024-05-23 05:24:54 +00:00
it('converts byte arrays to utf8', () => {
const data = [new TextEncoder().encode('foo'), new TextEncoder().encode('bar')]
2024-02-26 20:20:48 +00:00
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'UTF8' }
2024-05-23 05:24:54 +00:00
expect(convert(data, schemaElement)).toEqual(['foo', 'bar'])
})
it('converts byte arrays to utf8 default true', () => {
const data = [new TextEncoder().encode('foo'), new TextEncoder().encode('bar')]
/** @type {SchemaElement} */
const schemaElement = { name, type: 'BYTE_ARRAY' }
expect(convert(data, schemaElement)).toEqual(['foo', 'bar'])
})
it('preserves byte arrays utf8=false', () => {
const data = [new TextEncoder().encode('foo'), new TextEncoder().encode('bar')]
/** @type {SchemaElement} */
const schemaElement = { name, type: 'BYTE_ARRAY' }
expect(convert(data, schemaElement, false)).toEqual([
new Uint8Array([102, 111, 111]), new Uint8Array([98, 97, 114]),
])
2024-02-26 20:20:48 +00:00
})
it('converts numbers to DECIMAL', () => {
const data = [100, 200]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'DECIMAL' }
expect(convert(data, schemaElement)).toEqual([100, 200])
})
it('converts numbers to DECIMAL with scale', () => {
const data = [100, 200]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'DECIMAL', scale: 2 }
2024-05-13 03:41:39 +00:00
expect(convert(data, schemaElement)).toEqual([1, 2])
2024-02-26 20:20:48 +00:00
})
it('converts bigint to DECIMAL', () => {
const data = [BigInt(1000), BigInt(2000)]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'DECIMAL' }
2024-05-14 07:35:39 +00:00
expect(convert(data, schemaElement)).toEqual([1000, 2000])
2024-02-26 20:20:48 +00:00
})
it('converts bigint to DECIMAL with scale', () => {
2024-05-13 03:41:39 +00:00
const data = [BigInt(10), BigInt(20)]
2024-02-26 20:20:48 +00:00
/** @type {SchemaElement} */
2024-05-13 03:41:39 +00:00
const schemaElement = { name, converted_type: 'DECIMAL', scale: 2 }
expect(convert(data, schemaElement)).toEqual([0.1, 0.2])
2024-02-26 20:20:48 +00:00
})
it('converts byte arrays to DECIMAL', () => {
const data = [new Uint8Array([0, 0, 0, 100]), new Uint8Array([0, 0, 0, 200])]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'DECIMAL', scale: 0 }
expect(convert(data, schemaElement)).toEqual([100, 200])
})
it('converts epoch time to DATE', () => {
const data = [1, 2] // days since epoch
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'DATE' }
2024-05-13 01:12:30 +00:00
expect(convert(data, schemaElement)).toEqual([new Date(86400000), new Date(86400000 * 2)])
2024-02-26 20:20:48 +00:00
})
2024-05-13 01:12:30 +00:00
it('converts INT96 to DATE', () => {
// from alltypes_plain.parquet
const data = [45284764452596988585705472n, 45284764452597048585705472n]
/** @type {SchemaElement} */
const schemaElement = { name, type: 'INT96' }
expect(convert(data, schemaElement)).toEqual([new Date('2009-03-01T00:00:00.000Z'), new Date('2009-03-01T00:01:00.000Z')])
})
2024-02-26 20:20:48 +00:00
it('parses strings to JSON', () => {
const data = ['{"key": true}', '{"quay": 314}']
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'JSON' }
expect(convert(data, schemaElement)).toEqual([{ key: true }, { quay: 314 }])
})
it('throws error for BSON conversion', () => {
const data = [{}]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'BSON' }
expect(() => convert(data, schemaElement))
.toThrow('parquet bson not supported')
})
it('throws error for INTERVAL conversion', () => {
const data = [{}]
/** @type {SchemaElement} */
const schemaElement = { name, converted_type: 'INTERVAL' }
expect(() => convert(data, schemaElement))
.toThrow('parquet interval not supported')
})
})
2024-05-13 16:22:55 +00:00
describe('parseFloat16', () => {
it('convert float16 numbers', () => {
expect(parseFloat16(undefined)).toBe(undefined)
2024-05-13 16:22:55 +00:00
expect(parseFloat16(new Uint8Array([0x00, 0xbc]))).toBe(-1)
expect(parseFloat16(new Uint8Array([0x00, 0x00]))).toBe(0)
expect(parseFloat16(new Uint8Array([0x00, 0x38]))).toBe(0.5)
expect(parseFloat16(new Uint8Array([0x00, 0x3c]))).toBe(1)
expect(parseFloat16(new Uint8Array([0x00, 0x40]))).toBe(2)
})
it('convert float16 -0', () => {
2024-05-13 16:22:55 +00:00
expect(parseFloat16(new Uint8Array([0x00, 0x80]))).toBe(-0)
expect(parseFloat16(new Uint8Array([0x00, 0x80]))).not.toBe(0)
})
it('convert float16 Infinity', () => {
2024-05-13 16:22:55 +00:00
expect(parseFloat16(new Uint8Array([0x00, 0x7c]))).toBe(Infinity)
expect(parseFloat16(new Uint8Array([0x00, 0xfc]))).toBe(-Infinity)
})
it('convert float16 NaN', () => {
2024-05-13 16:22:55 +00:00
expect(parseFloat16(new Uint8Array([0x00, 0x7e]))).toBeNaN()
expect(parseFloat16(new Uint8Array([0x01, 0x7e]))).toBeNaN()
})
it('convert float16 subnormal number', () => {
2024-05-13 16:22:55 +00:00
expect(parseFloat16(new Uint8Array([0xff, 0x03])))
.toBeCloseTo(Math.pow(2, -14) * (1023 / 1024), 5)
})
})