predicate 2.5.0 → 2.6.0

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
  SHA256:
3
- metadata.gz: 4bd1cc5bc76250463f8dd68f07852df3838d8e9e553da27b188a87d968f83e5d
4
- data.tar.gz: eab52fff1970e5a74f21170e6486ec8082065be352053206b819fec2a2da3075
3
+ metadata.gz: 4d0149b8d39635ed0f27c39362d1c4aec0dc5f2ccc1290580ed67edf18414e5b
4
+ data.tar.gz: a623594513754521196f1a98f5d2f682650a3ec1b02b02b4dfa703600039faa1
5
5
  SHA512:
6
- metadata.gz: b3b4f2354d525a6c7a80de4fe6edba8459270ab34a2a5f15e17f233d485761b2c8e2f4c86c93349b2ffc06380cd37a4621da0df6ffa14672d1b43fa24ae9f428
7
- data.tar.gz: af95ddb5a971f2f7631046ed59e05982a5ff5309cbb1ac1a892c949ac9ed7305f4188f40616efce485978854561a756b3a722c0db192abb0b42e925beed42834
6
+ metadata.gz: dfc8fdb19e1d61171a4c91e893bfc6b6b91d559d8402f3a47dbede8d09dcb2f702f697cbd9e8b6db688e896d1831f837ace44d8c78b8c0e110d767ac0f99db05
7
+ data.tar.gz: 21ffbda2c7831051ac8ffba6a5c84d029735ce953e3fc969ae252945b0417ea28bc05f865e0e4e29771b542ca2993ec3720389a7be012b96b378536fb0743602
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Predicate
2
2
 
3
+ ![](https://travis-ci.com/enspirit/predicate.svg?branch=master)
4
+
3
5
  Boolean (truth-value) expressions that can be evaluated, manipulated,
4
6
  optimized, translated to code, etc.
5
7
 
@@ -160,6 +160,14 @@ class Predicate
160
160
 
161
161
  public # Low-level
162
162
 
163
+ # Factors a predicate from a mapping between variables
164
+ # and values. This typically generates a AND(EQ)
165
+ # predicate, but a value can be an Array (IN) or a
166
+ # Regexp (MATCH).
167
+ def h(h)
168
+ from_hash(h, :eq)
169
+ end
170
+
163
171
  # Factors a predicate for a ruby Proc that returns
164
172
  # truth-value for a single argument.
165
173
  def native(arg)
@@ -182,10 +190,10 @@ class Predicate
182
190
  tautology
183
191
  else
184
192
  terms = h.to_a.map{|(k,v)|
185
- if v.is_a?(Array)
186
- [:in, sexpr(k), sexpr(v)]
187
- else
188
- [op, sexpr(k), sexpr(v)]
193
+ case v
194
+ when Array then [:in, sexpr(k), sexpr(v)]
195
+ when Regexp then [:match, sexpr(k), sexpr(v) ]
196
+ else [op, sexpr(k), sexpr(v)]
189
197
  end
190
198
  }
191
199
  terms = terms.size == 1 ? terms.first : terms.unshift(:and)
@@ -1,7 +1,7 @@
1
1
  class Predicate
2
2
  module Version
3
3
  MAJOR = 2
4
- MINOR = 5
4
+ MINOR = 6
5
5
  TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
@@ -10,7 +10,15 @@ class Predicate
10
10
  it{ should eq(Factory.tautology) }
11
11
  end
12
12
 
13
- context "when the hash is singleton" do
13
+ context "when the hash is a singelton" do
14
+ let(:h){ {:x => 12} }
15
+
16
+ it_should_behave_like "a predicate AST node"
17
+ it{ should be_a(Eq) }
18
+ it{ should eq([:eq, [:identifier, :x], [:literal, 12]]) }
19
+ end
20
+
21
+ context "when the hash is not singleton" do
14
22
  let(:h){ {:x => 12, :y => :z} }
15
23
  let(:expected){
16
24
  [:and,
@@ -23,12 +31,27 @@ class Predicate
23
31
  it{ should eq(expected) }
24
32
  end
25
33
 
26
- context "when the hash is not singelton" do
27
- let(:h){ {:x => 12} }
34
+ context "when the value is a Regexp" do
35
+ let(:rx){ /[a-z]+/ }
36
+ let(:h){ {:x => /[a-z]+/} }
28
37
 
29
38
  it_should_behave_like "a predicate AST node"
30
- it{ should be_a(Eq) }
31
- it{ should eq([:eq, [:identifier, :x], [:literal, 12]]) }
39
+ it{ should be_a(Match) }
40
+ it{ should eq([:match, [:identifier, :x], [:literal, rx]]) }
41
+ end
42
+
43
+ context "when the hash mixes value types" do
44
+ let(:rx){ /[a-z]+/ }
45
+ let(:h){ {:x => 12, :y => rx} }
46
+ let(:expected){
47
+ [:and,
48
+ [:eq, [:identifier, :x], [:literal, 12]],
49
+ [:match, [:identifier, :y], [:literal, rx]]]
50
+ }
51
+
52
+ it_should_behave_like "a predicate AST node"
53
+ it{ should be_a(And) }
54
+ it{ should eq(expected) }
32
55
  end
33
56
 
34
57
  end
@@ -140,6 +140,15 @@ class Predicate
140
140
  end
141
141
  end
142
142
 
143
+ context 'nary and' do
144
+ let(:predicate) { Predicate.eq(:name, "Bob") & Predicate.eq(:price, 10.0) & Predicate.eq(:city, "London") }
145
+
146
+ it 'works as expected' do
147
+ puts predicate.sexpr.inspect
148
+ expect(subject).to eql("SELECT * FROM `items` WHERE ((`name` = 'Bob') AND (`price` = 10.0) AND (`city` = 'London'))")
149
+ end
150
+ end
151
+
143
152
  context 'or' do
144
153
  let(:predicate) { Predicate.eq(:name, "Bob") | Predicate.lt(:price, 10.0) }
145
154
 
@@ -18,6 +18,16 @@ describe "Predicate.comp" do
18
18
  it_should_behave_like "a predicate"
19
19
  end
20
20
 
21
+ describe "Predicate.h" do
22
+ subject{ Predicate.h(:x => 2) }
23
+
24
+ it_should_behave_like "a predicate"
25
+
26
+ it 'should be a eq on x' do
27
+ expect(subject).to eql(Predicate.eq(:x => 2))
28
+ end
29
+ end
30
+
21
31
  describe "Predicate.in, with a list" do
22
32
  subject{ Predicate.in(:x, [2, 3]) }
23
33
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: predicate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-30 00:00:00.000000000 Z
11
+ date: 2021-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sexpr
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.0
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.6.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement