dnif 0.0.1.beta.3 → 0.0.1.beta.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +52 -0
- data/Rakefile +24 -26
- data/dnif.gemspec +81 -55
- data/lib/dnif.rb +73 -24
- data/lib/dnif/configuration.rb +4 -3
- data/lib/dnif/document.rb +8 -8
- data/lib/dnif/indexer.rb +0 -2
- data/lib/dnif/schema.rb +1 -1
- data/lib/dnif/search.rb +1 -50
- data/lib/dnif/tasks.rb +11 -11
- data/lib/dnif/version.rb +10 -0
- data/spec/dnif/configuration_spec.rb +41 -0
- data/spec/dnif/dnif_spec.rb +157 -0
- data/spec/dnif/document_spec.rb +46 -0
- data/spec/dnif/index_spec.rb +20 -0
- data/spec/dnif/indexer_spec.rb +64 -0
- data/spec/dnif/multi_attribute_spec.rb +20 -0
- data/{test/unit/test_schema.rb → spec/dnif/schema_spec.rb} +5 -5
- data/spec/dnif/search_spec.rb +18 -0
- data/{test → spec}/fixtures/db/schema.rb +1 -0
- data/{test → spec}/fixtures/log/searchd.pid +0 -0
- data/{test → spec}/fixtures/models.rb +0 -0
- data/{test → spec}/fixtures/sphinx_1.xml +1 -0
- data/{test → spec}/fixtures/sphinx_2.xml +1 -0
- data/{test → spec}/fixtures/sphinx_3.xml +1 -0
- data/{test → spec}/fixtures/sphinx_4.xml +1 -0
- data/{test → spec}/fixtures/sphinx_5.xml +1 -0
- data/{test → spec}/fixtures/templates/config.erb +0 -0
- data/spec/spec_helper.rb +31 -0
- data/{test/test_helper.rb → spec/support/activerecord/models.rb} +2 -21
- data/templates/config.erb +38 -0
- metadata +158 -46
- data/lib/dnif/index_builder.rb +0 -30
- data/test/unit/test_configuration.rb +0 -37
- data/test/unit/test_dnif.rb +0 -21
- data/test/unit/test_document.rb +0 -41
- data/test/unit/test_index.rb +0 -21
- data/test/unit/test_index_builder.rb +0 -33
- data/test/unit/test_indexer.rb +0 -60
- data/test/unit/test_multi_attribute.rb +0 -17
- data/test/unit/test_search.rb +0 -116
data/lib/dnif/index_builder.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Dnif
|
2
|
-
class IndexBuilder
|
3
|
-
|
4
|
-
attr_reader :fields
|
5
|
-
attr_reader :attributes
|
6
|
-
attr_reader :conditions
|
7
|
-
|
8
|
-
def initialize(object, &block)
|
9
|
-
@fields = []
|
10
|
-
@attributes = {}
|
11
|
-
|
12
|
-
@object = object
|
13
|
-
self.instance_eval(&block)
|
14
|
-
end
|
15
|
-
|
16
|
-
def field(name)
|
17
|
-
@fields << name
|
18
|
-
end
|
19
|
-
|
20
|
-
def attribute(name, options)
|
21
|
-
raise "You must specify the attribute type (:integer, :datetime, :date, :boolean, :float)" if options[:type].nil?
|
22
|
-
|
23
|
-
@attributes[name] = options[:type]
|
24
|
-
end
|
25
|
-
|
26
|
-
def where(conditions)
|
27
|
-
@conditions = conditions
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
require 'erb'
|
4
|
-
|
5
|
-
class TestConfiguration < Test::Unit::TestCase
|
6
|
-
|
7
|
-
test "generate configuration from default template" do
|
8
|
-
File.expects(:read).with("config/path.erb").returns("configurations")
|
9
|
-
|
10
|
-
template = mock("Template")
|
11
|
-
template.expects(:result).returns('output')
|
12
|
-
ERB.expects(:new).with("configurations").returns(template)
|
13
|
-
|
14
|
-
file = mock
|
15
|
-
file.expects(:puts).with('output')
|
16
|
-
File.expects(:open).with(Dnif.root_path + "/config/sphinx/development.conf", "w").yields(file)
|
17
|
-
|
18
|
-
Dnif::Configuration.generate("config/path.erb")
|
19
|
-
end
|
20
|
-
|
21
|
-
test "sources should iterate over all indexed classes" do
|
22
|
-
names = []
|
23
|
-
classes = []
|
24
|
-
Dnif::Configuration.sources do |name, class_name|
|
25
|
-
names << name
|
26
|
-
classes << class_name
|
27
|
-
end
|
28
|
-
|
29
|
-
assert_equal ["users_main", "people_main", "orders_main", "notes_main"], names
|
30
|
-
assert_equal ["User", "Person", "Order", "Note"], classes
|
31
|
-
end
|
32
|
-
|
33
|
-
test ".options_for" do
|
34
|
-
client = Dnif::Configuration.options_for("searchd", File.join(Dnif.root_path, "templates", "config.erb"))
|
35
|
-
assert client.is_a?(Hash)
|
36
|
-
end
|
37
|
-
end
|
data/test/unit/test_dnif.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestDnif < Test::Unit::TestCase
|
5
|
-
|
6
|
-
test ".root_path" do
|
7
|
-
Dnif.root_path = "/root/path"
|
8
|
-
assert_equal "/root/path", Dnif.root_path
|
9
|
-
end
|
10
|
-
|
11
|
-
test ".environment" do
|
12
|
-
assert_equal "development", Dnif.environment
|
13
|
-
Dnif.environment = "production"
|
14
|
-
assert_equal "production", Dnif.environment
|
15
|
-
end
|
16
|
-
|
17
|
-
test ".models_path" do
|
18
|
-
Dnif.models_path = "/models/path"
|
19
|
-
assert_equal "/models/path", Dnif.models_path
|
20
|
-
end
|
21
|
-
end
|
data/test/unit/test_document.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestDocument < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def setup
|
7
|
-
DatabaseCleaner.start
|
8
|
-
end
|
9
|
-
|
10
|
-
def teardown
|
11
|
-
DatabaseCleaner.clean
|
12
|
-
end
|
13
|
-
|
14
|
-
test ".generate" do
|
15
|
-
Dnif::MultiAttribute.expects(:encode).with("User").returns("1,2,3,4")
|
16
|
-
|
17
|
-
user = User.create!(:name => "Rafael Souza", :active => true)
|
18
|
-
|
19
|
-
document = Dnif::Document.new(user)
|
20
|
-
expected = File.read(File.dirname(__FILE__) + "/../fixtures/sphinx_5.xml")
|
21
|
-
assert_equal expected, document.generate
|
22
|
-
end
|
23
|
-
|
24
|
-
test "convertion of date/datetime values to timestamp" do
|
25
|
-
now = DateTime.now
|
26
|
-
now.expects(:to_i)
|
27
|
-
expire = Date.today + 2.days
|
28
|
-
expire.expects(:to_i)
|
29
|
-
expire.expects(:to_datetime).returns(expire)
|
30
|
-
|
31
|
-
note = Note.create!(
|
32
|
-
:title => "Note Title",
|
33
|
-
:clicked => 10,
|
34
|
-
:published_at => now,
|
35
|
-
:expire_at => expire,
|
36
|
-
:active => true,
|
37
|
-
:points => 1000
|
38
|
-
)
|
39
|
-
note.to_sphinx
|
40
|
-
end
|
41
|
-
end
|
data/test/unit/test_index.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestIndex < Test::Unit::TestCase
|
5
|
-
|
6
|
-
test "field definition" do
|
7
|
-
index = Dnif::Index.new(&proc { field :name })
|
8
|
-
assert_equal [:name], index.fields
|
9
|
-
end
|
10
|
-
|
11
|
-
test "attribute definition" do
|
12
|
-
index = Dnif::Index.new(&proc { attribute :another, :type => :bool })
|
13
|
-
expected = { :another => :bool }
|
14
|
-
assert_equal expected, index.attributes
|
15
|
-
end
|
16
|
-
|
17
|
-
test "where definition" do
|
18
|
-
index = Dnif::Index.new(&proc { where "field = 'value'" })
|
19
|
-
assert_equal "field = 'value'", index.conditions
|
20
|
-
end
|
21
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestIndexBuilder < Test::Unit::TestCase
|
5
|
-
|
6
|
-
test "object" do
|
7
|
-
instance = Object.new
|
8
|
-
assert_equal instance, Dnif::IndexBuilder.new(instance, & proc {}).instance_variable_get("@object")
|
9
|
-
end
|
10
|
-
|
11
|
-
test "fields" do
|
12
|
-
builder = Dnif::IndexBuilder.new(Object.new, & proc {})
|
13
|
-
builder.field(:first_name)
|
14
|
-
builder.field(:last_name)
|
15
|
-
|
16
|
-
assert_equal [:first_name, :last_name], builder.fields
|
17
|
-
end
|
18
|
-
|
19
|
-
test "attribute" do
|
20
|
-
builder = Dnif::IndexBuilder.new(Object.new, & proc {})
|
21
|
-
builder.attribute(:ordered_at, :type => :datetime)
|
22
|
-
|
23
|
-
expected = { :ordered_at => :datetime }
|
24
|
-
assert_equal expected, builder.attributes
|
25
|
-
end
|
26
|
-
|
27
|
-
test "where" do
|
28
|
-
builder = Dnif::IndexBuilder.new(Object.new, & proc {})
|
29
|
-
builder.where("status = 'active'")
|
30
|
-
|
31
|
-
assert_equal "status = 'active'", builder.conditions
|
32
|
-
end
|
33
|
-
end
|
data/test/unit/test_indexer.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestIndexer < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def setup
|
7
|
-
DatabaseCleaner.start
|
8
|
-
end
|
9
|
-
|
10
|
-
def teardown
|
11
|
-
DatabaseCleaner.clean
|
12
|
-
end
|
13
|
-
|
14
|
-
test ".define_index" do
|
15
|
-
klass = Class.new
|
16
|
-
klass.extend(Dnif::Indexer)
|
17
|
-
klass.stubs(:name).returns("Klass")
|
18
|
-
klass.define_index do
|
19
|
-
field :a
|
20
|
-
attribute :b, :type => :integer
|
21
|
-
where "c"
|
22
|
-
end
|
23
|
-
|
24
|
-
assert_equal [:a], klass.indexes["Klass"].fields
|
25
|
-
assert_equal({ :b => :integer }, klass.indexes["Klass"].attributes)
|
26
|
-
assert_equal "c", klass.indexes["Klass"].conditions
|
27
|
-
|
28
|
-
klass.indexes.delete("Klass")
|
29
|
-
end
|
30
|
-
|
31
|
-
test "objects without index should not have dnif included" do
|
32
|
-
assert_false Post.new.respond_to?(:to_sphinx)
|
33
|
-
assert_false Post.respond_to?(:to_sphinx)
|
34
|
-
end
|
35
|
-
|
36
|
-
test "to_sphinx returns a string with sphinx document" do
|
37
|
-
comment = Person.create!(:first_name => "Rafael", :last_name => "Souza")
|
38
|
-
|
39
|
-
expected = File.read(File.dirname(__FILE__) + "/../fixtures/sphinx_3.xml")
|
40
|
-
assert_equal expected, comment.to_sphinx
|
41
|
-
end
|
42
|
-
|
43
|
-
test "attributes" do
|
44
|
-
note = Note.create!(:title => "Note Title", :clicked => 10, :published_at => (now = DateTime.now), :expire_at => (expire = Date.today + 2.days), :active => true, :points => 1000)
|
45
|
-
|
46
|
-
expected = File.read(File.dirname(__FILE__) + "/../fixtures/sphinx_2.xml")
|
47
|
-
assert_equal expected.gsub("{now}", now.to_i.to_s).gsub("{expire}", expire.to_datetime.to_i.to_s), note.to_sphinx
|
48
|
-
end
|
49
|
-
|
50
|
-
test ".to_sphinx should generate a full sphinx xml" do
|
51
|
-
comment = Person.create!(:first_name => "Rafael", :last_name => "Souza")
|
52
|
-
|
53
|
-
expected = File.read(File.dirname(__FILE__) + "/../fixtures/sphinx_1.xml")
|
54
|
-
assert_equal expected.gsub("{comment}", comment.to_sphinx), Person.to_sphinx
|
55
|
-
end
|
56
|
-
|
57
|
-
test "return all indexed classes" do
|
58
|
-
assert_equal ["User", "Person", "Order", "Note"], ActiveRecord::Base.indexes.keys
|
59
|
-
end
|
60
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestMultiAttribute < Test::Unit::TestCase
|
5
|
-
|
6
|
-
test ".encode" do
|
7
|
-
assert_equal "324,622,873,1126", Dnif::MultiAttribute.encode("Dnif")
|
8
|
-
end
|
9
|
-
|
10
|
-
test ".decode" do
|
11
|
-
assert_equal "Dnif", Dnif::MultiAttribute.decode("324,622,873,1126")
|
12
|
-
end
|
13
|
-
|
14
|
-
test ".decode as array" do
|
15
|
-
assert_equal "Dnif", Dnif::MultiAttribute.decode(["324", "622", "873", "1126"])
|
16
|
-
end
|
17
|
-
end
|
data/test/unit/test_search.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class TestSearch < Test::Unit::TestCase
|
5
|
-
|
6
|
-
test ".config_path with nil root_path" do
|
7
|
-
File.expects(:expand_path).returns("/expanded/path")
|
8
|
-
Dnif.expects(:root_path).twice.returns(nil, ".")
|
9
|
-
Dnif.expects(:root_path=).with("/expanded/path")
|
10
|
-
Dnif.expects(:environment).returns("development")
|
11
|
-
|
12
|
-
assert_equal "./config/sphinx/development.erb", Dnif.config_path
|
13
|
-
end
|
14
|
-
|
15
|
-
test ".config_path with defined root_path" do
|
16
|
-
Dnif.expects(:root_path).twice.returns("/root/path", "/root/path")
|
17
|
-
Dnif.expects(:environment).returns("development")
|
18
|
-
|
19
|
-
assert_equal "/root/path/config/sphinx/development.erb", Dnif.config_path
|
20
|
-
end
|
21
|
-
|
22
|
-
test ".client when config uses listen" do
|
23
|
-
Dnif.expects(:config_path).returns("config/path.erb")
|
24
|
-
Dnif::Configuration.expects(:options_for).with("searchd", "config/path.erb").returns({ "listen" => "127.0.0.1:3313" })
|
25
|
-
Riddle::Client.expects(:new).with("127.0.0.1", "3313")
|
26
|
-
|
27
|
-
Dnif.client
|
28
|
-
end
|
29
|
-
|
30
|
-
test ".client when config uses address and port" do
|
31
|
-
Dnif.expects(:config_path).returns("config/path.erb")
|
32
|
-
Dnif::Configuration.expects(:options_for).with("searchd", "config/path.erb").returns({ "address" => "127.0.0.1", "port" => "3313" })
|
33
|
-
Riddle::Client.expects(:new).with("127.0.0.1", "3313")
|
34
|
-
|
35
|
-
Dnif.client
|
36
|
-
end
|
37
|
-
|
38
|
-
test ".search" do
|
39
|
-
results = {
|
40
|
-
:matches => [{
|
41
|
-
:doc => 2983,
|
42
|
-
:attributes => {
|
43
|
-
"class_name" => "336,623,883,1140"
|
44
|
-
}
|
45
|
-
}, {
|
46
|
-
:doc => 7893,
|
47
|
-
:attributes => {
|
48
|
-
"class_name" => "323,623,877,1133,1381,1646,1908"
|
49
|
-
}
|
50
|
-
}]
|
51
|
-
}
|
52
|
-
|
53
|
-
riddle = mock("Riddle")
|
54
|
-
riddle.expects(:query).with("my search", "*").returns(results)
|
55
|
-
Dnif.expects(:client).returns(riddle)
|
56
|
-
Post.expects(:find_all_by_id).once.with([1])
|
57
|
-
Comment.expects(:find_all_by_id).once.with([2])
|
58
|
-
|
59
|
-
Dnif.search("my search")
|
60
|
-
end
|
61
|
-
|
62
|
-
test ".search through models" do
|
63
|
-
riddle = mock("Riddle")
|
64
|
-
riddle.expects(:query).with("post", "*").returns(results_for_post)
|
65
|
-
riddle.expects(:query).with("comment", "*").returns(results_for_comment)
|
66
|
-
riddle.expects(:filters=).twice.returns([])
|
67
|
-
Dnif.expects(:client).times(4).returns(riddle)
|
68
|
-
|
69
|
-
ActiveRecord::Base.expects(:indexes).twice.returns({ "Post" => mock, "Comment" => mock })
|
70
|
-
|
71
|
-
Riddle::Client::Filter.expects(:new).with("class_id", [0])
|
72
|
-
Riddle::Client::Filter.expects(:new).with("class_id", [1])
|
73
|
-
|
74
|
-
Post.expects(:find_all_by_id).once.with([1])
|
75
|
-
Comment.expects(:find_all_by_id).once.with([2])
|
76
|
-
|
77
|
-
Post.search("post")
|
78
|
-
Comment.search("comment")
|
79
|
-
end
|
80
|
-
|
81
|
-
test "search only in specified models" do
|
82
|
-
riddle = mock("Riddle")
|
83
|
-
riddle.expects(:query).with("post", "*").returns(results_for_post)
|
84
|
-
riddle.expects(:filters=).returns([])
|
85
|
-
Dnif.expects(:client).times(2).returns(riddle)
|
86
|
-
|
87
|
-
ActiveRecord::Base.expects(:indexes).returns({ "Post" => mock })
|
88
|
-
|
89
|
-
Riddle::Client::Filter.expects(:new).with("class_id", [0])
|
90
|
-
Post.expects(:find_all_by_id).once.with([1])
|
91
|
-
|
92
|
-
Dnif.search("post", :classes => "Post")
|
93
|
-
end
|
94
|
-
|
95
|
-
def results_for_post
|
96
|
-
{
|
97
|
-
:matches => [{
|
98
|
-
:doc => 2983,
|
99
|
-
:attributes => {
|
100
|
-
"class_name" => "336,623,883,1140"
|
101
|
-
}
|
102
|
-
}]
|
103
|
-
}
|
104
|
-
end
|
105
|
-
|
106
|
-
def results_for_comment
|
107
|
-
{
|
108
|
-
:matches => [{
|
109
|
-
:doc => 7893,
|
110
|
-
:attributes => {
|
111
|
-
"class_name" => "323,623,877,1133,1381,1646,1908"
|
112
|
-
}
|
113
|
-
}]
|
114
|
-
}
|
115
|
-
end
|
116
|
-
end
|