drtom-textacular 4.0.0.alpha.20160302

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +199 -0
  3. data/Gemfile +3 -0
  4. data/README.md +196 -0
  5. data/Rakefile +61 -0
  6. data/lib/textacular.rb +160 -0
  7. data/lib/textacular/full_text_indexer.rb +66 -0
  8. data/lib/textacular/migration_generator.rb +31 -0
  9. data/lib/textacular/postgres_module_installer.rb +57 -0
  10. data/lib/textacular/rails.rb +14 -0
  11. data/lib/textacular/searchable.rb +20 -0
  12. data/lib/textacular/tasks.rb +23 -0
  13. data/lib/textacular/trigram_installer.rb +18 -0
  14. data/lib/textacular/version.rb +7 -0
  15. data/spec/config.travis.yml +8 -0
  16. data/spec/config.yml.example +5 -0
  17. data/spec/spec_helper.rb +104 -0
  18. data/spec/support/ar_stand_in.rb +4 -0
  19. data/spec/support/character.rb +7 -0
  20. data/spec/support/game.rb +5 -0
  21. data/spec/support/game_extended_with_textacular.rb +5 -0
  22. data/spec/support/game_extended_with_textacular_and_custom_language.rb +7 -0
  23. data/spec/support/game_fail.rb +3 -0
  24. data/spec/support/game_fail_extended_with_textacular.rb +5 -0
  25. data/spec/support/not_there.rb +3 -0
  26. data/spec/support/textacular_web_comic.rb +7 -0
  27. data/spec/support/web_comic.rb +7 -0
  28. data/spec/support/web_comic_with_searchable.rb +6 -0
  29. data/spec/support/web_comic_with_searchable_name.rb +6 -0
  30. data/spec/support/web_comic_with_searchable_name_and_author.rb +6 -0
  31. data/spec/textacular/full_text_indexer_spec.rb +69 -0
  32. data/spec/textacular/migration_generator_spec.rb +67 -0
  33. data/spec/textacular/searchable_spec.rb +194 -0
  34. data/spec/textacular/trigram_installer_spec.rb +24 -0
  35. data/spec/textacular_spec.rb +287 -0
  36. metadata +210 -0
@@ -0,0 +1,287 @@
1
+ # coding: utf-8
2
+ # Above for Ruby 1.9 tests
3
+
4
+ require 'support/ar_stand_in'
5
+ require 'support/not_there'
6
+ require 'support/textacular_web_comic'
7
+ require 'support/game_extended_with_textacular'
8
+ require 'support/game_extended_with_textacular_and_custom_language'
9
+ require 'support/game_fail_extended_with_textacular'
10
+
11
+ RSpec.describe Textacular do
12
+ context "after extending ActiveRecord::Base" do
13
+ it "doesn't break #respond_to?" do
14
+ expect{ ARStandIn.respond_to?(:abstract_class?) }.to_not raise_error
15
+ end
16
+
17
+ it "doesn't break #respond_to? for table-less classes" do
18
+ expect(NotThere.table_exists?).to be_falsey
19
+ expect { NotThere.respond_to? :system }.to_not raise_error
20
+ end
21
+
22
+ it "doesn't break #method_missing" do
23
+ expect { ARStandIn.random }.to raise_error(NoMethodError)
24
+
25
+ begin
26
+ ARStandIn.random
27
+ rescue NoMethodError => error
28
+ expect(error.message).to match(/undefined method `random'/)
29
+ end
30
+ end
31
+
32
+ it "doesn't break #method_missing for table-less classes" do
33
+ expect(NotThere.table_exists?).to be_falsey
34
+
35
+ expect { NotThere.random }.to raise_error(NoMethodError)
36
+
37
+ begin
38
+ NotThere.random
39
+ rescue NoMethodError => error
40
+ expect(error.message).to match(/undefined method `random'/)
41
+ end
42
+ end
43
+
44
+ context "when finding models based on searching a related model" do
45
+ let(:webcomics_with_tall_characters) do
46
+ [johnny_wander]
47
+ end
48
+
49
+ let(:webcomics_with_angry_characters) do
50
+ [johnny_wander, penny_arcade, questionable_content]
51
+ end
52
+
53
+ let(:webcomics_with_crude_characters) do
54
+ [penny_arcade, questionable_content]
55
+ end
56
+
57
+ let!(:johnny_wander) do
58
+ TextacularWebComic.create(:name => "Johnny Wander", :author => "Ananth & Yuko").tap do |comic|
59
+ comic.characters.create :name => 'Ananth', :description => 'Stubble! What is under that hat?!?'
60
+ comic.characters.create :name => 'Yuko', :description => 'So... small. Carl Sagan haircut.'
61
+ comic.characters.create :name => 'John', :description => 'Tall. Anger issues?'
62
+ comic.characters.create :name => 'Cricket', :description => 'Chirrup!'
63
+ end
64
+ end
65
+
66
+ let!(:questionable_content) do
67
+ TextacularWebComic.create(:name => "Questionable Content", :author => "Jeph Jaques").tap do |comic|
68
+ comic.characters.create :name => 'Martin', :description => 'the insecure protagonist'
69
+ comic.characters.create :name => 'Faye', :description => 'a sarcastic barrista with anger management issues'
70
+ comic.characters.create :name => 'Pintsize', :description => 'a crude AnthroPC'
71
+ end
72
+ end
73
+
74
+ let!(:penny_arcade) do
75
+ TextacularWebComic.create(:name => "Penny Arcade", :author => "Tycho & Gabe").tap do |comic|
76
+ comic.characters.create :name => 'Gabe', :description => 'the simple one'
77
+ comic.characters.create :name => 'Tycho', :description => 'the wordy one'
78
+ comic.characters.create :name => 'Div', :description => 'a crude divx player with anger management issues'
79
+ end
80
+ end
81
+
82
+ it "looks in the related model with nested searching syntax" do
83
+ expect(
84
+ TextacularWebComic.joins(:characters).advanced_search(
85
+ :characters => {:description => 'tall'}
86
+ )
87
+ ).to eq(webcomics_with_tall_characters)
88
+
89
+ expect(
90
+ TextacularWebComic.joins(:characters).advanced_search(
91
+ :characters => {:description => 'anger'}
92
+ ).sort
93
+ ).to eq(webcomics_with_angry_characters.sort)
94
+
95
+ expect(
96
+ TextacularWebComic.joins(:characters).advanced_search(
97
+ :characters => {:description => 'crude'}
98
+ ).sort
99
+ ).to eq(webcomics_with_crude_characters.sort)
100
+ end
101
+ end
102
+ end
103
+
104
+ context "after extending an ActiveRecord::Base subclass" do
105
+ context "when the DB connection is unavailable" do
106
+ before do
107
+ GameFailExtendedWithTextacular.establish_connection({:adapter => :postgresql, :database =>'unavailable', :username=>'bad', :pool=>5, :timeout=>5000}) rescue nil
108
+ end
109
+
110
+ it "doesn't break respond_to?" do
111
+ expect { GameFailExtendedWithTextacular.respond_to?(:advanced_search) }.to_not raise_error
112
+ end
113
+ end
114
+
115
+ context "when the DB connection is available" do
116
+ let!(:zelda) do
117
+ GameExtendedWithTextacular.create(
118
+ :system => "NES",
119
+ :title => "Legend of Zelda",
120
+ :description => "A Link to the Past."
121
+ )
122
+ end
123
+
124
+ let!(:mario) do
125
+ GameExtendedWithTextacular.create(
126
+ :system => "NES",
127
+ :title => "Super Mario Bros.",
128
+ :description => "The original platformer."
129
+ )
130
+ end
131
+
132
+ let!(:sonic) do
133
+ GameExtendedWithTextacular.create(
134
+ :system => "Genesis",
135
+ :title => "Sonic the Hedgehog",
136
+ :description => "Spiky."
137
+ )
138
+ end
139
+
140
+ let!(:donkey_kong) do
141
+ GameExtendedWithTextacular.create(
142
+ :system => "SNES",
143
+ :title => "Diddy's Kong Quest",
144
+ :description => "Donkey Kong Country 2"
145
+ )
146
+ end
147
+
148
+ let!(:mega_man) do
149
+ GameExtendedWithTextacular.create(
150
+ :system => nil,
151
+ :title => "Mega Man",
152
+ :description => "Beware Dr. Brain"
153
+ )
154
+ end
155
+
156
+ let!(:sf_nes) do
157
+ GameExtendedWithTextacular.create(
158
+ :system => "SNES",
159
+ :title => "Street Fighter 2",
160
+ :description => "Yoga Flame!"
161
+ )
162
+ end
163
+
164
+ let!(:sf_genesis) do
165
+ GameExtendedWithTextacular.create(
166
+ :system => "Genesis",
167
+ :title => "Street Fighter 2",
168
+ :description => "Yoga Flame!"
169
+ )
170
+ end
171
+
172
+ let!(:takun) do
173
+ GameExtendedWithTextacular.create(
174
+ :system => "Saturn",
175
+ :title => "Magical Tarurūto-kun",
176
+ :description => "カッコイイ!"
177
+ )
178
+ end
179
+
180
+ it "defines a #search method" do
181
+ expect(GameExtendedWithTextacular).to respond_to(:search)
182
+ end
183
+
184
+ describe "#advanced_search" do
185
+ context "with a String argument" do
186
+ it "searches across all :string columns (if not indexes have been specified)" do
187
+ expect(
188
+ GameExtendedWithTextacular.advanced_search("Mario")
189
+ ).to eq([mario])
190
+
191
+ expect(
192
+ GameExtendedWithTextacular.advanced_search("NES").to_set
193
+ ).to eq(Set.new([mario, zelda]))
194
+ end
195
+
196
+ it "works if a query has an apostrophe" do
197
+ expect(GameExtendedWithTextacular.advanced_search("Diddy's")).to eq([donkey_kong])
198
+ end
199
+
200
+ it "works if the query contains whitespace" do
201
+ expect(GameExtendedWithTextacular.advanced_search("Mega Man")).to eq([mega_man])
202
+ end
203
+
204
+ it "works if the query contains an accent" do
205
+ expect(GameExtendedWithTextacular.advanced_search("Tarurūto-kun")).to eq([takun])
206
+ end
207
+
208
+ it "searches across records with NULL values" do
209
+ expect(GameExtendedWithTextacular.advanced_search("Mega")).to eq([mega_man])
210
+ end
211
+
212
+ it "scopes consecutively" do
213
+ expect(
214
+ GameExtendedWithTextacular.advanced_search("Genesis").advanced_search("Street Fighter")
215
+ ).to eq([sf_genesis])
216
+ end
217
+ end
218
+
219
+ context "with a Hash argument" do
220
+ it "searches across the given columns" do
221
+ expect(
222
+ GameExtendedWithTextacular.advanced_search(:title => 'NES')
223
+ ).to be_empty
224
+ expect(
225
+ GameExtendedWithTextacular.advanced_search(:system => "Mario")
226
+ ).to be_empty
227
+ expect(
228
+ GameExtendedWithTextacular.advanced_search(:system => "NES", :title => "Sonic")
229
+ ).to be_empty
230
+
231
+ expect(
232
+ GameExtendedWithTextacular.advanced_search(:title => "Mario")
233
+ ).to eq([mario])
234
+
235
+ expect(
236
+ GameExtendedWithTextacular.advanced_search(:system => "NES").size
237
+ ).to eq(2)
238
+
239
+ expect(
240
+ GameExtendedWithTextacular.advanced_search(:system => "NES", :title => "Zelda")
241
+ ).to eq([zelda])
242
+ expect(
243
+ GameExtendedWithTextacular.advanced_search(:title => "Mega")
244
+ ).to eq([mega_man])
245
+ end
246
+
247
+ it "scopes consecutively" do
248
+ expect(
249
+ GameExtendedWithTextacular
250
+ .advanced_search(:system => "Genesis")
251
+ .advanced_search(:title => "Street Fighter")
252
+ ).to eq([sf_genesis])
253
+ end
254
+
255
+ it "casts non-string columns as text" do
256
+ expect(
257
+ GameExtendedWithTextacular.advanced_search(:id => mario.id)
258
+ ).to eq([mario])
259
+ end
260
+ end
261
+
262
+ context "after selecting columns to return" do
263
+ it "doesn't fetch extra columns" do
264
+ expect {
265
+ GameExtendedWithTextacular.select(:title).advanced_search("Mario").first.system
266
+ }.to raise_error(ActiveModel::MissingAttributeError)
267
+ end
268
+ end
269
+
270
+ context "after setting a custom language" do
271
+ let!(:harry_potter_7) do
272
+ GameExtendedWithTextacularAndCustomLanguage.create(
273
+ :system => "PS3",
274
+ :title => "Harry Potter & the Deathly Hallows"
275
+ )
276
+ end
277
+
278
+ it "finds results" do
279
+ expect(
280
+ GameExtendedWithTextacularAndCustomLanguage.advanced_search(title: "harry")
281
+ ).to eq([harry_potter_7])
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end
287
+ end
metadata ADDED
@@ -0,0 +1,210 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: drtom-textacular
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.0.0.alpha.20160302
5
+ platform: ruby
6
+ authors:
7
+ - Ben Hamill
8
+ - ecin
9
+ - Aaron Patterson
10
+ - Greg Molnar
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2016-03-02 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: pg
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '0.14'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.14'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: database_cleaner
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: pry
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: pry-doc
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: activerecord
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '3.0'
107
+ - - "<="
108
+ - !ruby/object:Gem::Version
109
+ version: '5.0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '3.0'
117
+ - - "<="
118
+ - !ruby/object:Gem::Version
119
+ version: '5.0'
120
+ description: |-
121
+ Textacular exposes full text search capabilities from PostgreSQL, extending
122
+ ActiveRecord with scopes making search easy and fun!
123
+ email:
124
+ - git-commits@benhamill.com
125
+ - ecin@copypastel.com
126
+ executables: []
127
+ extensions: []
128
+ extra_rdoc_files: []
129
+ files:
130
+ - CHANGELOG.md
131
+ - Gemfile
132
+ - README.md
133
+ - Rakefile
134
+ - lib/textacular.rb
135
+ - lib/textacular/full_text_indexer.rb
136
+ - lib/textacular/migration_generator.rb
137
+ - lib/textacular/postgres_module_installer.rb
138
+ - lib/textacular/rails.rb
139
+ - lib/textacular/searchable.rb
140
+ - lib/textacular/tasks.rb
141
+ - lib/textacular/trigram_installer.rb
142
+ - lib/textacular/version.rb
143
+ - spec/config.travis.yml
144
+ - spec/config.yml.example
145
+ - spec/spec_helper.rb
146
+ - spec/support/ar_stand_in.rb
147
+ - spec/support/character.rb
148
+ - spec/support/game.rb
149
+ - spec/support/game_extended_with_textacular.rb
150
+ - spec/support/game_extended_with_textacular_and_custom_language.rb
151
+ - spec/support/game_fail.rb
152
+ - spec/support/game_fail_extended_with_textacular.rb
153
+ - spec/support/not_there.rb
154
+ - spec/support/textacular_web_comic.rb
155
+ - spec/support/web_comic.rb
156
+ - spec/support/web_comic_with_searchable.rb
157
+ - spec/support/web_comic_with_searchable_name.rb
158
+ - spec/support/web_comic_with_searchable_name_and_author.rb
159
+ - spec/textacular/full_text_indexer_spec.rb
160
+ - spec/textacular/migration_generator_spec.rb
161
+ - spec/textacular/searchable_spec.rb
162
+ - spec/textacular/trigram_installer_spec.rb
163
+ - spec/textacular_spec.rb
164
+ homepage: http://textacular.github.com/textacular
165
+ licenses:
166
+ - MIT
167
+ metadata: {}
168
+ post_install_message:
169
+ rdoc_options: []
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">"
180
+ - !ruby/object:Gem::Version
181
+ version: 1.3.1
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 2.4.5.1
185
+ signing_key:
186
+ specification_version: 4
187
+ summary: Textacular exposes full text search capabilities from PostgreSQL
188
+ test_files:
189
+ - spec/config.yml.example
190
+ - spec/config.travis.yml
191
+ - spec/spec_helper.rb
192
+ - spec/support/ar_stand_in.rb
193
+ - spec/support/character.rb
194
+ - spec/support/game.rb
195
+ - spec/support/game_extended_with_textacular.rb
196
+ - spec/support/game_extended_with_textacular_and_custom_language.rb
197
+ - spec/support/game_fail.rb
198
+ - spec/support/game_fail_extended_with_textacular.rb
199
+ - spec/support/not_there.rb
200
+ - spec/support/textacular_web_comic.rb
201
+ - spec/support/web_comic.rb
202
+ - spec/support/web_comic_with_searchable.rb
203
+ - spec/support/web_comic_with_searchable_name.rb
204
+ - spec/support/web_comic_with_searchable_name_and_author.rb
205
+ - spec/textacular_spec.rb
206
+ - spec/textacular/full_text_indexer_spec.rb
207
+ - spec/textacular/migration_generator_spec.rb
208
+ - spec/textacular/searchable_spec.rb
209
+ - spec/textacular/trigram_installer_spec.rb
210
+ has_rdoc: