ruy 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cb7f94655e005150da3e73788e1f3a9fd468a736
4
- data.tar.gz: 69ef1d941e8316dddcf67559502c091abe7df1af
3
+ metadata.gz: cd5ceb75eb7454f4c8b8477a9f57428c9d4c5a2a
4
+ data.tar.gz: 84566c136caaa90dc3b9b237d27edc6c60af8adc
5
5
  SHA512:
6
- metadata.gz: 21f385fc78e17bbb78dc68b26194574c08ed494f16f75b4fa37f570131c8d55aeec4bbc654bcef7b873c5651f5328b274def2f032edfe338c6acbf3edd6e1810
7
- data.tar.gz: dd62cdfa7593eb95b43ded250262358f057fa277d583cb7750d04811cbcf116504121fba08d9b93f111c4634371efeb3004cb64c6d7916442802a23d1b6a1748
6
+ metadata.gz: 1d732cd15c2acf298a872ce6a51de97740e6edfa1a1fdad9cfa4372423e0a78cf51578e8057eaeef38afcc0f250db3acd6f4ada9bb02778e8c829815cb4fc894
7
+ data.tar.gz: 7e38818c44bb7529e2c9283aaa975560acb6363f56fa221a8075013dd7a0731424659653a307dc9bb6edd844e4ad2e52bd214a3744cb53a7d84d7f9b8c1d3d20
data/lib/ruy.rb CHANGED
@@ -2,6 +2,7 @@ require_relative 'ruy/rule'
2
2
  require_relative 'ruy/adapters'
3
3
  require_relative 'ruy/conditions'
4
4
  require_relative 'ruy/rule_storage'
5
+ require_relative 'ruy/time_pattern'
5
6
 
6
7
  module Ruy
7
8
  class RuleSet < Rule
@@ -62,9 +63,7 @@ module Ruy
62
63
 
63
64
  def outcome(value, &block)
64
65
  outcome = Outcome.new(value)
65
-
66
66
  outcome.instance_exec(&block) if block_given?
67
-
68
67
  @outcomes << outcome
69
68
  end
70
69
 
@@ -93,9 +92,7 @@ module Ruy
93
92
  end
94
93
 
95
94
  def call(ctx)
96
- if super(ctx)
97
- @value
98
- end
95
+ @value if super(ctx)
99
96
  end
100
97
 
101
98
  def ==(o)
@@ -107,10 +104,9 @@ module Ruy
107
104
 
108
105
  # Context that can resolve variable access
109
106
  class VariableContext
110
- def initialize(ctx, vars)
107
+ def initialize(ctx, vars = {})
111
108
  @ctx = ctx
112
109
  @vars = vars
113
-
114
110
  @resolved_vars = {}
115
111
  end
116
112
 
@@ -10,6 +10,7 @@ require_relative 'conditions/include'
10
10
  require_relative 'conditions/included'
11
11
  require_relative 'conditions/less_than'
12
12
  require_relative 'conditions/less_than_or_equal'
13
+ require_relative 'conditions/tz'
13
14
 
14
15
  module Ruy
15
16
  module Conditions; end
@@ -7,6 +7,7 @@ module Ruy
7
7
 
8
8
  # @param attr Context attribute's name
9
9
  def initialize(attr)
10
+ super()
10
11
  @attr = attr
11
12
  @params = [@attr]
12
13
  end
@@ -17,12 +17,9 @@ module Ruy
17
17
 
18
18
  @attr = attr
19
19
  @value = value
20
-
21
20
  @params = [@attr, @value]
22
21
 
23
- if block_given?
24
- instance_exec(&block)
25
- end
22
+ instance_exec(&block) if block_given?
26
23
  end
27
24
 
28
25
  def call(var_ctx)
@@ -8,6 +8,7 @@ module Ruy
8
8
  # @param attr Context attribute's name
9
9
  # @param value
10
10
  def initialize(attr, value)
11
+ super()
11
12
  @attr = attr
12
13
  @value = value
13
14
 
@@ -8,6 +8,7 @@ module Ruy
8
8
  # @param attr Context attribute's name
9
9
  # @param value
10
10
  def initialize(attr, value)
11
+ super()
11
12
  @attr = attr
12
13
  @value = value
13
14
 
@@ -0,0 +1,62 @@
1
+ module Ruy
2
+ module Conditions
3
+
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.
8
+ class TZ < Ruy::Rule
9
+ # @param [String] tz_identifier String representing IANA's time zone identifier.
10
+ def initialize(tz_identifier)
11
+ super()
12
+ @tz_identifier = tz_identifier
13
+ @params = [@tz_identifier]
14
+ end
15
+
16
+ # @param [Ruy::VariableContext] var_ctx
17
+ def call(var_ctx)
18
+ @conditions.all? do |condition|
19
+ condition.call(var_ctx)
20
+ end
21
+ end
22
+
23
+ # Intercepts an 'eq' call to the superclass and enhances its arguments
24
+ #
25
+ # @param (see Ruy::Conditions::Eq#initialize)
26
+ def eq(attr, pattern, &block)
27
+ super(attr, TimePattern.new(pattern, @tz_identifier), &block)
28
+ end
29
+
30
+ # TODO Add Greater condition call here
31
+
32
+ # Intercepts a 'greater_than_or_equal' call to the superclass and enhances its arguments
33
+ #
34
+ # @param (see Ruy::Conditions::GreaterThanOrEqual#initialize)
35
+ def greater_than_or_equal(attr, pattern, &block)
36
+ super(attr, TimePattern.new(pattern, @tz_identifier), &block)
37
+ end
38
+
39
+ # Intercepts a 'less_than' call to the superclass and enhances its arguments
40
+ #
41
+ # @param (see Ruy::Conditions::LessThan#initialize)
42
+ def less_than(attr, pattern, &block)
43
+ super(attr, TimePattern.new(pattern, @tz_identifier), &block)
44
+ end
45
+
46
+ # Intercepts a 'less_than_or_equal' call to the superclass and enhances its arguments
47
+ #
48
+ # @param (see Ruy::Conditions::LessThanOrEqual#initialize)
49
+ def less_than_or_equal(attr, pattern, &block)
50
+ super(attr, TimePattern.new(pattern, @tz_identifier), &block)
51
+ end
52
+
53
+ # Intercepts a 'between' call to the superclass and enhances its arguments
54
+ #
55
+ # @param (see Ruy::Conditions::Between#initialize)
56
+ def between(attr, from, to, &block)
57
+ super(attr, TimePattern.new(from, @tz_identifier), TimePattern.new(to, @tz_identifier), &block)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
data/lib/ruy/rule.rb CHANGED
@@ -153,6 +153,17 @@ module Ruy
153
153
  @conditions << Conditions::LessThan.new(attr, value)
154
154
  end
155
155
 
156
+ # Adds a TZ condition block
157
+ #
158
+ # @param [String] tz_identifier String representing IANA's time zone identifier. Defaults to UTC if none passed.
159
+ # @yield Evaluates the given block in the context of the TZ rule
160
+ def tz(tz_identifier = 'UTC', &block)
161
+ cond = Conditions::TZ.new(tz_identifier)
162
+ cond.instance_exec(&block)
163
+
164
+ @conditions << cond
165
+ end
166
+
156
167
  # Gets attribute's value from the given name.
157
168
  #
158
169
  # @param name
@@ -0,0 +1,57 @@
1
+ require 'tzinfo'
2
+
3
+ module Ruy
4
+ class TimePattern
5
+ include Comparable
6
+
7
+ EXP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(z(\S+))?$/
8
+
9
+ attr_reader :tz, :local_time, :utc_time
10
+
11
+ # @param [String] pattern String representing a Ruy's well-formed timestamp pattern
12
+ # @param [String] tz_identifier String representing IANA's time zone identifier. Defaults to UTC if none passed.
13
+ def initialize(pattern, tz_identifier = 'UTC')
14
+ raise ArgumentError, 'Pattern is malformed' unless match_data = pattern.match(EXP)
15
+
16
+ year = match_data[1].to_i
17
+ month = match_data[2].to_i
18
+ day = match_data[3].to_i
19
+ hours = match_data[4].to_i
20
+ min = match_data[5].to_i
21
+ sec = match_data[6].to_i
22
+ tz_identifier = match_data[8] || tz_identifier
23
+
24
+ # Store the TZInfo::Timezone object corresponding to the specified time zone
25
+ @tz = TZInfo::Timezone.get(tz_identifier)
26
+
27
+ # Store a Time object with values based on the specified time zone
28
+ @local_time = Time.new(year, month, day, hours, min, sec, '+00:00')
29
+
30
+ # Store a Time object with values based on UTC
31
+ @utc_time = @tz.local_to_utc(@local_time)
32
+ end
33
+
34
+ # Implements Ruby's spaceship operator to work with TimePattern objects.
35
+ #
36
+ # @param [TimePattern|Time]
37
+ # @return [Fixnum]
38
+ def <=>(time)
39
+ @utc_time <=> (time.is_a?(self.class) ? time.utc_time : time)
40
+ end
41
+
42
+ # Returns a well-formed Ruy timestamp with IANA time zone identifier representing the current TimePattern object.
43
+ #
44
+ # @return [String]
45
+ def to_s
46
+ @local_time.strftime("%Y-%m-%dT%H:%M:%Sz#{@tz.identifier}")
47
+ end
48
+
49
+ # Overrides Ruby's method missing call to redirect calls to the stored Time object in case it responds to the
50
+ # missing method. Will call to super in case it doesn't.
51
+ #
52
+ # @param (see BasicObject#method_missing)
53
+ def method_missing(method, *args)
54
+ @utc_time.respond_to?(method) ? @utc_time.send(method, *args) : super
55
+ end
56
+ end
57
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moove-IT
@@ -10,43 +10,59 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tzinfo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rspec
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - '>='
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: 3.0.0
33
+ version: '3.1'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - '>='
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: 3.0.0
40
+ version: '3.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sequel
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - '>='
45
+ - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 4.12.0
47
+ version: '4.12'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - '>='
52
+ - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 4.12.0
54
+ version: '4.12'
41
55
  description:
42
56
  email:
43
57
  executables: []
44
58
  extensions: []
45
59
  extra_rdoc_files: []
46
60
  files:
61
+ - lib/ruy.rb
62
+ - lib/ruy/adapters.rb
47
63
  - lib/ruy/adapters/file_adapter.rb
48
64
  - lib/ruy/adapters/sequel_adapter.rb
49
- - lib/ruy/adapters.rb
65
+ - lib/ruy/conditions.rb
50
66
  - lib/ruy/conditions/all.rb
51
67
  - lib/ruy/conditions/any.rb
52
68
  - lib/ruy/conditions/assert.rb
@@ -59,10 +75,10 @@ files:
59
75
  - lib/ruy/conditions/included.rb
60
76
  - lib/ruy/conditions/less_than.rb
61
77
  - lib/ruy/conditions/less_than_or_equal.rb
62
- - lib/ruy/conditions.rb
78
+ - lib/ruy/conditions/tz.rb
63
79
  - lib/ruy/rule.rb
64
80
  - lib/ruy/rule_storage.rb
65
- - lib/ruy.rb
81
+ - lib/ruy/time_pattern.rb
66
82
  homepage: https://github.com/Moove-it/ruy
67
83
  licenses:
68
84
  - MIT
@@ -73,18 +89,19 @@ require_paths:
73
89
  - lib
74
90
  required_ruby_version: !ruby/object:Gem::Requirement
75
91
  requirements:
76
- - - '>='
92
+ - - ">="
77
93
  - !ruby/object:Gem::Version
78
94
  version: '0'
79
95
  required_rubygems_version: !ruby/object:Gem::Requirement
80
96
  requirements:
81
- - - '>='
97
+ - - ">="
82
98
  - !ruby/object:Gem::Version
83
99
  version: '0'
84
100
  requirements: []
85
101
  rubyforge_project:
86
- rubygems_version: 2.0.14
102
+ rubygems_version: 2.4.5
87
103
  signing_key:
88
104
  specification_version: 4
89
105
  summary: Rules Engine for Ruby
90
106
  test_files: []
107
+ has_rdoc: