pose 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/spec/pose_spec.rb ADDED
@@ -0,0 +1,256 @@
1
+ require "spec_helper"
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
4
+
5
+ class PosableOne < ActiveRecord::Base
6
+ posify { [text] }
7
+ end
8
+
9
+ class PosableTwo < ActiveRecord::Base
10
+ posify { [text] }
11
+ end
12
+
13
+ def setup_db
14
+ ActiveRecord::Schema.define(:version => 1) do
15
+
16
+ create_table 'posable_ones' do |t|
17
+ t.string 'text'
18
+ end
19
+
20
+ create_table 'posable_twos' do |t|
21
+ t.string 'text'
22
+ end
23
+
24
+ create_table "pose_assignments" do |t|
25
+ t.integer "pose_word_id", :null => false
26
+ t.integer "posable_id", :null => false
27
+ t.string "posable_type", :limit => 20, :null => false
28
+ end
29
+
30
+ create_table "pose_words" do |t|
31
+ t.string "text", :limit => 80, :null => false
32
+ end
33
+ end
34
+ end
35
+
36
+ def teardown_db
37
+ ActiveRecord::Base.connection.tables.each do |table|
38
+ ActiveRecord::Base.connection.drop_table(table)
39
+ end
40
+ end
41
+
42
+
43
+ describe Pose do
44
+ subject { PosableOne.new }
45
+
46
+ before :all do
47
+ setup_db
48
+ Pose::CONFIGURATION[:search_in_tests] = true
49
+ end
50
+
51
+ after :all do
52
+ teardown_db
53
+ Pose::CONFIGURATION[:search_in_tests] = false
54
+ end
55
+
56
+ before :each do
57
+ PosableOne.delete_all
58
+ PosableTwo.delete_all
59
+ PoseAssignment.delete_all
60
+ PoseWord.delete_all
61
+ end
62
+
63
+ describe 'associations' do
64
+ it 'allows to access the associated words of a posable object directly' do
65
+ subject.should have(0).pose_words
66
+ subject.pose_words << PoseWord.new(:text => 'one')
67
+ subject.should have_pose_words(['one'])
68
+ end
69
+ end
70
+
71
+ describe 'update_pose_index' do
72
+
73
+ context "in the 'test' environment" do
74
+ after :each do
75
+ Pose::CONFIGURATION[:search_in_tests] = true
76
+ end
77
+
78
+ it "doesn't calls update_pose_words in tests if the test flag is not enabled" do
79
+ Pose::CONFIGURATION[:search_in_tests] = false
80
+ subject.should_not_receive :update_pose_words
81
+ subject.update_pose_index
82
+ end
83
+
84
+ it "calls update_pose_words in tests if the test flag is enabled" do
85
+ Pose::CONFIGURATION[:search_in_tests] = true
86
+ subject.should_receive :update_pose_words
87
+ subject.update_pose_index
88
+ end
89
+ end
90
+
91
+ context "in the 'production' environment' do" do
92
+ before :each do
93
+ @old_env = Rails.env
94
+ Rails.env = 'production'
95
+ end
96
+
97
+ after :each do
98
+ Rails.env = @old_env
99
+ end
100
+
101
+ it "calls update_pose_words" do
102
+ subject.should_receive :update_pose_words
103
+ subject.update_pose_index
104
+ end
105
+ end
106
+ end
107
+
108
+ describe 'update_pose_words' do
109
+
110
+ it 'saves the words for search' do
111
+ subject.text = 'foo bar'
112
+ subject.update_pose_words
113
+ subject.should have(2).pose_words
114
+ subject.should have_pose_words ['foo', 'bar']
115
+ end
116
+
117
+ it 'updates the search index when the text is changed' do
118
+ subject.text = 'foo'
119
+ subject.save!
120
+
121
+ subject.text = 'other text'
122
+ subject.update_pose_words
123
+
124
+ subject.should have_pose_words ['other', 'text']
125
+ end
126
+
127
+ it "doesn't create duplicate words" do
128
+ subject.text = 'foo foo'
129
+ subject.save!
130
+ subject.should have(1).pose_words
131
+ end
132
+ end
133
+
134
+ describe 'get_words_to_remove' do
135
+
136
+ it "returns an array of word objects that need to be removed" do
137
+ word1 = PoseWord.new :text => 'one'
138
+ word2 = PoseWord.new :text => 'two'
139
+ existing_words = [word1, word2]
140
+ new_words = ['one', 'three']
141
+
142
+ result = Pose.get_words_to_remove existing_words, new_words
143
+
144
+ result.should eql([word2])
145
+ end
146
+
147
+ it 'returns an empty array if there are no words to be removed' do
148
+ word1 = PoseWord.new :text => 'one'
149
+ word2 = PoseWord.new :text => 'two'
150
+ existing_words = [word1, word2]
151
+ new_words = ['one', 'two']
152
+
153
+ result = Pose.get_words_to_remove existing_words, new_words
154
+
155
+ result.should eql([])
156
+ end
157
+ end
158
+
159
+ describe 'get_words_to_add' do
160
+
161
+ it 'returns an array with strings that need to be added' do
162
+ word1 = PoseWord.new :text => 'one'
163
+ word2 = PoseWord.new :text => 'two'
164
+ existing_words = [word1, word2]
165
+ new_words = ['one', 'three']
166
+
167
+ result = Pose.get_words_to_add existing_words, new_words
168
+
169
+ result.should eql(['three'])
170
+ end
171
+
172
+ it 'returns an empty array if there is nothing to be added' do
173
+ word1 = PoseWord.new :text => 'one'
174
+ word2 = PoseWord.new :text => 'two'
175
+ existing_words = [word1, word2]
176
+ new_words = ['one', 'two']
177
+
178
+ result = Pose.get_words_to_add existing_words, new_words
179
+
180
+ result.should eql([])
181
+ end
182
+ end
183
+
184
+ describe 'search' do
185
+
186
+ it 'works' do
187
+ pos1 = PosableOne.create :text => 'one'
188
+
189
+ result = Pose.search 'one', PosableOne
190
+
191
+ result.should have(1).items
192
+ result[PosableOne].should have(1).items
193
+ result[PosableOne][0].should == pos1
194
+ end
195
+
196
+ it 'returns an empty array if nothing matches' do
197
+ pos1 = PosableOne.create :text => 'one'
198
+
199
+ result = Pose.search 'two', PosableOne
200
+
201
+ result.should == { PosableOne => [] }
202
+ end
203
+
204
+ it 'returns all different classes by default' do
205
+ pos1 = PosableOne.create :text => 'foo'
206
+ pos2 = PosableTwo.create :text => 'foo'
207
+
208
+ result = Pose.search 'foo', [PosableOne, PosableTwo]
209
+
210
+ result.should have(2).items
211
+ result[PosableOne].should == [pos1]
212
+ result[PosableTwo].should == [pos2]
213
+ end
214
+
215
+ it 'allows to provide different classes to return' do
216
+ pos1 = PosableOne.create :text => 'foo'
217
+ pos2 = PosableTwo.create :text => 'foo'
218
+
219
+ result = Pose.search 'foo', [PosableOne, PosableTwo]
220
+
221
+ result.should have(2).items
222
+ result[PosableOne].should == [pos1]
223
+ result[PosableTwo].should == [pos2]
224
+ end
225
+
226
+ it 'returns only instances of the given classes' do
227
+ pos1 = PosableOne.create :text => 'one'
228
+ pos2 = PosableTwo.create :text => 'one'
229
+
230
+ result = Pose.search 'one', PosableOne
231
+
232
+ result.should have(1).items
233
+ result[PosableOne].should == [pos1]
234
+ end
235
+
236
+ it 'returns only objects that match all given query words' do
237
+ pos1 = PosableOne.create :text => 'one two'
238
+ pos2 = PosableOne.create :text => 'one three'
239
+ pos3 = PosableOne.create :text => 'two three'
240
+
241
+ result = Pose.search 'two one', PosableOne
242
+
243
+ result.should have(1).items
244
+ result[PosableOne].should == [pos1]
245
+ end
246
+
247
+ it 'returns nothing if searching for a non-existing word' do
248
+ pos1 = PosableOne.create :text => 'one two'
249
+
250
+ result = Pose.search 'one zonk', PosableOne
251
+
252
+ result.should have(1).items
253
+ result[PosableOne].should == []
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,60 @@
1
+ #require "rails/test_help"
2
+ #require 'rspec/rails'
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'hashie'
6
+ require 'active_record'
7
+ require 'active_support/core_ext/module/aliasing'
8
+ require "pose"
9
+ require 'pose_word.rb'
10
+ require 'pose_assignment.rb'
11
+ require "pose/posifier.rb"
12
+ require 'active_support/core_ext/string'
13
+ require 'meta_where'
14
+
15
+ # Configure Rails Environment
16
+ ENV["RAILS_ENV"] = "test"
17
+ Rails = Hashie::Mash.new({:env => 'test'})
18
+
19
+
20
+ #require 'your_gem_name' # and any other gems you need
21
+
22
+
23
+ # Load support files
24
+ #Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
25
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
26
+ #Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
27
+
28
+
29
+ RSpec.configure do |config|
30
+ # == Mock Framework
31
+ #
32
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
33
+ #
34
+ # config.mock_with :mocha
35
+ # config.mock_with :flexmock
36
+ # config.mock_with :rr
37
+ config.mock_with :rspec
38
+
39
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
40
+ # examples within a transaction, remove the following line or assign false
41
+ # instead of true.
42
+ # config.use_transactional_fixtures = true
43
+ end
44
+
45
+ # Verifies that a taggable object has the given tags.
46
+ RSpec::Matchers.define :have_pose_words do |expected|
47
+ match do |actual|
48
+ actual.should have(expected.size).pose_words
49
+ texts = actual.pose_words.map &:text
50
+ expected.each do |expected_word|
51
+ # Note (KG): Can't use text.should include(expected_word) here
52
+ # because Ruby thinks I want to include a Module for some reason.
53
+ texts.include?(expected_word).should be_true
54
+ end
55
+ end
56
+ failure_message_for_should do |actual|
57
+ texts = actual.pose_words.map &:text
58
+ "expected that subject would have pose words [#{expected.join ', '}], but it has [#{texts.join ', '}]"
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pose
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kevin Goslar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: &70121935615180 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70121935615180
25
+ - !ruby/object:Gem::Dependency
26
+ name: activerecord
27
+ requirement: &70121935614620 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - =
31
+ - !ruby/object:Gem::Version
32
+ version: 3.1.3
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70121935614620
36
+ - !ruby/object:Gem::Dependency
37
+ name: rails
38
+ requirement: &70121935614060 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 3.1.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70121935614060
47
+ - !ruby/object:Gem::Dependency
48
+ name: meta_where
49
+ requirement: &70121935613620 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70121935613620
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70121935613160 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70121935613160
69
+ - !ruby/object:Gem::Dependency
70
+ name: hashie
71
+ requirement: &70121935612580 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70121935612580
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: &70121935612140 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70121935612140
91
+ - !ruby/object:Gem::Dependency
92
+ name: sqlite3
93
+ requirement: &70121935611680 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70121935611680
102
+ description: Pose ('Polymorphic Search') allows fulltext search for ActiveRecord objects.
103
+ email:
104
+ - kevin.goslar@gmail.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - doc/_index.html
110
+ - doc/class_list.html
111
+ - doc/css/common.css
112
+ - doc/css/full_list.css
113
+ - doc/css/style.css
114
+ - doc/file_list.html
115
+ - doc/frames.html
116
+ - doc/index.html
117
+ - doc/js/app.js
118
+ - doc/js/full_list.js
119
+ - doc/js/jquery.js
120
+ - doc/method_list.html
121
+ - doc/Pose/InstanceMethods.html
122
+ - doc/Pose.html
123
+ - doc/PoseAssignment.html
124
+ - doc/PoseGenerator.html
125
+ - doc/PoseMigrations.html
126
+ - doc/PoseWord.html
127
+ - doc/top-level-namespace.html
128
+ - lib/generators/pose_generator.rb
129
+ - lib/generators/templates/migration.rb
130
+ - lib/pose/posifier.rb
131
+ - lib/pose/version.rb
132
+ - lib/pose.rb
133
+ - lib/pose_assignment.rb
134
+ - lib/pose_word.rb
135
+ - lib/tasks/pose_tasks.rake
136
+ - MIT-LICENSE
137
+ - Rakefile
138
+ - README.markdown
139
+ - spec/pose_spec.rb
140
+ - spec/spec_helper.rb
141
+ homepage: http://github.com/kevgo/pose
142
+ licenses: []
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 1.8.12
162
+ signing_key:
163
+ specification_version: 3
164
+ summary: A polymorphic, storage-system independent search engine for Ruby on Rails.
165
+ test_files:
166
+ - spec/pose_spec.rb
167
+ - spec/spec_helper.rb