muck-solr 0.4.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 (156) hide show
  1. data/CHANGE_LOG +239 -0
  2. data/LICENSE +19 -0
  3. data/README.markdown +118 -0
  4. data/README.rdoc +107 -0
  5. data/Rakefile +99 -0
  6. data/TESTING_THE_PLUGIN +25 -0
  7. data/VERSION.yml +4 -0
  8. data/config/solr.yml +15 -0
  9. data/config/solr_environment.rb +32 -0
  10. data/lib/acts_as_solr.rb +65 -0
  11. data/lib/acts_as_solr/acts_methods.rb +352 -0
  12. data/lib/acts_as_solr/class_methods.rb +236 -0
  13. data/lib/acts_as_solr/common_methods.rb +89 -0
  14. data/lib/acts_as_solr/deprecation.rb +61 -0
  15. data/lib/acts_as_solr/instance_methods.rb +165 -0
  16. data/lib/acts_as_solr/lazy_document.rb +18 -0
  17. data/lib/acts_as_solr/parser_methods.rb +203 -0
  18. data/lib/acts_as_solr/search_results.rb +68 -0
  19. data/lib/acts_as_solr/solr_fixtures.rb +13 -0
  20. data/lib/acts_as_solr/tasks.rb +10 -0
  21. data/lib/acts_as_solr/tasks/database.rake +16 -0
  22. data/lib/acts_as_solr/tasks/solr.rake +135 -0
  23. data/lib/acts_as_solr/tasks/test.rake +5 -0
  24. data/lib/solr.rb +26 -0
  25. data/lib/solr/connection.rb +177 -0
  26. data/lib/solr/document.rb +75 -0
  27. data/lib/solr/exception.rb +13 -0
  28. data/lib/solr/field.rb +36 -0
  29. data/lib/solr/importer.rb +19 -0
  30. data/lib/solr/importer/array_mapper.rb +26 -0
  31. data/lib/solr/importer/delimited_file_source.rb +38 -0
  32. data/lib/solr/importer/hpricot_mapper.rb +27 -0
  33. data/lib/solr/importer/mapper.rb +51 -0
  34. data/lib/solr/importer/solr_source.rb +41 -0
  35. data/lib/solr/importer/xpath_mapper.rb +35 -0
  36. data/lib/solr/indexer.rb +52 -0
  37. data/lib/solr/request.rb +26 -0
  38. data/lib/solr/request/add_document.rb +58 -0
  39. data/lib/solr/request/base.rb +36 -0
  40. data/lib/solr/request/commit.rb +29 -0
  41. data/lib/solr/request/delete.rb +48 -0
  42. data/lib/solr/request/dismax.rb +46 -0
  43. data/lib/solr/request/index_info.rb +22 -0
  44. data/lib/solr/request/modify_document.rb +46 -0
  45. data/lib/solr/request/optimize.rb +19 -0
  46. data/lib/solr/request/ping.rb +36 -0
  47. data/lib/solr/request/select.rb +54 -0
  48. data/lib/solr/request/spellcheck.rb +30 -0
  49. data/lib/solr/request/standard.rb +402 -0
  50. data/lib/solr/request/update.rb +23 -0
  51. data/lib/solr/response.rb +27 -0
  52. data/lib/solr/response/add_document.rb +17 -0
  53. data/lib/solr/response/base.rb +42 -0
  54. data/lib/solr/response/commit.rb +15 -0
  55. data/lib/solr/response/delete.rb +13 -0
  56. data/lib/solr/response/dismax.rb +8 -0
  57. data/lib/solr/response/index_info.rb +26 -0
  58. data/lib/solr/response/modify_document.rb +17 -0
  59. data/lib/solr/response/optimize.rb +14 -0
  60. data/lib/solr/response/ping.rb +26 -0
  61. data/lib/solr/response/ruby.rb +42 -0
  62. data/lib/solr/response/select.rb +17 -0
  63. data/lib/solr/response/spellcheck.rb +20 -0
  64. data/lib/solr/response/standard.rb +60 -0
  65. data/lib/solr/response/xml.rb +39 -0
  66. data/lib/solr/solrtasks.rb +27 -0
  67. data/lib/solr/util.rb +32 -0
  68. data/lib/solr/xml.rb +44 -0
  69. data/solr/CHANGES.txt +1207 -0
  70. data/solr/LICENSE.txt +712 -0
  71. data/solr/NOTICE.txt +90 -0
  72. data/solr/etc/jetty.xml +205 -0
  73. data/solr/etc/webdefault.xml +379 -0
  74. data/solr/lib/easymock.jar +0 -0
  75. data/solr/lib/jetty-6.1.3.jar +0 -0
  76. data/solr/lib/jetty-util-6.1.3.jar +0 -0
  77. data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  78. data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  79. data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
  80. data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  81. data/solr/lib/servlet-api-2.4.jar +0 -0
  82. data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
  83. data/solr/lib/xpp3-1.1.3.4.O.jar +0 -0
  84. data/solr/solr/README.txt +52 -0
  85. data/solr/solr/bin/abc +176 -0
  86. data/solr/solr/bin/abo +176 -0
  87. data/solr/solr/bin/backup +108 -0
  88. data/solr/solr/bin/backupcleaner +142 -0
  89. data/solr/solr/bin/commit +128 -0
  90. data/solr/solr/bin/optimize +129 -0
  91. data/solr/solr/bin/readercycle +129 -0
  92. data/solr/solr/bin/rsyncd-disable +77 -0
  93. data/solr/solr/bin/rsyncd-enable +76 -0
  94. data/solr/solr/bin/rsyncd-start +145 -0
  95. data/solr/solr/bin/rsyncd-stop +105 -0
  96. data/solr/solr/bin/scripts-util +83 -0
  97. data/solr/solr/bin/snapcleaner +148 -0
  98. data/solr/solr/bin/snapinstaller +168 -0
  99. data/solr/solr/bin/snappuller +248 -0
  100. data/solr/solr/bin/snappuller-disable +77 -0
  101. data/solr/solr/bin/snappuller-enable +77 -0
  102. data/solr/solr/bin/snapshooter +109 -0
  103. data/solr/solr/conf/admin-extra.html +31 -0
  104. data/solr/solr/conf/protwords.txt +21 -0
  105. data/solr/solr/conf/schema.xml +126 -0
  106. data/solr/solr/conf/scripts.conf +24 -0
  107. data/solr/solr/conf/solrconfig.xml +458 -0
  108. data/solr/solr/conf/stopwords.txt +57 -0
  109. data/solr/solr/conf/synonyms.txt +31 -0
  110. data/solr/solr/conf/xslt/example.xsl +132 -0
  111. data/solr/solr/conf/xslt/example_atom.xsl +63 -0
  112. data/solr/solr/conf/xslt/example_rss.xsl +62 -0
  113. data/solr/start.jar +0 -0
  114. data/solr/webapps/solr.war +0 -0
  115. data/test/config/solr.yml +2 -0
  116. data/test/db/connections/mysql/connection.rb +10 -0
  117. data/test/db/connections/sqlite/connection.rb +8 -0
  118. data/test/db/migrate/001_create_books.rb +15 -0
  119. data/test/db/migrate/002_create_movies.rb +12 -0
  120. data/test/db/migrate/003_create_categories.rb +11 -0
  121. data/test/db/migrate/004_create_electronics.rb +16 -0
  122. data/test/db/migrate/005_create_authors.rb +12 -0
  123. data/test/db/migrate/006_create_postings.rb +9 -0
  124. data/test/db/migrate/007_create_posts.rb +13 -0
  125. data/test/db/migrate/008_create_gadgets.rb +11 -0
  126. data/test/fixtures/authors.yml +9 -0
  127. data/test/fixtures/books.yml +13 -0
  128. data/test/fixtures/categories.yml +7 -0
  129. data/test/fixtures/db_definitions/mysql.sql +41 -0
  130. data/test/fixtures/electronics.yml +49 -0
  131. data/test/fixtures/movies.yml +9 -0
  132. data/test/fixtures/postings.yml +10 -0
  133. data/test/functional/acts_as_solr_test.rb +413 -0
  134. data/test/functional/association_indexing_test.rb +37 -0
  135. data/test/functional/faceted_search_test.rb +163 -0
  136. data/test/functional/multi_solr_search_test.rb +57 -0
  137. data/test/models/author.rb +10 -0
  138. data/test/models/book.rb +10 -0
  139. data/test/models/category.rb +8 -0
  140. data/test/models/electronic.rb +25 -0
  141. data/test/models/gadget.rb +9 -0
  142. data/test/models/movie.rb +17 -0
  143. data/test/models/novel.rb +2 -0
  144. data/test/models/post.rb +3 -0
  145. data/test/models/posting.rb +11 -0
  146. data/test/test_helper.rb +54 -0
  147. data/test/unit/acts_methods_shoulda.rb +68 -0
  148. data/test/unit/class_methods_shoulda.rb +85 -0
  149. data/test/unit/common_methods_shoulda.rb +111 -0
  150. data/test/unit/instance_methods_shoulda.rb +318 -0
  151. data/test/unit/lazy_document_shoulda.rb +34 -0
  152. data/test/unit/parser_instance.rb +19 -0
  153. data/test/unit/parser_methods_shoulda.rb +268 -0
  154. data/test/unit/solr_instance.rb +49 -0
  155. data/test/unit/test_helper.rb +24 -0
  156. metadata +241 -0
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), '../test_helper')
2
+
3
+ class AssociationIndexingTest < Test::Unit::TestCase
4
+
5
+ fixtures :categories, :books
6
+
7
+ # Testing the association indexing with has_many:
8
+ #
9
+ # class Category < ActiveRecord::Base
10
+ # has_many :books
11
+ # acts_as_solr :include => [:books]
12
+ # end
13
+ #
14
+ # Note that some of the search terms below are from the 'books'
15
+ # table, but get indexed as being a part of Category
16
+ def test_search_on_fields_in_has_many_association
17
+ ['thriller', 'novel', 'splinter', 'clancy', 'tom clancy thriller'].each do |term|
18
+ assert_equal 1, Category.count_by_solr(term), "expected one result: #{term}"
19
+ end
20
+ end
21
+
22
+ # Testing the association indexing with belongs_to:
23
+ #
24
+ # class Book < ActiveRecord::Base
25
+ # belongs_to :category
26
+ # acts_as_solr :include => [:category]
27
+ # end
28
+ #
29
+ # Note that some of the search terms below are from the 'categories'
30
+ # table, but get indexed as being a part of Book
31
+ def test_search_on_fields_in_belongs_to_association
32
+ ['splinter', 'clancy', 'tom clancy thriller', 'splinter novel'].each do |term|
33
+ assert_equal 1, Book.count_by_solr(term), "expected one result: #{term}"
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,163 @@
1
+ require File.join(File.dirname(__FILE__), '../test_helper')
2
+
3
+ class FacetedSearchTest < Test::Unit::TestCase
4
+
5
+ fixtures :electronics
6
+
7
+ # The tests below are for faceted search, but make sure you setup
8
+ # the fields on your model you'd like to index as a facet field:
9
+ #
10
+ # class Electronic < ActiveRecord::Base
11
+ # acts_as_solr :facets => [:category, :manufacturer]
12
+ # end
13
+ #
14
+ # A basic faceted search using just one facet field
15
+ def test_faceted_search_basic
16
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:category]}
17
+ assert_equal 4, records.docs.size
18
+ assert_match /Apple 60 GB Memory iPod/, records.docs.first.name
19
+ assert_equal({"category_facet" => {"Electronics" => 1,
20
+ "Memory" => 2,
21
+ "Hard Drive" => 1}},
22
+ records.facets['facet_fields'])
23
+ end
24
+
25
+ # Making sure the empty result returned what we expected
26
+ def test_faceted_search_no_matches
27
+ records = Electronic.find_by_solr "not found", :facets => { :fields => [:category]}
28
+ assert_equal [], records.docs
29
+ assert_equal [], records.facets['facet_fields']
30
+ end
31
+
32
+ # A basic faceted search using multiple facet fields
33
+ def test_faceted_search_multiple_fields
34
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:category, :manufacturer]}
35
+ assert_equal 4, records.docs.size
36
+ assert_equal({"category_facet" => {"Electronics" => 1,
37
+ "Memory" => 2,
38
+ "Hard Drive" => 1},
39
+ "manufacturer_facet" => {"Dell, Inc" => 0,
40
+ "Samsung Electronics Co. Ltd." => 1,
41
+ "Corsair Microsystems Inc." => 1,
42
+ "A-DATA Technology Inc." => 1,
43
+ "Apple Computer Inc." => 1}}, records.facets['facet_fields'])
44
+ end
45
+
46
+ # A basic faceted search using facet queries to get counts.
47
+ # Here are the facets search query meaning:
48
+ # "price:[* TO 200]" - Price up to 200
49
+ # "price:[200 TO 500]" - Price from 200 to 500
50
+ # "price:[500 TO *]" - Price higher than 500
51
+ def test_facet_search_with_query
52
+ records = Electronic.find_by_solr "memory", :facets => {:query => ["price:[* TO 200.00]",
53
+ "price:[200.00 TO 500.00]",
54
+ "price:[500.00 TO *]"]}
55
+ assert_equal 4, records.docs.size
56
+ assert_equal({"facet_queries" => {"price_rf:[* TO 200.00]"=>2,
57
+ "price_rf:[200.00 TO 500.00]"=>1,
58
+ "price_rf:[500.00 TO *]"=>1},
59
+ "facet_fields" => {}, "facet_dates" => {}}, records.facets)
60
+ end
61
+
62
+ # Faceted search specifying the query and fields
63
+ def test_facet_search_with_query_and_field
64
+ records = Electronic.find_by_solr "memory", :facets => {:query => ["price:[* TO 200.00]",
65
+ "price:[200.00 TO 500.00]",
66
+ "price:[500.00 TO *]"],
67
+ :fields => [:category, :manufacturer]}
68
+
69
+ q = records.facets["facet_queries"]
70
+ assert_equal 2, q["price_rf:[* TO 200.00]"]
71
+ assert_equal 1, q["price_rf:[500.00 TO *]"]
72
+ assert_equal 1, q["price_rf:[200.00 TO 500.00]"]
73
+
74
+ f = records.facets["facet_fields"]
75
+ assert_equal 1, f["category_facet"]["Electronics"]
76
+ assert_equal 2, f["category_facet"]["Memory"]
77
+ assert_equal 1, f["category_facet"]["Hard Drive"]
78
+ assert_equal 1, f["manufacturer_facet"]["Samsung Electronics Co. Ltd."]
79
+ assert_equal 1, f["manufacturer_facet"]["Corsair Microsystems Inc."]
80
+ assert_equal 1, f["manufacturer_facet"]["A-DATA Technology Inc."]
81
+ assert_equal 1, f["manufacturer_facet"]["Apple Computer Inc."]
82
+ end
83
+
84
+ # Faceted searches with :sort and :zeros options turned on/off
85
+ def test_faceted_search_using_zero_and_sort
86
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:category]}
87
+ assert_equal({"category_facet"=>{"Electronics"=>1, "Memory"=>2, "Hard Drive"=>1}}, records.facets['facet_fields'])
88
+
89
+ records = Electronic.find_by_solr "memory", :facets => {:sort => true, :fields =>[:category]}
90
+ assert_equal({"category_facet"=>{"Memory"=>2, "Electronics"=>1, "Hard Drive"=>1}}, records.facets['facet_fields'])
91
+
92
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:manufacturer]}
93
+ assert_equal({"manufacturer_facet" => {"Dell, Inc" => 0,
94
+ "Samsung Electronics Co. Ltd." => 1,
95
+ "Corsair Microsystems Inc." => 1,
96
+ "A-DATA Technology Inc." => 1,
97
+ "Apple Computer Inc." => 1}}, records.facets['facet_fields'])
98
+
99
+ records = Electronic.find_by_solr "memory", :facets => {:zeros => false, :fields =>[:manufacturer]}
100
+ assert_equal({"manufacturer_facet" => {"Samsung Electronics Co. Ltd." => 1,
101
+ "Corsair Microsystems Inc." => 1,
102
+ "A-DATA Technology Inc." => 1,
103
+ "Apple Computer Inc." => 1}}, records.facets['facet_fields'])
104
+ end
105
+
106
+ # Faceted search with 'drill-down' option being passed.
107
+ # The :browse option receives the argument in the format:
108
+ # "facet_field:term". You can drill-down to as many
109
+ # facet fields as you like
110
+ def test_faceted_search_with_drill_down
111
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:category]}
112
+ assert_equal 4, records.docs.size
113
+ assert_equal({"category_facet"=>{"Electronics"=>1, "Memory"=>2, "Hard Drive"=>1}}, records.facets['facet_fields'])
114
+
115
+ records = Electronic.find_by_solr "memory", :facets => {:fields =>[:category],
116
+ :browse => "category:Memory",
117
+ :zeros => false}
118
+ assert_equal 2, records.docs.size
119
+ assert_equal({"category_facet"=>{"Memory"=>2}}, records.facets['facet_fields'])
120
+ end
121
+
122
+ def test_faceted_search_with_dates
123
+ records = Electronic.find_by_solr "memory", :facets => {:dates => {:fields => [:created_at, :updated_at],
124
+ :start => (Date.today - 7.years).strftime("%Y-%m-%dT%H:%M:%SZ"), :end => Date.today.strftime("%Y-%m-%dT%H:%M:%SZ"), :gap => '+1YEAR', :other => :all}}
125
+
126
+ assert_equal 4, records.docs.size
127
+
128
+ assert_equal 0, records.facets["facet_dates"]["created_at_d"]["after"]
129
+ assert_equal 1, records.facets["facet_dates"]["created_at_d"]["before"]
130
+ assert_equal 3, records.facets["facet_dates"]["created_at_d"]["between"]
131
+
132
+ assert_equal 0, records.facets["facet_dates"]["updated_at_d"]["after"]
133
+ assert_equal 0, records.facets["facet_dates"]["updated_at_d"]["before"]
134
+ assert_equal 4, records.facets["facet_dates"]["updated_at_d"]["between"]
135
+ end
136
+
137
+ def test_faceted_search_with_dates_filter
138
+ records = Electronic.find_by_solr "memory", :facets => {:dates => {:filter => ["updated_at:[#{(Date.today - 3.months).strftime("%Y-%m-%dT%H:%M:%SZ")} TO NOW-1MONTH/DAY]"]}}
139
+
140
+ assert_equal 2, records.docs.size
141
+
142
+ records.docs.each { |r|
143
+ assert r.updated_at >= (Date.today - 3.month)
144
+ assert r.updated_at <= (Date.today - 1.month)
145
+ }
146
+ end
147
+
148
+ def test_faceted_search_with_dates_filter_and_facets
149
+ # this is a very contrived example but gives us data to validate
150
+ records = Electronic.find_by_solr "memory", :facets => {:dates => {:filter => ["updated_at:[#{(Date.today - 3.months).strftime("%Y-%m-%dT%H:%M:%SZ")} TO NOW-1MONTH/DAY]"],
151
+ :fields => [:created_at, :updated_at], :start => 'NOW-2MONTHS/DAY', :end => 'NOW-1MONTH/DAY', :gap => '+1MONTH', :other => :all}}
152
+
153
+ assert_equal 2, records.docs.size
154
+
155
+ assert_equal 0, records.facets["facet_dates"]["created_at_d"]["after"]
156
+ assert_equal 2, records.facets["facet_dates"]["created_at_d"]["before"]
157
+ assert_equal 0, records.facets["facet_dates"]["created_at_d"]["between"]
158
+
159
+ assert_equal 0, records.facets["facet_dates"]["updated_at_d"]["after"]
160
+ assert_equal 1, records.facets["facet_dates"]["updated_at_d"]["before"]
161
+ assert_equal 1, records.facets["facet_dates"]["updated_at_d"]["between"]
162
+ end
163
+ end
@@ -0,0 +1,57 @@
1
+ require File.join(File.dirname(__FILE__), '../test_helper')
2
+
3
+ class ActsAsSolrTest < Test::Unit::TestCase
4
+
5
+ fixtures :books, :movies
6
+
7
+ # Testing the multi_solr_search with the returning results being objects
8
+ def test_multi_solr_search_return_objects
9
+ records = Book.multi_solr_search "Napoleon OR Tom", :models => [Movie], :results_format => :objects
10
+ assert_equal 2, records.total
11
+ classes = records.docs.map {|d| d.class}
12
+ assert classes.include?(Book)
13
+ assert classes.include?(Movie)
14
+ end
15
+
16
+ # Testing the multi_solr_search with the returning results being ids
17
+ def test_multi_solr_search_return_ids
18
+ records = Book.multi_solr_search "Napoleon OR Tom", :models => [Movie], :results_format => :ids
19
+ assert_equal 2, records.total
20
+ assert records.docs.include?({"id" => "Movie:1"})
21
+ assert records.docs.include?({"id" => "Book:1"})
22
+ end
23
+
24
+ # Testing the multi_solr_search with multiple models
25
+ def test_multi_solr_search_multiple_models
26
+ # TODO: Generalize me
27
+ ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => 'type_s:Author AND NOT id:"Author:1" AND NOT id:"Author:2"'))
28
+ ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => 'type_s:Book AND NOT id:"Book:1" AND NOT id:"Book:2"'))
29
+ ActsAsSolr::Post.execute(Solr::Request::Commit.new)
30
+
31
+ records = Book.multi_solr_search "Napoleon OR Tom OR Thriller", :models => [Movie, Category], :results_format => :ids
32
+ assert_equal 3, records.total
33
+ assert records.docs.include?({"id" => "Category:1"})
34
+ assert records.docs.include?({"id" =>"Book:1"})
35
+ assert records.docs.include?({"id" => "Movie:1"})
36
+ end
37
+
38
+ # Testing empty result set format
39
+ def test_returns_no_matches
40
+ records = Book.multi_solr_search "not found", :models => [Movie, Category]
41
+ assert_equal [], records.docs
42
+ assert_equal 0, records.total
43
+ end
44
+
45
+ def test_search_on_empty_string_does_not_return_nil
46
+ records = Book.multi_solr_search('', :models => [Movie, Category])
47
+ assert_not_nil records
48
+ assert_equal [], records.docs
49
+ assert_equal 0, records.total
50
+ end
51
+
52
+ def test_search_with_score_should_set_score
53
+ records = Book.multi_solr_search "Napoleon OR Tom", :models => [Movie], :results_format => :objects, :scores => true
54
+ assert records.docs.first.solr_score.is_a?(Float)
55
+ assert records.docs.last.solr_score.is_a?(Float)
56
+ end
57
+ end
@@ -0,0 +1,10 @@
1
+ # Table fields for 'movies'
2
+ # - id
3
+ # - name
4
+ # - biography
5
+
6
+ class Author < ActiveRecord::Base
7
+
8
+ acts_as_solr :auto_commit => false
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ # Table fields for 'books'
2
+ # - id
3
+ # - category_id
4
+ # - name
5
+ # - author
6
+
7
+ class Book < ActiveRecord::Base
8
+ belongs_to :category
9
+ acts_as_solr :include => [:category]
10
+ end
@@ -0,0 +1,8 @@
1
+ # Table fields for 'categories'
2
+ # - id
3
+ # - name
4
+
5
+ class Category < ActiveRecord::Base
6
+ has_many :books
7
+ acts_as_solr :include => [:books]
8
+ end
@@ -0,0 +1,25 @@
1
+ # Table fields for 'electronics'
2
+ # - id
3
+ # - name
4
+ # - manufacturer
5
+ # - features
6
+ # - category
7
+ # - price
8
+ # - created_on
9
+
10
+ class Electronic < ActiveRecord::Base
11
+ acts_as_solr do
12
+ {
13
+ :facets => [:category, :manufacturer],
14
+ :fields => [:name, :manufacturer, :features, :category, {:created_at => :date}, {:updated_at => :date}, {:price => {:type => :range_float, :boost => 10.0}}],
15
+ :boost => 5.0,
16
+ :exclude_fields => [:features]
17
+ }
18
+ end
19
+
20
+ # The following example would also convert the :price field type to :range_float
21
+ #
22
+ # acts_as_solr :facets => [:category, :manufacturer],
23
+ # :fields => [:name, :manufacturer, :features, :category, {:price => :range_float}],
24
+ # :boost => 5.0
25
+ end
@@ -0,0 +1,9 @@
1
+ class Gadget < ActiveRecord::Base
2
+ cattr_accessor :search_disabled
3
+
4
+ acts_as_solr :offline => proc {|record| Gadget.search_disabled?}, :format => :ids
5
+
6
+ def self.search_disabled?
7
+ search_disabled
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ # Table fields for 'movies'
2
+ # - id
3
+ # - name
4
+ # - description
5
+
6
+ class Movie < ActiveRecord::Base
7
+ acts_as_solr :additional_fields => [:current_time, {:time_on_xml => :date}]
8
+
9
+ def current_time
10
+ Time.now.to_s
11
+ end
12
+
13
+ def time_on_xml
14
+ Time.now
15
+ end
16
+
17
+ end
@@ -0,0 +1,2 @@
1
+ class Novel < Book
2
+ end
@@ -0,0 +1,3 @@
1
+ class Post < ActiveRecord::Base
2
+ acts_as_solr
3
+ end
@@ -0,0 +1,11 @@
1
+ # Table fields for 'movies'
2
+ # - guid
3
+ # - name
4
+ # - description
5
+
6
+ class Posting < ActiveRecord::Base
7
+
8
+ set_primary_key 'guid'
9
+ acts_as_solr({},{:primary_key_field => 'pk_s'})
10
+
11
+ end
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_record'
4
+ require 'active_record/fixtures'
5
+
6
+ begin
7
+ require 'active_support/test_case'
8
+ rescue
9
+ end
10
+
11
+ RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT
12
+ RAILS_ENV = 'test' unless defined? RAILS_ENV
13
+ ENV["RAILS_ENV"] = "test"
14
+ ENV["ACTS_AS_SOLR_TEST"] = "true"
15
+
16
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/acts_as_solr')
17
+ require File.expand_path(File.dirname(__FILE__) + '/../config/solr_environment.rb')
18
+
19
+ # Load Models
20
+ models_dir = File.join(File.dirname( __FILE__ ), 'models')
21
+ require "#{models_dir}/book.rb"
22
+ Dir[ models_dir + '/*.rb'].each { |m| require m }
23
+
24
+ if defined?(ActiveSupport::TestCase)
25
+ class ActiveSupport::TestCase
26
+ include ActiveRecord::TestFixtures
27
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
28
+ end unless ActiveSupport::TestCase.respond_to?(:fixture_path=)
29
+ else
30
+ Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
31
+ end
32
+
33
+ class Test::Unit::TestCase
34
+ def self.fixtures(*table_names)
35
+ fixture_path = defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase.fixture_path : Test::Unit::TestCase.fixture_path
36
+ if block_given?
37
+ Fixtures.create_fixtures(fixture_path, table_names) { yield }
38
+ else
39
+ Fixtures.create_fixtures(fixture_path, table_names)
40
+ end
41
+ table_names.each do |table_name|
42
+ clear_from_solr(table_name)
43
+ klass = instance_eval table_name.to_s.capitalize.singularize
44
+ klass.find(:all).each{|content| content.solr_save}
45
+ end
46
+
47
+ clear_from_solr(:novels)
48
+ end
49
+
50
+ private
51
+ def self.clear_from_solr(table_name)
52
+ ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => "type_s:#{table_name.to_s.capitalize.singularize}"))
53
+ end
54
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class ActsMethodsTest < Test::Unit::TestCase
4
+ class Model
5
+ attr_accessor :birthdate
6
+
7
+ def initialize(birthdate)
8
+ @birthdate = birthdate
9
+ end
10
+
11
+ def self.configuration
12
+ @configuration ||= {:solr_fields => {}}
13
+ end
14
+
15
+ def self.columns_hash=(columns_hash)
16
+ @columns_hash = columns_hash
17
+ end
18
+
19
+ def self.columns_hash
20
+ @columns_hash
21
+ end
22
+
23
+ def [](key)
24
+ @birthday
25
+ end
26
+
27
+ self.extend ActsAsSolr::ActsMethods
28
+ end
29
+
30
+
31
+ context "when getting field values" do
32
+ setup do
33
+ Model.columns_hash = {"birthdate" => stub("column", :type => :date)}
34
+ Model.send(:get_field_value, :birthdate)
35
+ end
36
+
37
+ should "define an accessor methods for a solr converted value" do
38
+ assert Model.instance_methods.include?("birthdate_for_solr")
39
+ end
40
+
41
+ context "for date types" do
42
+ setup do
43
+ @model = Model.new(Date.today)
44
+ end
45
+
46
+ should "return nil when field is nil" do
47
+ @model.birthdate = nil
48
+ assert_nil @model.birthdate_for_solr
49
+ end
50
+
51
+ should "return the formatted date" do
52
+ assert_equal Date.today.strftime("%Y-%m-%dT%H:%M:%SZ"), @model.birthdate_for_solr
53
+ end
54
+ end
55
+
56
+ context "for timestamp types" do
57
+ setup do
58
+ @now = Time.now
59
+ @model = Model.new(@now)
60
+ end
61
+
62
+ should "return a formatted timestamp string for timestamps" do
63
+ assert_equal @now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"), @model.birthdate_for_solr
64
+ end
65
+ end
66
+ end
67
+
68
+ end