predicate 2.8.0 → 2.9.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -0
  3. data/lib/predicate/asserter.rb +1 -1
  4. data/lib/predicate/nodes/and.rb +22 -4
  5. data/lib/predicate/nodes/empty.rb +6 -0
  6. data/lib/predicate/nodes/eq.rb +4 -0
  7. data/lib/predicate/nodes/expr.rb +4 -0
  8. data/lib/predicate/nodes/gt.rb +6 -0
  9. data/lib/predicate/nodes/gte.rb +6 -0
  10. data/lib/predicate/nodes/in.rb +12 -0
  11. data/lib/predicate/nodes/lt.rb +6 -0
  12. data/lib/predicate/nodes/lte.rb +6 -0
  13. data/lib/predicate/nodes/neq.rb +11 -0
  14. data/lib/predicate/nodes/tautology.rb +4 -0
  15. data/lib/predicate/version.rb +1 -1
  16. data/lib/predicate.rb +16 -2
  17. data/spec/factory/shared/a_comparison_factory_method.rb +12 -4
  18. data/spec/factory/shared/a_predicate_ast_node.rb +11 -5
  19. data/spec/factory/test_${op_name}.rb.jeny +3 -1
  20. data/spec/factory/test_and.rb +6 -2
  21. data/spec/factory/test_comp.rb +27 -9
  22. data/spec/factory/test_contradiction.rb +3 -1
  23. data/spec/factory/test_empty.rb +3 -1
  24. data/spec/factory/test_factor_predicate.rb +21 -7
  25. data/spec/factory/test_from_hash.rb +21 -7
  26. data/spec/factory/test_has_size.rb +3 -1
  27. data/spec/factory/test_identifier.rb +6 -2
  28. data/spec/factory/test_literal.rb +6 -2
  29. data/spec/factory/test_match.rb +12 -4
  30. data/spec/factory/test_native.rb +6 -2
  31. data/spec/factory/test_not.rb +6 -2
  32. data/spec/factory/test_or.rb +6 -2
  33. data/spec/factory/test_qualified_identifier.rb +6 -2
  34. data/spec/factory/test_set_ops.rb +6 -2
  35. data/spec/factory/test_tautology.rb +3 -1
  36. data/spec/factory/test_var.rb +12 -4
  37. data/spec/grammar/test_match.rb +19 -19
  38. data/spec/grammar/test_sexpr.rb +49 -17
  39. data/spec/nodes/and/test_and_split.rb +30 -10
  40. data/spec/nodes/dyadic_comp/test_and_split.rb +18 -8
  41. data/spec/nodes/eq/test_and.rb +12 -4
  42. data/spec/nodes/identifier/test_and_split.rb +6 -2
  43. data/spec/nodes/identifier/test_free_variables.rb +3 -1
  44. data/spec/nodes/identifier/test_name.rb +3 -1
  45. data/spec/nodes/in/test_and.rb +18 -6
  46. data/spec/nodes/nadic_bool/test_free_variables.rb +3 -1
  47. data/spec/nodes/or/test_and_split.rb +6 -2
  48. data/spec/nodes/qualified_identifier/test_and_split.rb +6 -2
  49. data/spec/nodes/qualified_identifier/test_free_variables.rb +3 -1
  50. data/spec/nodes/qualified_identifier/test_name.rb +3 -1
  51. data/spec/nodes/qualified_identifier/test_qualifier.rb +3 -1
  52. data/spec/predicate/test_and_split.rb +48 -16
  53. data/spec/predicate/test_assert!.rb +210 -0
  54. data/spec/predicate/test_attr_split.rb +36 -12
  55. data/spec/predicate/test_bool_and.rb +7 -3
  56. data/spec/predicate/test_bool_not.rb +30 -10
  57. data/spec/predicate/test_bool_or.rb +7 -3
  58. data/spec/predicate/test_coerce.rb +19 -17
  59. data/spec/predicate/test_constants.rb +78 -26
  60. data/spec/predicate/test_free_variables.rb +3 -1
  61. data/spec/predicate/test_hash_and_equal.rb +7 -3
  62. data/spec/predicate/test_qualify.rb +8 -6
  63. data/spec/predicate/test_rename.rb +21 -11
  64. data/spec/sequel/test_to_sequel.rb +0 -1
  65. data/spec/shared/a_predicate.rb +8 -8
  66. data/spec/spec_helper.rb +1 -0
  67. data/spec/test_readme.rb +1 -1
  68. metadata +5 -5
@@ -7,39 +7,41 @@ class Predicate
7
7
  describe "from Predicate" do
8
8
  let(:arg){ Predicate.new(Factory.tautology) }
9
9
 
10
- it{ should be(arg) }
10
+ it {
11
+ expect(subject).to be(arg)
12
+ }
11
13
  end
12
14
 
13
15
  describe "from true" do
14
16
  let(:arg){ true }
15
17
 
16
- specify{
17
- subject.expr.should be_a(Tautology)
18
+ specify {
19
+ expect(subject.expr).to be_a(Tautology)
18
20
  }
19
21
  end
20
22
 
21
23
  describe "from false" do
22
24
  let(:arg){ false }
23
25
 
24
- specify{
25
- subject.expr.should be_a(Contradiction)
26
+ specify {
27
+ expect(subject.expr).to be_a(Contradiction)
26
28
  }
27
29
  end
28
30
 
29
31
  describe "from Symbol" do
30
32
  let(:arg){ :status }
31
33
 
32
- specify{
33
- subject.expr.should be_a(Identifier)
34
- subject.expr.name.should eq(arg)
34
+ specify {
35
+ expect(subject.expr).to be_a(Identifier)
36
+ expect(subject.expr.name).to eq(arg)
35
37
  }
36
38
  end
37
39
 
38
40
  describe "from Proc" do
39
41
  let(:arg){ lambda{ status == 10 } }
40
42
 
41
- specify{
42
- subject.expr.should be_a(Native)
43
+ specify {
44
+ expect(subject.expr).to be_a(Native)
43
45
  }
44
46
  end
45
47
 
@@ -47,25 +49,25 @@ class Predicate
47
49
  let(:arg){ "status == 10" }
48
50
 
49
51
  it 'raises an error' do
50
- lambda{
52
+ expect{
51
53
  subject
52
- }.should raise_error(ArgumentError)
54
+ }.to raise_error(ArgumentError)
53
55
  end
54
56
  end
55
57
 
56
58
  describe "from Hash (single)" do
57
59
  let(:arg){ {status: 10} }
58
60
 
59
- specify{
60
- subject.expr.should be_a(Eq)
61
- subject.expr.should eq([:eq, [:identifier, :status], [:literal, 10]])
61
+ specify {
62
+ expect(subject.expr).to be_a(Eq)
63
+ expect(subject.expr).to eq([:eq, [:identifier, :status], [:literal, 10]])
62
64
  }
63
65
  end
64
66
 
65
67
  describe "from Hash (multiple)" do
66
68
  let(:arg){ {status: 10, name: "Jones"} }
67
69
 
68
- specify{
70
+ specify {
69
71
  expect(subject).to eq(Predicate.eq(status: 10) & Predicate.eq(name: "Jones"))
70
72
  }
71
73
  end
@@ -73,7 +75,7 @@ class Predicate
73
75
  describe "from Hash (in)" do
74
76
  let(:arg){ {status: [10, 15]} }
75
77
 
76
- specify{
78
+ specify {
77
79
  expect(subject).to eq(Predicate.in(:status, [10,15]))
78
80
  }
79
81
  end
@@ -8,157 +8,209 @@ class Predicate
8
8
  context "on tautology" do
9
9
  let(:pred){ p.tautology }
10
10
 
11
- it{ should eq({}) }
11
+ it {
12
+ expect(subject).to eq({})
13
+ }
12
14
  end
13
15
 
14
16
  context "on contradiction" do
15
17
  let(:pred){ p.contradiction }
16
18
 
17
- it{ should eq({}) }
19
+ it {
20
+ expect(subject).to eq({})
21
+ }
18
22
  end
19
23
 
20
24
  context "on eq(identifier,value)" do
21
25
  let(:pred){ p.eq(:x, 2) }
22
26
 
23
- it{ should eq({x: 2}) }
27
+ it {
28
+ expect(subject).to eq({x: 2})
29
+ }
24
30
  end
25
31
 
26
32
  context "on eq(identifier,placeholder)" do
27
33
  let(:pred){ p.eq(:x, p.placeholder) }
28
34
 
29
- it{ should eq({}) }
35
+ it {
36
+ expect(subject).to eq({})
37
+ }
30
38
  end
31
39
 
32
40
  context "on eq(value,identifier)" do
33
41
  let(:pred){ p.eq(2, :x) }
34
42
 
35
- it{ should eq({x: 2}) }
43
+ it {
44
+ expect(subject).to eq({x: 2})
45
+ }
36
46
  end
37
47
 
38
48
  context "on eq(identifier,identifier)" do
39
49
  let(:pred){ p.eq(:x, :y) }
40
50
 
41
- it{ should eq({}) }
51
+ it {
52
+ expect(subject).to eq({})
53
+ }
42
54
  end
43
55
 
44
56
  context "on not" do
45
57
  let(:pred){ !p.eq(:x, 2) }
46
58
 
47
- it{ should eq({}) }
59
+ it {
60
+ expect(subject).to eq({})
61
+ }
48
62
  end
49
63
 
50
64
  context "on neq" do
51
65
  let(:pred){ p.neq(:x, 2) }
52
66
 
53
- it{ should eq({}) }
67
+ it {
68
+ expect(subject).to eq({})
69
+ }
54
70
  end
55
71
 
56
72
  context "on gt" do
57
73
  let(:pred){ p.gt(:x, 2) }
58
74
 
59
- it{ should eq({}) }
75
+ it {
76
+ expect(subject).to eq({})
77
+ }
60
78
  end
61
79
 
62
80
  context "on in (singleton)" do
63
81
  let(:pred){ p.in(:x, [2]) }
64
82
 
65
- it{ should eq({x: 2}) }
83
+ it {
84
+ expect(subject).to eq({x: 2})
85
+ }
66
86
  end
67
87
 
68
88
  context "on in (multiples)" do
69
89
  let(:pred){ p.in(:x, [2, 3]) }
70
90
 
71
- it{ should eq({}) }
91
+ it {
92
+ expect(subject).to eq({})
93
+ }
72
94
  end
73
95
 
74
96
  context "on in (opaque)" do
75
97
  let(:pred){ p.in(:x, p.opaque([2])) }
76
98
 
77
- it{ should eq({}) }
99
+ it {
100
+ expect(subject).to eq({})
101
+ }
78
102
  end
79
103
 
80
104
  context "on and (two eqs)" do
81
105
  let(:pred){ p.eq(:x, 2) & p.eq(:y, 4) }
82
106
 
83
- it{ should eq({x: 2, y: 4}) }
107
+ it {
108
+ expect(subject).to eq({x: 2, y: 4})
109
+ }
84
110
  end
85
111
 
86
112
  context "on and (one eq)" do
87
113
  let(:pred){ p.eq(:x, 2) & p.in(:y, [4,8]) }
88
114
 
89
- it{ should eq({x: 2}) }
115
+ it {
116
+ expect(subject).to eq({x: 2})
117
+ }
90
118
  end
91
119
 
92
120
  context "on and (one eq, one in, same variable)" do
93
121
  let(:pred){ p.in(:x, [2,8]) & p.eq(:x, 2) }
94
122
 
95
- it{ should eq({x: 2}) }
123
+ it {
124
+ expect(subject).to eq({x: 2})
125
+ }
96
126
  end
97
127
 
98
128
  context "on and (one eq, one in, yielding contradiction)" do
99
129
  let(:pred){ p.in(:x, [3,8]) & p.eq(:x, 2) }
100
130
 
101
- it{ should eq({}) }
131
+ it {
132
+ expect(subject).to eq({})
133
+ }
102
134
  end
103
135
 
104
136
  context "on and (contradiction)" do
105
137
  let(:pred){ p.eq(:x, 2) & p.eq(:x, 4) }
106
138
 
107
- it{ should eq({}) }
139
+ it {
140
+ expect(subject).to eq({})
141
+ }
108
142
  end
109
143
 
110
144
  context "on intersect" do
111
145
  let(:pred){ p.intersect(:x, [4,8]) }
112
146
 
113
- it{ should eq({}) }
147
+ it {
148
+ expect(subject).to eq({})
149
+ }
114
150
  end
115
151
 
116
152
  context "on intersect with placeholder" do
117
153
  let(:pred){ p.intersect(:x, p.placeholder) }
118
154
 
119
- it{ should eq({}) }
155
+ it {
156
+ expect(subject).to eq({})
157
+ }
120
158
  end
121
159
 
122
160
  context "on subset" do
123
161
  let(:pred){ p.subset(:x, [4,8]) }
124
162
 
125
- it{ should eq({}) }
163
+ it {
164
+ expect(subject).to eq({})
165
+ }
126
166
  end
127
167
 
128
168
  context "on subset with placeholder" do
129
169
  let(:pred){ p.subset(:x, p.placeholder) }
130
170
 
131
- it{ should eq({}) }
171
+ it {
172
+ expect(subject).to eq({})
173
+ }
132
174
  end
133
175
 
134
176
  context "on superset" do
135
177
  let(:pred){ p.superset(:x, [4,8]) }
136
178
 
137
- it{ should eq({}) }
179
+ it {
180
+ expect(subject).to eq({})
181
+ }
138
182
  end
139
183
 
140
184
  context "on superset with placeholder" do
141
185
  let(:pred){ p.superset(:x, p.placeholder) }
142
186
 
143
- it{ should eq({}) }
187
+ it {
188
+ expect(subject).to eq({})
189
+ }
144
190
  end
145
191
 
146
192
  context "on or (two eqs)" do
147
193
  let(:pred){ p.eq(:x, 2) | p.eq(:y, 4) }
148
194
 
149
- it{ should eq({}) }
195
+ it {
196
+ expect(subject).to eq({})
197
+ }
150
198
  end
151
199
 
152
200
  context "on match" do
153
201
  let(:pred){ p.match(:x, "London") }
154
202
 
155
- it{ should eq({}) }
203
+ it {
204
+ expect(subject).to eq({})
205
+ }
156
206
  end
157
207
 
158
208
  context "on native" do
159
209
  let(:pred){ p.native(->(t){}) }
160
210
 
161
- it{ should eq({}) }
211
+ it {
212
+ expect(subject).to eq({})
213
+ }
162
214
  end
163
215
 
164
216
  end
@@ -7,7 +7,9 @@ class Predicate
7
7
  describe "on a comp(:eq)" do
8
8
  let(:p){ Predicate.coerce(:x => 2) }
9
9
 
10
- it{ should eq([:x]) }
10
+ it {
11
+ expect(subject).to eq([:x])
12
+ }
11
13
  end
12
14
 
13
15
  end
@@ -5,21 +5,25 @@ class Predicate
5
5
  subject{ left == right }
6
6
 
7
7
  after do
8
- left.hash.should eq(right.hash) if subject
8
+ expect(left.hash).to eq(right.hash) if subject
9
9
  end
10
10
 
11
11
  describe "on equal predicates" do
12
12
  let(:left) { Predicate.coerce(:x => 2) }
13
13
  let(:right){ Predicate.coerce(:x => 2) }
14
14
 
15
- it{ should be(true) }
15
+ it {
16
+ expect(subject).to be(true)
17
+ }
16
18
  end
17
19
 
18
20
  describe "on non equal predicates" do
19
21
  let(:left) { Predicate.coerce(:x => 2) }
20
22
  let(:right){ Predicate.coerce(:x => 3) }
21
23
 
22
- it{ should be(false) }
24
+ it {
25
+ expect(subject).to be(false)
26
+ }
23
27
  end
24
28
 
25
29
  end
@@ -24,12 +24,14 @@ class Predicate
24
24
  context 'on a full AST predicate' do
25
25
  let(:predicate){ p.in(:x, [2]) & p.eq(:y, 3) }
26
26
 
27
- it{ should eq(p.in(Factory.qualified_identifier(:t, :x), [2]) & p.eq(:y, 3)) }
27
+ it {
28
+ expect(subject).to eq(p.in(Factory.qualified_identifier(:t, :x), [2]) & p.eq(:y, 3))
29
+ }
28
30
 
29
31
  specify "it should tag expressions correctly" do
30
- subject.expr.should be_a(Sexpr)
31
- subject.expr.should be_a(Expr)
32
- subject.expr.should be_a(And)
32
+ expect(subject.expr).to be_a(Sexpr)
33
+ expect(subject.expr).to be_a(Expr)
34
+ expect(subject.expr).to be_a(And)
33
35
  end
34
36
  end
35
37
 
@@ -37,9 +39,9 @@ class Predicate
37
39
  let(:predicate){ p.in(:x, [2]) & p.native(lambda{}) }
38
40
 
39
41
  it 'raises an error' do
40
- lambda{
42
+ expect{
41
43
  subject
42
- }.should raise_error(NotSupportedError)
44
+ }.to raise_error(NotSupportedError)
43
45
  end
44
46
  end
45
47
  end
@@ -12,12 +12,14 @@ class Predicate
12
12
  context 'on a full AST predicate' do
13
13
  let(:predicate){ p.in(:x, [2]) & p.eq(:y, 3) }
14
14
 
15
- it{ should eq(p.in(:z, [2]) & p.eq(:y, 3)) }
15
+ it {
16
+ expect(subject).to eq(p.in(:z, [2]) & p.eq(:y, 3))
17
+ }
16
18
 
17
19
  specify "it should tag expressions correctly" do
18
- subject.expr.should be_a(Sexpr)
19
- subject.expr.should be_a(Expr)
20
- subject.expr.should be_a(And)
20
+ expect(subject.expr).to be_a(Sexpr)
21
+ expect(subject.expr).to be_a(Expr)
22
+ expect(subject.expr).to be_a(And)
21
23
  end
22
24
  end
23
25
 
@@ -25,9 +27,9 @@ class Predicate
25
27
  let(:predicate){ p.in(:x, [2]) & p.native(lambda{}) }
26
28
 
27
29
  it 'raises an error' do
28
- lambda{
30
+ expect{
29
31
  subject
30
- }.should raise_error(NotSupportedError)
32
+ }.to raise_error(NotSupportedError)
31
33
  end
32
34
  end
33
35
 
@@ -35,7 +37,7 @@ class Predicate
35
37
  let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 3) }
36
38
 
37
39
  it 'renames correctly' do
38
- subject.should eq(p.eq(Factory.qualified_identifier(:t, :z), 3))
40
+ expect(subject).to eq(p.eq(Factory.qualified_identifier(:t, :z), 3))
39
41
  end
40
42
  end
41
43
  end
@@ -46,13 +48,17 @@ class Predicate
46
48
  context "on an identifier" do
47
49
  let(:predicate){ p.eq(:x, 2) }
48
50
 
49
- it{ should eq(p.eq(:y, 2)) }
51
+ it {
52
+ expect(subject).to eq(p.eq(:y, 2))
53
+ }
50
54
  end
51
55
 
52
56
  context "on a qualifier identifier" do
53
57
  let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 2) }
54
58
 
55
- it{ should eq(p.eq(:y, 2)) }
59
+ it {
60
+ expect(subject).to eq(p.eq(:y, 2))
61
+ }
56
62
  end
57
63
  end
58
64
 
@@ -62,13 +68,17 @@ class Predicate
62
68
  context 'on an identifier' do
63
69
  let(:predicate){ p.eq(:x, 2) }
64
70
 
65
- it{ should eq(p.eq(Factory.qualified_identifier(:t, :y), 2)) }
71
+ it {
72
+ expect(subject).to eq(p.eq(Factory.qualified_identifier(:t, :y), 2))
73
+ }
66
74
  end
67
75
 
68
76
  context 'on a qualified' do
69
77
  let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 2) }
70
78
 
71
- it{ should eq(p.eq(Factory.qualified_identifier(:t, :y), 2)) }
79
+ it {
80
+ expect(subject).to eq(p.eq(Factory.qualified_identifier(:t, :y), 2))
81
+ }
72
82
  end
73
83
  end
74
84
 
@@ -136,7 +136,6 @@ class Predicate
136
136
  let(:predicate) { Predicate.eq(:name, "Bob") & Predicate.eq(:price, 10.0) & Predicate.eq(:city, "London") }
137
137
 
138
138
  it 'works as expected' do
139
- puts predicate.sexpr.inspect
140
139
  expect(subject).to eql("SELECT * FROM `items` WHERE ((`name` = 'Bob') AND (`price` = 10.0) AND (`city` = 'London'))")
141
140
  end
142
141
  end
@@ -5,30 +5,30 @@ shared_examples_for "a predicate" do
5
5
  let(:y){ 13 }
6
6
 
7
7
  it 'is a Predicate' do
8
- subject.should be_a(Predicate)
8
+ expect(subject).to be_a(Predicate)
9
9
  end
10
10
 
11
11
  it 'can be negated easily' do
12
- (!subject).should be_a(Predicate)
12
+ expect(!subject).to be_a(Predicate)
13
13
  end
14
14
 
15
15
  it 'detects stupid AND' do
16
- (subject & Predicate.tautology).should be(subject)
16
+ expect(subject & Predicate.tautology).to be(subject)
17
17
  end
18
18
 
19
19
  it 'detects stupid OR' do
20
- (subject | Predicate.contradiction).should be(subject)
20
+ expect(subject | Predicate.contradiction).to be(subject)
21
21
  end
22
22
 
23
23
  it 'has free variables' do
24
- (fv = subject.free_variables).should be_a(Array)
25
- (fv - [ :w, :x, :y ]).should be_empty
24
+ expect(fv = subject.free_variables).to be_a(Array)
25
+ expect(fv - [ :w, :x, :y ]).to be_empty
26
26
  end
27
27
 
28
28
  it 'always splits around and trivially when no free variables are touched' do
29
29
  top, down = subject.and_split([:z])
30
- top.should be_tautology
31
- down.should eq(subject)
30
+ expect(top).to be_tautology
31
+ expect(down).to eq(subject)
32
32
  end
33
33
 
34
34
  end
data/spec/spec_helper.rb CHANGED
@@ -26,4 +26,5 @@ end
26
26
  RSpec.configure do |c|
27
27
  c.include Helpers
28
28
  c.extend Helpers
29
+ c.raise_errors_for_deprecations!
29
30
  end
data/spec/test_readme.rb CHANGED
@@ -49,7 +49,7 @@ describe "README" do
49
49
  { name: "Candy", price: 6 },
50
50
  { name: "Crush", price: 4 }
51
51
  ]
52
- })).to eql(true)
52
+ })).to eql(true)
53
53
  end
54
54
 
55
55
  it 'has a correct sixth example' do
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.8.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-09 00:00:00.000000000 Z
11
+ date: 2025-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sexpr
@@ -265,7 +265,7 @@ homepage: http://github.com/enspirit/predicate
265
265
  licenses:
266
266
  - MIT
267
267
  metadata: {}
268
- post_install_message:
268
+ post_install_message:
269
269
  rdoc_options: []
270
270
  require_paths:
271
271
  - lib
@@ -281,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
281
  version: '0'
282
282
  requirements: []
283
283
  rubygems_version: 3.1.6
284
- signing_key:
284
+ signing_key:
285
285
  specification_version: 4
286
286
  summary: Predicate provides a simple class and processors to encode and manipulate
287
287
  (tuple) predicates