ohm-contrib 0.0.42 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ohm/contrib.rb +3 -3
- data/lib/ohm/contrib/fulltext_searching.rb +80 -0
- data/lib/ohm/contrib/typecast.rb +13 -3
- data/test/autoload_test.rb +3 -3
- data/test/fixtures/ascii8bit.txt +1 -0
- data/test/fulltext_searching_test.rb +63 -0
- data/test/typecast_array_test.rb +1 -15
- data/test/typecast_hash_test.rb +10 -12
- metadata +6 -5
- data/lib/ohm/contrib/lunar_macros.rb +0 -58
- data/test/lunar_macros_test.rb +0 -146
data/lib/ohm/contrib.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Ohm
|
2
2
|
module Contrib
|
3
|
-
VERSION = "0.0
|
3
|
+
VERSION = "0.1.0"
|
4
4
|
end
|
5
5
|
|
6
6
|
autoload :ActiveModelExtension, "ohm/contrib/active_model_extension"
|
@@ -14,8 +14,8 @@ module Ohm
|
|
14
14
|
autoload :Typecast, "ohm/contrib/typecast"
|
15
15
|
autoload :Locking, "ohm/contrib/locking"
|
16
16
|
autoload :Callbacks, "ohm/contrib/callbacks"
|
17
|
-
autoload :LunarMacros, "ohm/contrib/lunar_macros"
|
18
17
|
autoload :Slug, "ohm/contrib/slug"
|
19
18
|
autoload :Scope, "ohm/contrib/scope"
|
20
19
|
autoload :SoftDelete, "ohm/contrib/soft_delete"
|
21
|
-
|
20
|
+
autoload :FulltextSearching, "ohm/contrib/fulltext_searching"
|
21
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
begin
|
2
|
+
require "text"
|
3
|
+
rescue LoadError
|
4
|
+
raise LoadError,
|
5
|
+
"Type `[sudo] gem install text` to use Ohm::FulltextSearching."
|
6
|
+
end
|
7
|
+
|
8
|
+
module Ohm
|
9
|
+
module FulltextSearching
|
10
|
+
def self.included(model)
|
11
|
+
model.extend ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def search(hash)
|
16
|
+
find(hash_to_metaphones(hash))
|
17
|
+
end
|
18
|
+
|
19
|
+
def hash_to_metaphones(hash)
|
20
|
+
ret = Hash.new { |h, k| h[k] = [] }
|
21
|
+
|
22
|
+
hash.each do |att, string|
|
23
|
+
metaphones(string).each { |m| ret[:"fulltext_#{att}"] << m }
|
24
|
+
end
|
25
|
+
|
26
|
+
return ret
|
27
|
+
end
|
28
|
+
|
29
|
+
def double_metaphone(str)
|
30
|
+
return [] if STOPWORDS.include?(str.to_s.downcase)
|
31
|
+
|
32
|
+
Text::Metaphone.double_metaphone(str).compact
|
33
|
+
end
|
34
|
+
|
35
|
+
def metaphones(str)
|
36
|
+
str.to_s.strip.split(/\s+/).map { |s| double_metaphone(s) }.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
def fulltext(att)
|
40
|
+
field = :"fulltext_#{att}"
|
41
|
+
|
42
|
+
define_method(field) { self.class.metaphones(send(att)) }
|
43
|
+
index(field)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
STOPWORDS = %w{a about above according across actually adj after
|
48
|
+
afterwards again against all almost alone along already also although
|
49
|
+
always among amongst an and another any anyhow anyone anything anywhere
|
50
|
+
are aren't around as at b be became because become becomes becoming
|
51
|
+
been before beforehand begin behind being below beside besides between
|
52
|
+
beyond both but by c can can't cannot caption co co. could couldn't d
|
53
|
+
did didn't do does doesn't don't down during e each eg eight eighty
|
54
|
+
either else elsewhere end ending enough etc even ever every everyone
|
55
|
+
everything everywhere except f few first for found from further g h
|
56
|
+
had has hasn't have haven't he he'd he'll he's hence her here here's
|
57
|
+
hereafter hereby herein hereupon hers herself him himself his how
|
58
|
+
however hundred i i'd i'll i'm i've ie if in inc. indeed instead into is
|
59
|
+
isn't it it's its itself j k l last later latter latterly least less let
|
60
|
+
let's like likely ltd m made make makes many maybe me meantime meanwhile
|
61
|
+
might miss more moreover most mostly mr mrs much must my myself n namely
|
62
|
+
neither never nevertheless next nine ninety no nobody none nonetheless
|
63
|
+
noone nor not nothing now nowhere o of off often on once one one's only
|
64
|
+
onto or other others otherwise our ours ourselves out over overall own
|
65
|
+
p per perhaps q r rather recent recently s same seem seemed seeming
|
66
|
+
seems seven several she she'd she'll she's should shouldn't since so
|
67
|
+
some somehow someone something sometime sometimes somewhere still such
|
68
|
+
t taking than that that'll that's that've the their them themselves then
|
69
|
+
thence there there'd there'll there're there's there've thereafter thereby
|
70
|
+
therefore therein thereupon these they they'd they'll they're they've
|
71
|
+
thirty this those though three through throughout thru thus to together
|
72
|
+
too toward towards u under unless unlike unlikely until up upon us used
|
73
|
+
using v very via w was wasn't we we'd we'll we're we've well were weren't
|
74
|
+
what what'll what's what've whatever when whence whenever where where's
|
75
|
+
whereafter whereas whereby wherein whereupon wherever whether which while
|
76
|
+
whither who who'd who'll who's whoever whole whom whomever whose why will
|
77
|
+
with within without won't would wouldn't x y yes yet you you'd you'll
|
78
|
+
you're you've your yours yourself yourselves z}
|
79
|
+
end
|
80
|
+
end
|
data/lib/ohm/contrib/typecast.rb
CHANGED
@@ -1,9 +1,20 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
require 'time'
|
3
3
|
require 'date'
|
4
|
-
require 'json'
|
5
4
|
require 'forwardable'
|
6
5
|
|
6
|
+
begin
|
7
|
+
require "yajl/json_gem"
|
8
|
+
rescue LoadError
|
9
|
+
$stderr.puts(
|
10
|
+
"WARNING: Currently using the `json` gem. You might encounter encoding " +
|
11
|
+
"problems with `Ohm::Types::Hash` and `Ohm::Types::Array`. Best to use " +
|
12
|
+
"the `yajl-ruby` gem to avoid problems and also for performance reasons."
|
13
|
+
)
|
14
|
+
|
15
|
+
require "json"
|
16
|
+
end
|
17
|
+
|
7
18
|
module Ohm
|
8
19
|
# Provides all the primitive types. The following are included:
|
9
20
|
#
|
@@ -342,5 +353,4 @@ module Ohm
|
|
342
353
|
end
|
343
354
|
end
|
344
355
|
end
|
345
|
-
end
|
346
|
-
|
356
|
+
end
|
data/test/autoload_test.rb
CHANGED
@@ -4,6 +4,7 @@ require File.expand_path("./helper", File.dirname(__FILE__))
|
|
4
4
|
|
5
5
|
test "autoloading of all libraries" do
|
6
6
|
assert_nothing_raised NameError, LoadError do
|
7
|
+
Ohm::ActiveModelExtension
|
7
8
|
Ohm::Boundaries
|
8
9
|
Ohm::Timestamping
|
9
10
|
Ohm::WebValidations
|
@@ -12,8 +13,7 @@ test "autoloading of all libraries" do
|
|
12
13
|
Ohm::Locking
|
13
14
|
Ohm::ExtraValidations
|
14
15
|
Ohm::DateValidations
|
15
|
-
Ohm::
|
16
|
+
Ohm::FulltextSearching
|
16
17
|
Ohm::Slug
|
17
18
|
end
|
18
|
-
end
|
19
|
-
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
café
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class Video < Ohm::Model
|
6
|
+
include Ohm::FulltextSearching
|
7
|
+
|
8
|
+
attribute :title
|
9
|
+
attribute :description
|
10
|
+
|
11
|
+
fulltext :title
|
12
|
+
fulltext :description
|
13
|
+
end
|
14
|
+
|
15
|
+
test "finding basic words using metaphones" do
|
16
|
+
v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
|
17
|
+
|
18
|
+
assert Video.find(:fulltext_title => "KK").include?(v)
|
19
|
+
assert Video.find(:fulltext_title => "PRN").include?(v)
|
20
|
+
assert Video.find(:fulltext_title => "FKS").include?(v)
|
21
|
+
assert Video.find(:fulltext_title => "JMPS").include?(v)
|
22
|
+
assert Video.find(:fulltext_title => "AMPS").include?(v)
|
23
|
+
assert Video.find(:fulltext_title => ["JMPS", "AMPS"]).include?(v)
|
24
|
+
assert Video.find(:fulltext_title => "LS").include?(v)
|
25
|
+
assert Video.find(:fulltext_title => "TK").include?(v)
|
26
|
+
end
|
27
|
+
|
28
|
+
test "finding using the actual words" do
|
29
|
+
v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
|
30
|
+
|
31
|
+
assert Video.search(:title => "quick").include?(v)
|
32
|
+
assert Video.search(:title => "brown").include?(v)
|
33
|
+
assert Video.search(:title => "fox").include?(v)
|
34
|
+
assert Video.search(:title => "jumps").include?(v)
|
35
|
+
assert Video.search(:title => "lazy").include?(v)
|
36
|
+
assert Video.search(:title => "dog").include?(v)
|
37
|
+
end
|
38
|
+
|
39
|
+
test "finding using slightly mispelled words" do
|
40
|
+
v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
|
41
|
+
|
42
|
+
assert Video.search(:title => "quik").include?(v)
|
43
|
+
assert Video.search(:title => "brwn").include?(v)
|
44
|
+
assert Video.search(:title => "fx").include?(v)
|
45
|
+
assert Video.search(:title => "fax").include?(v)
|
46
|
+
assert Video.search(:title => "jumps").include?(v)
|
47
|
+
assert Video.search(:title => "lazi").include?(v)
|
48
|
+
assert Video.search(:title => "dag").include?(v)
|
49
|
+
end
|
50
|
+
|
51
|
+
test "stopword stripping" do
|
52
|
+
# This is the actual code that strips out stopwords.
|
53
|
+
|
54
|
+
assert_equal [], Video.double_metaphone("about")
|
55
|
+
|
56
|
+
# Here we just verify that actually on a long string level,
|
57
|
+
# stop words are in fact stripped.
|
58
|
+
assert Video.metaphones(Video::STOPWORDS.join(" ")).empty?
|
59
|
+
|
60
|
+
# Finally we need to make sure that finding stop words
|
61
|
+
# should not even proceed.
|
62
|
+
assert Video.hash_to_metaphones(:title => "about").empty?
|
63
|
+
end
|
data/test/typecast_array_test.rb
CHANGED
@@ -139,22 +139,8 @@ test "raises when trying to assign a non-array" do
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
-
test "inspecting" do
|
143
|
-
post = Post.create(:addresses => [{ "address1" => "#456",
|
144
|
-
"city" => "Singapore",
|
145
|
-
"country" => "SG" }])
|
146
|
-
|
147
|
-
expected = %q{[{"address1":"#456","city":"Singapore","country":"SG"}]}
|
148
|
-
|
149
|
-
assert expected == post.addresses.inspect
|
150
|
-
|
151
|
-
post.addresses = 'FooBar'
|
152
|
-
assert %{"\\\"FooBar\\\""} == post.addresses.inspect
|
153
|
-
end
|
154
|
-
|
155
142
|
test "type is array" do
|
156
143
|
post = Post.create(:addresses => ["address1"])
|
157
144
|
|
158
145
|
assert post.addresses.type == Array
|
159
|
-
end
|
160
|
-
|
146
|
+
end
|
data/test/typecast_hash_test.rb
CHANGED
@@ -103,20 +103,18 @@ test "raises when trying to assign a non-hash" do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
test "inspecting" do
|
107
|
-
post = Post.create(:address => { "address1" => "#456",
|
108
|
-
"city" => "Singapore",
|
109
|
-
"country" => "SG" })
|
110
|
-
|
111
|
-
expected = %q{{"address1":"#456","city":"Singapore","country":"SG"}}
|
112
|
-
assert expected == post.address.inspect
|
113
|
-
|
114
|
-
post.address = 'FooBar'
|
115
|
-
assert %{"\\\"FooBar\\\""} == post.address.inspect
|
116
|
-
end
|
117
|
-
|
118
106
|
test "type is Hash" do
|
119
107
|
post = Post.new(:address => { "address1" => "#456" })
|
120
108
|
assert Hash == post.address.type
|
121
109
|
end
|
122
110
|
|
111
|
+
test "ascii 8bit encoding" do
|
112
|
+
txt = File.expand_path("fixtures/ascii8bit.txt", File.dirname(__FILE__))
|
113
|
+
|
114
|
+
data = File.read(txt, :encoding => "ascii-8bit")
|
115
|
+
|
116
|
+
post = Post.create(:address => { "address1" => data })
|
117
|
+
post = Post[post.id]
|
118
|
+
|
119
|
+
assert_equal post.address["address1"], data.force_encoding("UTF-8")
|
120
|
+
end if defined?(Encoding)
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.42
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Cyril David
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-01-08 00:00:00 +08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -96,9 +96,9 @@ files:
|
|
96
96
|
- lib/ohm/contrib/callbacks.rb
|
97
97
|
- lib/ohm/contrib/date_validations.rb
|
98
98
|
- lib/ohm/contrib/extra_validations.rb
|
99
|
+
- lib/ohm/contrib/fulltext_searching.rb
|
99
100
|
- lib/ohm/contrib/length_validations.rb
|
100
101
|
- lib/ohm/contrib/locking.rb
|
101
|
-
- lib/ohm/contrib/lunar_macros.rb
|
102
102
|
- lib/ohm/contrib/number_validations.rb
|
103
103
|
- lib/ohm/contrib/scope.rb
|
104
104
|
- lib/ohm/contrib/slug.rb
|
@@ -115,10 +115,11 @@ files:
|
|
115
115
|
- test/boundaries_test.rb
|
116
116
|
- test/callbacks_lint.rb
|
117
117
|
- test/date_validations_test.rb
|
118
|
+
- test/fixtures/ascii8bit.txt
|
119
|
+
- test/fulltext_searching_test.rb
|
118
120
|
- test/helper.rb
|
119
121
|
- test/instance_callbacks_test.rb
|
120
122
|
- test/length_validations_test.rb
|
121
|
-
- test/lunar_macros_test.rb
|
122
123
|
- test/macro_callbacks_test.rb
|
123
124
|
- test/membership_validation_test.rb
|
124
125
|
- test/number_validations_test.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'lunar'
|
3
|
-
rescue LoadError
|
4
|
-
raise "You have to install Lunar in order to use Ohm::LunarMacros."
|
5
|
-
end
|
6
|
-
|
7
|
-
module Ohm
|
8
|
-
module LunarMacros
|
9
|
-
def self.included(base)
|
10
|
-
base.send :include, Ohm::Callbacks
|
11
|
-
base.after :save, :update_lunar_index
|
12
|
-
base.after :delete, :delete_lunar_index
|
13
|
-
|
14
|
-
base.extend ClassMethods
|
15
|
-
end
|
16
|
-
|
17
|
-
module ClassMethods
|
18
|
-
def fuzzy(*atts) lunar_fields(:fuzzy, *atts) end
|
19
|
-
def text(*atts) lunar_fields(:text, *atts) end
|
20
|
-
def number(*atts) lunar_fields(:number, *atts) end
|
21
|
-
def sortable(*atts) lunar_fields(:sortable, *atts) end
|
22
|
-
|
23
|
-
def lunar_fields(type, *atts)
|
24
|
-
@lunar_fields ||= Hash.new { |h, k| h[k] = [] }
|
25
|
-
|
26
|
-
atts.each { |att|
|
27
|
-
@lunar_fields[type] << att unless @lunar_fields[type].include?(att)
|
28
|
-
}
|
29
|
-
|
30
|
-
@lunar_fields[type]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def update_lunar_index
|
35
|
-
Lunar.index self.class do |i|
|
36
|
-
i.id id
|
37
|
-
|
38
|
-
[:fuzzy, :text, :number, :sortable].each do |type|
|
39
|
-
self.class.lunar_fields(type).each do |field|
|
40
|
-
value = send(field)
|
41
|
-
|
42
|
-
if type == :text and value.kind_of?(Enumerable)
|
43
|
-
i.text field, value.join(' ') unless value.empty?
|
44
|
-
else
|
45
|
-
i.send type, field, value unless value.to_s.empty?
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
protected
|
53
|
-
def delete_lunar_index
|
54
|
-
Lunar.delete self.class, id
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
data/test/lunar_macros_test.rb
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class Post < Ohm::Model
|
6
|
-
include Ohm::LunarMacros
|
7
|
-
end
|
8
|
-
|
9
|
-
test "fuzzy / text / number / sortable" do
|
10
|
-
Post.fuzzy :name
|
11
|
-
assert [:name] == Post.fuzzy
|
12
|
-
|
13
|
-
Post.text :name
|
14
|
-
assert [:name] == Post.text
|
15
|
-
|
16
|
-
Post.number :name
|
17
|
-
assert [:name] == Post.number
|
18
|
-
|
19
|
-
Post.sortable :name
|
20
|
-
assert [:name] == Post.sortable
|
21
|
-
end
|
22
|
-
|
23
|
-
test "fuzzy / text / number / sortable done twice" do
|
24
|
-
Post.fuzzy :name
|
25
|
-
Post.fuzzy :name
|
26
|
-
assert [:name] == Post.fuzzy
|
27
|
-
|
28
|
-
Post.text :name
|
29
|
-
Post.text :name
|
30
|
-
assert [:name] == Post.text
|
31
|
-
|
32
|
-
Post.number :name
|
33
|
-
Post.number :name
|
34
|
-
assert [:name] == Post.number
|
35
|
-
|
36
|
-
Post.sortable :name
|
37
|
-
Post.sortable :name
|
38
|
-
assert [:name] == Post.sortable
|
39
|
-
end
|
40
|
-
|
41
|
-
class Document < Ohm::Model
|
42
|
-
include Ohm::LunarMacros
|
43
|
-
|
44
|
-
fuzzy :filename
|
45
|
-
text :content
|
46
|
-
number :author_id
|
47
|
-
sortable :views
|
48
|
-
|
49
|
-
attribute :filename
|
50
|
-
attribute :content
|
51
|
-
attribute :author_id
|
52
|
-
attribute :views
|
53
|
-
end
|
54
|
-
|
55
|
-
test "fuzzy indexing" do
|
56
|
-
doc = Document.create(:filename => "amazing.mp3")
|
57
|
-
|
58
|
-
strs = %w{a am ama amaz amazi amazin amazing amazing. amazing.m
|
59
|
-
amazing.mp amazing.mp3}
|
60
|
-
|
61
|
-
strs.each do |str|
|
62
|
-
r = Lunar.search(Document, :fuzzy => { :filename => str })
|
63
|
-
assert r.include?(doc)
|
64
|
-
end
|
65
|
-
|
66
|
-
doc.update(:filename => "crazy.mp3")
|
67
|
-
|
68
|
-
strs = %w{c cr cra craz crazy crazy. crazy.m crazy.mp crazy.mp3}
|
69
|
-
|
70
|
-
strs.each do |str|
|
71
|
-
r = Lunar.search(Document, :fuzzy => { :filename => str })
|
72
|
-
assert r.include?(doc)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
test "text indexing" do
|
77
|
-
doc = Document.create(:content => "The quick brown fox")
|
78
|
-
|
79
|
-
queries = ['quick', 'brown', 'fox', 'quick brown' 'quick fox', 'fox brown',
|
80
|
-
'the quick brown fox']
|
81
|
-
|
82
|
-
queries.each do |q|
|
83
|
-
r = Lunar.search(Document, :q => q)
|
84
|
-
assert r.include?(doc)
|
85
|
-
end
|
86
|
-
|
87
|
-
doc.update(:content => "lazy dog jumps over")
|
88
|
-
|
89
|
-
queries = ['lazy', 'dog', 'jumps', 'over', 'lazy dog', 'jumps over']
|
90
|
-
|
91
|
-
queries.each do |q|
|
92
|
-
r = Lunar.search(Document, :q => q)
|
93
|
-
assert r.include?(doc)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
test "number indexing" do
|
98
|
-
doc = Document.create(:author_id => 99)
|
99
|
-
|
100
|
-
[99..100, 98..99, 98..100].each do |range|
|
101
|
-
r = Lunar.search(Document, :author_id => range)
|
102
|
-
assert r.include?(doc)
|
103
|
-
end
|
104
|
-
|
105
|
-
[97..98, 100..101].each do |range|
|
106
|
-
r = Lunar.search(Document, :author_id => range)
|
107
|
-
assert ! r.include?(doc)
|
108
|
-
end
|
109
|
-
|
110
|
-
doc.update(:author_id => 49)
|
111
|
-
|
112
|
-
[49..50, 48..49, 48..50].each do |range|
|
113
|
-
r = Lunar.search(Document, :author_id => range)
|
114
|
-
assert r.include?(doc)
|
115
|
-
end
|
116
|
-
|
117
|
-
[47..48, 50..51].each do |range|
|
118
|
-
r = Lunar.search(Document, :author_id => range)
|
119
|
-
assert ! r.include?(doc)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
test "sortable indexing" do
|
124
|
-
osx = Document.create(:content => "apple mac osx", :views => 500)
|
125
|
-
iphone = Document.create(:content => "apple iphone", :views => 10_000)
|
126
|
-
|
127
|
-
assert [iphone, osx] == Lunar.search(Document, :q => "apple").sort_by(:views, :order => "DESC")
|
128
|
-
assert [osx, iphone] == Lunar.search(Document, :q => "apple").sort_by(:views, :order => "ASC")
|
129
|
-
|
130
|
-
osx.update(:content => "ios mac osx", :views => 1000)
|
131
|
-
iphone.update(:content => "ios iphone", :views => 500)
|
132
|
-
|
133
|
-
assert [osx, iphone] == Lunar.search(Document, :q => "ios").sort_by(:views, :order => "DESC")
|
134
|
-
assert [iphone, osx] == Lunar.search(Document, :q => "ios").sort_by(:views, :order => "ASC")
|
135
|
-
end
|
136
|
-
|
137
|
-
test "on delete" do
|
138
|
-
doc = Document.create(:filename => "amazing.mp3", :content => "apple mac osx",
|
139
|
-
:author_id => 99, :views => 500)
|
140
|
-
|
141
|
-
doc.delete
|
142
|
-
|
143
|
-
assert Lunar.search(Document, :q => "apple").size.zero?
|
144
|
-
assert Lunar.search(Document, :fuzzy => { :filename => "amazing" }).size.zero?
|
145
|
-
end
|
146
|
-
|