use strict;
use warnings;
use utf8;
use Test::More;
use Test::RedisServer;
use Redis;
use Redis::LeaderBoard;
my $redis_server = eval { Test::RedisServer->new }
or plan skip_all => 'redis-server is required in PATH to run this test';
my $redis = Redis->new($redis_server->connect_info);
subtest 'get incr set' => sub {
my $redis_ranking = Redis::LeaderBoard->new(
key => 'test1',
redis => $redis,
);
$redis_ranking->set_score(one => 10);
is $redis_ranking->incr_score(one => 10), 20;
is $redis_ranking->get_score('one'), 20;
is $redis_ranking->decr_score(one => 3), 17;
is $redis_ranking->get_score('one'), 17;
$redis_ranking->set_score(one => 5);
is $redis_ranking->get_score('one'), 5;
};
subtest 'empty' => sub {
my $redis_ranking = Redis::LeaderBoard->new(
key => 'empty',
redis => $redis,
);
my ($rank, $score) = $redis_ranking->get_rank_with_score('one');
ok !$rank;
ok !$score;
ok !$redis_ranking->get_score('one');
ok !$redis_ranking->get_rank('one');
};
subtest 'get_rank_with_score' => sub {
my $redis_ranking = Redis::LeaderBoard->new(
key => 'test_asc',
redis => $redis,
);
my @scores = (
[1, one => 100],
[2, two => 50],
[2, two2 => 50],
[4, four => 30],
[5, five => 10],
[6, six => 8],
[6, six2 => 8],
[6, six3 => 8],
[9, nine => 1],
);
for my $score (@scores) {
my ($rank, $member, $score) = @$score;
$redis_ranking->set_score($member => $score);
}
for my $score (@scores) {
my ($rank, $member, $score) = @$score;
is_deeply [$redis_ranking->get_rank_with_score($member)], [$rank, $score];
is $redis_ranking->get_rank($member), $rank;
}
};
subtest 'get_rank_with_score_desc' => sub {
my $redis_ranking = Redis::LeaderBoard->new(
key => 'test_desc',
redis => $redis,
order => 'asc',
);
my @scores = (
[1, one => -11],
[2, two => 11],
[2, two2 => 11],
[4, four => 20],
[5, five => 30],
[6, six => 44],
[6, six2 => 44],
[6, six3 => 44],
[9, nine => 80],
);
my @flat_scores = map { ($_->[1], $_->[2]) } @scores;
$redis_ranking->set_score(@flat_scores);
for my $score (@scores) {
my ($rank, $member, $score) = @$score;
is_deeply [$redis_ranking->get_rank_with_score($member)], [$rank, $score];
is $redis_ranking->get_rank($member), $rank;
}
is_deeply $redis_ranking->rankings(limit => 2, offset => 3), [{
member => 'four',
rank => 4,
score => 20,
}, {
member => 'five',
rank => 5,
score => 30,
}];
};
subtest 'get_rank_with_score_same' => sub {
my $redis_ranking = Redis::LeaderBoard->new(
key => 'test_same1',
redis => $redis,
);
my @scores = (
[1, one => 100],
[1, one2 => 100],
[3, three => 50],
[4, four => 30],
);
for my $score (@scores) {
my ($rank, $member, $score) = @$score;
$redis_ranking->set_score($member => $score);
}
is_deeply [$redis_ranking->get_rank_with_score('one')], [1, 100];
is_deeply [$redis_ranking->get_rank_with_score('one2')], [1, 100];
is_deeply [$redis_ranking->get_rank_with_score('three')], [3, 50];
$redis_ranking->incr_score(one => 1);
is_deeply [$redis_ranking->get_rank_with_score('one')], [1, 101];
is_deeply [$redis_ranking->get_rank_with_score('one2')], [2, 100];
is $redis_ranking->member_count, 4;
subtest rankings => sub {
is_deeply( $redis_ranking->rankings, [{
member => 'one',
rank => 1,
score => 101,
}, {
member => 'one2',
rank => 2,
score => 100,
}, {
member => 'three',
rank => 3,
score => 50,
}, {
member => 'four',
rank => 4,
score => 30,
},]);
is_deeply( $redis_ranking->rankings(limit => 2), [{
member => 'one',
rank => 1,
score => 101,
}, {
member => 'one2',
rank => 2,
score => 100,
},]);
is_deeply( $redis_ranking->rankings(limit => 1, offset => 2), [{
member => 'three',
rank => 3,
score => 50,
},]);
is_deeply( $redis_ranking->rankings(limit => 10, offset => 2), [{
member => 'three',
rank => 3,
score => 50,
}, {
member => 'four',
rank => 4,
score => 30,
},]);
is_deeply( $redis_ranking->rankings(offset => 4), []);
};
$redis_ranking->remove('one2');
is_deeply [$redis_ranking->get_rank_with_score('three')], [2, 50];
};
done_testing;