commendo 1.2.4 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/bin/commendo-create-mysql-db +3 -0
- data/bin/commendo-create.sql +99 -0
- data/bin/commendo-load-tsv +11 -5
- data/bin/commendo-load-tsv-mysql.rb +43 -0
- data/bin/commendo-time-mysql.rb +31 -0
- data/commendo.gemspec +4 -2
- data/lib/commendo.rb +24 -0
- data/lib/commendo/configuration.rb +25 -0
- data/lib/commendo/content_set.rb +13 -182
- data/lib/commendo/mysql-backed/content_set.rb +152 -0
- data/lib/commendo/mysql-backed/tag_set.rb +81 -0
- data/lib/commendo/mysql-backed/weighted_group.rb +40 -0
- data/lib/commendo/redis-backed/content_set.rb +194 -0
- data/lib/commendo/{pair_comparison.lua → redis-backed/pair_comparison.lua} +0 -0
- data/lib/commendo/{similarity.lua → redis-backed/similarity.lua} +0 -0
- data/lib/commendo/redis-backed/tag_set.rb +54 -0
- data/lib/commendo/redis-backed/weighted_group.rb +54 -0
- data/lib/commendo/tag_set.rb +6 -42
- data/lib/commendo/version.rb +1 -1
- data/lib/commendo/weighted_group.rb +7 -41
- data/lib/mysql2/client.rb +17 -0
- data/model 2.mwb +0 -0
- data/sql_model.mwb +0 -0
- data/test/configuration_test.rb +71 -0
- data/test/mysql_content_set_test.rb +40 -0
- data/test/mysql_tag_set_test.rb +34 -0
- data/test/mysql_weighted_group_test.rb +54 -0
- data/test/redis_content_set_test.rb +57 -0
- data/test/redis_tag_set_test.rb +31 -0
- data/test/redis_weighted_group_test.rb +49 -0
- data/test/tests_for_content_sets.rb +379 -0
- data/test/tests_for_tag_sets.rb +130 -0
- data/test/tests_for_weighted_groups.rb +106 -0
- metadata +72 -12
- data/test/content_set_test.rb +0 -408
- data/test/tag_set_test.rb +0 -128
- data/test/weighted_group_test.rb +0 -191
data/test/tag_set_test.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
gem 'minitest'
|
2
|
-
require 'minitest/autorun'
|
3
|
-
require 'minitest/pride'
|
4
|
-
require 'minitest/mock'
|
5
|
-
require 'mocha/setup'
|
6
|
-
require 'commendo'
|
7
|
-
|
8
|
-
module Commendo
|
9
|
-
|
10
|
-
class TagSetTest < Minitest::Test
|
11
|
-
|
12
|
-
def setup
|
13
|
-
@redis = Redis.new(db: 15)
|
14
|
-
@redis.flushdb
|
15
|
-
@ts = TagSet.new(@redis, 'TagSetTest')
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_adds_tags_for_resource
|
19
|
-
assert_equal [], @ts.get(1)
|
20
|
-
@ts.add(1, 'foo', 'bar', 'baz')
|
21
|
-
assert_equal %w(bar baz foo), @ts.get(1)
|
22
|
-
@ts.add(1, 'qux', 'qip')
|
23
|
-
assert_equal %w(bar baz foo qip qux), @ts.get(1)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_empty?
|
27
|
-
assert @ts.respond_to? :empty?
|
28
|
-
assert @ts.empty?
|
29
|
-
@ts.add(1, 'qux', 'qip')
|
30
|
-
refute @ts.empty?
|
31
|
-
@ts.delete(1)
|
32
|
-
assert @ts.empty?
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_sets_tags_for_resource
|
36
|
-
assert_equal [], @ts.get(1)
|
37
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
38
|
-
assert_equal %w(bar baz foo), @ts.get(1)
|
39
|
-
@ts.set(1, 'qux', 'qip')
|
40
|
-
assert_equal %w(qip qux), @ts.get(1)
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_sets_tags_when_empty
|
44
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
45
|
-
@ts.set(2, 'qux', 'qip')
|
46
|
-
assert_equal %w(bar baz foo), @ts.get(1)
|
47
|
-
assert_equal %w(qip qux), @ts.get(2)
|
48
|
-
@ts.set(1, *[])
|
49
|
-
assert_equal [], @ts.get(1)
|
50
|
-
assert_equal %w(qip qux), @ts.get(2)
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_deletes_all_tags_for_resource
|
54
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
55
|
-
@ts.set(2, 'qux', 'qip')
|
56
|
-
assert_equal %w(bar baz foo), @ts.get(1)
|
57
|
-
assert_equal %w(qip qux), @ts.get(2)
|
58
|
-
@ts.delete(1)
|
59
|
-
assert_equal [], @ts.get(1)
|
60
|
-
assert_equal %w(qip qux), @ts.get(2)
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_deletes_given_tags_for_resource
|
64
|
-
assert_equal [], @ts.get(1)
|
65
|
-
@ts.set(1, 'foo', 'bar', 'baz', 'qux', 'qip')
|
66
|
-
@ts.delete(1, 'qux', 'qip')
|
67
|
-
assert_equal %w(bar baz foo), @ts.get(1)
|
68
|
-
end
|
69
|
-
|
70
|
-
def test_matches_tags
|
71
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
72
|
-
@ts.set(2, 'qux', 'qip')
|
73
|
-
|
74
|
-
assert @ts.matches(1, ['foo'])
|
75
|
-
assert @ts.matches(1, %w(bar baz))
|
76
|
-
assert @ts.matches(1, %w(bar baz foo))
|
77
|
-
refute @ts.matches(1, ['qux'])
|
78
|
-
refute @ts.matches(1, ['qip'])
|
79
|
-
|
80
|
-
refute @ts.matches(2, ['foo'])
|
81
|
-
refute @ts.matches(2, %w(bar baz))
|
82
|
-
refute @ts.matches(2, %w(bar baz foo))
|
83
|
-
assert @ts.matches(2, %w(qux qip))
|
84
|
-
assert @ts.matches(2, ['qux'])
|
85
|
-
assert @ts.matches(2, ['qip'])
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_matches_exclude_tags
|
89
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
90
|
-
@ts.set(2, 'qux', 'qip')
|
91
|
-
|
92
|
-
refute @ts.matches(1, nil, ['foo'])
|
93
|
-
refute @ts.matches(1, [], ['foo'])
|
94
|
-
refute @ts.matches(1, [], %w(bar baz))
|
95
|
-
refute @ts.matches(1, [], %w(bar baz foo))
|
96
|
-
assert @ts.matches(1, [], ['qux'])
|
97
|
-
assert @ts.matches(1, [], ['qip'])
|
98
|
-
|
99
|
-
assert @ts.matches(2, nil, ['foo'])
|
100
|
-
assert @ts.matches(2, [], ['foo'])
|
101
|
-
assert @ts.matches(2, [], %w(bar baz))
|
102
|
-
assert @ts.matches(2, [], %w(bar baz foo))
|
103
|
-
refute @ts.matches(2, [], %w(qux qip))
|
104
|
-
refute @ts.matches(2, [], ['qux'])
|
105
|
-
refute @ts.matches(2, [], ['qip'])
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_matches_include_and_exclude_tags
|
109
|
-
@ts.set(1, 'foo', 'bar', 'baz')
|
110
|
-
@ts.set(2, 'qux', 'qip')
|
111
|
-
|
112
|
-
refute @ts.matches(1, ['foo'], ['bar'])
|
113
|
-
refute @ts.matches(1, ['bar'], ['foo'])
|
114
|
-
|
115
|
-
assert @ts.matches(1, ['foo'], [])
|
116
|
-
assert @ts.matches(1, ['foo'], nil)
|
117
|
-
assert @ts.matches(1, ['foo'], ['qux'])
|
118
|
-
|
119
|
-
assert @ts.matches(2, ['qip'], ['foo'])
|
120
|
-
assert @ts.matches(2, ['qux'], %w(bar baz))
|
121
|
-
assert @ts.matches(2, ['qip'], %w(bar baz foo))
|
122
|
-
refute @ts.matches(2, ['qip'], %w(qux qip))
|
123
|
-
refute @ts.matches(2, ['qip'], ['qux'])
|
124
|
-
refute @ts.matches(2, ['qux'], ['qip'])
|
125
|
-
end
|
126
|
-
|
127
|
-
end
|
128
|
-
end
|
data/test/weighted_group_test.rb
DELETED
@@ -1,191 +0,0 @@
|
|
1
|
-
gem 'minitest'
|
2
|
-
require 'minitest/autorun'
|
3
|
-
require 'minitest/pride'
|
4
|
-
require 'minitest/mock'
|
5
|
-
require 'mocha/setup'
|
6
|
-
require 'commendo'
|
7
|
-
|
8
|
-
module Commendo
|
9
|
-
|
10
|
-
class WeightedGroupTest < Minitest::Test
|
11
|
-
|
12
|
-
def setup
|
13
|
-
super
|
14
|
-
@redis ||= Redis.new(db: 15)
|
15
|
-
@redis.flushdb
|
16
|
-
@tag_set = TagSet.new(@redis, 'CommendoTests:Tags')
|
17
|
-
@cs1 = ContentSet.new(@redis, 'CommendoTests:ContentSet1', @tag_set)
|
18
|
-
@cs2 = ContentSet.new(@redis, 'CommendoTests:ContentSet2', @tag_set)
|
19
|
-
@cs3 = ContentSet.new(@redis, 'CommendoTests:ContentSet3', @tag_set)
|
20
|
-
(3..23).each do |group|
|
21
|
-
(3..23).each do |res|
|
22
|
-
@cs1.add_by_group(group, res) if res.modulo(group).zero? && res.modulo(2).zero?
|
23
|
-
@cs2.add_by_group(group, res) if res.modulo(group).zero? && res.modulo(3).zero?
|
24
|
-
@cs3.add_by_group(group, res) if res.modulo(group).zero? && res.modulo(6).zero?
|
25
|
-
@tag_set.add(res, 'mod3') if res.modulo(3).zero?
|
26
|
-
@tag_set.add(res, 'mod4') if res.modulo(4).zero?
|
27
|
-
@tag_set.add(res, 'mod5') if res.modulo(5).zero?
|
28
|
-
@tag_set.add(res, 'mod7') if res.modulo(7).zero?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
[@cs1, @cs2, @cs3].each { |cs| cs.calculate_similarity }
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_calls_each_content_set
|
35
|
-
weighted_group = WeightedGroup.new(
|
36
|
-
@redis,
|
37
|
-
'CommendoTests:WeightedGroup',
|
38
|
-
{cs: @cs1, weight: 1.0},
|
39
|
-
{cs: @cs2, weight: 10.0},
|
40
|
-
{cs: @cs3, weight: 100.0}
|
41
|
-
)
|
42
|
-
expected = [
|
43
|
-
{resource: '6', similarity: 74.037},
|
44
|
-
{resource: '12', similarity: 55.5},
|
45
|
-
{resource: '9', similarity: 6.67},
|
46
|
-
{resource: '3', similarity: 4.0},
|
47
|
-
{resource: '21', similarity: 2.86},
|
48
|
-
{resource: '15', similarity: 2.86}
|
49
|
-
]
|
50
|
-
assert_equal expected, weighted_group.similar_to(18)
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_calls_each_content_set_with_limits
|
54
|
-
weighted_group = WeightedGroup.new(
|
55
|
-
@redis,
|
56
|
-
'CommendoTests:WeightedGroup',
|
57
|
-
{cs: @cs1, weight: 1.0},
|
58
|
-
{cs: @cs2, weight: 10.0},
|
59
|
-
{cs: @cs3, weight: 100.0}
|
60
|
-
)
|
61
|
-
expected = [
|
62
|
-
{resource: '6', similarity: 74.037},
|
63
|
-
{resource: '12', similarity: 55.5},
|
64
|
-
{resource: '9', similarity: 6.67},
|
65
|
-
{resource: '3', similarity: 4.0},
|
66
|
-
{resource: '21', similarity: 2.86},
|
67
|
-
{resource: '15', similarity: 2.86}
|
68
|
-
]
|
69
|
-
assert_equal expected[0..0], weighted_group.similar_to(18, 1)
|
70
|
-
assert_equal expected[0..2], weighted_group.similar_to(18, 3)
|
71
|
-
assert_equal expected, weighted_group.similar_to(18, 6)
|
72
|
-
assert_equal expected, weighted_group.similar_to(18, 99)
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_filters_include_recommendations
|
76
|
-
weighted_group = WeightedGroup.new(
|
77
|
-
@redis,
|
78
|
-
'CommendoTests:WeightedGroup',
|
79
|
-
{cs: @cs1, weight: 1.0},
|
80
|
-
{cs: @cs2, weight: 10.0},
|
81
|
-
{cs: @cs3, weight: 100.0}
|
82
|
-
)
|
83
|
-
expected = [{resource: '15', similarity: 2.86}]
|
84
|
-
weighted_group.tag_set = @tag_set
|
85
|
-
assert_equal expected, weighted_group.filtered_similar_to(18, include: ['mod5'])
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_filters_exclude_recommendations
|
89
|
-
weighted_group = WeightedGroup.new(
|
90
|
-
@redis,
|
91
|
-
'CommendoTests:WeightedGroup',
|
92
|
-
{cs: @cs1, weight: 1.0},
|
93
|
-
{cs: @cs2, weight: 10.0},
|
94
|
-
{cs: @cs3, weight: 100.0}
|
95
|
-
)
|
96
|
-
expected = [
|
97
|
-
{resource: '6', similarity: 74.037},
|
98
|
-
{resource: '12', similarity: 55.5},
|
99
|
-
{resource: '9', similarity: 6.67},
|
100
|
-
{resource: '3', similarity: 4.0}
|
101
|
-
]
|
102
|
-
weighted_group.tag_set = @tag_set
|
103
|
-
assert_equal expected, weighted_group.filtered_similar_to(18, exclude: ['mod5', 'mod7'])
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_filters_include_and_exclude_recommendations
|
107
|
-
weighted_group = WeightedGroup.new(
|
108
|
-
@redis,
|
109
|
-
'CommendoTests:WeightedGroup',
|
110
|
-
{cs: @cs1, weight: 100.0},
|
111
|
-
{cs: @cs2, weight: 10.0},
|
112
|
-
{cs: @cs3, weight: 1.0}
|
113
|
-
)
|
114
|
-
expected = [
|
115
|
-
{resource: '16', similarity: 80.0},
|
116
|
-
{resource: '4', similarity: 66.7},
|
117
|
-
{resource: '12', similarity: 33.3}
|
118
|
-
]
|
119
|
-
weighted_group.tag_set = @tag_set
|
120
|
-
assert_equal expected, weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'])
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_filters_include_and_exclude_recommendations_and_limits
|
124
|
-
weighted_group = WeightedGroup.new(
|
125
|
-
@redis,
|
126
|
-
'CommendoTests:WeightedGroup',
|
127
|
-
{cs: @cs1, weight: 100.0},
|
128
|
-
{cs: @cs2, weight: 10.0},
|
129
|
-
{cs: @cs3, weight: 1.0}
|
130
|
-
)
|
131
|
-
expected = [
|
132
|
-
{resource: '16', similarity: 80.0},
|
133
|
-
{resource: '4', similarity: 66.7},
|
134
|
-
{resource: '12', similarity: 33.3}
|
135
|
-
]
|
136
|
-
weighted_group.tag_set = @tag_set
|
137
|
-
assert_equal expected[0..0], weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'], limit: 1)
|
138
|
-
assert_equal expected[0..1], weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'], limit: 2)
|
139
|
-
assert_equal expected, weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'], limit: 3)
|
140
|
-
assert_equal expected, weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'], limit: 99)
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_similar_to_mutliple_items
|
144
|
-
weighted_group = WeightedGroup.new(
|
145
|
-
@redis,
|
146
|
-
'CommendoTests:WeightedGroup',
|
147
|
-
{cs: @cs1, weight: 100.0},
|
148
|
-
{cs: @cs2, weight: 10.0},
|
149
|
-
{cs: @cs3, weight: 1.0}
|
150
|
-
)
|
151
|
-
expected = [
|
152
|
-
{resource: '12', similarity: 118.037},
|
153
|
-
{resource: '18', similarity: 78.037},
|
154
|
-
{resource: '8', similarity: 66.7},
|
155
|
-
{resource: '16', similarity: 50.0},
|
156
|
-
{resource: '20', similarity: 40.0},
|
157
|
-
{resource: '9', similarity: 11.67},
|
158
|
-
{resource: '21', similarity: 9.0},
|
159
|
-
{resource: '15', similarity: 9.0},
|
160
|
-
{resource: '6', similarity: 6.67},
|
161
|
-
{resource: '3', similarity: 6.67}
|
162
|
-
]
|
163
|
-
weighted_group.tag_set = @tag_set
|
164
|
-
assert_equal expected, weighted_group.similar_to([3,4,5,6,7])
|
165
|
-
end
|
166
|
-
|
167
|
-
def test_filtered_similar_to_mutliple_items
|
168
|
-
weighted_group = WeightedGroup.new(
|
169
|
-
@redis,
|
170
|
-
'CommendoTests:WeightedGroup',
|
171
|
-
{cs: @cs1, weight: 100.0},
|
172
|
-
{cs: @cs2, weight: 10.0},
|
173
|
-
{cs: @cs3, weight: 1.0}
|
174
|
-
)
|
175
|
-
expected = [
|
176
|
-
{resource: '12', similarity: 118.037},
|
177
|
-
{resource: '8', similarity: 66.7},
|
178
|
-
{resource: '16', similarity: 50.0},
|
179
|
-
]
|
180
|
-
weighted_group.tag_set = @tag_set
|
181
|
-
assert_equal expected, weighted_group.filtered_similar_to([3,4,5,6,7], include: ['mod4'], exclude: ['mod5'])
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_precalculates
|
185
|
-
skip
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|