thinking-sphinx 2.1.0 → 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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,401 @@
1
+ require 'spec_helper'
2
+
3
+ describe ThinkingSphinx::ActiveRecord::SQLSource do
4
+ let(:model) { double('model', :connection => connection,
5
+ :name => 'User', :column_names => [], :inheritance_column => 'type') }
6
+ let(:connection) {
7
+ double('connection', :instance_variable_get => db_config) }
8
+ let(:db_config) { {:host => 'localhost', :user => 'root',
9
+ :database => 'default'} }
10
+ let(:source) { ThinkingSphinx::ActiveRecord::SQLSource.new(model) }
11
+ let(:adapter) { double('adapter') }
12
+
13
+ before :each do
14
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter.
15
+ stub!(:=== => true)
16
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters.
17
+ stub!(:adapter_for => adapter)
18
+ end
19
+
20
+ describe '#adapter' do
21
+ it "returns a database adapter for the model" do
22
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters.
23
+ should_receive(:adapter_for).with(model).and_return(adapter)
24
+
25
+ source.adapter.should == adapter
26
+ end
27
+ end
28
+
29
+ describe '#attributes' do
30
+ it "has the internal id attribute by default" do
31
+ source.attributes.collect(&:name).should include('sphinx_internal_id')
32
+ end
33
+
34
+ it "has the internal deleted attribute by default" do
35
+ source.attributes.collect(&:name).should include('sphinx_deleted')
36
+ end
37
+ end
38
+
39
+ describe '#delta_processor' do
40
+ let(:processor_class) { double('processor class', :try => processor) }
41
+ let(:processor) { double('processor') }
42
+ let(:source) {
43
+ ThinkingSphinx::ActiveRecord::SQLSource.new model,
44
+ :delta_processor => processor_class
45
+ }
46
+
47
+ it "loads the processor with the adapter" do
48
+ processor_class.should_receive(:try).with(:new, adapter).
49
+ and_return processor
50
+
51
+ source.delta_processor
52
+ end
53
+
54
+ it "returns the given processor" do
55
+ source.delta_processor.should == processor
56
+ end
57
+ end
58
+
59
+ describe '#delta?' do
60
+ it "returns the given delta setting" do
61
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model,
62
+ :delta? => true
63
+
64
+ source.should be_a_delta
65
+ end
66
+ end
67
+
68
+ describe '#disable_range?' do
69
+ it "returns the given range setting" do
70
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model,
71
+ :disable_range? => true
72
+
73
+ source.disable_range?.should be_true
74
+ end
75
+ end
76
+
77
+ describe '#fields' do
78
+ it "has the internal class field by default" do
79
+ source.fields.collect(&:name).should include('sphinx_internal_class')
80
+ end
81
+
82
+ it "sets the sphinx class field to use a string of the class name" do
83
+ source.fields.detect { |field|
84
+ field.name == 'sphinx_internal_class'
85
+ }.columns.first.__name.should == "'User'"
86
+ end
87
+
88
+ it "uses the inheritance column if it exists for the sphinx class field" do
89
+ adapter.stub(:convert_nulls) { |clause, default|
90
+ "ifnull(#{clause}, #{default})"
91
+ }
92
+ model.stub :column_names => ['type']
93
+
94
+ source.fields.detect { |field|
95
+ field.name == 'sphinx_internal_class'
96
+ }.columns.first.__name.
97
+ should == "ifnull(type, 'User')"
98
+ end
99
+
100
+ it "marks the internal class field as a facet" do
101
+ source.fields.detect { |field|
102
+ field.name == 'sphinx_internal_class'
103
+ }.options[:facet].should be_true
104
+ end
105
+ end
106
+
107
+ describe '#name' do
108
+ it "defaults to the model name downcased with the core suffix" do
109
+ source.name.should == 'user_core'
110
+ end
111
+
112
+ it "changes the suffix to delta if set to true" do
113
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model,
114
+ :delta? => true
115
+
116
+ source.name.should == 'user_delta'
117
+ end
118
+
119
+ it "allows for custom names, but adds the core suffix" do
120
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model,
121
+ :name => 'people'
122
+
123
+ source.name.should == 'people_core'
124
+ end
125
+
126
+ it "allows for custom names and adds the delta suffix if a delta source" do
127
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model,
128
+ :name => 'people', :delta? => true
129
+
130
+ source.name.should == 'people_delta'
131
+ end
132
+ end
133
+
134
+ describe '#offset' do
135
+ it "returns the given offset" do
136
+ source = ThinkingSphinx::ActiveRecord::SQLSource.new model, :offset => 12
137
+
138
+ source.offset.should == 12
139
+ end
140
+ end
141
+
142
+ describe '#render' do
143
+ let(:builder) { double('builder', :sql_query_pre => []).as_null_object }
144
+ let(:config) { double('config', :settings => {}) }
145
+ let(:presenter) { double('presenter', :collection_type => :uint) }
146
+ let(:template) { double('template', :apply => true) }
147
+
148
+ before :each do
149
+ ThinkingSphinx::ActiveRecord::SQLBuilder.stub! :new => builder
150
+ ThinkingSphinx::ActiveRecord::Attribute::SphinxPresenter.stub :new => presenter
151
+ ThinkingSphinx::ActiveRecord::SQLSource::Template.stub :new => template
152
+ ThinkingSphinx::Configuration.stub :instance => config
153
+ end
154
+
155
+ it "sets the sql_host setting from the model's database settings" do
156
+ db_config[:host] = '12.34.56.78'
157
+
158
+ source.render
159
+
160
+ source.sql_host.should == '12.34.56.78'
161
+ end
162
+
163
+ it "defaults sql_host to localhost if the model has no host" do
164
+ db_config[:host] = nil
165
+
166
+ source.render
167
+
168
+ source.sql_host.should == 'localhost'
169
+ end
170
+
171
+ it "sets the sql_user setting from the model's database settings" do
172
+ db_config[:username] = 'pat'
173
+
174
+ source.render
175
+
176
+ source.sql_user.should == 'pat'
177
+ end
178
+
179
+ it "uses the user setting if username is not set in the model" do
180
+ db_config[:username] = nil
181
+ db_config[:user] = 'pat'
182
+
183
+ source.render
184
+
185
+ source.sql_user.should == 'pat'
186
+ end
187
+
188
+ it "sets the sql_pass setting from the model's database settings" do
189
+ db_config[:password] = 'swordfish'
190
+
191
+ source.render
192
+
193
+ source.sql_pass.should == 'swordfish'
194
+ end
195
+
196
+ it "escapes hashes in the password for sql_pass" do
197
+ db_config[:password] = 'sword#fish'
198
+
199
+ source.render
200
+
201
+ source.sql_pass.should == 'sword\#fish'
202
+ end
203
+
204
+ it "sets the sql_db setting from the model's database settings" do
205
+ db_config[:database] = 'rails_app'
206
+
207
+ source.render
208
+
209
+ source.sql_db.should == 'rails_app'
210
+ end
211
+
212
+ it "sets the sql_port setting from the model's database settings" do
213
+ db_config[:port] = 5432
214
+
215
+ source.render
216
+
217
+ source.sql_port.should == 5432
218
+ end
219
+
220
+ it "sets the sql_sock setting from the model's database settings" do
221
+ db_config[:socket] = '/unix/socket'
222
+
223
+ source.render
224
+
225
+ source.sql_sock.should == '/unix/socket'
226
+ end
227
+
228
+ it "uses the builder's sql_query value" do
229
+ builder.stub! :sql_query => 'select * from table'
230
+
231
+ source.render
232
+
233
+ source.sql_query.should == 'select * from table'
234
+ end
235
+
236
+ it "uses the builder's sql_query_range value" do
237
+ builder.stub! :sql_query_range => 'select 0, 10 from table'
238
+
239
+ source.render
240
+
241
+ source.sql_query_range.should == 'select 0, 10 from table'
242
+ end
243
+
244
+ it "uses the builder's sql_query_info value" do
245
+ builder.stub! :sql_query_info => 'select * from table where id = ?'
246
+
247
+ source.render
248
+
249
+ source.sql_query_info.should == 'select * from table where id = ?'
250
+ end
251
+
252
+ it "appends the builder's sql_query_pre value" do
253
+ builder.stub! :sql_query_pre => ['Change Setting']
254
+
255
+ source.render
256
+
257
+ source.sql_query_pre.should == ['Change Setting']
258
+ end
259
+
260
+ it "adds fields with attributes to sql_field_string" do
261
+ source.fields << double('field',
262
+ :name => 'title', :with_attribute? => true, :file? => false)
263
+
264
+ source.render
265
+
266
+ source.sql_field_string.should include('title')
267
+ end
268
+
269
+ it "adds any joined or file fields" do
270
+ source.fields << double('field',
271
+ :name => 'title', :file? => true, :with_attribute? => false)
272
+
273
+ source.render
274
+
275
+ source.sql_file_field.should include('title')
276
+ end
277
+
278
+ it "adds any joined fields"
279
+
280
+ it "adds integer attributes to sql_attr_uint" do
281
+ source.attributes << double('attribute')
282
+ presenter.stub :declaration => 'count', :collection_type => :uint
283
+
284
+ source.render
285
+
286
+ source.sql_attr_uint.should include('count')
287
+ end
288
+
289
+ it "adds boolean attributes to sql_attr_bool" do
290
+ source.attributes << double('attribute')
291
+ presenter.stub :declaration => 'published', :collection_type => :bool
292
+
293
+ source.render
294
+
295
+ source.sql_attr_bool.should include('published')
296
+ end
297
+
298
+ it "adds string attributes to sql_attr_string" do
299
+ source.attributes << double('attribute')
300
+ presenter.stub :declaration => 'name', :collection_type => :string
301
+
302
+ source.render
303
+
304
+ source.sql_attr_string.should include('name')
305
+ end
306
+
307
+ it "adds timestamp attributes to sql_attr_timestamp" do
308
+ source.attributes << double('attribute')
309
+ presenter.stub :declaration => 'created_at',
310
+ :collection_type => :timestamp
311
+
312
+ source.render
313
+
314
+ source.sql_attr_timestamp.should include('created_at')
315
+ end
316
+
317
+ it "adds float attributes to sql_attr_float" do
318
+ source.attributes << double('attribute')
319
+ presenter.stub :declaration => 'rating', :collection_type => :float
320
+
321
+ source.render
322
+
323
+ source.sql_attr_float.should include('rating')
324
+ end
325
+
326
+ it "adds bigint attributes to sql_attr_bigint" do
327
+ source.attributes << double('attribute')
328
+ presenter.stub :declaration => 'super_id', :collection_type => :bigint
329
+
330
+ source.render
331
+
332
+ source.sql_attr_bigint.should include('super_id')
333
+ end
334
+
335
+ it "adds ordinal strings to sql_attr_str2ordinal" do
336
+ source.attributes << double('attribute')
337
+ presenter.stub :declaration => 'name', :collection_type => :str2ordinal
338
+
339
+ source.render
340
+
341
+ source.sql_attr_str2ordinal.should include('name')
342
+ end
343
+
344
+ it "adds multi-value attributes to sql_attr_multi" do
345
+ source.attributes << double('attribute')
346
+ presenter.stub :declaration => 'uint tag_ids from field',
347
+ :collection_type => :multi
348
+
349
+ source.render
350
+
351
+ source.sql_attr_multi.should include('uint tag_ids from field')
352
+ end
353
+
354
+ it "adds word count attributes to sql_attr_str2wordcount" do
355
+ source.attributes << double('attribute')
356
+ presenter.stub :declaration => 'name', :collection_type => :str2wordcount
357
+
358
+ source.render
359
+
360
+ source.sql_attr_str2wordcount.should include('name')
361
+ end
362
+
363
+ it "adds relevant settings from thinking_sphinx.yml" do
364
+ config.settings['mysql_ssl_cert'] = 'foo.cert'
365
+ config.settings['morphology'] = 'stem_en' # should be ignored
366
+
367
+ source.render
368
+
369
+ source.mysql_ssl_cert.should == 'foo.cert'
370
+ end
371
+ end
372
+
373
+ describe '#type' do
374
+ it "is mysql when using the MySQL Adapter" do
375
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter.
376
+ stub!(:=== => true)
377
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter.
378
+ stub!(:=== => false)
379
+
380
+ source.type.should == 'mysql'
381
+ end
382
+
383
+ it "is pgsql when using the PostgreSQL Adapter" do
384
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter.
385
+ stub!(:=== => false)
386
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter.
387
+ stub!(:=== => true)
388
+
389
+ source.type.should == 'pgsql'
390
+ end
391
+
392
+ it "raises an exception for any other adapter" do
393
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter.
394
+ stub!(:=== => false)
395
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter.
396
+ stub!(:=== => false)
397
+
398
+ lambda { source.type }.should raise_error
399
+ end
400
+ end
401
+ end
@@ -1,258 +1,351 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Configuration do
4
- describe "environment class method" do
5
- before :each do
6
- ThinkingSphinx::Configuration.reset_environment
4
+ let(:config) { ThinkingSphinx::Configuration.instance }
7
5
 
8
- ENV["RAILS_ENV"] = nil
9
- end
6
+ after :each do
7
+ ThinkingSphinx::Configuration.reset
8
+ end
10
9
 
11
- it "should use Rails.env if set" do
12
- was = Rails.env
13
- Rails.env = 'global_rails'
10
+ describe '.instance' do
11
+ it "returns an instance of ThinkingSphinx::Configuration" do
12
+ ThinkingSphinx::Configuration.instance.
13
+ should be_a(ThinkingSphinx::Configuration)
14
+ end
14
15
 
15
- ThinkingSphinx::Configuration.environment.should == 'global_rails'
16
+ it "memoizes the instance" do
17
+ config = double('configuration')
16
18
 
17
- Rails.env = was
18
- end
19
+ ThinkingSphinx::Configuration.should_receive(:new).once.and_return(config)
19
20
 
20
- it "should use the Rails environment value if set" do
21
- Rails.stub!(:env => "rails_production")
22
- ThinkingSphinx::Configuration.environment.should == "rails_production"
21
+ ThinkingSphinx::Configuration.instance
22
+ ThinkingSphinx::Configuration.instance
23
23
  end
24
+ end
24
25
 
25
- it "should default to development" do
26
- ThinkingSphinx::Configuration.environment.should == "development"
26
+ describe '#configuration_file' do
27
+ it "uses the Rails environment in the configuration file name" do
28
+ config.configuration_file.
29
+ should == Rails.root.join('config', 'test.sphinx.conf')
27
30
  end
28
31
  end
29
32
 
30
- describe '#version' do
33
+ describe '#connection' do
34
+ let(:connection) { double('connection') }
35
+
31
36
  before :each do
32
- @config = ThinkingSphinx::Configuration.instance
33
- @config.reset
37
+ Mysql2::Client.stub :new => connection
34
38
  end
35
39
 
36
- it "should use the given version from sphinx.yml if there is one" do
37
- open("#{Rails.root}/config/sphinx.yml", "w") do |f|
38
- f.write YAML.dump({'development' => {'version' => '0.9.7'}})
39
- end
40
- @config.reset
40
+ it "connects using the searchd address and port" do
41
+ config.searchd.stub :address => '127.0.0.1', :mysql41 => 121
41
42
 
42
- @config.version.should == '0.9.7'
43
+ Mysql2::Client.should_receive(:new).with(
44
+ :host => '127.0.0.1',
45
+ :port => 121,
46
+ :flags => Mysql2::Client::MULTI_STATEMENTS
47
+ ).and_return(connection)
48
+
49
+ config.connection
50
+ end
43
51
 
44
- FileUtils.rm "#{Rails.root}/config/sphinx.yml"
52
+ it "returns the connection" do
53
+ config.connection.should == connection
45
54
  end
46
55
 
47
- it "should detect the version from Riddle otherwise" do
48
- controller = @config.controller
49
- controller.stub!(:sphinx_version => '0.9.6')
56
+ it "respects any connection options in the settings" do
57
+ write_configuration(
58
+ 'connection_options' => {:username => 'pat', :port => 9312}
59
+ )
50
60
 
51
- Riddle::Controller.stub!(:new => controller)
52
- @config.reset
61
+ Mysql2::Client.should_receive(:new).with(
62
+ :host => '127.0.0.1',
63
+ :port => 9312,
64
+ :flags => Mysql2::Client::MULTI_STATEMENTS,
65
+ :username => 'pat'
66
+ ).and_return(connection)
53
67
 
54
- @config.version.should == '0.9.6'
68
+ config.connection
55
69
  end
56
70
  end
57
71
 
58
- describe "parse_config method" do
59
- before :each do
60
- @settings = {
61
- "development" => {
62
- "config_file" => "tmp/config/development.sphinx.conf",
63
- "searchd_log_file" => "searchd_log_file.log",
64
- "query_log_file" => "query_log_file.log",
65
- "pid_file" => "pid_file.pid",
66
- "searchd_file_path" => "searchd/file/path",
67
- "address" => "127.0.0.1",
68
- "port" => 3333,
69
- "min_prefix_len" => 2,
70
- "min_infix_len" => 3,
71
- "mem_limit" => "128M",
72
- "max_matches" => 1001,
73
- "morphology" => "stem_ru",
74
- "charset_type" => "latin1",
75
- "charset_table" => "table",
76
- "ignore_chars" => "e",
77
- "searchd_binary_name" => "sphinx-searchd",
78
- "indexer_binary_name" => "sphinx-indexer",
79
- "index_exact_words" => true,
80
- "indexed_models" => ['Alpha', 'Beta']
81
- }
82
- }
83
-
84
- open("#{Rails.root}/config/sphinx.yml", "w") do |f|
85
- f.write YAML.dump(@settings)
86
- end
72
+ describe '#controller' do
73
+ it "returns an instance of Riddle::Controller" do
74
+ config.controller.should be_a(Riddle::Controller)
87
75
  end
88
76
 
89
- it "should use the accessors to set the configuration values" do
90
- config = ThinkingSphinx::Configuration.instance
91
- config.send(:parse_config)
77
+ it "memoizes the instance" do
78
+ Riddle::Controller.should_receive(:new).once.
79
+ and_return(double('controller'))
92
80
 
93
- %w(config_file searchd_log_file query_log_file pid_file searchd_file_path
94
- address port searchd_binary_name indexer_binary_name).each do |key|
95
- config.send(key).should == @settings["development"][key]
96
- end
81
+ config.controller
82
+ config.controller
97
83
  end
98
84
 
99
- after :each do
100
- FileUtils.rm "#{Rails.root}/config/sphinx.yml"
85
+ it "sets the bin path from the thinking_sphinx.yml file" do
86
+ write_configuration('bin_path' => '/foo/bar/bin/')
87
+
88
+ config.controller.bin_path.should == '/foo/bar/bin/'
101
89
  end
102
- end
103
90
 
104
- describe "block configuration" do
105
- it "should let the user set-up a custom app_root" do
106
- ThinkingSphinx::Configuration.configure do |config|
107
- config.app_root = "/here/somewhere"
108
- end
109
- ThinkingSphinx::Configuration.instance.app_root.should == "/here/somewhere"
91
+ it "appends a backslash to the bin_path if appropriate" do
92
+ write_configuration('bin_path' => '/foo/bar/bin')
110
93
 
111
- ThinkingSphinx::Configuration.instance.reset
94
+ config.controller.bin_path.should == '/foo/bar/bin/'
112
95
  end
113
96
  end
114
97
 
115
- describe "initialisation" do
116
- it "should have a default bin_path of nothing" do
117
- ThinkingSphinx::Configuration.instance.bin_path.should == ""
98
+ describe '#index_paths' do
99
+ it "uses app/indices in the Rails app by default" do
100
+ config.index_paths.should == [Rails.root.join('app', 'indices')]
118
101
  end
102
+ end
119
103
 
120
- it "should append a / to bin_path if one is supplied" do
121
- @settings = {
122
- "development" => {
123
- "bin_path" => "path/to/somewhere"
124
- }
125
- }
126
-
127
- open("#{Rails.root}/config/sphinx.yml", "w") do |f|
128
- f.write YAML.dump(@settings)
129
- end
104
+ describe '#indices_for_references' do
105
+ it "selects from the full index set those with matching references" do
106
+ config.indices << double('index', :reference => :article)
107
+ config.indices << double('index', :reference => :book)
108
+ config.indices << double('index', :reference => :page)
130
109
 
131
- ThinkingSphinx::Configuration.instance.send(:parse_config)
132
- ThinkingSphinx::Configuration.instance.bin_path.should match(/\/$/)
110
+ config.indices_for_references(:book, :article).length.should == 2
111
+ end
112
+ end
133
113
 
134
- FileUtils.rm "#{Rails.root}/config/sphinx.yml"
114
+ describe '#indices_location' do
115
+ it "stores index files in db/sphinx/ENVIRONMENT" do
116
+ config.indices_location.should == Rails.root.join('db', 'sphinx', 'test')
135
117
  end
136
118
  end
137
119
 
138
- describe "index options" do
139
- before :each do
140
- @settings = {
141
- "development" => {"disable_range" => true}
142
- }
120
+ describe '#initialize' do
121
+ it "sets the daemon pid file within log for the Rails app" do
122
+ config.searchd.pid_file.
123
+ should == Rails.root.join('log', 'test.sphinx.pid')
124
+ end
143
125
 
144
- open("#{Rails.root}/config/sphinx.yml", "w") do |f|
145
- f.write YAML.dump(@settings)
146
- end
126
+ it "sets the daemon log within log for the Rails app" do
127
+ config.searchd.log.should == Rails.root.join('log', 'test.searchd.log')
128
+ end
129
+
130
+ it "sets the query log within log for the Rails app" do
131
+ config.searchd.query_log.
132
+ should == Rails.root.join('log', 'test.searchd.query.log')
133
+ end
134
+ end
135
+
136
+ describe '#next_offset' do
137
+ let(:reference) { double('reference') }
147
138
 
148
- @config = ThinkingSphinx::Configuration.instance
149
- @config.send(:parse_config)
139
+ it "starts at 0" do
140
+ config.next_offset(reference).should == 0
150
141
  end
151
142
 
152
- it "should collect disable_range" do
153
- @config.index_options[:disable_range].should be_true
143
+ it "increments for each new reference" do
144
+ config.next_offset(double('reference')).should == 0
145
+ config.next_offset(double('reference')).should == 1
146
+ config.next_offset(double('reference')).should == 2
154
147
  end
155
148
 
156
- after :each do
157
- FileUtils.rm "#{Rails.root}/config/sphinx.yml"
149
+ it "doesn't increment for recorded references" do
150
+ config.next_offset(reference).should == 0
151
+ config.next_offset(reference).should == 0
158
152
  end
159
153
  end
160
154
 
161
- it "should insert set index options into the configuration file" do
162
- config = ThinkingSphinx::Configuration.instance
155
+ describe '#preload_indices' do
156
+ it "searches each index path for ruby files" do
157
+ config.index_paths.replace ['/path/to/indices', '/path/to/other/indices']
163
158
 
164
- ThinkingSphinx::Configuration::IndexOptions.each do |option|
165
- config.reset
166
- config.index_options[option.to_sym] = "something"
167
- config.build
159
+ Dir.should_receive(:[]).with('/path/to/indices/**/*.rb').once.
160
+ and_return([])
161
+ Dir.should_receive(:[]).with('/path/to/other/indices/**/*.rb').once.
162
+ and_return([])
168
163
 
169
- file = open(config.config_file) { |f| f.read }
170
- file.should match(/#{option}\s+= something/)
164
+ config.preload_indices
165
+ end
166
+
167
+ it "loads each file returned" do
168
+ config.index_paths.replace ['/path/to/indices']
169
+ Dir.stub! :[] => [
170
+ '/path/to/indices/foo_index.rb',
171
+ '/path/to/indices/bar_index.rb'
172
+ ]
173
+
174
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
175
+ with('/path/to/indices/foo_index.rb').once
176
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
177
+ with('/path/to/indices/bar_index.rb').once
171
178
 
172
- config.index_options[option.to_sym] = nil
179
+ config.preload_indices
180
+ end
181
+
182
+ it "does not double-load indices" do
183
+ config.index_paths.replace ['/path/to/indices']
184
+ Dir.stub! :[] => [
185
+ '/path/to/indices/foo_index.rb',
186
+ '/path/to/indices/bar_index.rb'
187
+ ]
188
+
189
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
190
+ with('/path/to/indices/foo_index.rb').once
191
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
192
+ with('/path/to/indices/bar_index.rb').once
193
+
194
+ config.preload_indices
195
+ config.preload_indices
173
196
  end
174
197
  end
175
198
 
176
- it "should insert set source options into the configuration file" do
177
- config = ThinkingSphinx::Configuration.instance
178
- config.reset
199
+ describe '#render' do
200
+ before :each do
201
+ config.searchd.stub! :render => 'searchd { }'
202
+ end
203
+
204
+ it "searches each index path for ruby files" do
205
+ config.index_paths.replace ['/path/to/indices', '/path/to/other/indices']
206
+
207
+ Dir.should_receive(:[]).with('/path/to/indices/**/*.rb').once.
208
+ and_return([])
209
+ Dir.should_receive(:[]).with('/path/to/other/indices/**/*.rb').once.
210
+ and_return([])
179
211
 
180
- config.source_options[:sql_query_pre] = ["something"]
181
- ThinkingSphinx::Configuration::SourceOptions.each do |option|
182
- config.source_options[option.to_sym] ||= "something"
183
- config.build
212
+ config.render
213
+ end
184
214
 
185
- file = open(config.config_file) { |f| f.read }
186
- file.should match(/#{option}\s+= something/)
215
+ it "loads each file returned" do
216
+ config.index_paths.replace ['/path/to/indices']
217
+ Dir.stub! :[] => [
218
+ '/path/to/indices/foo_index.rb',
219
+ '/path/to/indices/bar_index.rb'
220
+ ]
187
221
 
188
- config.source_options.delete option.to_sym
222
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
223
+ with('/path/to/indices/foo_index.rb').once
224
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
225
+ with('/path/to/indices/bar_index.rb').once
226
+
227
+ config.render
189
228
  end
190
229
 
191
- config.source_options[:sql_query_pre] = []
230
+ it "does not double-load indices" do
231
+ config.index_paths.replace ['/path/to/indices']
232
+ Dir.stub! :[] => [
233
+ '/path/to/indices/foo_index.rb',
234
+ '/path/to/indices/bar_index.rb'
235
+ ]
236
+
237
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
238
+ with('/path/to/indices/foo_index.rb').once
239
+ ActiveSupport::Dependencies.should_receive(:require_or_load).
240
+ with('/path/to/indices/bar_index.rb').once
241
+
242
+ config.preload_indices
243
+ config.preload_indices
244
+ end
192
245
  end
193
246
 
194
- it "should not blow away delta or utf options if sql pre is specified in config" do
195
- config = ThinkingSphinx::Configuration.instance
196
- config.reset
247
+ describe '#render_to_file' do
248
+ let(:file) { double('file') }
249
+ let(:output) { config.render }
250
+
251
+ before :each do
252
+ config.searchd.stub! :render => 'searchd { }'
253
+ end
197
254
 
198
- config.source_options[:sql_query_pre] = ["a pre query"]
199
- config.build
200
- file = open(config.config_file) { |f| f.read }
255
+ it "writes the rendered configuration to the file" do
256
+ config.configuration_file = '/path/to/file.config'
201
257
 
202
- file.should match(/sql_query_pre = a pre query\n\s*sql_query_pre = UPDATE `\w+` SET `delta` = 0 WHERE `delta` = 1/im)
203
- file.should match(/sql_query_pre = a pre query\n\s*sql_query_pre = \n/im)
258
+ config.should_receive(:open).with('/path/to/file.config', 'w').
259
+ and_yield(file)
260
+ file.should_receive(:write).with(output)
204
261
 
205
- config.source_options[:sql_query_pre] = []
262
+ config.render_to_file
263
+ end
206
264
  end
207
265
 
208
- it "should set any explicit prefixed or infixed fields" do
209
- ThinkingSphinx::Configuration.instance.build
266
+ describe '#searchd' do
267
+ describe '#address' do
268
+ it "defaults to 127.0.0.1" do
269
+ config.searchd.address.should == '127.0.0.1'
270
+ end
210
271
 
211
- file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
212
- f.read
213
- }
214
- file.should match(/prefix_fields\s+= city/)
215
- file.should match(/infix_fields\s+= state/)
216
- end
272
+ it "respects the address setting" do
273
+ write_configuration('address' => '10.11.12.13')
217
274
 
218
- it "should not have prefix fields in indexes where nothing is set" do
219
- ThinkingSphinx::Configuration.instance.build
275
+ config.searchd.address.should == '10.11.12.13'
276
+ end
277
+ end
220
278
 
221
- file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
222
- f.read
223
- }
224
- file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m)
225
- end
279
+ describe '#mysql41' do
280
+ it "defaults to 9306" do
281
+ config.searchd.mysql41.should == 9306
282
+ end
226
283
 
227
- describe '#generate' do
228
- let(:config) { ThinkingSphinx::Configuration.instance }
284
+ it "respects the port setting" do
285
+ write_configuration('port' => 9313)
229
286
 
230
- it "should set all sphinx_internal_id attributes to bigints if one is" do
231
- config.reset
232
- config.generate
287
+ config.searchd.mysql41.should == 9313
288
+ end
233
289
 
234
- config.configuration.indices.each do |index|
235
- next if index.is_a? Riddle::Configuration::DistributedIndex
290
+ it "respects the mysql41 setting" do
291
+ write_configuration('mysql41' => 9307)
236
292
 
237
- index.sources.each do |source|
238
- source.sql_attr_bigint.should include(:sphinx_internal_id)
239
- end
293
+ config.searchd.mysql41.should == 9307
240
294
  end
241
295
  end
242
296
  end
243
297
 
244
- describe '#models_by_crc' do
245
- before :each do
246
- @config = ThinkingSphinx::Configuration.instance
247
- end
298
+ describe '#settings' do
299
+ context 'YAML file exists' do
300
+ before :each do
301
+ File.stub :exists? => true
302
+ end
303
+
304
+ it "reads from the YAML file" do
305
+ File.should_receive(:read).and_return('')
306
+
307
+ config.settings
308
+ end
248
309
 
249
- it "should return a hash" do
250
- @config.models_by_crc.should be_a(Hash)
310
+ it "uses the settings for the given environment" do
311
+ File.stub :read => {
312
+ 'test' => {'foo' => 'bar'},
313
+ 'staging' => {'baz' => 'qux'}
314
+ }.to_yaml
315
+ Rails.stub :env => 'staging'
316
+
317
+ config.settings['baz'].should == 'qux'
318
+ end
319
+
320
+ it "remembers the file contents" do
321
+ File.should_receive(:read).and_return('')
322
+
323
+ config.settings
324
+ config.settings
325
+ end
326
+
327
+ it "returns an empty hash when no settings for the environment exist" do
328
+ File.stub :read => {'test' => {'foo' => 'bar'}}.to_yaml
329
+ Rails.stub :env => 'staging'
330
+
331
+ config.settings.should == {}
332
+ end
251
333
  end
252
334
 
253
- it "should pair class names to their crc codes" do
254
- @config.models_by_crc[Person.to_crc32].should == 'Person'
255
- @config.models_by_crc[Alpha.to_crc32].should == 'Alpha'
335
+ context 'YAML file does not exist' do
336
+ before :each do
337
+ File.stub :exists? => false
338
+ end
339
+
340
+ it "does not read the file" do
341
+ File.should_not_receive(:read)
342
+
343
+ config.settings
344
+ end
345
+
346
+ it "returns an empty hash" do
347
+ config.settings.should == {}
348
+ end
256
349
  end
257
350
  end
258
351
  end