1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18import { util, Vector, DataType, Int64 } from 'apache-arrow';
19import {
20    validateVector,
21    encodeAll, encodeEach, encodeEachDOM, encodeEachNode,
22    int64sNoNulls, int64sWithNulls, int64sWithMaxInts,
23} from './utils';
24
25const testDOMStreams = process.env.TEST_DOM_STREAMS === 'true';
26const testNodeStreams = process.env.TEST_NODE_STREAMS === 'true';
27
28const typeFactory = () => new Int64();
29const valueName = `Int64`.toLowerCase();
30const encode0 = encodeAll(typeFactory);
31const encode1 = encodeEach(typeFactory);
32const encode2 = encodeEach(typeFactory, 5);
33const encode3 = encodeEach(typeFactory, 25);
34const encode4 = encodeEachDOM(typeFactory, 25);
35const encode5 = encodeEachNode(typeFactory, 25);
36
37const nulls0: any[] = [0x7fffffff];
38const nulls1: any[] = [0x7fffffff];
39nulls0[0] = new Uint32Array([0x7fffffff, 0x7fffffff]);
40nulls1[0] = util.BN.new(nulls0[0])[Symbol.toPrimitive]();
41
42type EncodeValues<T extends DataType> = (values: (T['TValue'] | null)[], nullVals?: any[]) => Promise<Vector<T>>;
43
44function encodeAndValidate<T extends DataType>(encode: EncodeValues<T>, providedNulls: any[] = [], expectedNulls = providedNulls) {
45    return (values: any[]) => {
46        return async () => {
47            const vector = await encode(values, providedNulls);
48            const expected = values.map((x) => {
49                switch (typeof x) {
50                    case 'number': return new Int32Array([x, 0]);
51                    case 'bigint': return new Int32Array(new BigInt64Array([x]).buffer);
52                }
53                return x ? x.slice() : x;
54            });
55            return validateVector(expected, vector, expectedNulls);
56        };
57    };
58}
59
60describe(`Int64Builder`, () => {
61    describe(`encode single chunk`, () => {
62        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode0, [], [])(int64sNoNulls(20)));
63        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode0, [null], [null])(int64sWithNulls(20)));
64        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode0, nulls0, nulls1)(int64sWithMaxInts(20)));
65    });
66    describe(`encode chunks length default`, () => {
67        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode1, [], [])(int64sNoNulls(20)));
68        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode1, [null], [null])(int64sWithNulls(20)));
69        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode1, nulls0, nulls1)(int64sWithMaxInts(20)));
70    });
71    describe(`encode chunks length 5`, () => {
72        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode2, [], [])(int64sNoNulls(20)));
73        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode2, [null], [null])(int64sWithNulls(20)));
74        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode2, nulls0, nulls1)(int64sWithMaxInts(20)));
75    });
76    describe(`encode chunks length 25`, () => {
77        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode3, [], [])(int64sNoNulls(20)));
78        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode3, [null], [null])(int64sWithNulls(20)));
79        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode3, nulls0, nulls1)(int64sWithMaxInts(20)));
80    });
81    testDOMStreams && describe(`encode chunks length 25, WhatWG stream`, () => {
82        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode4, [], [])(int64sNoNulls(20)));
83        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode4, [null], [null])(int64sWithNulls(20)));
84        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode4, nulls0, nulls1)(int64sWithMaxInts(20)));
85    });
86    testNodeStreams && describe(`encode chunks length 25, NodeJS stream`, () => {
87        it(`encodes ${valueName} no nulls`, encodeAndValidate(encode5, [], [])(int64sNoNulls(20)));
88        it(`encodes ${valueName} with nulls`, encodeAndValidate(encode5, [null], [null])(int64sWithNulls(20)));
89        it(`encodes ${valueName} with MAX_INT`, encodeAndValidate(encode5, nulls0, nulls1)(int64sWithMaxInts(20)));
90    });
91});
92