wvanbergen-scoped_search 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +48 -32
- data/Rakefile +1 -3
- data/lib/scoped_search.rb +45 -95
- data/lib/scoped_search/adapters.rb +41 -0
- data/lib/scoped_search/definition.rb +122 -0
- data/lib/scoped_search/query_builder.rb +213 -0
- data/lib/scoped_search/query_language.rb +30 -0
- data/lib/scoped_search/query_language/ast.rb +141 -0
- data/lib/scoped_search/query_language/parser.rb +115 -0
- data/lib/scoped_search/query_language/tokenizer.rb +62 -0
- data/{test → spec}/database.yml +0 -0
- data/spec/integration/api_spec.rb +82 -0
- data/spec/integration/ordinal_querying_spec.rb +153 -0
- data/spec/integration/relation_querying_spec.rb +258 -0
- data/spec/integration/string_querying_spec.rb +187 -0
- data/spec/lib/database.rb +44 -0
- data/spec/lib/matchers.rb +40 -0
- data/spec/lib/mocks.rb +19 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/unit/ast_spec.rb +197 -0
- data/spec/unit/definition_spec.rb +24 -0
- data/spec/unit/parser_spec.rb +105 -0
- data/spec/unit/query_builder_spec.rb +5 -0
- data/spec/unit/tokenizer_spec.rb +97 -0
- data/tasks/database_tests.rake +5 -5
- data/tasks/github-gem.rake +8 -3
- metadata +39 -23
- data/lib/scoped_search/query_conditions_builder.rb +0 -209
- data/lib/scoped_search/query_language_parser.rb +0 -117
- data/lib/scoped_search/reg_tokens.rb +0 -51
- data/tasks/documentation.rake +0 -33
- data/test/integration/api_test.rb +0 -53
- data/test/lib/test_models.rb +0 -148
- data/test/lib/test_schema.rb +0 -68
- data/test/test_helper.rb +0 -44
- data/test/unit/query_conditions_builder_test.rb +0 -410
- data/test/unit/query_language_test.rb +0 -155
- data/test/unit/search_for_test.rb +0 -124
@@ -1,155 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
|
3
|
-
class ScopedSearch::Test::QueryLanguage < Test::Unit::TestCase
|
4
|
-
|
5
|
-
# change this function if you switch to another query language parser
|
6
|
-
def parse_query(query)
|
7
|
-
ScopedSearch::QueryLanguageParser.parse(query)
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_empty_search_query
|
11
|
-
parsed = parse_query('')
|
12
|
-
assert_equal 0, parsed.length
|
13
|
-
|
14
|
-
parsed = parse_query("\t \n")
|
15
|
-
assert_equal 0, parsed.length
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_single_keyword
|
19
|
-
parsed = parse_query('hallo')
|
20
|
-
assert_equal 1, parsed.length
|
21
|
-
assert_equal 'hallo', parsed.first.first
|
22
|
-
|
23
|
-
parsed = parse_query(' hallo ')
|
24
|
-
assert_equal 1, parsed.length
|
25
|
-
assert_equal 'hallo', parsed.first.first
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_multiple_keywords
|
29
|
-
parsed = parse_query(' hallo willem')
|
30
|
-
assert_equal 2, parsed.length
|
31
|
-
assert_equal 'willem', parsed.last.first
|
32
|
-
|
33
|
-
parsed = parse_query(" hallo willem van\tbergen 25")
|
34
|
-
assert_equal 5, parsed.length
|
35
|
-
assert_equal 'hallo', parsed[0].first
|
36
|
-
assert_equal 'willem', parsed[1].first
|
37
|
-
assert_equal 'van', parsed[2].first
|
38
|
-
assert_equal 'bergen', parsed[3].first
|
39
|
-
assert_equal '25', parsed[4].first
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_quoted_keywords
|
43
|
-
parsed = parse_query(' "hallo"')
|
44
|
-
assert_equal 1, parsed.length
|
45
|
-
assert_equal 'hallo', parsed.first.first
|
46
|
-
|
47
|
-
parsed = parse_query(' "hallo willem"')
|
48
|
-
assert_equal 1, parsed.length
|
49
|
-
assert_equal 'hallo willem', parsed.first.first
|
50
|
-
|
51
|
-
parsed = parse_query(' "hallo willem')
|
52
|
-
assert_equal 2, parsed.length
|
53
|
-
assert_equal 'hallo', parsed[0].first
|
54
|
-
assert_equal 'willem', parsed[1].first
|
55
|
-
|
56
|
-
parsed = parse_query(' "hallo wi"llem"')
|
57
|
-
assert_equal 2, parsed.length
|
58
|
-
assert_equal 'hallo wi', parsed[0].first
|
59
|
-
assert_equal 'llem', parsed[1].first
|
60
|
-
|
61
|
-
parsed = parse_query('"hays 25"')
|
62
|
-
assert_equal 1, parsed.length
|
63
|
-
assert_equal 'hays 25', parsed[0].first
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_quote_escaping
|
67
|
-
parsed = parse_query(' "hallo wi\\"llem"')
|
68
|
-
assert_equal 3, parsed.length
|
69
|
-
assert_equal 'hallo', parsed[0].first
|
70
|
-
assert_equal 'wi', parsed[1].first
|
71
|
-
assert_equal 'llem', parsed[2].first
|
72
|
-
|
73
|
-
parsed = parse_query('"\\"hallo willem\\""')
|
74
|
-
assert_equal 2, parsed.length
|
75
|
-
assert_equal 'hallo', parsed[0].first
|
76
|
-
assert_equal 'willem', parsed[1].first
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_negation
|
80
|
-
parsed = parse_query('-willem')
|
81
|
-
assert_equal 1, parsed.length
|
82
|
-
assert_equal 'willem', parsed[0].first
|
83
|
-
assert_equal :not, parsed[0].last
|
84
|
-
|
85
|
-
parsed = parse_query('hallo-world')
|
86
|
-
assert_equal 1, parsed.length
|
87
|
-
assert_equal 'hallo-world', parsed.first.first
|
88
|
-
|
89
|
-
parsed = parse_query('hallo -world')
|
90
|
-
assert_equal 2, parsed.length
|
91
|
-
assert_equal 'hallo', parsed.first.first
|
92
|
-
assert_equal 'world', parsed.last.first
|
93
|
-
assert_equal :not, parsed.last.last
|
94
|
-
|
95
|
-
parsed = parse_query('123 -"456 789"')
|
96
|
-
assert_equal 2, parsed.length
|
97
|
-
assert_equal '123', parsed[0].first
|
98
|
-
assert_equal :like, parsed[0].last
|
99
|
-
|
100
|
-
assert_equal '456 789', parsed[1].first
|
101
|
-
assert_equal :not, parsed[1].last
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_or
|
105
|
-
parsed = parse_query('Wes OR Hays')
|
106
|
-
assert_equal 1, parsed.length
|
107
|
-
assert_equal 'Wes OR Hays', parsed[0][0]
|
108
|
-
assert_equal :or, parsed[0][1]
|
109
|
-
|
110
|
-
parsed = parse_query('"Man made" OR Dogs')
|
111
|
-
assert_equal 1, parsed.length
|
112
|
-
assert_equal 'Man made OR Dogs', parsed[0][0]
|
113
|
-
assert_equal :or, parsed[0][1]
|
114
|
-
|
115
|
-
parsed = parse_query('Cows OR "Frog Toys"')
|
116
|
-
assert_equal 1, parsed.length
|
117
|
-
assert_equal 'Cows OR Frog Toys', parsed[0][0]
|
118
|
-
assert_equal :or, parsed[0][1]
|
119
|
-
|
120
|
-
parsed = parse_query('"Happy cow" OR "Sad Frog"')
|
121
|
-
assert_equal 1, parsed.length
|
122
|
-
assert_equal 'Happy cow OR Sad Frog', parsed[0][0]
|
123
|
-
assert_equal :or, parsed[0][1]
|
124
|
-
end
|
125
|
-
|
126
|
-
def test_long_string
|
127
|
-
str = 'Wes -Hays "Hello World" -"Goodnight Moon" Bob OR Wes "Happy cow" OR "Sad Frog" "Man made" OR Dogs Cows OR "Frog Toys"'
|
128
|
-
parsed = parse_query(str)
|
129
|
-
assert_equal 8, parsed.length
|
130
|
-
|
131
|
-
assert_equal 'Wes', parsed[0].first
|
132
|
-
assert_equal :like, parsed[0].last
|
133
|
-
|
134
|
-
assert_equal 'Hays', parsed[1].first
|
135
|
-
assert_equal :not, parsed[1].last
|
136
|
-
|
137
|
-
assert_equal 'Hello World', parsed[2].first
|
138
|
-
assert_equal :like, parsed[2].last
|
139
|
-
|
140
|
-
assert_equal 'Goodnight Moon', parsed[3].first
|
141
|
-
assert_equal :not, parsed[3].last
|
142
|
-
|
143
|
-
assert_equal 'Bob OR Wes', parsed[4].first
|
144
|
-
assert_equal :or, parsed[4].last
|
145
|
-
|
146
|
-
assert_equal 'Happy cow OR Sad Frog', parsed[5].first
|
147
|
-
assert_equal :or, parsed[5].last
|
148
|
-
|
149
|
-
assert_equal 'Man made OR Dogs', parsed[6].first
|
150
|
-
assert_equal :or, parsed[6].last
|
151
|
-
|
152
|
-
assert_equal 'Cows OR Frog Toys', parsed[7].first
|
153
|
-
assert_equal :or, parsed[7].last
|
154
|
-
end
|
155
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
|
3
|
-
class ScopedSearch::Test::SearchFor < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def self.const_missing(const)
|
6
|
-
ScopedSearch::Test::Models.const_get(const)
|
7
|
-
end
|
8
|
-
|
9
|
-
def setup
|
10
|
-
ScopedSearch::Test.establish_connection
|
11
|
-
ScopedSearch::Test::DatabaseSchema.up
|
12
|
-
ScopedSearch::Test.create_corpus!
|
13
|
-
end
|
14
|
-
|
15
|
-
def teardown
|
16
|
-
ScopedSearch::Test::DatabaseSchema.down
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_search
|
20
|
-
Foo.searchable_on :string_field, :text_field, :date_field, :some_int_field
|
21
|
-
|
22
|
-
assert_equal Foo.count, Foo.search_for('').count
|
23
|
-
assert_equal 0, Foo.search_for('456').count
|
24
|
-
assert_equal 2, Foo.search_for('hays').count
|
25
|
-
assert_equal 1, Foo.search_for('hay ob').count
|
26
|
-
assert_equal 15, Foo.search_for('o').count
|
27
|
-
assert_equal 2, Foo.search_for('-o').count
|
28
|
-
assert_equal 15, Foo.search_for('-Jim').count
|
29
|
-
assert_equal 1, Foo.search_for('Jim -Bush').count
|
30
|
-
assert_equal 1, Foo.search_for('"Hello World" -"Goodnight Moon"').count
|
31
|
-
assert_equal 2, Foo.search_for('Wes OR Bob').count
|
32
|
-
assert_equal 3, Foo.search_for('"Happy cow" OR "Sad Frog"').count
|
33
|
-
assert_equal 3, Foo.search_for('"Man made" OR Dogs').count
|
34
|
-
assert_equal 2, Foo.search_for('Cows OR "Frog Toys"').count
|
35
|
-
assert_equal 1, Foo.search_for('700').count
|
36
|
-
|
37
|
-
# ** DATES **
|
38
|
-
#
|
39
|
-
# The next two dates are invalid therefore it will be ignored.
|
40
|
-
# Since it is just a date being searched for it will also
|
41
|
-
# be searched for in text fields regardless of whether or
|
42
|
-
# not it is a valid date.
|
43
|
-
assert_equal 0, Foo.search_for('2/30/1980').count
|
44
|
-
assert_equal 0, Foo.search_for('99/99/9999').count
|
45
|
-
|
46
|
-
assert_equal 1, Foo.search_for('9/27/1980').count
|
47
|
-
assert_equal 1, Foo.search_for('hays 9/27/1980').count
|
48
|
-
assert_equal 0, Foo.search_for('hays 2/30/1980').count
|
49
|
-
|
50
|
-
assert_equal 1, Foo.search_for('< 12/01/1980').count
|
51
|
-
assert_equal 6, Foo.search_for('> 2006/1/1').count
|
52
|
-
|
53
|
-
assert_equal 5, Foo.search_for('< 12/26/2002').count
|
54
|
-
assert_equal 6, Foo.search_for('<= 12/26/2002').count
|
55
|
-
|
56
|
-
assert_equal 6, Foo.search_for('> 2/5/2005').count
|
57
|
-
assert_equal 7, Foo.search_for('>= 2/5/2005').count
|
58
|
-
|
59
|
-
assert_equal 3, Foo.search_for('1/1/2005 TO 1/1/2007').count
|
60
|
-
|
61
|
-
assert_equal 2, Foo.search_for('Happy 1/1/2005 TO 1/1/2007').count
|
62
|
-
|
63
|
-
# This should return one with a date of 7/15/2006 found in the text.
|
64
|
-
assert_equal 2, Foo.search_for('7/15/2006').count
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_search_belongs_to_association
|
68
|
-
User.searchable_on :first_name, :last_name, :group_name
|
69
|
-
|
70
|
-
assert_equal User.count, User.search_for('').count
|
71
|
-
assert_equal 1, User.search_for('Wes').count
|
72
|
-
assert_equal 2, User.search_for('System Administrator').count
|
73
|
-
assert_equal 2, User.search_for('Managers').count
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_search_has_many_association
|
77
|
-
User.searchable_on :first_name, :last_name, :notes_title, :notes_content
|
78
|
-
|
79
|
-
assert_equal User.count, User.search_for('').count
|
80
|
-
assert_equal 2, User.search_for('Router').count
|
81
|
-
assert_equal 1, User.search_for('milk').count
|
82
|
-
assert_equal 1, User.search_for('"Spec Tests"').count
|
83
|
-
assert_equal 0, User.search_for('Wes "Spec Tests"').count
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_search_has_many_through_association
|
87
|
-
User.searchable_on :first_name, :last_name, :age, :clients_first_name, :clients_last_name
|
88
|
-
|
89
|
-
assert_equal User.count, User.search_for('').count
|
90
|
-
assert_equal 2, User.search_for('Smith').count
|
91
|
-
assert_equal 1, User.search_for('Sam').count
|
92
|
-
assert_equal 1, User.search_for('Johnson').count
|
93
|
-
assert_equal 1, User.search_for('28').count
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_search_has_one_association
|
97
|
-
User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code
|
98
|
-
|
99
|
-
assert_equal User.count, User.search_for('').count
|
100
|
-
assert_equal 1, User.search_for('Fernley').count
|
101
|
-
assert_equal 4, User.search_for('NV').count
|
102
|
-
assert_equal 1, User.search_for('Haskell').count
|
103
|
-
assert_equal 2, User.search_for('89434').count
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_search_has_and_belongs_to_many_association
|
107
|
-
User.searchable_on :first_name, :last_name, :locations_name
|
108
|
-
|
109
|
-
assert_equal User.count, User.search_for('').count
|
110
|
-
assert_equal 2, User.search_for('Office').count
|
111
|
-
assert_equal 1, User.search_for('Store').count
|
112
|
-
assert_equal 1, User.search_for('John Office').count
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_search_with_very_long_query
|
116
|
-
User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code
|
117
|
-
really_long_string = ''
|
118
|
-
10000.times {really_long_string << 'really long string'}
|
119
|
-
assert_equal 0, User.search_for(really_long_string).count
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
|