Skip to content

Commit

Permalink
fix)commands): add count argument to lpop and remove key when list is…
Browse files Browse the repository at this point in the history
… empty
  • Loading branch information
roertbb committed Oct 20, 2023
1 parent 6a58955 commit 57c8afb
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/commands/lpop.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
import { convertStringToBuffer } from '../commands-utils/convertStringToBuffer'

export function lpop(key) {
export function lpop(key, count) {
if (this.data.has(key) && !(this.data.get(key) instanceof Array)) {
throw new Error(`Key ${key} does not contain a list`)
}
const list = this.data.get(key) || []

const item = list.length > 0 ? list.shift() : null
if (list.length === 0) {
return null
}

if (count) {
const items = list.slice(0, count)
const remainingItems = list.slice(count)

this.data.set(key, list)
if (remainingItems.length > 0) {
this.data.set(key, remainingItems)
} else {
this.data.delete(key)
}

return items
}

const item = list.shift()

if (list.length > 0) {
this.data.set(key, list)
} else {
this.data.delete(key)
}

return item
}

export function lpopBuffer(key) {
const val = lpop.apply(this, [key])
export function lpopBuffer(key, count) {
const val = lpop.apply(this, [key, count])
return convertStringToBuffer(val)
}
50 changes: 50 additions & 0 deletions test/integration/commands/lpop.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,56 @@ runTwinSuite('lpop', (command, equals) => {
}
)

// @TODO Rewrite test so it runs on a real Redis instance
;(process.env.IS_E2E ? it.skip : it)(
'should remove key and return first elements when it was last on the list',
() => {
const redis = new Redis({
data: {
foo: ['1'],
},
})

return redis[command]('foo')
.then(result => expect(equals(result, '1')).toBe(true))
.then(() => redis.exists('foo'))
.then(status => expect(status).toBe(0))
}
)

// @TODO Rewrite test so it runs on a real Redis instance
;(process.env.IS_E2E ? it.skip : it)(
'should remove and return "count" elements if second argument is provided',
() => {
const redis = new Redis({
data: {
foo: ['5', '4', '3', '2', '1'],
},
})

return redis[command]('foo', 2)
.then(result => expect(result.map(v => Buffer.isBuffer(v) ? v.toString() : v)).toEqual(['5', '4']))
.then(() => expect(redis.data.get('foo')).toEqual(['3', '2', '1']))
}
)

// @TODO Rewrite test so it runs on a real Redis instance
;(process.env.IS_E2E ? it.skip : it)(
'should remove key and return all elements on larger number if second argument is provided',
() => {
const redis = new Redis({
data: {
foo: ['5', '4', '3', '2', '1'],
},
})

return redis[command]('foo', 7)
.then(result => expect(result.map(v => Buffer.isBuffer(v) ? v.toString() : v)).toEqual(['5', '4', '3', '2', '1']))
.then(() => redis.exists('foo'))
.then(status => expect(status).toBe(0))
}
)

// @TODO Rewrite test so it runs on a real Redis instance
;(process.env.IS_E2E ? it.skip : it)(
'should return buffer values correctly as buffer',
Expand Down

0 comments on commit 57c8afb

Please sign in to comment.