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,23 @@
1
+ class Predicate
2
+ class Qualifier < Sexpr::Rewriter
3
+
4
+ grammar Grammar
5
+
6
+ def initialize(qualifier)
7
+ @qualifier = qualifier
8
+ end
9
+ attr_reader :qualifier
10
+
11
+ def on_identifier(sexpr)
12
+ return sexpr unless q = qualifier[sexpr.name]
13
+ [:qualified_identifier, q, sexpr.name]
14
+ end
15
+
16
+ def on_native(sexpr)
17
+ raise NotSupportedError
18
+ end
19
+
20
+ alias :on_missing :copy_and_apply
21
+
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ class Predicate
2
+ class Renamer < Sexpr::Rewriter
3
+
4
+ grammar Grammar
5
+
6
+ def on_identifier(sexpr)
7
+ return sexpr unless new_name = options[:renaming][sexpr.name]
8
+ return new_name if Sexpr===new_name
9
+ [:identifier, new_name]
10
+ end
11
+
12
+ def on_qualified_identifier(sexpr)
13
+ return sexpr unless new_name = options[:renaming][sexpr.name]
14
+ return new_name if Sexpr===new_name
15
+ [:qualified_identifier, sexpr.qualifier, new_name]
16
+ end
17
+
18
+ def on_native(sexpr)
19
+ raise NotSupportedError
20
+ end
21
+
22
+ alias :on_missing :copy_and_apply
23
+
24
+ end
25
+ end
@@ -0,0 +1,71 @@
1
+ class Predicate
2
+ class ToRubyCode < Sexpr::Processor
3
+
4
+ def on_tautology(sexpr)
5
+ "true"
6
+ end
7
+
8
+ def on_contradiction(sexpr)
9
+ "false"
10
+ end
11
+
12
+ def on_qualified_identifier(sexpr)
13
+ "#{sexpr.qualifier}[:#{sexpr.name}]"
14
+ end
15
+
16
+ def on_identifier(sexpr)
17
+ if s = options[:scope]
18
+ "#{s}[:#{sexpr.last.to_s}]"
19
+ else
20
+ sexpr.last.to_s
21
+ end
22
+ end
23
+
24
+ def on_not(sexpr)
25
+ "#{sexpr.operator_symbol}" << apply(sexpr.last, sexpr)
26
+ end
27
+
28
+ def on_nadic_bool(sexpr)
29
+ sexpr.sexpr_body.map{|term|
30
+ apply(term, sexpr)
31
+ }.join(" #{sexpr.operator_symbol} ")
32
+ end
33
+ alias :on_and :on_nadic_bool
34
+ alias :on_or :on_nadic_bool
35
+
36
+ def on_dyadic(sexpr)
37
+ sexpr.sexpr_body.map{|term|
38
+ apply(term, sexpr)
39
+ }.join(" #{sexpr.operator_symbol} ")
40
+ end
41
+ alias :on_eq :on_dyadic
42
+ alias :on_neq :on_dyadic
43
+ alias :on_lt :on_dyadic
44
+ alias :on_lte :on_dyadic
45
+ alias :on_gt :on_dyadic
46
+ alias :on_gte :on_dyadic
47
+
48
+ def on_in(sexpr)
49
+ "#{to_ruby_literal(sexpr.values)}.include?(#{apply(sexpr.identifier)})"
50
+ end
51
+
52
+ def on_literal(sexpr)
53
+ to_ruby_literal(sexpr.last)
54
+ end
55
+
56
+ protected
57
+
58
+ def to_ruby_literal(x)
59
+ x.inspect
60
+ end
61
+
62
+ def apply(sexpr, parent = nil)
63
+ code = super(sexpr)
64
+ if parent && (parent.priority >= sexpr.priority)
65
+ code = "(" << code << ")"
66
+ end
67
+ code
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ require_relative "processors/to_ruby_code"
2
+ require_relative "processors/renamer"
3
+ require_relative "processors/qualifier"
@@ -0,0 +1,8 @@
1
+ class Predicate
2
+ module Version
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ TINY = 0
6
+ end
7
+ VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
+ end
data/lib/predicate.rb ADDED
@@ -0,0 +1,113 @@
1
+ require 'sexpr'
2
+ require_relative 'predicate/version'
3
+ require_relative 'predicate/factory'
4
+ require_relative 'predicate/grammar'
5
+ require_relative 'predicate/processors'
6
+ class Predicate
7
+
8
+ class NotSupportedError < StandardError; end
9
+
10
+ TupleLike = ->(t){ t.is_a?(Hash) }
11
+
12
+ def initialize(sexpr)
13
+ @sexpr = sexpr
14
+ end
15
+ attr_reader :sexpr
16
+ alias :expr :sexpr
17
+
18
+ class << self
19
+ include Factory
20
+
21
+ def coerce(arg)
22
+ case arg
23
+ when Predicate then arg
24
+ when TrueClass then tautology
25
+ when FalseClass then contradiction
26
+ when Symbol then identifier(arg)
27
+ when Proc then native(arg)
28
+ when Hash then eq(arg)
29
+ else
30
+ raise ArgumentError, "Unable to coerce `#{arg}` to a predicate"
31
+ end
32
+ end
33
+ alias :parse :coerce
34
+
35
+ private
36
+
37
+ def _factor_predicate(arg)
38
+ Predicate.new Grammar.sexpr(arg)
39
+ end
40
+
41
+ end
42
+
43
+ def native?
44
+ Native===expr
45
+ end
46
+
47
+ def tautology?
48
+ expr.tautology?
49
+ end
50
+
51
+ def contradiction?
52
+ expr.contradiction?
53
+ end
54
+
55
+ def free_variables
56
+ expr.free_variables
57
+ end
58
+
59
+ def constant_variables
60
+ expr.constant_variables
61
+ end
62
+
63
+ def &(other)
64
+ return self if other.tautology? or other==self
65
+ return other if tautology?
66
+ Predicate.new(expr & other.expr)
67
+ end
68
+
69
+ def |(other)
70
+ return self if other.contradiction? or other==self
71
+ return other if contradiction?
72
+ Predicate.new(expr | other.expr)
73
+ end
74
+
75
+ def !
76
+ Predicate.new(!expr)
77
+ end
78
+
79
+ def qualify(qualifier)
80
+ Predicate.new(expr.qualify(qualifier))
81
+ end
82
+
83
+ def rename(renaming)
84
+ Predicate.new(expr.rename(renaming))
85
+ end
86
+
87
+ def evaluate(tuple)
88
+ to_proc.call(tuple)
89
+ end
90
+
91
+ def and_split(attr_list)
92
+ expr.and_split(attr_list).map{|e| Predicate.new(e)}
93
+ end
94
+
95
+ def ==(other)
96
+ other.is_a?(Predicate) && (other.expr==expr)
97
+ end
98
+ alias :eql? :==
99
+
100
+ def hash
101
+ expr.hash
102
+ end
103
+
104
+ def to_ruby_code(scope = "t")
105
+ expr.to_ruby_code(scope)
106
+ end
107
+ alias :to_s :to_ruby_code
108
+
109
+ def to_proc
110
+ @proc ||= expr.to_proc("t")
111
+ end
112
+
113
+ end # class Predicate
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Expr, "to_proc" do
4
+
5
+ let(:expr){ Factory.lte(:x, 2) }
6
+
7
+ subject{ expr.to_proc }
8
+
9
+ it{ should be_a(Proc) }
10
+
11
+ it 'has arity 1' do
12
+ subject.arity.should eq(1)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Expr, "to_ruby_code" do
4
+
5
+ let(:f){ Factory }
6
+
7
+ subject{ expr.to_ruby_code }
8
+
9
+ after do
10
+ unless expr.is_a?(Native)
11
+ lambda{
12
+ eval(subject)
13
+ }.should_not raise_error
14
+ end
15
+ end
16
+
17
+ context 'tautology' do
18
+ let(:expr){ f.tautology }
19
+
20
+ it{ should eq("->(t){ true }") }
21
+ end
22
+
23
+ context 'contradiction' do
24
+ let(:expr){ f.contradiction }
25
+
26
+ it{ should eq("->(t){ false }") }
27
+ end
28
+
29
+ describe "identifier" do
30
+ let(:expr){ f.identifier(:name) }
31
+
32
+ it{ should eq("->(t){ t[:name] }") }
33
+ end
34
+
35
+ describe "and" do
36
+ let(:expr){ f.and(f.contradiction, f.contradiction) }
37
+
38
+ it{ should eq("->(t){ false && false }") }
39
+ end
40
+
41
+ describe "or" do
42
+ let(:expr){ f.or(f.contradiction, f.contradiction) }
43
+
44
+ it{ should eq("->(t){ false || false }") }
45
+ end
46
+
47
+ describe "not" do
48
+ let(:expr){ f.not(f.contradiction) }
49
+
50
+ it{ should eq("->(t){ !false }") }
51
+ end
52
+
53
+ describe "comp" do
54
+ let(:expr){ f.comp(:lt, {:x => 2}) }
55
+
56
+ it{ should eq("->(t){ t[:x] < 2 }") }
57
+ end
58
+
59
+ describe "eq" do
60
+ let(:expr){ f.eq(:x, 2) }
61
+
62
+ it{ should eq("->(t){ t[:x] == 2 }") }
63
+ end
64
+
65
+ describe "eq (parentheses required)" do
66
+ let(:expr){ f.eq(f.eq(:y, 2), true) }
67
+
68
+ it{ should eq("->(t){ (t[:y] == 2) == true }") }
69
+ end
70
+
71
+ describe "comp (multiple)" do
72
+ let(:expr){ f.comp(:eq, :x => 2, :y => 3) }
73
+
74
+ it{ should eq("->(t){ (t[:x] == 2) && (t[:y] == 3) }") }
75
+ end
76
+
77
+ describe "in" do
78
+ let(:expr){ f.in(:x, [2, 3]) }
79
+
80
+ it{ should eq("->(t){ [2, 3].include?(t[:x]) }") }
81
+ end
82
+
83
+ describe "neq" do
84
+ let(:expr){ f.neq(:x, 2) }
85
+
86
+ it{ should eq("->(t){ t[:x] != 2 }") }
87
+ end
88
+
89
+ describe "gt" do
90
+ let(:expr){ f.gt(:x, 2) }
91
+
92
+ it{ should eq("->(t){ t[:x] > 2 }") }
93
+ end
94
+
95
+ describe "gte" do
96
+ let(:expr){ f.gte(:x, 2) }
97
+
98
+ it{ should eq("->(t){ t[:x] >= 2 }") }
99
+ end
100
+
101
+ describe "lt" do
102
+ let(:expr){ f.lt(:x, 2) }
103
+
104
+ it{ should eq("->(t){ t[:x] < 2 }") }
105
+ end
106
+
107
+ describe "lte" do
108
+ let(:expr){ f.lte(:x, 2) }
109
+
110
+ it{ should eq("->(t){ t[:x] <= 2 }") }
111
+ end
112
+
113
+ describe "literal" do
114
+ let(:expr){ f.literal(12) }
115
+
116
+ it{ should eq("->(t){ 12 }") }
117
+ end
118
+
119
+ describe "native" do
120
+ let(:expr){ f.native(lambda{}) }
121
+
122
+ specify{
123
+ lambda{ subject }.should raise_error(NotSupportedError)
124
+ }
125
+ end
126
+
127
+ describe "conjunction of two eqs" do
128
+ let(:expr){
129
+ f.and(f.eq(:x, 2), f.eq(:y, 3))
130
+ }
131
+
132
+ it{ should eq("->(t){ (t[:x] == 2) && (t[:y] == 3) }") }
133
+ end
134
+
135
+ describe "conjunction of two comps" do
136
+ let(:expr){
137
+ f.and(f.comp(:eq, :x => 2), f.comp(:eq, :y => 3))
138
+ }
139
+
140
+ it{ should eq("->(t){ (t[:x] == 2) && (t[:y] == 3) }") }
141
+ end
142
+
143
+ describe "or and and" do
144
+ let(:expr){
145
+ f.and(f.eq(:x, 2), f.or(true, false))
146
+ }
147
+
148
+ it{ should eq("->(t){ (t[:x] == 2) && (true || false) }") }
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'a_predicate_ast_node'
2
+ shared_examples_for "a comparison factory method" do
3
+ include Predicate::Factory
4
+
5
+ context 'with two operands' do
6
+ subject{ self.send(method, true, true) }
7
+
8
+ it_should_behave_like "a predicate AST node"
9
+ it{ should be_a(node_class) }
10
+ it{ should eql([method, tautology, tautology]) }
11
+ end
12
+
13
+ context 'with a Hash operand (singleton)' do
14
+ subject{ self.send(method, :x => :y) }
15
+ let(:expected){
16
+ [method, [:identifier, :x], [:identifier, :y]]
17
+ }
18
+
19
+ it_should_behave_like "a predicate AST node"
20
+ it{ should eql(expected) }
21
+ end
22
+
23
+ context 'with a Hash operand' do
24
+ subject{ self.send(method, :x => :y, :v => 2) }
25
+ let(:expected){
26
+ [:and,
27
+ [method, [:identifier, :x], [:identifier, :y]],
28
+ [method, [:identifier, :v], [:literal, 2]]]
29
+ }
30
+
31
+ it_should_behave_like "a predicate AST node"
32
+ it{ should eql(expected) }
33
+ end
34
+
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ shared_examples_for "a predicate AST node" do
3
+
4
+ it{ should be_a(Sexpr) }
5
+
6
+ it{ should be_a(Predicate::Expr) }
7
+
8
+ specify{
9
+ (subject.tautology? == subject.is_a?(Predicate::Tautology)).should be(true)
10
+ }
11
+
12
+ specify{
13
+ (subject.contradiction? == subject.is_a?(Predicate::Contradiction)).should be(true)
14
+ }
15
+
16
+ specify{
17
+ subject.free_variables.should be_a(Array) unless subject.is_a?(Predicate::Native)
18
+ }
19
+
20
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'shared/a_predicate_ast_node'
2
+ class Predicate
3
+ describe Factory, 'and' do
4
+ include Factory
5
+
6
+ subject{ self.and(true, true) }
7
+
8
+ it_should_behave_like "a predicate AST node"
9
+ it{ should be_a(And) }
10
+ it{ should eql([:and, tautology, tautology]) }
11
+
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'between' do
4
+
5
+ subject{ Factory.between(:x, 2, 3) }
6
+
7
+ it{ should be_a(And) }
8
+
9
+ it{ should eq([:and, [:gte, [:identifier, :x], [:literal, 2]], [:lte, [:identifier, :x], [:literal, 3]]]) }
10
+
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'shared/a_predicate_ast_node'
2
+ class Predicate
3
+ describe Factory, 'comp' do
4
+
5
+ subject{ Factory.comp(:eq, h) }
6
+
7
+ context "when the hash is empty" do
8
+ let(:h){ {} }
9
+
10
+ it{ should eq(Factory.tautology) }
11
+ end
12
+
13
+ context "when the hash is singleton" do
14
+ let(:h){ {:x => 12, :y => :z} }
15
+ let(:expected){
16
+ [:and,
17
+ [:eq, [:identifier, :x], [:literal, 12]],
18
+ [:eq, [:identifier, :y], [:identifier, :z]]]
19
+ }
20
+
21
+ it_should_behave_like "a predicate AST node"
22
+ it{ should be_a(And) }
23
+ it{ should eq(expected) }
24
+ end
25
+
26
+ context "when the hash is not singelton" do
27
+ let(:h){ {:x => 12} }
28
+
29
+ it_should_behave_like "a predicate AST node"
30
+ it{ should be_a(Eq) }
31
+ it{ should eq([:eq, [:identifier, :x], [:literal, 12]]) }
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'shared/a_predicate_ast_node'
2
+ class Predicate
3
+ describe Factory, 'contradiction' do
4
+ include Factory
5
+
6
+ subject{ contradiction }
7
+
8
+ it_should_behave_like "a predicate AST node"
9
+ it{ should be_a(Contradiction) }
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'eq' do
4
+ let(:method){ :eq }
5
+ let(:node_class){ Eq }
6
+
7
+ it_should_behave_like "a comparison factory method"
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ class Predicate
3
+ describe Factory, "_factor_predicate" do
4
+
5
+ subject{ Factory._factor_predicate(arg) }
6
+
7
+ context "on Expr" do
8
+ let(:arg){ Grammar.sexpr([:literal, 12]) }
9
+
10
+ it{ should be(arg) }
11
+ end
12
+
13
+ context "on true" do
14
+ let(:arg){ true }
15
+
16
+ it{ should be_a(Tautology) }
17
+ end
18
+
19
+ context "on false" do
20
+ let(:arg){ false }
21
+
22
+ it{ should be_a(Contradiction) }
23
+ end
24
+
25
+ context "on Symbol" do
26
+ let(:arg){ :name }
27
+
28
+ it{ should be_a(Identifier) }
29
+ end
30
+
31
+ context "on Proc" do
32
+ let(:arg){ lambda{} }
33
+
34
+ it{ should be_a(Native) }
35
+ end
36
+
37
+ context "on Array" do
38
+ let(:arg){ [:identifier, :name] }
39
+
40
+ it{ should be_a(Identifier) }
41
+ end
42
+
43
+ context "on 12" do
44
+ let(:arg){ 12 }
45
+
46
+ it{ should be_a(Literal) }
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'gt' do
4
+ let(:method){ :gt }
5
+ let(:node_class){ Gt }
6
+
7
+ it_should_behave_like "a comparison factory method"
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'gte' do
4
+ let(:method){ :gte }
5
+ let(:node_class){ Gte }
6
+
7
+ it_should_behave_like "a comparison factory method"
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'shared/a_predicate_ast_node'
2
+ class Predicate
3
+ describe Factory, 'identifier' do
4
+ include Factory
5
+
6
+ subject{ identifier(:name) }
7
+
8
+ it_should_behave_like "a predicate AST node"
9
+ it{ should be_a(Identifier) }
10
+ it{ should eql([:identifier, :name]) }
11
+
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'in' do
4
+
5
+ subject{ Factory.in(:x, [2, 3]) }
6
+
7
+ it{ should be_a(In) }
8
+
9
+ it{ should eq([:in, [:identifier, :x], [2, 3]]) }
10
+
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'shared/a_predicate_ast_node'
2
+ class Predicate
3
+ describe Factory, 'literal' do
4
+ include Factory
5
+
6
+ subject{ literal(12) }
7
+
8
+ it_should_behave_like "a predicate AST node"
9
+ it{ should be_a(Literal) }
10
+ it{ should eql([:literal, 12]) }
11
+
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'lt' do
4
+ let(:method){ :lt }
5
+ let(:node_class){ Lt }
6
+
7
+ it_should_behave_like "a comparison factory method"
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "shared/a_comparison_factory_method"
2
+ class Predicate
3
+ describe Factory, 'lte' do
4
+ let(:method){ :lte }
5
+ let(:node_class){ Lte }
6
+
7
+ it_should_behave_like "a comparison factory method"
8
+ end
9
+ end