Skip to content
This repository has been archived by the owner on Aug 25, 2023. It is now read-only.

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
hdachev committed Apr 15, 2012
1 parent 3018697 commit 7429920
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 14 deletions.
46 changes: 33 additions & 13 deletions lib/backend.js
Expand Up @@ -117,16 +117,20 @@ var slice = function ( arr, start, stop, asCount )
if ( arr.slice )
{
var n = arr.length;
if ( start < 0 )
start = n + start;
if ( asCount )
stop += start;

{
if ( start < 0 )
{
start = 0; // Redis is inconsistent about this, ZRANGEBYSCORE will return an empty multibulk on negative offset
stop = 0; // whilst SORT will return as if the offset was 0. Best to lint these away with client-side errors.
}
else if ( stop < 0 ) stop = n;
else stop += start;
}
else
{
if ( stop < 0 )
stop = n + stop;

if ( start < 0 ) start = n + start;
if ( stop < 0 ) stop = n + stop;
stop ++;
}

Expand All @@ -153,7 +157,7 @@ var str2float = function ( string )
var str2int = function ( string )
{
var value = str2float ( string );
if ( value instanceof ERROR || value % 1 ) return BAD_INT;
if ( value instanceof ERROR || value % 1 !== 0 ) return BAD_INT;
return value;
};

Expand Down Expand Up @@ -799,6 +803,16 @@ exports.Backend.prototype =

//// Lists, non-blocking.

lStore : function ( key, values )
{
//// Only used in SORT.

if ( values.length )
return this.setKey ( key, new LIST ( values ) );
else
return this.setKey ( key, null );
},

LINDEX : function ( key, index )
{
var K = this.getKey ( LIST, key );
Expand Down Expand Up @@ -1350,12 +1364,12 @@ exports.Backend.prototype =

sStore : function ( key, members )
{
var K = new SET ({});
var i, n = members.length;
var K, i, n = members.length;
if ( n ) K = new SET ({});
for ( i = 0; i < n; i ++ )
K.value [ members [ i ] ] = true;

return this.setKey ( key, K );
return this.setKey ( key, K || null );
},

sStoreOp : function ( op, args )
Expand Down Expand Up @@ -1763,10 +1777,13 @@ exports.Backend.prototype =
{
store = args [ 1 ];
if ( typeof store !== 'string' ) return BAD_SYNTAX;
args.splice ( 0, 1 );
args.splice ( 0, 2 );
}

if ( args.length ) return BAD_ARGS;
//// Redis appears to accept params in any order,
//// needs some tests before allowing this here.

if ( args.length ) return BAD_SYNTAX;

//// Collect data.

Expand Down Expand Up @@ -1824,6 +1841,9 @@ exports.Backend.prototype =

//// Limit.

if ( parseInt ( offset ) < 0 )
offset = '0'; // SORT treats negative offset limit differently from other redis commands.

if ( limit ) data = slice ( data, offset, count, true );

//// Format.
Expand Down
8 changes: 8 additions & 0 deletions main.js
@@ -1,5 +1,13 @@


/**
TODO:
- lint negative count and offset LIMITs away,
SORT and ZRANGEBYSCORE treat them differently, so it's just confusing and a bad practice.
**/

var index = require ( "redis" ),
Backend = require ( "./lib/backend" ).Backend,
Connection = require ( "./lib/connection" ).Connection,
Expand Down
31 changes: 30 additions & 1 deletion test.js
Expand Up @@ -108,6 +108,10 @@ process.stdout.write ( 'testing fakeredis ...\n\n' );
redis.SISMEMBER ( "nonex", "what", test ( "SISMEMBER nonex", null, 0 ) );
redis.SISMEMBER ( "hello", "what", test ( "SISMEMBER bad", BAD_TYPE, null ) );

redis.SADD ( "otherset", "whatever" );
redis.SINTERSTORE ( "nothing", "otherset", "output", test ( "SINTERSTORE empty out", null, 0 ) );
redis.TYPE ( "nothing", test ( "SINTERSTORE empty out / TYPE", null, "none" ) );

redis.DEL ( "set3" );
redis.SPOP ( "set3", test ( "SPOP nothing", null, null ) );
redis.SINTER ( "output", function ( err, members )
Expand Down Expand Up @@ -141,7 +145,13 @@ process.stdout.write ( 'testing fakeredis ...\n\n' );
redis.ZREVRANGEBYSCORE ( "myzset", 2, "(1", test ( "ZREVRANGEBYSCORE soso", null, [ "two" ] ) );
redis.ZREVRANGEBYSCORE ( "myzset", "(2", "(1", test ( "ZREVRANGEBYSCORE excl", null, [] ) );
redis.ZADD ( "myzset", 1.5, "one.five" );
redis.ZRANGEBYSCORE ( "myzset", "-inf", "+inf", "WITHSCORES", "LIMIT", 1, 2, test ( "ZREVRANGEBYSCORE with limit", null, [ "one.five", "1.5", "two", "2" ] ) );
redis.ZRANGEBYSCORE ( "myzset", "-inf", "+inf", "WITHSCORES", "LIMIT", 1, 2, test ( "ZREVRANGEBYSCORE limit", null, [ "one.five", "1.5", "two", "2" ] ) );

//// Negative offset behaves differently here and in SORT

redis.ZRANGEBYSCORE ( "myzset", "-inf", "+inf", "WITHSCORES", "LIMIT", -1, 2, test ( "ZREVRANGEBYSCORE limit +negoffset", null, [] ) );
redis.ZRANGEBYSCORE ( "myzset", "-inf", "+inf", "WITHSCORES", "LIMIT", 1, -11, test ( "ZREVRANGEBYSCORE limit +negcount", null, [ "one.five", "1.5", "two", "2", "three", "3" ] ) );

redis.ZCOUNT ( "myzset", "(1", 2, test ( "ZCOUNT", null, 2 ) );
redis.SET ( "wrong", "indeed" );
redis.ZREMRANGEBYRANK ( "wrong", 0, -1, test ( "ZREMRANGEBYRANK badkey", BAD_TYPE, null ) );
Expand Down Expand Up @@ -228,6 +238,10 @@ process.stdout.write ( 'testing fakeredis ...\n\n' );
redis.ZRANGE ( "lexi", 0, -1, test ( "lexicographic zset member sort", null, [ "AAA", "BBB", "XXX", "YYY", "ZZZ", "FFF" ] ) );
redis.ZREVRANGE ( "lexi", 0, -1, test ( "lexicographic zset member sort", null, [ "FFF", "ZZZ", "YYY", "XXX", "BBB", "AAA" ] ) );

redis.ZADD ( "otherzset", 100, "whatever" );
redis.ZINTERSTORE ( "nothing", 2, "lexi", "otherzset", test ( "ZINTERSTORE empty out", null, 0 ) );
redis.TYPE ( "nothing", test ( "ZINTERSTORE empty out / TYPE", null, "none" ) );



//// Hashes.
Expand Down Expand Up @@ -780,8 +794,23 @@ process.stdout.write ( 'testing fakeredis ...\n\n' );
redis.SORT ( "set", "by", "o*->age", "get", "#", "get", "o*->name", test ( "SORT set by+get, h*->f", null, result ) );
redis.SORT ( "zset", "by", "o*->age", "get", "#", "get", "o*->name", test ( "SORT zset by+get, h*->f", null, result ) );

//// Negative offset behaves differently here and in ZRANGEBYSCORE

redis.SORT ( "list", "by", "o*->age", "limit", 0, 2, "get", "#", "get", "o*->name", test ( "SORT limit", null, result.slice ( 0, 4 ) ) );
redis.SORT ( "list", "by", "o*->age", "limit", 2, 4, "get", "#", "get", "o*->name", test ( "SORT limit +offset", null, result.slice ( 4 ) ) );
redis.SORT ( "list", "by", "o*->age", "limit", 2, -10, "get", "#", "get", "o*->name", test ( "SORT limit +negcount", null, result.slice ( 4 ) ) );
redis.SORT ( "list", "by", "o*->age", "limit", -2, 2, "get", "#", "get", "o*->name", test ( "SORT limit +negoffset+negcount", null, result.slice ( 0, 4 ) ) );

redis.HSET ( "o11", "age", "not-a-number" );
redis.SORT ( "list", "by", "o*->age", "get", "#", "get", "o*->name", test ( "SORT by+scorefail", BAD_SORT, null ) );

//// Edge cases.

redis.SORT ( "nonex", test ( "SORT nonex", null, [] ) );
redis.SORT ( "nonex", "by", "o*->age", test ( "SORT nonex+by", null, [] ) );
redis.SORT ( "nonex", "by", "o*->age", "get", "#", "get", "o*->name", test ( "SORT nonex+by+get", null, [] ) );
redis.SET ( "hello", "world" );
redis.SORT ( "hello", test ( "SORT bad type", BAD_TYPE, null ) );
}
() );

Expand Down

0 comments on commit 7429920

Please sign in to comment.