ts-xml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +30 -0
  3. data/features/alternate_primary_key.feature +27 -0
  4. data/features/attribute_transformation.feature +22 -0
  5. data/features/attribute_updates.feature +39 -0
  6. data/features/deleting_instances.feature +67 -0
  7. data/features/direct_attributes.feature +11 -0
  8. data/features/excerpts.feature +13 -0
  9. data/features/extensible_delta_indexing.feature +9 -0
  10. data/features/facets.feature +82 -0
  11. data/features/facets_across_model.feature +29 -0
  12. data/features/handling_edits.feature +92 -0
  13. data/features/retry_stale_indexes.feature +24 -0
  14. data/features/searching_across_models.feature +20 -0
  15. data/features/searching_by_index.feature +40 -0
  16. data/features/searching_by_model.feature +175 -0
  17. data/features/searching_with_find_arguments.feature +56 -0
  18. data/features/sphinx_detection.feature +25 -0
  19. data/features/sphinx_scopes.feature +42 -0
  20. data/features/step_definitions/alpha_steps.rb +7 -0
  21. data/features/step_definitions/beta_steps.rb +7 -0
  22. data/features/step_definitions/common_steps.rb +188 -0
  23. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  24. data/features/step_definitions/facet_steps.rb +96 -0
  25. data/features/step_definitions/find_arguments_steps.rb +36 -0
  26. data/features/step_definitions/gamma_steps.rb +15 -0
  27. data/features/step_definitions/scope_steps.rb +15 -0
  28. data/features/step_definitions/search_steps.rb +89 -0
  29. data/features/step_definitions/sphinx_steps.rb +35 -0
  30. data/features/sti_searching.feature +19 -0
  31. data/features/support/database.example.yml +3 -0
  32. data/features/support/db/fixtures/alphas.rb +10 -0
  33. data/features/support/db/fixtures/authors.rb +1 -0
  34. data/features/support/db/fixtures/betas.rb +10 -0
  35. data/features/support/db/fixtures/boxes.rb +9 -0
  36. data/features/support/db/fixtures/categories.rb +1 -0
  37. data/features/support/db/fixtures/cats.rb +3 -0
  38. data/features/support/db/fixtures/comments.rb +24 -0
  39. data/features/support/db/fixtures/developers.rb +29 -0
  40. data/features/support/db/fixtures/dogs.rb +3 -0
  41. data/features/support/db/fixtures/extensible_betas.rb +10 -0
  42. data/features/support/db/fixtures/foxes.rb +3 -0
  43. data/features/support/db/fixtures/gammas.rb +10 -0
  44. data/features/support/db/fixtures/people.rb +1001 -0
  45. data/features/support/db/fixtures/posts.rb +6 -0
  46. data/features/support/db/fixtures/robots.rb +14 -0
  47. data/features/support/db/fixtures/tags.rb +27 -0
  48. data/features/support/db/migrations/create_alphas.rb +7 -0
  49. data/features/support/db/migrations/create_animals.rb +5 -0
  50. data/features/support/db/migrations/create_authors.rb +3 -0
  51. data/features/support/db/migrations/create_authors_posts.rb +6 -0
  52. data/features/support/db/migrations/create_betas.rb +5 -0
  53. data/features/support/db/migrations/create_boxes.rb +5 -0
  54. data/features/support/db/migrations/create_categories.rb +3 -0
  55. data/features/support/db/migrations/create_comments.rb +10 -0
  56. data/features/support/db/migrations/create_developers.rb +9 -0
  57. data/features/support/db/migrations/create_extensible_betas.rb +5 -0
  58. data/features/support/db/migrations/create_gammas.rb +3 -0
  59. data/features/support/db/migrations/create_people.rb +13 -0
  60. data/features/support/db/migrations/create_posts.rb +5 -0
  61. data/features/support/db/migrations/create_robots.rb +4 -0
  62. data/features/support/db/migrations/create_taggings.rb +5 -0
  63. data/features/support/db/migrations/create_tags.rb +4 -0
  64. data/features/support/env.rb +21 -0
  65. data/features/support/lib/generic_delta_handler.rb +8 -0
  66. data/features/support/models/alpha.rb +21 -0
  67. data/features/support/models/animal.rb +5 -0
  68. data/features/support/models/author.rb +3 -0
  69. data/features/support/models/beta.rb +8 -0
  70. data/features/support/models/box.rb +8 -0
  71. data/features/support/models/cat.rb +3 -0
  72. data/features/support/models/category.rb +4 -0
  73. data/features/support/models/comment.rb +10 -0
  74. data/features/support/models/developer.rb +16 -0
  75. data/features/support/models/dog.rb +3 -0
  76. data/features/support/models/extensible_beta.rb +9 -0
  77. data/features/support/models/fox.rb +5 -0
  78. data/features/support/models/gamma.rb +5 -0
  79. data/features/support/models/person.rb +23 -0
  80. data/features/support/models/post.rb +21 -0
  81. data/features/support/models/robot.rb +12 -0
  82. data/features/support/models/tag.rb +3 -0
  83. data/features/support/models/tagging.rb +4 -0
  84. data/lib/thinking_sphinx/xml.rb +5 -0
  85. data/lib/thinking_sphinx/xml/adapters/abstract_adapter.rb +34 -0
  86. data/lib/thinking_sphinx/xml/adapters/oracle_adapter.rb +123 -0
  87. data/lib/thinking_sphinx/xml/adapters/sqlite3_adapter.rb +95 -0
  88. data/lib/thinking_sphinx/xml/source.rb +46 -0
  89. data/lib/thinking_sphinx/xml/tasks.rb +95 -0
  90. data/spec/cucumber_env.rb +22 -0
  91. metadata +183 -0
@@ -0,0 +1,24 @@
1
+ Feature: Manually updating Sphinx indexes to handle uncaught deletions
2
+ In order to keep indexes as up to date as possible
3
+ Thinking Sphinx
4
+ Should automatically update the indexes and retry the search if it gets a nil result
5
+
6
+ Scenario: Changing retry_stale settings
7
+ Given Sphinx is running
8
+ And I am searching on gammas
9
+ Then I should not get 0 results
10
+
11
+ When I set retry stale to false
12
+ And I set per page to 1
13
+ And I order by "sphinx_internal_id ASC"
14
+ And I destroy gamma one without callbacks
15
+ Then I should get a single result of nil
16
+
17
+ When I set retry stale to 1
18
+ Then I should get a single gamma result with a name of two
19
+
20
+ When I destroy gamma two without callbacks
21
+ Then I should get a single result of nil
22
+
23
+ When I set retry stale to true
24
+ Then I should get a single gamma result with a name of three
@@ -0,0 +1,20 @@
1
+ Feature: Searching across multiple model
2
+ In order to use Thinking Sphinx's core functionality
3
+ A developer
4
+ Should be able to search on multiple models
5
+
6
+ Scenario: Retrieving total result count
7
+ Given Sphinx is running
8
+ When I search for James
9
+ And I am retrieving the result count
10
+ Then I should get a value of 3
11
+
12
+ Scenario: Confirming existance of a document id in a given index
13
+ Given Sphinx is running
14
+ When I search for the document id of alpha one in the alpha_core index
15
+ Then it should exist
16
+
17
+ Scenario: Retrieving results from multiple models
18
+ Given Sphinx is running
19
+ When I search for ten
20
+ Then I should get 4 results
@@ -0,0 +1,40 @@
1
+ Feature: Searching within a single index
2
+ In order to use Thinking Sphinx's core functionality
3
+ A developer
4
+ Should be able to search on a single index
5
+
6
+ Scenario: Searching with alternative index
7
+ Given Sphinx is running
8
+ And I am searching on alphas
9
+ When I order by value
10
+ And I use index alternative_core
11
+ Then I should get 7 results
12
+
13
+ Scenario: Searching with default index
14
+ Given Sphinx is running
15
+ And I am searching on alphas
16
+ When I order by value
17
+ And I use index alpha_core
18
+ Then I should get 10 results
19
+
20
+ Scenario: Searching without specified index
21
+ Given Sphinx is running
22
+ And I am searching on alphas
23
+ When I order by value
24
+ Then I should get 10 results
25
+
26
+ Scenario: Deleting instances from the core index
27
+ Given Sphinx is running
28
+ And I am searching on alphas
29
+
30
+ When I create a new alpha named eleven
31
+ And I process the alpha_core index
32
+ And I process the alternative_core index
33
+ And I wait for Sphinx to catch up
34
+ And I search for eleven
35
+ Then I should get 1 result
36
+
37
+ When I destroy alpha eleven
38
+ And I wait for Sphinx to catch up
39
+ And I search for eleven
40
+ Then I should get 0 results
@@ -0,0 +1,175 @@
1
+ Feature: Searching on a single model
2
+ In order to use Thinking Sphinx's core functionality
3
+ A developer
4
+ Should be able to search on a single model
5
+
6
+ Scenario: Searching using a basic query
7
+ Given Sphinx is running
8
+ And I am searching on people
9
+ When I search for James
10
+ Then I should get 3 results
11
+
12
+ Scenario: Searching on a specific field
13
+ Given Sphinx is running
14
+ And I am searching on people
15
+ When I search for James on first_name
16
+ Then I should get 2 results
17
+
18
+ Scenario: Searching on multiple fields
19
+ Given Sphinx is running
20
+ And I am searching on people
21
+ When I search for James on first_name
22
+ And I search for Chamberlain on last_name
23
+ Then I should get 1 result
24
+
25
+ Scenario: Searching on association content
26
+ Given Sphinx is running
27
+ And I am searching on posts
28
+
29
+ When I search for "Waffles"
30
+ Then I should get 1 result
31
+
32
+ When I search for "Turtle"
33
+ Then I should get 1 result
34
+
35
+ Scenario: Searching with a filter
36
+ Given Sphinx is running
37
+ And I am searching on alphas
38
+ When I filter by 1 on value
39
+ Then I should get 1 result
40
+
41
+ Scenario: Searching with multiple filters
42
+ Given Sphinx is running
43
+ And I am searching on boxes
44
+ When I filter by 2 on width
45
+ And I filter by 2 on length
46
+ Then I should get 1 result
47
+
48
+ Scenario: Searching with a ranged time filter
49
+ Given Sphinx is running
50
+ And I am searching on people
51
+ When I filter by birthday between 1975 and 1976
52
+ Then I should get 16 results
53
+
54
+ Scenario: Searching to filter multiple values on an MVA
55
+ Given Sphinx is running
56
+ And I am searching on boxes
57
+ When I filter by 11 and 12 on dimensions
58
+ Then I should get 2 results
59
+ When I clear existing filters
60
+ And I filter by both 11 and 12 on dimensions
61
+ Then I should get 1 result
62
+
63
+ Scenario: Filtering on timestamp MVAs
64
+ Given Sphinx is running
65
+ And I am searching on posts
66
+ When I filter by 978307200 on comments_created_at
67
+ Then I should get 1 result
68
+
69
+ Scenario: Searching by NULL/0 values in MVAs
70
+ Given Sphinx is running
71
+ And I am searching on boxes
72
+ When I filter by 0 on dimensions
73
+ Then I should get 1 result
74
+
75
+ Given Sphinx is running
76
+ And I am searching on developers
77
+ When I clear existing filters
78
+ And I filter by 0 on tag_ids
79
+ Then I should get 1 result
80
+
81
+ Scenario: Searching on a MVA configured as ranged_query
82
+ Given Sphinx is running
83
+ And I am searching on posts
84
+ When I filter by 1 on comment_ids
85
+ Then I should get 1 result
86
+ When I clear existing filters
87
+ And I filter by both 1 and 2 on comment_ids
88
+ Then I should get 1 results
89
+ When I clear existing filters
90
+ And I filter by 10 on comment_ids
91
+ Then I should get 0 results
92
+
93
+ Scenario: Searching with ordering by attribute
94
+ Given Sphinx is running
95
+ And I am searching on alphas
96
+ When I order by value
97
+ Then I should get 10 results
98
+ And the value of each result should indicate order
99
+
100
+ Scenario: Searching with ordering on a sortable field
101
+ Given Sphinx is running
102
+ And I am searching on people
103
+ And I order by first_name
104
+ Then I should get 20 results
105
+ And the first_name of each result should indicate order
106
+
107
+ Scenario: Intepreting Sphinx Internal Identifiers
108
+ Given Sphinx is running
109
+ And I am searching on people
110
+ Then I should get 20 results
111
+ And each result id should match the corresponding sphinx internal id
112
+
113
+ Scenario: Retrieving weightings
114
+ Given Sphinx is running
115
+ And I am searching on people
116
+ When I search for "Ellie Ford"
117
+ And I set match mode to any
118
+ Then I can iterate by result and weighting
119
+
120
+ Scenario: Retrieving group counts
121
+ Given Sphinx is running
122
+ And I am searching on people
123
+ When I group results by the birthday attribute
124
+ Then I can iterate by result and count
125
+
126
+ Scenario: Retrieving group values
127
+ Given Sphinx is running
128
+ And I am searching on people
129
+ When I group results by the birthday attribute
130
+ Then I can iterate by result and group
131
+
132
+ Scenario: Retrieving both group values and counts
133
+ Given Sphinx is running
134
+ And I am searching on people
135
+ When I group results by the birthday attribute
136
+ Then I can iterate by result and group and count
137
+
138
+ Scenario: Searching for ids
139
+ Given Sphinx is running
140
+ And I am searching on people
141
+ When I search for Ellie
142
+ And I am searching for ids
143
+ Then I should have an array of integers
144
+
145
+ Scenario: Search results should match Sphinx's order
146
+ Given Sphinx is running
147
+ And I am searching on people
148
+ When I search for Ellie
149
+ And I order by "sphinx_internal_id DESC"
150
+ Then searching for ids should match the record ids of the normal search results
151
+
152
+ Scenario: Retrieving total result count when total is less than a page
153
+ Given Sphinx is running
154
+ And I am searching on people
155
+ When I search for James
156
+ And I am retrieving the result count
157
+ Then I should get a value of 3
158
+
159
+ Scenario: Retrieving total result count for more than a page
160
+ Given Sphinx is running
161
+ And I am searching on people
162
+ When I am retrieving the result count
163
+ Then I should get a value of 1000
164
+
165
+ Scenario: Searching with Unicode Characters
166
+ Given Sphinx is running
167
+ And I am searching on people
168
+ When I search for "José* "
169
+ Then I should get 1 result
170
+
171
+ Scenario: Searching by fields from HABTM joins
172
+ Given Sphinx is running
173
+ And I am searching on posts
174
+ When I search for "Shakespeare"
175
+ Then I should get 1 result
@@ -0,0 +1,56 @@
1
+ Feature: Keeping AR::Base.find arguments in search calls
2
+ To keep things as streamlined as possible
3
+ Thinking Sphinx
4
+ Should respect particular arguments to AR::Base.find calls
5
+
6
+ Scenario: Respecting the include option
7
+ Given Sphinx is running
8
+ And I am searching on posts
9
+ Then I should get 1 result
10
+
11
+ When I get the first comment
12
+ And I track queries
13
+ And I compare comments
14
+ Then I should have 1 query
15
+
16
+ When I include comments
17
+ Then I should get 1 result
18
+ When I track queries
19
+ And I compare comments
20
+ Then I should have 0 queries
21
+
22
+ Scenario: Respecting the include option without using a specific model
23
+ Given Sphinx is running
24
+ And I search for "Hello World"
25
+ Then I should get 1 result
26
+
27
+ When I get the first comment
28
+ And I track queries
29
+ And I compare comments
30
+ Then I should have 1 query
31
+
32
+ When I include comments
33
+ Then I should get 1 result
34
+ When I track queries
35
+ And I compare comments
36
+ Then I should have 0 queries
37
+
38
+ Scenario: Respecting the select option
39
+ Given Sphinx is running
40
+ And I am searching on posts
41
+ Then I should get 1 result
42
+ And I should not get an error accessing the subject
43
+
44
+ When I select only content
45
+ Then I should get 1 result
46
+ And I should get an error accessing the subject
47
+
48
+ Scenario: Respecting the select option without using a specific model
49
+ Given Sphinx is running
50
+ When I search for "Hello World"
51
+ Then I should get 1 result
52
+ And I should not get an error accessing the subject
53
+
54
+ When I select only content
55
+ Then I should get 1 result
56
+ And I should get an error accessing the subject
@@ -0,0 +1,25 @@
1
+ Feature: Checking whether Sphinx is running or not
2
+ In order to avoid unnecessary errors
3
+ Thinking Sphinx
4
+ Should be able to determine whether Sphinx is running or not
5
+
6
+ Scenario: Checking Sphinx's status
7
+ Given Sphinx is running
8
+ Then Sphinx should be running
9
+
10
+ When I stop Sphinx
11
+ And I wait for Sphinx to catch up
12
+ Then Sphinx should not be running
13
+
14
+ When I start Sphinx
15
+ And I wait for Sphinx to catch up
16
+ Then Sphinx should be running
17
+
18
+ Given Sphinx is running
19
+ When I kill the Sphinx process
20
+ And I wait for Sphinx to catch up
21
+ Then Sphinx should not be running
22
+
23
+ When I start Sphinx again
24
+ And I wait for Sphinx to catch up
25
+ Then Sphinx should be running again
@@ -0,0 +1,42 @@
1
+ Feature: Sphinx Scopes
2
+
3
+ Scenario: Single Scope
4
+ Given Sphinx is running
5
+ And I am searching on people
6
+ When I use the with_first_name scope set to "Andrew"
7
+ Then I should get 7 results
8
+
9
+ Scenario: Two Field Scopes
10
+ Given Sphinx is running
11
+ And I am searching on people
12
+ When I use the with_first_name scope set to "Andrew"
13
+ And I use the with_last_name scope set to "Byrne"
14
+ Then I should get 1 result
15
+
16
+ Scenario: Mixing Filter and Field Scopes
17
+ Given Sphinx is running
18
+ And I am searching on people
19
+ When I use the with_first_name scope set to "Andrew"
20
+ And I use the with_id scope set to 99
21
+ Then I should get 1 result
22
+
23
+ Scenario: Mixing Field and ID Scopes
24
+ Given Sphinx is running
25
+ And I am searching on people
26
+ When I use the with_first_name scope set to "Andrew"
27
+ And I use the ids_only scope
28
+ Then I should get 7 results
29
+ And I should have an array of integers
30
+
31
+ Scenario: Non-field/filter Scopes
32
+ Given Sphinx is running
33
+ And I am searching on people
34
+ When I use the ids_only scope
35
+ Then I should have an array of integers
36
+
37
+ Scenario: Counts with scopes
38
+ Given Sphinx is running
39
+ And I am searching on people
40
+ When I use the with_first_name scope set to "Andrew"
41
+ And I am retrieving the scoped result count
42
+ Then I should get a value of 7
@@ -0,0 +1,7 @@
1
+ When /^I create a new alpha named (\w+)$/ do |name|
2
+ Alpha.create!(:name => name, :value => 101)
3
+ end
4
+
5
+ When /^I change the (\w+) of alpha (\w+) to (\w+)$/ do |column, name, replacement|
6
+ Alpha.find_by_name(name).update_attributes(column.to_sym => replacement)
7
+ end
@@ -0,0 +1,7 @@
1
+ When /^I create a new beta named (\w+)$/ do |name|
2
+ Beta.create!(:name => name, :value => 101)
3
+ end
4
+
5
+ When /^I change the (\w+) of beta (\w+) to (\w+)$/ do |column, name, replacement|
6
+ Beta.find_by_name(name).update_attributes(column.to_sym => replacement)
7
+ end
@@ -0,0 +1,188 @@
1
+ Before do
2
+ $queries_executed = []
3
+
4
+ @model = nil
5
+ @method = :search
6
+ @query = ""
7
+ @conditions = {}
8
+ @with = {}
9
+ @without = {}
10
+ @with_all = {}
11
+ @options = {}
12
+ @results = nil
13
+
14
+ Given "updates are enabled"
15
+ end
16
+
17
+ Given /^I am searching on (.+)$/ do |model|
18
+ @model = model.gsub(/\s/, '_').singularize.camelize.constantize
19
+ end
20
+
21
+ Given /^updates are (\w+)$/ do |action|
22
+ ThinkingSphinx.updates_enabled = (action == "enabled")
23
+ end
24
+
25
+ When /^I am searching for ids$/ do
26
+ @results = nil
27
+ @method = :search_for_ids
28
+ end
29
+
30
+ When /^I use index (.+)$/ do |index|
31
+ @results = nil
32
+ @options[:index] = index
33
+ end
34
+
35
+ When /^I am retrieving the result count$/ do
36
+ @result = nil
37
+ @method = @model ? :search_count : :count
38
+ end
39
+
40
+ When /^I search$/ do
41
+ @results = nil
42
+ end
43
+
44
+ When /^I search for (\w+)$/ do |query|
45
+ @results = nil
46
+ @query = query
47
+ end
48
+
49
+ When /^I search for "([^\"]*)"$/ do |query|
50
+ @results = nil
51
+ @query = query
52
+ end
53
+
54
+ When /^I search for (\w+) on (\w+)$/ do |query, field|
55
+ @results = nil
56
+ @conditions[field.to_sym] = query
57
+ end
58
+
59
+ When /^I output the raw result data$/ do
60
+ puts results.results.inspect
61
+ end
62
+
63
+ When /^I clear existing filters$/ do
64
+ @with = {}
65
+ @without = {}
66
+ @with_all = {}
67
+ end
68
+
69
+ When /^I filter by (\w+) on (\w+)$/ do |filter, attribute|
70
+ @results = nil
71
+ @with[attribute.to_sym] = filter.to_i
72
+ end
73
+
74
+ When /^I filter by (\d+) and (\d+) on (\w+)$/ do |value_one, value_two, attribute|
75
+ @results = nil
76
+ @with[attribute.to_sym] = [value_one.to_i, value_two.to_i]
77
+ end
78
+
79
+ When /^I filter by both (\d+) and (\d+) on (\w+)$/ do |value_one, value_two, attribute|
80
+ @results = nil
81
+ @with_all[attribute.to_sym] = [value_one.to_i, value_two.to_i]
82
+ end
83
+
84
+ When /^I filter between ([\d\.]+) and ([\d\.]+) on (\w+)$/ do |first, last, attribute|
85
+ @results = nil
86
+ if first[/\./].nil? && last[/\./].nil?
87
+ @with[attribute.to_sym] = first.to_i..last.to_i
88
+ else
89
+ @with[attribute.to_sym] = first.to_f..last.to_f
90
+ end
91
+ end
92
+
93
+ When /^I filter between (\d+) and (\d+) days ago on (\w+)$/ do |last, first, attribute|
94
+ @results = nil
95
+ @with[attribute.to_sym] = first.to_i.days.ago..last.to_i.days.ago
96
+ end
97
+
98
+ When /^I filter by (\w+) between (\d+) and (\d+)$/ do |attribute, first, last|
99
+ @results = nil
100
+ @with[attribute.to_sym] = Time.utc(first.to_i)..Time.utc(last.to_i)
101
+ end
102
+
103
+ When /^I order by (\w+)$/ do |attribute|
104
+ @results = nil
105
+ @options[:order] = attribute.to_sym
106
+ end
107
+
108
+ When /^I order by "([^\"]+)"$/ do |str|
109
+ @results = nil
110
+ @options[:order] = str
111
+ end
112
+
113
+ When /^I group results by the (\w+) attribute$/ do |attribute|
114
+ @results = nil
115
+ @options[:group_function] = :attr
116
+ @options[:group_by] = attribute
117
+ end
118
+
119
+ When /^I set match mode to (\w+)$/ do |match_mode|
120
+ @results = nil
121
+ @options[:match_mode] = match_mode.to_sym
122
+ end
123
+
124
+ When /^I set per page to (\d+)$/ do |per_page|
125
+ @results = nil
126
+ @options[:per_page] = per_page.to_i
127
+ end
128
+
129
+ When /^I set retry stale to (\w+)$/ do |retry_stale|
130
+ @results = nil
131
+ @options[:retry_stale] = case retry_stale
132
+ when "true" then true
133
+ when "false" then false
134
+ else retry_stale.to_i
135
+ end
136
+ end
137
+
138
+ When /^I destroy (\w+) (\w+)$/ do |model, name|
139
+ model.gsub(/\s/, '_').camelize.
140
+ constantize.find_by_name(name).destroy
141
+ end
142
+
143
+ Then /^the (\w+) of each result should indicate order$/ do |attribute|
144
+ results.inject(nil) do |prev, current|
145
+ unless prev.nil?
146
+ current.send(attribute.to_sym).should >= prev.send(attribute.to_sym)
147
+ end
148
+
149
+ current
150
+ end
151
+ end
152
+
153
+ Then /^I can iterate by result and (\w+)$/ do |attribute|
154
+ iteration = lambda { |result, attr_value|
155
+ result.should be_kind_of(@model)
156
+ unless attribute == "group" && attr_value.nil?
157
+ attr_value.should be_kind_of(Integer)
158
+ end
159
+ }
160
+
161
+ results.send("each_with_#{attribute}", &iteration)
162
+ end
163
+
164
+ Then /^I should get (\d+) results?$/ do |count|
165
+ results.length.should == count.to_i
166
+ end
167
+
168
+ Then /^I should not get (\d+) results?$/ do |count|
169
+ results.length.should_not == count.to_i
170
+ end
171
+
172
+ Then /^I should get as many results as there are (.+)$/ do |model|
173
+ results.length.should == model.gsub(/\s/, '_').singularize.camelize.
174
+ constantize.count
175
+ end
176
+
177
+ def results
178
+ @results ||= (@model || ThinkingSphinx).send(
179
+ @method,
180
+ @query,
181
+ @options.merge(
182
+ :conditions => @conditions,
183
+ :with => @with,
184
+ :without => @without,
185
+ :with_all => @with_all
186
+ )
187
+ )
188
+ end