UNPKG

aerospike

Version:
219 lines (182 loc) 7.32 kB
'use strict' /* eslint-env mocha */ /* global expect */ /* eslint-disable no-unused-expressions */ import { setTimeout as sleep } from 'timers/promises'; import {Query} from '../lib/aerospike.js'; import type { Scan, Client, Key, ScanOptions, QueryOptions, AerospikeRecord, AerospikeBins} from '../lib/aerospike.js'; import {AerospikeError} from '../lib/aerospike.js'; import {expect} from 'chai'; import * as chai from 'chai'; import * as helper from './test_helper.ts'; import * as Aerospike from '../lib/aerospike.js'; import * as keygen from './generators/key.ts' import * as recgen from './generators/record.ts' import chaiAsPromised from 'chai-as-promised'; chai.use(chaiAsPromised); // Bin projection is in its own test file because in test/query.ts, some records will return null // if bin projection tries to read a nested element in a bin that doesn't exist // in those records. // Also because we need to test both query and scan, and query.ts is only focused towards // queries. describe('bin projection', function () { helper.skipUnlessVersion('>= 8.1.2', this) const client: Client = helper.client const gen_key = keygen.string(helper.namespace, helper.set) const key: Key = gen_key() const bins: AerospikeBins = {'a': 1, 'nested': {'value': 10}}; before(function () { client.truncate(helper.namespace, helper.set, 0) client.put(key, bins) }) after(function () { client.remove(key) }) describe('bin projection can read root-level elements', function () { const args: QueryOptions = { ops: [Aerospike.operations.read('a')] } it('works with query.foreach()', function (){ const query: Query = client.query(helper.namespace, helper.set, args) const stream = query.foreach() stream.on('data', (record: AerospikeRecord) => { expect(record.bins).to.have.property('a', 1) }) }) it('works with query.results()', async function (){ const query: Query = client.query(helper.namespace, helper.set, args) let results = await query.results() for (const record of results) { expect(record.bins).to.have.property('a', 1) } }) const scan_args: ScanOptions = { ops: [Aerospike.operations.read('a')] } it('works with scan.foreach()', function (){ // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() const scan: Scan = client.scan(helper.namespace, helper.set, scan_args) const stream = scan.foreach() stream.on('data', (record: AerospikeRecord) => { expect(record.bins).to.have.property('a', 1) }) }) it('works with scan.results()', async function (){ // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() // const scan: Scan = client.scan(helper.namespace, helper.set, scan_args) // let results = await scan.results() // for (const record of results) { // expect(record.bins).to.have.property('a', 1) // } }) }) describe('bin projection can read nested-level elements', function () { const args: QueryOptions = { ops: [Aerospike.maps.getByKey('nested', 'value', Aerospike.maps.returnType.VALUE)] } it('works with query.foreach()', function (){ const query: Query = client.query(helper.namespace, helper.set, args) const stream = query.foreach() stream.on('data', (record: AerospikeRecord) => { expect(record.bins).to.have.property('nested', 10) }) }) it('works with query.results()', async function (){ const query: Query = client.query(helper.namespace, helper.set, args) let results = await query.results() for (const record of results) { expect(record.bins).to.have.property('nested', 10) } }) const scan_args: ScanOptions = { ops: [Aerospike.maps.getByKey('nested', 'value', Aerospike.maps.returnType.VALUE)] } it('works with scan.foreach()', function (){ // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() const scan: Scan = client.scan(helper.namespace, helper.set, scan_args) const stream = scan.foreach() stream.on('data', (record: AerospikeRecord) => { expect(record.bins).to.have.property('nested', 10) }) }) it('works.with scan.results()', async function (){ // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() // const scan: Scan = client.scan(helper.namespace, helper.set, scan_args) // let results = await scan.results() // for (const record of results) { // expect(record.bins).to.have.property('nested', 10) // } }) }) // Negative tests describe('selected bins and ops are mutually exclusive', function() { let warnings = []; const warningHandler = (warning: any) => { warnings.push(warning); }; beforeEach(() => { // Listen for warnings process.on('warning', warningHandler); }); afterEach(() => { process.removeListener('warning', warningHandler); warnings = []; }); it('raises a warning for queries', async function () { const args: QueryOptions = { ops: [Aerospike.operations.read('a')], select: ["nonexistent_bin"] } const query: Query = client.query(helper.namespace, helper.set, args) // Make sure the warning goes through await sleep(1000) expect(warnings.length).to.equal(1) // Bin named "a" should still be returned by ops // i.e it is not filtered out let results = await query.results() for (const record of results) { expect(record.bins).to.have.property('a', 1) } }) it('raises a warning for scans', async function () { // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() // const args: ScanOptions = { // ops: [Aerospike.operations.read('a')], // select: ["nonexistent_bin"] // } // const scan: Scan = client.scan(helper.namespace, helper.set, args) // // Make sure the warning goes through // await sleep(1000) // expect(warnings.length).to.equal(1) // // Bin named "a" should still be returned by ops // // i.e it is not filtered out // let results = await scan.results() // for (const record of results) { // expect(record.bins).to.have.property('a', 1) // } }) }) it('foreground query should reject write operations', async function (){ const args: QueryOptions = { ops: [Aerospike.operations.write('name', 'filter1')] } const query: Query = client.query(helper.namespace, helper.set, args) let promise = query.results() return expect(promise).to.be.rejectedWith(AerospikeError) }) it('foreground scan should reject write operations.', async function (){ // TODO this fails possibly because of a client bug. CLIENT-4648 this.skip() // const args: ScanOptions = { // ops: [Aerospike.operations.write('name', 'filter1')] // } // const scan: Scan = client.scan(helper.namespace, helper.set, args) // let promise = scan.results() // return promise.should.be.rejectedWith(AerospikeError) }) })