philtre 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 554f9586dbea206ed2c4d498f846c0fb135aa29b
4
- data.tar.gz: f8ba5129e7b77a349803a24028834dfe537dbd4e
3
+ metadata.gz: c75bbf7d7dfed6ed3cd5afb6f4477f48b613e8e2
4
+ data.tar.gz: 8d4dd4dc4075865c44baa7872a03ff6dbf21fed1
5
5
  SHA512:
6
- metadata.gz: 6d2b3db1dc47dedbee316e3c78df9d2c305f47e3f05a5bf711f27d7014f4f418758762f84d367009e452a733bacd9f552c6c5b4c2ff75417cf8f5fe9c052bdaa
7
- data.tar.gz: 618d2eacbd24c67eb5552551fb28d77ad1c18ae5f5e586f056b3e5dba3ef36f489498a7c99dccaf14c832de7e80670386cc54ee3b734c58413fdffeb98a07167
6
+ metadata.gz: dcb1f7273340067c4d12faa431406a8b1f9f8658730d1516cdb1bf9568b95033f71e6631c497c6dcef1854193cecba2d18754a06406e5546cc0cff41cedd975d
7
+ data.tar.gz: 057199f52f8ec5b894020acb67e618ccfe952e450b374e8e29d68163e587ba8aa756376d8f5ba11e0bc3961634968a2fa273db3ac142d7df9b9dc4600f7179b1
@@ -1,7 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
- - 2.1.0
5
- - 2.1.1
6
- - 2.1.2
4
+ - 2.1.10
5
+ - 2.2.5
6
+ - 2.3.1
7
+ - jruby-9.0.5.0
8
+ - jruby-9.1.0.0
9
+ - rbx-2
7
10
  script: bundle exec rspec spec
data/AUTHORS ADDED
@@ -0,0 +1,2 @@
1
+ John Anderson
2
+ Damir Roso - idea nil parameter values
@@ -0,0 +1,7 @@
1
+ == 0.1.1
2
+ * drop support for ruby-2.0.0
3
+ * add customisable parameter filtering
4
+ * null and not_null predicates
5
+
6
+ == 0.1.0
7
+ * initial release
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # philtre [![Gem Version](https://badge.fury.io/rb/philtre.png)](http://badge.fury.io/rb/philtre) [![Build Status](https://travis-ci.org/djellemah/philtre.png?branch=master)](https://travis-ci.org/djellemah/philtre)
1
+ # philtre [![Gem Version](https://badge.fury.io/rb/philtre.svg)](http://badge.fury.io/rb/philtre) [![Build Status](https://travis-ci.org/djellemah/philtre.svg?branch=master)](https://travis-ci.org/djellemah/philtre)
2
2
 
3
3
  It's the [Sequel](http://sequel.jeremyevans.net) equivalent for Ransack, Metasearch, Searchlogic. If
4
4
  this doesn't make you fall in love, I don't know what will :-p
@@ -75,6 +75,8 @@ There are a range of predefined predicates, mostly borrowed from the other searc
75
75
  not_blank
76
76
  like_all
77
77
  like_any
78
+ null
79
+ not_null
78
80
  ```
79
81
 
80
82
  ## Custom Predicates
@@ -104,8 +106,8 @@ Now you can pass the filter_parameter hash ```{tagged_by_id: 45}```.
104
106
 
105
107
  The result of a predicate block should be a ```Sequel::SQL::Expression``` (ie
106
108
  one of Sequel's hash expressions in the simplest case) which will work instead
107
- of its named placeholder. That is, if the placeholder is inside a SELECT
108
- clause it worked work to give in an ORDER BY.
109
+ of its named placeholder. So for example, if the placeholder is inside a SELECT
110
+ clause it wouldn't work to give it an ORDER BY expression.
109
111
 
110
112
  2) You could also inherit from ```Philtre::Filter``` and override
111
113
  ```#predicates```. And optionally override ```Philtre.new``` (which is just a
@@ -163,7 +165,7 @@ is canonical in that all the other possibilities use it.
163
165
 
164
166
  ## Highly Advanced Usage
165
167
 
166
- Sometimes method chaining gets ugly. So you can say
168
+ Sometimes method chaining gets ugly. So you can install gem ripar, then you can say
167
169
 
168
170
  ``` ruby
169
171
  store_id_range = 20..90
@@ -174,9 +176,10 @@ Sometimes method chaining gets ugly. So you can say
174
176
  end
175
177
  ```
176
178
 
177
- Notice that values outside the block are accessible inside, _without_
178
- the need for a block parameter. This uses Ripar under the cover and indirects
179
- the binding lookup, so may result in errors that you won't expect.
179
+ Notice that values outside the block are accessible inside, _without_ the need
180
+ for a block parameter. This uses [Ripar](https://github.com/djellemah/ripar/)
181
+ under the cover and indirects the binding lookup, so may result in errors that
182
+ you won't expect.
180
183
 
181
184
  ## Specs
182
185
 
@@ -28,11 +28,12 @@ module Philtre
28
28
  def initialize( filter_parameters = nil, &custom_predicate_block )
29
29
  # This must be a new instance of Hash, because sometimes
30
30
  # HashWithIndifferentAccess is passed in, which breaks things in here.
31
+
31
32
  # Don't use symbolize_keys because that creates a dependency on ActiveSupport
33
+ # have to iterate anyway to convert keys to symbols
32
34
  @filter_parameters =
33
35
  if filter_parameters
34
- # preserve 2.0 compatibility
35
- filter_parameters.inject({}){|ha,(k,v)| ha[k.to_sym] = v; ha}
36
+ filter_parameters.each_with_object(Hash.new){|(k,v),ha| ha[k.to_sym] = v}
36
37
  else
37
38
  {}
38
39
  end
@@ -67,12 +68,22 @@ module Philtre
67
68
 
68
69
  alias apply call
69
70
 
71
+ # called by valued_parameters to generate the set of expressions. This
72
+ # returns true for a value that show up in the set of expressions, false
73
+ # otherwise.
74
+ #
75
+ # Intended to be overridden if necessary.
76
+ def valued_parameter?( key, value )
77
+ value.is_a?(Array) || !value.blank?
78
+ end
79
+
70
80
  # Values in the parameter list which are not blank, and not
71
81
  # an ordering. That is, parameters which will be used to generate
72
82
  # the filter expression.
73
83
  def valued_parameters
74
- filter_parameters.select do |key,value|
75
- key.to_sym != :order && (value.is_a?(Array) || !value.blank?)
84
+ @valued_parameters ||= filter_parameters.select do |key,value|
85
+ # :order is special, it must always be excluded
86
+ key.to_sym != :order && valued_parameter?(key,value)
76
87
  end
77
88
  end
78
89
 
@@ -164,6 +175,7 @@ module Philtre
164
175
  @order_expressions = nil
165
176
  @order_hash = nil
166
177
  @order_clause = nil
178
+ @valued_parameters = nil
167
179
  end
168
180
 
169
181
  def clone( extra_parameters = {} )
@@ -1,4 +1,8 @@
1
- require 'ripar'
1
+ begin
2
+ require 'ripar'
3
+ rescue LoadError
4
+ "silently move on cos it's not critical and we'll just not add those bits"
5
+ end
2
6
 
3
7
  require 'philtre/filter.rb'
4
8
  require 'philtre/place_holder.rb'
@@ -17,7 +17,7 @@ module Philtre
17
17
  # split suffix from the key and store the two values as name and op
18
18
  # return truthy if successful
19
19
  def split_key( suffix )
20
- rv = @key =~ /(.*?)_?(#{suffix})$/
20
+ rv = @key =~ /\A(?:(.*?)_)?(#{suffix})\z/
21
21
  @field, @op = $1, $2
22
22
  rv
23
23
  end
@@ -60,12 +60,15 @@ module Philtre
60
60
  alias [] call
61
61
 
62
62
  def predicate_names
63
- DefaultPredicates.instance_methods
63
+ # ruby-2.3 no longer stores methods in order of definition. So sort by
64
+ # longest so that we don't get false positives from shorter predicates
65
+ # that are substrings of longer predicates, eg blank matching
66
+ # thing_not_blank.
67
+ DefaultPredicates.instance_methods.sort_by{|name| -name.length}
64
68
  end
65
69
 
66
70
  # Define the set of default predicates.
67
71
  DefaultPredicates = PredicateDsl.new do
68
- # longer suffixes first, so they match first in define_name_predicate
69
72
  not_eq {|expr, val| ~Sequel.expr( expr => val) }
70
73
 
71
74
  def not_like( expr, val )
@@ -78,13 +81,15 @@ module Philtre
78
81
  Sequel.~(blank expr, val)
79
82
  end
80
83
 
84
+ null {|expr,_| Sequel.expr(expr => nil)}
85
+ not_null {|expr,_| Sequel.~(Sequel.expr(expr => nil))}
86
+
81
87
  def blank(expr, _)
82
88
  is_nil = Sequel.expr(expr => nil)
83
89
  is_empty = Sequel.expr(expr => '')
84
90
  Sequel.| is_nil, is_empty
85
91
  end
86
92
 
87
- # and now the shorter suffixes
88
93
  eq {|expr, val| Sequel.expr( expr => val) }
89
94
  gt {|expr, val| expr > val }
90
95
  gte( :gteq ) {|expr, val| expr >= val }
@@ -103,7 +108,7 @@ module Philtre
103
108
  end
104
109
  end
105
110
 
106
- # make the available to Predicates instances.
111
+ # make them available to Predicate instances.
107
112
  include DefaultPredicates
108
113
  end
109
114
  end
@@ -1,19 +1,21 @@
1
1
  # TODO docs for this
2
- class Sequel::Dataset
3
- include Ripar
2
+ if defined? Ripar
3
+ class Sequel::Dataset
4
+ include Ripar
4
5
 
5
- # make the roller understand dataset method
6
- def roller
7
- rv = super
8
- class << rv
9
- def to_dataset; riven end
6
+ # make the roller understand dataset method
7
+ def roller
8
+ rv = super
9
+ class << rv
10
+ def to_dataset; riven end
11
+ end
12
+ rv
10
13
  end
11
- rv
12
- end
13
14
 
14
- # roll the block and return the resulting dataset immediately
15
- def rolled( &blk )
16
- roller.rive &blk
15
+ # roll the block and return the resulting dataset immediately
16
+ def rolled( &blk )
17
+ roller.rive &blk
18
+ end
17
19
  end
18
20
  end
19
21
 
@@ -1,3 +1,3 @@
1
1
  module Philtre #:nodoc:
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -20,11 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency 'sequel'
22
22
  spec.add_dependency 'fastandand'
23
- spec.add_dependency 'ripar', '~> 0.0.3'
24
23
 
25
24
  spec.add_development_dependency 'bundler', '~> 1.5'
26
25
  spec.add_development_dependency 'rake'
27
26
  spec.add_development_dependency 'rspec'
28
27
  spec.add_development_dependency 'faker'
29
- spec.add_development_dependency 'sqlite3'
30
28
  end
@@ -1,6 +1,4 @@
1
- require 'rspec'
2
- require 'faker'
3
- require 'sequel'
1
+ require_relative 'spec_helper.rb'
4
2
 
5
3
  require_relative '../lib/philtre/grinder.rb'
6
4
  require_relative '../lib/philtre/sequel_extensions.rb'
@@ -29,29 +27,36 @@ describe Sequel::Dataset do
29
27
 
30
28
  it 'passes apply_unknown'
31
29
 
32
- describe '#roller' do
33
- it 'result has to_dataset' do
34
- rlr = subject.roller do
35
- where title: 'Exalted Fromaginess'
36
- end
30
+ describe 'fancy stuff' do
31
+
32
+ describe '#roller' do
33
+ it 'result has to_dataset' do
34
+ pending "Ripar optionally not loaded" unless defined? Ripar
35
+
36
+ rlr = subject.roller do
37
+ where title: 'Exalted Fromaginess'
38
+ end
37
39
 
38
- # This depends on Ripar, so it's a bit fragile
39
- rlr.should respond_to(:__class__)
40
- rlr.__class__.should == Ripar::Roller
40
+ # This depends on Ripar, so it's a bit fragile
41
+ rlr.should respond_to(:__class__)
42
+ rlr.__class__.should == Ripar::Roller
41
43
 
42
- rlr.should_not respond_to(:datset)
43
- rlr.should respond_to(:to_dataset)
44
+ rlr.should_not respond_to(:datset)
45
+ rlr.should respond_to(:to_dataset)
46
+ end
44
47
  end
45
- end
46
48
 
47
- describe '#rolled' do
48
- it 'gives back a rolled dataset' do
49
- rlr = subject.rolled do
50
- where title: 'Exalted Fromaginess'
49
+ describe '#rolled' do
50
+ it 'gives back a rolled dataset' do
51
+ pending "Ripar optionally not loaded" unless defined? Ripar
52
+
53
+ rlr = subject.rolled do
54
+ where title: 'Exalted Fromaginess'
55
+ end
56
+ rlr.should be_a(Sequel::Dataset)
57
+ rlr.should_not respond_to(:datset)
58
+ rlr.should_not respond_to(:to_dataset)
51
59
  end
52
- rlr.should be_a(Sequel::Dataset)
53
- rlr.should_not respond_to(:datset)
54
- rlr.should_not respond_to(:to_dataset)
55
60
  end
56
61
  end
57
62
  end
@@ -1,6 +1,4 @@
1
- require 'rspec'
2
- require 'faker'
3
-
1
+ require_relative 'spec_helper.rb'
4
2
  require_relative '../lib/philtre/filter.rb'
5
3
 
6
4
  # for blank?
@@ -114,7 +112,7 @@ describe Philtre::Filter do
114
112
  @dataset.order( *filter.order_clause ).sql.should =~ /order by things desc$/i
115
113
  end
116
114
 
117
- it 'respecs asc' do
115
+ it 'respects asc' do
118
116
  filter = described_class.new one: 1, two: 2, order: 'things_desc'
119
117
  @dataset.order( *filter.order_clause ).sql.should =~ /order by things desc$/i
120
118
  end
@@ -131,7 +129,7 @@ describe Philtre::Filter do
131
129
  end
132
130
 
133
131
  describe '#predicates' do
134
- EASY_PREDICATES = %i[gt gte gteq lt lte lteq eq not_eq matches like not_like]
132
+ EASY_PREDICATES = %i[gt gte gteq lt lte lteq eq not_eq matches like not_like not_null null]
135
133
  TRICKY_PREDICATES = %i[like_all like_any not_blank blank]
136
134
 
137
135
  it 'creates predicates' do
@@ -201,17 +199,34 @@ describe Philtre::Filter do
201
199
  end
202
200
 
203
201
  it 'not_blank' do
204
- field = Sequel.expr Faker::Lorem.word
202
+ field = Faker::Lorem.word
205
203
  expr = described_class.predicates.call :"#{field}_not_blank", Faker::Lorem.word
206
204
 
207
205
  expr.op.should == :AND
206
+ is_not_null, not_equals_empty = expr.args
208
207
 
209
208
  # the not-nil part
210
- expr.args.first.op.should == :'IS NOT'
209
+ is_not_null.op.should == :'IS NOT'
211
210
 
212
211
  # the not empty string part
213
- expr.args.last.op.should == :'!='
214
- expr.args.last.args.last.should == ''
212
+ not_equals_empty.op.should == :'!='
213
+ not_equals_empty.args.last.should == ''
214
+ end
215
+
216
+ it 'blank' do
217
+ field = Faker::Lorem.word
218
+ expr = described_class.predicates.call :"#{field}_blank", Faker::Lorem.word
219
+
220
+ expr.op.should == :OR
221
+
222
+ is_null, equals_empty = expr.args
223
+
224
+ # the null part
225
+ is_null.op.should == :'IS'
226
+
227
+ # the empty string part
228
+ equals_empty.op.should == :'='
229
+ equals_empty.args.last.should == ''
215
230
  end
216
231
  end
217
232
 
@@ -406,11 +421,21 @@ describe Philtre::Filter do
406
421
  sql.should =~ /select \* from planks where \(title = '\w+'\)$/i
407
422
  end
408
423
 
409
- it 'excludes nil values' do
424
+ it 'excludes nil values by default' do
410
425
  filter.filter_parameters[:name] = nil
411
426
  sql = filter.apply(@dataset).sql
412
427
  sql.should =~ /select \* from planks where \(title = '\w+'\)$/i
413
428
  end
429
+
430
+ it 'can customise value exclusion' do
431
+ def filter.valued_parameter?(key,value)
432
+ key != :order
433
+ end
434
+
435
+ filter.filter_parameters[:name] = nil
436
+ sql = filter.apply(@dataset).sql
437
+ sql.should =~ /SELECT \* FROM planks WHERE \(\(name IS NULL\) AND \(title = '\w+'\)\)/
438
+ end
414
439
  end
415
440
 
416
441
  describe '#empty?' do
@@ -1,7 +1,4 @@
1
- require 'rspec'
2
- require 'faker'
3
- require 'sequel'
4
- require 'ripar'
1
+ require_relative 'spec_helper.rb'
5
2
 
6
3
  require_relative '../lib/philtre.rb'
7
4
 
@@ -161,6 +158,8 @@ describe Philtre::Grinder do
161
158
  end
162
159
 
163
160
  it 'handles rollers' do
161
+ pending "Ripar optionally not loaded" unless defined? Ripar
162
+
164
163
  grinder = Philtre::Grinder.new Philtre::Filter.new(person_id: 212728)
165
164
  tds = ds.roller do
166
165
  where linkage: other_ds.where( :person_id.lieu )
@@ -172,9 +171,9 @@ describe Philtre::Grinder do
172
171
  end
173
172
 
174
173
  it 'handles Models' do
175
- Sequel::Model.db = Sequel.sqlite
174
+ Sequel::Model.db = Sequel.mock
176
175
  class Ods < Sequel::Model(:ods); end
177
176
  Philtre::Grinder.new( Philtre::Filter.new ).transform(Ods).should be_a(Sequel::Dataset)
178
- Philtre::Grinder.new( Philtre::Filter.new ).transform(Ods).sql.should =~ /SELECT \* FROM .ods./
177
+ Philtre::Grinder.new( Philtre::Filter.new ).transform(Ods).sql.should =~ /SELECT \* FROM ods/
179
178
  end
180
179
  end
@@ -1,7 +1,6 @@
1
- require 'rspec'
2
- require 'faker'
3
-
1
+ require_relative 'spec_helper.rb'
4
2
  require_relative '../lib/philtre/predicate_splitter.rb'
3
+ require_relative '../lib/philtre/predicates.rb'
5
4
 
6
5
  # for blank?
7
6
  Sequel.extension :blank
@@ -28,6 +27,7 @@ describe Philtre::PredicateSplitter do
28
27
 
29
28
  describe 'unsuccessful' do
30
29
  let(:splitter){ Philtre::PredicateSplitter.new 'birth_year', 'fifteeen' }
30
+
31
31
  it 'returns false' do
32
32
  splitter.split_key( :like ).should be_falsey
33
33
  end
@@ -44,11 +44,31 @@ describe Philtre::PredicateSplitter do
44
44
  end
45
45
 
46
46
  describe 'custom predicate' do
47
- let(:splitter){ Philtre::PredicateSplitter.new( 'custom_predicate', 'fifteeen' ) }
48
- it 'accepts the whole thing' do
47
+ it 'accepts the whole thing, undeterred by _' do
48
+ splitter = Philtre::PredicateSplitter.new 'custom_predicate', 'fifteeen'
49
49
  (splitter === :custom_predicate).should === 0
50
50
  end
51
51
  end
52
+
53
+ describe "'ware the false matches, laddie" do
54
+ Philtre::Predicates::DefaultPredicates.instance_methods.each do |suffix|
55
+ word = Faker::Lorem.words(rand(1..3)) * '_'
56
+
57
+ let(:suffix){suffix}
58
+ let(:word){word}
59
+
60
+ it "#{word}#{suffix} unsplit" do
61
+ splitter = Philtre::PredicateSplitter.new "#{word}#{suffix}", 'blabla'
62
+ splitter.split_key(suffix).should be_falsey
63
+ end
64
+
65
+ it "#{word}_#{suffix} split" do
66
+ splitter = Philtre::PredicateSplitter.new "#{word}_#{suffix}", 'unbla'
67
+ splitter.split_key suffix
68
+ splitter.field.should == word.to_sym
69
+ end
70
+ end
71
+ end
52
72
  end
53
73
  end
54
74
 
@@ -0,0 +1,14 @@
1
+ require 'rspec'
2
+ require 'faker'
3
+ require 'sequel'
4
+
5
+ # turn off the "old syntax" warnings
6
+ RSpec.configure do |config|
7
+ config.mock_with :rspec do |c|
8
+ c.syntax = [:should, :expect]
9
+ end
10
+
11
+ config.expect_with :rspec do |c|
12
+ c.syntax = [:should, :expect]
13
+ end
14
+ end
@@ -3,7 +3,7 @@ task :console do
3
3
  ARGV.shift()
4
4
  ENV['RUBYLIB'] ||= ''
5
5
  ENV['RUBYLIB'] += ":#{File.expand_path('.')}/lib/philtre"
6
- exec "pry -r philtre -I ./lib -I ."
6
+ exec "pry -r sequel -r philtre -I ./lib -I ."
7
7
  end
8
8
 
9
9
  task :pry => :console
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philtre
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Anderson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-18 00:00:00.000000000 Z
11
+ date: 2016-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: ripar
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.0.3
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.0.3
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: bundler
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,20 +94,6 @@ dependencies:
108
94
  - - ">="
109
95
  - !ruby/object:Gem::Version
110
96
  version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: sqlite3
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
97
  description: Encode various filtering operations in http parameter hashes
126
98
  email:
127
99
  - panic@semiosix.com
@@ -131,7 +103,9 @@ extra_rdoc_files: []
131
103
  files:
132
104
  - ".gitignore"
133
105
  - ".travis.yml"
106
+ - AUTHORS
134
107
  - Gemfile
108
+ - History.txt
135
109
  - LICENSE.txt
136
110
  - README.md
137
111
  - Rakefile
@@ -152,6 +126,7 @@ files:
152
126
  - spec/filter_spec.rb
153
127
  - spec/grinder_spec.rb
154
128
  - spec/predicate_splitter_spec.rb
129
+ - spec/spec_helper.rb
155
130
  - tasks/console.rake
156
131
  homepage: http://github.com/djellemah/philtre
157
132
  licenses:
@@ -173,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
148
  version: '0'
174
149
  requirements: []
175
150
  rubyforge_project:
176
- rubygems_version: 2.2.2
151
+ rubygems_version: 2.5.1
177
152
  signing_key:
178
153
  specification_version: 4
179
154
  summary: http parameter-hash friendly filtering for Sequel
@@ -182,3 +157,4 @@ test_files:
182
157
  - spec/filter_spec.rb
183
158
  - spec/grinder_spec.rb
184
159
  - spec/predicate_splitter_spec.rb
160
+ - spec/spec_helper.rb