hunt 0.1
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.
- data/.gitignore +3 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +20 -0
- data/README.rdoc +57 -0
- data/Rakefile +7 -0
- data/hunt.gemspec +24 -0
- data/lib/hunt.rb +36 -0
- data/lib/hunt/util.rb +57 -0
- data/lib/hunt/version.rb +3 -0
- data/spec/helper.rb +17 -0
- data/spec/hunt/util_spec.rb +62 -0
- data/spec/hunt_spec.rb +150 -0
- data/specs.watchr +45 -0
- metadata +127 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
hunt (0.1)
|
5
|
+
fast-stemmer (~> 1.0)
|
6
|
+
mongo_mapper (~> 0.8.6)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.0.3)
|
12
|
+
bson (1.1.5)
|
13
|
+
bson_ext (1.1.5)
|
14
|
+
diff-lcs (1.1.2)
|
15
|
+
fast-stemmer (1.0.0)
|
16
|
+
i18n (0.4.2)
|
17
|
+
jnunemaker-validatable (1.8.4)
|
18
|
+
activesupport (>= 2.3.4)
|
19
|
+
mongo (1.1.5)
|
20
|
+
bson (>= 1.1.5)
|
21
|
+
mongo_mapper (0.8.6)
|
22
|
+
activesupport (>= 2.3.4)
|
23
|
+
jnunemaker-validatable (~> 1.8.4)
|
24
|
+
plucky (~> 0.3.6)
|
25
|
+
plucky (0.3.6)
|
26
|
+
mongo (~> 1.1)
|
27
|
+
rspec (2.3.0)
|
28
|
+
rspec-core (~> 2.3.0)
|
29
|
+
rspec-expectations (~> 2.3.0)
|
30
|
+
rspec-mocks (~> 2.3.0)
|
31
|
+
rspec-core (2.3.1)
|
32
|
+
rspec-expectations (2.3.0)
|
33
|
+
diff-lcs (~> 1.1.2)
|
34
|
+
rspec-mocks (2.3.0)
|
35
|
+
|
36
|
+
PLATFORMS
|
37
|
+
ruby
|
38
|
+
|
39
|
+
DEPENDENCIES
|
40
|
+
bson_ext (= 1.1.5)
|
41
|
+
fast-stemmer (~> 1.0)
|
42
|
+
hunt!
|
43
|
+
i18n
|
44
|
+
mongo_mapper (~> 0.8.6)
|
45
|
+
rspec (~> 2.3)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 John Nunemaker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= Hunt
|
2
|
+
|
3
|
+
Insanely stupid and basic indexed search for MongoMapper. Probably pointless, but something I am playing around with on side projects.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
Declare the plugin.
|
8
|
+
|
9
|
+
class Note
|
10
|
+
include MongoMapper::Document
|
11
|
+
plugin Hunt
|
12
|
+
|
13
|
+
key :title, String
|
14
|
+
key :body, String
|
15
|
+
key :tags, Array
|
16
|
+
timestamps!
|
17
|
+
|
18
|
+
searches :title, :body, :tags
|
19
|
+
end
|
20
|
+
|
21
|
+
This creates a key named searches that is a Hash. Title, body, and tags get mashed together before save into a unique array of stemmed words and stored in searches.default.
|
22
|
+
|
23
|
+
You can index the terms individually or with any other combination of keys.
|
24
|
+
|
25
|
+
Note.ensure_index :'searches.default' # or ...
|
26
|
+
Note.ensure_index [[:user_id, Mongo::Ascending], [:'searches.default', Mongo::Ascending]]
|
27
|
+
|
28
|
+
You also get a search class method that returns a scope.
|
29
|
+
|
30
|
+
# Returns Plucky::Query (MM Scope), no query actually fired
|
31
|
+
Note.search('mongodb')
|
32
|
+
|
33
|
+
# Gets everything matching mongodb
|
34
|
+
Note.search('mongodb').all
|
35
|
+
|
36
|
+
# Gets first page of everything matching mongodb
|
37
|
+
Note.search('mongodb').paginate(:page => 1)
|
38
|
+
|
39
|
+
# Counts everything matching mongodb
|
40
|
+
Note.search('mongodb').count
|
41
|
+
|
42
|
+
# Matches everything with any of the terms
|
43
|
+
Note.search('mongodb is awesome')
|
44
|
+
|
45
|
+
== Note on Patches/Pull Requests
|
46
|
+
|
47
|
+
* Fork the project.
|
48
|
+
* Make your feature addition or bug fix.
|
49
|
+
* Add tests for it. This is important so I don't break it in a
|
50
|
+
future version unintentionally.
|
51
|
+
* Commit, do not mess with rakefile, version, or history.
|
52
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
53
|
+
* Send me a pull request. Bonus points for topic branches.
|
54
|
+
|
55
|
+
== Copyright
|
56
|
+
|
57
|
+
Copyright (c) 2010 John Nunemaker. See LICENSE for details.
|
data/Rakefile
ADDED
data/hunt.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "hunt/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "hunt"
|
7
|
+
s.version = Hunt::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["John Nunemaker"]
|
10
|
+
s.email = ["nunemaker@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/jnunemaker/hunt"
|
12
|
+
s.summary = %q{Really basic search for MongoMapper models.}
|
13
|
+
s.description = %q{Really basic search for MongoMapper models.}
|
14
|
+
|
15
|
+
s.add_dependency 'fast-stemmer', '~> 1.0'
|
16
|
+
s.add_dependency 'mongo_mapper', '~> 0.8.6'
|
17
|
+
|
18
|
+
s.add_development_dependency 'rspec', '~> 2.3'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/hunt.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'fast_stemmer'
|
2
|
+
require 'hunt/util'
|
3
|
+
|
4
|
+
module Hunt
|
5
|
+
def self.configure(model)
|
6
|
+
model.before_save(:index_search_terms)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def search_keys
|
11
|
+
@search_keys ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
def searches(*keys)
|
15
|
+
# Using a hash to support multiple indexes per document at some point
|
16
|
+
key(:searches, Hash)
|
17
|
+
@search_keys = keys
|
18
|
+
end
|
19
|
+
|
20
|
+
def search(value)
|
21
|
+
terms = Util.to_stemmed_words(value)
|
22
|
+
return [] if terms.blank?
|
23
|
+
where('searches.default' => terms)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module InstanceMethods
|
28
|
+
def concatted_search_values
|
29
|
+
self.class.search_keys.map { |key| send(key) }.flatten.join(' ')
|
30
|
+
end
|
31
|
+
|
32
|
+
def index_search_terms
|
33
|
+
self.searches['default'] = Util.to_stemmed_words(concatted_search_values)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/hunt/util.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Hunt
|
2
|
+
module Util
|
3
|
+
Separator = ' '
|
4
|
+
StripPunctuationRegex = /[^a-zA-Z0-9]/
|
5
|
+
PunctuationReplacement = ''
|
6
|
+
WordsToIgnore = [
|
7
|
+
"about", "above", "after", "again", "against", "all",
|
8
|
+
"and", "any", "are", "aren't", "because", "been",
|
9
|
+
"before", "being", "below", "between", "both", "but", "cannot",
|
10
|
+
"can't", "could", "couldn't", "did", "didn't", "does", "doesn't",
|
11
|
+
"doing", "don't", "down", "during", "each", "few", "for", "from",
|
12
|
+
"further", "had", "hadn't", "has", "hasn't", "have", "haven't", "having",
|
13
|
+
"he'd", "he'll", "her", "here", "here's", "hers", "herself", "he's",
|
14
|
+
"him", "himself", "his", "how", "how's", "i'd", "if", "i'll", "i'm",
|
15
|
+
"into", "isn't", "its", "it's", "itself", "i've", "let's",
|
16
|
+
"more", "most", "mustn't", "myself", "nor", "not",
|
17
|
+
"off", "once", "only", "other", "ought", "our", "ours", "ourselves",
|
18
|
+
"out", "over", "own", "same", "shan't", "she", "she'd", "she'll", "she's",
|
19
|
+
"should", "shouldn't", "some", "such", "than", "that", "that's", "the",
|
20
|
+
"their", "theirs", "them", "themselves", "then", "there", "there's", "these",
|
21
|
+
"they", "they'd", "they'll", "they're", "they've", "this", "those", "through",
|
22
|
+
"too", "under", "until", "up", "very", "was", "wasn't", "we'd",
|
23
|
+
"we'll", "were", "we're", "weren't", "we've", "what", "what's", "when",
|
24
|
+
"when's", "where", "where's", "which", "while", "who", "whom", "who's",
|
25
|
+
"why", "why's", "with", "won't", "would", "wouldn't", "you", "you'd",
|
26
|
+
"you'll", "your", "you're", "yours", "yourself", "yourselves", "you've",
|
27
|
+
"the", "how"
|
28
|
+
]
|
29
|
+
|
30
|
+
def strip_puncuation(value)
|
31
|
+
value.to_s.gsub(StripPunctuationRegex, PunctuationReplacement)
|
32
|
+
end
|
33
|
+
|
34
|
+
def stem(word)
|
35
|
+
Stemmer.stem_word(word)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_words(value)
|
39
|
+
value.
|
40
|
+
to_s.
|
41
|
+
squeeze(Separator).
|
42
|
+
split(Separator).
|
43
|
+
map { |word| word.downcase }.
|
44
|
+
reject { |word| word.size < 3 }.
|
45
|
+
reject { |word| WordsToIgnore.include?(word) }.
|
46
|
+
map { |word| strip_puncuation(word) }.
|
47
|
+
reject { |word| word.blank? }.
|
48
|
+
uniq
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_stemmed_words(value)
|
52
|
+
to_words(value).map { |word| stem(word) }
|
53
|
+
end
|
54
|
+
|
55
|
+
extend self
|
56
|
+
end
|
57
|
+
end
|
data/lib/hunt/version.rb
ADDED
data/spec/helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
Bundler.require(:default, :development)
|
7
|
+
|
8
|
+
require 'hunt'
|
9
|
+
|
10
|
+
MongoMapper.connection = Mongo::Connection.new
|
11
|
+
MongoMapper.database = 'hunt-test'
|
12
|
+
|
13
|
+
Rspec.configure do |c|
|
14
|
+
c.before(:each) do
|
15
|
+
MongoMapper.database.collections.each(&:remove)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Hunt::Util do
|
4
|
+
describe ".strip_puncuation" do
|
5
|
+
it "removes punctuation" do
|
6
|
+
Hunt::Util.strip_puncuation('woot!').should == 'woot'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".stem" do
|
11
|
+
it "stems word" do
|
12
|
+
Hunt::Util.stem('kissing').should == 'kiss'
|
13
|
+
Hunt::Util.stem('hello').should == 'hello'
|
14
|
+
Hunt::Util.stem('barfing').should == 'barf'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".to_words" do
|
19
|
+
it "does not fail with nil" do
|
20
|
+
Hunt::Util.to_words(nil).should == []
|
21
|
+
end
|
22
|
+
|
23
|
+
it "converts string to array of words" do
|
24
|
+
Hunt::Util.to_words('first sentence').should == %w(first sentence)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "squeezes multiple spaces" do
|
28
|
+
Hunt::Util.to_words('first sentence').should == %w(first sentence)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "removes punctuation" do
|
32
|
+
Hunt::Util.to_words('woot!').should == %w(woot)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "removes blanks from removed punctuation" do
|
36
|
+
Hunt::Util.to_words('first sentence & second').should == %w(first sentence second)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "lowercases each word" do
|
40
|
+
Hunt::Util.to_words('Sweet First Sentence').should == %w(sweet first sentence)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "removes any words under 3 characters" do
|
44
|
+
Hunt::Util.to_words('my first sentence').should == %w(first sentence)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "removes words that should be ignored" do
|
48
|
+
Hunt::Util.to_words('how was your day').should == %w(day)
|
49
|
+
Hunt::Util.to_words("didn't you see that").should == %w(see)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "removes duplicates" do
|
53
|
+
Hunt::Util.to_words('boom boom').should == %w(boom)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".to_stemmed_words" do
|
58
|
+
it "converts value to array of stemmed words" do
|
59
|
+
Hunt::Util.to_stemmed_words('I just Caught you kissing.').should == %w(just caught kiss)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/hunt_spec.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class Note
|
4
|
+
include MongoMapper::Document
|
5
|
+
|
6
|
+
plugin Hunt
|
7
|
+
|
8
|
+
key :title, String
|
9
|
+
key :body, String
|
10
|
+
key :tags, Array
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Hunt do
|
14
|
+
it "adds searches key to model to store search terms" do
|
15
|
+
Note.searches(:title)
|
16
|
+
Note.new.should respond_to(:searches)
|
17
|
+
Note.new.should respond_to(:searches=)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".search" do
|
21
|
+
before(:each) do
|
22
|
+
Note.searches(:title)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns empty array if nil" do
|
26
|
+
Note.search(nil).should == []
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns empty array if blank" do
|
30
|
+
Note.search('').should == []
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with one search term" do
|
34
|
+
before(:each) do
|
35
|
+
@note = Note.create(:title => 'MongoDB is awesome!')
|
36
|
+
@result = Note.search('mongodb')
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:note) { @note }
|
40
|
+
let(:result) { @result }
|
41
|
+
|
42
|
+
it "returns plucky query" do
|
43
|
+
result.should be_instance_of(Plucky::Query)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "scopes query to searches.default in stemmed terms" do
|
47
|
+
result['searches.default'].should == {'$in' => %w(mongodb)}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "does return matched documents" do
|
51
|
+
result.all.should include(note)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "does not query unmatched documents" do
|
55
|
+
not_found = Note.create(:title => 'Something different')
|
56
|
+
result.all.should_not include(not_found)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with multiple search terms" do
|
61
|
+
before(:each) do
|
62
|
+
@note = Note.create(:title => 'MongoDB is awesome!')
|
63
|
+
@result = Note.search('mongodb is awesome')
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:note) { @note }
|
67
|
+
let(:result) { @result }
|
68
|
+
|
69
|
+
it "returns plucky query" do
|
70
|
+
result.should be_instance_of(Plucky::Query)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "scopes query to searches.default in stemmed terms" do
|
74
|
+
result['searches.default'].should == {'$in' => Hunt::Util.to_stemmed_words(note.concatted_search_values)}
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns documents that match both terms" do
|
78
|
+
result.all.should include(note)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns documents that match any of the terms" do
|
82
|
+
awesome = Note.create(:title => 'Something awesome')
|
83
|
+
mongodb = Note.create(:title => 'Something MongoDB')
|
84
|
+
result.all.should include(awesome)
|
85
|
+
result.all.should include(mongodb)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "does not query unmatched documents" do
|
89
|
+
not_found = Note.create(:title => 'Something different')
|
90
|
+
result.all.should_not include(not_found)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "Search indexing" do
|
96
|
+
context "on one field" do
|
97
|
+
before(:each) do
|
98
|
+
Note.searches(:title)
|
99
|
+
@note = Note.create(:title => 'Woot for MongoDB!')
|
100
|
+
end
|
101
|
+
|
102
|
+
let(:note) { @note }
|
103
|
+
|
104
|
+
it "indexes terms on create" do
|
105
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "indexes terms on update" do
|
109
|
+
note.update_attributes(:title => 'Another woot')
|
110
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "on multiple fields" do
|
115
|
+
before(:each) do
|
116
|
+
Note.searches(:title, :body)
|
117
|
+
@note = Note.create(:title => 'Woot for MongoDB!', :body => 'This is my body.')
|
118
|
+
end
|
119
|
+
|
120
|
+
let(:note) { @note }
|
121
|
+
|
122
|
+
it "indexes merged terms on create" do
|
123
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "indexes merged terms on update" do
|
127
|
+
note.update_attributes(:title => 'Another woot', :body => 'An updated body.')
|
128
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "on multiple fields one of which is array key" do
|
133
|
+
before(:each) do
|
134
|
+
Note.searches(:title, :tags)
|
135
|
+
@note = Note.create(:title => 'Woot for MongoDB!', :tags => %w(mongo nosql))
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:note) { @note }
|
139
|
+
|
140
|
+
it "indexes merged terms on create" do
|
141
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "indexes merged terms on update" do
|
145
|
+
note.update_attributes(:title => 'Another woot', :tags => %w(mongo))
|
146
|
+
note.searches['default'].should == Hunt::Util.to_stemmed_words(note.concatted_search_values)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/specs.watchr
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
def growl(title, msg, img)
|
2
|
+
%x{growlnotify -m #{ msg.inspect} -t #{title.inspect} --image ~/.watchr/#{img}.png}
|
3
|
+
end
|
4
|
+
|
5
|
+
def form_growl_message(str)
|
6
|
+
msg = str.split("\n").last
|
7
|
+
if msg =~ /(\d)\sfailure/
|
8
|
+
img = $1.to_i > 0 ? 'fail' : 'pass'
|
9
|
+
end
|
10
|
+
growl 'Results', msg, img
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(cmd)
|
14
|
+
puts cmd
|
15
|
+
output = ""
|
16
|
+
IO.popen(cmd) do |com|
|
17
|
+
com.each_char do |c|
|
18
|
+
print c
|
19
|
+
output << c
|
20
|
+
$stdout.flush
|
21
|
+
end
|
22
|
+
end
|
23
|
+
form_growl_message output
|
24
|
+
end
|
25
|
+
|
26
|
+
def run_spec(path)
|
27
|
+
path.gsub!('lib/', 'spec/')
|
28
|
+
path.gsub!('_spec', '')
|
29
|
+
file_name = File.basename(path, '.rb')
|
30
|
+
path.gsub!(file_name, file_name + "_spec")
|
31
|
+
run %Q(bundle exec rspec #{path})
|
32
|
+
end
|
33
|
+
|
34
|
+
watch('spec/helper\.rb') { system('clear'); run('rake') }
|
35
|
+
watch('lib/.*\.rb') { |m| system('clear'); run_spec(m[0]) }
|
36
|
+
watch('spec/.*_spec\.rb') { |m| system('clear'); run_spec(m[0]) }
|
37
|
+
|
38
|
+
# Ctrl-\
|
39
|
+
Signal.trap('QUIT') do
|
40
|
+
puts " --- Running all tests ---\n\n"
|
41
|
+
run('rake')
|
42
|
+
end
|
43
|
+
|
44
|
+
# Ctrl-C
|
45
|
+
Signal.trap('INT') { abort("\n") }
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hunt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- John Nunemaker
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-19 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: fast-stemmer
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 15
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 0
|
32
|
+
version: "1.0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mongo_mapper
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 51
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 8
|
47
|
+
- 6
|
48
|
+
version: 0.8.6
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rspec
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 5
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 3
|
63
|
+
version: "2.3"
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
description: Really basic search for MongoMapper models.
|
67
|
+
email:
|
68
|
+
- nunemaker@gmail.com
|
69
|
+
executables: []
|
70
|
+
|
71
|
+
extensions: []
|
72
|
+
|
73
|
+
extra_rdoc_files: []
|
74
|
+
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- Gemfile.lock
|
79
|
+
- LICENSE
|
80
|
+
- README.rdoc
|
81
|
+
- Rakefile
|
82
|
+
- hunt.gemspec
|
83
|
+
- lib/hunt.rb
|
84
|
+
- lib/hunt/util.rb
|
85
|
+
- lib/hunt/version.rb
|
86
|
+
- spec/helper.rb
|
87
|
+
- spec/hunt/util_spec.rb
|
88
|
+
- spec/hunt_spec.rb
|
89
|
+
- specs.watchr
|
90
|
+
has_rdoc: true
|
91
|
+
homepage: http://github.com/jnunemaker/hunt
|
92
|
+
licenses: []
|
93
|
+
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.3.7
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Really basic search for MongoMapper models.
|
124
|
+
test_files:
|
125
|
+
- spec/helper.rb
|
126
|
+
- spec/hunt/util_spec.rb
|
127
|
+
- spec/hunt_spec.rb
|