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.
Files changed (38) hide show
  1. data/README.rdoc +48 -32
  2. data/Rakefile +1 -3
  3. data/lib/scoped_search.rb +45 -95
  4. data/lib/scoped_search/adapters.rb +41 -0
  5. data/lib/scoped_search/definition.rb +122 -0
  6. data/lib/scoped_search/query_builder.rb +213 -0
  7. data/lib/scoped_search/query_language.rb +30 -0
  8. data/lib/scoped_search/query_language/ast.rb +141 -0
  9. data/lib/scoped_search/query_language/parser.rb +115 -0
  10. data/lib/scoped_search/query_language/tokenizer.rb +62 -0
  11. data/{test → spec}/database.yml +0 -0
  12. data/spec/integration/api_spec.rb +82 -0
  13. data/spec/integration/ordinal_querying_spec.rb +153 -0
  14. data/spec/integration/relation_querying_spec.rb +258 -0
  15. data/spec/integration/string_querying_spec.rb +187 -0
  16. data/spec/lib/database.rb +44 -0
  17. data/spec/lib/matchers.rb +40 -0
  18. data/spec/lib/mocks.rb +19 -0
  19. data/spec/spec_helper.rb +21 -0
  20. data/spec/unit/ast_spec.rb +197 -0
  21. data/spec/unit/definition_spec.rb +24 -0
  22. data/spec/unit/parser_spec.rb +105 -0
  23. data/spec/unit/query_builder_spec.rb +5 -0
  24. data/spec/unit/tokenizer_spec.rb +97 -0
  25. data/tasks/database_tests.rake +5 -5
  26. data/tasks/github-gem.rake +8 -3
  27. metadata +39 -23
  28. data/lib/scoped_search/query_conditions_builder.rb +0 -209
  29. data/lib/scoped_search/query_language_parser.rb +0 -117
  30. data/lib/scoped_search/reg_tokens.rb +0 -51
  31. data/tasks/documentation.rake +0 -33
  32. data/test/integration/api_test.rb +0 -53
  33. data/test/lib/test_models.rb +0 -148
  34. data/test/lib/test_schema.rb +0 -68
  35. data/test/test_helper.rb +0 -44
  36. data/test/unit/query_conditions_builder_test.rb +0 -410
  37. data/test/unit/query_language_test.rb +0 -155
  38. 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
-