ranker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ module Ranker
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Ranking do
4
+ let(:klass) { Ranker::Ranking }
5
+ let(:strategy) { double(:strategy) }
6
+ let(:rankings) { Ranker::Rankings.new(strategy) }
7
+
8
+ describe :properties do
9
+
10
+ describe :percentile do
11
+ let(:rankables) { [1, 2, 3, 4, 5, 5, 1, 2] }
12
+ before {
13
+ rankables.each_with_index { |value, index|
14
+ rankings.create(index + 1, value, [value])
15
+ }
16
+ }
17
+
18
+ context '1st ranking' do
19
+ let(:ranking) { rankings[0] }
20
+ subject { ranking.percentile }
21
+ it { should == 100 }
22
+ end
23
+
24
+ context '2nd ranking' do
25
+ let(:ranking) { rankings[1] }
26
+ subject { ranking.percentile }
27
+ it { should == 87.5 }
28
+ end
29
+
30
+ context '3rd ranking' do
31
+ let(:ranking) { rankings[2] }
32
+ subject { ranking.percentile }
33
+ it { should == 75.0 }
34
+ end
35
+
36
+ context 'last ranking' do
37
+ let(:ranking) { rankings.last }
38
+ subject { ranking.percentile }
39
+ it { should == 12.5 }
40
+ end
41
+
42
+ end # percentile
43
+
44
+ describe :z_score do
45
+ let(:rankables) { [1, 2, 3, 4, 5, 5, 1, 2] }
46
+ before {
47
+ rankables.each_with_index { |value, index|
48
+ rankings.create(index + 1, value, [value])
49
+ }
50
+ }
51
+
52
+ context '1st ranking' do
53
+ let(:ranking) { rankings[0] }
54
+ subject { ranking.z_score }
55
+ it { should == -1.2206826881567392 }
56
+ end
57
+
58
+ context '2nd ranking' do
59
+ let(:ranking) { rankings[1] }
60
+ subject { ranking.z_score }
61
+ it { should == -0.5696519211398116 }
62
+ end
63
+
64
+ context '3rd ranking' do
65
+ let(:ranking) { rankings[2] }
66
+ subject { ranking.z_score }
67
+ it { should == 0.08137884587711594 }
68
+ end
69
+
70
+ context 'last ranking' do
71
+ let(:ranking) { rankings.last }
72
+ subject { ranking.z_score }
73
+ it { should == -0.5696519211398116 }
74
+ end
75
+
76
+ context 'when standard deviation is zero' do
77
+ let(:rankables) { [1, 1, 1, 1, 1, 1, 1] }
78
+
79
+ context '1st ranking' do
80
+ let(:ranking) { rankings[0] }
81
+ subject { ranking.z_score }
82
+ it { should == 0 }
83
+ end
84
+
85
+ end # when standard deviation is zero
86
+
87
+ end # z_score
88
+
89
+ end # properties
90
+
91
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Rankings do
4
+ let(:klass) { Ranker::Rankings }
5
+ let(:strategy) { double(:strategy) }
6
+ let(:rankings) { klass.new(strategy) }
7
+
8
+ describe :properties do
9
+
10
+ describe :mean do
11
+ let(:rankables) { raise NotImplementedError }
12
+ subject { rankings.mean }
13
+ before {
14
+ rankables.each_with_index { |value, index|
15
+ rankings.create(index + 1, value, [value])
16
+ }
17
+ }
18
+
19
+ context 'when there are rankables' do
20
+ let(:rankables) { [1, 2, 3, 4, 5, 5, 1, 2] }
21
+ it { should == 2.875 }
22
+ end
23
+
24
+ context 'when there are no rankables' do
25
+ let(:rankables) { [] }
26
+ it { should be_nan }
27
+ end
28
+
29
+ end # mean
30
+
31
+ describe :standard_deviation do
32
+ let(:rankables) { raise NotImplementedError }
33
+ subject { rankings.standard_deviation }
34
+ before {
35
+ rankables.each_with_index { |value, index|
36
+ rankings.create(index + 1, value, [value])
37
+ }
38
+ }
39
+
40
+ context 'when there are rankables' do
41
+ let(:rankables) { [1, 2, 3, 4, 5, 5, 1, 2] }
42
+ it { should == 1.5360257159305635 }
43
+ end
44
+
45
+ context 'when all rankables are the same' do
46
+ let(:rankables) { [1, 1, 1, 1, 1, 1, 1] }
47
+ it { should == 0 }
48
+ end
49
+
50
+ context 'when there are no rankables' do
51
+ let(:rankables) { [] }
52
+ it { should be_nan }
53
+ end
54
+
55
+ end # standard_deviation
56
+
57
+ end # properties
58
+
59
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Strategies::Dense do
4
+ let(:klass) { Ranker::Strategies::Dense }
5
+
6
+ describe :methods do
7
+
8
+ describe :rank do
9
+ let(:rankables) { raise ArgumentError }
10
+ let(:strategy) { klass.new(rankables) }
11
+ let(:rankings) { strategy.rank }
12
+ subject { rankings }
13
+
14
+ context 'when list of rankables is large' do
15
+ let(:rankables) { [1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 7, 1, 1, 3] }
16
+ it { should have(7).items }
17
+
18
+ context '1st ranking' do
19
+ let(:ranking) { rankings[0] }
20
+ subject { ranking }
21
+ its(:rank) { should == 1 }
22
+ its(:rankables) { should == [7, 7, 7] }
23
+ end
24
+
25
+ context '2nd ranking' do
26
+ let(:ranking) { rankings[1] }
27
+ subject { ranking }
28
+ its(:rank) { should == 2 }
29
+ its(:rankables) { should == [6] }
30
+ end
31
+
32
+ context '3rd ranking' do
33
+ let(:ranking) { rankings[2] }
34
+ subject { ranking }
35
+ its(:rank) { should == 3 }
36
+ its(:rankables) { should == [5] }
37
+ end
38
+
39
+ context '4th ranking' do
40
+ let(:ranking) { rankings[3] }
41
+ subject { ranking }
42
+ its(:rank) { should == 4 }
43
+ its(:rankables) { should == [4] }
44
+ end
45
+
46
+ context '5th ranking' do
47
+ let(:ranking) { rankings[4] }
48
+ subject { ranking }
49
+ its(:rank) { should == 5 }
50
+ its(:rankables) { should == [3, 3, 3] }
51
+ end
52
+
53
+ context '6th ranking' do
54
+ let(:ranking) { rankings[5] }
55
+ subject { ranking }
56
+ its(:rank) { should == 6 }
57
+ its(:rankables) { should == [2] }
58
+ end
59
+
60
+ context '7th ranking' do
61
+ let(:ranking) { rankings[6] }
62
+ subject { ranking }
63
+ its(:rank) { should == 7 }
64
+ its(:rankables) { should == [1, 1, 1, 1] }
65
+ end
66
+
67
+ end # when list of rankables is large
68
+
69
+ context 'when list of rankables is small' do
70
+ let(:rankables) { [3, 2, 2, 1] }
71
+ it { should have(3).items }
72
+
73
+ context '1st ranking' do
74
+ let(:ranking) { rankings[0] }
75
+ subject { ranking }
76
+ its(:rank) { should == 1 }
77
+ its(:rankables) { should == [3] }
78
+ end
79
+
80
+ context '2nd ranking' do
81
+ let(:ranking) { rankings[1] }
82
+ subject { ranking }
83
+ its(:rank) { should == 2 }
84
+ its(:rankables) { should == [2, 2] }
85
+ end
86
+
87
+ context '3rd ranking' do
88
+ let(:ranking) { rankings[2] }
89
+ subject { ranking }
90
+ its(:rank) { should == 3 }
91
+ its(:rankables) { should == [1] }
92
+ end
93
+
94
+ end # list of rankables is small
95
+
96
+ end # rank
97
+
98
+ end # methods
99
+
100
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Strategies::ModifiedCompetition do
4
+ let(:klass) { Ranker::Strategies::ModifiedCompetition }
5
+
6
+ describe :methods do
7
+
8
+ describe :rank do
9
+ let(:rankables) { raise ArgumentError }
10
+ let(:strategy) { klass.new(rankables) }
11
+ let(:rankings) { strategy.rank }
12
+ subject { rankings }
13
+
14
+ context 'when list of rankables is large' do
15
+ let(:rankables) { [1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 7, 1, 1, 3] }
16
+ it { should have(7).items }
17
+
18
+ context '1st ranking' do
19
+ let(:ranking) { rankings[0] }
20
+ subject { ranking }
21
+ its(:rank) { should == 1 }
22
+ its(:rankables) { should == [7, 7, 7] }
23
+ end
24
+
25
+ context '2nd ranking' do
26
+ let(:ranking) { rankings[1] }
27
+ subject { ranking }
28
+ its(:rank) { should == 4 }
29
+ its(:rankables) { should == [6] }
30
+ end
31
+
32
+ context '3rd ranking' do
33
+ let(:ranking) { rankings[2] }
34
+ subject { ranking }
35
+ its(:rank) { should == 5 }
36
+ its(:rankables) { should == [5] }
37
+ end
38
+
39
+ context '4th ranking' do
40
+ let(:ranking) { rankings[3] }
41
+ subject { ranking }
42
+ its(:rank) { should == 6 }
43
+ its(:rankables) { should == [4] }
44
+ end
45
+
46
+ context '5th ranking' do
47
+ let(:ranking) { rankings[4] }
48
+ subject { ranking }
49
+ its(:rank) { should == 9 }
50
+ its(:rankables) { should == [3, 3, 3] }
51
+ end
52
+
53
+ context '6th ranking' do
54
+ let(:ranking) { rankings[5] }
55
+ subject { ranking }
56
+ its(:rank) { should == 10 }
57
+ its(:rankables) { should == [2] }
58
+ end
59
+
60
+ context '7th ranking' do
61
+ let(:ranking) { rankings[6] }
62
+ subject { ranking }
63
+ its(:rank) { should == 14 }
64
+ its(:rankables) { should == [1, 1, 1, 1] }
65
+ end
66
+
67
+ end # when list of rankables is large
68
+
69
+ context 'when list of rankables is small' do
70
+ let(:rankables) { [3, 2, 2, 1] }
71
+ it { should have(3).items }
72
+
73
+ context '1st ranking' do
74
+ let(:ranking) { rankings[0] }
75
+ subject { ranking }
76
+ its(:rank) { should == 1 }
77
+ its(:rankables) { should == [3] }
78
+ end
79
+
80
+ context '2nd ranking' do
81
+ let(:ranking) { rankings[1] }
82
+ subject { ranking }
83
+ its(:rank) { should == 3 }
84
+ its(:rankables) { should == [2, 2] }
85
+ end
86
+
87
+ context '3rd ranking' do
88
+ let(:ranking) { rankings[2] }
89
+ subject { ranking }
90
+ its(:rank) { should == 4 }
91
+ its(:rankables) { should == [1] }
92
+ end
93
+
94
+ end # list of rankables is small
95
+
96
+ end # rank
97
+
98
+ end # methods
99
+
100
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Strategies::Ordinal do
4
+ let(:klass) { Ranker::Strategies::Ordinal }
5
+
6
+ describe :methods do
7
+
8
+ describe :rank do
9
+ let(:rankables) { raise ArgumentError }
10
+ let(:strategy) { klass.new(rankables) }
11
+ let(:rankings) { strategy.rank }
12
+ subject { rankings }
13
+
14
+ context 'when list of rankables is large' do
15
+ let(:rankables) { [1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 7, 1, 1, 3] }
16
+ it { should have(14).items }
17
+
18
+ context '1st ranking' do
19
+ let(:ranking) { rankings[0] }
20
+ subject { ranking }
21
+ its(:rank) { should == 1 }
22
+ its(:rankables) { should == [7] }
23
+ end
24
+
25
+ context '2nd ranking' do
26
+ let(:ranking) { rankings[1] }
27
+ subject { ranking }
28
+ its(:rank) { should == 2 }
29
+ its(:rankables) { should == [7] }
30
+ end
31
+
32
+ context '2nd to last ranking' do
33
+ let(:ranking) { rankings[-2] }
34
+ subject { ranking }
35
+ its(:rank) { should == 13 }
36
+ its(:rankables) { should == [1] }
37
+ end
38
+
39
+ context 'last ranking' do
40
+ let(:ranking) { rankings[-1] }
41
+ subject { ranking }
42
+ its(:rank) { should == 14 }
43
+ its(:rankables) { should == [1] }
44
+ end
45
+
46
+ end # when list of rankables is large
47
+
48
+ context 'when list of rankables is small' do
49
+ let(:rankables) { [3, 2, 2, 1] }
50
+ it { should have(4).items }
51
+
52
+ context '1st ranking' do
53
+ let(:ranking) { rankings[0] }
54
+ subject { ranking }
55
+ its(:rank) { should == 1 }
56
+ its(:rankables) { should == [3] }
57
+ end
58
+
59
+ context '2nd ranking' do
60
+ let(:ranking) { rankings[1] }
61
+ subject { ranking }
62
+ its(:rank) { should == 2 }
63
+ its(:rankables) { should == [2] }
64
+ end
65
+
66
+ context '3rd ranking' do
67
+ let(:ranking) { rankings[2] }
68
+ subject { ranking }
69
+ its(:rank) { should == 3 }
70
+ its(:rankables) { should == [2] }
71
+ end
72
+
73
+ context '4th ranking' do
74
+ let(:ranking) { rankings[3] }
75
+ subject { ranking }
76
+ its(:rank) { should == 4 }
77
+ its(:rankables) { should == [1] }
78
+ end
79
+
80
+ end # list of rankables is small
81
+
82
+ end # rank
83
+
84
+ end # methods
85
+
86
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ranker::Strategies::StandardCompetition do
4
+ let(:klass) { Ranker::Strategies::StandardCompetition }
5
+
6
+ describe :methods do
7
+
8
+ describe :rank do
9
+ let(:rankables) { raise ArgumentError }
10
+ let(:strategy) { klass.new(rankables) }
11
+ let(:rankings) { strategy.rank }
12
+ subject { rankings }
13
+
14
+ context 'when list of rankables is large' do
15
+ let(:rankables) { [1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 7, 1, 1, 3] }
16
+ it { should have(7).items }
17
+
18
+ context '1st ranking' do
19
+ let(:ranking) { rankings[0] }
20
+ subject { ranking }
21
+ its(:rank) { should == 1 }
22
+ its(:score) { should == 7 }
23
+ its(:rankables) { should == [7, 7, 7] }
24
+ end
25
+
26
+ context '2nd ranking' do
27
+ let(:ranking) { rankings[1] }
28
+ subject { ranking }
29
+ its(:rank) { should == 4 }
30
+ its(:score) { should == 6 }
31
+ its(:rankables) { should == [6] }
32
+ end
33
+
34
+ context '3rd ranking' do
35
+ let(:ranking) { rankings[2] }
36
+ subject { ranking }
37
+ its(:rank) { should == 5 }
38
+ its(:score) { should == 5 }
39
+ its(:rankables) { should == [5] }
40
+ end
41
+
42
+ context '4th ranking' do
43
+ let(:ranking) { rankings[3] }
44
+ subject { ranking }
45
+ its(:rank) { should == 6 }
46
+ its(:score) { should == 4 }
47
+ its(:rankables) { should == [4] }
48
+ end
49
+
50
+ context '5th ranking' do
51
+ let(:ranking) { rankings[4] }
52
+ subject { ranking }
53
+ its(:rank) { should == 7 }
54
+ its(:score) { should == 3 }
55
+ its(:rankables) { should == [3, 3, 3] }
56
+ end
57
+
58
+ context '6th ranking' do
59
+ let(:ranking) { rankings[5] }
60
+ subject { ranking }
61
+ its(:rank) { should == 10 }
62
+ its(:score) { should == 2 }
63
+ its(:rankables) { should == [2] }
64
+ end
65
+
66
+ context '7th ranking' do
67
+ let(:ranking) { rankings[6] }
68
+ subject { ranking }
69
+ its(:rank) { should == 11 }
70
+ its(:score) { should == 1 }
71
+ its(:rankables) { should == [1, 1, 1, 1] }
72
+ end
73
+
74
+ end # list of rankables is large
75
+
76
+ context 'when list of rankables is small' do
77
+ let(:rankables) { [3, 2, 2, 1] }
78
+ it { should have(3).items }
79
+
80
+ context '1st ranking' do
81
+ let(:ranking) { rankings[0] }
82
+ subject { ranking }
83
+ its(:rank) { should == 1 }
84
+ its(:rankables) { should == [3] }
85
+ end
86
+
87
+ context '2nd ranking' do
88
+ let(:ranking) { rankings[1] }
89
+ subject { ranking }
90
+ its(:rank) { should == 2 }
91
+ its(:rankables) { should == [2, 2] }
92
+ end
93
+
94
+ context '3rd ranking' do
95
+ let(:ranking) { rankings[2] }
96
+ subject { ranking }
97
+ its(:rank) { should == 4 }
98
+ its(:rankables) { should == [1] }
99
+ end
100
+
101
+ end # list of rankables is small
102
+
103
+ context 'when ranking with a non-default score lambda' do
104
+ let(:value_1) { {:score => 3} }
105
+ let(:value_2) { {:score => 2} }
106
+ let(:value_3) { {:score => 2} }
107
+ let(:value_4) { {:score => 1} }
108
+ let(:rankables) { [value_1, value_2, value_3, value_4] }
109
+ let(:strategy) { klass.new(rankables, :by => lambda { |scorable| scorable[:score] }) }
110
+ it { should have(3).items }
111
+
112
+ context '1st ranking' do
113
+ let(:ranking) { rankings[0] }
114
+ subject { ranking }
115
+ its(:rank) { should == 1 }
116
+ its(:rankables) { should == [value_1] }
117
+ end
118
+
119
+ context '2nd ranking' do
120
+ let(:ranking) { rankings[1] }
121
+ subject { ranking }
122
+ its(:rank) { should == 2 }
123
+ its(:rankables) { should == [value_2, value_3] }
124
+ end
125
+
126
+ context '3rd ranking' do
127
+ let(:ranking) { rankings[2] }
128
+ subject { ranking }
129
+ its(:rank) { should == 4 }
130
+ its(:rankables) { should == [value_4] }
131
+ end
132
+
133
+ end # when ranking with a block
134
+
135
+ end # rank
136
+
137
+ end # methods
138
+
139
+ end