thinking-sphinx 2.1.0 → 3.0.0.pre

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 (352) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +7 -0
  4. data/Gemfile +10 -0
  5. data/HISTORY +2 -267
  6. data/LICENCE +1 -1
  7. data/README.textile +194 -226
  8. data/Rakefile +24 -0
  9. data/gemfiles/.gitignore +1 -0
  10. data/gemfiles/rails_3_1.gemfile +11 -0
  11. data/gemfiles/rails_3_2.gemfile +11 -0
  12. data/lib/thinking-sphinx.rb +1 -1
  13. data/lib/thinking_sphinx.rb +34 -292
  14. data/lib/thinking_sphinx/active_record.rb +22 -383
  15. data/lib/thinking_sphinx/active_record/association.rb +9 -0
  16. data/lib/thinking_sphinx/active_record/association_proxy.rb +68 -0
  17. data/lib/thinking_sphinx/active_record/associations.rb +68 -0
  18. data/lib/thinking_sphinx/active_record/attribute.rb +20 -0
  19. data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +32 -0
  20. data/lib/thinking_sphinx/active_record/attribute/type.rb +79 -0
  21. data/lib/thinking_sphinx/active_record/attribute/values.rb +18 -0
  22. data/lib/thinking_sphinx/active_record/base.rb +36 -0
  23. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +31 -0
  24. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +55 -0
  25. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +59 -0
  26. data/lib/thinking_sphinx/active_record/column.rb +30 -0
  27. data/lib/thinking_sphinx/active_record/database_adapters.rb +51 -0
  28. data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +13 -0
  29. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +23 -0
  30. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +25 -0
  31. data/lib/thinking_sphinx/active_record/field.rb +11 -0
  32. data/lib/thinking_sphinx/active_record/index.rb +55 -0
  33. data/lib/thinking_sphinx/active_record/interpreter.rb +47 -0
  34. data/lib/thinking_sphinx/active_record/log_subscriber.rb +10 -58
  35. data/lib/thinking_sphinx/active_record/property.rb +28 -0
  36. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +60 -0
  37. data/lib/thinking_sphinx/active_record/sql_builder.rb +159 -0
  38. data/lib/thinking_sphinx/active_record/sql_source.rb +138 -0
  39. data/lib/thinking_sphinx/active_record/sql_source/template.rb +46 -0
  40. data/lib/thinking_sphinx/batched_search.rb +26 -0
  41. data/lib/thinking_sphinx/callbacks.rb +15 -0
  42. data/lib/thinking_sphinx/configuration.rb +80 -331
  43. data/lib/thinking_sphinx/configuration/consistent_ids.rb +31 -0
  44. data/lib/thinking_sphinx/configuration/defaults.rb +5 -0
  45. data/lib/thinking_sphinx/core.rb +6 -0
  46. data/lib/thinking_sphinx/core/index.rb +68 -0
  47. data/lib/thinking_sphinx/core/interpreter.rb +19 -0
  48. data/lib/thinking_sphinx/deltas.rb +35 -26
  49. data/lib/thinking_sphinx/deltas/default_delta.rb +56 -56
  50. data/lib/thinking_sphinx/excerpter.rb +23 -21
  51. data/lib/thinking_sphinx/facet.rb +22 -127
  52. data/lib/thinking_sphinx/facet_search.rb +95 -162
  53. data/lib/thinking_sphinx/index.rb +39 -143
  54. data/lib/thinking_sphinx/index_set.rb +51 -0
  55. data/lib/thinking_sphinx/masks.rb +8 -0
  56. data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +23 -0
  57. data/lib/thinking_sphinx/masks/pagination_mask.rb +60 -0
  58. data/lib/thinking_sphinx/masks/scopes_mask.rb +35 -0
  59. data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +11 -0
  60. data/lib/thinking_sphinx/middlewares.rb +36 -0
  61. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +73 -0
  62. data/lib/thinking_sphinx/middlewares/geographer.rb +53 -0
  63. data/lib/thinking_sphinx/middlewares/glazier.rb +39 -0
  64. data/lib/thinking_sphinx/middlewares/ids_only.rb +13 -0
  65. data/lib/thinking_sphinx/middlewares/inquirer.rb +62 -0
  66. data/lib/thinking_sphinx/middlewares/middleware.rb +9 -0
  67. data/lib/thinking_sphinx/middlewares/sphinxql.rb +149 -0
  68. data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +45 -0
  69. data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +46 -0
  70. data/lib/thinking_sphinx/panes.rb +8 -0
  71. data/lib/thinking_sphinx/panes/attributes_pane.rb +9 -0
  72. data/lib/thinking_sphinx/panes/distance_pane.rb +13 -0
  73. data/lib/thinking_sphinx/panes/excerpts_pane.rb +37 -0
  74. data/lib/thinking_sphinx/panes/weight_pane.rb +9 -0
  75. data/lib/thinking_sphinx/railtie.rb +6 -40
  76. data/lib/thinking_sphinx/rake_interface.rb +47 -0
  77. data/lib/thinking_sphinx/real_time.rb +11 -0
  78. data/lib/thinking_sphinx/real_time/attribute.rb +5 -0
  79. data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +48 -0
  80. data/lib/thinking_sphinx/real_time/field.rb +3 -0
  81. data/lib/thinking_sphinx/real_time/index.rb +47 -0
  82. data/lib/thinking_sphinx/real_time/index/template.rb +33 -0
  83. data/lib/thinking_sphinx/real_time/interpreter.rb +23 -0
  84. data/lib/thinking_sphinx/real_time/property.rb +16 -0
  85. data/lib/thinking_sphinx/scopes.rb +22 -0
  86. data/lib/thinking_sphinx/search.rb +90 -1028
  87. data/lib/thinking_sphinx/search/batch_inquirer.rb +27 -0
  88. data/lib/thinking_sphinx/search/context.rb +26 -0
  89. data/lib/thinking_sphinx/search/glaze.rb +32 -0
  90. data/lib/thinking_sphinx/search/merger.rb +24 -0
  91. data/lib/thinking_sphinx/search/query.rb +43 -0
  92. data/lib/thinking_sphinx/search/stale_ids_exception.rb +11 -0
  93. data/lib/thinking_sphinx/search/translator.rb +50 -0
  94. data/lib/thinking_sphinx/tasks.rb +22 -125
  95. data/lib/thinking_sphinx/test.rb +9 -19
  96. data/sketchpad.rb +58 -0
  97. data/spec/acceptance/association_scoping_spec.rb +23 -0
  98. data/spec/acceptance/attribute_access_spec.rb +39 -0
  99. data/spec/acceptance/attribute_updates_spec.rb +16 -0
  100. data/spec/acceptance/batch_searching_spec.rb +21 -0
  101. data/spec/acceptance/big_integers_spec.rb +27 -0
  102. data/spec/acceptance/excerpts_spec.rb +14 -0
  103. data/spec/acceptance/facets_spec.rb +122 -0
  104. data/spec/acceptance/geosearching_spec.rb +39 -0
  105. data/spec/acceptance/grouping_by_attributes_spec.rb +77 -0
  106. data/spec/acceptance/paginating_search_results_spec.rb +24 -0
  107. data/spec/acceptance/remove_deleted_records_spec.rb +23 -0
  108. data/spec/acceptance/search_counts_spec.rb +18 -0
  109. data/spec/acceptance/search_for_just_ids_spec.rb +19 -0
  110. data/spec/acceptance/searching_across_models_spec.rb +28 -0
  111. data/spec/acceptance/searching_on_fields_spec.rb +56 -0
  112. data/spec/acceptance/searching_with_filters_spec.rb +109 -0
  113. data/spec/acceptance/searching_with_sti_spec.rb +55 -0
  114. data/spec/acceptance/searching_within_a_model_spec.rb +52 -0
  115. data/spec/acceptance/sorting_search_results_spec.rb +41 -0
  116. data/spec/acceptance/spec_helper.rb +4 -0
  117. data/spec/acceptance/specifying_sql_spec.rb +62 -0
  118. data/spec/acceptance/sphinx_scopes_spec.rb +49 -0
  119. data/spec/acceptance/sql_deltas_spec.rb +43 -0
  120. data/spec/acceptance/support/database_cleaner.rb +11 -0
  121. data/spec/acceptance/support/sphinx_controller.rb +39 -0
  122. data/spec/acceptance/support/sphinx_helpers.rb +24 -0
  123. data/spec/acceptance/suspended_deltas_spec.rb +20 -0
  124. data/spec/internal/.gitignore +1 -0
  125. data/spec/internal/app/indices/animal_index.rb +3 -0
  126. data/spec/internal/app/indices/article_index.rb +24 -0
  127. data/spec/internal/app/indices/book_index.rb +8 -0
  128. data/spec/internal/app/indices/city_index.rb +6 -0
  129. data/spec/internal/app/indices/product_index.rb +3 -0
  130. data/spec/internal/app/indices/tee_index.rb +4 -0
  131. data/spec/internal/app/indices/user_index.rb +5 -0
  132. data/spec/internal/app/models/animal.rb +2 -0
  133. data/spec/internal/app/models/article.rb +5 -0
  134. data/spec/internal/app/models/bird.rb +2 -0
  135. data/spec/internal/app/models/book.rb +11 -0
  136. data/spec/internal/app/models/city.rb +2 -0
  137. data/spec/internal/app/models/colour.rb +3 -0
  138. data/spec/internal/app/models/flightless_bird.rb +2 -0
  139. data/spec/internal/app/models/mammal.rb +2 -0
  140. data/spec/internal/app/models/product.rb +3 -0
  141. data/spec/internal/app/models/tag.rb +4 -0
  142. data/{features/thinking_sphinx → spec/internal/app}/models/tagging.rb +1 -1
  143. data/spec/internal/app/models/tee.rb +3 -0
  144. data/spec/internal/app/models/tweet.rb +3 -0
  145. data/spec/internal/app/models/user.rb +3 -0
  146. data/spec/internal/config/database.yml +5 -0
  147. data/spec/internal/db/schema.rb +65 -0
  148. data/spec/internal/log/.gitignore +1 -0
  149. data/spec/spec_helper.rb +8 -49
  150. data/spec/support/sphinx_yaml_helpers.rb +9 -0
  151. data/spec/thinking_sphinx/active_record/association_spec.rb +12 -0
  152. data/spec/thinking_sphinx/active_record/associations_spec.rb +184 -0
  153. data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +147 -0
  154. data/spec/thinking_sphinx/active_record/base_spec.rb +61 -0
  155. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +80 -0
  156. data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +147 -0
  157. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +69 -0
  158. data/spec/thinking_sphinx/active_record/column_spec.rb +47 -0
  159. data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +31 -0
  160. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +43 -0
  161. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +45 -0
  162. data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +108 -0
  163. data/spec/thinking_sphinx/active_record/field_spec.rb +36 -0
  164. data/spec/thinking_sphinx/active_record/index_spec.rb +208 -0
  165. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +293 -0
  166. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +162 -0
  167. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +666 -0
  168. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +401 -0
  169. data/spec/thinking_sphinx/configuration_spec.rb +264 -171
  170. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +116 -0
  171. data/spec/thinking_sphinx/deltas_spec.rb +58 -0
  172. data/spec/thinking_sphinx/excerpter_spec.rb +40 -38
  173. data/spec/thinking_sphinx/facet_search_spec.rb +49 -151
  174. data/spec/thinking_sphinx/index_set_spec.rb +68 -0
  175. data/spec/thinking_sphinx/index_spec.rb +91 -155
  176. data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +121 -0
  177. data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +68 -0
  178. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +132 -0
  179. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +89 -0
  180. data/spec/thinking_sphinx/middlewares/glazier_spec.rb +62 -0
  181. data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +55 -0
  182. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +271 -0
  183. data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +47 -0
  184. data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +91 -0
  185. data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +21 -0
  186. data/spec/thinking_sphinx/panes/distance_pane_spec.rb +41 -0
  187. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +53 -0
  188. data/spec/thinking_sphinx/panes/weight_pane_spec.rb +20 -0
  189. data/spec/thinking_sphinx/rake_interface_spec.rb +147 -0
  190. data/spec/thinking_sphinx/real_time/attribute_spec.rb +62 -0
  191. data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +76 -0
  192. data/spec/thinking_sphinx/real_time/field_spec.rb +54 -0
  193. data/spec/thinking_sphinx/real_time/index_spec.rb +154 -0
  194. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +147 -0
  195. data/spec/thinking_sphinx/scopes_spec.rb +38 -0
  196. data/spec/thinking_sphinx/search/glaze_spec.rb +55 -0
  197. data/spec/thinking_sphinx/search/query_spec.rb +46 -0
  198. data/spec/thinking_sphinx/search_spec.rb +65 -1357
  199. data/spec/thinking_sphinx_spec.rb +19 -182
  200. data/thinking-sphinx.gemspec +33 -0
  201. metadata +318 -431
  202. data/features/abstract_inheritance.feature +0 -10
  203. data/features/alternate_primary_key.feature +0 -27
  204. data/features/attribute_transformation.feature +0 -22
  205. data/features/attribute_updates.feature +0 -79
  206. data/features/deleting_instances.feature +0 -70
  207. data/features/direct_attributes.feature +0 -11
  208. data/features/excerpts.feature +0 -21
  209. data/features/extensible_delta_indexing.feature +0 -9
  210. data/features/facets.feature +0 -88
  211. data/features/facets_across_model.feature +0 -29
  212. data/features/field_sorting.feature +0 -18
  213. data/features/handling_edits.feature +0 -97
  214. data/features/retry_stale_indexes.feature +0 -24
  215. data/features/searching_across_models.feature +0 -20
  216. data/features/searching_by_index.feature +0 -41
  217. data/features/searching_by_model.feature +0 -175
  218. data/features/searching_with_find_arguments.feature +0 -56
  219. data/features/sphinx_detection.feature +0 -25
  220. data/features/sphinx_scopes.feature +0 -68
  221. data/features/step_definitions/alpha_steps.rb +0 -16
  222. data/features/step_definitions/beta_steps.rb +0 -7
  223. data/features/step_definitions/common_steps.rb +0 -205
  224. data/features/step_definitions/extensible_delta_indexing_steps.rb +0 -7
  225. data/features/step_definitions/facet_steps.rb +0 -96
  226. data/features/step_definitions/find_arguments_steps.rb +0 -36
  227. data/features/step_definitions/gamma_steps.rb +0 -15
  228. data/features/step_definitions/scope_steps.rb +0 -19
  229. data/features/step_definitions/search_steps.rb +0 -94
  230. data/features/step_definitions/sphinx_steps.rb +0 -35
  231. data/features/sti_searching.feature +0 -19
  232. data/features/support/env.rb +0 -24
  233. data/features/support/lib/generic_delta_handler.rb +0 -8
  234. data/features/thinking_sphinx/database.example.yml +0 -3
  235. data/features/thinking_sphinx/db/.gitignore +0 -1
  236. data/features/thinking_sphinx/db/fixtures/alphas.rb +0 -8
  237. data/features/thinking_sphinx/db/fixtures/authors.rb +0 -1
  238. data/features/thinking_sphinx/db/fixtures/betas.rb +0 -11
  239. data/features/thinking_sphinx/db/fixtures/boxes.rb +0 -9
  240. data/features/thinking_sphinx/db/fixtures/categories.rb +0 -1
  241. data/features/thinking_sphinx/db/fixtures/cats.rb +0 -3
  242. data/features/thinking_sphinx/db/fixtures/comments.rb +0 -24
  243. data/features/thinking_sphinx/db/fixtures/developers.rb +0 -31
  244. data/features/thinking_sphinx/db/fixtures/dogs.rb +0 -3
  245. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +0 -10
  246. data/features/thinking_sphinx/db/fixtures/foxes.rb +0 -3
  247. data/features/thinking_sphinx/db/fixtures/gammas.rb +0 -10
  248. data/features/thinking_sphinx/db/fixtures/music.rb +0 -4
  249. data/features/thinking_sphinx/db/fixtures/people.rb +0 -1001
  250. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
  251. data/features/thinking_sphinx/db/fixtures/posts.rb +0 -10
  252. data/features/thinking_sphinx/db/fixtures/robots.rb +0 -8
  253. data/features/thinking_sphinx/db/fixtures/tags.rb +0 -27
  254. data/features/thinking_sphinx/db/migrations/create_alphas.rb +0 -8
  255. data/features/thinking_sphinx/db/migrations/create_animals.rb +0 -5
  256. data/features/thinking_sphinx/db/migrations/create_authors.rb +0 -3
  257. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +0 -6
  258. data/features/thinking_sphinx/db/migrations/create_betas.rb +0 -5
  259. data/features/thinking_sphinx/db/migrations/create_boxes.rb +0 -5
  260. data/features/thinking_sphinx/db/migrations/create_categories.rb +0 -3
  261. data/features/thinking_sphinx/db/migrations/create_comments.rb +0 -10
  262. data/features/thinking_sphinx/db/migrations/create_developers.rb +0 -7
  263. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +0 -5
  264. data/features/thinking_sphinx/db/migrations/create_gammas.rb +0 -3
  265. data/features/thinking_sphinx/db/migrations/create_genres.rb +0 -3
  266. data/features/thinking_sphinx/db/migrations/create_music.rb +0 -6
  267. data/features/thinking_sphinx/db/migrations/create_people.rb +0 -13
  268. data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -6
  269. data/features/thinking_sphinx/db/migrations/create_robots.rb +0 -4
  270. data/features/thinking_sphinx/db/migrations/create_taggings.rb +0 -5
  271. data/features/thinking_sphinx/db/migrations/create_tags.rb +0 -4
  272. data/features/thinking_sphinx/models/alpha.rb +0 -23
  273. data/features/thinking_sphinx/models/andrew.rb +0 -17
  274. data/features/thinking_sphinx/models/animal.rb +0 -5
  275. data/features/thinking_sphinx/models/author.rb +0 -3
  276. data/features/thinking_sphinx/models/beta.rb +0 -13
  277. data/features/thinking_sphinx/models/box.rb +0 -8
  278. data/features/thinking_sphinx/models/cat.rb +0 -3
  279. data/features/thinking_sphinx/models/category.rb +0 -4
  280. data/features/thinking_sphinx/models/comment.rb +0 -10
  281. data/features/thinking_sphinx/models/developer.rb +0 -21
  282. data/features/thinking_sphinx/models/dog.rb +0 -3
  283. data/features/thinking_sphinx/models/extensible_beta.rb +0 -9
  284. data/features/thinking_sphinx/models/fox.rb +0 -5
  285. data/features/thinking_sphinx/models/gamma.rb +0 -5
  286. data/features/thinking_sphinx/models/genre.rb +0 -3
  287. data/features/thinking_sphinx/models/medium.rb +0 -5
  288. data/features/thinking_sphinx/models/music.rb +0 -10
  289. data/features/thinking_sphinx/models/person.rb +0 -24
  290. data/features/thinking_sphinx/models/post.rb +0 -22
  291. data/features/thinking_sphinx/models/robot.rb +0 -12
  292. data/features/thinking_sphinx/models/tag.rb +0 -3
  293. data/lib/cucumber/thinking_sphinx/external_world.rb +0 -12
  294. data/lib/cucumber/thinking_sphinx/internal_world.rb +0 -137
  295. data/lib/cucumber/thinking_sphinx/sql_logger.rb +0 -28
  296. data/lib/thinking_sphinx/action_controller.rb +0 -31
  297. data/lib/thinking_sphinx/active_record/attribute_updates.rb +0 -54
  298. data/lib/thinking_sphinx/active_record/collection_proxy.rb +0 -47
  299. data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +0 -27
  300. data/lib/thinking_sphinx/active_record/delta.rb +0 -67
  301. data/lib/thinking_sphinx/active_record/has_many_association.rb +0 -44
  302. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
  303. data/lib/thinking_sphinx/active_record/scopes.rb +0 -110
  304. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +0 -94
  305. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -62
  306. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +0 -188
  307. data/lib/thinking_sphinx/association.rb +0 -230
  308. data/lib/thinking_sphinx/attribute.rb +0 -405
  309. data/lib/thinking_sphinx/auto_version.rb +0 -40
  310. data/lib/thinking_sphinx/bundled_search.rb +0 -40
  311. data/lib/thinking_sphinx/class_facet.rb +0 -20
  312. data/lib/thinking_sphinx/connection.rb +0 -71
  313. data/lib/thinking_sphinx/context.rb +0 -81
  314. data/lib/thinking_sphinx/core/string.rb +0 -15
  315. data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
  316. data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
  317. data/lib/thinking_sphinx/deploy/capistrano.rb +0 -99
  318. data/lib/thinking_sphinx/field.rb +0 -98
  319. data/lib/thinking_sphinx/index/builder.rb +0 -315
  320. data/lib/thinking_sphinx/index/faux_column.rb +0 -118
  321. data/lib/thinking_sphinx/join.rb +0 -37
  322. data/lib/thinking_sphinx/property.rb +0 -187
  323. data/lib/thinking_sphinx/search_methods.rb +0 -439
  324. data/lib/thinking_sphinx/sinatra.rb +0 -7
  325. data/lib/thinking_sphinx/source.rb +0 -194
  326. data/lib/thinking_sphinx/source/internal_properties.rb +0 -51
  327. data/lib/thinking_sphinx/source/sql.rb +0 -174
  328. data/spec/fixtures/data.sql +0 -32
  329. data/spec/fixtures/database.yml.default +0 -3
  330. data/spec/fixtures/models.rb +0 -164
  331. data/spec/fixtures/structure.sql +0 -146
  332. data/spec/sphinx_helper.rb +0 -60
  333. data/spec/support/rails.rb +0 -25
  334. data/spec/thinking_sphinx/active_record/delta_spec.rb +0 -123
  335. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -173
  336. data/spec/thinking_sphinx/active_record/scopes_spec.rb +0 -177
  337. data/spec/thinking_sphinx/active_record_spec.rb +0 -573
  338. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
  339. data/spec/thinking_sphinx/association_spec.rb +0 -250
  340. data/spec/thinking_sphinx/attribute_spec.rb +0 -552
  341. data/spec/thinking_sphinx/auto_version_spec.rb +0 -103
  342. data/spec/thinking_sphinx/connection_spec.rb +0 -77
  343. data/spec/thinking_sphinx/context_spec.rb +0 -127
  344. data/spec/thinking_sphinx/core/array_spec.rb +0 -9
  345. data/spec/thinking_sphinx/core/string_spec.rb +0 -9
  346. data/spec/thinking_sphinx/facet_spec.rb +0 -359
  347. data/spec/thinking_sphinx/field_spec.rb +0 -127
  348. data/spec/thinking_sphinx/index/builder_spec.rb +0 -532
  349. data/spec/thinking_sphinx/index/faux_column_spec.rb +0 -36
  350. data/spec/thinking_sphinx/search_methods_spec.rb +0 -156
  351. data/spec/thinking_sphinx/source_spec.rb +0 -267
  352. data/spec/thinking_sphinx/test_spec.rb +0 -20
@@ -0,0 +1,68 @@
1
+ module ThinkingSphinx
2
+ module Masks; end
3
+ end
4
+
5
+ require 'thinking_sphinx/masks/scopes_mask'
6
+
7
+ describe ThinkingSphinx::Masks::ScopesMask do
8
+ let(:search) { double('search', :options => {}, :per_page => 20) }
9
+ let(:mask) { ThinkingSphinx::Masks::ScopesMask.new search }
10
+
11
+ describe '#search' do
12
+ it "replaces the query if one is supplied" do
13
+ search.should_receive(:query=).with('bar')
14
+
15
+ mask.search('bar')
16
+ end
17
+
18
+ it "keeps the existing query when only options are offered" do
19
+ search.should_not_receive(:query=)
20
+
21
+ mask.search :with => {:foo => :bar}
22
+ end
23
+
24
+ it "merges conditions" do
25
+ search.options[:conditions] = {:foo => 'bar'}
26
+
27
+ mask.search :conditions => {:baz => 'qux'}
28
+
29
+ search.options[:conditions].should == {:foo => 'bar', :baz => 'qux'}
30
+ end
31
+
32
+ it "merges filters" do
33
+ search.options[:with] = {:foo => :bar}
34
+
35
+ mask.search :with => {:baz => :qux}
36
+
37
+ search.options[:with].should == {:foo => :bar, :baz => :qux}
38
+ end
39
+
40
+ it "merges exclusive filters" do
41
+ search.options[:without] = {:foo => :bar}
42
+
43
+ mask.search :without => {:baz => :qux}
44
+
45
+ search.options[:without].should == {:foo => :bar, :baz => :qux}
46
+ end
47
+
48
+ it "appends excluded ids" do
49
+ search.options[:without_ids] = [1, 3]
50
+
51
+ mask.search :without_ids => [5, 7]
52
+
53
+ search.options[:without_ids].should == [1, 3, 5, 7]
54
+ end
55
+
56
+ it "replaces the retry_stale option" do
57
+ search.options[:retry_stale] = true
58
+
59
+ mask.search :retry_stale => 6
60
+
61
+ search.options[:retry_stale].should == 6
62
+ end
63
+
64
+ it "returns the original search object" do
65
+ mask.search.object_id.should == search.object_id
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,132 @@
1
+ module ThinkingSphinx
2
+ module Middlewares; end
3
+ class Search; end
4
+ end
5
+
6
+ require 'thinking_sphinx/middlewares/middleware'
7
+ require 'thinking_sphinx/middlewares/active_record_translator'
8
+ require 'thinking_sphinx/search/stale_ids_exception'
9
+
10
+ describe ThinkingSphinx::Middlewares::ActiveRecordTranslator do
11
+ let(:app) { double('app', :call => true) }
12
+ let(:middleware) {
13
+ ThinkingSphinx::Middlewares::ActiveRecordTranslator.new app }
14
+ let(:context) { {:raw => [], :results => []} }
15
+ let(:model) { double('model') }
16
+ let(:search) { double('search', :options => {}) }
17
+
18
+ def raw_result(id, model_name)
19
+ {'sphinx_internal_id' => id, 'sphinx_internal_class' => model_name}
20
+ end
21
+
22
+ describe '#call' do
23
+ before :each do
24
+ context.stub :search => search
25
+ model.stub :unscoped => model
26
+ end
27
+
28
+ it "translates records to ActiveRecord objects" do
29
+ model_name = double('article', :constantize => model)
30
+ instance = double('instance', :id => 24)
31
+ model.stub :where => [instance]
32
+
33
+ context[:results] << raw_result(24, model_name)
34
+
35
+ middleware.call [context]
36
+
37
+ context[:results].should == [instance]
38
+ end
39
+
40
+ it "only queries the model once for the given search results" do
41
+ model_name = double('article', :constantize => model)
42
+ instance_a = double('instance', :id => 24)
43
+ instance_b = double('instance', :id => 42)
44
+ context[:results] << raw_result(24, model_name)
45
+ context[:results] << raw_result(42, model_name)
46
+
47
+ model.should_receive(:where).once.and_return([instance_a, instance_b])
48
+
49
+ middleware.call [context]
50
+ end
51
+
52
+ it "handles multiple models" do
53
+ article_model = double('article model')
54
+ article_name = double('article name', :constantize => article_model)
55
+ article = double('article instance', :id => 24)
56
+
57
+ user_model = double('user model')
58
+ user_name = double('user name', :constantize => user_model)
59
+ user = double('user instance', :id => 12)
60
+
61
+ article_model.stub :unscoped => article_model
62
+ user_model.stub :unscoped => user_model
63
+
64
+ context[:results] << raw_result(24, article_name)
65
+ context[:results] << raw_result(12, user_name)
66
+
67
+ article_model.should_receive(:where).once.and_return([article])
68
+ user_model.should_receive(:where).once.and_return([user])
69
+
70
+ middleware.call [context]
71
+ end
72
+
73
+ it "sorts the results according to Sphinx order, not database order" do
74
+ model_name = double('article', :constantize => model)
75
+ instance_1 = double('instance 1', :id => 1)
76
+ instance_2 = double('instance 1', :id => 2)
77
+
78
+ context[:results] << raw_result(2, model_name)
79
+ context[:results] << raw_result(1, model_name)
80
+
81
+ model.stub(:where => [instance_1, instance_2])
82
+
83
+ middleware.call [context]
84
+
85
+ context[:results].should == [instance_2, instance_1]
86
+ end
87
+
88
+ context 'SQL options' do
89
+ let(:relation) { double('relation', :where => []) }
90
+
91
+ before :each do
92
+ model.stub :unscoped => relation
93
+
94
+ model_name = double('article', :constantize => model)
95
+ context[:results] << raw_result(1, model_name)
96
+ end
97
+
98
+ it "passes through SQL include options to the relation" do
99
+ search.options[:sql] = {:include => :association}
100
+
101
+ relation.should_receive(:includes).with(:association).
102
+ and_return(relation)
103
+
104
+ middleware.call [context]
105
+ end
106
+
107
+ it "passes through SQL join options to the relation" do
108
+ search.options[:sql] = {:joins => :association}
109
+
110
+ relation.should_receive(:joins).with(:association).and_return(relation)
111
+
112
+ middleware.call [context]
113
+ end
114
+
115
+ it "passes through SQL order options to the relation" do
116
+ search.options[:sql] = {:order => 'name DESC'}
117
+
118
+ relation.should_receive(:order).with('name DESC').and_return(relation)
119
+
120
+ middleware.call [context]
121
+ end
122
+
123
+ it "passes through SQL select options to the relation" do
124
+ search.options[:sql] = {:select => :column}
125
+
126
+ relation.should_receive(:select).with(:column).and_return(relation)
127
+
128
+ middleware.call [context]
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,89 @@
1
+ module ThinkingSphinx
2
+ module Middlewares; end
3
+ end
4
+
5
+ require 'thinking_sphinx/middlewares/middleware'
6
+ require 'thinking_sphinx/middlewares/geographer'
7
+
8
+ describe ThinkingSphinx::Middlewares::Geographer do
9
+ let(:app) { double('app', :call => true) }
10
+ let(:middleware) { ThinkingSphinx::Middlewares::Geographer.new app }
11
+ let(:context) { {:sphinxql => sphinx_sql, :indices => [], :panes => []} }
12
+ let(:sphinx_sql) { double('sphinx_sql') }
13
+ let(:search) { double('search', :options => {}) }
14
+
15
+ before :each do
16
+ stub_const 'ThinkingSphinx::Panes::DistancePane', double
17
+
18
+ context.stub :search => search
19
+ end
20
+
21
+ describe '#call' do
22
+ context 'no geodistance location provided' do
23
+ before :each do
24
+ search.options[:geo] = nil
25
+ end
26
+
27
+ it "doesn't add anything if :geo is nil" do
28
+ sphinx_sql.should_not_receive(:values)
29
+
30
+ middleware.call [context]
31
+ end
32
+ end
33
+
34
+ context 'geodistance location provided' do
35
+ before :each do
36
+ search.options[:geo] = [0.1, 0.2]
37
+ end
38
+
39
+ it "adds the geodist function when given a :geo option" do
40
+ sphinx_sql.should_receive(:values).
41
+ with('GEODIST(0.1, 0.2, lat, lng) AS geodist').
42
+ and_return(sphinx_sql)
43
+
44
+ middleware.call [context]
45
+ end
46
+
47
+ it "adds the distance pane" do
48
+ sphinx_sql.stub :values => sphinx_sql
49
+
50
+ middleware.call [context]
51
+
52
+ context[:panes].should include(ThinkingSphinx::Panes::DistancePane)
53
+ end
54
+
55
+ it "respects :latitude_attr and :longitude_attr options" do
56
+ search.options[:latitude_attr] = 'side_to_side'
57
+ search.options[:longitude_attr] = 'up_or_down'
58
+
59
+ sphinx_sql.should_receive(:values).
60
+ with('GEODIST(0.1, 0.2, side_to_side, up_or_down) AS geodist').
61
+ and_return(sphinx_sql)
62
+
63
+ middleware.call [context]
64
+ end
65
+
66
+ it "uses latitude if any index has that but not lat as an attribute" do
67
+ context[:indices] << double('index',
68
+ :unique_attribute_names => ['latitude'], :name => 'an_index')
69
+
70
+ sphinx_sql.should_receive(:values).
71
+ with('GEODIST(0.1, 0.2, latitude, lng) AS geodist').
72
+ and_return(sphinx_sql)
73
+
74
+ middleware.call [context]
75
+ end
76
+
77
+ it "uses latitude if any index has that but not lat as an attribute" do
78
+ context[:indices] << double('index',
79
+ :unique_attribute_names => ['longitude'], :name => 'an_index')
80
+
81
+ sphinx_sql.should_receive(:values).
82
+ with('GEODIST(0.1, 0.2, lat, longitude) AS geodist').
83
+ and_return(sphinx_sql)
84
+
85
+ middleware.call [context]
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,62 @@
1
+ module ThinkingSphinx
2
+ module Middlewares; end
3
+ end
4
+
5
+ require 'thinking_sphinx/middlewares/middleware'
6
+ require 'thinking_sphinx/middlewares/glazier'
7
+
8
+ describe ThinkingSphinx::Middlewares::Glazier do
9
+ let(:app) { double('app', :call => true) }
10
+ let(:middleware) { ThinkingSphinx::Middlewares::Glazier.new app }
11
+ let(:context) { {:results => [result], :indices => [index],
12
+ :meta => {}, :raw => [raw_result], :panes => []} }
13
+ let(:result) { double('result', :id => 10,
14
+ :class => double(:name => 'Article')) }
15
+ let(:index) { double('index', :name => 'foo_core') }
16
+ let(:search) { double('search', :options => {}) }
17
+ let(:glazed_result) { double('glazed result') }
18
+ let(:raw_result) {
19
+ {'sphinx_internal_class' => 'Article', 'sphinx_internal_id' => 10} }
20
+
21
+ describe '#call' do
22
+ before :each do
23
+ stub_const 'ThinkingSphinx::Search::Glaze', double(:new => glazed_result)
24
+
25
+ context.stub :search => search
26
+ end
27
+
28
+ context 'No panes provided' do
29
+ before :each do
30
+ context[:panes].clear
31
+ end
32
+
33
+ it "leaves the results as they are" do
34
+ middleware.call [context]
35
+
36
+ context[:results].should == [result]
37
+ end
38
+ end
39
+
40
+ context 'Panes provided' do
41
+ let(:pane_class) { double('pane class') }
42
+
43
+ before :each do
44
+ context[:panes] << pane_class
45
+ end
46
+
47
+ it "replaces each result with a glazed version" do
48
+ middleware.call [context]
49
+
50
+ context[:results].should == [glazed_result]
51
+ end
52
+
53
+ it "creates a glazed result for each result" do
54
+ ThinkingSphinx::Search::Glaze.should_receive(:new).
55
+ with(context, result, raw_result, [pane_class]).
56
+ and_return(glazed_result)
57
+
58
+ middleware.call [context]
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,55 @@
1
+ module ThinkingSphinx
2
+ module Middlewares; end
3
+ end
4
+
5
+ require 'thinking_sphinx/middlewares/middleware'
6
+ require 'thinking_sphinx/middlewares/inquirer'
7
+
8
+ describe ThinkingSphinx::Middlewares::Inquirer do
9
+ let(:app) { double('app', :call => true) }
10
+ let(:middleware) { ThinkingSphinx::Middlewares::Inquirer.new app }
11
+ let(:context) { {:sphinxql => sphinx_sql} }
12
+ let(:sphinx_sql) { double('sphinx_sql',
13
+ :to_sql => 'SELECT * FROM index') }
14
+ let(:batch_inquirer) { double('batcher', :append_query => true,
15
+ :results => [[:raw], [{'Variable_name' => 'meta', 'Value' => 'value'}]]) }
16
+
17
+ before :each do
18
+ context.stub(:log) do |notification, message, &block|
19
+ block.call unless block.nil?
20
+ end
21
+
22
+ batch_class = double
23
+ batch_class.stub(:new).and_return(batch_inquirer)
24
+
25
+ stub_const 'Riddle::Query', double(:meta => 'SHOW META')
26
+ stub_const 'ThinkingSphinx::Search::BatchInquirer', batch_class
27
+ end
28
+
29
+ describe '#call' do
30
+ it "passes through the SphinxQL from a Riddle::Query::Select object" do
31
+ batch_inquirer.should_receive(:append_query).with('SELECT * FROM index')
32
+ batch_inquirer.should_receive(:append_query).with('SHOW META')
33
+
34
+ middleware.call [context]
35
+ end
36
+
37
+ it "sets up the raw results" do
38
+ middleware.call [context]
39
+
40
+ context[:raw].should == [:raw]
41
+ end
42
+
43
+ it "sets up the meta results as a hash" do
44
+ middleware.call [context]
45
+
46
+ context[:meta].should == {'meta' => 'value'}
47
+ end
48
+
49
+ it "uses the raw values as the initial results" do
50
+ middleware.call [context]
51
+
52
+ context[:results].should == [:raw]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,271 @@
1
+ module ThinkingSphinx
2
+ module Middlewares; end
3
+ end
4
+
5
+ module ActiveRecord
6
+ class Base; end
7
+ end
8
+
9
+ require 'active_support/core_ext/object/blank'
10
+ require 'active_support/core_ext/string/inflections'
11
+ require 'thinking_sphinx/middlewares/middleware'
12
+ require 'thinking_sphinx/middlewares/sphinxql'
13
+
14
+ describe ThinkingSphinx::Middlewares::SphinxQL do
15
+ let(:app) { double('app', :call => true) }
16
+ let(:middleware) { ThinkingSphinx::Middlewares::SphinxQL.new app }
17
+ let(:context) { {} }
18
+ let(:search) { double('search', :query => '', :options => {},
19
+ :offset => 0, :per_page => 5) }
20
+ let(:index_set) { [] }
21
+ let(:sphinx_sql) { double('sphinx_sql', :from => true, :offset => true,
22
+ :limit => true, :where => true, :matching => true) }
23
+ let(:query) { double('query') }
24
+
25
+ before :each do
26
+ stub_const 'Riddle::Query::Select', double(:new => sphinx_sql)
27
+ stub_const 'ThinkingSphinx::Search::Query', double(:new => query)
28
+ stub_const 'ThinkingSphinx::Masks::GroupEnumeratorsMask', double
29
+ stub_const 'ThinkingSphinx::IndexSet', double(:new => index_set)
30
+
31
+ context.stub :search => search
32
+ end
33
+
34
+ describe '#call' do
35
+ it "uses the indexes for the FROM clause" do
36
+ index_set.replace [
37
+ double('index', :name => 'article_core'),
38
+ double('index', :name => 'user_core')
39
+ ]
40
+
41
+ sphinx_sql.should_receive(:from).with('`article_core`', '`user_core`').
42
+ and_return(sphinx_sql)
43
+
44
+ middleware.call [context]
45
+ end
46
+
47
+ it "finds index objects for the given models and indices options" do
48
+ klass = double(:column_names => [], :inheritance_column => 'type',
49
+ :name => 'User')
50
+ search.options[:classes] = [klass]
51
+ search.options[:indices] = ['user_core']
52
+
53
+ ThinkingSphinx::IndexSet.should_receive(:new).
54
+ with([klass], ['user_core']).and_return(index_set)
55
+
56
+ middleware.call [context]
57
+ end
58
+
59
+ it "generates a Sphinx query from the provided keyword and conditions" do
60
+ search.stub :query => 'tasty'
61
+ search.options[:conditions] = {:title => 'pancakes'}
62
+
63
+ ThinkingSphinx::Search::Query.should_receive(:new).
64
+ with('tasty', {:title => 'pancakes'}, anything).and_return(query)
65
+
66
+ middleware.call [context]
67
+ end
68
+
69
+ it "matches on the generated query" do
70
+ query.stub :to_s => 'waffles'
71
+
72
+ sphinx_sql.should_receive(:matching).with('waffles')
73
+
74
+ middleware.call [context]
75
+ end
76
+
77
+ it "requests a starred query if the :star option is set to true" do
78
+ search.options[:star] = true
79
+
80
+ ThinkingSphinx::Search::Query.should_receive(:new).
81
+ with(anything, anything, true).and_return(query)
82
+
83
+ middleware.call [context]
84
+ end
85
+
86
+ it "appends field conditions for the class when searching on subclasses" do
87
+ db_connection = double('db connection', :select_values => [],
88
+ :schema_cache => double('cache', :table_exists? => false))
89
+ supermodel = Class.new(ActiveRecord::Base) do
90
+ def self.name; 'Cat'; end
91
+ def self.inheritance_column; 'type'; end
92
+ end
93
+ supermodel.stub :connection => db_connection, :column_names => ['type']
94
+ submodel = Class.new(supermodel) do
95
+ def self.name; 'Lion'; end
96
+ def self.inheritance_column; 'type'; end
97
+ def self.table_name; 'cats'; end
98
+ end
99
+ submodel.stub :connection => db_connection, :column_names => ['type'],
100
+ :descendants => []
101
+
102
+ search.options[:classes] = [submodel]
103
+
104
+ ThinkingSphinx::Search::Query.should_receive(:new).with(anything,
105
+ hash_including(:sphinx_internal_class => '(Lion)'), anything).
106
+ and_return(query)
107
+
108
+ middleware.call [context]
109
+ end
110
+
111
+ it "does not query the database for subclasses if :skip_sti is set to true" do
112
+ model = double('model', :connection => double,
113
+ :ancestors => [ActiveRecord::Base], :name => 'Animal')
114
+
115
+ search.options[:classes] = [model]
116
+ search.options[:skip_sti] = true
117
+
118
+ model.connection.should_not_receive(:select_values)
119
+
120
+ middleware.call [context]
121
+ end
122
+
123
+ it "filters out deleted values by default" do
124
+ sphinx_sql.should_receive(:where).with(:sphinx_deleted => false).
125
+ and_return(sphinx_sql)
126
+
127
+ middleware.call [context]
128
+ end
129
+
130
+ it "appends boolean attribute filters to the query" do
131
+ search.options[:with] = {:visible => true}
132
+
133
+ sphinx_sql.should_receive(:where).with(hash_including(:visible => true)).
134
+ and_return(sphinx_sql)
135
+
136
+ middleware.call [context]
137
+ end
138
+
139
+ it "appends exclusive filters to the query" do
140
+ search.options[:without] = {:tag_ids => [2, 4, 8]}
141
+
142
+ sphinx_sql.should_receive(:where_not).
143
+ with(hash_including(:tag_ids => [2, 4, 8])).and_return(sphinx_sql)
144
+
145
+ middleware.call [context]
146
+ end
147
+
148
+ it "appends the without_ids option as an exclusive filter" do
149
+ search.options[:without_ids] = [1, 4, 9]
150
+
151
+ sphinx_sql.should_receive(:where_not).
152
+ with(hash_including(:sphinx_internal_id => [1, 4, 9])).
153
+ and_return(sphinx_sql)
154
+
155
+ middleware.call [context]
156
+ end
157
+
158
+ it "appends MVA matches with all values" do
159
+ search.options[:with_all] = {:tag_ids => [1, 7]}
160
+
161
+ sphinx_sql.should_receive(:where_all).
162
+ with(:tag_ids => [1, 7]).and_return(sphinx_sql)
163
+
164
+ middleware.call [context]
165
+ end
166
+
167
+ it "appends MVA matches without all of the given values" do
168
+ search.options[:without_all] = {:tag_ids => [1, 7]}
169
+
170
+ sphinx_sql.should_receive(:where_not_all).
171
+ with(:tag_ids => [1, 7]).and_return(sphinx_sql)
172
+
173
+ middleware.call [context]
174
+ end
175
+
176
+ it "appends order clauses to the query" do
177
+ search.options[:order] = 'created_at ASC'
178
+
179
+ sphinx_sql.should_receive(:order_by).with('created_at ASC').
180
+ and_return(sphinx_sql)
181
+
182
+ middleware.call [context]
183
+ end
184
+
185
+ it "presumes attributes given as symbols should be sorted ascendingly" do
186
+ search.options[:order] = :updated_at
187
+
188
+ sphinx_sql.should_receive(:order_by).with('updated_at ASC').
189
+ and_return(sphinx_sql)
190
+
191
+ middleware.call [context]
192
+ end
193
+
194
+ it "appends a group by clause to the query" do
195
+ search.options[:group_by] = :foreign_id
196
+ search.stub :masks => []
197
+ sphinx_sql.stub :values => sphinx_sql
198
+
199
+ sphinx_sql.should_receive(:group_by).with('foreign_id').
200
+ and_return(sphinx_sql)
201
+
202
+ middleware.call [context]
203
+ end
204
+
205
+ it "adds the group enumerator mask when using :group_by" do
206
+ search.options[:group_by] = :foreign_id
207
+ search.stub :masks => []
208
+ sphinx_sql.stub :group_by => sphinx_sql, :values => sphinx_sql
209
+
210
+ middleware.call [context]
211
+
212
+ search.masks.should include(ThinkingSphinx::Masks::GroupEnumeratorsMask)
213
+ end
214
+
215
+ it "appends a sort within group clause to the query" do
216
+ search.options[:order_group_by] = :title
217
+
218
+ sphinx_sql.should_receive(:order_within_group_by).with('title ASC').
219
+ and_return(sphinx_sql)
220
+
221
+ middleware.call [context]
222
+ end
223
+
224
+ it "uses the provided offset" do
225
+ search.stub :offset => 50
226
+
227
+ sphinx_sql.should_receive(:offset).with(50).and_return(sphinx_sql)
228
+
229
+ middleware.call [context]
230
+ end
231
+
232
+ it "uses the provided limit" do
233
+ search.stub :per_page => 24
234
+
235
+ sphinx_sql.should_receive(:limit).with(24).and_return(sphinx_sql)
236
+
237
+ middleware.call [context]
238
+ end
239
+
240
+ it "adds the provided select statement" do
241
+ search.options[:select] = 'foo as bar'
242
+
243
+ sphinx_sql.should_receive(:values).with('foo as bar').
244
+ and_return(sphinx_sql)
245
+
246
+ middleware.call [context]
247
+ end
248
+
249
+ it "uses any provided field weights" do
250
+ search.options[:field_weights] = {:title => 3}
251
+
252
+ sphinx_sql.should_receive(:with_options) do |options|
253
+ options[:field_weights].should == {:title => 3}
254
+ sphinx_sql
255
+ end
256
+
257
+ middleware.call [context]
258
+ end
259
+
260
+ it "uses any given ranker option" do
261
+ search.options[:ranker] = 'proximity'
262
+
263
+ sphinx_sql.should_receive(:with_options) do |options|
264
+ options[:ranker].should == 'proximity'
265
+ sphinx_sql
266
+ end
267
+
268
+ middleware.call [context]
269
+ end
270
+ end
271
+ end