Skip to content

Commit

Permalink
feat: add scanBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
stipsan committed May 8, 2022
1 parent 142ccd8 commit ec09d77
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 100 deletions.
1 change: 0 additions & 1 deletion compat.md
Expand Up @@ -234,7 +234,6 @@
## Missing buffer commands

- [hscanBuffer][1]
- [scanBuffer][1]
- [sscanBuffer][1]
- [subscribeBuffer][1]
- [xaddBuffer][1]
Expand Down
1 change: 0 additions & 1 deletion jest.config.redis.js
Expand Up @@ -25,7 +25,6 @@ module.exports = {
'test/integration/commands/publish.js',
'test/integration/commands/rpop.js',
'test/integration/commands/rpoplpush.js',
'test/integration/commands/scan.js',
'test/integration/commands/scanStream.js',
'test/integration/commands/scard.js',
'test/integration/commands/sdiff.js',
Expand Down
6 changes: 6 additions & 0 deletions src/commands/scan.js
@@ -1,6 +1,12 @@
import { convertStringToBuffer } from '../commands-utils/convertStringToBuffer'
import { scanHelper } from '../commands-utils/scan-command.common'

export function scan(cursor, opt1, opt1val, opt2, opt2val) {
const allKeys = this.data.keys()
return scanHelper(allKeys, 1, cursor, opt1, opt1val, opt2, opt2val)
}

export function scanBuffer(...args) {
const val = scan.apply(this, args)
return convertStringToBuffer(val)
}
15 changes: 15 additions & 0 deletions test/integration/commands/__snapshots__/scan.js.snap
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`scan should return null array if nothing in db 1`] = `
Array [
"0",
Array [],
]
`;

exports[`scanBuffer should return null array if nothing in db 1`] = `
Array [
Buffer<30>,
Array [],
]
`;
198 changes: 100 additions & 98 deletions test/integration/commands/scan.js
@@ -1,116 +1,118 @@
import Redis from 'ioredis'
import { convertBufferToString } from 'ioredis/built/utils'
import sortBy from 'lodash.sortby'

describe('scan', () => {
it('should return null array if nothing in db', () => {
const redis = new Redis()
return redis.scan(0).then(result => {
expect(result[0]).toBe('0')
expect(result[1]).toEqual([])
})
})
// eslint-disable-next-line import/no-relative-parent-imports
import { browserSafeDescribe, runTwinSuite } from '../../../test-utils'

it('should return keys in db', () => {
const redis = new Redis({
data: {
foo: 'bar',
test: 'bar',
},
runTwinSuite('scan', command => {
browserSafeDescribe(command)(command, () => {
it('should return null array if nothing in db', async () => {
const redis = new Redis()
const result = await redis[command](0)
expect(result).toMatchSnapshot()
})

return redis.scan(0).then(result => {
expect(result[0]).toBe('0')
expect(result[1]).toEqual(['foo', 'test'])
})
})
it('should return fail if incorrect count', () => {
const redis = new Redis()
return redis.scan('asdf').catch(result => {
expect(result).toBeInstanceOf(Error)
it('should return keys in db', async () => {
const redis = new Redis()
await redis.set('foo', 'bar')
await redis.set('test', 'bar')

return redis[command](0).then(result => {
expect(convertBufferToString(result[0])).toBe('0')
expect(sortBy(convertBufferToString(result[1]))).toEqual([
'foo',
'test',
])
})
})
})
it('should return fail if incorrect command', () => {
const redis = new Redis()
return redis.scan(0, 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
it('should return fail if incorrect count', () => {
const redis = new Redis()
return redis[command]('asdf').catch(result => {
expect(result).toBeInstanceOf(Error)
})
})
})
it('should return fail if incorrect MATCH usage', () => {
const redis = new Redis()
return redis.scan(0, 'MATCH', 'sadf', 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
it('should return fail if incorrect command', () => {
const redis = new Redis()
return redis[command](0, 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
})
})
})
it('should return fail if incorrect COUNT usage', () => {
const redis = new Redis()
return redis.scan(0, 'COUNT', 10, 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
it('should return fail if incorrect MATCH usage', () => {
const redis = new Redis()
return redis[command](0, 'MATCH', 'sadf', 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
})
})
})
it('should return fail if incorrect COUNT usage 2', () => {
const redis = new Redis()
return redis.scan(0, 'COUNT', 'adsf').catch(result => {
expect(result).toBeInstanceOf(Error)
it('should return fail if incorrect COUNT usage', () => {
const redis = new Redis()
return redis[command](0, 'COUNT', 10, 'ZU').catch(result => {
expect(result).toBeInstanceOf(Error)
})
})
})
it('should return only mathced keys', () => {
const redis = new Redis({
data: {
foo0: 'x',
foo1: 'x',
foo2: 'x',
test0: 'x',
test1: 'x',
},
it('should return fail if incorrect COUNT usage 2', () => {
const redis = new Redis()
return redis[command](0, 'COUNT', 'adsf').catch(result => {
expect(result).toBeInstanceOf(Error)
})
})
it('should return only mathced keys', async () => {
const redis = new Redis()
await redis.set('foo0', 'x')
await redis.set('foo1', 'x')
await redis.set('foo2', 'x')
await redis.set('test0', 'x')
await redis.set('test1', 'x')

return redis.scan(0, 'MATCH', 'foo*').then(result => {
expect(result[0]).toBe('0')
expect(result[1]).toEqual(['foo0', 'foo1', 'foo2'])
})
})
it('should return only mathced keys and limit by COUNT', () => {
const redis = new Redis({
data: {
foo0: 'x',
foo1: 'x',
foo2: 'x',
test0: 'x',
test1: 'x',
},
return redis[command](0, 'MATCH', 'foo*').then(result => {
expect(convertBufferToString(result[0])).toBe('0')
expect(sortBy(convertBufferToString(result[1]))).toEqual([
'foo0',
'foo1',
'foo2',
])
})
})
it('should return only mathced keys and limit by COUNT', async () => {
const redis = new Redis()
await redis.set('foo0', 'x')
await redis.set('foo1', 'x')
await redis.set('foo2', 'x')
await redis.set('test0', 'x')
await redis.set('test1', 'x')

return redis
.scan(0, 'MATCH', 'foo*', 'COUNT', 1)
.then(result => {
expect(result[0]).toBe('1') // more elements left, this is why cursor is not 0
expect(result[1]).toEqual(['foo0'])
return redis.scan(result[0], 'MATCH', 'foo*', 'COUNT', 10)
})
.then(result2 => {
expect(result2[0]).toBe('0')
expect(result2[1]).toEqual(['foo1', 'foo2'])
})
})
it('should return number of keys set by COUNT and continue by cursor', () => {
const redis = new Redis({
data: {
foo0: 'x',
foo1: 'x',
test0: 'x',
test1: 'x',
},
return redis[command](0, 'MATCH', 'foo*', 'COUNT', 1)
.then(result => {
expect(convertBufferToString(result[0])).not.toBe('0') // more elements left, this is why cursor is not 0
expect(result[1]).toEqual(expect.any(Array))
return redis[command](result[0], 'MATCH', 'foo*', 'COUNT', 10)
})
.then(result2 => {
expect(convertBufferToString(result2[0])).toBe('0')
expect(result2[1]).toEqual(expect.any(Array))
})
})
it('should return number of keys set by COUNT and continue by cursor', async () => {
const redis = new Redis()
await redis.set('foo0', 'x')
await redis.set('foo1', 'x')
await redis.set('test0', 'x')
await redis.set('test1', 'x')

return redis
.scan(0, 'COUNT', 3)
.then(result => {
expect(result[0]).toBe('3')
expect(result[1]).toEqual(['foo0', 'foo1', 'test0'])
return redis.scan(result[0], 'COUNT', 3)
})
.then(result2 => {
expect(result2[0]).toBe('0')
expect(result2[1]).toEqual(['test1'])
})
return redis[command](0, 'COUNT', 3)
.then(result => {
expect(convertBufferToString(result[0])).toBe('3')
expect(sortBy(convertBufferToString(result[1]))).toEqual([
'foo0',
'foo1',
'test0',
])
return redis[command](result[0], 'COUNT', 3)
})
.then(result2 => {
expect(convertBufferToString(result2[0])).toBe('0')
expect(convertBufferToString(result2[1])).toEqual(['test1'])
})
})
})
})

0 comments on commit ec09d77

Please sign in to comment.