http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/cache/ComplexObject.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/cache/ComplexObject.spec.js b/modules/platforms/nodejs/spec/cache/ComplexObject.spec.js new file mode 100644 index 0000000..2119ab5 --- /dev/null +++ b/modules/platforms/nodejs/spec/cache/ComplexObject.spec.js @@ -0,0 +1,464 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require('jasmine-expect'); + +const Util = require('util'); +const TestingHelper = require('../TestingHelper'); +const IgniteClient = require('apache-ignite-client'); +const ObjectType = IgniteClient.ObjectType; +const MapObjectType = IgniteClient.MapObjectType; +const ComplexObjectType = IgniteClient.ComplexObjectType; +const BinaryObject = IgniteClient.BinaryObject; + +const CACHE_NAME = '__test_cache'; + +class Class1 { + constructor() { + this.field_1_1 = null; + this.field_1_2 = new Class2(); + this.field_1_3 = null; + } +} + +class SubClass1 extends Class1 { + constructor() { + super(); + this.field_1_4 = null; + this.field_1_5 = new Class3(); + this.field_1_6 = null; + this.field_1_7 = null; + this.field_1_8 = null; + } +} + +class Class2 { + constructor() { + this.field_2_1 = null; + this.field_2_2 = null; + } +} + +class Class3 { + constructor() { + this.field_3_1 = null; + this.field_3_2 = null; + } +} + +describe('complex object test suite >', () => { + let igniteClient = null; + + beforeAll((done) => { + Promise.resolve(). + then(async () => { + await TestingHelper.init(); + igniteClient = TestingHelper.igniteClient; + await testSuiteCleanup(done); + await igniteClient.getOrCreateCache(CACHE_NAME); + }). + then(done). + catch(error => done.fail(error)); + }, TestingHelper.TIMEOUT); + + afterAll((done) => { + Promise.resolve(). + then(async () => { + await testSuiteCleanup(done); + await TestingHelper.cleanUp(); + }). + then(done). + catch(error => done.fail(error)); + }, TestingHelper.TIMEOUT); + + it('put get complex objects', (done) => { + Promise.resolve(). + then(async () => { + const value1 = new Class1(); + value1.field_1_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.BYTE); + value1.field_1_2.field_2_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.SHORT); + value1.field_1_2.field_2_2 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.INTEGER); + value1.field_1_3 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.LONG); + + const valueType1 = new ComplexObjectType(new Class1()). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.BYTE). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2ShortInteger'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.SHORT). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.INTEGER)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.LONG); + + const value2 = new SubClass1(); + value2.field_1_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.FLOAT); + value2.field_1_2.field_2_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.DOUBLE); + value2.field_1_2.field_2_2 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.CHAR); + value2.field_1_3 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.BOOLEAN); + value2.field_1_4 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.STRING); + value2.field_1_5.field_3_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.DATE); + value2.field_1_5.field_3_2 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.UUID); + value2.field_1_6 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.DECIMAL); + value2.field_1_7 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.TIMESTAMP); + value2.field_1_8 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.TIME); + + const valueType2 = new ComplexObjectType(new SubClass1()). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.FLOAT). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2DoubleChar'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.DOUBLE). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.CHAR)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.BOOLEAN). + setFieldType('field_1_4', ObjectType.PRIMITIVE_TYPE.STRING). + setFieldType('field_1_5', new ComplexObjectType(new Class3()). + setFieldType('field_3_1', ObjectType.PRIMITIVE_TYPE.DATE). + setFieldType('field_3_2', ObjectType.PRIMITIVE_TYPE.UUID)). + setFieldType('field_1_6', ObjectType.PRIMITIVE_TYPE.DECIMAL). + setFieldType('field_1_7', ObjectType.PRIMITIVE_TYPE.TIMESTAMP). + setFieldType('field_1_8', ObjectType.PRIMITIVE_TYPE.TIME); + + await putGetComplexObjectsWithDifferentTypes( + value1, value2, valueType1, valueType2, Class1, SubClass1); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('put get unnamed complex objects', (done) => { + Promise.resolve(). + then(async () => { + const value1 = {}; + value1.field_1_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.BYTE); + value1.field_1_2 = {}; + value1.field_1_2.field_2_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.SHORT); + value1.field_1_2.field_2_2 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.INTEGER); + value1.field_1_3 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.LONG); + + const valueType1 = new ComplexObjectType(value1, 'ObjectWithByteObjLong'). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.BYTE). + setFieldType('field_1_2', new ComplexObjectType(value1.field_1_2, 'ObjectWithShortInteger'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.SHORT). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.INTEGER)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.LONG); + + const value2 = {}; + value2.field_1_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.FLOAT); + value2.field_1_2 = {}; + value2.field_1_2.field_2_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.DOUBLE); + value2.field_1_2.field_2_2 = {}; + value2.field_1_2.field_2_2.field_3_1 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.CHAR); + value2.field_1_2.field_2_2.field_3_2 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.BOOLEAN); + value2.field_1_3 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.STRING); + value2.field_1_4 = getPrimitiveValue(ObjectType.PRIMITIVE_TYPE.DATE); + + const valueType2 = new ComplexObjectType(value2, 'ObjectWithFloatObjStringDate'). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.FLOAT). + setFieldType('field_1_2', new ComplexObjectType(value2.field_1_2, 'ObjectWithDoubleObj'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.DOUBLE). + setFieldType('field_2_2', new ComplexObjectType(value2.field_1_2.field_2_2, 'ObjectWithCharBoolean'). + setFieldType('field_3_1', ObjectType.PRIMITIVE_TYPE.CHAR). + setFieldType('field_3_2', ObjectType.PRIMITIVE_TYPE.BOOLEAN))). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.STRING). + setFieldType('field_1_4', ObjectType.PRIMITIVE_TYPE.DATE); + + await putGetComplexObjects(value1, value2, + valueType1, valueType2, value2); + + await putGetComplexObjects({}, {}, + new ComplexObjectType({}), new ComplexObjectType({}), {}); + + let binaryKey = await BinaryObject.fromObject(value1, valueType1); + let binaryValue = await BinaryObject.fromObject(value2, valueType2); + await putGetComplexObjects(binaryKey, binaryValue, + null, null, value2); + + binaryKey = await BinaryObject.fromObject({}); + binaryValue = await BinaryObject.fromObject({}); + await putGetComplexObjects(binaryKey, binaryValue, + null, null, {}); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('put get complex objects with arrays', (done) => { + Promise.resolve(). + then(async () => { + const value1 = new Class1(); + value1.field_1_1 = getArrayValues(ObjectType.PRIMITIVE_TYPE.BYTE_ARRAY); + value1.field_1_2.field_2_1 = getArrayValues(ObjectType.PRIMITIVE_TYPE.SHORT_ARRAY); + value1.field_1_2.field_2_2 = getArrayValues(ObjectType.PRIMITIVE_TYPE.INTEGER_ARRAY); + value1.field_1_3 = getArrayValues(ObjectType.PRIMITIVE_TYPE.LONG_ARRAY); + + const valueType1 = new ComplexObjectType(new Class1(), 'Class1WithArrays'). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.BYTE_ARRAY). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2WithShortIntegerArrays'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.SHORT_ARRAY). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.INTEGER_ARRAY)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.LONG_ARRAY); + + const value2 = new SubClass1(); + value2.field_1_1 = getArrayValues(ObjectType.PRIMITIVE_TYPE.FLOAT_ARRAY); + value2.field_1_2.field_2_1 = getArrayValues(ObjectType.PRIMITIVE_TYPE.DOUBLE_ARRAY); + value2.field_1_2.field_2_2 = getArrayValues(ObjectType.PRIMITIVE_TYPE.CHAR_ARRAY); + value2.field_1_3 = getArrayValues(ObjectType.PRIMITIVE_TYPE.BOOLEAN_ARRAY); + value2.field_1_4 = getArrayValues(ObjectType.PRIMITIVE_TYPE.STRING_ARRAY); + value2.field_1_5.field_3_1 = getArrayValues(ObjectType.PRIMITIVE_TYPE.DATE_ARRAY); + value2.field_1_5.field_3_2 = getArrayValues(ObjectType.PRIMITIVE_TYPE.UUID_ARRAY); + value2.field_1_6 = getArrayValues(ObjectType.PRIMITIVE_TYPE.DECIMAL_ARRAY); + value2.field_1_7 = getArrayValues(ObjectType.PRIMITIVE_TYPE.TIMESTAMP_ARRAY); + value2.field_1_8 = getArrayValues(ObjectType.PRIMITIVE_TYPE.TIME_ARRAY); + + const valueType2 = new ComplexObjectType(new SubClass1(), 'SubClass1WithArrays'). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.FLOAT_ARRAY). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2WithDoubleCharArrays'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.DOUBLE_ARRAY). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.CHAR_ARRAY)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.BOOLEAN_ARRAY). + setFieldType('field_1_4', ObjectType.PRIMITIVE_TYPE.STRING_ARRAY). + setFieldType('field_1_5', new ComplexObjectType(new Class3(), 'Class3WithArrays'). + setFieldType('field_3_1', ObjectType.PRIMITIVE_TYPE.DATE_ARRAY). + setFieldType('field_3_2', ObjectType.PRIMITIVE_TYPE.UUID_ARRAY)). + setFieldType('field_1_6', ObjectType.PRIMITIVE_TYPE.DECIMAL_ARRAY). + setFieldType('field_1_7', ObjectType.PRIMITIVE_TYPE.TIMESTAMP_ARRAY). + setFieldType('field_1_8', ObjectType.PRIMITIVE_TYPE.TIME_ARRAY); + + await putGetComplexObjectsWithDifferentTypes( + value1, value2, valueType1, valueType2, Class1, SubClass1, true); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('put get complex objects with maps', (done) => { + Promise.resolve(). + then(async () => { + const value1 = new Class1(); + value1.field_1_1 = getMapValue(ObjectType.PRIMITIVE_TYPE.BYTE); + value1.field_1_2.field_2_1 = getMapValue(ObjectType.PRIMITIVE_TYPE.SHORT); + value1.field_1_2.field_2_2 = getMapValue(ObjectType.PRIMITIVE_TYPE.INTEGER); + value1.field_1_3 = getMapValue(ObjectType.PRIMITIVE_TYPE.LONG); + + const valueType1 = new ComplexObjectType(new Class1(), 'Class1WithMaps'). + setFieldType('field_1_1', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.BYTE, ObjectType.PRIMITIVE_TYPE.BYTE)). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2WithShortIntegerMaps'). + setFieldType('field_2_1', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.SHORT, ObjectType.PRIMITIVE_TYPE.SHORT)). + setFieldType('field_2_2', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.INTEGER, ObjectType.PRIMITIVE_TYPE.INTEGER))). + setFieldType('field_1_3', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.LONG, ObjectType.PRIMITIVE_TYPE.LONG)); + + const value2 = new SubClass1(); + value2.field_1_1 = getMapValue(ObjectType.PRIMITIVE_TYPE.FLOAT); + value2.field_1_2.field_2_1 = getMapValue(ObjectType.PRIMITIVE_TYPE.DOUBLE); + value2.field_1_2.field_2_2 = getMapValue(ObjectType.PRIMITIVE_TYPE.CHAR); + value2.field_1_3 = getMapValue(ObjectType.PRIMITIVE_TYPE.BOOLEAN); + value2.field_1_4 = getMapValue(ObjectType.PRIMITIVE_TYPE.STRING); + value2.field_1_5.field_3_1 = getMapValue(ObjectType.PRIMITIVE_TYPE.DATE); + value2.field_1_5.field_3_2 = getMapValue(ObjectType.PRIMITIVE_TYPE.UUID); + value2.field_1_6 = getMapValue(ObjectType.PRIMITIVE_TYPE.DECIMAL); + value2.field_1_7 = getMapValue(ObjectType.PRIMITIVE_TYPE.TIMESTAMP); + value2.field_1_8 = getMapValue(ObjectType.PRIMITIVE_TYPE.TIME); + + const valueType2 = new ComplexObjectType(new SubClass1(), 'SubClass1WithMaps'). + setFieldType('field_1_1', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.FLOAT)). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2WithDoubleCharMaps'). + setFieldType('field_2_1', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.DOUBLE)). + setFieldType('field_2_2', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.CHAR, ObjectType.PRIMITIVE_TYPE.CHAR))). + setFieldType('field_1_3', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.BOOLEAN, ObjectType.PRIMITIVE_TYPE.BOOLEAN)). + setFieldType('field_1_4', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.STRING)). + setFieldType('field_1_5', new ComplexObjectType(new Class3(), 'Class3WithMaps'). + setFieldType('field_3_1', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.DATE)). + setFieldType('field_3_2', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.UUID))). + setFieldType('field_1_6', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.DECIMAL)). + setFieldType('field_1_7', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.TIMESTAMP)). + setFieldType('field_1_8', new MapObjectType( + MapObjectType.MAP_SUBTYPE.HASH_MAP, ObjectType.PRIMITIVE_TYPE.STRING, ObjectType.PRIMITIVE_TYPE.TIME)); + + await putGetComplexObjectsWithDifferentTypes( + value1, value2, valueType1, valueType2, Class1, SubClass1, true); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('put get binary objects from objects', (done) => { + Promise.resolve(). + then(async () => { + const valueType = new ComplexObjectType(new Class1(), 'Class1WithStringObjStringArray'). + setFieldType('field_1_1', ObjectType.PRIMITIVE_TYPE.STRING). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2WithShortBoolean'). + setFieldType('field_2_1', ObjectType.PRIMITIVE_TYPE.SHORT). + setFieldType('field_2_2', ObjectType.PRIMITIVE_TYPE.BOOLEAN)). + setFieldType('field_1_3', ObjectType.PRIMITIVE_TYPE.STRING_ARRAY); + await putGetBinaryObjects(valueType); + const defaultValueType = new ComplexObjectType(new Class1(), 'Class1Default'). + setFieldType('field_1_2', new ComplexObjectType(new Class2(), 'Class2Default')); + await putGetBinaryObjects(defaultValueType); + }). + then(done). + catch(error => done.fail(error)); + }); + + async function testSuiteCleanup(done) { + await TestingHelper.destroyCache(CACHE_NAME, done); + } + + async function putGetComplexObjects(key, value, keyType, valueType, valuePattern) { + const cache = igniteClient.getCache(CACHE_NAME).setKeyType(keyType).setValueType(valueType); + try { + await cache.put(key, value); + const result = await cache.get(key); + expect(await TestingHelper.compare(valuePattern, result)).toBe(true, + `values are not equal: put value=${TestingHelper.printValue(valuePattern)}, get value=${TestingHelper.printValue(result)}`); + } + finally { + await cache.removeAll(); + } + } + + async function binaryObjectEquals(binaryObj, valuePattern, valueType) { + expect(await TestingHelper.compare(valuePattern, binaryObj)).toBe(true, + `binary values are not equal: put value=${TestingHelper.printValue(valuePattern)}, get value=${TestingHelper.printValue(binaryObj)}`); + + let value1, value2; + for (let key of Object.keys(valuePattern)) { + value1 = valuePattern[key]; + value2 = await binaryObj.getField(key, valueType ? valueType._getFieldType(key) : null); + expect(await TestingHelper.compare(value1, value2)).toBe(true, + `values for key ${key} are not equal: put value=${TestingHelper.printValue(value1) + }, get value=${TestingHelper.printValue(value2)}`); + } + + if (valueType) { + const toObject = await binaryObj.toObject(valueType); + expect(await TestingHelper.compare(valuePattern, toObject)).toBe(true, + `values are not equal: put value=${TestingHelper.printValue(valuePattern)}, get value=${TestingHelper.printValue(toObject)}`); + } + } + + async function putGetComplexObjectsWithDifferentTypes( + key, value, keyType, valueType, keyClass, valueClass, isNullable = false) { + await putGetComplexObjects(key, value, keyType, valueType, value); + + if (isNullable) { + await putGetComplexObjects(new keyClass(), new valueClass(), keyType, valueType, new valueClass()); + } + + let binaryKey = await BinaryObject.fromObject(key, keyType); + let binaryValue = await BinaryObject.fromObject(value, valueType); + await putGetComplexObjects(binaryKey, binaryValue, null, null, value); + + if (isNullable) { + binaryKey = await BinaryObject.fromObject(new keyClass(), keyType); + binaryValue = await BinaryObject.fromObject(new valueClass(), valueType); + await putGetComplexObjects(binaryKey, binaryValue, null, null, new valueClass()); + } + } + + async function putGetBinaryObjects(valueType) { + const value1 = new Class1(); + value1.field_1_1 = 'abc'; + value1.field_1_2.field_2_1 = 1234; + value1.field_1_2.field_2_2 = true; + value1.field_1_3 = ['a', 'bb', 'ccc']; + + const value2 = new Class1(); + value2.field_1_1 = 'def'; + value2.field_1_2.field_2_1 = 5432; + value2.field_1_2.field_2_2 = false; + value2.field_1_3 = ['a', 'bb', 'ccc', 'dddd']; + + const value3 = new Class1(); + value3.field_1_1 = 'defdef'; + value3.field_1_2.field_2_1 = 543; + value3.field_1_2.field_2_2 = false; + value3.field_1_3 = ['a', 'bb', 'ccc', 'dddd', 'eeeee']; + + const field_1_2_Type = valueType ? valueType._getFieldType('field_1_2') : null; + + const binaryValue1 = await BinaryObject.fromObject(value1, valueType); + const binaryValue2 = await BinaryObject.fromObject(value2, valueType); + const binaryValue3 = await BinaryObject.fromObject(value3, valueType); + + const cache = igniteClient.getCache(CACHE_NAME); + try { + await cache.put(binaryValue1, binaryValue2); + let result = await cache.get(binaryValue1); + await binaryObjectEquals(result, value2, valueType); + + binaryValue1.setField('field_1_1', 'abcde'); + result = await cache.get(binaryValue1); + expect(result === null).toBe(true); + + binaryValue2.setField('field_1_1', value3.field_1_1); + binaryValue2.setField('field_1_2', value3.field_1_2, field_1_2_Type); + binaryValue2.setField('field_1_3', value3.field_1_3); + await cache.put(binaryValue1, binaryValue2); + result = await cache.get(binaryValue1); + await binaryObjectEquals(result, value3, valueType); + + binaryValue1.setField('field_1_1', 'abc'); + binaryValue1.setField('field_1_3', await binaryValue1.getField('field_1_3')); + result = await cache.get(binaryValue1); + await binaryObjectEquals(result, value2, valueType); + + result = await cache.get(binaryValue1); + await binaryObjectEquals(result, value2, valueType); + + binaryValue3.setField('field_1_1', await result.getField('field_1_1')); + binaryValue3.setField('field_1_2', await result.getField('field_1_2', field_1_2_Type), field_1_2_Type); + binaryValue3.setField('field_1_3', await result.getField('field_1_3')); + await cache.put(binaryValue1, binaryValue3); + result = await cache.get(binaryValue1); + await binaryObjectEquals(result, value2, valueType); + } + finally { + await cache.removeAll(); + } + } + + function getPrimitiveValue(typeCode) { + return TestingHelper.primitiveValues[typeCode].values[0]; + } + + function getArrayValues(typeCode) { + return TestingHelper.primitiveValues[TestingHelper.arrayValues[typeCode].elemType].values; + } + + function getMapValue(typeCode) { + const map = new Map(); + const values = TestingHelper.primitiveValues[typeCode].values; + const length = values.length; + values.forEach((value, index) => { + if (!TestingHelper.primitiveValues[typeCode].isMapKey) { + value = Util.format("%s", value); + } + map.set(value, values[length - index - 1]); + }); + return map; + } +});
http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/config.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/config.js b/modules/platforms/nodejs/spec/config.js new file mode 100644 index 0000000..4e89875 --- /dev/null +++ b/modules/platforms/nodejs/spec/config.js @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +exports.endpoints = process.env.APACHE_IGNITE_CLIENT_ENDPOINTS ? + process.env.APACHE_IGNITE_CLIENT_ENDPOINTS.split(',') : []; +exports.debug = process.env.APACHE_IGNITE_CLIENT_DEBUG === 'true' || + process.env.APACHE_IGNITE_CLIENT_DEBUG === '1'; + + +//exports.endpoints = ['127.0.0.1:10800']; +//exports.debug = false; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/examples/AuthExample.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/examples/AuthExample.spec.js b/modules/platforms/nodejs/spec/examples/AuthExample.spec.js new file mode 100644 index 0000000..3fb9205 --- /dev/null +++ b/modules/platforms/nodejs/spec/examples/AuthExample.spec.js @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const TestingHelper = require('../TestingHelper'); + +describe('execute auth example >', () => { + it('AuthTlsExample', (done) => { + TestingHelper.executeExample('examples/AuthTlsExample.js'). + then(done). + catch(error => done.fail(error)); + }); +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/examples/Examples.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/examples/Examples.spec.js b/modules/platforms/nodejs/spec/examples/Examples.spec.js new file mode 100644 index 0000000..c8dce3c --- /dev/null +++ b/modules/platforms/nodejs/spec/examples/Examples.spec.js @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const TestingHelper = require('../TestingHelper'); + +describe('execute examples >', () => { + it('CachePutGetExample', (done) => { + TestingHelper.executeExample('examples/CachePutGetExample.js'). + then(done). + catch(error => done.fail(error)); + }); + + it('SqlExample', (done) => { + TestingHelper.executeExample('examples/SqlExample.js'). + then(done). + catch(error => done.fail(error)); + }); + + it('SqlQueryEntriesExample', (done) => { + TestingHelper.executeExample('examples/SqlQueryEntriesExample.js'). + then(done). + catch(error => done.fail(error)); + }); +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/query/ScanQuery.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/query/ScanQuery.spec.js b/modules/platforms/nodejs/spec/query/ScanQuery.spec.js new file mode 100644 index 0000000..ab28973 --- /dev/null +++ b/modules/platforms/nodejs/spec/query/ScanQuery.spec.js @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require('jasmine-expect'); + +const config = require('../config'); +const TestingHelper = require('../TestingHelper'); +const IgniteClient = require('apache-ignite-client'); +const Errors = IgniteClient.Errors; +const ScanQuery = IgniteClient.ScanQuery; +const ObjectType = IgniteClient.ObjectType; + +const CACHE_NAME = '__test_cache'; +const ELEMENTS_NUMBER = 10; + +describe('scan query test suite >', () => { + let igniteClient = null; + + beforeAll((done) => { + Promise.resolve(). + then(async () => { + await TestingHelper.init(); + igniteClient = TestingHelper.igniteClient; + await testSuiteCleanup(done); + await igniteClient.getOrCreateCache(CACHE_NAME); + await generateData(done); + }). + then(done). + catch(error => done.fail(error)); + }, TestingHelper.TIMEOUT); + + afterAll((done) => { + Promise.resolve(). + then(async () => { + await testSuiteCleanup(done); + await TestingHelper.cleanUp(); + }). + then(done). + catch(error => done()); + }, TestingHelper.TIMEOUT); + + it('get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery()); + const set = new Set(); + for (let cacheEntry of await cursor.getAll()) { + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue()).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get all with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery().setPageSize(1)); + const set = new Set(); + for (let cacheEntry of await cursor.getAll()) { + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue()).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery()); + const set = new Set(); + do { + let cacheEntry = await cursor.getValue(); + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue()).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery().setPageSize(2)); + const set = new Set(); + do { + let cacheEntry = await cursor.getValue(); + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue()).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery().setPageSize(1)); + await cursor.getValue(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor after get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery()); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('scan query settings', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new ScanQuery(). + setPartitionNumber(0). + setPageSize(2). + setLocal(true)); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + + it('scan empty cache', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + await cache.removeAll(); + let cursor = await cache.query(new ScanQuery()); + const cacheEntries = await cursor.getAll(); + expect(cacheEntries.length).toBe(0); + await cursor.close(); + + cursor = await cache.query(new ScanQuery()); + expect(await cursor.getValue()).toBe(null); + expect(cursor.hasMore()).toBe(false); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + async function testSuiteCleanup(done) { + await TestingHelper.destroyCache(CACHE_NAME, done); + } + + async function generateData(done) { + try { + let cache = igniteClient.getCache(CACHE_NAME). + setKeyType(ObjectType.PRIMITIVE_TYPE.INTEGER); + for (let i = 0; i < ELEMENTS_NUMBER; i++) { + await cache.put(i, generateValue(i)); + } + } + catch (err) { + done.fail('unexpected error: ' + err); + } + } + + function generateValue(key) { + return 'value' + key; + } +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/query/SqlFieldsQuery.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/query/SqlFieldsQuery.spec.js b/modules/platforms/nodejs/spec/query/SqlFieldsQuery.spec.js new file mode 100644 index 0000000..c81838a --- /dev/null +++ b/modules/platforms/nodejs/spec/query/SqlFieldsQuery.spec.js @@ -0,0 +1,247 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require('jasmine-expect'); + +const config = require('../config'); +const TestingHelper = require('../TestingHelper'); +const IgniteClient = require('apache-ignite-client'); +const Errors = IgniteClient.Errors; +const SqlFieldsQuery = IgniteClient.SqlFieldsQuery; +const ObjectType = IgniteClient.ObjectType; +const CacheConfiguration = IgniteClient.CacheConfiguration; + +const CACHE_NAME = '__test_cache'; +const TABLE_NAME = '__test_SqlFieldsQuery_table'; +const ELEMENTS_NUMBER = 10; + +describe('sql fields query test suite >', () => { + let igniteClient = null; + + beforeAll((done) => { + Promise.resolve(). + then(async () => { + await TestingHelper.init(); + igniteClient = TestingHelper.igniteClient; + await testSuiteCleanup(done); + await igniteClient.getOrCreateCache(CACHE_NAME, new CacheConfiguration().setSqlSchema('PUBLIC')); + await generateData(done); + }). + then(done). + catch(error => done.fail(error)); + }, TestingHelper.TIMEOUT); + + afterAll((done) => { + Promise.resolve(). + then(async () => { + await dropTables(done); + await testSuiteCleanup(done); + await TestingHelper.cleanUp(); + }). + then(done). + catch(error => done()); + }, TestingHelper.TIMEOUT); + + it('get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query( + new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`)); + const set = new Set(); + for (let fields of await cursor.getAll()) { + expect(fields.length).toBe(2); + expect(generateValue(fields[0]) === fields[1]).toBe(true); + set.add(fields[0]); + expect(fields[0] >= 0 && fields[0] < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get all with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query( + new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + const set = new Set(); + for (let fields of await cursor.getAll()) { + expect(fields.length).toBe(2); + expect(generateValue(fields[0]) === fields[1]).toBe(true); + set.add(fields[0]); + expect(fields[0] >= 0 && fields[0] < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query( + new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`)); + const set = new Set(); + do { + let fields = await cursor.getValue(); + expect(fields.length).toBe(2); + expect(generateValue(fields[0]) === fields[1]).toBe(true); + set.add(fields[0]); + expect(fields[0] >= 0 && fields[0] < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query( + new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`).setPageSize(2)); + const set = new Set(); + do { + let fields = await cursor.getValue(); + expect(fields.length).toBe(2); + expect(generateValue(fields[0]) === fields[1]).toBe(true); + set.add(fields[0]); + expect(fields[0] >= 0 && fields[0] < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query( + new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + await cursor.getValue(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor after get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`)); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('sql fields query settings', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + const cursor = await cache.query(new SqlFieldsQuery(`SELECT * FROM ${TABLE_NAME}`). + setPageSize(2). + setLocal(false). + setSql(`INSERT INTO ${TABLE_NAME} (field1, field2) VALUES (?, ?)`). + setArgTypes(ObjectType.PRIMITIVE_TYPE.INTEGER, ObjectType.PRIMITIVE_TYPE.STRING). + setArgs(50, 'test'). + setDistributedJoins(true). + setReplicatedOnly(false). + setTimeout(10000). + setSchema('PUBLIC'). + setMaxRows(20). + setStatementType(SqlFieldsQuery.STATEMENT_TYPE.ANY). + setEnforceJoinOrder(true). + setCollocated(false). + setLazy(true). + setIncludeFieldNames(true)); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get empty results', (done) => { + Promise.resolve(). + then(async () => { + let cache = igniteClient.getCache(CACHE_NAME); + await cache.removeAll(); + let cursor = await cache.query( + new SqlFieldsQuery(`SELECT field1 FROM ${TABLE_NAME} WHERE field1 > 100`)); + const cacheEntries = await cursor.getAll(); + expect(cacheEntries.length).toBe(0); + await cursor.close(); + + cursor = await cache.query( + new SqlFieldsQuery(`SELECT field1 FROM ${TABLE_NAME} WHERE field1 > 100`)); + expect(await cursor.getValue()).toBe(null); + expect(cursor.hasMore()).toBe(false); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + async function dropTables(done) { + try { + let cache = igniteClient.getCache(CACHE_NAME); + (await cache.query(new SqlFieldsQuery(`DROP TABLE ${TABLE_NAME}`))).getAll(); + } + catch (err) { + done.fail('unexpected error: ' + err); + } + } + + async function testSuiteCleanup(done) { + await TestingHelper.destroyCache(CACHE_NAME, done); + } + + async function generateData(done) { + try { + let cache = igniteClient.getCache(CACHE_NAME); + (await cache.query(new SqlFieldsQuery( + `CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (field1 INT, field2 VARCHAR, PRIMARY KEY (field1))`))).getAll(); + + const insertQuery = new SqlFieldsQuery(`INSERT INTO ${TABLE_NAME} (field1, field2) VALUES (?, ?)`). + setArgTypes(ObjectType.PRIMITIVE_TYPE.INTEGER); + + for (let i = 0; i < ELEMENTS_NUMBER; i++) { + (await cache.query(insertQuery.setArgs(i, generateValue(i)))).getAll(); + } + } + catch (err) { + done.fail('unexpected error: ' + err); + } + } + + function generateValue(key) { + return 'value' + key; + } +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/query/SqlQuery.spec.js ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/query/SqlQuery.spec.js b/modules/platforms/nodejs/spec/query/SqlQuery.spec.js new file mode 100644 index 0000000..2bbd0e5 --- /dev/null +++ b/modules/platforms/nodejs/spec/query/SqlQuery.spec.js @@ -0,0 +1,247 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require('jasmine-expect'); + +const config = require('../config'); +const TestingHelper = require('../TestingHelper'); +const IgniteClient = require('apache-ignite-client'); +const Errors = IgniteClient.Errors; +const SqlQuery = IgniteClient.SqlQuery; +const SqlFieldsQuery = IgniteClient.SqlFieldsQuery; +const ObjectType = IgniteClient.ObjectType; +const CacheConfiguration = IgniteClient.CacheConfiguration; +const QueryEntity = IgniteClient.QueryEntity; +const QueryField = IgniteClient.QueryField; +const ComplexObjectType = IgniteClient.ComplexObjectType; + +const CACHE_NAME = '__test_cache'; +const TABLE_NAME = '__test_SqlQuery'; +const ELEMENTS_NUMBER = 10; + +describe('sql query test suite >', () => { + let igniteClient = null; + + beforeAll((done) => { + Promise.resolve(). + then(async () => { + await TestingHelper.init(); + igniteClient = TestingHelper.igniteClient; + await testSuiteCleanup(done); + await igniteClient.getOrCreateCache( + CACHE_NAME, + new CacheConfiguration(). + setQueryEntities( + new QueryEntity(). + setKeyTypeName('java.lang.Integer'). + setValueTypeName(TABLE_NAME). + setFields([ + new QueryField('field1', 'java.lang.Integer'), + new QueryField('field2', 'java.lang.String') + ]))); + await generateData(done); + }). + then(done). + catch(error => done.fail(error)); + }, TestingHelper.TIMEOUT); + + afterAll((done) => { + Promise.resolve(). + then(async () => { + await testSuiteCleanup(done); + await TestingHelper.cleanUp(); + }). + then(done). + catch(error => done()); + }, TestingHelper.TIMEOUT); + + it('get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`)); + const set = new Set(); + for (let cacheEntry of await cursor.getAll()) { + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue().field2).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get all with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + const set = new Set(); + for (let cacheEntry of await cursor.getAll()) { + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue().field2).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`)); + const set = new Set(); + do { + let cacheEntry = await cursor.getValue(); + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue().field2).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get value with page size', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`).setPageSize(2)); + const set = new Set(); + do { + let cacheEntry = await cursor.getValue(); + expect(generateValue(cacheEntry.getKey()) === cacheEntry.getValue().field2).toBe(true); + set.add(cacheEntry.getKey()); + expect(cacheEntry.getKey() >= 0 && cacheEntry.getKey() < ELEMENTS_NUMBER).toBe(true); + } while (cursor.hasMore()); + expect(set.size).toBe(ELEMENTS_NUMBER); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + await cursor.getValue(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('close cursor after get all', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query( + new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`)); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('sql query settings', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + const cursor = await cache.query(new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`). + setType(TABLE_NAME). + setPageSize(2). + setLocal(false). + setSql('field1 > ? and field1 <= ?'). + setArgTypes(ObjectType.PRIMITIVE_TYPE.INTEGER, ObjectType.PRIMITIVE_TYPE.INTEGER). + setArgs(3, 7). + setDistributedJoins(true). + setReplicatedOnly(false). + setTimeout(10000)); + await cursor.getAll(); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + it('get values from empty cache', (done) => { + Promise.resolve(). + then(async () => { + let cache = getCache(); + await cache.removeAll(); + let cursor = await cache.query(new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + const cacheEntries = await cursor.getAll(); + expect(cacheEntries.length).toBe(0); + await cursor.close(); + + cursor = await cache.query(new SqlQuery(TABLE_NAME, `SELECT * FROM ${TABLE_NAME}`).setPageSize(1)); + expect(await cursor.getValue()).toBe(null); + expect(cursor.hasMore()).toBe(false); + await cursor.close(); + }). + then(done). + catch(error => done.fail(error)); + }); + + async function testSuiteCleanup(done) { + await TestingHelper.destroyCache(CACHE_NAME, done); + } + + function getCache() { + return igniteClient.getCache(CACHE_NAME). + setKeyType(ObjectType.PRIMITIVE_TYPE.INTEGER). + setValueType(new ComplexObjectType({ + 'field1' : 1, + 'field2' : 'a' + }, TABLE_NAME). + setFieldType('field1', ObjectType.PRIMITIVE_TYPE.INTEGER)); + } + + async function generateData(done) { + try { + let cache = igniteClient.getCache(CACHE_NAME); + + const insertQuery = new SqlFieldsQuery(`INSERT INTO ${TABLE_NAME} (_key, field1, field2) VALUES (?, ?, ?)`). + setArgTypes(ObjectType.PRIMITIVE_TYPE.INTEGER, ObjectType.PRIMITIVE_TYPE.INTEGER); + + for (let i = 0; i < ELEMENTS_NUMBER; i++) { + (await cache.query(insertQuery.setArgs(i, i, generateValue(i)))).getAll(); + } + } + catch (err) { + done.fail('unexpected error: ' + err); + } + } + + function generateValue(key) { + return 'value' + key; + } +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/c56d16fb/modules/platforms/nodejs/spec/support/jasmine.json ---------------------------------------------------------------------- diff --git a/modules/platforms/nodejs/spec/support/jasmine.json b/modules/platforms/nodejs/spec/support/jasmine.json new file mode 100644 index 0000000..8ba68ba --- /dev/null +++ b/modules/platforms/nodejs/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "cache/**/*[sS]pec.js", + "query/**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "random": false +}