query_string_search 0.0.4 → 0.0.5
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.
- 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
|