picky 3.0.0.pre5 → 3.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.
- data/lib/picky/adapters/rack/search.rb +1 -1
- data/lib/picky/application.rb +1 -1
- data/lib/picky/backend/file/marshal.rb +1 -1
- data/lib/picky/character_substituters/west_european.rb +21 -11
- data/lib/picky/extensions/hash.rb +5 -5
- data/lib/picky/generators/weights/logarithmic.rb +1 -2
- data/lib/picky/indexed/wrappers/bundle/calculation.rb +13 -5
- data/lib/picky/indexed/wrappers/bundle/location.rb +1 -1
- data/lib/picky/indexed/wrappers/category/location.rb +2 -0
- data/lib/picky/indexes/index.rb +3 -1
- data/lib/picky/query/allocations.rb +7 -1
- data/lib/picky/query/combination.rb +29 -12
- data/lib/picky/query/combinations/base.rb +1 -1
- data/lib/picky/query/weights.rb +48 -22
- data/lib/picky/results.rb +38 -37
- data/lib/picky/search.rb +5 -5
- data/lib/picky/tokenizers/base.rb +1 -1
- data/spec/lib/backend/file/marshal_spec.rb +1 -1
- data/spec/lib/extensions/hash_spec.rb +2 -2
- data/spec/lib/query/combinations/base_spec.rb +1 -1
- data/spec/lib/query/combinations/memory_spec.rb +1 -1
- data/spec/lib/query/combinations/redis_spec.rb +1 -1
- data/spec/lib/query/weights_spec.rb +13 -2
- data/spec/lib/results_spec.rb +23 -12
- data/spec/lib/search_spec.rb +9 -2
- metadata +6 -6
data/lib/picky/application.rb
CHANGED
@@ -197,7 +197,7 @@ module Picky
|
|
197
197
|
# Reloads & finalizes the apps.
|
198
198
|
#
|
199
199
|
def reload
|
200
|
-
Loader.load_user 'app' # Sinatra
|
200
|
+
Loader.load_user 'app' # Sinatra appfile.
|
201
201
|
Loader.load_user 'app/application' # Standard Picky appfile.
|
202
202
|
finalize_apps
|
203
203
|
exclaim "Application #{apps.map(&:name).join(', ')} loaded."
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
#
|
3
|
-
#
|
4
|
-
# diactritics from japanese characters, like べ to へ.
|
3
|
+
# THINK Does it also remove diaritics, like べ to へ?
|
5
4
|
#
|
6
5
|
module Picky
|
7
6
|
|
8
|
-
module CharacterSubstituters
|
7
|
+
module CharacterSubstituters
|
9
8
|
|
10
9
|
# Substitutes Umlauts like
|
11
10
|
# ä, ö, ü => ae, oe, ue.
|
@@ -13,32 +12,43 @@ module Picky
|
|
13
12
|
#
|
14
13
|
class WestEuropean
|
15
14
|
|
16
|
-
def initialize
|
15
|
+
def initialize # :nodoc:
|
17
16
|
@chars = ActiveSupport::Multibyte.proxy_class
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
# Substitutes occurrences of certain characters
|
20
|
+
# (like Umlauts) with ASCII representations of them.
|
21
|
+
#
|
22
|
+
# Examples:
|
23
|
+
# ä -> ae
|
24
|
+
# Ö -> Oe
|
25
|
+
# ß -> ss
|
26
|
+
# ç -> c
|
27
|
+
#
|
28
|
+
# (See the associated spec for all examples)
|
29
|
+
#
|
24
30
|
def substitute text
|
25
31
|
trans = @chars.new(text).normalize(:kd)
|
26
32
|
|
27
|
-
#
|
33
|
+
# Substitute special cases.
|
28
34
|
#
|
29
35
|
trans.gsub!('ß', 'ss')
|
30
36
|
|
31
|
-
#
|
37
|
+
# Substitute umlauts (of A,O,U,a,o,u).
|
32
38
|
#
|
33
39
|
trans.gsub!(/([AOUaou])\314\210/u, '\1e')
|
34
40
|
|
35
|
-
#
|
41
|
+
# Get rid of ecutes, graves etc.
|
36
42
|
#
|
37
43
|
trans.unpack('U*').select { |cp|
|
38
44
|
cp < 0x0300 || cp > 0x035F
|
39
45
|
}.pack('U*')
|
40
46
|
end
|
41
47
|
|
48
|
+
def to_s # :nodoc:
|
49
|
+
self.class.name
|
50
|
+
end
|
51
|
+
|
42
52
|
end
|
43
53
|
|
44
54
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Extensions for the Hash.
|
2
2
|
#
|
3
3
|
class Hash # :nodoc:all
|
4
|
-
|
4
|
+
|
5
5
|
# Dumps jsonized self to the path given. Minus extension.
|
6
6
|
#
|
7
7
|
def dump_json path
|
@@ -9,19 +9,19 @@ class Hash # :nodoc:all
|
|
9
9
|
Yajl::Encoder.encode self, out_file
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Dumps binary self to the path given. Minus extension.
|
14
14
|
#
|
15
|
-
def
|
15
|
+
def dump_marshal path
|
16
16
|
File.open(path, 'w:binary') do |out_file|
|
17
17
|
Marshal.dump self, out_file
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Use yajl's encoding.
|
22
22
|
#
|
23
23
|
def to_json options = {}
|
24
24
|
Yajl::Encoder.encode self, options
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
end
|
@@ -14,8 +14,7 @@ module Picky
|
|
14
14
|
# Generates a partial index from the given inverted index.
|
15
15
|
#
|
16
16
|
def generate_from inverted
|
17
|
-
inverted.inject({}) do |hash,
|
18
|
-
text, ids = *text_ids
|
17
|
+
inverted.inject({}) do |hash, (text, ids)|
|
19
18
|
weight = weight_for ids.size
|
20
19
|
hash[text] ||= weight.round(2) if weight
|
21
20
|
hash
|
@@ -7,11 +7,19 @@ module Picky
|
|
7
7
|
|
8
8
|
# A calculation rewrites the symbol into a float.
|
9
9
|
#
|
10
|
-
#
|
10
|
+
# Note: A calculation will try to find a float in the index,
|
11
|
+
# not a sym.
|
12
|
+
#
|
13
|
+
# TODO I really need to allow integers as keys.
|
14
|
+
# The code below is just not up to the needed quality.
|
15
|
+
# Use key_format :to_i?
|
11
16
|
#
|
12
17
|
class Calculation < Wrapper
|
13
18
|
|
19
|
+
# API.
|
14
20
|
#
|
21
|
+
# By default, a calculation does not
|
22
|
+
# recalculate anything.
|
15
23
|
#
|
16
24
|
def recalculate float
|
17
25
|
float
|
@@ -19,14 +27,14 @@ module Picky
|
|
19
27
|
|
20
28
|
#
|
21
29
|
#
|
22
|
-
def ids
|
23
|
-
@bundle.ids recalculate(
|
30
|
+
def ids float_as_sym
|
31
|
+
@bundle.ids recalculate(float_as_sym.to_s.to_f).to_s.to_sym
|
24
32
|
end
|
25
33
|
|
26
34
|
#
|
27
35
|
#
|
28
|
-
def weight
|
29
|
-
@bundle.weight recalculate(
|
36
|
+
def weight float_as_sym
|
37
|
+
@bundle.weight recalculate(float_as_sym.to_s.to_f).to_s.to_sym
|
30
38
|
end
|
31
39
|
|
32
40
|
end
|
@@ -30,7 +30,7 @@ module Picky
|
|
30
30
|
# Load first the bundle, then extract the config.
|
31
31
|
#
|
32
32
|
bundle.load
|
33
|
-
#
|
33
|
+
# THINK Can I move the to_f to the backend?
|
34
34
|
#
|
35
35
|
minimum = bundle[:location_minimum] && bundle[:location_minimum].to_f || raise("Configuration :location_minimum for #{bundle.identifier} missing. Did you run rake index already?")
|
36
36
|
@calculation.minimum = minimum
|
data/lib/picky/indexes/index.rb
CHANGED
@@ -224,8 +224,10 @@ module Picky
|
|
224
224
|
# * ... all options of #define_category.
|
225
225
|
#
|
226
226
|
def ranged_category category_name, range, options = {}
|
227
|
-
precision = options[:precision] || 1
|
227
|
+
precision = options[:precision] || 1 # THINK options.delete?
|
228
228
|
|
229
|
+
# Note: :key_format => :to_f ?
|
230
|
+
#
|
229
231
|
options = { partial: Partial::None.new }.merge options
|
230
232
|
|
231
233
|
define_category category_name, options do |category|
|
@@ -6,9 +6,14 @@ module Picky
|
|
6
6
|
#
|
7
7
|
class Allocations # :nodoc:all
|
8
8
|
|
9
|
-
delegate :each, :inject, :empty?, :size, :to => :@allocations
|
10
9
|
attr_reader :total
|
11
10
|
|
11
|
+
delegate :each,
|
12
|
+
:inject,
|
13
|
+
:empty?,
|
14
|
+
:size,
|
15
|
+
:to => :@allocations
|
16
|
+
|
12
17
|
def initialize allocations = []
|
13
18
|
@allocations = allocations
|
14
19
|
end
|
@@ -20,6 +25,7 @@ module Picky
|
|
20
25
|
allocation.calculate_score weights
|
21
26
|
end
|
22
27
|
end
|
28
|
+
|
23
29
|
# Sort the allocations.
|
24
30
|
#
|
25
31
|
def sort!
|
@@ -13,19 +13,30 @@ module Picky
|
|
13
13
|
#
|
14
14
|
class Combination # :nodoc:all
|
15
15
|
|
16
|
-
attr_reader :token,
|
16
|
+
attr_reader :token,
|
17
|
+
:category
|
17
18
|
|
18
19
|
def initialize token, category
|
19
|
-
@token
|
20
|
-
@
|
21
|
-
@bundle = category.bundle_for token
|
22
|
-
@text = @token.text # don't want to use reset_similar already
|
20
|
+
@token = token
|
21
|
+
@category = category
|
23
22
|
end
|
24
23
|
|
25
|
-
#
|
24
|
+
# Returns the token's text.
|
26
25
|
#
|
27
|
-
def
|
28
|
-
|
26
|
+
def text
|
27
|
+
@text ||= token.text
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the category's bundle.
|
31
|
+
#
|
32
|
+
def bundle
|
33
|
+
@bundle ||= category.bundle_for(token)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the category's name.
|
37
|
+
#
|
38
|
+
def category_name
|
39
|
+
@category_name ||= category.name
|
29
40
|
end
|
30
41
|
|
31
42
|
# Returns the weight of this combination.
|
@@ -33,7 +44,7 @@ module Picky
|
|
33
44
|
# Note: Caching is most of the time useful.
|
34
45
|
#
|
35
46
|
def weight
|
36
|
-
@weight ||=
|
47
|
+
@weight ||= bundle.weight(text)
|
37
48
|
end
|
38
49
|
|
39
50
|
# Returns an array of ids for the given text.
|
@@ -41,13 +52,13 @@ module Picky
|
|
41
52
|
# Note: Caching is most of the time useful.
|
42
53
|
#
|
43
54
|
def ids
|
44
|
-
@ids ||=
|
55
|
+
@ids ||= bundle.ids(text)
|
45
56
|
end
|
46
57
|
|
47
58
|
# The identifier for this combination.
|
48
59
|
#
|
49
60
|
def identifier
|
50
|
-
"#{bundle.identifier}:#{
|
61
|
+
"#{bundle.identifier}:#{token.identifier}"
|
51
62
|
end
|
52
63
|
|
53
64
|
# Is the identifier in the given identifiers?
|
@@ -56,6 +67,12 @@ module Picky
|
|
56
67
|
identifiers.include? identifier
|
57
68
|
end
|
58
69
|
|
70
|
+
# Note: Required for uniq!
|
71
|
+
#
|
72
|
+
def hash
|
73
|
+
[token.to_s, bundle].hash
|
74
|
+
end
|
75
|
+
|
59
76
|
# Combines the category names with the original names.
|
60
77
|
# [
|
61
78
|
# [:title, 'Flarbl', :flarbl],
|
@@ -63,7 +80,7 @@ module Picky
|
|
63
80
|
# ]
|
64
81
|
#
|
65
82
|
def to_result
|
66
|
-
[
|
83
|
+
[category_name, *token.to_result]
|
67
84
|
end
|
68
85
|
|
69
86
|
# Example:
|
data/lib/picky/query/weights.rb
CHANGED
@@ -2,51 +2,77 @@ module Picky
|
|
2
2
|
|
3
3
|
module Query
|
4
4
|
|
5
|
-
# Calculates weights for
|
5
|
+
# Calculates scores/weights for combinations.
|
6
6
|
#
|
7
|
-
|
7
|
+
# Example:
|
8
|
+
# Someone searches for peter fish.
|
9
|
+
# Picky might match this to categories as follows:
|
10
|
+
# [:name, :food]
|
11
|
+
# and
|
12
|
+
# [:name, :surname]
|
13
|
+
#
|
14
|
+
# This class is concerned with calculating scores
|
15
|
+
# for the category combinations.
|
16
|
+
#
|
17
|
+
# Implement either
|
18
|
+
# #score_for(combinations)
|
19
|
+
# or
|
20
|
+
# #weight_for(category_names) # Subclass this class for this.
|
21
|
+
#
|
22
|
+
# And return a weight.
|
23
|
+
#
|
24
|
+
class Weights
|
8
25
|
|
9
26
|
attr_reader :weights
|
10
27
|
|
11
|
-
delegate :empty?,
|
28
|
+
delegate :empty?,
|
29
|
+
:to => :weights
|
12
30
|
|
13
|
-
#
|
31
|
+
# Needs a Hash of
|
32
|
+
# [:category_name1, :category_name2] => +3
|
33
|
+
# (some positive or negative weight)
|
14
34
|
#
|
15
35
|
def initialize weights = {}
|
16
36
|
@weights = weights
|
17
37
|
end
|
18
38
|
|
19
|
-
#
|
39
|
+
# API.
|
20
40
|
#
|
21
|
-
|
22
|
-
|
41
|
+
# Get the weight for an array of category names.
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
# [:name, :height, :color] returns +3, but
|
45
|
+
# [:name, :height, :street] returns -1.
|
46
|
+
#
|
47
|
+
# Note: Use Array#clustered_uniq_fast to make
|
48
|
+
# [:a, :a, :b, :a] => [:a, :b, :a]
|
49
|
+
#
|
50
|
+
def weight_for category_names
|
51
|
+
@weights[category_names.clustered_uniq_fast] || 0
|
23
52
|
end
|
24
53
|
|
25
|
-
#
|
26
|
-
# by P(allocation) = 1/Z * exp (-1/T * E(allocation)),
|
27
|
-
# where Z is the normalizing partition function
|
28
|
-
# sum_allocations exp(-1/T *E(allocation)), and T is a temperature constant.
|
29
|
-
# If T is high the distribution will be close to equally distributed.
|
30
|
-
# If T is low, the distribution will be the indicator function
|
31
|
-
# for min (E(allocation))…
|
54
|
+
# API.
|
32
55
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
56
|
+
# Calculates a score for the combinations.
|
57
|
+
# Implement #weight_for(category_names) if you don't need the
|
58
|
+
# actual combinations, just the category names.
|
36
59
|
#
|
37
60
|
# Note: Cache this if more complicated weighings become necessary.
|
61
|
+
# Note: Maybe make combinations comparable to Symbols?
|
38
62
|
#
|
39
|
-
def
|
40
|
-
|
41
|
-
#
|
42
|
-
weight_for combinations.map(&:category_name).clustered_uniq_fast
|
63
|
+
def score_for combinations
|
64
|
+
weight_for combinations.map(&:category_name)
|
43
65
|
end
|
44
66
|
|
67
|
+
# A Weights instance is == to another if
|
68
|
+
# the weights are the same.
|
69
|
+
#
|
45
70
|
def == other
|
46
71
|
@weights == other.weights
|
47
72
|
end
|
48
73
|
|
49
|
-
# Prints out a nice representation of the
|
74
|
+
# Prints out a nice representation of the
|
75
|
+
# configured weights.
|
50
76
|
#
|
51
77
|
def to_s
|
52
78
|
"#{self.class}(#{@weights})"
|
data/lib/picky/results.rb
CHANGED
@@ -8,44 +8,38 @@ module Picky
|
|
8
8
|
# Duration is set externally by the query.
|
9
9
|
#
|
10
10
|
attr_writer :duration
|
11
|
-
attr_reader :allocations,
|
11
|
+
attr_reader :allocations,
|
12
|
+
:offset,
|
13
|
+
:amount,
|
14
|
+
:query
|
12
15
|
|
13
16
|
# Takes instances of Query::Allocations as param.
|
14
17
|
#
|
15
|
-
def initialize amount = 0, offset = 0, allocations = Query::Allocations.new
|
16
|
-
@offset = offset
|
18
|
+
def initialize query = nil, amount = 0, offset = 0, allocations = Query::Allocations.new
|
17
19
|
@amount = amount
|
20
|
+
@query = query
|
21
|
+
@offset = offset
|
18
22
|
@allocations = allocations
|
19
23
|
end
|
24
|
+
|
20
25
|
# Create new results and calculate the ids.
|
21
26
|
#
|
22
|
-
def self.from amount, offset, allocations
|
23
|
-
results = new amount, offset, allocations
|
27
|
+
def self.from query, amount, offset, allocations
|
28
|
+
results = new query, amount, offset, allocations
|
24
29
|
results.prepare!
|
25
30
|
results
|
26
31
|
end
|
27
32
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
def to_hash
|
31
|
-
{ allocations: allocations.to_result,
|
32
|
-
offset: offset,
|
33
|
-
duration: duration,
|
34
|
-
total: total }
|
35
|
-
end
|
36
|
-
# Convert to json format.
|
33
|
+
# Delegates to allocations.
|
37
34
|
#
|
38
|
-
def
|
39
|
-
|
35
|
+
def ids amount = 20
|
36
|
+
allocations.ids amount
|
40
37
|
end
|
41
38
|
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# Without this, the allocations are not processed,
|
45
|
-
# and no ids are calculated.
|
39
|
+
# The total results. Delegates to the allocations.
|
46
40
|
#
|
47
|
-
def
|
48
|
-
allocations.
|
41
|
+
def total
|
42
|
+
@total || @total = allocations.total || 0
|
49
43
|
end
|
50
44
|
|
51
45
|
# Duration default is 0.
|
@@ -53,30 +47,31 @@ module Picky
|
|
53
47
|
def duration
|
54
48
|
@duration || 0
|
55
49
|
end
|
56
|
-
|
50
|
+
|
51
|
+
# This starts the actual processing.
|
57
52
|
#
|
58
|
-
#
|
53
|
+
# Without this, the allocations are not processed,
|
54
|
+
# and no ids are calculated.
|
59
55
|
#
|
60
|
-
def
|
61
|
-
|
56
|
+
def prepare!
|
57
|
+
allocations.process! amount, offset
|
62
58
|
end
|
63
59
|
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
# Delegates to allocations.
|
60
|
+
# Returns a hash with the allocations, offset, duration and total.
|
68
61
|
#
|
69
|
-
def
|
70
|
-
allocations.
|
62
|
+
def to_hash
|
63
|
+
{ allocations: allocations.to_result,
|
64
|
+
offset: offset,
|
65
|
+
duration: duration,
|
66
|
+
total: total }
|
71
67
|
end
|
72
68
|
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# TODO Should this be to_s? (And it should also hold the original query?)
|
69
|
+
# Convert to json format.
|
76
70
|
#
|
77
|
-
def
|
78
|
-
|
71
|
+
def to_json options = {}
|
72
|
+
to_hash.to_json options
|
79
73
|
end
|
74
|
+
|
80
75
|
# The first character in the blog designates what type of query it is.
|
81
76
|
#
|
82
77
|
# No calculated ids means: No results.
|
@@ -85,6 +80,12 @@ module Picky
|
|
85
80
|
amount.zero?? :'.' : :'>'
|
86
81
|
end
|
87
82
|
|
83
|
+
# For logging.
|
84
|
+
#
|
85
|
+
def to_s
|
86
|
+
"#{log_type}|#{Time.now.to_s(:db)}|#{'%8f' % duration}|#{'%-50s' % query}|#{'%8d' % total}|#{'%4d' % offset}|#{'%2d' % allocations.size}|"
|
87
|
+
end
|
88
|
+
|
88
89
|
end
|
89
90
|
|
90
91
|
end
|
data/lib/picky/search.rb
CHANGED
@@ -84,18 +84,18 @@ module Picky
|
|
84
84
|
# Note: The Rack adapter calls this method after unravelling the HTTP request.
|
85
85
|
#
|
86
86
|
def search text, ids = 20, offset = 0
|
87
|
-
search_with tokenized(text), ids.to_i, offset.to_i
|
87
|
+
search_with tokenized(text), ids.to_i, offset.to_i, text
|
88
88
|
end
|
89
89
|
|
90
90
|
# Runs the actual search using Query::Tokens.
|
91
91
|
#
|
92
92
|
# Note: Internal method, use #search
|
93
93
|
#
|
94
|
-
def search_with tokens, ids = 20, offset = 0
|
94
|
+
def search_with tokens, ids = 20, offset = 0, original_text = nil
|
95
95
|
results = nil
|
96
96
|
|
97
97
|
duration = timed do
|
98
|
-
results = execute tokens, ids, offset
|
98
|
+
results = execute tokens, ids, offset, original_text
|
99
99
|
end
|
100
100
|
results.duration = duration.round 6
|
101
101
|
|
@@ -106,8 +106,8 @@ module Picky
|
|
106
106
|
#
|
107
107
|
# Note: Internal method, use #search.
|
108
108
|
#
|
109
|
-
def execute tokens, ids, offset
|
110
|
-
Results.from ids, offset, sorted_allocations(tokens)
|
109
|
+
def execute tokens, ids, offset, original_text = nil
|
110
|
+
Results.from original_text, ids, offset, sorted_allocations(tokens)
|
111
111
|
end
|
112
112
|
|
113
113
|
# Delegates the tokenizing to the query tokenizer.
|
@@ -120,7 +120,7 @@ Case sensitive? #{@case_sensitive ? "Yes." : "-"}
|
|
120
120
|
|
121
121
|
# Reject tokens after tokenizing based on the given criteria.
|
122
122
|
#
|
123
|
-
# Note: Currently only for indexing.
|
123
|
+
# Note: Currently only for indexing. TODO Put into searching as well.
|
124
124
|
#
|
125
125
|
def rejects_token_if &condition
|
126
126
|
@reject_condition = condition
|
@@ -8,7 +8,7 @@ describe Picky::Backend::File::Marshal do
|
|
8
8
|
it "delegates to the given hash" do
|
9
9
|
hash = stub :hash
|
10
10
|
|
11
|
-
hash.should_receive(:
|
11
|
+
hash.should_receive(:dump_marshal).once.with "some/cache/path/to/file.dump"
|
12
12
|
|
13
13
|
file.dump hash
|
14
14
|
end
|
@@ -22,7 +22,7 @@ describe Hash do
|
|
22
22
|
it 'uses the right file' do
|
23
23
|
File.should_receive(:open).once.with('some/file/path.dump', 'w:binary')
|
24
24
|
|
25
|
-
{}.
|
25
|
+
{}.dump_marshal 'some/file/path.dump'
|
26
26
|
end
|
27
27
|
it "uses the right encoder" do
|
28
28
|
file = stub :file
|
@@ -30,7 +30,7 @@ describe Hash do
|
|
30
30
|
|
31
31
|
Marshal.should_receive(:dump).once.with({ :some => :hash }, file)
|
32
32
|
|
33
|
-
{ :some => :hash }.
|
33
|
+
{ :some => :hash }.dump_marshal 'unimportant'
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -27,7 +27,7 @@ describe Picky::Query::Combinations::Base do
|
|
27
27
|
describe "weighted_score" do
|
28
28
|
it "uses the weights' score method" do
|
29
29
|
weights = stub :weights
|
30
|
-
weights.should_receive(:
|
30
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
31
31
|
|
32
32
|
@combinations.weighted_score weights
|
33
33
|
end
|
@@ -27,7 +27,7 @@ describe Picky::Query::Combinations::Memory do
|
|
27
27
|
describe "weighted_score" do
|
28
28
|
it "uses the weights' score method" do
|
29
29
|
weights = stub :weights
|
30
|
-
weights.should_receive(:
|
30
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
31
31
|
|
32
32
|
@combinations.weighted_score weights
|
33
33
|
end
|
@@ -71,7 +71,7 @@ describe Picky::Query::Combinations::Redis do
|
|
71
71
|
describe "weighted_score" do
|
72
72
|
it "uses the weights' score method" do
|
73
73
|
weights = stub :weights
|
74
|
-
weights.should_receive(:
|
74
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
75
75
|
|
76
76
|
@combinations.weighted_score weights
|
77
77
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Picky::Query::Weights do
|
4
|
-
|
4
|
+
|
5
5
|
context 'with weights' do
|
6
6
|
before(:each) do
|
7
7
|
@weights = described_class.new [:test1, :test2] => 6,
|
@@ -18,7 +18,18 @@ describe Picky::Query::Weights do
|
|
18
18
|
[:test3, :test1] => 2,
|
19
19
|
[:test1, :test3] => 2
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
|
+
describe 'score_for' do
|
23
|
+
it 'gets the category names from the combinations' do
|
24
|
+
combinations = [
|
25
|
+
stub(:combination1, :category_name => :test1),
|
26
|
+
stub(:combination1, :category_name => :test2)
|
27
|
+
]
|
28
|
+
|
29
|
+
@weights.score_for(combinations).should == +6
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
22
33
|
describe "weight_for" do
|
23
34
|
it "should return zero if there is no specific weight" do
|
24
35
|
@weights.weight_for([:not_a_specific_allocation]).should be_zero
|
data/spec/lib/results_spec.rb
CHANGED
@@ -10,14 +10,14 @@ describe Picky::Results do
|
|
10
10
|
@results.stub! :prepare!
|
11
11
|
end
|
12
12
|
it "should generate a result" do
|
13
|
-
described_class.from(20, 0, @allocations).should == @results
|
13
|
+
described_class.from("some query", 20, 0, @allocations).should == @results
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe "ids" do
|
18
18
|
before(:each) do
|
19
19
|
@allocations = stub :allocations
|
20
|
-
@results = described_class.new :unimportant, :unimportant, @allocations
|
20
|
+
@results = described_class.new :unimportant, :unimportant, :unimportant, @allocations
|
21
21
|
end
|
22
22
|
it "delegates" do
|
23
23
|
@allocations.should_receive(:ids).once.with :anything
|
@@ -26,17 +26,17 @@ describe Picky::Results do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe '
|
29
|
+
describe 'to_s' do
|
30
30
|
before(:each) do
|
31
31
|
time = stub :time, :to_s => '0-08-16 10:07:33'
|
32
32
|
Time.stub! :now => time
|
33
33
|
end
|
34
34
|
context 'without results' do
|
35
35
|
before(:each) do
|
36
|
-
@results = described_class.new
|
36
|
+
@results = described_class.new "some_query"
|
37
37
|
end
|
38
38
|
it 'should output a default log' do
|
39
|
-
@results.
|
39
|
+
@results.to_s.should == '.|0-08-16 10:07:33|0.000000|some_query | 0| 0| 0|'
|
40
40
|
end
|
41
41
|
end
|
42
42
|
context 'with results' do
|
@@ -45,12 +45,12 @@ describe Picky::Results do
|
|
45
45
|
:process! => nil,
|
46
46
|
:size => 12
|
47
47
|
|
48
|
-
@results = described_class.new 20, 1234, @allocations
|
48
|
+
@results = described_class.new "some_query", 20, 1234, @allocations
|
49
49
|
@results.stub! :duration => 0.1234567890,
|
50
50
|
:total => 12345678
|
51
51
|
end
|
52
52
|
it 'should output a specific log' do
|
53
|
-
@results.
|
53
|
+
@results.to_s.should == '>|0-08-16 10:07:33|0.123457|some_query |12345678|1234|12|'
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -70,7 +70,7 @@ describe Picky::Results do
|
|
70
70
|
before(:each) do
|
71
71
|
@allocations = stub :allocations, :process! => nil, :to_result => :allocations, :total => :some_total
|
72
72
|
|
73
|
-
@results = described_class.new :some_results_amount, :some_offset, @allocations
|
73
|
+
@results = described_class.new :unimportant, :some_results_amount, :some_offset, @allocations
|
74
74
|
@results.duration = :some_duration
|
75
75
|
end
|
76
76
|
it 'should do it correctly' do
|
@@ -82,12 +82,23 @@ describe Picky::Results do
|
|
82
82
|
|
83
83
|
describe "accessors" do
|
84
84
|
before(:each) do
|
85
|
-
@results = described_class.new :
|
86
|
-
|
85
|
+
@results = described_class.new :query, :amount, :offset, :allocations
|
86
|
+
end
|
87
|
+
it "should have accessors for query" do
|
88
|
+
@results.query.should == :query
|
89
|
+
end
|
90
|
+
it "should have accessors for amount" do
|
91
|
+
@results.amount.should == :amount
|
92
|
+
end
|
93
|
+
it "should have accessors for offset" do
|
94
|
+
@results.offset.should == :offset
|
95
|
+
end
|
96
|
+
it "should have accessors for allocations" do
|
97
|
+
@results.allocations.should == :allocations
|
87
98
|
end
|
88
99
|
it "should have accessors for duration" do
|
89
|
-
@results.duration =
|
90
|
-
@results.duration.should ==
|
100
|
+
@results.duration = :some_duration
|
101
|
+
@results.duration.should == :some_duration
|
91
102
|
end
|
92
103
|
end
|
93
104
|
|
data/spec/lib/search_spec.rb
CHANGED
@@ -102,10 +102,17 @@ describe Picky::Search do
|
|
102
102
|
before(:each) do
|
103
103
|
@search = described_class.new
|
104
104
|
end
|
105
|
-
it "delegates to search_with" do
|
105
|
+
it "delegates to search_with correctly" do
|
106
106
|
@search.stub! :tokenized => :tokens
|
107
107
|
|
108
|
-
@search.should_receive(:search_with).once.with :tokens, 20,
|
108
|
+
@search.should_receive(:search_with).once.with :tokens, 20, 10, :text
|
109
|
+
|
110
|
+
@search.search :text, 20, 10
|
111
|
+
end
|
112
|
+
it "delegates to search_with correctly" do
|
113
|
+
@search.stub! :tokenized => :tokens
|
114
|
+
|
115
|
+
@search.should_receive(:search_with).once.with :tokens, 20, 0, :text
|
109
116
|
|
110
117
|
@search.search :text, 20, 0
|
111
118
|
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: picky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 3.0.0
|
4
|
+
prerelease:
|
5
|
+
version: 3.0.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Florian Hanke
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-16 00:00:00 +10:00
|
14
14
|
default_executable: picky
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 3.0.0
|
35
|
+
version: 3.0.0
|
36
36
|
type: :development
|
37
37
|
version_requirements: *id002
|
38
38
|
description: Fast Ruby semantic text search engine with comfortable single field interface.
|
@@ -288,9 +288,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
288
288
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
289
289
|
none: false
|
290
290
|
requirements:
|
291
|
-
- - "
|
291
|
+
- - ">="
|
292
292
|
- !ruby/object:Gem::Version
|
293
|
-
version:
|
293
|
+
version: "0"
|
294
294
|
requirements: []
|
295
295
|
|
296
296
|
rubyforge_project: http://rubyforge.org/projects/picky
|