picky 3.0.1 → 3.1.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.
Files changed (106) hide show
  1. data/lib/picky/application.rb +12 -12
  2. data/lib/picky/backends/backend.rb +17 -0
  3. data/lib/picky/{backend → backends}/file/basic.rb +1 -1
  4. data/lib/picky/{backend → backends}/file/json.rb +1 -1
  5. data/lib/picky/{backend → backends}/file/marshal.rb +1 -1
  6. data/lib/picky/{backend → backends}/file/text.rb +1 -1
  7. data/lib/picky/backends/memory.rb +53 -0
  8. data/lib/picky/{backend → backends}/redis/basic.rb +9 -14
  9. data/lib/picky/backends/redis/float_hash.rb +26 -0
  10. data/lib/picky/{backend → backends}/redis/list_hash.rb +7 -11
  11. data/lib/picky/{backend → backends}/redis/string_hash.rb +7 -11
  12. data/lib/picky/backends/redis.rb +87 -0
  13. data/lib/picky/bundle.rb +107 -11
  14. data/lib/picky/category.rb +5 -5
  15. data/lib/picky/index.rb +329 -0
  16. data/lib/picky/index_indexed.rb +31 -0
  17. data/lib/picky/index_indexing.rb +161 -0
  18. data/lib/picky/indexed/bundle.rb +112 -0
  19. data/lib/picky/indexed/wrappers/exact_first.rb +1 -1
  20. data/lib/picky/indexers/parallel.rb +2 -1
  21. data/lib/picky/indexers/serial.rb +2 -1
  22. data/lib/picky/indexes_indexing.rb +1 -1
  23. data/lib/picky/indexing/bundle.rb +188 -0
  24. data/lib/picky/indexing/wrappers/category/location.rb +1 -1
  25. data/lib/picky/interfaces/live_parameters.rb +8 -8
  26. data/lib/picky/loader.rb +24 -38
  27. data/lib/picky/migrations/from_30_to_31.rb +61 -0
  28. data/lib/picky/query/allocation.rb +10 -5
  29. data/lib/picky/query/combinations.rb +70 -0
  30. data/lib/picky/query/indexes.rb +8 -7
  31. data/lib/picky/query/indexes_check.rb +47 -0
  32. data/lib/picky/query/token.rb +16 -29
  33. data/lib/picky/query/tokens.rb +4 -20
  34. data/lib/picky/search.rb +51 -58
  35. data/lib/picky/tokenizer.rb +231 -0
  36. data/lib/picky/tokenizers/location.rb +1 -1
  37. data/lib/tasks/try.rake +4 -12
  38. data/lib/tasks/try.rb +37 -0
  39. data/spec/lib/application_spec.rb +5 -5
  40. data/spec/lib/{backend → backends}/file/basic_spec.rb +2 -2
  41. data/spec/lib/{backend → backends}/file/json_spec.rb +2 -2
  42. data/spec/lib/{backend → backends}/file/marshal_spec.rb +2 -2
  43. data/spec/lib/{backend → backends}/file/text_spec.rb +1 -1
  44. data/spec/lib/backends/memory_spec.rb +77 -0
  45. data/spec/lib/{backend → backends}/redis/basic_spec.rb +19 -21
  46. data/spec/lib/backends/redis/float_hash_spec.rb +38 -0
  47. data/spec/lib/backends/redis/list_hash_spec.rb +27 -0
  48. data/spec/lib/backends/redis/string_hash_spec.rb +38 -0
  49. data/spec/lib/backends/redis_spec.rb +79 -0
  50. data/spec/lib/categories_indexed_spec.rb +3 -3
  51. data/spec/lib/category_indexed_spec.rb +6 -6
  52. data/spec/lib/category_indexing_spec.rb +1 -1
  53. data/spec/lib/category_spec.rb +1 -1
  54. data/spec/lib/frontend_adapters/rack_spec.rb +2 -2
  55. data/spec/lib/{indexes/index_indexed_spec.rb → index_indexed_spec.rb} +1 -1
  56. data/spec/lib/{indexes/index_indexing_spec.rb → index_indexing_spec.rb} +1 -1
  57. data/spec/lib/{indexes/index_spec.rb → index_spec.rb} +1 -1
  58. data/spec/lib/indexed/{bundle/memory_spec.rb → memory_spec.rb} +18 -18
  59. data/spec/lib/indexed/wrappers/exact_first_spec.rb +2 -2
  60. data/spec/lib/indexing/{bundle/memory_partial_generation_speed_spec.rb → bundle_partial_generation_speed_spec.rb} +3 -3
  61. data/spec/lib/indexing/bundle_spec.rb +302 -0
  62. data/spec/lib/query/allocation_spec.rb +21 -11
  63. data/spec/lib/query/combination_spec.rb +2 -2
  64. data/spec/lib/query/{combinations/base_spec.rb → combinations_spec.rb} +1 -1
  65. data/spec/lib/query/indexes_check_spec.rb +25 -0
  66. data/spec/lib/query/indexes_spec.rb +5 -1
  67. data/spec/lib/query/token_spec.rb +18 -20
  68. data/spec/lib/query/tokens_spec.rb +14 -65
  69. data/spec/lib/search_spec.rb +36 -37
  70. data/spec/lib/tasks/try_spec.rb +51 -0
  71. data/spec/lib/{tokenizers/base_spec.rb → tokenizer_spec.rb} +15 -44
  72. metadata +64 -81
  73. data/lib/picky/backend/base.rb +0 -121
  74. data/lib/picky/backend/files.rb +0 -28
  75. data/lib/picky/backend/redis.rb +0 -44
  76. data/lib/picky/indexed/bundle/base.rb +0 -47
  77. data/lib/picky/indexed/bundle/memory.rb +0 -88
  78. data/lib/picky/indexed/bundle/redis.rb +0 -91
  79. data/lib/picky/indexes/index.rb +0 -328
  80. data/lib/picky/indexes/index_indexed.rb +0 -35
  81. data/lib/picky/indexes/index_indexing.rb +0 -165
  82. data/lib/picky/indexes/memory.rb +0 -20
  83. data/lib/picky/indexes/redis.rb +0 -20
  84. data/lib/picky/indexing/bundle/base.rb +0 -242
  85. data/lib/picky/indexing/bundle/memory.rb +0 -26
  86. data/lib/picky/indexing/bundle/redis.rb +0 -26
  87. data/lib/picky/query/combinations/base.rb +0 -74
  88. data/lib/picky/query/combinations/memory.rb +0 -52
  89. data/lib/picky/query/combinations/redis.rb +0 -90
  90. data/lib/picky/query.rb +0 -6
  91. data/lib/picky/tokenizers/base.rb +0 -231
  92. data/lib/picky/tokenizers/index.rb +0 -34
  93. data/lib/picky/tokenizers/query.rb +0 -61
  94. data/spec/lib/backend/files_spec.rb +0 -189
  95. data/spec/lib/backend/redis/list_hash_spec.rb +0 -40
  96. data/spec/lib/backend/redis/string_hash_spec.rb +0 -47
  97. data/spec/lib/backend/redis_spec.rb +0 -170
  98. data/spec/lib/indexed/bundle/redis_spec.rb +0 -41
  99. data/spec/lib/indexes/redis_spec.rb +0 -15
  100. data/spec/lib/indexing/bundle/base_spec.rb +0 -38
  101. data/spec/lib/indexing/bundle/memory_spec.rb +0 -287
  102. data/spec/lib/indexing/bundle/redis_spec.rb +0 -283
  103. data/spec/lib/query/combinations/memory_spec.rb +0 -158
  104. data/spec/lib/query/combinations/redis_spec.rb +0 -172
  105. data/spec/lib/tokenizers/index_spec.rb +0 -69
  106. data/spec/lib/tokenizers/query_spec.rb +0 -121
@@ -1,231 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- module Picky
4
-
5
- module Tokenizers # :nodoc:all
6
-
7
- # Defines tokenizing processes used both in indexing and querying.
8
- #
9
- class Base
10
-
11
- # TODO Move EMPTY_STRING top level.
12
- #
13
- EMPTY_STRING = ''.freeze
14
-
15
- def to_s
16
- reject_condition_location = @reject_condition.to_s[/:(\d+) \(lambda\)/, 1]
17
- <<-TOKENIZER
18
- Removes characters: #{@removes_characters_regexp ? "/#{@removes_characters_regexp.source}/" : '-'}
19
- Stopwords: #{@remove_stopwords_regexp ? "/#{@remove_stopwords_regexp.source}/" : '-'}
20
- Splits text on: #{@splits_text_on.respond_to?(:source) ? "/#{@splits_text_on.source}/" : (@splits_text_on ? @splits_text_on : '-')}
21
- Removes chars after split: #{@removes_characters_after_splitting_regexp ? "/#{@removes_characters_after_splitting_regexp.source}/" : '-'}
22
- Normalizes words: #{@normalizes_words_regexp_replaces ? @normalizes_words_regexp_replaces : '-'}
23
- Rejects tokens? #{reject_condition_location ? "Yes, see line #{reject_condition_location} in app/application.rb" : '-'}
24
- Substitutes chars? #{@substituter ? "Yes, using #{@substituter}." : '-' }
25
- Case sensitive? #{@case_sensitive ? "Yes." : "-"}
26
- TOKENIZER
27
- end
28
-
29
- # Stopwords.
30
- #
31
- # We only allow regexps (even if string would be okay
32
- # too for gsub! - it's too hard to understand)
33
- #
34
- def stopwords regexp
35
- check_argument_in __method__, Regexp, regexp
36
- @remove_stopwords_regexp = regexp
37
- end
38
- def remove_stopwords text
39
- text.gsub! @remove_stopwords_regexp, EMPTY_STRING if @remove_stopwords_regexp
40
- text
41
- end
42
- @@non_single_stopword_regexp = /^\b[\w:]+?\b[\.\*\~]?\s?$/
43
- def remove_non_single_stopwords text
44
- return text if text.match @@non_single_stopword_regexp
45
- remove_stopwords text
46
- end
47
-
48
- # Illegals.
49
- #
50
- # We only allow regexps (even if string would be okay
51
- # too for gsub! - it's too hard to understand)
52
- #
53
- def removes_characters regexp
54
- check_argument_in __method__, Regexp, regexp
55
- @removes_characters_regexp = regexp
56
- end
57
- def remove_illegals text
58
- text.gsub! @removes_characters_regexp, EMPTY_STRING if @removes_characters_regexp
59
- text
60
- end
61
-
62
- # Splitting.
63
- #
64
- # We allow Strings and Regexps.
65
- # Note: We do not test against to_str since symbols do not work with String#split.
66
- #
67
- def splits_text_on regexp_or_string
68
- raise ArgumentError.new "#{__method__} takes a Regexp or String as argument, not a #{regexp_or_string.class}." unless Regexp === regexp_or_string || String === regexp_or_string
69
- @splits_text_on = regexp_or_string
70
- end
71
- def split text
72
- text.split @splits_text_on
73
- end
74
-
75
- # Normalizing.
76
- #
77
- # We only allow arrays.
78
- #
79
- def normalizes_words regexp_replaces
80
- raise ArgumentError.new "#{__method__} takes an Array of replaces as argument, not a #{regexp_replaces.class}." unless regexp_replaces.respond_to?(:to_ary)
81
- @normalizes_words_regexp_replaces = regexp_replaces
82
- end
83
- def normalize_with_patterns text
84
- return text unless @normalizes_words_regexp_replaces
85
-
86
- @normalizes_words_regexp_replaces.each do |regex, replace|
87
- # This should be sufficient
88
- #
89
- text.gsub!(regex, replace) and break
90
- end
91
-
92
- remove_after_normalizing_illegals text
93
- text
94
- end
95
-
96
- # Illegal after normalizing.
97
- #
98
- # We only allow regexps (even if string would be okay
99
- # too for gsub! - it's too hard to understand)
100
- #
101
- def removes_characters_after_splitting regexp
102
- check_argument_in __method__, Regexp, regexp
103
- @removes_characters_after_splitting_regexp = regexp
104
- end
105
- def remove_after_normalizing_illegals text
106
- text.gsub! @removes_characters_after_splitting_regexp, EMPTY_STRING if @removes_characters_after_splitting_regexp
107
- end
108
-
109
- # Substitute Characters with this substituter.
110
- #
111
- # Default is European Character substitution.
112
- #
113
- def substitutes_characters_with substituter = CharacterSubstituters::WestEuropean.new
114
- raise ArgumentError.new "The substitutes_characters_with option needs a character substituter, which responds to #substitute." unless substituter.respond_to?(:substitute)
115
- @substituter = substituter
116
- end
117
- def substitute_characters text
118
- substituter?? substituter.substitute(text) : text
119
- end
120
-
121
- # Reject tokens after tokenizing based on the given criteria.
122
- #
123
- # Note: Currently only for indexing. TODO Put into searching as well.
124
- #
125
- def rejects_token_if &condition
126
- @reject_condition = condition
127
- end
128
- def reject tokens
129
- tokens.reject! &@reject_condition
130
- end
131
-
132
- def case_sensitive case_sensitive
133
- @case_sensitive = case_sensitive
134
- end
135
- def downcase?
136
- !@case_sensitive
137
- end
138
-
139
- # Checks if the right argument type has been given.
140
- #
141
- def check_argument_in method, type, argument, &condition
142
- raise ArgumentError.new "Application##{method} takes a #{type} as argument, not a #{argument.class}." unless type === argument
143
- end
144
-
145
-
146
- # Returns a number of tokens, generated from the given text.
147
- #
148
- # Note:
149
- # * preprocess, pretokenize are hooks
150
- #
151
- def tokenize text
152
- text = preprocess text # processing the text
153
- return empty_tokens if text.blank?
154
- words = pretokenize text # splitting and preparations for tokenizing
155
- return empty_tokens if words.empty?
156
- tokens = tokens_for words # creating tokens / strings
157
- process tokens # processing tokens / strings
158
- end
159
-
160
- attr_reader :substituter
161
- alias substituter? substituter
162
-
163
- def initialize options = {}
164
- removes_characters options[:removes_characters] if options[:removes_characters]
165
- contracts_expressions *options[:contracts_expressions] if options[:contracts_expressions]
166
- stopwords options[:stopwords] if options[:stopwords]
167
- normalizes_words options[:normalizes_words] if options[:normalizes_words]
168
- removes_characters_after_splitting options[:removes_characters_after_splitting] if options[:removes_characters_after_splitting]
169
- substitutes_characters_with options[:substitutes_characters_with] if options[:substitutes_characters_with]
170
- case_sensitive options[:case_sensitive] unless options[:case_sensitive].nil?
171
-
172
- # Defaults.
173
- #
174
- splits_text_on options[:splits_text_on] || /\s/
175
- rejects_token_if &(options[:rejects_token_if] || :blank?)
176
- end
177
-
178
- # Default preprocessing hook.
179
- #
180
- # Does:
181
- # 1. Character substitution.
182
- # 2. Remove illegal expressions.
183
- # 3. Remove non-single stopwords. (Stopwords that occur with other words)
184
- #
185
- def preprocess text
186
- text = substitute_characters text
187
- remove_illegals text
188
- # We do not remove single stopwords e.g. in the indexer for
189
- # an entirely different reason than in the query tokenizer.
190
- # An indexed thing with just name "UND" (a possible stopword)
191
- # should not lose its name.
192
- #
193
- remove_non_single_stopwords text
194
- text
195
- end
196
- # Pretokenizing.
197
- #
198
- # Does:
199
- # 1. Split the text into words.
200
- # 2. Normalize each word.
201
- #
202
- def pretokenize text
203
- words = split text
204
- words.collect! do |word|
205
- normalize_with_patterns word
206
- word
207
- end
208
- end
209
- # Basic postprocessing (overridden in both query/index tokenizers).
210
- #
211
- def process tokens
212
- reject tokens # Reject any tokens that don't meet criteria
213
- tokens
214
- end
215
-
216
- # # Converts words into real tokens.
217
- # #
218
- # def tokens_for words
219
- # Query::Tokens.new words.collect! { |word| token_for word }
220
- # end
221
- # Turns non-blank text into symbols.
222
- #
223
- def symbolize text
224
- text.blank? ? nil : text.to_sym
225
- end
226
-
227
- end
228
-
229
- end
230
-
231
- end
@@ -1,34 +0,0 @@
1
- module Picky
2
-
3
- module Tokenizers
4
-
5
- # The base indexing tokenizer.
6
- #
7
- # Override in indexing subclasses and define in configuration.
8
- #
9
- class Index < Base
10
-
11
- def self.default= new_default
12
- @default = new_default
13
- end
14
- def self.default
15
- @default ||= new
16
- end
17
-
18
- # Does not actually return a token, but a
19
- # symbol "token".
20
- #
21
- def tokens_for words
22
- words.collect! { |word| word.downcase! if downcase?; word.to_sym }
23
- end
24
- # Returns empty tokens.
25
- #
26
- def empty_tokens
27
- []
28
- end
29
-
30
- end
31
-
32
- end
33
-
34
- end
@@ -1,61 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- module Picky
4
-
5
- module Tokenizers
6
-
7
- # There are a few class methods that you can use to configure how a query works.
8
- #
9
- # removes_characters regexp
10
- # illegal_after_normalizing regexp
11
- # stopwords regexp
12
- # contracts_expressions regexp, to_string
13
- # splits_text_on regexp
14
- # normalizes_words [[/regexp1/, 'replacement1'], [/regexp2/, 'replacement2']]
15
- #
16
- class Query < Base
17
-
18
- attr_reader :qualifiers
19
-
20
- def self.default= new_default
21
- @default = new_default
22
- end
23
- def self.default
24
- @default ||= new
25
- end
26
-
27
- attr_reader :maximum_tokens
28
-
29
- def initialize options = {}
30
- super options
31
- @maximum_tokens = options[:maximum_tokens] || 5
32
- end
33
-
34
- # Let each token process itself.
35
- # Reject, limit, and partialize tokens.
36
- #
37
- # In querying we work with real tokens (in indexing it's just symbols).
38
- #
39
- def process tokens
40
- tokens.reject # Reject any tokens that don't meet criteria.
41
- tokens.cap maximum_tokens # Cut off superfluous tokens.
42
- tokens.partialize_last # Set certain tokens as partial.
43
- tokens
44
- end
45
-
46
- # Converts words into real tokens.
47
- #
48
- def tokens_for words
49
- Picky::Query::Tokens.processed words, downcase?
50
- end
51
- # Returns a tokens object.
52
- #
53
- def empty_tokens
54
- Picky::Query::Tokens.new
55
- end
56
-
57
- end
58
-
59
- end
60
-
61
- end
@@ -1,189 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Picky::Backend::Files do
4
-
5
- before(:each) do
6
- index = Picky::Indexes::Memory.new :some_index
7
- category = Picky::Category.new :some_category, index
8
- bundle = Picky::Indexing::Bundle::Base.new :some_bundle, category, nil, nil, nil
9
-
10
- @files = described_class.new bundle
11
-
12
- @index = @files.inverted
13
- @weights = @files.weights
14
- @similarity = @files.similarity
15
- @configuration = @files.configuration
16
- end
17
-
18
- describe "dump indexes" do
19
- before(:each) do
20
- @files.stub! :timed_exclaim
21
- end
22
- describe "dump_index" do
23
- it "uses the right file" do
24
- @index.should_receive(:dump).once.with :some_hash
25
-
26
- @files.dump_inverted :some_hash
27
- end
28
- end
29
- describe "dump_weights" do
30
- it "uses the right file" do
31
- @weights.should_receive(:dump).once.with :some_hash
32
-
33
- @files.dump_weights :some_hash
34
- end
35
- end
36
- describe "dump_similarity" do
37
- it "uses the right file" do
38
- @similarity.should_receive(:dump).once.with :some_hash
39
-
40
- @files.dump_similarity :some_hash
41
- end
42
- end
43
- describe "dump_configuration" do
44
- it "uses the right file" do
45
- @configuration.should_receive(:dump).once.with :some_hash
46
-
47
- @files.dump_configuration :some_hash
48
- end
49
- end
50
- end
51
-
52
- describe "loading indexes" do
53
- before(:each) do
54
- @files.stub! :timed_exclaim
55
- end
56
- describe "load_index" do
57
- it "uses the right file" do
58
- Yajl::Parser.stub! :parse
59
-
60
- File.should_receive(:open).once.with 'spec/test_directory/index/test/some_index/some_category_some_bundle_inverted.json', 'r'
61
-
62
- @files.load_inverted
63
- end
64
- end
65
- describe "load_weights" do
66
- it "uses the right file" do
67
- Yajl::Parser.stub! :parse
68
-
69
- File.should_receive(:open).once.with 'spec/test_directory/index/test/some_index/some_category_some_bundle_weights.json', 'r'
70
-
71
- @files.load_weights
72
- end
73
- end
74
- describe "load_similarity" do
75
- it "uses the right file" do
76
- Marshal.stub! :load
77
-
78
- File.should_receive(:open).once.with 'spec/test_directory/index/test/some_index/some_category_some_bundle_similarity.dump', 'r:binary'
79
-
80
- @files.load_similarity
81
- end
82
- end
83
- describe "load_configuration" do
84
- it "uses the right file" do
85
- Yajl::Parser.stub! :parse
86
-
87
- File.should_receive(:open).once.with 'spec/test_directory/index/test/some_index/some_category_some_bundle_configuration.json', 'r'
88
-
89
- @files.load_configuration
90
- end
91
- end
92
- end
93
-
94
- describe "dump indexes" do
95
- describe "index_cache_ok?" do
96
- it 'uses the right method' do
97
- @index.should_receive(:cache_ok?).once.with
98
-
99
- @files.inverted_cache_ok?
100
- end
101
- end
102
- describe "weights_cache_ok?" do
103
- it 'uses the right method' do
104
- @weights.should_receive(:cache_ok?).once.with
105
-
106
- @files.weights_cache_ok?
107
- end
108
- end
109
- describe "similarity_cache_ok?" do
110
- it 'uses the right method' do
111
- @similarity.should_receive(:cache_ok?).once.with
112
-
113
- @files.similarity_cache_ok?
114
- end
115
- end
116
- end
117
-
118
- describe 'dump indexes' do
119
- describe 'inverted_cache_small?' do
120
- it 'uses the right method' do
121
- @index.should_receive(:cache_small?).once.with
122
-
123
- @files.inverted_cache_small?
124
- end
125
- end
126
- describe 'weights_cache_small?' do
127
- it 'uses the right method' do
128
- @weights.should_receive(:cache_small?).once.with
129
-
130
- @files.weights_cache_small?
131
- end
132
- end
133
- describe 'similarity_cache_small?' do
134
- it 'uses the right method' do
135
- @similarity.should_receive(:cache_small?).once.with
136
-
137
- @files.similarity_cache_small?
138
- end
139
- end
140
- end
141
-
142
- describe 'backup' do
143
- it 'should call backup on all' do
144
- @index.should_receive(:backup).once.with
145
- @weights.should_receive(:backup).once.with
146
- @similarity.should_receive(:backup).once.with
147
- @configuration.should_receive(:backup).once.with
148
-
149
- @files.backup
150
- end
151
- end
152
- describe 'restore' do
153
- it 'should call delete on all' do
154
- @index.should_receive(:restore).once.with
155
- @weights.should_receive(:restore).once.with
156
- @similarity.should_receive(:restore).once.with
157
- @configuration.should_receive(:restore).once.with
158
-
159
- @files.restore
160
- end
161
- end
162
- describe 'delete' do
163
- it 'should call delete on all' do
164
- @index.should_receive(:delete).once.with
165
- @weights.should_receive(:delete).once.with
166
- @similarity.should_receive(:delete).once.with
167
- @configuration.should_receive(:delete).once.with
168
-
169
- @files.delete
170
- end
171
- end
172
-
173
- describe 'initialization' do
174
- it 'should initialize the name correctly' do
175
- @files.bundle.name.should == :some_bundle
176
- end
177
- end
178
-
179
- describe 'to_s' do
180
- it 'returns the right value' do
181
- bundle = stub :bundle,
182
- :index_path => 'index/path',
183
- :prepared_index_path => 'prepared/index/path'
184
-
185
- described_class.new(bundle).to_s.should == "Picky::Backend::Files(Picky::Backend::File::JSON(index/path.json), Picky::Backend::File::JSON(index/path.json), Picky::Backend::File::Marshal(index/path.dump), Picky::Backend::File::JSON(index/path.json))"
186
- end
187
- end
188
-
189
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Picky::Backend::Redis::ListHash do
4
-
5
- let(:index) { described_class.new :some_namespace }
6
-
7
- describe 'member' do
8
- it 'raises an error' do
9
- expect {
10
- index.member :some_sym
11
- }.to raise_error("Can't retrieve single value :some_sym from a Redis ListHash. Use Indexes::Redis::StringHash.")
12
- end
13
- end
14
-
15
- describe 'collection' do
16
- it 'returns whatever comes back from the backend' do
17
- backend = stub :backend
18
- index.should_receive(:backend).and_return backend
19
-
20
- backend.stub! :zrange => :some_lrange_result
21
-
22
- index.collection(:anything).should == :some_lrange_result
23
- end
24
- it 'calls the right method on the backend' do
25
- backend = stub :backend
26
- index.should_receive(:backend).and_return backend
27
-
28
- backend.should_receive(:zrange).once.with "some_namespace:some_sym", 0, -1
29
-
30
- index.collection :some_sym
31
- end
32
- end
33
-
34
- describe 'to_s' do
35
- it 'returns the cache path with the default file extension' do
36
- index.to_s.should == 'Picky::Backend::Redis::ListHash(some_namespace:*)'
37
- end
38
- end
39
-
40
- end
@@ -1,47 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Picky::Backend::Redis::StringHash do
4
-
5
- let(:index) { described_class.new :some_namespace }
6
-
7
- describe 'dump' do
8
- let(:backend) { index.backend }
9
- it 'dumps correctly' do
10
- backend.should_receive(:hset).once.ordered.with :some_namespace, :a, 1
11
- backend.should_receive(:hset).once.ordered.with :some_namespace, :b, 2
12
- backend.should_receive(:hset).once.ordered.with :some_namespace, :c, 3
13
-
14
- index.dump a: 1, b: 2, c: 3
15
- end
16
- end
17
-
18
- describe 'collection' do
19
- it 'raises' do
20
- expect { index.collection :anything }.to raise_error("Can't retrieve collection for :anything from a StringHash. Use Indexes::Redis::ListHash.")
21
- end
22
- end
23
-
24
- describe 'member' do
25
- before(:each) do
26
- @backend = stub :backend
27
- index.stub! :backend => @backend
28
- end
29
- it 'delegates to the backend' do
30
- @backend.should_receive(:hget).once.with :some_namespace, :some_symbol
31
-
32
- index.member :some_symbol
33
- end
34
- it 'returns whatever it gets from the backend' do
35
- @backend.should_receive(:hget).any_number_of_times.and_return :some_result
36
-
37
- index.member(:anything).should == :some_result
38
- end
39
- end
40
-
41
- describe 'to_s' do
42
- it 'returns the cache path with the default file extension' do
43
- index.to_s.should == 'Picky::Backend::Redis::StringHash(some_namespace:*)'
44
- end
45
- end
46
-
47
- end