diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59cde639..e484bef9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,8 +129,8 @@ jobs: # if: failure() # run: | # npm run test:e2e -- --detectOpenHandles --forceExit - #env: - # DEBUG: ioredis:* + #env: + # DEBUG: ioredis:* release: permissions: diff --git a/src/commands/lmove.js b/src/commands/lmove.js index 76e5295d..cf0ff31a 100644 --- a/src/commands/lmove.js +++ b/src/commands/lmove.js @@ -1,48 +1,50 @@ export function lmove(listKey1, listKey2, position1, position2) { - if (this.data.has(listKey1) && !(this.data.get(listKey1) instanceof Array)) { - throw new Error(`Key ${listKey1} does not contain a list`) + throw new Error( + 'WRONGTYPE Operation against a key holding the wrong kind of value' + ) } if (this.data.has(listKey2) && !(this.data.get(listKey2) instanceof Array)) { - throw new Error(`Key ${listKey2} does not contain a list`) + throw new Error( + 'WRONGTYPE Operation against a key holding the wrong kind of value' + ) } - if (position1 !== "LEFT" && position1 !== "RIGHT") { - throw new Error("Position1 argument must be 'LEFT' or 'RIGHT'"); + if (position1 !== 'LEFT' && position1 !== 'RIGHT') { + throw new Error("Position1 argument must be 'LEFT' or 'RIGHT'") } - if (position2 !== "LEFT" && position2 !== "RIGHT") { - throw new Error("Position2 argument must be 'LEFT' or 'RIGHT'"); + if (position2 !== 'LEFT' && position2 !== 'RIGHT') { + throw new Error("Position2 argument must be 'LEFT' or 'RIGHT'") } const list1 = this.data.get(listKey1) || [] - let list2 = list1; // Operate on the same list + let list2 = list1 // Operate on the same list if (listKey1 !== listKey2) { // Operate on two different lists list2 = this.data.get(listKey2) || [] } if (list1.length === 0) { - return null; + return null } - let value; - if (position1 === "LEFT") { - value = list1.shift(); + let value + if (position1 === 'LEFT') { + value = list1.shift() } else { - value = list1.pop(); + value = list1.pop() } - if (position2 === "LEFT") { - list2.unshift(value); + if (position2 === 'LEFT') { + list2.unshift(value) } else { - list2.push(value); + list2.push(value) } - this.data.set(listKey1, list1); + this.data.set(listKey1, list1) if (listKey2 !== listKey1) { - this.data.set(listKey2, list2); + this.data.set(listKey2, list2) } return value - } diff --git a/test/integration/commands/lmove.js b/test/integration/commands/lmove.js index 765e8f3f..2dd50ecf 100644 --- a/test/integration/commands/lmove.js +++ b/test/integration/commands/lmove.js @@ -10,123 +10,124 @@ runTwinSuite('lmove', command => { redis.disconnect() }) - const listId1 = "LIST1"; - const listId2 = "LIST2"; - const emptyList = "EMPTY"; - const notalist = "NOTALIST"; + const listId1 = 'LIST1' + const listId2 = 'LIST2' + const emptyList = 'EMPTY' + const notalist = 'NOTALIST' beforeEach(async () => { - await redis.del(listId1); - await redis.del(listId2); - await redis.del(notalist); - - await redis.lpush(emptyList, "TEST"); - await redis.lpop(emptyList); - const membersEmpty = await redis.lrange(listId1, 0, -1); - expect(membersEmpty).toEqual([]); - - await redis.lpush(listId1, ['two', 'one']); - await redis.lpush(listId2, ['four', 'three']); - await redis.set(notalist, "TEST"); - const members1 = await redis.lrange(listId1, 0, -1); - const members2 = await redis.lrange(listId2, 0, -1); - expect(members1).toEqual(['one', 'two']); - expect(members2).toEqual(['three', 'four']); - }); + await redis.del(listId1) + await redis.del(listId2) + await redis.del(notalist) + + await redis.lpush(emptyList, 'TEST') + await redis.lpop(emptyList) + const membersEmpty = await redis.lrange(listId1, 0, -1) + expect(membersEmpty).toEqual([]) + + await redis.lpush(listId1, ['two', 'one']) + await redis.lpush(listId2, ['four', 'three']) + await redis.set(notalist, 'TEST') + const members1 = await redis.lrange(listId1, 0, -1) + const members2 = await redis.lrange(listId2, 0, -1) + expect(members1).toEqual(['one', 'two']) + expect(members2).toEqual(['three', 'four']) + }) it('should move the value from LEFT of list1 to LEFT of list2', async () => { - const result = await redis.lmove(listId1, listId2, "LEFT", "LEFT"); - expect(result).toEqual('one'); + const result = await redis.lmove(listId1, listId2, 'LEFT', 'LEFT') + expect(result).toEqual('one') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['two']); - expect(current2).toEqual(['one', 'three', 'four']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['two']) + expect(current2).toEqual(['one', 'three', 'four']) + }) it('should move the value from RIGHT of list1 to LEFT of list2', async () => { - const result = await redis.lmove(listId1, listId2, "RIGHT", "LEFT"); - expect(result).toEqual('two'); + const result = await redis.lmove(listId1, listId2, 'RIGHT', 'LEFT') + expect(result).toEqual('two') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one']); - expect(current2).toEqual(['two', 'three', 'four']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one']) + expect(current2).toEqual(['two', 'three', 'four']) + }) it('should move the value from LEFT of list1 to RIGHT of list2', async () => { - const result = await redis.lmove(listId1, listId2, "LEFT", "RIGHT"); - expect(result).toEqual('one'); + const result = await redis.lmove(listId1, listId2, 'LEFT', 'RIGHT') + expect(result).toEqual('one') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['two']); - expect(current2).toEqual(['three', 'four', 'one']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['two']) + expect(current2).toEqual(['three', 'four', 'one']) + }) it('should move the value from RIGHT of list1 to RIGHT of list2', async () => { - const result = await redis.lmove(listId1, listId2, "RIGHT", "RIGHT"); - expect(result).toEqual('two'); + const result = await redis.lmove(listId1, listId2, 'RIGHT', 'RIGHT') + expect(result).toEqual('two') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one']); - expect(current2).toEqual(['three', 'four', 'two']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one']) + expect(current2).toEqual(['three', 'four', 'two']) + }) it('should rotate the list if the source and destination are the same', async () => { - const result = await redis.lmove(listId2, listId2, "LEFT", "RIGHT"); - expect(result).toEqual('three'); + const result = await redis.lmove(listId2, listId2, 'LEFT', 'RIGHT') + expect(result).toEqual('three') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one', 'two']); - expect(current2).toEqual(['four', 'three']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one', 'two']) + expect(current2).toEqual(['four', 'three']) + }) it('should perform no operation if the source is an empty list', async () => { - const result = await redis.lmove(emptyList, listId2, "LEFT", "LEFT"); - expect(result).toEqual(null); + const result = await redis.lmove(emptyList, listId2, 'LEFT', 'LEFT') + expect(result).toEqual(null) - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one', 'two']); - expect(current2).toEqual(['three', 'four']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one', 'two']) + expect(current2).toEqual(['three', 'four']) + }) it('should perform no operation if the source and destination are the same and both positions are LEFT', async () => { - const result = await redis.lmove(listId2, listId2, "LEFT", "LEFT"); - expect(result).toEqual('three'); + const result = await redis.lmove(listId2, listId2, 'LEFT', 'LEFT') + expect(result).toEqual('three') - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one', 'two']); - expect(current2).toEqual(['three', 'four']); - }); + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one', 'two']) + expect(current2).toEqual(['three', 'four']) + }) it('should perform no operation if the source and destination are the same and both positions are RIGHT', async () => { - const result = await redis.lmove(listId2, listId2, "RIGHT", "RIGHT"); - expect(result).toEqual('four'); - - const current1 = await redis.lrange(listId1, 0, -1); - const current2 = await redis.lrange(listId2, 0, -1); - expect(current1).toEqual(['one', 'two']); - expect(current2).toEqual(['three', 'four']); - }); + const result = await redis.lmove(listId2, listId2, 'RIGHT', 'RIGHT') + expect(result).toEqual('four') + const current1 = await redis.lrange(listId1, 0, -1) + const current2 = await redis.lrange(listId2, 0, -1) + expect(current1).toEqual(['one', 'two']) + expect(current2).toEqual(['three', 'four']) + }) it('should perform no operation and return nil when source does not exist', async () => { - const value = await redis.get("unknown"); - expect(value).toEqual(null); // Ensures nil is being represented by null + const value = await redis.get('unknown') + expect(value).toEqual(null) // Ensures nil is being represented by null - const result = await redis.lmove("unknown", listId2, "LEFT", "LEFT"); - expect(result).toEqual(null); - }); + const result = await redis.lmove('unknown', listId2, 'LEFT', 'LEFT') + expect(result).toEqual(null) + }) it('should error if the value is not a list', async () => { expect(async () => { - await redis.lmove(notalist, listId2, "LEFT", "LEFT"); - }).rejects.toThrow("Key NOTALIST does not contain a list"); - }); + await redis.lmove(notalist, listId2, 'LEFT', 'LEFT') + }).rejects.toThrow( + 'WRONGTYPE Operation against a key holding the wrong kind of value' + ) + }) }) })