ruy 0.2.1 → 0.3.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.
@@ -5,18 +5,18 @@ module Ruy
5
5
  class GreaterThanOrEqual < Ruy::Rule
6
6
  attr_reader :attr, :value
7
7
 
8
- # @param attr Context attribute's name
9
8
  # @param value
9
+ # @param attr Context attribute's name
10
10
  # @yield a block in the context of the current rule
11
- def initialize(attr, value, &block)
11
+ def initialize(value, attr, &block)
12
12
  super
13
- @attr = attr
14
13
  @value = value
14
+ @attr = attr
15
15
  instance_exec(&block) if block_given?
16
16
  end
17
17
 
18
- def call(var_ctx)
19
- var_ctx.resolve(@attr) >= @value && super
18
+ def call(ctx)
19
+ @value <= ctx.resolve(@attr) && super
20
20
  end
21
21
 
22
22
  def ==(o)
@@ -0,0 +1,31 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute is included in a set of values.
5
+ class In < Ruy::Rule
6
+ attr_reader :attr, :values
7
+
8
+ # @param values Expected set of values
9
+ # @param attr Context attribute's name
10
+ # @yield a block in the context of the current rule
11
+ def initialize(values, attr, &block)
12
+ super
13
+ @values = values
14
+ @attr = attr
15
+ instance_exec(&block) if block_given?
16
+ end
17
+
18
+ def call(var_ctx)
19
+ self.values.include?(var_ctx.resolve(self.attr)) && super
20
+ end
21
+
22
+ def ==(o)
23
+ o.kind_of?(In) &&
24
+ self.attr == o.attr &&
25
+ self.values == o.values &&
26
+ self.conditions == o.conditions
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ module Ruy
2
+ module Conditions
3
+ class InCyclicOrder < Ruy::Rule
4
+ attr_reader :from, :to, :attr
5
+
6
+ def initialize(from, to, attr, &block)
7
+ super
8
+ @from = from
9
+ @to = to
10
+ @attr = attr
11
+ instance_exec(&block) if block_given?
12
+ end
13
+
14
+ def call(ctx)
15
+ value = ctx.resolve(@attr)
16
+
17
+ if @from > @to
18
+ (@from <= value || @to >= value) && super
19
+ else
20
+ (@from <= value && @to >= value) && super
21
+ end
22
+ end
23
+
24
+ def ==(o)
25
+ o.kind_of?(self.class) &&
26
+ @from == o.from &&
27
+ @to == o.to &&
28
+ @attr == o.attr &&
29
+ self.conditions == o.conditions
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,28 +1,28 @@
1
1
  module Ruy
2
2
  module Conditions
3
3
 
4
- # Expects that a context attribute is included in a set of values.
4
+ # Expects that a value is included in a set of values from the context attribute.
5
5
  class Include < Ruy::Rule
6
- attr_reader :attr, :values
6
+ attr_reader :attr, :value
7
7
 
8
+ # @param value Expected set of values
8
9
  # @param attr Context attribute's name
9
- # @param values Expected set of values
10
10
  # @yield a block in the context of the current rule
11
- def initialize(attr, values, &block)
11
+ def initialize(value, attr, &block)
12
12
  super
13
+ @value = value
13
14
  @attr = attr
14
- @values = values
15
15
  instance_exec(&block) if block_given?
16
16
  end
17
17
 
18
- def call(var_ctx)
19
- self.values.include?(var_ctx.resolve(self.attr)) && super
18
+ def call(ctx)
19
+ ctx.resolve(self.attr).include?(self.value) && super
20
20
  end
21
21
 
22
22
  def ==(o)
23
23
  o.kind_of?(Include) &&
24
24
  self.attr == o.attr &&
25
- self.values == o.values &&
25
+ self.value == o.value &&
26
26
  self.conditions == o.conditions
27
27
  end
28
28
  end
@@ -15,8 +15,8 @@ module Ruy
15
15
  instance_exec(&block) if block_given?
16
16
  end
17
17
 
18
- def call(var_ctx)
19
- var_ctx.resolve(self.attr).include?(self.value) && super
18
+ def call(ctx)
19
+ ctx.resolve(self.attr).include?(self.value) && super
20
20
  end
21
21
 
22
22
  def ==(o)
@@ -5,16 +5,16 @@ module Ruy
5
5
  class LessThan < Ruy::Rule
6
6
  attr_reader :attr, :value
7
7
 
8
- # @param attr Context attribute's name
9
8
  # @param value
10
- def initialize(attr, value)
9
+ # @param attr Context attribute's name
10
+ def initialize(value, attr)
11
11
  super
12
- @attr = attr
13
12
  @value = value
13
+ @attr = attr
14
14
  end
15
15
 
16
- def call(var_ctx)
17
- var_ctx.resolve(@attr) < @value
16
+ def call(ctx)
17
+ @value > ctx.resolve(@attr)
18
18
  end
19
19
 
20
20
  def ==(o)
@@ -7,14 +7,14 @@ module Ruy
7
7
 
8
8
  # @param attr Context attribute's name
9
9
  # @param value
10
- def initialize(attr, value)
10
+ def initialize(value, attr)
11
11
  super
12
- @attr = attr
13
12
  @value = value
13
+ @attr = attr
14
14
  end
15
15
 
16
- def call(var_ctx)
17
- var_ctx.resolve(@attr) <= @value
16
+ def call(ctx)
17
+ @value >= ctx.resolve(@attr)
18
18
  end
19
19
 
20
20
  def ==(o)
@@ -2,9 +2,10 @@ module Ruy
2
2
  module Conditions
3
3
 
4
4
  # Evaluates a block using comparison matchers that receive time-related objects with time zone awareness.
5
- # Does not support time zone-aware matchers inside sub-blocks.
6
- # A workaround for this is always surrounding your time zone-aware matchers by a 'tz' block even in sub-blocks
7
- # already surrounded by one.
5
+ #
6
+ # @note Does not support time zone-aware matchers inside sub-blocks.
7
+ # A workaround for this is always surrounding your time zone-aware matchers by a 'tz' block even in sub-blocks
8
+ # already surrounded by one.
8
9
  class TZ < Ruy::Rule
9
10
  # @param [String] tz_identifier String representing IANA's time zone identifier.
10
11
  def initialize(tz_identifier)
@@ -12,25 +13,25 @@ module Ruy
12
13
  @tz_identifier = tz_identifier
13
14
  end
14
15
 
15
- # @param [Ruy::VariableContext] var_ctx
16
- def call(var_ctx)
16
+ # @param [Ruy::VariableContext] ctx
17
+ def call(ctx)
17
18
  @conditions.all? do |condition|
18
- condition.call(var_ctx)
19
+ condition.call(ctx)
19
20
  end
20
21
  end
21
22
 
22
23
  # Adds a DayOfWeek condition
23
24
  #
24
25
  # @param (see Ruy::Conditions::DayOfWeek#initialize)
25
- def day_of_week(attr, dow)
26
- @conditions << DayOfWeek.new(attr, dow, @tz_identifier)
26
+ def day_of_week(dow, attr)
27
+ @conditions << DayOfWeek.new(dow, attr, @tz_identifier)
27
28
  end
28
29
 
29
30
  # Intercepts an 'eq' call to the superclass and enhances its arguments
30
31
  #
31
32
  # @param (see Ruy::Conditions::Eq#initialize)
32
- def eq(attr, pattern, &block)
33
- super(attr, TimePattern.new(pattern, @tz_identifier), &block)
33
+ def eq(pattern, attr, &block)
34
+ super(TimePattern.new(pattern, @tz_identifier), attr, &block)
34
35
  end
35
36
 
36
37
  # TODO Add Greater condition call here
@@ -38,29 +39,29 @@ module Ruy
38
39
  # Intercepts a 'greater_than_or_equal' call to the superclass and enhances its arguments
39
40
  #
40
41
  # @param (see Ruy::Conditions::GreaterThanOrEqual#initialize)
41
- def greater_than_or_equal(attr, pattern, &block)
42
- super(attr, TimePattern.new(pattern, @tz_identifier), &block)
42
+ def greater_than_or_equal(pattern, attr, &block)
43
+ super(TimePattern.new(pattern, @tz_identifier), attr, &block)
43
44
  end
44
45
 
45
46
  # Intercepts a 'less_than' call to the superclass and enhances its arguments
46
47
  #
47
48
  # @param (see Ruy::Conditions::LessThan#initialize)
48
- def less_than(attr, pattern, &block)
49
- super(attr, TimePattern.new(pattern, @tz_identifier), &block)
49
+ def less_than(pattern, attr, &block)
50
+ super(TimePattern.new(pattern, @tz_identifier), attr, &block)
50
51
  end
51
52
 
52
53
  # Intercepts a 'less_than_or_equal' call to the superclass and enhances its arguments
53
54
  #
54
55
  # @param (see Ruy::Conditions::LessThanOrEqual#initialize)
55
- def less_than_or_equal(attr, pattern, &block)
56
- super(attr, TimePattern.new(pattern, @tz_identifier), &block)
56
+ def less_than_or_equal(pattern, attr, &block)
57
+ super(TimePattern.new(pattern, @tz_identifier), attr, &block)
57
58
  end
58
59
 
59
60
  # Intercepts a 'between' call to the superclass and enhances its arguments
60
61
  #
61
62
  # @param (see Ruy::Conditions::Between#initialize)
62
- def between(attr, from, to, &block)
63
- super(attr, TimePattern.new(from, @tz_identifier), TimePattern.new(to, @tz_identifier), &block)
63
+ def between(from, to, attr, &block)
64
+ super(TimePattern.new(from, @tz_identifier), TimePattern.new(to, @tz_identifier), attr, &block)
64
65
  end
65
66
 
66
67
  end
@@ -1,10 +1,28 @@
1
1
  module Ruy
2
- class Context < Hash
3
- def self.from_hash(hash)
4
- ctx = Context.new
5
- ctx.merge!(hash)
2
+ # Context that resolves lets and values access.
3
+ class Context
6
4
 
7
- ctx
5
+ # @param [Hash] ctx
6
+ # @param [Array] lets Names of the 'let' variables
7
+ def initialize(ctx, lets = [])
8
+ @ctx = ctx
9
+ @lets = lets
10
+
11
+ @resolved_lets = {}
12
+ end
13
+
14
+ # Resolve the given attr from the lets or the context.
15
+ #
16
+ # @param [Symbol] attr
17
+ #
18
+ # @return [Object]
19
+ # @return [nil] when attribute cannot be resolved
20
+ def resolve(attr)
21
+ if @lets.include?(attr)
22
+ @resolved_lets[attr] ||= @ctx.instance_exec(&@ctx[attr])
23
+ else
24
+ @ctx.fetch(attr) { |key| @ctx[key.to_s] }
25
+ end
8
26
  end
9
27
  end
10
28
  end
@@ -0,0 +1,146 @@
1
+ module Ruy
2
+ module DSL
3
+
4
+ # Adds an All condition.
5
+ #
6
+ # @yield Evaluates the given block in the context of the new rule
7
+ def all(&block)
8
+ cond = Conditions::All.new
9
+ cond.instance_exec(&block)
10
+
11
+ self.conditions << cond
12
+ end
13
+
14
+ # Adds an Any condition.
15
+ #
16
+ # @yield Evaluates the given block in the context of the new rule
17
+ def any(&block)
18
+ cond = Conditions::Any.new
19
+ cond.instance_exec(&block)
20
+
21
+ self.conditions << cond
22
+ end
23
+
24
+ # Adds an Assert condition.
25
+ #
26
+ # @param (see Conditions::Assert#initialize)
27
+ def assert(attr)
28
+ self.conditions << Conditions::Assert.new(attr)
29
+ end
30
+
31
+ # Adds a Between condition.
32
+ #
33
+ # @param (see Conditions::Between#initialize)
34
+ def between(from, to, attr, &block)
35
+ self.conditions << Conditions::Between.new(from, to, attr, &block)
36
+ end
37
+
38
+ # Adds an Eq condition.
39
+ #
40
+ # @param (see Conditions::Eq#initialize)
41
+ def eq(value, attr, &block)
42
+ self.conditions << Conditions::Eq.new(value, attr, &block)
43
+ end
44
+
45
+ # Adds a Cond condition.
46
+ #
47
+ # @yield Evaluates the given block in the context of the new rule
48
+ def cond(&block)
49
+ cond = Conditions::Cond.new
50
+ cond.instance_exec(&block)
51
+
52
+ self.conditions << cond
53
+ end
54
+
55
+ # Adds an Except condition.
56
+ #
57
+ # @param (see Conditions::Except#initialize)
58
+ def except(value = nil, attr = nil, &block)
59
+ self.conditions << Conditions::Except.new(value, attr, &block)
60
+ end
61
+
62
+ # Adds a GreaterThan condition.
63
+ #
64
+ # @param (see Conditions::GreaterThanOrEqual#initialize)
65
+ def greater_than(value, attr)
66
+ @conditions << Conditions::GreaterThan.new(value, attr)
67
+ end
68
+
69
+ # Adds a GreaterThanOrEqual condition.
70
+ #
71
+ # @param (see Conditions::GreaterThanOrEqual#initialize)
72
+ def greater_than_or_equal(value, attr)
73
+ self.conditions << Conditions::GreaterThanOrEqual.new(value, attr)
74
+ end
75
+
76
+ # Adds an In condition.
77
+ #
78
+ # @param (see Conditions::Include#initialize)
79
+ def in(values, attr, &block)
80
+ self.conditions << Conditions::In.new(values, attr, &block)
81
+ end
82
+
83
+ # Adds a InCyclicOrder condition.
84
+ #
85
+ # @param (see Conditions::InCyclicOrder#initialize)
86
+ def in_cyclic_order(from, to, attr, &block)
87
+ @conditions << Conditions::InCyclicOrder.new(from, to, attr, &block)
88
+ end
89
+
90
+ # Adds an Include condition.
91
+ #
92
+ # @param (see Conditions::Included#initialize)
93
+ def include(value, attr, &block)
94
+ self.conditions << Conditions::Include.new(value, attr, &block)
95
+ end
96
+
97
+ # Adds a LessOrEqualThan condition.
98
+ #
99
+ # @param (see Conditions::LessOrEqualThan#initialize)
100
+ def less_than_or_equal(value, attr, &block)
101
+ self.conditions << Conditions::LessThanOrEqual.new(value, attr)
102
+ end
103
+
104
+ # Adds a LessThan condition.
105
+ #
106
+ # @param (see Conditions::LessThan#initialize)
107
+ def less_than(value, attr)
108
+ self.conditions << Conditions::LessThan.new(value, attr)
109
+ end
110
+
111
+ # Adds a TZ condition block
112
+ #
113
+ # @param [String] tz_identifier String representing IANA's
114
+ # time zone identifier. Defaults to UTC if none passed.
115
+ # @yield Evaluates the given block in the context of the TZ rule
116
+ def tz(tz_identifier = 'UTC', &block)
117
+ cond = Conditions::TZ.new(tz_identifier)
118
+ cond.instance_exec(&block)
119
+
120
+ self.conditions << cond
121
+ end
122
+
123
+ # @param [Integer] indentation Indentation level
124
+ def to_s(indentation = 0)
125
+ rule_name = Ruy::Utils::Naming.rule_name(self)
126
+
127
+ s = Ruy::Utils::Printable.indent(indentation) << rule_name
128
+
129
+ if self.params.any?
130
+ stringified_params = self.params.map(&:inspect)
131
+
132
+ s << ' ' << stringified_params.join(', ')
133
+ end
134
+
135
+ if self.conditions.empty?
136
+ s << "\n"
137
+ else
138
+ s << " do\n"
139
+ s << self.conditions.map { |c| c.to_s(indentation + 1) }.join()
140
+ s << Ruy::Utils::Printable.indent(indentation) + "end\n"
141
+ end
142
+
143
+ s
144
+ end
145
+ end
146
+ end