pose 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,279 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Pose do
6
+ subject { PosableOne.new }
7
+
8
+ describe 'associations' do
9
+ it 'allows to access the associated words of a posable object directly' do
10
+ subject.should have(0).pose_words
11
+ subject.pose_words << PoseWord.new(text: 'one')
12
+ subject.should have_pose_words(['one'])
13
+ end
14
+ end
15
+
16
+ describe '#update_pose_index' do
17
+
18
+ context "in the 'test' environment" do
19
+ # Set global env configuration.
20
+ before :each do
21
+ Pose::CONFIGURATION[:search_in_tests] = search_in_tests
22
+ end
23
+
24
+ # Restores global configuration to default.
25
+ after :each do
26
+ Pose::CONFIGURATION[:search_in_tests] = true
27
+ end
28
+
29
+ context "search_in_tests flag is not enabled" do
30
+ let(:search_in_tests) { false }
31
+
32
+ it "doesn't call update_pose_words" do
33
+ subject.should_not_receive :update_pose_words
34
+ subject.update_pose_index
35
+ end
36
+ end
37
+
38
+ context "search_in_tests flag is enabled" do
39
+ let(:search_in_tests) { true }
40
+
41
+ it "calls update_pose_words" do
42
+ subject.should_receive :update_pose_words
43
+ subject.update_pose_index
44
+ end
45
+ end
46
+ end
47
+
48
+ # TODO(REMOVE).
49
+ context "in the 'production' environment' do" do
50
+ before :each do
51
+ @old_env = Rails.env
52
+ Rails.env = 'production'
53
+ Pose::CONFIGURATION[:search_in_tests] = false
54
+ end
55
+
56
+ after :each do
57
+ Rails.env = @old_env
58
+ Pose::CONFIGURATION[:search_in_tests] = true
59
+ end
60
+
61
+ it "always calls update_pose_words, even when search_in_tests is disabled" do
62
+ subject.should_receive :update_pose_words
63
+ subject.update_pose_index
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+ describe '#update_pose_words' do
70
+
71
+ it 'saves the words for search' do
72
+ subject.text = 'foo bar'
73
+ subject.update_pose_words
74
+ subject.should have_pose_words ['foo', 'bar']
75
+ end
76
+
77
+ it 'updates the search index when the text is changed' do
78
+ subject.text = 'foo'
79
+ subject.save!
80
+
81
+ subject.text = 'other text'
82
+ subject.update_pose_words
83
+
84
+ subject.should have_pose_words ['other', 'text']
85
+ end
86
+
87
+ it "doesn't create duplicate words" do
88
+ subject.text = 'foo foo'
89
+ subject.save!
90
+ subject.should have(1).pose_words
91
+ end
92
+ end
93
+
94
+
95
+ describe 'search' do
96
+
97
+ it 'works' do
98
+ pos = PosableOne.create text: 'foo'
99
+ result = Pose.search 'foo', PosableOne
100
+ result.should == { PosableOne => [pos] }
101
+ end
102
+
103
+ describe 'classes parameter' do
104
+
105
+ before :each do
106
+ @pos1 = PosableOne.create text: 'foo'
107
+ @pos2 = PosableTwo.create text: 'foo'
108
+ end
109
+
110
+ it 'returns all requested classes' do
111
+ result = Pose.search 'foo', [PosableOne, PosableTwo]
112
+
113
+ result.keys.should have(2).items
114
+ result.keys.should include PosableOne
115
+ result.keys.should include PosableTwo
116
+ end
117
+
118
+ it 'returns all matching instances of each requested class' do
119
+ result = Pose.search 'foo', [PosableOne, PosableTwo]
120
+
121
+ result[PosableOne].should == [@pos1]
122
+ result[PosableTwo].should == [@pos2]
123
+ end
124
+
125
+ it 'returns only instances of the given classes' do
126
+ result = Pose.search 'foo', PosableOne
127
+ result.keys.should include PosableOne
128
+ result.keys.should_not include PosableTwo
129
+ end
130
+ end
131
+
132
+ describe 'query parameter' do
133
+
134
+ it 'returns an empty array if nothing matches' do
135
+ pos1 = PosableOne.create text: 'one'
136
+ result = Pose.search 'two', PosableOne
137
+ result[PosableOne].should be_empty
138
+ end
139
+
140
+ it 'returns only objects that match all given query words' do
141
+ pos1 = PosableOne.create text: 'one two'
142
+ pos2 = PosableOne.create text: 'one three'
143
+ pos3 = PosableOne.create text: 'two three'
144
+
145
+ result = Pose.search 'two one', PosableOne
146
+
147
+ result[PosableOne].should == [pos1]
148
+ end
149
+
150
+ it 'returns nothing if searching for a non-existing word' do
151
+ pos1 = PosableOne.create text: 'one two'
152
+ result = Pose.search 'one zonk', PosableOne
153
+ result[PosableOne].should be_empty
154
+ end
155
+
156
+ it 'works if the query is given in uppercase' do
157
+ pos1 = PosableOne.create text: 'one two'
158
+ result = Pose.search 'OnE TwO', PosableOne
159
+ result[PosableOne].should == [pos1]
160
+ end
161
+ end
162
+
163
+
164
+ describe "'limit' parameter" do
165
+
166
+ it 'works' do
167
+ FactoryGirl.create :posable_one, text: 'foo one'
168
+ FactoryGirl.create :posable_one, text: 'foo two'
169
+ FactoryGirl.create :posable_one, text: 'foo three'
170
+
171
+ result = Pose.search 'foo', PosableOne, limit: 2
172
+
173
+ result[PosableOne].should have(2).items
174
+ end
175
+ end
176
+
177
+
178
+ describe "'result_type' parameter" do
179
+
180
+ before :each do
181
+ @foo_one = FactoryGirl.create :posable_one, text: 'foo one'
182
+ end
183
+
184
+ describe 'default behavior' do
185
+ it 'returns full objects' do
186
+ result = Pose.search 'foo', PosableOne
187
+ result[PosableOne].first.should == @foo_one
188
+ end
189
+ end
190
+
191
+ context ':ids given' do
192
+ it 'returns ids instead of objects' do
193
+ result = Pose.search 'foo', PosableOne, result_type: :ids
194
+ result[PosableOne].first.should == @foo_one.id
195
+ end
196
+ end
197
+ end
198
+
199
+
200
+ describe "'scopes' parameter" do
201
+
202
+ before :each do
203
+ @one = FactoryGirl.create :posable_one, text: 'foo one', private: true
204
+ @bar = FactoryGirl.create :posable_one, text: 'bar one', private: true
205
+ @two = FactoryGirl.create :posable_one, text: 'foo two', private: false
206
+ end
207
+
208
+ context 'with result type :classes' do
209
+
210
+ it 'limits the result set by the given scope' do
211
+ result = Pose.search 'foo', PosableOne, scope: [ private: true ]
212
+ result[PosableOne].should have(1).item
213
+ result[PosableOne].should include @one
214
+ end
215
+
216
+ it 'allows to use the hash syntax for queries' do
217
+ result = Pose.search 'foo', PosableOne, scope: [ private: true ]
218
+ result[PosableOne].should have(1).item
219
+ result[PosableOne].should include @one
220
+ end
221
+
222
+ it 'allows to use the string syntax for queries' do
223
+ result = Pose.search 'foo', PosableOne, scope: [ ['private = ?', true] ]
224
+ result[PosableOne].should have(1).item
225
+ result[PosableOne].should include @one
226
+ end
227
+
228
+ it 'allows to combine several scopes' do
229
+ @three = FactoryGirl.create :posable_one, text: 'foo two', private: true
230
+ result = Pose.search 'foo', PosableOne, scope: [ {private: true}, ['text = ?', 'foo two'] ]
231
+ result[PosableOne].should have(1).item
232
+ result[PosableOne].should include @three
233
+ end
234
+ end
235
+
236
+ context 'with result type :ids' do
237
+
238
+ it 'limits the result set by the given scope' do
239
+ result = Pose.search 'foo', PosableOne, result_type: :ids, scope: [ private: true ]
240
+ result[PosableOne].should have(1).item
241
+ result[PosableOne].should include @one.id
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+
248
+ describe 'autocomplete_words' do
249
+
250
+ it 'returns words that start with the given phrase' do
251
+ PosableOne.create text: 'great green pine tree'
252
+
253
+ result = Pose::Helpers.autocomplete_words 'gr'
254
+
255
+ result.should have(2).words
256
+ result.should include 'great'
257
+ result.should include 'green'
258
+ end
259
+
260
+ it 'returns words that match the given phrase exactly' do
261
+ PoseWord.create text: 'cat'
262
+ result = Pose::Helpers.autocomplete_words 'cat'
263
+ result.should == ['cat']
264
+ end
265
+
266
+ it 'stems the search query' do
267
+ PosableOne.create text: 'car'
268
+ result = Pose::Helpers.autocomplete_words 'cars'
269
+ result.should have(1).words
270
+ result[0].should == 'car'
271
+ end
272
+
273
+ it 'returns nothing if the search query is empty' do
274
+ PosableOne.create text: 'foo bar'
275
+ result = Pose::Helpers.autocomplete_words ''
276
+ result.should be_empty
277
+ end
278
+ end
279
+ end
@@ -2,47 +2,44 @@ require 'spec_helper'
2
2
 
3
3
  describe PoseAssignment do
4
4
 
5
- before :each do
6
- PoseAssignment.delete_all
7
- end
8
-
9
5
  describe "delete_class_index" do
10
-
6
+
11
7
  before :each do
12
8
  FactoryGirl.create :pose_assignment, posable_id: 1, posable_type: 'PosableOne'
13
9
  FactoryGirl.create :pose_assignment, posable_id: 2, posable_type: 'PosableTwo'
14
10
  PoseAssignment.delete_class_index PosableOne
15
11
  end
16
-
12
+
17
13
  it "deletes all PoseAssignments for the given class" do
18
14
  PoseAssignment.where(posable_type: 'PosableOne').should have(0).items
19
15
  end
20
-
16
+
21
17
  it "doesn't delete PoseAssignments for other classes" do
22
18
  PoseAssignment.where(posable_type: 'PosableTwo').should have(1).items
23
19
  end
24
20
  end
25
-
21
+
22
+
26
23
  describe "cleanup_orphaned_pose_assignments" do
27
-
24
+
28
25
  it "deletes the assignment if the posable object doesn't exist" do
29
26
  FactoryGirl.create :pose_assignment, posable_id: 2, posable_type: 'PosableOne'
30
27
  PoseAssignment.count.should > 0
31
28
  PoseAssignment.cleanup_orphaned_pose_assignments
32
- PoseAssignment.should have(0).items
29
+ PoseAssignment.count.should == 0
33
30
  end
34
-
31
+
35
32
  it "deletes the assignment if the pose_word doesn't exist" do
36
33
  assignment = FactoryGirl.create :pose_assignment, pose_word: nil, pose_word_id: 27
37
34
  PoseAssignment.cleanup_orphaned_pose_assignments
38
35
  PoseAssignment.find_by_id(assignment.id).should be_nil
39
36
  end
40
-
37
+
41
38
  it "doesn't delete the assignment if it is still used" do
42
39
  assignment = FactoryGirl.create :pose_assignment
43
40
  PoseAssignment.cleanup_orphaned_pose_assignments
44
41
  PoseAssignment.find_by_id(assignment.id).should_not be_nil
45
42
  end
46
43
  end
47
-
44
+
48
45
  end
@@ -1,23 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe PoseWord do
4
-
5
- before :all do
6
- PoseWord.delete_all
7
- end
8
-
9
- describe 'remove_unused_words' do
10
4
 
11
- it 'removes unused words' do
12
- FactoryGirl.create :pose_word
13
- PoseWord.remove_unused_words
14
- PoseWord.count.should == 0
15
- end
16
-
17
- it "doesn't remove used words" do
18
- snippet = FactoryGirl.create :posable_one
19
- PoseWord.remove_unused_words
20
- PoseWord.count.should > 0
5
+ describe 'class methods' do
6
+ subject { PoseWord }
7
+
8
+ describe '::remove_unused_words' do
9
+
10
+ before :each do
11
+ instantiate_objects
12
+ PoseWord.remove_unused_words
13
+ end
14
+
15
+ context 'having unused words' do
16
+ let(:instantiate_objects) { FactoryGirl.create :pose_word }
17
+ its(:count) { should == 0 }
18
+ end
19
+
20
+ context 'having used words' do
21
+ let(:instantiate_objects) { FactoryGirl.create :posable_one }
22
+ its(:count) { should > 0 }
23
+ end
21
24
  end
22
25
  end
23
26
  end
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,8 @@ require 'active_support/core_ext/string'
9
9
  require 'pose'
10
10
  require 'faker'
11
11
  require 'factory_girl'
12
+ require 'database_cleaner'
13
+
12
14
  FactoryGirl.find_definitions
13
15
 
14
16
  # Configure Rails Environment
@@ -16,7 +18,7 @@ ENV["RAILS_ENV"] = "test"
16
18
  Rails = Hashie::Mash.new({env: 'test'})
17
19
 
18
20
  # We have no Railtie in these tests --> load Pose manually.
19
- ActiveRecord::Base.send :extend, Pose::BaseAdditions
21
+ ActiveRecord::Base.send :extend, Pose::ActiveRecordBaseAdditions
20
22
 
21
23
  # Load support files
22
24
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
@@ -35,51 +37,21 @@ RSpec.configure do |config|
35
37
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
36
38
  # examples within a transaction, remove the following line or assign false
37
39
  # instead of true.
38
- # config.use_transactional_fixtures = true
40
+ # config.use_transactional_fixtures = true
39
41
 
40
42
  config.before :suite do
41
43
  setup_db
42
44
  Pose::CONFIGURATION[:search_in_tests] = true
45
+ DatabaseCleaner.strategy = :deletion
43
46
  end
44
-
45
- config.after :suite do
46
- teardown_db
47
- end
48
- end
49
47
 
50
-
51
- #####################
52
- # MATCHERS
53
- #
54
-
55
- # Verifies that a taggable object has the given tags.
56
- RSpec::Matchers.define :have_pose_words do |expected|
57
- match do |actual|
58
- actual.should have(expected.size).pose_words
59
- texts = actual.pose_words.map &:text
60
- expected.each do |expected_word|
61
- # Note (KG): Can't use text.should include(expected_word) here
62
- # because Ruby thinks I want to include a Module for some reason.
63
- texts.include?(expected_word).should be_true
64
- end
65
- end
66
- failure_message_for_should do |actual|
67
- texts = actual.pose_words.map &:text
68
- "expected that subject would have pose words [#{expected.join ', '}], but it has [#{texts.join ', '}]"
48
+ config.before :each do
49
+ DatabaseCleaner.start
69
50
  end
70
- end
71
-
72
51
 
73
- #####################
74
- # TEST CLASSES
75
- #
76
-
77
- class PosableOne < ActiveRecord::Base
78
- posify { text }
79
- end
80
-
81
- class PosableTwo < ActiveRecord::Base
82
- posify { text }
52
+ config.after :each do
53
+ DatabaseCleaner.clean
54
+ end
83
55
  end
84
56
 
85
57
 
@@ -88,32 +60,37 @@ end
88
60
  #
89
61
 
90
62
  def setup_db
91
- ActiveRecord::Schema.define(version: 1) do
63
+ ActiveRecord::Base.establish_connection adapter: 'postgresql',
64
+ database: 'pose_test',
65
+ min_messages: 'INFO'
92
66
 
93
- create_table 'posable_ones' do |t|
94
- t.string 'text'
95
- t.boolean 'private'
67
+ ActiveRecord::Schema.define(version: 1) do
68
+ unless table_exists? 'posable_ones'
69
+ create_table 'posable_ones' do |t|
70
+ t.string 'text'
71
+ t.boolean 'private'
72
+ end
96
73
  end
97
74
 
98
- create_table 'posable_twos' do |t|
99
- t.string 'text'
100
- t.boolean 'private'
75
+ unless table_exists? 'posable_twos'
76
+ create_table 'posable_twos' do |t|
77
+ t.string 'text'
78
+ t.boolean 'private'
79
+ end
101
80
  end
102
81
 
103
- create_table "pose_assignments" do |t|
104
- t.integer "pose_word_id", null: false
105
- t.integer "posable_id", null: false
106
- t.string "posable_type", limit: 20, null: false
82
+ unless table_exists? 'pose_assignments'
83
+ create_table "pose_assignments" do |t|
84
+ t.integer "pose_word_id", null: false
85
+ t.integer "posable_id", null: false
86
+ t.string "posable_type", limit: 20, null: false
87
+ end
107
88
  end
108
89
 
109
- create_table "pose_words" do |t|
110
- t.string "text", limit: 80, null: false
90
+ unless table_exists? 'pose_words'
91
+ create_table "pose_words" do |t|
92
+ t.string "text", limit: 80, null: false
93
+ end
111
94
  end
112
95
  end
113
96
  end
114
-
115
- def teardown_db
116
- ActiveRecord::Base.connection.tables.each do |table|
117
- ActiveRecord::Base.connection.drop_table(table)
118
- end
119
- end