onuro 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7826a6ec7bc1eecff6013f3fcfe7d59ae8b7a1aba636b062c886d87e9278e6ee
4
- data.tar.gz: f25e753a231f1ab7e23360b9263b464f9383f3c4a3f13210d98ac71d32f44303
3
+ metadata.gz: 0b8f298894039efad8040411f7f20ef9520904d86ba94e2a2e81affec3e3e42e
4
+ data.tar.gz: 69feab312564ca16fa4bcd2da211cf40c67e961379a744857c920bad0d761bb7
5
5
  SHA512:
6
- metadata.gz: 456107defeb433d5878e7625aaaa77c95f442e37d09a91fb37afa9f5b8d6c9141c12bfd87936988a9d1da659e717e4663478b7fcd20e03ed9cb898ef6c548e58
7
- data.tar.gz: f72546cb01de305f26e307a46dfcce80c741c3e739e99855b0575b42b0dbcd9d63ee1efb5d9ecce6c8d644dce92a74717422e9d315d05629e435a31c7fd5c131
6
+ metadata.gz: 342d089f5b6ea8180887d006e37fb3a3e13951483688774b46288319ea68e777230dee9f26e432f47611a72bd1fc24330d99858318d27afa47f70977b951e441
7
+ data.tar.gz: dddd4518bbf349f4b2ba1700936d6eee919f320e21d335e8fde0c365c360cbe1e6151169fc6b04ba0d8618728d3eaa6c6f42ba8045fbd6113eafd2981d5cf1b5
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /log/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -1,3 +1,6 @@
1
+ require:
2
+ - rubocop-rspec
3
+
1
4
  Metrics/LineLength:
2
5
  Max: 100
3
6
 
@@ -9,3 +12,6 @@ Rails/Output:
9
12
 
10
13
  Style/ClassAndModuleChildren:
11
14
  Enabled: false
15
+
16
+ Metrics/AbcSize:
17
+ Max: 30
@@ -1,14 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- onuro (0.1.1)
4
+ onuro (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activesupport (5.2.3)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 0.7, < 2)
12
+ minitest (~> 5.1)
13
+ tzinfo (~> 1.1)
9
14
  ast (2.4.0)
15
+ byebug (11.0.1)
16
+ coderay (1.1.2)
17
+ concurrent-ruby (1.1.5)
10
18
  diff-lcs (1.3)
19
+ docile (1.3.1)
20
+ i18n (1.6.0)
21
+ concurrent-ruby (~> 1.0)
11
22
  jaro_winkler (1.5.2)
23
+ json (2.2.0)
24
+ minitest (5.11.3)
12
25
  parallel (1.17.0)
13
26
  parser (2.6.3.0)
14
27
  ast (~> 2.4.0)
@@ -34,18 +47,33 @@ GEM
34
47
  rainbow (>= 2.2.2, < 4.0)
35
48
  ruby-progressbar (~> 1.7)
36
49
  unicode-display_width (>= 1.4.0, < 1.7)
50
+ rubocop-rspec (1.33.0)
51
+ rubocop (>= 0.60.0)
37
52
  ruby-progressbar (1.10.1)
53
+ simplecov (0.16.1)
54
+ docile (~> 1.1)
55
+ json (>= 1.8, < 3)
56
+ simplecov-html (~> 0.10.0)
57
+ simplecov-html (0.10.2)
58
+ thread_safe (0.3.6)
59
+ tzinfo (1.2.5)
60
+ thread_safe (~> 0.1)
38
61
  unicode-display_width (1.6.0)
39
62
 
40
63
  PLATFORMS
41
64
  ruby
42
65
 
43
66
  DEPENDENCIES
67
+ activesupport (~> 5.2)
44
68
  bundler (~> 1.17)
69
+ byebug (~> 11.0)
70
+ coderay (~> 1.1)
45
71
  onuro!
46
72
  rake (~> 12.3)
47
73
  rspec (~> 3.8)
48
74
  rubocop (~> 0.71.0)
75
+ rubocop-rspec (~> 1.33)
76
+ simplecov (~> 0.16.1)
49
77
 
50
78
  BUNDLED WITH
51
79
  1.17.2
data/README.md CHANGED
@@ -22,7 +22,59 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ ### Engine
26
+
27
+ ### Rule
28
+
29
+ ### RuleStage
30
+
31
+ ### Events
32
+
33
+ Events are the component that hold an *rulset stage* composed of a list of rules and their settings for execution. The easiest way to define and event is creating the instance object always with the event name required. In order to create complex events with more settings, take a look to the *Event Builder* section.
34
+
35
+ ```ruby
36
+ event = Event.new(:my_event)
37
+ engine.add_event(event)
38
+ engine.execute(:my_event)
39
+ ```
40
+
41
+ ### Event Builder
42
+
43
+ An easier way to create an event, is using the **EventBuilder*** class based on the *builder pattern*. This gives a lot of flexibility when you are creating the events and avoid having a lot or parameters in the constructor and assembling all the event internals, and easy to to be plugged in you **Engine** class instance.
44
+
45
+ ```ruby
46
+ event = EventBuilder.build(:test_ruleset) do |builder|
47
+ builder.add_ruleset_stage([rule1, rule2, rule3])
48
+ builder.add_event_strategy(MyCustomEventStrategy)
49
+ builder.exec_order(:desc)
50
+ buidler.ignore_diseabled
51
+ end
52
+
53
+ engine.add_event(event)
54
+ engine.execute(:test_ruleset)
55
+ ```
56
+
57
+ ### Event Strategies
58
+
59
+ Events allow you to implement your custom strategy, to control what happens before and after the rule is executed in the event. By default Onuro provides a default strategy:
60
+
61
+ ```ruby
62
+ module Onuro
63
+ class DefaultEventStrategy
64
+ def before_rule_exec(_rule_stage, _context)
65
+ true
66
+ end
67
+
68
+ def after_rule_exec(_rule_stage, _context, _result)
69
+ true
70
+ end
71
+ end
72
+ end
73
+ ```
74
+
75
+ You only need to implement the methods **before_rule_exec** and **after_rule_exec** in your custom class returning a boolean value. Basically, this is the *strategy pattern*.
76
+
77
+ If **before_rule_exec** returns false, skip the current rule execution and move to the next one in the ruleset list.
26
78
 
27
79
  ## Development
28
80
 
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'onuro/version'
4
+ require 'onuro/execution_result'
5
+ require 'onuro/logging'
4
6
  require 'onuro/engine'
7
+ require 'onuro/default_event_strategy'
8
+ require 'onuro/event_builder'
9
+ require 'onuro/event'
10
+ require 'onuro/base_rule'
11
+ require 'onuro/rule_stage'
5
12
 
6
13
  module Onuro
7
14
  class Error < StandardError; end
8
- # Your code goes here...
9
- Event = Struct.new(:name, :rules)
10
- Rule = Struct.new(:rule, :enabled, :order)
15
+ class InvalidEventNameException < StandardError; end
11
16
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ class BaseRule
5
+ include ExecutionResult
6
+ include Logging
7
+
8
+ def execute(_context = {})
9
+ SUCCESSFUL
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ class DefaultEventStrategy
5
+ def before_rule_exec(_rule_stage, _context)
6
+ true
7
+ end
8
+
9
+ def after_rule_exec(_rule_stage, _context, _result)
10
+ true
11
+ end
12
+ end
13
+ end
@@ -1,22 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Onuro::Engine
4
- def initialize
5
- @events = []
6
- end
3
+ module Onuro
4
+ class Engine
5
+ include Logging
7
6
 
8
- def add_event(event)
9
- @events << event
10
- end
7
+ attr_accessor :events
11
8
 
12
- def event?(event_name)
13
- @events.each do |event|
14
- return true if event.name == event_name
9
+ def initialize
10
+ self.events = Hash.new(0)
11
+ end
12
+
13
+ def add_event(event)
14
+ events[event.name] = event
15
+ self
16
+ end
17
+
18
+ def add_events(new_events)
19
+ new_events.each { |event| add_event(event) }
20
+ self
15
21
  end
16
- false
17
- end
18
22
 
19
- def execute
20
- ['Still WIP']
23
+ def event?(event_name)
24
+ events.key?(event_name)
25
+ end
26
+
27
+ def delete_event!(event_name)
28
+ result = events.delete(event_name)
29
+ raise InvalidEventNameException unless result
30
+ end
31
+
32
+ def execute(event_name, context = {})
33
+ raise InvalidEventNameException unless event?(event_name)
34
+
35
+ events[event_name].execute(context)
36
+ end
21
37
  end
22
38
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ class Event
5
+ include Logging
6
+ include ExecutionResult
7
+
8
+ attr_reader :name, :ruleset_stage
9
+ attr_accessor :event_strategy
10
+
11
+ def name=(name)
12
+ raise InvalidEventNameException if name.empty?
13
+
14
+ @name = name.downcase.to_sym
15
+ end
16
+
17
+ def initialize(name, ruleset_stage: [], event_strategy: DefaultEventStrategy.new)
18
+ self.name = name
19
+ self.event_strategy = event_strategy
20
+ @ruleset_stage = ruleset_stage
21
+ end
22
+
23
+ def add_ruleset_stage(ruleset_stage)
24
+ @ruleset_stage += ruleset_stage
25
+ end
26
+
27
+ def add_rule_stage(rule_stage)
28
+ ruleset_stage << rule_stage
29
+ end
30
+
31
+ def execute(context = {})
32
+ result = execution_flow(context)
33
+ execution_result(SUCCESSFUL, result[:processed], result[:failed])
34
+ end
35
+
36
+ private
37
+
38
+ def execution_result(status, processed, failed)
39
+ result = Hash.new(0)
40
+ result[:status] = status
41
+ result[:event_name] = name
42
+ result[:processed_rules] = processed
43
+ result[:failed_rules] = failed
44
+ result
45
+ end
46
+
47
+ def execution_flow(context = {})
48
+ result = Hash.new(0)
49
+ ruleset_stage.each do |rule_stage|
50
+ proc_exec = event_strategy.before_rule_exec(rule_stage, context)
51
+ next unless proc_exec
52
+
53
+ result_status = rule_stage.rule.new.execute(context)
54
+ event_strategy.after_rule_exec(rule_stage, context, result)
55
+
56
+ result[:processed] += 1 if result_status == SUCCESSFUL
57
+ result[:failed] += 1 if result_status == FAILURE
58
+ end
59
+ result
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ class EventBuilder
5
+ attr_accessor :event
6
+
7
+ def initialize(name)
8
+ self.event = Event.new(name)
9
+ end
10
+
11
+ def add_event_strategy(event_strategy)
12
+ event.event_strategy = event_strategy
13
+ end
14
+
15
+ def add_ruleset_stage(ruleset_stage)
16
+ event.add_ruleset_stage(ruleset_stage)
17
+ end
18
+
19
+ def add_rule_stage(rule_stage)
20
+ event.add_rule_stage(rule_stage)
21
+ end
22
+
23
+ def exec_order(order)
24
+ # can be :asc, :desc, :none by default (order is as rules were introduced
25
+ # in the ruleset_stage list)
26
+ end
27
+
28
+ def ignore_diseabled
29
+ # sets to true and all the diseablked rules will be executed
30
+ # default should be false, so diseabled rules will not be executed
31
+ end
32
+
33
+ def self.build(name)
34
+ builder = new(name)
35
+ yield builder
36
+ builder.event
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ module ExecutionResult
5
+ SUCCESSFUL = 'SUCCESSFUL'
6
+ FAILURE = 'FAILURE'
7
+ NO_PROCESSABLE = 'NO_PROCESSABLE'
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/logger'
4
+
5
+ module Onuro
6
+ module Logging
7
+ def logger
8
+ Logging.logger
9
+ end
10
+
11
+ # Global, memoized, lazy initialized instance of a logger
12
+ def self.logger
13
+ @logger ||= ActiveSupport::Logger.new(logger_file, 10, 1_024_000)
14
+ end
15
+
16
+ def self.logger_file
17
+ 'log/onuro_engine.log'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onuro
4
+ class RuleStage
5
+ attr_reader :rule, :enabled, :order
6
+
7
+ def initialize(rule:, enabled:, order:)
8
+ @rule = rule
9
+ @enabled = enabled
10
+ @order = order
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Onuro
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
@@ -41,8 +41,13 @@ Gem::Specification.new do |spec|
41
41
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
42
42
  spec.require_paths = ['lib']
43
43
 
44
+ spec.add_development_dependency 'activesupport', '~> 5.2'
44
45
  spec.add_development_dependency 'bundler', '~> 1.17'
46
+ spec.add_development_dependency 'byebug', '~> 11.0'
47
+ spec.add_development_dependency 'coderay', '~> 1.1'
45
48
  spec.add_development_dependency 'rake', '~> 12.3'
46
49
  spec.add_development_dependency 'rspec', '~> 3.8'
47
50
  spec.add_development_dependency 'rubocop', '~> 0.71.0'
51
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.33'
52
+ spec.add_development_dependency 'simplecov', '~> 0.16.1'
48
53
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onuro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Reyes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-10 00:00:00.000000000 Z
11
+ date: 2019-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,34 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: coderay
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: rake
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +108,34 @@ dependencies:
66
108
  - - "~>"
67
109
  - !ruby/object:Gem::Version
68
110
  version: 0.71.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.33'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.33'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.16.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.16.1
69
139
  description: Ruby Workflow Engine based in events that execute a collection of rules.
70
140
  email:
71
141
  - encode@bytedecoder.me
@@ -74,6 +144,7 @@ extensions: []
74
144
  extra_rdoc_files: []
75
145
  files:
76
146
  - ".gitignore"
147
+ - ".rspec"
77
148
  - ".rubocop.yml"
78
149
  - CHANGELOG.md
79
150
  - CODE_OF_CONDUCT.md
@@ -85,7 +156,14 @@ files:
85
156
  - bin/console
86
157
  - bin/setup
87
158
  - lib/onuro.rb
159
+ - lib/onuro/base_rule.rb
160
+ - lib/onuro/default_event_strategy.rb
88
161
  - lib/onuro/engine.rb
162
+ - lib/onuro/event.rb
163
+ - lib/onuro/event_builder.rb
164
+ - lib/onuro/execution_result.rb
165
+ - lib/onuro/logging.rb
166
+ - lib/onuro/rule_stage.rb
89
167
  - lib/onuro/version.rb
90
168
  - onuro.gemspec
91
169
  homepage: https://github.com/ByteDecoder/onuro