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,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