predicate 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE.md +22 -0
  4. data/Rakefile +11 -0
  5. data/lib/predicate/factory.rb +107 -0
  6. data/lib/predicate/grammar.rb +33 -0
  7. data/lib/predicate/grammar.sexp.yml +58 -0
  8. data/lib/predicate/nodes/and.rb +23 -0
  9. data/lib/predicate/nodes/contradiction.rb +34 -0
  10. data/lib/predicate/nodes/dyadic_comp.rb +26 -0
  11. data/lib/predicate/nodes/eq.rb +15 -0
  12. data/lib/predicate/nodes/expr.rb +68 -0
  13. data/lib/predicate/nodes/gt.rb +10 -0
  14. data/lib/predicate/nodes/gte.rb +10 -0
  15. data/lib/predicate/nodes/identifier.rb +18 -0
  16. data/lib/predicate/nodes/in.rb +26 -0
  17. data/lib/predicate/nodes/literal.rb +18 -0
  18. data/lib/predicate/nodes/lt.rb +10 -0
  19. data/lib/predicate/nodes/lte.rb +10 -0
  20. data/lib/predicate/nodes/nadic_bool.rb +16 -0
  21. data/lib/predicate/nodes/native.rb +30 -0
  22. data/lib/predicate/nodes/neq.rb +10 -0
  23. data/lib/predicate/nodes/not.rb +22 -0
  24. data/lib/predicate/nodes/or.rb +10 -0
  25. data/lib/predicate/nodes/qualified_identifier.rb +22 -0
  26. data/lib/predicate/nodes/tautology.rb +30 -0
  27. data/lib/predicate/processors/qualifier.rb +23 -0
  28. data/lib/predicate/processors/renamer.rb +25 -0
  29. data/lib/predicate/processors/to_ruby_code.rb +71 -0
  30. data/lib/predicate/processors.rb +3 -0
  31. data/lib/predicate/version.rb +8 -0
  32. data/lib/predicate.rb +113 -0
  33. data/spec/expr/test_to_proc.rb +16 -0
  34. data/spec/expr/test_to_ruby_code.rb +152 -0
  35. data/spec/factory/shared/a_comparison_factory_method.rb +35 -0
  36. data/spec/factory/shared/a_predicate_ast_node.rb +20 -0
  37. data/spec/factory/test_and.rb +13 -0
  38. data/spec/factory/test_between.rb +12 -0
  39. data/spec/factory/test_comp.rb +35 -0
  40. data/spec/factory/test_contradiction.rb +11 -0
  41. data/spec/factory/test_eq.rb +9 -0
  42. data/spec/factory/test_factor_predicate.rb +50 -0
  43. data/spec/factory/test_gt.rb +9 -0
  44. data/spec/factory/test_gte.rb +9 -0
  45. data/spec/factory/test_identifier.rb +13 -0
  46. data/spec/factory/test_in.rb +12 -0
  47. data/spec/factory/test_literal.rb +13 -0
  48. data/spec/factory/test_lt.rb +9 -0
  49. data/spec/factory/test_lte.rb +9 -0
  50. data/spec/factory/test_native.rb +19 -0
  51. data/spec/factory/test_neq.rb +9 -0
  52. data/spec/factory/test_not.rb +13 -0
  53. data/spec/factory/test_or.rb +13 -0
  54. data/spec/factory/test_qualified_identifier.rb +15 -0
  55. data/spec/factory/test_tautology.rb +12 -0
  56. data/spec/grammar/test_match.rb +93 -0
  57. data/spec/grammar/test_sexpr.rb +103 -0
  58. data/spec/nodes/and/test_and_split.rb +66 -0
  59. data/spec/nodes/dyadic_comp/test_and_split.rb +45 -0
  60. data/spec/nodes/identifier/test_and_split.rb +23 -0
  61. data/spec/nodes/identifier/test_free_variables.rb +12 -0
  62. data/spec/nodes/identifier/test_name.rb +12 -0
  63. data/spec/nodes/nadic_bool/test_free_variables.rb +14 -0
  64. data/spec/nodes/qualified_identifier/test_and_split.rb +23 -0
  65. data/spec/nodes/qualified_identifier/test_free_variables.rb +12 -0
  66. data/spec/nodes/qualified_identifier/test_name.rb +12 -0
  67. data/spec/nodes/qualified_identifier/test_qualifier.rb +12 -0
  68. data/spec/predicate/test_and_split.rb +57 -0
  69. data/spec/predicate/test_bool_and.rb +34 -0
  70. data/spec/predicate/test_bool_not.rb +68 -0
  71. data/spec/predicate/test_bool_or.rb +34 -0
  72. data/spec/predicate/test_coerce.rb +75 -0
  73. data/spec/predicate/test_constant_variables.rb +52 -0
  74. data/spec/predicate/test_contradiction.rb +24 -0
  75. data/spec/predicate/test_evaluate.rb +66 -0
  76. data/spec/predicate/test_factory_methods.rb +77 -0
  77. data/spec/predicate/test_free_variables.rb +14 -0
  78. data/spec/predicate/test_hash_and_equal.rb +26 -0
  79. data/spec/predicate/test_qualify.rb +34 -0
  80. data/spec/predicate/test_rename.rb +76 -0
  81. data/spec/predicate/test_tautology.rb +24 -0
  82. data/spec/predicate/test_to_proc.rb +14 -0
  83. data/spec/predicate/test_to_ruby_code.rb +20 -0
  84. data/spec/spec_helper.rb +12 -0
  85. data/spec/test_predicate.rb +127 -0
  86. data/tasks/test.rake +11 -0
  87. metadata +186 -0
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "|" do
4
+
5
+ let(:left) { Predicate.coerce(x: 2) }
6
+
7
+ subject{ left | right }
8
+
9
+ before do
10
+ subject.should be_a(Predicate)
11
+ end
12
+
13
+ context 'with itself' do
14
+ let(:right){ left }
15
+
16
+ it{ should be(left) }
17
+ end
18
+
19
+ context 'with the same expression' do
20
+ let(:right){ Predicate.coerce(x: 2) }
21
+
22
+ it{ should be(left) }
23
+ end
24
+
25
+ context 'with another predicate' do
26
+ let(:right){ Predicate.coerce(y: 3) }
27
+
28
+ it 'should be a expected' do
29
+ subject.to_ruby_code.should eq("->(t){ (t[:x] == 2) || (t[:y] == 3) }")
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, ".coerce" do
4
+
5
+ subject{ Predicate.coerce(arg) }
6
+
7
+ describe "from Predicate" do
8
+ let(:arg){ Predicate.new(Factory.tautology) }
9
+
10
+ it{ should be(arg) }
11
+ end
12
+
13
+ describe "from true" do
14
+ let(:arg){ true }
15
+
16
+ specify{
17
+ subject.expr.should be_a(Tautology)
18
+ }
19
+ end
20
+
21
+ describe "from false" do
22
+ let(:arg){ false }
23
+
24
+ specify{
25
+ subject.expr.should be_a(Contradiction)
26
+ }
27
+ end
28
+
29
+ describe "from Symbol" do
30
+ let(:arg){ :status }
31
+
32
+ specify{
33
+ subject.expr.should be_a(Identifier)
34
+ subject.expr.name.should eq(arg)
35
+ }
36
+ end
37
+
38
+ describe "from Proc" do
39
+ let(:arg){ lambda{ status == 10 } }
40
+
41
+ specify{
42
+ subject.expr.should be_a(Native)
43
+ subject.to_proc.should be(arg)
44
+ }
45
+ end
46
+
47
+ describe "from String" do
48
+ let(:arg){ "status == 10" }
49
+
50
+ it 'raises an error' do
51
+ lambda{
52
+ subject
53
+ }.should raise_error(ArgumentError)
54
+ end
55
+ end
56
+
57
+ describe "from Hash (single)" do
58
+ let(:arg){ {status: 10} }
59
+
60
+ specify{
61
+ subject.expr.should be_a(Eq)
62
+ subject.expr.should eq([:eq, [:identifier, :status], [:literal, 10]])
63
+ }
64
+ end
65
+
66
+ describe "from Hash (multiple)" do
67
+ let(:arg){ {status: 10, name: "Jones"} }
68
+
69
+ specify{
70
+ subject.should eq(Predicate.eq(status: 10) & Predicate.eq(name: "Jones"))
71
+ }
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "constant_variables" do
4
+
5
+ subject{ p.constant_variables }
6
+
7
+ describe "on a comp(:eq)" do
8
+ let(:p){ Predicate.coerce(x: 2, y: 3) }
9
+
10
+ it{ expect(subject).to eql([:x, :y]) }
11
+ end
12
+
13
+ describe "on a in with one value" do
14
+ let(:p){ Predicate.in(:x, [2]) }
15
+
16
+ it{ expect(subject).to eql([:x]) }
17
+ end
18
+
19
+ describe "on a in with mutiple values" do
20
+ let(:p){ Predicate.in(:x, [2, 3]) }
21
+
22
+ it{ expect(subject).to eql([]) }
23
+ end
24
+
25
+ describe "on a NOT" do
26
+ let(:p){ !Predicate.coerce(x: 2) }
27
+
28
+ it{ expect(subject).to eql([]) }
29
+ end
30
+
31
+ describe "on a AND" do
32
+ let(:p){ Predicate.coerce(x: 2) & Predicate.coerce(y: 3) }
33
+
34
+ it{ expect(subject).to eql([:x, :y]) }
35
+ end
36
+
37
+ describe "on a OR" do
38
+ let(:p){ Predicate.coerce(x: 2) | Predicate.coerce(y: 3) }
39
+
40
+ it{ expect(subject).to eql([]) }
41
+ end
42
+
43
+ describe "on a negated OR" do
44
+ let(:p){ !(Predicate.coerce(x: 2) | Predicate.coerce(y: 3)) }
45
+
46
+ pending("NNF would make constant_variables smarter"){
47
+ expect(subject).to eql([:x, :y])
48
+ }
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "contradiction?" do
4
+
5
+ context "tautology" do
6
+ subject{ Predicate.tautology }
7
+
8
+ it{ expect(subject.contradiction?).to be(false) }
9
+ end
10
+
11
+ context "contradiction" do
12
+ subject{ Predicate.contradiction }
13
+
14
+ it{ expect(subject.contradiction?).to be(true) }
15
+ end
16
+
17
+ context "identifier" do
18
+ subject{ Predicate.identifier(:x) }
19
+
20
+ it{ expect(subject.contradiction?).to be(false) }
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "evaluate" do
4
+
5
+ context 'on a native predicate of arity 1, used through tuple#[]' do
6
+ let(:predicate){
7
+ Predicate.native(->(t){ t[:name] =~ /foo/ })
8
+ }
9
+
10
+ context 'on a matching tuple' do
11
+ let(:scope){ { :name => "foo" } }
12
+
13
+ it{ expect(predicate.evaluate(scope)).to be_truthy }
14
+ end
15
+
16
+ context 'on a non-matching tuple' do
17
+ let(:scope){ { :name => "bar" } }
18
+
19
+ it{ expect(predicate.evaluate(scope)).to be_falsy }
20
+ end
21
+ end
22
+
23
+ context 'on a native predicate of arity 1, used through tuple[:xxx]' do
24
+ let(:predicate){
25
+ Predicate.native(->(t){ t[:name] =~ /foo/ })
26
+ }
27
+
28
+ context 'on a matching tuple' do
29
+ let(:scope){ { :name => "foo" } }
30
+
31
+ it{ expect(predicate.evaluate(scope)).to be_truthy }
32
+ end
33
+
34
+ context 'on a non-matching tuple' do
35
+ let(:scope){ { :name => "bar" } }
36
+
37
+ it{ expect(predicate.evaluate(scope)).to be_falsy }
38
+ end
39
+ end
40
+
41
+ context 'on a factored predicate' do
42
+ let(:predicate){
43
+ Predicate.new(Factory.lte(:x => 2))
44
+ }
45
+
46
+ describe "on x == 2" do
47
+ let(:scope){ { :x => 2 } }
48
+
49
+ it{ expect(predicate.evaluate(scope)).to be_truthy }
50
+ end
51
+
52
+ describe "on x == 1" do
53
+ let(:scope){ { :x => 1 } }
54
+
55
+ it{ expect(predicate.evaluate(scope)).to be_truthy }
56
+ end
57
+
58
+ describe "on x == 3" do
59
+ let(:scope){ { :x => 3 } }
60
+
61
+ it{ expect(predicate.evaluate(scope)).to be_falsy }
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "factory methods" do
4
+
5
+ before do
6
+ subject.should be_a(Predicate)
7
+ subject.expr.should be_a(Expr)
8
+ end
9
+
10
+ context "tautology" do
11
+ subject{ Predicate.tautology }
12
+
13
+ specify{ subject.to_ruby_code.should eq("->(t){ true }") }
14
+ end
15
+
16
+ context "contradiction" do
17
+ subject{ Predicate.contradiction }
18
+
19
+ specify{ subject.to_ruby_code.should eq("->(t){ false }") }
20
+ end
21
+
22
+ context "identifier" do
23
+ subject{ Predicate.identifier(:x) }
24
+
25
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] }") }
26
+ end
27
+
28
+ context "eq" do
29
+ subject{ Predicate.eq(:x, 2) }
30
+
31
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] == 2 }") }
32
+ end
33
+
34
+ context "neq" do
35
+ subject{ Predicate.neq(:x, 2) }
36
+
37
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] != 2 }") }
38
+ end
39
+
40
+ context "lt" do
41
+ subject{ Predicate.lt(:x, 2) }
42
+
43
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] < 2 }") }
44
+ end
45
+
46
+ context "lte" do
47
+ subject{ Predicate.lte(:x, 2) }
48
+
49
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] <= 2 }") }
50
+ end
51
+
52
+ context "gt" do
53
+ subject{ Predicate.gt(:x, 2) }
54
+
55
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] > 2 }") }
56
+ end
57
+
58
+ context "gte" do
59
+ subject{ Predicate.gte(:x, 2) }
60
+
61
+ specify{ subject.to_ruby_code.should eq("->(t){ t[:x] >= 2 }") }
62
+ end
63
+
64
+ context "literal" do
65
+ subject{ Predicate.literal(2) }
66
+
67
+ specify{ subject.to_ruby_code.should eq("->(t){ 2 }") }
68
+ end
69
+
70
+ context "native" do
71
+ subject{ Predicate.native(lambda{}) }
72
+
73
+ specify{ subject.expr.should be_a(Native) }
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "free_variables" do
4
+
5
+ subject{ p.free_variables }
6
+
7
+ describe "on a comp(:eq)" do
8
+ let(:p){ Predicate.coerce(:x => 2) }
9
+
10
+ it{ should eq([:x]) }
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "hash and ==" do
4
+
5
+ subject{ left == right }
6
+
7
+ after do
8
+ left.hash.should eq(right.hash) if subject
9
+ end
10
+
11
+ describe "on equal predicates" do
12
+ let(:left) { Predicate.coerce(:x => 2) }
13
+ let(:right){ Predicate.coerce(:x => 2) }
14
+
15
+ it{ should be(true) }
16
+ end
17
+
18
+ describe "on non equal predicates" do
19
+ let(:left) { Predicate.coerce(:x => 2) }
20
+ let(:right){ Predicate.coerce(:x => 3) }
21
+
22
+ it{ should be(false) }
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "qualify" do
4
+
5
+ let(:p){ Predicate }
6
+
7
+ subject{ predicate.qualify(qualifier) }
8
+
9
+ let(:qualifier) { {:x => :t} }
10
+
11
+ context 'on a full AST predicate' do
12
+ let(:predicate){ p.in(:x, [2]) & p.eq(:y, 3) }
13
+
14
+ it{ should eq(p.in(Factory.qualified_identifier(:t, :x), [2]) & p.eq(:y, 3)) }
15
+
16
+ specify "it should tag expressions correctly" do
17
+ subject.expr.should be_a(Sexpr)
18
+ subject.expr.should be_a(Expr)
19
+ subject.expr.should be_a(And)
20
+ end
21
+ end
22
+
23
+ context 'on a predicate that contains natives' do
24
+ let(:predicate){ p.in(:x, [2]) & p.native(lambda{}) }
25
+
26
+ it 'raises an error' do
27
+ lambda{
28
+ subject
29
+ }.should raise_error(NotSupportedError)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "rename" do
4
+
5
+ let(:p){ Predicate }
6
+
7
+ subject{ predicate.rename(renaming) }
8
+
9
+ context 'on a pure renaming hash' do
10
+ let(:renaming) { {:x => :z} }
11
+
12
+ context 'on a full AST predicate' do
13
+ let(:predicate){ p.in(:x, [2]) & p.eq(:y, 3) }
14
+
15
+ it{ should eq(p.in(:z, [2]) & p.eq(:y, 3)) }
16
+
17
+ 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)
21
+ end
22
+ end
23
+
24
+ context 'on a predicate that contains natives' do
25
+ let(:predicate){ p.in(:x, [2]) & p.native(lambda{}) }
26
+
27
+ it 'raises an error' do
28
+ lambda{
29
+ subject
30
+ }.should raise_error(NotSupportedError)
31
+ end
32
+ end
33
+
34
+ context 'on a predicate that contains qualified identifiers' do
35
+ let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 3) }
36
+
37
+ it 'renames correctly' do
38
+ subject.should eq(p.eq(Factory.qualified_identifier(:t, :z), 3))
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when the renamer is a Proc returning identifiers' do
44
+ let(:renaming){ ->(a){ Grammar.sexpr([:identifier, :y]) } }
45
+
46
+ context "on an identifier" do
47
+ let(:predicate){ p.eq(:x, 2) }
48
+
49
+ it{ should eq(p.eq(:y, 2)) }
50
+ end
51
+
52
+ context "on a qualifier identifier" do
53
+ let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 2) }
54
+
55
+ it{ should eq(p.eq(:y, 2)) }
56
+ end
57
+ end
58
+
59
+ context 'when the renamer is a Proc returning qualified identifiers' do
60
+ let(:renaming){ ->(a){ Grammar.sexpr([:qualified_identifier, :t, :y]) } }
61
+
62
+ context 'on an identifier' do
63
+ let(:predicate){ p.eq(:x, 2) }
64
+
65
+ it{ should eq(p.eq(Factory.qualified_identifier(:t, :y), 2)) }
66
+ end
67
+
68
+ context 'on a qualified' do
69
+ let(:predicate){ p.eq(Factory.qualified_identifier(:t, :x), 2) }
70
+
71
+ it{ should eq(p.eq(Factory.qualified_identifier(:t, :y), 2)) }
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "tautology?" do
4
+
5
+ context "tautology" do
6
+ subject{ Predicate.tautology }
7
+
8
+ it{ expect(subject.tautology?).to be(true) }
9
+ end
10
+
11
+ context "contradiction" do
12
+ subject{ Predicate.contradiction }
13
+
14
+ it{ expect(subject.tautology?).to be(false) }
15
+ end
16
+
17
+ context "identifier" do
18
+ subject{ Predicate.identifier(:x) }
19
+
20
+ it{ expect(subject.tautology?).to be(false) }
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "to_proc" do
4
+
5
+ subject{ p.to_proc }
6
+
7
+ describe "on a comp(:eq)" do
8
+ let(:p){ Predicate.coerce(:x => 2) }
9
+
10
+ it{ should be_a(Proc) }
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Predicate, "to_ruby_code" do
4
+
5
+ subject{ p.to_ruby_code }
6
+
7
+ describe "on a comp(:eq)" do
8
+ let(:p){ Predicate.coerce(:x => 2) }
9
+
10
+ it{ should eq("->(t){ t[:x] == 2 }") }
11
+ end
12
+
13
+ describe "with qualified identifiers" do
14
+ let(:p){ Predicate.eq(Factory.qualified_identifier(:t, :y), 2) }
15
+
16
+ it{ should eq("->(t){ t[:y] == 2 }") }
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require "rspec"
3
+ require 'predicate'
4
+
5
+ module Helpers
6
+
7
+ end
8
+
9
+ RSpec.configure do |c|
10
+ c.include Helpers
11
+ c.extend Helpers
12
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "a predicate" do
4
+
5
+ let(:x){ 12 }
6
+ let(:y){ 13 }
7
+
8
+ it 'provides a proc for easy evaluation' do
9
+ got = subject.to_proc.call(x: 12, y: 13)
10
+ [ TrueClass, FalseClass ].should include(got.class)
11
+ end
12
+
13
+ it 'can be negated easily' do
14
+ (!subject).should be_a(Predicate)
15
+ end
16
+
17
+ it 'detects stupid AND' do
18
+ (subject & Predicate.tautology).should be(subject)
19
+ end
20
+
21
+ it 'detects stupid OR' do
22
+ (subject | Predicate.contradiction).should be(subject)
23
+ end
24
+
25
+ it 'has free variables' do
26
+ (fv = subject.free_variables).should be_a(Array)
27
+ (fv - [ :x, :y ]).should be_empty
28
+ end
29
+
30
+ it 'always splits around and trivially when no free variables are touched' do
31
+ top, down = subject.and_split([:z])
32
+ top.should be_tautology
33
+ down.should eq(subject)
34
+ end
35
+
36
+ end
37
+
38
+ describe 'Predicate.tautology' do
39
+ subject{ Predicate.tautology }
40
+
41
+ it_should_behave_like "a predicate"
42
+ end
43
+
44
+ describe 'Predicate.contradiction' do
45
+ subject{ Predicate.contradiction }
46
+
47
+ it_should_behave_like "a predicate"
48
+ end
49
+
50
+ describe "Predicate.comp" do
51
+ subject{ Predicate.comp(:lt, {:x => 2}) }
52
+
53
+ it_should_behave_like "a predicate"
54
+ end
55
+
56
+ describe "Predicate.in" do
57
+ subject{ Predicate.in(:x, [2, 3]) }
58
+
59
+ it_should_behave_like "a predicate"
60
+ end
61
+
62
+ describe "Predicate.among" do
63
+ subject{ Predicate.among(:x, [2, 3]) }
64
+
65
+ it_should_behave_like "a predicate"
66
+ end
67
+
68
+ describe "Predicate.eq" do
69
+ subject{ Predicate.eq(:x, 2) }
70
+
71
+ it_should_behave_like "a predicate"
72
+ end
73
+
74
+ describe "Predicate.neq" do
75
+ subject{ Predicate.neq(:x, 2) }
76
+
77
+ it_should_behave_like "a predicate"
78
+ end
79
+
80
+ describe "Predicate.gt" do
81
+ subject{ Predicate.gt(:x, 2) }
82
+
83
+ it_should_behave_like "a predicate"
84
+ end
85
+
86
+ describe "Predicate.gte" do
87
+ subject{ Predicate.gte(:x, 2) }
88
+
89
+ it_should_behave_like "a predicate"
90
+ end
91
+
92
+ describe "Predicate.lt" do
93
+ subject{ Predicate.lt(:x, 2) }
94
+
95
+ it_should_behave_like "a predicate"
96
+ end
97
+
98
+ describe "Predicate.lte" do
99
+ subject{ Predicate.lte(:x, 2) }
100
+
101
+ it_should_behave_like "a predicate"
102
+ end
103
+
104
+ describe "Predicate.between" do
105
+ subject{ Predicate.between(:x, 2, 3) }
106
+
107
+ it_should_behave_like "a predicate"
108
+ end
109
+
110
+ describe "Predicate.and" do
111
+ subject{ Predicate.and(Predicate.eq(:x, 12), Predicate.eq(:y, 12)) }
112
+
113
+ it_should_behave_like "a predicate"
114
+ end
115
+
116
+ describe "Predicate.or" do
117
+ subject{ Predicate.or(Predicate.eq(:x, 12), Predicate.eq(:y, 12)) }
118
+
119
+ it_should_behave_like "a predicate"
120
+ end
121
+
122
+ describe "Predicate.not" do
123
+ subject{ Predicate.not(Predicate.in(:x, [12])) }
124
+
125
+ it_should_behave_like "a predicate"
126
+ end
127
+
data/tasks/test.rake ADDED
@@ -0,0 +1,11 @@
1
+ namespace :test do
2
+
3
+ desc %q{Run all RSpec tests}
4
+ task :unit do
5
+ require 'rspec'
6
+ RSpec::Core::Runner.run(%w[-I. -Ilib -Ispec --pattern=spec/**/test_*.rb --color .])
7
+ end
8
+
9
+ task :all => :"unit"
10
+ end
11
+ task :test => :"test:all"