You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1664 lines
51 KiB
JavaScript

10 years ago
'use strict';
10 years ago
const async = require('async');
const assert = require('assert');
const db = require('../mocks/databasemock');
10 years ago
describe('Sorted Set methods', () => {
before((done) => {
10 years ago
async.parallel([
function (next) {
db.sortedSetAdd('sortedSetTest1', [1.1, 1.2, 1.3], ['value1', 'value2', 'value3'], next);
10 years ago
},
function (next) {
10 years ago
db.sortedSetAdd('sortedSetTest2', [1, 4], ['value1', 'value4'], next);
},
function (next) {
10 years ago
db.sortedSetAdd('sortedSetTest3', [2, 4], ['value2', 'value4'], next);
},
function (next) {
db.sortedSetAdd('sortedSetTest4', [1, 1, 2, 3, 5], ['b', 'a', 'd', 'e', 'c'], next);
},
function (next) {
db.sortedSetAdd('sortedSetLex', [0, 0, 0, 0], ['a', 'b', 'c', 'd'], next);
},
10 years ago
], done);
});
describe('sortedSetScan', () => {
it('should find matches in sorted set containing substring', async () => {
await db.sortedSetAdd('scanzset', [1, 2, 3, 4, 5, 6], ['aaaa', 'bbbb', 'bbcc', 'ddd', 'dddd', 'fghbc']);
const data = await db.getSortedSetScan({
key: 'scanzset',
match: '*bc*',
});
assert(data.includes('bbcc'));
assert(data.includes('fghbc'));
});
it('should find matches in sorted set with scores', async () => {
const data = await db.getSortedSetScan({
key: 'scanzset',
match: '*bc*',
withScores: true,
});
data.sort((a, b) => a.score - b.score);
assert.deepStrictEqual(data, [{ value: 'bbcc', score: 3 }, { value: 'fghbc', score: 6 }]);
});
it('should find matches in sorted set with a limit', async () => {
await db.sortedSetAdd('scanzset2', [1, 2, 3, 4, 5, 6], ['aaab', 'bbbb', 'bbcb', 'ddb', 'dddd', 'fghbc']);
const data = await db.getSortedSetScan({
key: 'scanzset2',
match: '*b*',
limit: 2,
});
assert.equal(data.length, 2);
});
it('should work for special characters', async () => {
await db.sortedSetAdd('scanzset3', [1, 2, 3, 4, 5], ['aaab{', 'bbbb', 'bbcb{', 'ddb', 'dddd']);
const data = await db.getSortedSetScan({
key: 'scanzset3',
match: '*b{',
limit: 2,
});
Chat refactor (#11779) * first part of chat refactor remove per user chat zsets & store all mids in chat:room:<roomId>:mids reverse uids in getUidsInRoom * feat: create room button public groups wip * feat: public rooms create chats:room zset chat room deletion * join socket.io room * get rid of some calls that load all users in room * dont load all users when loadRoom is called * mange room users infinitescroll dont load all members in api call * IS for user list ability to change groups field for public rooms update groups field if group is renamed * test: test fixes * wip * keep 150 messages * fix extra awaits fix dupe code in chat toggleReadState * unread state for public rooms * feat: faster push unread * test: spec * change base to harmony * test: lint fixes * fix language of chat with message * add 2 methods for perf messaging.getTeasers and getUsers(roomIds) instead of loading one by one * refactor: cleaner conditional * test fix upgrade script fix save timestamp of room creation in room object * set progress.total * don't check for guests/spiders * public room unread fix * add public unread counts * mark read on send * ignore instead of throwing * doggy.gif * fix: restore delete * prevent entering chat rooms with meta.enter * fix self message causing mark unread * ability to sort public rooms * dont init sortable on mobile * move chat-loaded class to core * test: fix spec * add missing keys * use ajaxify * refactor: store some refs * fix: when user is deleted remove from public rooms as well * feat: change how unread count is calculated * get rid of cleaned content get rid of mid * add help text * test: fix tests, add back mid to prevent breaking change * ability to search members of chat rooms * remove * derp * perf: switch with partial data fix tests * more fixes if user leaves a group leave public rooms is he is no longer part of any of the groups that have access fix the cache key used to get all public room ids dont allow joining chat socket.io room if user is no longer part of group * fix: lint * fix: js error when trying to delete room after switching * add isRoomPublic
2 years ago
assert.strictEqual(data.length, 2);
assert(data.includes('aaab{'));
assert(data.includes('bbcb{'));
});
it('should find everything starting with string', async () => {
await db.sortedSetAdd('scanzset4', [1, 2, 3, 4, 5], ['aaab{', 'bbbb', 'bbcb', 'ddb', 'dddd']);
const data = await db.getSortedSetScan({
key: 'scanzset4',
match: 'b*',
});
Chat refactor (#11779) * first part of chat refactor remove per user chat zsets & store all mids in chat:room:<roomId>:mids reverse uids in getUidsInRoom * feat: create room button public groups wip * feat: public rooms create chats:room zset chat room deletion * join socket.io room * get rid of some calls that load all users in room * dont load all users when loadRoom is called * mange room users infinitescroll dont load all members in api call * IS for user list ability to change groups field for public rooms update groups field if group is renamed * test: test fixes * wip * keep 150 messages * fix extra awaits fix dupe code in chat toggleReadState * unread state for public rooms * feat: faster push unread * test: spec * change base to harmony * test: lint fixes * fix language of chat with message * add 2 methods for perf messaging.getTeasers and getUsers(roomIds) instead of loading one by one * refactor: cleaner conditional * test fix upgrade script fix save timestamp of room creation in room object * set progress.total * don't check for guests/spiders * public room unread fix * add public unread counts * mark read on send * ignore instead of throwing * doggy.gif * fix: restore delete * prevent entering chat rooms with meta.enter * fix self message causing mark unread * ability to sort public rooms * dont init sortable on mobile * move chat-loaded class to core * test: fix spec * add missing keys * use ajaxify * refactor: store some refs * fix: when user is deleted remove from public rooms as well * feat: change how unread count is calculated * get rid of cleaned content get rid of mid * add help text * test: fix tests, add back mid to prevent breaking change * ability to search members of chat rooms * remove * derp * perf: switch with partial data fix tests * more fixes if user leaves a group leave public rooms is he is no longer part of any of the groups that have access fix the cache key used to get all public room ids dont allow joining chat socket.io room if user is no longer part of group * fix: lint * fix: js error when trying to delete room after switching * add isRoomPublic
2 years ago
assert.strictEqual(data.length, 2);
assert(data.includes('bbbb'));
assert(data.includes('bbcb'));
});
it('should find everything ending with string', async () => {
await db.sortedSetAdd('scanzset5', [1, 2, 3, 4, 5, 6], ['aaab{', 'bbbb', 'bbcb', 'ddb', 'dddd', 'adb']);
const data = await db.getSortedSetScan({
key: 'scanzset5',
match: '*db',
});
Chat refactor (#11779) * first part of chat refactor remove per user chat zsets & store all mids in chat:room:<roomId>:mids reverse uids in getUidsInRoom * feat: create room button public groups wip * feat: public rooms create chats:room zset chat room deletion * join socket.io room * get rid of some calls that load all users in room * dont load all users when loadRoom is called * mange room users infinitescroll dont load all members in api call * IS for user list ability to change groups field for public rooms update groups field if group is renamed * test: test fixes * wip * keep 150 messages * fix extra awaits fix dupe code in chat toggleReadState * unread state for public rooms * feat: faster push unread * test: spec * change base to harmony * test: lint fixes * fix language of chat with message * add 2 methods for perf messaging.getTeasers and getUsers(roomIds) instead of loading one by one * refactor: cleaner conditional * test fix upgrade script fix save timestamp of room creation in room object * set progress.total * don't check for guests/spiders * public room unread fix * add public unread counts * mark read on send * ignore instead of throwing * doggy.gif * fix: restore delete * prevent entering chat rooms with meta.enter * fix self message causing mark unread * ability to sort public rooms * dont init sortable on mobile * move chat-loaded class to core * test: fix spec * add missing keys * use ajaxify * refactor: store some refs * fix: when user is deleted remove from public rooms as well * feat: change how unread count is calculated * get rid of cleaned content get rid of mid * add help text * test: fix tests, add back mid to prevent breaking change * ability to search members of chat rooms * remove * derp * perf: switch with partial data fix tests * more fixes if user leaves a group leave public rooms is he is no longer part of any of the groups that have access fix the cache key used to get all public room ids dont allow joining chat socket.io room if user is no longer part of group * fix: lint * fix: js error when trying to delete room after switching * add isRoomPublic
2 years ago
assert.strictEqual(data.length, 2);
assert(data.includes('ddb'));
assert(data.includes('adb'));
});
});
describe('sortedSetAdd()', () => {
it('should add an element to a sorted set', (done) => {
db.sortedSetAdd('sorted1', 1, 'value1', function (err) {
10 years ago
assert.equal(err, null);
assert.equal(arguments.length, 1);
done();
});
});
it('should add two elements to a sorted set', (done) => {
db.sortedSetAdd('sorted2', [1, 2], ['value1', 'value2'], function (err) {
10 years ago
assert.equal(err, null);
assert.equal(arguments.length, 1);
done();
});
});
it('should gracefully handle adding the same element twice', (done) => {
db.sortedSetAdd('sorted2', [1, 2], ['value1', 'value1'], function (err) {
assert.equal(err, null);
assert.equal(arguments.length, 1);
db.sortedSetScore('sorted2', 'value1', function (err, score) {
assert.equal(err, null);
assert.equal(score, 2);
assert.equal(arguments.length, 2);
done();
});
});
});
it('should error if score is null', (done) => {
db.sortedSetAdd('errorScore', null, 'value1', (err) => {
assert.equal(err.message, '[[error:invalid-score, null]]');
done();
});
});
it('should error if any score is undefined', (done) => {
db.sortedSetAdd('errorScore', [1, undefined], ['value1', 'value2'], (err) => {
assert.equal(err.message, '[[error:invalid-score, undefined]]');
done();
});
});
it('should add null value as `null` string', (done) => {
db.sortedSetAdd('nullValueZSet', 1, null, (err) => {
assert.ifError(err);
db.getSortedSetRange('nullValueZSet', 0, -1, (err, values) => {
assert.ifError(err);
assert.strictEqual(values[0], 'null');
done();
});
});
});
10 years ago
});
describe('sortedSetsAdd()', () => {
it('should add an element to two sorted sets', (done) => {
db.sortedSetsAdd(['sorted1', 'sorted2'], 3, 'value3', function (err) {
10 years ago
assert.equal(err, null);
assert.equal(arguments.length, 1);
done();
});
});
it('should add an element to two sorted sets with different scores', (done) => {
db.sortedSetsAdd(['sorted1', 'sorted2'], [4, 5], 'value4', (err) => {
assert.ifError(err);
db.sortedSetsScore(['sorted1', 'sorted2'], 'value4', (err, scores) => {
assert.ifError(err);
assert.deepStrictEqual(scores, [4, 5]);
done();
});
});
});
it('should error if keys.length is different than scores.length', (done) => {
db.sortedSetsAdd(['sorted1', 'sorted2'], [4], 'value4', (err) => {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should error if score is null', (done) => {
db.sortedSetsAdd(['sorted1', 'sorted2'], null, 'value1', (err) => {
assert.equal(err.message, '[[error:invalid-score, null]]');
done();
});
});
it('should error if scores has null', async () => {
let err;
try {
await db.sortedSetsAdd(['sorted1', 'sorted2'], [1, null], 'dontadd');
} catch (_err) {
err = _err;
}
assert.equal(err.message, '[[error:invalid-score, 1,]]');
assert.strictEqual(await db.isSortedSetMember('sorted1', 'dontadd'), false);
assert.strictEqual(await db.isSortedSetMember('sorted2', 'dontadd'), false);
});
10 years ago
});
describe('sortedSetAddMulti()', () => {
it('should add elements into multiple sorted sets with different scores', (done) => {
db.sortedSetAddBulk([
['bulk1', 1, 'item1'],
['bulk2', 2, 'item1'],
['bulk2', 3, 'item2'],
['bulk3', 4, 'item3'],
], function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRevRangeWithScores(['bulk1', 'bulk2', 'bulk3'], 0, -1, (err, data) => {
assert.ifError(err);
assert.deepStrictEqual(data, [{ value: 'item3', score: 4 },
{ value: 'item2', score: 3 },
{ value: 'item1', score: 2 },
{ value: 'item1', score: 1 }]);
done();
});
});
});
it('should not error if data is undefined', (done) => {
db.sortedSetAddBulk(undefined, (err) => {
assert.ifError(err);
done();
});
});
it('should error if score is null', async () => {
let err;
try {
await db.sortedSetAddBulk([
['bulk4', 0, 'dontadd'],
['bulk5', null, 'dontadd'],
]);
} catch (_err) {
err = _err;
}
assert.equal(err.message, '[[error:invalid-score, null]]');
assert.strictEqual(await db.isSortedSetMember('bulk4', 'dontadd'), false);
assert.strictEqual(await db.isSortedSetMember('bulk5', 'dontadd'), false);
});
});
describe('getSortedSetRange()', () => {
it('should return the lowest scored element', (done) => {
db.getSortedSetRange('sortedSetTest1', 0, 0, function (err, value) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(value, ['value1']);
done();
});
});
it('should return elements sorted by score lowest to highest', (done) => {
db.getSortedSetRange('sortedSetTest1', 0, -1, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, ['value1', 'value2', 'value3']);
done();
});
});
it('should return empty array if set does not exist', (done) => {
db.getSortedSetRange('doesnotexist', 0, -1, (err, values) => {
assert.ifError(err);
assert(Array.isArray(values));
assert.equal(values.length, 0);
done();
});
});
7 years ago
it('should handle negative start/stop', (done) => {
db.sortedSetAdd('negatives', [1, 2, 3, 4, 5], ['1', '2', '3', '4', '5'], (err) => {
7 years ago
assert.ifError(err);
db.getSortedSetRange('negatives', -2, -4, (err, data) => {
7 years ago
assert.ifError(err);
assert.deepEqual(data, []);
done();
});
});
});
it('should handle negative start/stop', (done) => {
db.getSortedSetRange('negatives', -4, -2, (err, data) => {
7 years ago
assert.ifError(err);
assert.deepEqual(data, ['2', '3', '4']);
done();
});
});
it('should handle negative start/stop', (done) => {
db.getSortedSetRevRange('negatives', -4, -2, (err, data) => {
7 years ago
assert.ifError(err);
assert.deepEqual(data, ['4', '3', '2']);
done();
});
});
it('should handle negative start/stop', (done) => {
db.getSortedSetRange('negatives', -5, -1, (err, data) => {
7 years ago
assert.ifError(err);
assert.deepEqual(data, ['1', '2', '3', '4', '5']);
done();
});
});
it('should handle negative start/stop', (done) => {
db.getSortedSetRange('negatives', 0, -2, (err, data) => {
7 years ago
assert.ifError(err);
assert.deepEqual(data, ['1', '2', '3', '4']);
done();
});
});
it('should return empty array if keys is empty array', (done) => {
db.getSortedSetRange([], 0, -1, (err, data) => {
assert.ifError(err);
assert.deepStrictEqual(data, []);
done();
});
});
it('should return duplicates if two sets have same elements', async () => {
await db.sortedSetAdd('dupezset1', [1, 2], ['value 1', 'value 2']);
await db.sortedSetAdd('dupezset2', [2, 3], ['value 2', 'value 3']);
const data = await db.getSortedSetRange(['dupezset1', 'dupezset2'], 0, -1);
assert.deepStrictEqual(data, ['value 1', 'value 2', 'value 2', 'value 3']);
});
it('should return correct number of elements', async () => {
await db.sortedSetAdd('dupezset3', [1, 2, 3], ['value 1', 'value 2', 'value3']);
await db.sortedSetAdd('dupezset4', [0, 5], ['value 0', 'value5']);
const data = await db.getSortedSetRevRange(['dupezset3', 'dupezset4'], 0, 1);
assert.deepStrictEqual(data, ['value5', 'value3']);
});
it('should work with big arrays (length > 100) ', async function () {
this.timeout(100000);
const keys = [];
for (let i = 0; i < 400; i++) {
/* eslint-disable no-await-in-loop */
const bulkAdd = [];
keys.push(`testzset${i}`);
for (let k = 0; k < 100; k++) {
bulkAdd.push([`testzset${i}`, 1000000 + k + (i * 100), k + (i * 100)]);
}
await db.sortedSetAddBulk(bulkAdd);
}
let data = await db.getSortedSetRevRange(keys, 0, 3);
assert.deepStrictEqual(data, ['39999', '39998', '39997', '39996']);
data = await db.getSortedSetRevRangeWithScores(keys, 0, 3);
assert.deepStrictEqual(data, [
{ value: '39999', score: 1039999 },
{ value: '39998', score: 1039998 },
{ value: '39997', score: 1039997 },
{ value: '39996', score: 1039996 },
]);
data = await db.getSortedSetRevRange(keys, 0, -1);
assert.equal(data.length, 40000);
data = await db.getSortedSetRange(keys, 9998, 10002);
assert.deepStrictEqual(data, ['9998', '9999', '10000', '10001', '10002']);
});
});
describe('getSortedSetRevRange()', () => {
it('should return the highest scored element', (done) => {
db.getSortedSetRevRange('sortedSetTest1', 0, 0, function (err, value) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(value, ['value3']);
done();
});
});
it('should return elements sorted by score highest to lowest', (done) => {
db.getSortedSetRevRange('sortedSetTest1', 0, -1, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, ['value3', 'value2', 'value1']);
done();
});
});
});
describe('getSortedSetRangeWithScores()', () => {
it('should return array of elements sorted by score lowest to highest with scores', (done) => {
db.getSortedSetRangeWithScores('sortedSetTest1', 0, -1, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, [{ value: 'value1', score: 1.1 }, { value: 'value2', score: 1.2 }, { value: 'value3', score: 1.3 }]);
done();
});
});
});
describe('getSortedSetRevRangeWithScores()', () => {
it('should return array of elements sorted by score highest to lowest with scores', (done) => {
db.getSortedSetRevRangeWithScores('sortedSetTest1', 0, -1, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, [{ value: 'value3', score: 1.3 }, { value: 'value2', score: 1.2 }, { value: 'value1', score: 1.1 }]);
done();
});
});
});
10 years ago
describe('getSortedSetRangeByScore()', () => {
it('should get count elements with score between min max sorted by score lowest to highest', (done) => {
db.getSortedSetRangeByScore('sortedSetTest1', 0, -1, '-inf', 1.2, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, ['value1', 'value2']);
done();
});
});
it('should return empty array if set does not exist', (done) => {
db.getSortedSetRangeByScore('doesnotexist', 0, -1, '-inf', 0, (err, values) => {
assert.ifError(err);
assert(Array.isArray(values));
assert.equal(values.length, 0);
done();
});
});
it('should return empty array if count is 0', (done) => {
db.getSortedSetRevRangeByScore('sortedSetTest1', 0, 0, '+inf', '-inf', (err, values) => {
assert.ifError(err);
assert.deepEqual(values, []);
done();
});
});
it('should return elements from 1 to end', (done) => {
db.getSortedSetRevRangeByScore('sortedSetTest1', 1, -1, '+inf', '-inf', (err, values) => {
assert.ifError(err);
assert.deepEqual(values, ['value2', 'value1']);
done();
});
});
it('should return elements from 3 to last', (done) => {
db.sortedSetAdd('partialZset', [1, 2, 3, 4, 5], ['value1', 'value2', 'value3', 'value4', 'value5'], (err) => {
assert.ifError(err);
db.getSortedSetRangeByScore('partialZset', 3, 10, '-inf', '+inf', (err, data) => {
assert.ifError(err);
assert.deepStrictEqual(data, ['value4', 'value5']);
done();
});
});
});
it('should return elements if min/max are numeric strings', async () => {
await db.sortedSetAdd('zsetstringminmax', [1, 2, 3, 4, 5], ['value1', 'value2', 'value3', 'value4', 'value5']);
const results = await db.getSortedSetRevRangeByScore('zsetstringminmax', 0, -1, '3', '3');
assert.deepStrictEqual(results, ['value3']);
});
});
describe('getSortedSetRevRangeByScore()', () => {
it('should get count elements with score between max min sorted by score highest to lowest', (done) => {
db.getSortedSetRevRangeByScore('sortedSetTest1', 0, -1, '+inf', 1.2, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, ['value3', 'value2']);
done();
});
});
});
describe('getSortedSetRangeByScoreWithScores()', () => {
it('should get count elements with score between min max sorted by score lowest to highest with scores', (done) => {
db.getSortedSetRangeByScoreWithScores('sortedSetTest1', 0, -1, '-inf', 1.2, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, [{ value: 'value1', score: 1.1 }, { value: 'value2', score: 1.2 }]);
done();
});
});
});
describe('getSortedSetRevRangeByScoreWithScores()', () => {
it('should get count elements with score between max min sorted by score highest to lowest', (done) => {
db.getSortedSetRevRangeByScoreWithScores('sortedSetTest1', 0, -1, '+inf', 1.2, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(values, [{ value: 'value3', score: 1.3 }, { value: 'value2', score: 1.2 }]);
done();
});
});
it('should work with an array of keys', async () => {
await db.sortedSetAddBulk([
['byScoreWithScoresKeys1', 1, 'value1'],
['byScoreWithScoresKeys2', 2, 'value2'],
]);
const data = await db.getSortedSetRevRangeByScoreWithScores(['byScoreWithScoresKeys1', 'byScoreWithScoresKeys2'], 0, -1, 5, -5);
assert.deepStrictEqual(data, [{ value: 'value2', score: 2 }, { value: 'value1', score: 1 }]);
});
});
describe('sortedSetCount()', () => {
it('should return 0 for a sorted set that does not exist', (done) => {
db.sortedSetCount('doesnotexist', 0, 10, function (err, count) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(count, 0);
done();
});
});
it('should return number of elements between scores min max inclusive', (done) => {
db.sortedSetCount('sortedSetTest1', '-inf', 1.2, function (err, count) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(count, 2);
done();
});
10 years ago
});
it('should return number of elements between scores -inf +inf inclusive', (done) => {
db.sortedSetCount('sortedSetTest1', '-inf', '+inf', function (err, count) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(count, 3);
done();
10 years ago
});
});
});
describe('sortedSetCard()', () => {
it('should return 0 for a sorted set that does not exist', (done) => {
db.sortedSetCard('doesnotexist', function (err, count) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(count, 0);
done();
});
});
it('should return number of elements in a sorted set', (done) => {
db.sortedSetCard('sortedSetTest1', function (err, count) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(count, 3);
done();
});
});
});
describe('sortedSetsCard()', () => {
it('should return the number of elements in sorted sets', (done) => {
db.sortedSetsCard(['sortedSetTest1', 'sortedSetTest2', 'doesnotexist'], function (err, counts) {
assert.ifError(err);
assert.equal(arguments.length, 2);
10 years ago
assert.deepEqual(counts, [3, 2, 0]);
done();
});
});
it('should return empty array if keys is falsy', (done) => {
db.sortedSetsCard(undefined, function (err, counts) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(counts, []);
done();
});
});
it('should return empty array if keys is empty array', (done) => {
db.sortedSetsCard([], function (err, counts) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(counts, []);
done();
});
});
});
describe('sortedSetsCardSum()', () => {
it('should return the total number of elements in sorted sets', (done) => {
db.sortedSetsCardSum(['sortedSetTest1', 'sortedSetTest2', 'doesnotexist'], function (err, sum) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.equal(sum, 5);
done();
});
});
it('should return 0 if keys is falsy', (done) => {
db.sortedSetsCardSum(undefined, function (err, counts) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(counts, 0);
done();
});
});
it('should return 0 if keys is empty array', (done) => {
db.sortedSetsCardSum([], function (err, counts) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(counts, 0);
done();
});
});
it('should return the total number of elements in sorted set', (done) => {
db.sortedSetsCardSum('sortedSetTest1', function (err, sum) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.equal(sum, 3);
done();
});
});
});
describe('sortedSetRank()', () => {
it('should return falsy if sorted set does not exist', (done) => {
db.sortedSetRank('doesnotexist', 'value1', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!rank, false);
done();
});
});
it('should return falsy if element isnt in sorted set', (done) => {
db.sortedSetRank('sortedSetTest1', 'value5', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!rank, false);
done();
});
});
it('should return the rank of the element in the sorted set sorted by lowest to highest score', (done) => {
db.sortedSetRank('sortedSetTest1', 'value1', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(rank, 0);
done();
});
});
it('should return the rank sorted by the score and then the value (a)', (done) => {
db.sortedSetRank('sortedSetTest4', 'a', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(rank, 0);
done();
});
});
it('should return the rank sorted by the score and then the value (b)', (done) => {
db.sortedSetRank('sortedSetTest4', 'b', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(rank, 1);
done();
});
});
it('should return the rank sorted by the score and then the value (c)', (done) => {
db.sortedSetRank('sortedSetTest4', 'c', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(rank, 4);
done();
});
});
});
describe('sortedSetRevRank()', () => {
it('should return falsy if sorted set doesnot exist', (done) => {
db.sortedSetRevRank('doesnotexist', 'value1', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!rank, false);
done();
});
});
it('should return falsy if element isnt in sorted set', (done) => {
db.sortedSetRevRank('sortedSetTest1', 'value5', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!rank, false);
done();
});
});
it('should return the rank of the element in the sorted set sorted by highest to lowest score', (done) => {
db.sortedSetRevRank('sortedSetTest1', 'value1', function (err, rank) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(rank, 2);
done();
});
});
});
describe('sortedSetsRanks()', () => {
it('should return the ranks of values in sorted sets', (done) => {
db.sortedSetsRanks(['sortedSetTest1', 'sortedSetTest2'], ['value1', 'value4'], function (err, ranks) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(ranks, [0, 1]);
done();
});
});
});
describe('sortedSetRanks()', () => {
it('should return the ranks of values in a sorted set', (done) => {
db.sortedSetRanks('sortedSetTest1', ['value2', 'value1', 'value3', 'value4'], function (err, ranks) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(ranks, [1, 0, 2, null]);
done();
});
});
it('should return the ranks of values in a sorted set in reverse', (done) => {
db.sortedSetRevRanks('sortedSetTest1', ['value2', 'value1', 'value3', 'value4'], function (err, ranks) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(ranks, [1, 2, 0, null]);
done();
});
});
});
describe('sortedSetScore()', () => {
it('should return falsy if sorted set does not exist', (done) => {
db.sortedSetScore('doesnotexist', 'value1', function (err, score) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!score, false);
8 years ago
assert.strictEqual(score, null);
done();
});
});
it('should return falsy if element is not in sorted set', (done) => {
db.sortedSetScore('sortedSetTest1', 'value5', function (err, score) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.equal(!!score, false);
8 years ago
assert.strictEqual(score, null);
done();
});
});
it('should return the score of an element', (done) => {
db.sortedSetScore('sortedSetTest1', 'value2', function (err, score) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.strictEqual(score, 1.2);
done();
});
});
8 years ago
it('should not error if key is undefined', (done) => {
db.sortedSetScore(undefined, 1, (err, score) => {
8 years ago
assert.ifError(err);
assert.strictEqual(score, null);
done();
});
});
it('should not error if value is undefined', (done) => {
db.sortedSetScore('sortedSetTest1', undefined, (err, score) => {
8 years ago
assert.ifError(err);
assert.strictEqual(score, null);
done();
});
});
});
describe('sortedSetsScore()', () => {
it('should return the scores of value in sorted sets', (done) => {
db.sortedSetsScore(['sortedSetTest1', 'sortedSetTest2', 'doesnotexist'], 'value1', function (err, scores) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(scores, [1.1, 1, null]);
done();
});
});
8 years ago
it('should return scores even if some keys are undefined', (done) => {
8 years ago
db.sortedSetsScore(['sortedSetTest1', undefined, 'doesnotexist'], 'value1', function (err, scores) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(scores, [1.1, null, null]);
done();
});
});
it('should return empty array if keys is empty array', (done) => {
db.sortedSetsScore([], 'value1', function (err, scores) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(scores, []);
done();
});
});
});
describe('sortedSetScores()', () => {
before((done) => {
9 years ago
db.sortedSetAdd('zeroScore', 0, 'value1', done);
});
it('should return 0 if score is 0', (done) => {
db.sortedSetScores('zeroScore', ['value1'], (err, scores) => {
9 years ago
assert.ifError(err);
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
assert.strictEqual(scores[0], 0);
9 years ago
done();
});
});
it('should return the scores of value in sorted sets', (done) => {
db.sortedSetScores('sortedSetTest1', ['value2', 'value1', 'doesnotexist'], function (err, scores) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepStrictEqual(scores, [1.2, 1.1, null]);
done();
});
});
8 years ago
it('should return scores even if some values are undefined', (done) => {
8 years ago
db.sortedSetScores('sortedSetTest1', ['value2', undefined, 'doesnotexist'], function (err, scores) {
assert.ifError(err);
8 years ago
assert.equal(arguments.length, 2);
assert.deepStrictEqual(scores, [1.2, null, null]);
8 years ago
done();
});
});
it('should return empty array if values is an empty array', (done) => {
db.sortedSetScores('sortedSetTest1', [], function (err, scores) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepStrictEqual(scores, []);
done();
});
});
it('should return scores properly', (done) => {
db.sortedSetsScore(['zeroScore', 'sortedSetTest1', 'doesnotexist'], 'value1', function (err, scores) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepStrictEqual(scores, [0, 1.1, null]);
done();
});
});
});
describe('isSortedSetMember()', () => {
before((done) => {
10 years ago
db.sortedSetAdd('zeroscore', 0, 'itemwithzeroscore', done);
});
it('should return false if sorted set does not exist', (done) => {
db.isSortedSetMember('doesnotexist', 'value1', function (err, isMember) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.equal(isMember, false);
done();
});
});
it('should return false if element is not in sorted set', (done) => {
db.isSortedSetMember('sorted2', 'value5', function (err, isMember) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.equal(isMember, false);
done();
});
});
it('should return true if element is in sorted set', (done) => {
db.isSortedSetMember('sortedSetTest1', 'value2', function (err, isMember) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.strictEqual(isMember, true);
done();
});
});
10 years ago
it('should return true if element is in sorted set with score 0', (done) => {
db.isSortedSetMember('zeroscore', 'itemwithzeroscore', (err, isMember) => {
10 years ago
assert.ifError(err);
assert.strictEqual(isMember, true);
10 years ago
done();
});
});
});
describe('isSortedSetMembers()', () => {
it('should return an array of booleans indicating membership', (done) => {
db.isSortedSetMembers('sortedSetTest1', ['value1', 'value2', 'value5'], function (err, isMembers) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(isMembers, [true, true, false]);
done();
});
});
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
it('should return true if element is in sorted set with score 0', (done) => {
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
db.isSortedSetMembers('zeroscore', ['itemwithzeroscore'], function (err, isMembers) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(isMembers, [true]);
done();
});
});
});
describe('isMemberOfSortedSets', () => {
it('should return true for members false for non members', (done) => {
db.isMemberOfSortedSets(['doesnotexist', 'sortedSetTest1', 'sortedSetTest2'], 'value2', function (err, isMembers) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(isMembers, [false, true, false]);
done();
});
});
it('should return empty array if keys is empty array', (done) => {
db.isMemberOfSortedSets([], 'value2', function (err, isMembers) {
assert.ifError(err);
assert.equal(arguments.length, 2);
assert.deepEqual(isMembers, []);
done();
});
});
});
describe('getSortedSetsMembers', () => {
it('should return members of a sorted set', async () => {
const result = await db.getSortedSetMembers('sortedSetTest1');
result.forEach((element) => {
assert(['value1', 'value2', 'value3'].includes(element));
});
});
it('should return members of multiple sorted sets', (done) => {
db.getSortedSetsMembers(['doesnotexist', 'sortedSetTest1'], function (err, sortedSets) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(sortedSets[0], []);
sortedSets[0].forEach((element) => {
assert.notEqual(['value1', 'value2', 'value3'].indexOf(element), -1);
});
done();
});
});
it('should return members of sorted set with scores', async () => {
await db.sortedSetAdd('getSortedSetsMembersWithScores', [1, 2, 3], ['v1', 'v2', 'v3']);
const d = await db.getSortedSetMembersWithScores('getSortedSetsMembersWithScores');
assert.deepEqual(d, [
{ value: 'v1', score: 1 },
{ value: 'v2', score: 2 },
{ value: 'v3', score: 3 },
]);
});
it('should return members of multiple sorted sets with scores', async () => {
const d = await db.getSortedSetsMembersWithScores(
['doesnotexist', 'getSortedSetsMembersWithScores']
);
assert.deepEqual(d[0], []);
assert.deepEqual(d[1], [
{ value: 'v1', score: 1 },
{ value: 'v2', score: 2 },
{ value: 'v3', score: 3 },
]);
});
});
describe('sortedSetUnionCard', () => {
it('should return the number of elements in the union', (done) => {
db.sortedSetUnionCard(['sortedSetTest2', 'sortedSetTest3'], (err, count) => {
assert.ifError(err);
assert.equal(count, 3);
done();
});
});
});
describe('getSortedSetUnion()', () => {
it('should return an array of values from both sorted sets sorted by scores lowest to highest', (done) => {
db.getSortedSetUnion({ sets: ['sortedSetTest2', 'sortedSetTest3'], start: 0, stop: -1 }, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
10 years ago
assert.deepEqual(values, ['value1', 'value2', 'value4']);
done();
});
});
it('should return an array of values and scores from both sorted sets sorted by scores lowest to highest', (done) => {
db.getSortedSetUnion({ sets: ['sortedSetTest2', 'sortedSetTest3'], start: 0, stop: -1, withScores: true }, function (err, data) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.deepEqual(data, [{ value: 'value1', score: 1 }, { value: 'value2', score: 2 }, { value: 'value4', score: 8 }]);
done();
});
});
});
describe('getSortedSetRevUnion()', () => {
it('should return an array of values from both sorted sets sorted by scores highest to lowest', (done) => {
db.getSortedSetRevUnion({ sets: ['sortedSetTest2', 'sortedSetTest3'], start: 0, stop: -1 }, function (err, values) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
10 years ago
assert.deepEqual(values, ['value4', 'value2', 'value1']);
done();
});
});
it('should return empty array if sets is empty', async () => {
const result = await db.getSortedSetRevUnion({ sets: [], start: 0, stop: -1 });
assert.deepStrictEqual(result, []);
});
});
describe('sortedSetIncrBy()', () => {
it('should create a sorted set with a field set to 1', (done) => {
db.sortedSetIncrBy('sortedIncr', 1, 'field1', function (err, newValue) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.strictEqual(newValue, 1);
db.sortedSetScore('sortedIncr', 'field1', (err, score) => {
assert.equal(err, null);
assert.strictEqual(score, 1);
done();
});
});
});
it('should increment a field of a sorted set by 5', (done) => {
db.sortedSetIncrBy('sortedIncr', 5, 'field1', function (err, newValue) {
assert.equal(err, null);
assert.equal(arguments.length, 2);
assert.strictEqual(newValue, 6);
db.sortedSetScore('sortedIncr', 'field1', (err, score) => {
assert.equal(err, null);
assert.strictEqual(score, 6);
done();
});
});
});
it('should increment fields of sorted sets with a single call', async () => {
const data = await db.sortedSetIncrByBulk([
['sortedIncrBulk1', 1, 'value1'],
['sortedIncrBulk2', 2, 'value2'],
['sortedIncrBulk3', 3, 'value3'],
['sortedIncrBulk3', 4, 'value4'],
]);
assert.deepStrictEqual(data, [1, 2, 3, 4]);
assert.deepStrictEqual(
await db.getSortedSetRangeWithScores('sortedIncrBulk1', 0, -1),
[{ value: 'value1', score: 1 }],
);
assert.deepStrictEqual(
await db.getSortedSetRangeWithScores('sortedIncrBulk2', 0, -1),
[{ value: 'value2', score: 2 }],
);
assert.deepStrictEqual(
await db.getSortedSetRangeWithScores('sortedIncrBulk3', 0, -1),
[
{ value: 'value3', score: 3 },
{ value: 'value4', score: 4 },
],
);
});
it('should increment the same field', async () => {
const data1 = await db.sortedSetIncrByBulk([
['sortedIncrBulk5', 5, 'value5'],
]);
const data2 = await db.sortedSetIncrByBulk([
['sortedIncrBulk5', 5, 'value5'],
]);
assert.deepStrictEqual(
await db.getSortedSetRangeWithScores('sortedIncrBulk5', 0, -1),
[
{ value: 'value5', score: 10 },
],
);
});
});
describe('sortedSetRemove()', () => {
before((done) => {
10 years ago
db.sortedSetAdd('sorted3', [1, 2], ['value1', 'value2'], done);
});
it('should remove an element from a sorted set', (done) => {
db.sortedSetRemove('sorted3', 'value2', function (err) {
assert.equal(err, null);
assert.equal(arguments.length, 1);
db.isSortedSetMember('sorted3', 'value2', (err, isMember) => {
assert.equal(err, null);
assert.equal(isMember, false);
done();
});
});
});
it('should not think the sorted set exists if the last element is removed', async () => {
await db.sortedSetRemove('sorted3', 'value1');
assert.strictEqual(await db.exists('sorted3'), false);
});
it('should remove multiple values from multiple keys', (done) => {
db.sortedSetAdd('multiTest1', [1, 2, 3, 4], ['one', 'two', 'three', 'four'], (err) => {
assert.ifError(err);
db.sortedSetAdd('multiTest2', [3, 4, 5, 6], ['three', 'four', 'five', 'six'], (err) => {
assert.ifError(err);
db.sortedSetRemove(['multiTest1', 'multiTest2'], ['two', 'three', 'four', 'five', 'doesnt exist'], (err) => {
assert.ifError(err);
db.getSortedSetsMembers(['multiTest1', 'multiTest2'], (err, members) => {
assert.ifError(err);
assert.equal(members[0].length, 1);
assert.equal(members[1].length, 1);
assert.deepEqual(members, [['one'], ['six']]);
done();
});
});
});
});
});
it('should remove value from multiple keys', async () => {
await db.sortedSetAdd('multiTest3', [1, 2, 3, 4], ['one', 'two', 'three', 'four']);
await db.sortedSetAdd('multiTest4', [3, 4, 5, 6], ['three', 'four', 'five', 'six']);
await db.sortedSetRemove(['multiTest3', 'multiTest4'], 'three');
assert.deepStrictEqual(await db.getSortedSetRange('multiTest3', 0, -1), ['one', 'two', 'four']);
assert.deepStrictEqual(await db.getSortedSetRange('multiTest4', 0, -1), ['four', 'five', 'six']);
});
it('should remove multiple values from multiple keys', (done) => {
db.sortedSetAdd('multiTest5', [1], ['one'], (err) => {
assert.ifError(err);
db.sortedSetAdd('multiTest6', [2], ['two'], (err) => {
assert.ifError(err);
db.sortedSetAdd('multiTest7', [3], [333], (err) => {
assert.ifError(err);
db.sortedSetRemove(['multiTest5', 'multiTest6', 'multiTest7'], ['one', 'two', 333], (err) => {
assert.ifError(err);
db.getSortedSetsMembers(['multiTest5', 'multiTest6', 'multiTest7'], (err, members) => {
assert.ifError(err);
assert.deepEqual(members, [[], [], []]);
done();
});
});
});
});
});
});
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
it('should not remove anything if values is empty array', (done) => {
db.sortedSetAdd('removeNothing', [1, 2, 3], ['val1', 'val2', 'val3'], (err) => {
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
assert.ifError(err);
db.sortedSetRemove('removeNothing', [], (err) => {
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
assert.ifError(err);
db.getSortedSetRange('removeNothing', 0, -1, (err, data) => {
Async refactor in place (#7736) * feat: allow both callback&and await * feat: ignore async key * feat: callbackify and promisify in same file * Revert "feat: callbackify and promisify in same file" This reverts commit cea206a9b8e6d8295310074b18cc82a504487862. * feat: no need to store .callbackify * feat: change getTopics to async * feat: remove .async * fix: byScore * feat: rewrite topics/index and social with async/await * fix: rewrite topics/data.js fix issue with async.waterfall, only pass result if its not undefined * feat: add callbackify to redis/psql * feat: psql use await * fix: redis :volcano: * feat: less returns * feat: more await rewrite * fix: redis tests * feat: convert sortedSetAdd rewrite psql transaction to async/await * feat: :dog: * feat: test * feat: log client and query * feat: log bind * feat: more logs * feat: more logs * feat: check perform * feat: dont callbackify transaction * feat: remove logs * fix: main functions * feat: more logs * fix: increment * fix: rename * feat: remove cls * fix: remove console.log * feat: add deprecation message to .async usage * feat: update more dbal methods * fix: redis :voodoo: * feat: fix redis zrem, convert setObject * feat: upgrade getObject methods * fix: psql getObjectField * fix: redis tests * feat: getObjectKeys * feat: getObjectValues * feat: isObjectField * fix: add missing return * feat: delObjectField * feat: incrObjectField * fix: add missing await * feat: remove exposed helpers * feat: list methods * feat: flush/empty * feat: delete * fix: redis delete all * feat: get/set * feat: incr/rename * feat: type * feat: expire * feat: setAdd * feat: setRemove * feat: isSetMember * feat: getSetMembers * feat: setCount, setRemoveRandom * feat: zcard,zcount * feat: sortedSetRank * feat: isSortedSetMember * feat: zincrby * feat: sortedSetLex * feat: processSortedSet * fix: add mising await * feat: debug psql * fix: psql test * fix: test * fix: another test * fix: test fix * fix: psql tests * feat: remove logs * feat: user arrow func use builtin async promises * feat: topic bookmarks * feat: topic.delete * feat: topic.restore * feat: topics.purge * feat: merge * feat: suggested * feat: topics/user.js * feat: topics modules * feat: topics/follow * fix: deprecation msg * feat: fork * feat: topics/posts * feat: sorted/recent * feat: topic/teaser * feat: topics/tools * feat: topics/unread * feat: add back node versions disable deprecation notice wrap async controllers in try/catch * feat: use db directly * feat: promisify in place * fix: redis/psql * feat: deprecation message logs for psql * feat: more logs * feat: more logs * feat: logs again * feat: more logs * fix: call release * feat: restore travis, remove logs * fix: loops * feat: remove .async. usage
6 years ago
assert.ifError(err);
assert.deepStrictEqual(data, ['val1', 'val2', 'val3']);
done();
});
});
});
});
it('should do a bulk remove', async () => {
await db.sortedSetAddBulk([
['bulkRemove1', 1, 'value1'],
['bulkRemove1', 2, 'value2'],
['bulkRemove2', 3, 'value2'],
]);
await db.sortedSetRemoveBulk([
['bulkRemove1', 'value1'],
['bulkRemove1', 'value2'],
['bulkRemove2', 'value2'],
]);
const members = await db.getSortedSetsMembers(['bulkRemove1', 'bulkRemove2']);
assert.deepStrictEqual(members, [[], []]);
});
it('should not remove wrong elements in bulk remove', async () => {
await db.sortedSetAddBulk([
['bulkRemove4', 1, 'value1'],
['bulkRemove4', 2, 'value2'],
['bulkRemove4', 3, 'value4'],
['bulkRemove5', 1, 'value1'],
['bulkRemove5', 2, 'value2'],
['bulkRemove5', 3, 'value3'],
]);
await db.sortedSetRemoveBulk([
['bulkRemove4', 'value1'],
['bulkRemove4', 'value3'],
['bulkRemove5', 'value1'],
['bulkRemove5', 'value4'],
]);
const members = await Promise.all([
db.getSortedSetRange('bulkRemove4', 0, -1),
db.getSortedSetRange('bulkRemove5', 0, -1),
]);
assert.deepStrictEqual(members[0], ['value2', 'value4']);
assert.deepStrictEqual(members[1], ['value2', 'value3']);
});
});
describe('sortedSetsRemove()', () => {
before((done) => {
10 years ago
async.parallel([
async.apply(db.sortedSetAdd, 'sorted4', [1, 2], ['value1', 'value2']),
async.apply(db.sortedSetAdd, 'sorted5', [1, 2], ['value1', 'value3']),
10 years ago
], done);
});
it('should remove element from multiple sorted sets', (done) => {
db.sortedSetsRemove(['sorted4', 'sorted5'], 'value1', function (err) {
assert.equal(err, null);
assert.equal(arguments.length, 1);
db.sortedSetsScore(['sorted4', 'sorted5'], 'value1', (err, scores) => {
assert.equal(err, null);
assert.deepStrictEqual(scores, [null, null]);
done();
});
});
});
});
describe('sortedSetsRemoveRangeByScore()', () => {
before((done) => {
db.sortedSetAdd('sorted6', [1, 2, 3, 4, 5], ['value1', 'value2', 'value3', 'value4', 'value5'], done);
10 years ago
});
it('should remove elements with scores between min max inclusive', (done) => {
db.sortedSetsRemoveRangeByScore(['sorted6'], 4, 5, function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRange('sorted6', 0, -1, (err, values) => {
assert.ifError(err);
10 years ago
assert.deepEqual(values, ['value1', 'value2', 'value3']);
done();
});
});
});
it('should remove elements with if strin score is passed in', (done) => {
db.sortedSetAdd('sortedForRemove', [11, 22, 33], ['value1', 'value2', 'value3'], (err) => {
assert.ifError(err);
db.sortedSetsRemoveRangeByScore(['sortedForRemove'], '22', '22', (err) => {
assert.ifError(err);
db.getSortedSetRange('sortedForRemove', 0, -1, (err, values) => {
assert.ifError(err);
assert.deepEqual(values, ['value1', 'value3']);
done();
});
});
});
});
});
describe('getSortedSetIntersect', () => {
before((done) => {
9 years ago
async.parallel([
function (next) {
db.sortedSetAdd('interSet1', [1, 2, 3], ['value1', 'value2', 'value3'], next);
9 years ago
},
function (next) {
db.sortedSetAdd('interSet2', [4, 5, 6], ['value2', 'value3', 'value5'], next);
},
9 years ago
], done);
});
it('should return the intersection of two sets', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: -1,
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.deepEqual(['value2', 'value3'], data);
done();
});
});
it('should return the intersection of two sets with scores', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: -1,
withScores: true,
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.deepEqual([{ value: 'value2', score: 6 }, { value: 'value3', score: 8 }], data);
9 years ago
done();
});
});
it('should return the reverse intersection of two sets', (done) => {
db.getSortedSetRevIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: 2,
}, (err, data) => {
assert.ifError(err);
assert.deepEqual(['value3', 'value2'], data);
done();
});
});
it('should return the intersection of two sets with scores aggregate MIN', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: -1,
withScores: true,
aggregate: 'MIN',
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.deepEqual([{ value: 'value2', score: 2 }, { value: 'value3', score: 3 }], data);
9 years ago
done();
});
});
it('should return the intersection of two sets with scores aggregate MAX', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: -1,
withScores: true,
aggregate: 'MAX',
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.deepEqual([{ value: 'value2', score: 4 }, { value: 'value3', score: 5 }], data);
9 years ago
done();
});
});
it('should return the intersection with scores modified by weights', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet2'],
start: 0,
stop: -1,
withScores: true,
weights: [1, 0.5],
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.deepEqual([{ value: 'value2', score: 4 }, { value: 'value3', score: 5.5 }], data);
9 years ago
done();
});
});
it('should return empty array if sets do not exist', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet10', 'interSet12'],
start: 0,
stop: -1,
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.equal(data.length, 0);
done();
});
});
it('should return empty array if one set does not exist', (done) => {
9 years ago
db.getSortedSetIntersect({
sets: ['interSet1', 'interSet12'],
start: 0,
stop: -1,
}, (err, data) => {
9 years ago
assert.ifError(err);
assert.equal(data.length, 0);
done();
});
});
it('should return correct results if sorting by different zset', async () => {
await db.sortedSetAdd('bigzset', [1, 2, 3, 4, 5, 6], ['a', 'b', 'c', 'd', 'e', 'f']);
await db.sortedSetAdd('smallzset', [3, 2, 1], ['b', 'e', 'g']);
const data = await db.getSortedSetRevIntersect({
sets: ['bigzset', 'smallzset'],
start: 0,
stop: 19,
weights: [1, 0],
withScores: true,
});
assert.deepStrictEqual(data, [{ value: 'e', score: 5 }, { value: 'b', score: 2 }]);
const data2 = await db.getSortedSetRevIntersect({
sets: ['bigzset', 'smallzset'],
start: 0,
stop: 19,
weights: [0, 1],
withScores: true,
});
assert.deepStrictEqual(data2, [{ value: 'b', score: 3 }, { value: 'e', score: 2 }]);
});
it('should return correct results when intersecting big zsets', async () => {
const scores = [];
const values = [];
for (let i = 0; i < 30000; i++) {
scores.push((i + 1) * 1000);
values.push(String(i + 1));
}
await db.sortedSetAdd('verybigzset', scores, values);
scores.length = 0;
values.length = 0;
for (let i = 15000; i < 45000; i++) {
scores.push((i + 1) * 1000);
values.push(String(i + 1));
}
await db.sortedSetAdd('anotherbigzset', scores, values);
const data = await db.getSortedSetRevIntersect({
sets: ['verybigzset', 'anotherbigzset'],
start: 0,
stop: 3,
weights: [1, 0],
withScores: true,
});
assert.deepStrictEqual(data, [
{ value: '30000', score: 30000000 },
{ value: '29999', score: 29999000 },
{ value: '29998', score: 29998000 },
{ value: '29997', score: 29997000 },
]);
});
9 years ago
});
describe('sortedSetIntersectCard', () => {
before((done) => {
async.parallel([
function (next) {
db.sortedSetAdd('interCard1', [0, 0, 0], ['value1', 'value2', 'value3'], next);
},
function (next) {
db.sortedSetAdd('interCard2', [0, 0, 0], ['value2', 'value3', 'value4'], next);
},
function (next) {
db.sortedSetAdd('interCard3', [0, 0, 0], ['value3', 'value4', 'value5'], next);
},
function (next) {
db.sortedSetAdd('interCard4', [0, 0, 0], ['value4', 'value5', 'value6'], next);
},
], done);
});
it('should return # of elements in intersection', (done) => {
db.sortedSetIntersectCard(['interCard1', 'interCard2', 'interCard3'], (err, count) => {
assert.ifError(err);
assert.strictEqual(count, 1);
done();
});
});
it('should return 0 if intersection is empty', (done) => {
db.sortedSetIntersectCard(['interCard1', 'interCard4'], (err, count) => {
assert.ifError(err);
assert.strictEqual(count, 0);
done();
});
});
});
describe('getSortedSetRangeByLex', () => {
it('should return an array of all values', (done) => {
db.getSortedSetRangeByLex('sortedSetLex', '-', '+', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
done();
});
});
it('should return an array with an inclusive range by default', (done) => {
db.getSortedSetRangeByLex('sortedSetLex', 'a', 'd', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
done();
});
});
it('should return an array with an inclusive range', (done) => {
db.getSortedSetRangeByLex('sortedSetLex', '[a', '[d', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
done();
});
});
it('should return an array with an exclusive range', (done) => {
db.getSortedSetRangeByLex('sortedSetLex', '(a', '(d', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['b', 'c']);
done();
});
});
it('should return an array limited to the first two values', (done) => {
db.getSortedSetRangeByLex('sortedSetLex', '-', '+', 0, 2, (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['a', 'b']);
done();
});
});
it('should return correct result', async () => {
await db.sortedSetAdd('sortedSetLexSearch', [0, 0, 0], ['baris:usakli:1', 'baris usakli:2', 'baris soner:3']);
const query = 'baris:';
const min = query;
const max = query.slice(0, -1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1);
const result = await db.getSortedSetRangeByLex('sortedSetLexSearch', min, max, 0, -1);
assert.deepStrictEqual(result, ['baris:usakli:1']);
});
});
describe('getSortedSetRevRangeByLex', () => {
it('should return an array of all values reversed', (done) => {
db.getSortedSetRevRangeByLex('sortedSetLex', '+', '-', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
done();
});
});
it('should return an array with an inclusive range by default reversed', (done) => {
db.getSortedSetRevRangeByLex('sortedSetLex', 'd', 'a', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
done();
});
});
it('should return an array with an inclusive range reversed', (done) => {
db.getSortedSetRevRangeByLex('sortedSetLex', '[d', '[a', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
done();
});
});
it('should return an array with an exclusive range reversed', (done) => {
db.getSortedSetRevRangeByLex('sortedSetLex', '(d', '(a', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['c', 'b']);
done();
});
});
it('should return an array limited to the first two values reversed', (done) => {
db.getSortedSetRevRangeByLex('sortedSetLex', '+', '-', 0, 2, (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['d', 'c']);
done();
});
});
});
describe('sortedSetLexCount', () => {
it('should return the count of all values', (done) => {
db.sortedSetLexCount('sortedSetLex', '-', '+', (err, data) => {
assert.ifError(err);
assert.strictEqual(data, 4);
done();
});
});
it('should return the count with an inclusive range by default', (done) => {
db.sortedSetLexCount('sortedSetLex', 'a', 'd', (err, data) => {
assert.ifError(err);
assert.strictEqual(data, 4);
done();
});
});
it('should return the count with an inclusive range', (done) => {
db.sortedSetLexCount('sortedSetLex', '[a', '[d', (err, data) => {
assert.ifError(err);
assert.strictEqual(data, 4);
done();
});
});
it('should return the count with an exclusive range', (done) => {
db.sortedSetLexCount('sortedSetLex', '(a', '(d', (err, data) => {
assert.ifError(err);
assert.strictEqual(data, 2);
done();
});
});
});
describe('sortedSetRemoveRangeByLex', () => {
before((done) => {
db.sortedSetAdd('sortedSetLex2', [0, 0, 0, 0, 0, 0, 0], ['a', 'b', 'c', 'd', 'e', 'f', 'g'], done);
});
it('should remove an inclusive range by default', (done) => {
db.sortedSetRemoveRangeByLex('sortedSetLex2', 'a', 'b', function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['c', 'd', 'e', 'f', 'g']);
done();
});
});
});
it('should remove an inclusive range', (done) => {
db.sortedSetRemoveRangeByLex('sortedSetLex2', '[c', '[d', function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['e', 'f', 'g']);
done();
});
});
});
it('should remove an exclusive range', (done) => {
db.sortedSetRemoveRangeByLex('sortedSetLex2', '(e', '(g', function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, ['e', 'g']);
done();
});
});
});
it('should remove all values', (done) => {
db.sortedSetRemoveRangeByLex('sortedSetLex2', '-', '+', function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', (err, data) => {
assert.ifError(err);
assert.deepEqual(data, []);
done();
});
});
});
});
10 years ago
});