query_string_search 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +26 -0
- data/lib/query_string_search.rb +6 -1
- data/lib/query_string_search/abstract_comparison.rb +38 -0
- data/lib/query_string_search/abstract_matcher.rb +15 -7
- data/lib/query_string_search/comparison_factory.rb +16 -0
- data/lib/query_string_search/comparisons/inequality.rb +21 -0
- data/lib/query_string_search/comparisons/set.rb +13 -0
- data/lib/query_string_search/matcher_factory.rb +8 -4
- data/lib/query_string_search/matchers/match_all.rb +2 -2
- data/lib/query_string_search/matchers/match_attribute.rb +4 -4
- data/lib/query_string_search/matchers/match_attribute_value.rb +6 -6
- data/lib/query_string_search/matchers/match_multiple_attribute_values.rb +10 -6
- data/lib/query_string_search/matchers/match_no_attribute.rb +4 -4
- data/lib/query_string_search/search_option.rb +35 -0
- data/lib/query_string_search/search_options.rb +4 -23
- data/lib/query_string_search/search_parameters.rb +5 -5
- data/lib/query_string_search/version.rb +1 -1
- data/spec/features/find_records_by_searching_a_attribute_that_returns_a_collection_spec.rb +23 -0
- data/spec/features/find_records_with_inequality_matchers_spec.rb +48 -0
- data/spec/fixtures/movie.rb +19 -15
- data/spec/lib/query_string_search/abstract_matcher_spec.rb +5 -2
- data/spec/lib/query_string_search/matcher_factory_spec.rb +11 -6
- data/spec/lib/query_string_search/matchers/match_all_spec.rb +22 -7
- data/spec/lib/query_string_search/matchers/match_attribute_spec.rb +25 -16
- data/spec/lib/query_string_search/matchers/match_attribute_value_spec.rb +38 -14
- data/spec/lib/query_string_search/matchers/match_multiple_attribute_values_spec.rb +22 -8
- data/spec/lib/query_string_search/matchers/match_no_attribute_spec.rb +25 -16
- data/spec/lib/query_string_search/search_option_spec.rb +34 -0
- data/spec/lib/query_string_search/search_options_spec.rb +19 -38
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d98152d90936269401df2e71217c03c41c5f249a
|
4
|
+
data.tar.gz: b9d1b39ecfb46a0fbc15816e849575c30970e571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 731af57376be5e8859edc378c5d2c3b6c41196ae88c4bda918ca0f973713fb5bfcc1a6f3d0844977deca202b278c74219341a48545bce9fc08250e9195e29bbf
|
7
|
+
data.tar.gz: 4c1a8a92387aeb3390f4a46a0b40746b2dcc031b9586bbe0138dbce930e6360cb62d906f17b013006549580216bdf05e7d38b1f8267f0c37cd7d79c10ad48134
|
data/.travis.yml
CHANGED
@@ -6,4 +6,4 @@ rvm:
|
|
6
6
|
addons:
|
7
7
|
code_climate:
|
8
8
|
repo_token:
|
9
|
-
secure:
|
9
|
+
secure: xcf282dQMF1ZUZ9V9a/oY6zVo+nacSJqsxWJ7W8bOA4ii+Xq44EKLp1x88XSnWsD+yD3bdw4mHtPoQDCa+ouJLul5p35TwVZWGVxNdnWUdr3CjCS8lw4DYyR8BUHtH10JvvQN3AZpQ5IeHFqAujVMumfAPRkeuOLMs8iyfezrpI=
|
data/README.md
CHANGED
@@ -34,6 +34,32 @@ Returns every movie with a year of 1994
|
|
34
34
|
|
35
35
|
Returns all movies with a year of 1994 or 1995
|
36
36
|
|
37
|
+
### Return all data with values greater than or less than an attribute
|
38
|
+
|
39
|
+
`movies?q=star_rating>1`
|
40
|
+
Returns all movies with a star rating greater than one
|
41
|
+
|
42
|
+
`movies?q=star_rating<3`
|
43
|
+
Returns all movies with a star rating less than three
|
44
|
+
|
45
|
+
`movies?q=star_rating>=2`
|
46
|
+
Returns all movies with a star rating greater than or equal to 2
|
47
|
+
|
48
|
+
`movies?q=star_rating<=4`
|
49
|
+
Returns all movies with a star rating less than or equal to 4
|
50
|
+
|
51
|
+
### Search an attribute that returns a collection
|
52
|
+
|
53
|
+
If your `movie` has a `home_formats` method that retuns an array like `["DVD", "BD"]` you can filter that too.
|
54
|
+
|
55
|
+
`movies?q=home_formats=DVD`
|
56
|
+
Returns all movies whose `home_formats` includes "DVD"
|
57
|
+
|
58
|
+
or
|
59
|
+
|
60
|
+
`movies?q=home_formats=BD|DVD`
|
61
|
+
Returns all movies whose `home_formats` includes "DVD" or "BD"
|
62
|
+
|
37
63
|
### Combining Searches
|
38
64
|
|
39
65
|
Search criteria can be separated with commas
|
data/lib/query_string_search.rb
CHANGED
@@ -4,7 +4,8 @@ module QueryStringSearch
|
|
4
4
|
end
|
5
5
|
|
6
6
|
class Search
|
7
|
-
attr_accessor :data_source
|
7
|
+
attr_accessor :data_source
|
8
|
+
attr_reader :query_string
|
8
9
|
|
9
10
|
def initialize(data_source, query_string)
|
10
11
|
self.data_source = data_source
|
@@ -21,6 +22,10 @@ module QueryStringSearch
|
|
21
22
|
|
22
23
|
private
|
23
24
|
|
25
|
+
def query_string=(x)
|
26
|
+
@query_string = x ? CGI.unescape(x) : nil
|
27
|
+
end
|
28
|
+
|
24
29
|
def filter_by_param(data, param)
|
25
30
|
data.select { |c| param.match?(c) }
|
26
31
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
module QueryStringSearch
|
4
|
+
module Comparator
|
5
|
+
class AbstractComparison
|
6
|
+
attr_accessor :other, :subject, :operator
|
7
|
+
|
8
|
+
def self.comparisons
|
9
|
+
descendants.push(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.descendants
|
13
|
+
ObjectSpace.each_object(Class).select { |klass| klass < AbstractComparison }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all_reserved_operators
|
17
|
+
descendants.each_with_object([]) { |d, ret| ret << d.reserved_operators }.flatten
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.reserved_operators
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def normalize(unnormalized)
|
25
|
+
Array(unnormalized).map(&:to_s).map(&:upcase)
|
26
|
+
end
|
27
|
+
|
28
|
+
def compare
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.build_me?(_)
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
Dir.glob(File.join(File.dirname(__FILE__), "comparisons", "*.rb")) { |file| require file }
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module QueryStringSearch
|
2
2
|
class AbstractMatcher
|
3
|
-
attr_accessor :attribute, :
|
3
|
+
attr_accessor :attribute, :desired_value
|
4
|
+
attr_reader :operator
|
4
5
|
|
5
6
|
def self.matchers
|
6
7
|
descendants.push(self)
|
@@ -14,11 +15,6 @@ module QueryStringSearch
|
|
14
15
|
descendants.each_with_object([]) { |d, ret| ret << d.reserved_words }.flatten
|
15
16
|
end
|
16
17
|
|
17
|
-
def initialize(attribute = nil, value = nil)
|
18
|
-
self.attribute = attribute
|
19
|
-
self.value = value
|
20
|
-
end
|
21
|
-
|
22
18
|
def match?(_)
|
23
19
|
false
|
24
20
|
end
|
@@ -27,10 +23,18 @@ module QueryStringSearch
|
|
27
23
|
[]
|
28
24
|
end
|
29
25
|
|
30
|
-
def self.build_me?(_
|
26
|
+
def self.build_me?(_)
|
31
27
|
true
|
32
28
|
end
|
33
29
|
|
30
|
+
def operator=(x)
|
31
|
+
@operator = x.to_s.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def comparison
|
35
|
+
@comparison ||= QueryStringSearch::Comparator::ComparisonFactory.build(self)
|
36
|
+
end
|
37
|
+
|
34
38
|
private
|
35
39
|
|
36
40
|
def match_with_contingency
|
@@ -38,6 +42,10 @@ module QueryStringSearch
|
|
38
42
|
rescue
|
39
43
|
false
|
40
44
|
end
|
45
|
+
|
46
|
+
def actual_value(actual)
|
47
|
+
actual.public_send(attribute)
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
Dir.glob(File.join(File.dirname(__FILE__), "matchers", "*.rb")) { |file| require file }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module QueryStringSearch
|
2
|
+
module Comparator
|
3
|
+
class ComparisonFactory
|
4
|
+
def self.build(matcher, available_comparisons = AbstractComparison.comparisons)
|
5
|
+
comparison_to_build = available_comparisons.detect { |c| c.build_me?(matcher) }
|
6
|
+
|
7
|
+
if comparison_to_build
|
8
|
+
comparison = comparison_to_build.new
|
9
|
+
comparison.subject = matcher.desired_value
|
10
|
+
comparison.operator = matcher.operator
|
11
|
+
comparison
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module QueryStringSearch
|
2
|
+
module Comparator
|
3
|
+
class Inequality < AbstractComparison
|
4
|
+
def compare(other)
|
5
|
+
normalize(other).public_send(operator, normalize(subject))
|
6
|
+
end
|
7
|
+
|
8
|
+
def normalize(unnormalized)
|
9
|
+
unnormalized.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.reserved_operators
|
13
|
+
[:<, :>, :<=, :>=]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build_me?(matcher)
|
17
|
+
reserved_operators.include?(matcher.operator)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module QueryStringSearch
|
2
|
+
module Comparator
|
3
|
+
class Set < AbstractComparison
|
4
|
+
def compare(other)
|
5
|
+
(normalize(subject) & normalize(other)).any?
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.build_me?(matcher)
|
9
|
+
all_reserved_operators.none? { |o| o == matcher.operator }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module QueryStringSearch
|
2
2
|
class MatcherFactory
|
3
|
-
def self.build(
|
4
|
-
|
3
|
+
def self.build(search_option, build_options)
|
4
|
+
matcher_to_build = build_options.detect { |m| m.build_me?(search_option) }
|
5
5
|
|
6
|
-
if
|
7
|
-
|
6
|
+
if matcher_to_build
|
7
|
+
matcher = matcher_to_build.new
|
8
|
+
matcher.attribute = search_option.attribute
|
9
|
+
matcher.desired_value = search_option.desired_value
|
10
|
+
matcher.operator = search_option.operator
|
11
|
+
matcher
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -3,7 +3,7 @@ class MatchAll < QueryStringSearch::AbstractMatcher
|
|
3
3
|
true
|
4
4
|
end
|
5
5
|
|
6
|
-
def self.build_me?(
|
7
|
-
|
6
|
+
def self.build_me?(search_option)
|
7
|
+
search_option.attribute.nil? && search_option.desired_value.nil?
|
8
8
|
end
|
9
9
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class MatchAttribute < QueryStringSearch::AbstractMatcher
|
2
|
-
def match?(
|
3
|
-
match_with_contingency {
|
2
|
+
def match?(data)
|
3
|
+
match_with_contingency { actual_value(data) }
|
4
4
|
end
|
5
5
|
|
6
6
|
def self.reserved_words
|
@@ -10,7 +10,7 @@ class MatchAttribute < QueryStringSearch::AbstractMatcher
|
|
10
10
|
]
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.build_me?(
|
14
|
-
reserved_words.any? { |r| r.match(
|
13
|
+
def self.build_me?(search_option)
|
14
|
+
reserved_words.any? { |r| r.match(search_option.desired_value) }
|
15
15
|
end
|
16
16
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
class MatchAttributeValue < QueryStringSearch::AbstractMatcher
|
2
|
-
def match?(
|
2
|
+
def match?(data)
|
3
3
|
match_with_contingency do
|
4
|
-
|
4
|
+
comparison.compare(actual_value(data))
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.build_me?(
|
9
|
-
|
10
|
-
|
11
|
-
all_reserved_words.none? { |r| r.match(
|
8
|
+
def self.build_me?(search_option)
|
9
|
+
search_option.desired_value &&
|
10
|
+
search_option.attribute &&
|
11
|
+
all_reserved_words.none? { |r| r.match(search_option.desired_value) }
|
12
12
|
end
|
13
13
|
end
|
@@ -1,21 +1,25 @@
|
|
1
1
|
class MatchMultipleAttributeValues < QueryStringSearch::AbstractMatcher
|
2
|
-
def match?(
|
2
|
+
def match?(data)
|
3
3
|
match_with_contingency do
|
4
|
-
|
4
|
+
comparison.compare(actual_value(data))
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
+
def operator
|
9
|
+
:&
|
10
|
+
end
|
11
|
+
|
8
12
|
def self.reserved_words
|
9
13
|
[
|
10
14
|
/^\w+\|\w+/
|
11
15
|
]
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
15
|
-
super(x.split("|")
|
18
|
+
def desired_value=(x)
|
19
|
+
super(x.split("|"))
|
16
20
|
end
|
17
21
|
|
18
|
-
def self.build_me?(
|
19
|
-
reserved_words.any? { |r| r.match(
|
22
|
+
def self.build_me?(search_option)
|
23
|
+
reserved_words.any? { |r| r.match(search_option.desired_value) }
|
20
24
|
end
|
21
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class MatchNoAttribute < QueryStringSearch::AbstractMatcher
|
2
|
-
def match?(
|
3
|
-
match_with_contingency { !
|
2
|
+
def match?(data)
|
3
|
+
match_with_contingency { !actual_value(data) }
|
4
4
|
end
|
5
5
|
|
6
6
|
def self.reserved_words
|
@@ -10,7 +10,7 @@ class MatchNoAttribute < QueryStringSearch::AbstractMatcher
|
|
10
10
|
]
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.build_me?(
|
14
|
-
reserved_words.any? { |r| r.match(
|
13
|
+
def self.build_me?(search_option)
|
14
|
+
reserved_words.any? { |r| r.match(search_option.desired_value) }
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module QueryStringSearch
|
2
|
+
class SearchOption
|
3
|
+
attr_reader :attribute, :desired_value, :operator
|
4
|
+
|
5
|
+
def initialize(raw_query)
|
6
|
+
parsed_query = KeyValue.parse(raw_query)
|
7
|
+
self.attribute = parsed_query.attribute
|
8
|
+
self.desired_value = parsed_query.desired_value
|
9
|
+
self.operator = parsed_query.operator
|
10
|
+
end
|
11
|
+
|
12
|
+
def attribute
|
13
|
+
@attribute ? @attribute.to_sym : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_writer :attribute, :desired_value, :operator
|
19
|
+
end
|
20
|
+
|
21
|
+
class KeyValue
|
22
|
+
attr_accessor :attribute, :desired_value, :operator
|
23
|
+
|
24
|
+
def self.parse(raw_query)
|
25
|
+
new(/(?<attribute>\w+)(?<operator>\W+)(?<desired_value>.+)/.match(raw_query))
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(match_data)
|
29
|
+
match_data = match_data ? match_data : {}
|
30
|
+
self.attribute = match_data[:attribute]
|
31
|
+
self.desired_value = match_data[:desired_value]
|
32
|
+
self.operator = match_data[:operator]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,32 +1,13 @@
|
|
1
1
|
module QueryStringSearch
|
2
|
-
|
3
|
-
attr_reader :search_type, :search_param
|
4
|
-
|
2
|
+
module SearchOptions
|
5
3
|
def self.parse(query_string)
|
6
4
|
if query_string
|
7
|
-
|
8
|
-
|
9
|
-
ret << new(p)
|
5
|
+
query_string.split(",").each_with_object([]) do |p, ret|
|
6
|
+
ret << QueryStringSearch::SearchOption.new(p)
|
10
7
|
end
|
11
8
|
else
|
12
|
-
[new(nil)]
|
9
|
+
[QueryStringSearch::SearchOption.new(nil)]
|
13
10
|
end
|
14
11
|
end
|
15
|
-
|
16
|
-
def initialize(raw_query)
|
17
|
-
self.search_type, self.search_param = raw_query.to_s.split("=")
|
18
|
-
end
|
19
|
-
|
20
|
-
def search_type
|
21
|
-
@search_type ? @search_type.to_sym : nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def search_param
|
25
|
-
@search_param ? CGI.unescape(@search_param) : @search_param
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
attr_writer :search_type, :search_param
|
31
12
|
end
|
32
13
|
end
|
@@ -5,13 +5,13 @@ module QueryStringSearch
|
|
5
5
|
def_delegators :@collection, :each
|
6
6
|
|
7
7
|
def self.build_from_querystring(query_string, factory = QueryStringSearch::MatcherFactory, matchers = QueryStringSearch::AbstractMatcher.matchers)
|
8
|
-
|
9
|
-
new(
|
8
|
+
search_options = QueryStringSearch::SearchOptions.parse(query_string)
|
9
|
+
new(search_options, factory, matchers)
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
|
14
|
-
collection << factory.build(
|
12
|
+
def initialize(search_options, factory, matchers)
|
13
|
+
search_options.each do |search_option|
|
14
|
+
collection << factory.build(search_option, matchers)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative "../../lib/query_string_search"
|
2
|
+
require_relative "../fixtures/movie"
|
3
|
+
|
4
|
+
RSpec.describe "Finding data based on an attribute that returns a collection" do
|
5
|
+
let(:data_set) { Movie.random_collection }
|
6
|
+
|
7
|
+
let(:movies_on_dvd) { data_set.select { |d| d.home_formats.include?("DVD") } }
|
8
|
+
let(:movies_on_dvd_or_bd) { data_set.select { |d| d.home_formats.include?("DVD") || d.home_formats.include?("BD") } }
|
9
|
+
|
10
|
+
it "Returns the correct records when searching for one value" do
|
11
|
+
query_string = "home_formats=DVD"
|
12
|
+
results = QueryStringSearch.new(data_set, query_string).results
|
13
|
+
|
14
|
+
expect(results).to eq(movies_on_dvd)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "Returns the correct records when searching for two values" do
|
18
|
+
query_string = "home_formats=DVD|BD"
|
19
|
+
results = QueryStringSearch.new(data_set, query_string).results
|
20
|
+
|
21
|
+
expect(results).to eq(movies_on_dvd_or_bd)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative "../../lib/query_string_search"
|
2
|
+
require_relative "../fixtures/movie"
|
3
|
+
|
4
|
+
RSpec.describe "Finding data with inequality matchers" do
|
5
|
+
describe "Allows searching for values greater than a number" do
|
6
|
+
let(:data_set) { Movie.random_collection }
|
7
|
+
let(:movies_with_more_than_one_star) { data_set.select { |d| d.star_rating > 1 } }
|
8
|
+
|
9
|
+
it "Returns records that match the requested value" do
|
10
|
+
results = QueryStringSearch.new(data_set, "star_rating>1").results
|
11
|
+
|
12
|
+
expect(results).to eq(movies_with_more_than_one_star)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "Allows searching for values less than a number" do
|
17
|
+
let(:data_set) { Movie.random_collection }
|
18
|
+
let(:movies_with_fewer_than_three_stars) { data_set.select { |d| d.star_rating < 3 } }
|
19
|
+
|
20
|
+
it "Returns records that match the requested value" do
|
21
|
+
results = QueryStringSearch.new(data_set, "star_rating<3").results
|
22
|
+
|
23
|
+
expect(results).to eq(movies_with_fewer_than_three_stars)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Allows searching for values greater than or equal to a number" do
|
28
|
+
let(:data_set) { Movie.random_collection }
|
29
|
+
let(:movies_with_two_or_more_stars) { data_set.select { |d| d.star_rating >= 2 } }
|
30
|
+
|
31
|
+
it "Returns records that match the requested value" do
|
32
|
+
results = QueryStringSearch.new(data_set, "star_rating>=2").results
|
33
|
+
|
34
|
+
expect(results).to eq(movies_with_two_or_more_stars)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "Allows searching for values less than or equal to a number" do
|
39
|
+
let(:data_set) { Movie.random_collection }
|
40
|
+
let(:movies_with_four_or_fewer_stars) { data_set.select { |d| d.star_rating <= 4 } }
|
41
|
+
|
42
|
+
it "Returns records that match the requested value" do
|
43
|
+
results = QueryStringSearch.new(data_set, "star_rating<=4").results
|
44
|
+
|
45
|
+
expect(results).to eq(movies_with_four_or_fewer_stars)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/fixtures/movie.rb
CHANGED
@@ -1,37 +1,41 @@
|
|
1
1
|
class Movie
|
2
|
-
attr_accessor :title, :rating, :year, :country, :seen
|
2
|
+
attr_accessor :title, :rating, :year, :country, :seen, :star_rating, :home_formats
|
3
3
|
|
4
|
-
def self.random_collection(count =
|
5
|
-
(1...count).
|
6
|
-
collection << Movie.new(random_title, random_rating, random_year, random_country)
|
7
|
-
end
|
4
|
+
def self.random_collection(count = 100)
|
5
|
+
(1...count).map { |_| Movie.random }
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
self.
|
8
|
+
def self.random
|
9
|
+
Movie.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
self.title = random_title
|
14
|
+
self.rating = random_rating
|
15
|
+
self.year = random_year
|
16
|
+
self.country = random_country
|
17
|
+
self.seen = [true, false].sample
|
18
|
+
self.star_rating = [1, 2, 3, 4, 5].sample
|
19
|
+
self.home_formats = %w(BD DVD Hulu Amazon Netflix).sample(2)
|
16
20
|
end
|
17
21
|
|
18
22
|
def seen?
|
19
23
|
seen
|
20
24
|
end
|
21
25
|
|
22
|
-
def
|
26
|
+
def random_title
|
23
27
|
"Random Movie #{rand(10_000)}"
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
30
|
+
def random_rating
|
27
31
|
["X", "NC-17", "R", "PG-13", "PG", "G", nil].sample
|
28
32
|
end
|
29
33
|
|
30
|
-
def
|
34
|
+
def random_year
|
31
35
|
(1990..2014).to_a.sample.to_s
|
32
36
|
end
|
33
37
|
|
34
|
-
def
|
38
|
+
def random_country
|
35
39
|
%w(
|
36
40
|
US CAN UK HK BR RUS FR IN
|
37
41
|
).sample
|
@@ -6,14 +6,17 @@ RSpec.describe QueryStringSearch::AbstractMatcher do
|
|
6
6
|
it "is false" do
|
7
7
|
value = rand
|
8
8
|
target = OpenStruct.new(other: value)
|
9
|
-
it = QueryStringSearch::AbstractMatcher.new
|
9
|
+
it = QueryStringSearch::AbstractMatcher.new
|
10
|
+
it.attribute = :other
|
11
|
+
it.desired_value = value
|
12
|
+
it.operator = "="
|
10
13
|
expect(it.match?(target)).to be_falsey
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
17
|
describe "build_me?" do
|
15
18
|
it "is true" do
|
16
|
-
it = QueryStringSearch::AbstractMatcher.build_me?(
|
19
|
+
it = QueryStringSearch::AbstractMatcher.build_me?(Object.new)
|
17
20
|
expect(it).to be_truthy
|
18
21
|
end
|
19
22
|
end
|
@@ -7,16 +7,21 @@ RSpec.describe QueryStringSearch::MatcherFactory do
|
|
7
7
|
let(:build_candidates) { [matcher_double] }
|
8
8
|
|
9
9
|
before do
|
10
|
-
allow(param_double).to receive(:
|
11
|
-
allow(param_double).to receive(:
|
10
|
+
allow(param_double).to receive(:desired_value).and_return("test_search_value")
|
11
|
+
allow(param_double).to receive(:attribute).and_return("test_search_attribute")
|
12
|
+
allow(param_double).to receive(:operator).and_return("test_operator")
|
12
13
|
end
|
13
14
|
|
14
15
|
describe "build" do
|
15
16
|
describe "finds a matcher to build" do
|
16
|
-
it "builds that matcher and returns it" do
|
17
|
-
test_return =
|
18
|
-
expect(
|
19
|
-
expect(
|
17
|
+
it "builds that matcher, configures and returns it" do
|
18
|
+
test_return = instance_double(QueryStringSearch::AbstractMatcher.matchers.sample)
|
19
|
+
expect(test_return).to receive(:attribute=).with("test_search_attribute")
|
20
|
+
expect(test_return).to receive(:desired_value=).with("test_search_value")
|
21
|
+
expect(test_return).to receive(:operator=).with("test_operator")
|
22
|
+
|
23
|
+
expect(matcher_double).to receive(:build_me?).with(param_double).and_return(true)
|
24
|
+
expect(matcher_double).to receive(:new).and_return(test_return)
|
20
25
|
expect(QueryStringSearch::MatcherFactory.build(param_double, build_candidates)).to eq(test_return)
|
21
26
|
end
|
22
27
|
end
|
@@ -3,23 +3,38 @@ require_relative "../../../../lib/query_string_search/abstract_matcher"
|
|
3
3
|
RSpec.describe MatchAll do
|
4
4
|
describe "match?" do
|
5
5
|
it "is true" do
|
6
|
-
it = MatchAll.new
|
6
|
+
it = MatchAll.new
|
7
|
+
it.attribute = :other
|
8
|
+
it.desired_value = rand
|
7
9
|
expect(it.match?(rand)).to be_truthy
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
13
|
describe "build_me?" do
|
12
|
-
|
14
|
+
let(:search_option) { instance_double(QueryStringSearch::SearchOption) }
|
15
|
+
|
16
|
+
describe "given a nil attribute and desired_value" do
|
13
17
|
it "is true" do
|
14
|
-
|
18
|
+
allow(search_option).to receive(:attribute).and_return(nil)
|
19
|
+
allow(search_option).to receive(:desired_value).and_return(nil)
|
20
|
+
|
21
|
+
expect(MatchAll.build_me?(search_option)).to be_truthy
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
18
|
-
describe "given a non-nil
|
25
|
+
describe "given a non-nil attribute or desired_value" do
|
19
26
|
it "is false" do
|
20
|
-
|
21
|
-
|
22
|
-
expect(MatchAll.build_me?(
|
27
|
+
allow(search_option).to receive(:attribute).and_return(rand)
|
28
|
+
allow(search_option).to receive(:desired_value).and_return(nil)
|
29
|
+
expect(MatchAll.build_me?(search_option)).to be_falsey
|
30
|
+
|
31
|
+
allow(search_option).to receive(:attribute).and_return(nil)
|
32
|
+
allow(search_option).to receive(:desired_value).and_return(rand)
|
33
|
+
expect(MatchAll.build_me?(search_option)).to be_falsey
|
34
|
+
|
35
|
+
allow(search_option).to receive(:attribute).and_return(rand)
|
36
|
+
allow(search_option).to receive(:desired_value).and_return(rand)
|
37
|
+
expect(MatchAll.build_me?(search_option)).to be_falsey
|
23
38
|
end
|
24
39
|
end
|
25
40
|
end
|
@@ -5,63 +5,72 @@ RSpec.describe MatchAttribute do
|
|
5
5
|
describe "match?" do
|
6
6
|
describe "if the target's attribute is not nil" do
|
7
7
|
let(:target) { SearchTarget.new(property: "search_value") }
|
8
|
-
let(:subject) { MatchAttribute.new(:property) }
|
9
8
|
|
10
9
|
it "is true" do
|
11
|
-
|
10
|
+
matcher = MatchAttribute.new
|
11
|
+
matcher.attribute = :property
|
12
|
+
expect(matcher.match?(target)).to be_truthy
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
describe "if the target's attribute is true" do
|
16
17
|
let(:target) { SearchTarget.new(property: true) }
|
17
|
-
let(:subject) { MatchAttribute.new(:property) }
|
18
18
|
|
19
19
|
it "is true" do
|
20
|
-
|
20
|
+
matcher = MatchAttribute.new
|
21
|
+
matcher.attribute = :property
|
22
|
+
expect(matcher.match?(target)).to be_truthy
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
describe "if the target's attribute is nil" do
|
25
27
|
let(:target) { SearchTarget.new(property: nil) }
|
26
|
-
let(:subject) { MatchAttribute.new(:property) }
|
27
28
|
|
28
29
|
it "is false" do
|
29
|
-
|
30
|
+
matcher = MatchAttribute.new
|
31
|
+
matcher.attribute = :property
|
32
|
+
expect(matcher.match?(target)).to be_falsey
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
36
|
describe "if the target's attribute is false" do
|
34
37
|
let(:target) { SearchTarget.new(property: false) }
|
35
|
-
let(:subject) { MatchAttribute.new(:property) }
|
36
38
|
|
37
39
|
it "is true" do
|
38
|
-
|
40
|
+
matcher = MatchAttribute.new
|
41
|
+
matcher.attribute = :property
|
42
|
+
expect(matcher.match?(target)).to be_falsey
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
46
|
describe "if the target doesn't have the attribute" do
|
43
47
|
let(:target) { SearchTarget.new(property: rand) }
|
44
|
-
let(:subject) { MatchAttribute.new(:bad_attr) }
|
45
48
|
|
46
49
|
it "is false" do
|
47
|
-
|
50
|
+
matcher = MatchAttribute.new
|
51
|
+
matcher.attribute = :bat_attr
|
52
|
+
expect(matcher.match?(target)).to be_falsey
|
48
53
|
end
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
57
|
describe "build_me?" do
|
53
|
-
|
58
|
+
let(:search_option) { instance_double(QueryStringSearch::SearchOption) }
|
59
|
+
|
60
|
+
describe "given a value of 'all' or 'true'" do
|
54
61
|
it "is true" do
|
55
|
-
%w(all true).each do |
|
56
|
-
|
62
|
+
%w(all true).each do |desired_value|
|
63
|
+
allow(search_option).to receive(:desired_value).and_return(desired_value)
|
64
|
+
expect(MatchAttribute.build_me?(search_option)).to be_truthy
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
61
|
-
describe "given a
|
69
|
+
describe "given a value that is not 'all' or 'true'" do
|
62
70
|
it "is false" do
|
63
|
-
%w(1all rue).each do |
|
64
|
-
|
71
|
+
%w(1all rue).each do |desired_value|
|
72
|
+
allow(search_option).to receive(:desired_value).and_return(desired_value)
|
73
|
+
expect(MatchAttribute.build_me?(search_option)).to be_falsey
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -5,53 +5,77 @@ RSpec.describe MatchAttributeValue do
|
|
5
5
|
describe "match?" do
|
6
6
|
describe "given a target with an attribute that matches the Parameter's attribute" do
|
7
7
|
let(:target) { SearchTarget.new(property: "search_value") }
|
8
|
-
let(:subject) { MatchAttributeValue.new(:property, "search_value") }
|
9
8
|
|
10
9
|
it "returns true" do
|
11
|
-
|
10
|
+
matcher = MatchAttributeValue.new
|
11
|
+
matcher.attribute = :property
|
12
|
+
matcher.desired_value = "search_value"
|
13
|
+
matcher.operator = "="
|
14
|
+
expect(matcher.match?(target)).to be_truthy
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
15
18
|
describe "given a value with spaces" do
|
16
19
|
let(:target) { SearchTarget.new(property: "search value") }
|
17
|
-
let(:subject) { MatchAttributeValue.new(:property, "search value") }
|
18
20
|
|
19
21
|
it "returns true" do
|
20
|
-
|
22
|
+
matcher = MatchAttributeValue.new
|
23
|
+
matcher.attribute = :property
|
24
|
+
matcher.desired_value = "search value"
|
25
|
+
matcher.operator = "="
|
26
|
+
expect(matcher.match?(target)).to be_truthy
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
24
30
|
describe "given a target with an attribute that does not match the Parameter's attribute" do
|
25
31
|
let(:target) { SearchTarget.new(property: "other_value") }
|
26
|
-
let(:subject) { MatchAttributeValue.new(:property, "search_value") }
|
27
32
|
|
28
33
|
it "returns false" do
|
29
|
-
|
34
|
+
matcher = MatchAttributeValue.new
|
35
|
+
matcher.attribute = :property
|
36
|
+
matcher.desired_value = "search_value"
|
37
|
+
matcher.operator = "="
|
38
|
+
expect(matcher.match?(target)).to be_falsey
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
33
42
|
describe "if the target doesn't have the attribute" do
|
34
43
|
let(:target) { SearchTarget.new(property: "search_value") }
|
35
|
-
let(:subject) { MatchAttribute.new(:bad_attr, "search_value") }
|
36
44
|
|
37
45
|
it "is false" do
|
38
|
-
|
46
|
+
matcher = MatchAttributeValue.new
|
47
|
+
matcher.attribute = :bat_attr
|
48
|
+
matcher.desired_value = "search_value"
|
49
|
+
matcher.operator = "="
|
50
|
+
expect(matcher.match?(target)).to be_falsey
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
42
54
|
|
43
55
|
describe "build_me?" do
|
44
|
-
|
56
|
+
let(:search_option) { instance_double(QueryStringSearch::SearchOption) }
|
57
|
+
|
58
|
+
describe "given a non-nil attribute and desired_value" do
|
45
59
|
it "is true" do
|
46
|
-
|
60
|
+
allow(search_option).to receive(:attribute).and_return(rand.to_s)
|
61
|
+
allow(search_option).to receive(:desired_value).and_return(rand.to_s)
|
62
|
+
expect(MatchAttributeValue.build_me?(search_option)).to be_truthy
|
47
63
|
end
|
48
64
|
end
|
49
65
|
|
50
|
-
describe "given a nil
|
66
|
+
describe "given a nil attribute or desired_value" do
|
51
67
|
it "is false" do
|
52
|
-
|
53
|
-
|
54
|
-
expect(MatchAttributeValue.build_me?(
|
68
|
+
allow(search_option).to receive(:attribute).and_return(rand.to_s)
|
69
|
+
allow(search_option).to receive(:desired_value).and_return(nil)
|
70
|
+
expect(MatchAttributeValue.build_me?(search_option)).to be_falsey
|
71
|
+
|
72
|
+
allow(search_option).to receive(:attribute).and_return(nil)
|
73
|
+
allow(search_option).to receive(:desired_value).and_return(rand.to_s)
|
74
|
+
expect(MatchAttributeValue.build_me?(search_option)).to be_falsey
|
75
|
+
|
76
|
+
allow(search_option).to receive(:attribute).and_return(nil)
|
77
|
+
allow(search_option).to receive(:desired_value).and_return(nil)
|
78
|
+
expect(MatchAttributeValue.build_me?(search_option)).to be_falsey
|
55
79
|
end
|
56
80
|
end
|
57
81
|
end
|
@@ -5,20 +5,26 @@ RSpec.describe MatchMultipleAttributeValues do
|
|
5
5
|
describe "match?" do
|
6
6
|
it "matches if the target's attribute is one of the values" do
|
7
7
|
target = SearchTarget.new(property: "1994")
|
8
|
-
matcher = MatchMultipleAttributeValues.new
|
8
|
+
matcher = MatchMultipleAttributeValues.new
|
9
|
+
matcher.attribute = :property
|
10
|
+
matcher.desired_value = "1994|1995"
|
9
11
|
expect(matcher.match?(target)).to be_truthy
|
10
12
|
end
|
11
13
|
|
12
14
|
it "does not match if the target's attribute is not one of the values" do
|
13
15
|
target = SearchTarget.new(property: "199")
|
14
|
-
matcher = MatchMultipleAttributeValues.new
|
16
|
+
matcher = MatchMultipleAttributeValues.new
|
17
|
+
matcher.attribute = :property
|
18
|
+
matcher.desired_value = "1994|1995"
|
15
19
|
expect(matcher.match?(target)).to be_falsey
|
16
20
|
end
|
17
21
|
|
18
22
|
describe "if the target doesn't have the attribute" do
|
19
23
|
it "is false" do
|
20
24
|
target = SearchTarget.new(property: "1994")
|
21
|
-
|
25
|
+
matcher = MatchMultipleAttributeValues.new
|
26
|
+
matcher.attribute = :bad_attr
|
27
|
+
matcher.desired_value = "1994|1995"
|
22
28
|
|
23
29
|
expect(subject.match?(target)).to be_falsey
|
24
30
|
end
|
@@ -26,21 +32,29 @@ RSpec.describe MatchMultipleAttributeValues do
|
|
26
32
|
end
|
27
33
|
|
28
34
|
describe "build_me?" do
|
29
|
-
|
35
|
+
let(:search_option) { instance_double(QueryStringSearch::SearchOption) }
|
36
|
+
|
37
|
+
describe "given a search type and value that contains a pipe" do
|
30
38
|
it "is true" do
|
31
|
-
|
39
|
+
allow(search_option).to receive(:attribute).and_return(rand.to_s)
|
40
|
+
allow(search_option).to receive(:desired_value).and_return("x|y")
|
41
|
+
expect(MatchMultipleAttributeValues.build_me?(search_option)).to be_truthy
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
35
|
-
describe "given a search type and
|
45
|
+
describe "given a search type and value that starts with a pipe" do
|
36
46
|
it "is false" do
|
37
|
-
|
47
|
+
allow(search_option).to receive(:attribute).and_return(rand.to_s)
|
48
|
+
allow(search_option).to receive(:desired_value).and_return("|x|y")
|
49
|
+
expect(MatchMultipleAttributeValues.build_me?(search_option)).to be_falsey
|
38
50
|
end
|
39
51
|
end
|
40
52
|
|
41
53
|
describe "given a search type without a pipe" do
|
42
54
|
it "is false" do
|
43
|
-
|
55
|
+
allow(search_option).to receive(:attribute).and_return(rand.to_s)
|
56
|
+
allow(search_option).to receive(:desired_value).and_return("xy")
|
57
|
+
expect(MatchMultipleAttributeValues.build_me?(search_option)).to be_falsey
|
44
58
|
end
|
45
59
|
end
|
46
60
|
end
|
@@ -5,63 +5,72 @@ RSpec.describe MatchNoAttribute do
|
|
5
5
|
describe "match?" do
|
6
6
|
describe "if the target's attribute is not nil" do
|
7
7
|
let(:target) { SearchTarget.new(property: "search_value") }
|
8
|
-
let(:subject) { MatchNoAttribute.new(:property) }
|
9
8
|
|
10
9
|
it "is false" do
|
11
|
-
|
10
|
+
matcher = MatchNoAttribute.new
|
11
|
+
matcher.attribute = :property
|
12
|
+
expect(matcher.match?(target)).to be_falsey
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
describe "if the target's attribute is true" do
|
16
17
|
let(:target) { SearchTarget.new(property: true) }
|
17
|
-
let(:subject) { MatchNoAttribute.new(:property) }
|
18
18
|
|
19
19
|
it "is true" do
|
20
|
-
|
20
|
+
matcher = MatchNoAttribute.new
|
21
|
+
matcher.attribute = :property
|
22
|
+
expect(matcher.match?(target)).to be_falsey
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
describe "if the target's attribute is false" do
|
25
27
|
let(:target) { SearchTarget.new(property: false) }
|
26
|
-
let(:subject) { MatchNoAttribute.new(:property) }
|
27
28
|
|
28
29
|
it "is true" do
|
29
|
-
|
30
|
+
matcher = MatchNoAttribute.new
|
31
|
+
matcher.attribute = :property
|
32
|
+
expect(matcher.match?(target)).to be_truthy
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
36
|
describe "if the target's attribute is nil" do
|
34
37
|
let(:target) { SearchTarget.new(property: nil) }
|
35
|
-
let(:subject) { MatchNoAttribute.new(:property) }
|
36
38
|
|
37
39
|
it "is true" do
|
38
|
-
|
40
|
+
matcher = MatchNoAttribute.new
|
41
|
+
matcher.attribute = :property
|
42
|
+
expect(matcher.match?(target)).to be_truthy
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
46
|
describe "if the target doesn't have the attribute" do
|
43
47
|
let(:target) { SearchTarget.new(property: rand) }
|
44
|
-
let(:subject) { MatchNoAttribute.new(:bad_attr) }
|
45
48
|
|
46
49
|
it "is false" do
|
47
|
-
|
50
|
+
matcher = MatchNoAttribute.new
|
51
|
+
matcher.attribute = :bad_attr
|
52
|
+
expect(matcher.match?(target)).to be_falsey
|
48
53
|
end
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
57
|
describe "build_me?" do
|
53
|
-
|
58
|
+
let(:search_option) { instance_double(QueryStringSearch::SearchOption) }
|
59
|
+
|
60
|
+
describe "given a value of 'none' or 'false'" do
|
54
61
|
it "is true" do
|
55
|
-
%w(none false).each do |
|
56
|
-
|
62
|
+
%w(none false).each do |desired_value|
|
63
|
+
allow(search_option).to receive(:desired_value).and_return(desired_value)
|
64
|
+
expect(MatchNoAttribute.build_me?(search_option)).to be_truthy
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
61
|
-
describe "given a
|
69
|
+
describe "given a value that is not 'none' or 'false'" do
|
62
70
|
it "is false" do
|
63
|
-
%w(one falsey).each do |
|
64
|
-
|
71
|
+
%w(one falsey).each do |desired_value|
|
72
|
+
allow(search_option).to receive(:desired_value).and_return(desired_value)
|
73
|
+
expect(MatchNoAttribute.build_me?(search_option)).to be_falsey
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "../../../lib/query_string_search/search_option"
|
2
|
+
|
3
|
+
RSpec.describe QueryStringSearch::SearchOption do
|
4
|
+
describe "new" do
|
5
|
+
describe "with equality operator" do
|
6
|
+
let(:equal_query) { "test=2" }
|
7
|
+
|
8
|
+
it "correctly splits the attribute, value and operator" do
|
9
|
+
equal_option = QueryStringSearch::SearchOption.new("test=2")
|
10
|
+
expect(equal_option.attribute).to eq(:test)
|
11
|
+
expect(equal_option.desired_value).to eq("2")
|
12
|
+
expect(equal_option.operator).to eq("=")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with inequality operators" do
|
17
|
+
let(:less_than_query_string) { "test<1" }
|
18
|
+
let(:greater_than_or_equal_query) { "test>=2" }
|
19
|
+
|
20
|
+
it "correctly splits the attribute, value and operator" do
|
21
|
+
less_than = QueryStringSearch::SearchOption.new(less_than_query_string)
|
22
|
+
greater_or_equal = QueryStringSearch::SearchOption.new(greater_than_or_equal_query)
|
23
|
+
|
24
|
+
expect(less_than.attribute).to eq(:test)
|
25
|
+
expect(less_than.desired_value).to eq("1")
|
26
|
+
expect(less_than.operator).to eq("<")
|
27
|
+
|
28
|
+
expect(greater_or_equal.attribute).to eq(:test)
|
29
|
+
expect(greater_or_equal.desired_value).to eq("2")
|
30
|
+
expect(greater_or_equal.operator).to eq(">=")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -2,51 +2,32 @@ require_relative "../../../lib/query_string_search/search_options"
|
|
2
2
|
|
3
3
|
RSpec.describe QueryStringSearch::SearchOptions do
|
4
4
|
describe "parse" do
|
5
|
-
describe "with a single-element
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
it "that is enumerable" do
|
13
|
-
[single_element, multi_element].each do |it|
|
14
|
-
expect(it).to respond_to(:each)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "whose contents" do
|
19
|
-
it "have search_type that are symbols" do
|
20
|
-
expect(single_element.collect(&:search_type)).to eq([:test])
|
21
|
-
expect(multi_element.collect(&:search_type)).to eq([:test, :test2])
|
22
|
-
end
|
5
|
+
describe "with a single-element query_string" do
|
6
|
+
it "returns a collection of a single search option" do
|
7
|
+
option_double = Object.new
|
8
|
+
expect(QueryStringSearch::SearchOption).to receive(:new).with("test=filter").and_return(option_double)
|
9
|
+
expect(QueryStringSearch::SearchOptions.parse("test=filter")).to eq([option_double])
|
10
|
+
end
|
11
|
+
end
|
23
12
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
13
|
+
describe "with a multi-element query_string" do
|
14
|
+
let(:multi_query_string) { "test=filter,test2=test attribute" }
|
15
|
+
it "returns a collection of a multiple search options" do
|
16
|
+
option_double1 = Object.new
|
17
|
+
option_double2 = Object.new
|
18
|
+
expect(QueryStringSearch::SearchOption).to receive(:new).with("test=filter").and_return(option_double1)
|
19
|
+
expect(QueryStringSearch::SearchOption).to receive(:new).with("test2=test attribute").and_return(option_double2)
|
20
|
+
expect(QueryStringSearch::SearchOptions.parse(multi_query_string)).to eq([option_double1, option_double2])
|
29
21
|
end
|
30
22
|
end
|
31
23
|
|
32
24
|
describe "with a nil" do
|
33
25
|
let(:nil_element) { QueryStringSearch::SearchOptions.parse(nil) }
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
it "with one element" do
|
40
|
-
expect(nil_element.count).to eq(1)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "with nil search_type" do
|
44
|
-
expect(nil_element.first.search_type).to be_nil
|
45
|
-
end
|
26
|
+
it "creates a collection with one nil search option" do
|
27
|
+
option_double = Object.new
|
28
|
+
expect(QueryStringSearch::SearchOption).to receive(:new).with(nil).and_return(option_double)
|
46
29
|
|
47
|
-
|
48
|
-
expect(nil_element.first.search_param).to be_nil
|
49
|
-
end
|
30
|
+
expect(QueryStringSearch::SearchOptions.parse(nil)).to eq([option_double])
|
50
31
|
end
|
51
32
|
end
|
52
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: query_string_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Whitney
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-02-
|
13
|
+
date: 2015-02-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -114,21 +114,28 @@ files:
|
|
114
114
|
- README.md
|
115
115
|
- Rakefile
|
116
116
|
- lib/query_string_search.rb
|
117
|
+
- lib/query_string_search/abstract_comparison.rb
|
117
118
|
- lib/query_string_search/abstract_matcher.rb
|
119
|
+
- lib/query_string_search/comparison_factory.rb
|
120
|
+
- lib/query_string_search/comparisons/inequality.rb
|
121
|
+
- lib/query_string_search/comparisons/set.rb
|
118
122
|
- lib/query_string_search/matcher_factory.rb
|
119
123
|
- lib/query_string_search/matchers/match_all.rb
|
120
124
|
- lib/query_string_search/matchers/match_attribute.rb
|
121
125
|
- lib/query_string_search/matchers/match_attribute_value.rb
|
122
126
|
- lib/query_string_search/matchers/match_multiple_attribute_values.rb
|
123
127
|
- lib/query_string_search/matchers/match_no_attribute.rb
|
128
|
+
- lib/query_string_search/search_option.rb
|
124
129
|
- lib/query_string_search/search_options.rb
|
125
130
|
- lib/query_string_search/search_parameters.rb
|
126
131
|
- lib/query_string_search/version.rb
|
127
132
|
- query_string_search.gemspec
|
128
133
|
- spec/doubles/search_target.rb
|
129
134
|
- spec/features/find_all_data_spec.rb
|
135
|
+
- spec/features/find_records_by_searching_a_attribute_that_returns_a_collection_spec.rb
|
130
136
|
- spec/features/find_records_that_match_multiple_parameters_spec.rb
|
131
137
|
- spec/features/find_records_that_match_one_of_many_attributes_spec.rb
|
138
|
+
- spec/features/find_records_with_inequality_matchers_spec.rb
|
132
139
|
- spec/features/find_records_with_matching_attribute_values_spec.rb
|
133
140
|
- spec/features/find_records_with_nil_attributes_spec.rb
|
134
141
|
- spec/features/find_records_with_nonnil_attributes_spec.rb
|
@@ -141,6 +148,7 @@ files:
|
|
141
148
|
- spec/lib/query_string_search/matchers/match_attribute_value_spec.rb
|
142
149
|
- spec/lib/query_string_search/matchers/match_multiple_attribute_values_spec.rb
|
143
150
|
- spec/lib/query_string_search/matchers/match_no_attribute_spec.rb
|
151
|
+
- spec/lib/query_string_search/search_option_spec.rb
|
144
152
|
- spec/lib/query_string_search/search_options_spec.rb
|
145
153
|
- spec/lib/query_string_search/search_parameters_spec.rb
|
146
154
|
- spec/spec_helper.rb
|
@@ -171,8 +179,10 @@ summary: Provides a standard way to do searches using query strings in an API en
|
|
171
179
|
test_files:
|
172
180
|
- spec/doubles/search_target.rb
|
173
181
|
- spec/features/find_all_data_spec.rb
|
182
|
+
- spec/features/find_records_by_searching_a_attribute_that_returns_a_collection_spec.rb
|
174
183
|
- spec/features/find_records_that_match_multiple_parameters_spec.rb
|
175
184
|
- spec/features/find_records_that_match_one_of_many_attributes_spec.rb
|
185
|
+
- spec/features/find_records_with_inequality_matchers_spec.rb
|
176
186
|
- spec/features/find_records_with_matching_attribute_values_spec.rb
|
177
187
|
- spec/features/find_records_with_nil_attributes_spec.rb
|
178
188
|
- spec/features/find_records_with_nonnil_attributes_spec.rb
|
@@ -185,6 +195,7 @@ test_files:
|
|
185
195
|
- spec/lib/query_string_search/matchers/match_attribute_value_spec.rb
|
186
196
|
- spec/lib/query_string_search/matchers/match_multiple_attribute_values_spec.rb
|
187
197
|
- spec/lib/query_string_search/matchers/match_no_attribute_spec.rb
|
198
|
+
- spec/lib/query_string_search/search_option_spec.rb
|
188
199
|
- spec/lib/query_string_search/search_options_spec.rb
|
189
200
|
- spec/lib/query_string_search/search_parameters_spec.rb
|
190
201
|
- spec/spec_helper.rb
|