predicate 1.0.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 (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"