Skip to content

Commit

Permalink
feat: add spopBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
stipsan committed Jan 31, 2022
1 parent cd8e279 commit aa1db83
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 114 deletions.
1 change: 0 additions & 1 deletion compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@

- [hscanBuffer][1]
- [scanBuffer][1]
- [spopBuffer][1]
- [srandmemberBuffer][1]
- [sremBuffer][1]
- [sscanBuffer][1]
Expand Down
8 changes: 8 additions & 0 deletions src/commands/spop.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ export function spop(key, count) {
this.data.set(key, set)
return result
}

export function spopBuffer(...args) {
const val = spop.apply(this, args)
if (Array.isArray(val)) {
return val.map(Buffer.from)
}
return val ? Buffer.from(val) : val
}
243 changes: 130 additions & 113 deletions test/integration/commands/spop.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,135 @@
import Redis from 'ioredis'

describe('spop', () => {
it('should return a random item', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset').then(result => {
expect(result.constructor).toBe(String)
expect(['one', 'two', 'three']).toContain(result)
expect(redis.data.get('myset').size).toBe(2)
})
})

it('should not return an array when count == set.size == 1', () => {
const redis = new Redis({
data: {
myset: new Set(['one']),
},
})

return redis.spop('myset').then(result => {
expect(result.constructor).toBe(String)
expect(result).toBe('one')
expect(redis.data.get('myset').size).toBe(0)
})
})

it('should return random unique items', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset', 2).then(results => {
expect(['one', 'two', 'three']).toContain(results[0])
expect(['one', 'two', 'three']).toContain(results[1])
expect(redis.data.get('myset').size).toBe(1)
})
})

it('should return all items if positive count is bigger than set', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset', 5).then(results => {
expect(results).toEqual(['one', 'two', 'three'])
expect(redis.data.get('myset').size).toBe(0)
})
})

it('should return null if set is empty', () => {
const redis = new Redis()

return redis.spop('myset').then(result => {
return expect(result).toBe(null)
})
})

it('should return undefined if count is 0', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset', 0).then(result => {
return expect(result).toBe(undefined)
})
})

it('should throw an exception if the key contains something other than a set', () => {
const redis = new Redis({
data: {
foo: 'not a set',
},
})

return redis.spop('foo').catch(err => {
return expect(err.message).toBe('Key foo does not contain a set')
})
})

it('should throw an exception if count is not an integer', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset', 'not an integer').catch(err => {
return expect(err.message).toBe(
'ERR value is not an integer or out of range'
)
})
})

it('should throw an exception if count is out of range', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis.spop('myset', -10).catch(err => {
return expect(err.message).toBe(
'ERR value is not an integer or out of range'
)
// eslint-disable-next-line import/no-relative-parent-imports
import { runTwinSuite } from '../../../test-utils'

runTwinSuite('spop', command => {
describe(command, () => {
it('should return a random item', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset').then(_result => {
const result = Buffer.isBuffer(_result) ? _result.toString() : _result
expect(result.constructor).toBe(String)
expect(['one', 'two', 'three']).toContain(result)
expect(redis.data.get('myset').size).toBe(2)
})
})

it('should not return an array when count == set.size == 1', () => {
const redis = new Redis({
data: {
myset: new Set(['one']),
},
})

return redis[command]('myset').then(_result => {
const result = Buffer.isBuffer(_result) ? _result.toString() : _result
expect(result.constructor).toBe(String)
expect(result).toBe('one')
expect(redis.data.get('myset').size).toBe(0)
})
})

it('should return random unique items', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset', 2).then(_results => {
const results = Buffer.isBuffer(_results[0])
? _results.map(result => {
return result.toString()
})
: _results
expect(['one', 'two', 'three']).toContain(results[0])
expect(['one', 'two', 'three']).toContain(results[1])
expect(redis.data.get('myset').size).toBe(1)
})
})

it('should return all items if positive count is bigger than set', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset', 5).then(_results => {
const results = Buffer.isBuffer(_results[0])
? _results.map(result => {
return result.toString()
})
: _results
expect(results).toEqual(['one', 'two', 'three'])
expect(redis.data.get('myset').size).toBe(0)
})
})

it('should return null if set is empty', () => {
const redis = new Redis()

return redis[command]('myset').then(result => {
return expect(result).toBe(null)
})
})

it('should return undefined if count is 0', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset', 0).then(result => {
return expect(result).toBe(undefined)
})
})

it('should throw an exception if the key contains something other than a set', () => {
const redis = new Redis({
data: {
foo: 'not a set',
},
})

return redis[command]('foo').catch(err => {
return expect(err.message).toBe('Key foo does not contain a set')
})
})

it('should throw an exception if count is not an integer', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset', 'not an integer').catch(err => {
return expect(err.message).toBe(
'ERR value is not an integer or out of range'
)
})
})

it('should throw an exception if count is out of range', () => {
const redis = new Redis({
data: {
myset: new Set(['one', 'two', 'three']),
},
})

return redis[command]('myset', -10).catch(err => {
return expect(err.message).toBe(
'ERR value is not an integer or out of range'
)
})
})
})
})

0 comments on commit aa1db83

Please sign in to comment.