rung 0.0.1.pre.alpha → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +72 -0
  3. data/.config/cucumber.yml +1 -0
  4. data/.gitignore +3 -0
  5. data/.rspec +0 -1
  6. data/.rubocop.yml +22 -0
  7. data/Gemfile +6 -2
  8. data/Gemfile.lock +23 -1
  9. data/README.adoc +111 -0
  10. data/Rakefile +19 -4
  11. data/features/{steps_definition.feature → 010_operation.feature} +29 -6
  12. data/features/{state.feature → 020_state.feature} +17 -4
  13. data/features/{failure.feature → 030_failure.feature} +29 -6
  14. data/features/040_failure_step.feature +118 -0
  15. data/features/050_other_steps.feature +135 -0
  16. data/features/051_fail_fast.feature +66 -0
  17. data/features/060_step_wrappers.feature +170 -0
  18. data/features/070_operation_wrappers.feature +41 -0
  19. data/features/080_exceptions_handling.feature +57 -0
  20. data/features/090_around_step_wrapper.feature +130 -0
  21. data/features/200_misc.feature +18 -0
  22. data/features/step_definitions/output.rb +8 -3
  23. data/features/step_definitions/temporary_code_scope.rb +8 -7
  24. data/lib/rung.rb +7 -6
  25. data/lib/rung/definition/callback.rb +14 -0
  26. data/lib/rung/definition/nested_step.rb +16 -0
  27. data/lib/rung/definition/operation_dsl.rb +31 -0
  28. data/lib/rung/definition/step.rb +43 -0
  29. data/lib/rung/definition/steps_dsl.rb +33 -18
  30. data/lib/rung/{base.rb → operation.rb} +3 -2
  31. data/lib/rung/runner/call_helper.rb +30 -12
  32. data/lib/rung/runner/run_context.rb +23 -6
  33. data/lib/rung/runner/runner.rb +34 -14
  34. data/lib/rung/state.rb +35 -0
  35. data/lib/rung/value_object.rb +12 -0
  36. data/lib/rung/version.rb +1 -1
  37. data/rung.gemspec +15 -16
  38. data/target/cukedoctor-intro.adoc +1 -0
  39. data/target/cukedoctor.css +3 -0
  40. metadata +39 -23
  41. data/README.md +0 -79
  42. data/lib/rung/definition/steps/nested_step.rb +0 -20
  43. data/lib/rung/definition/steps/step.rb +0 -30
  44. data/lib/rung/definition/steps_definition.rb +0 -13
  45. data/lib/rung/runner/result.rb +0 -24
  46. data/lib/rung/runner/run_state.rb +0 -12
@@ -1,13 +1,14 @@
1
1
  module Rung
2
- class Base
2
+ class Operation
3
3
  extend Definition::StepsDSL
4
+ extend Definition::OperationDSL
4
5
 
5
6
  def self.call(initial_state = {})
6
7
  new.call(initial_state)
7
8
  end
8
9
 
9
10
  def call(initial_state = {})
10
- Runner::Runner.new(self.class.steps_definition, initial_state, self).call
11
+ Runner::Runner.new(self, initial_state).call
11
12
  end
12
13
  end
13
14
  end
@@ -1,33 +1,51 @@
1
+ # rubocop:disable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/LineLength
1
2
  module Rung
2
3
  module Runner
3
4
  module CallHelper
4
5
  class << self
5
- def call(operation, state, operation_instance, from_block = false, &block)
6
- raise "Can't pass block when from_block is enabled" if block && from_block
7
- runnable = to_runnable(operation, operation_instance)
6
+ def call(action, state, operation_instance, action_from_block = false, second_argument = nil, &block)
7
+ raise Error, "Can't pass block when action_from_block is enabled" if block && action_from_block
8
8
 
9
- if from_block
10
- runnable.arity.zero? ? operation_instance.instance_exec(&runnable) : operation_instance.instance_exec(state, &runnable)
9
+ runnable = to_runnable(action, operation_instance)
10
+ arity = runnable.arity
11
+
12
+ if action_from_block
13
+ case arity
14
+ when 0
15
+ operation_instance.instance_exec(&runnable)
16
+ when 1
17
+ operation_instance.instance_exec(state, &runnable)
18
+ else
19
+ operation_instance.instance_exec(state, second_argument, &runnable)
20
+ end
11
21
  else
12
- runnable.arity.zero? ? runnable.call(&block) : runnable.call(state, &block)
22
+ case arity
23
+ when 0
24
+ runnable.call(&block)
25
+ when 1
26
+ runnable.call(state, &block)
27
+ else
28
+ runnable.call(state, second_argument, &block)
29
+ end
13
30
  end
14
31
  end
15
32
 
16
33
  private
17
34
 
18
- def to_runnable(operation, operation_instance)
19
- case operation
35
+ def to_runnable(action, operation_instance)
36
+ case action
20
37
  when Symbol, String
21
- operation_instance.method(operation)
38
+ operation_instance.method(action)
22
39
  when Proc
23
- operation
40
+ action
24
41
  else
25
- operation.method(:call)
42
+ action.method(:call)
26
43
  end
27
44
  rescue NameError
28
- operation
45
+ action
29
46
  end
30
47
  end
31
48
  end
32
49
  end
33
50
  end
51
+ # rubocop:enable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/LineLength
@@ -1,25 +1,42 @@
1
1
  module Rung
2
2
  module Runner
3
3
  class RunContext
4
- def initialize(steps_definition:, operation_instance:, state:)
5
- @steps_definition = steps_definition
4
+ extend Forwardable
5
+
6
+ def initialize(operation_instance, state)
6
7
  @operation_instance = operation_instance
7
8
  @state = state
8
9
  @failed = false
10
+ @stopped = false
9
11
  end
10
12
 
11
- attr_reader :steps_definition, :operation_instance, :state
13
+ def_delegators :operation_class,
14
+ :steps_definition, :around_callbacks,
15
+ :around_each_callbacks
16
+ attr_reader :operation_instance, :state
17
+
18
+ def operation_class
19
+ operation_instance.class
20
+ end
12
21
 
13
22
  def fail!
14
23
  @failed = true
15
24
  end
16
25
 
17
- def failed?
18
- @failed
26
+ def stop!
27
+ @stopped = true
28
+ end
29
+
30
+ def stopped?
31
+ @stopped
19
32
  end
20
33
 
21
34
  def success?
22
- !failed?
35
+ !@failed
36
+ end
37
+
38
+ def to_state
39
+ State.new state, success?, operation_instance
23
40
  end
24
41
  end
25
42
  end
@@ -1,26 +1,33 @@
1
1
  module Rung
2
2
  module Runner
3
3
  class Runner
4
- def initialize(steps_definition, initial_state, operation_instance)
5
- @context = RunContext.new(
6
- steps_definition: steps_definition,
7
- operation_instance: operation_instance,
8
- state: RunState.new(initial_state)
9
- )
4
+ def initialize(operation_instance, initial_state)
5
+ @context = RunContext.new(operation_instance, {}.merge(initial_state))
10
6
  end
11
7
 
12
8
  extend Forwardable
13
9
  def_delegators :@context,
14
- :steps_definition, :operation_instance, :state, :failed?, :success?, :fail!
10
+ :steps_definition, :operation_instance,
11
+ :around_callbacks, :around_each_callbacks,
12
+ :success?, :stopped?, :fail!, :stop!
15
13
 
16
14
  def call
17
- run_success = iterate(steps_definition)
15
+ with_callbacks(around_callbacks) { iterate(steps_definition) }
18
16
 
19
- Result.new(run_success, state)
17
+ current_state
20
18
  end
21
19
 
22
20
  private
23
21
 
22
+ def with_callbacks(callbacks, second_argument: nil, &block)
23
+ callbacks.reverse.inject(block) do |inner, callback|
24
+ lambda do
25
+ CallHelper.call callback.action, current_state, operation_instance,
26
+ callback.from_block, second_argument, &inner
27
+ end
28
+ end.call
29
+ end
30
+
24
31
  def iterate(steps_definition)
25
32
  steps_definition.each(&method(:run_step))
26
33
 
@@ -28,11 +35,14 @@ module Rung
28
35
  end
29
36
 
30
37
  def run_step(step)
38
+ return if stopped?
31
39
  return unless step.run?(success?)
32
40
 
33
- step_success = call_step(step)
41
+ step_success = with_callbacks(
42
+ around_each_callbacks, second_argument: step
43
+ ) { call_step(step) }
34
44
 
35
- fail! unless step_success
45
+ handle_failure(step) unless step_success
36
46
  end
37
47
 
38
48
  def call_step(step)
@@ -40,13 +50,23 @@ module Rung
40
50
  end
41
51
 
42
52
  def call_nested_step(nested)
43
- CallHelper.call(nested.operation, state, operation_instance) do
44
- iterate(nested.nested_steps)
53
+ CallHelper.call nested.action, current_state, operation_instance do
54
+ iterate nested.nested_steps
45
55
  end
46
56
  end
47
57
 
48
58
  def call_simple_step(step)
49
- CallHelper.call(step.operation, state, operation_instance, step.from_block)
59
+ CallHelper.call step.action, current_state, operation_instance,
60
+ step.from_block
61
+ end
62
+
63
+ def current_state
64
+ @context.to_state
65
+ end
66
+
67
+ def handle_failure(step)
68
+ fail! unless step.ignore_result?
69
+ stop! if step.fail_fast?
50
70
  end
51
71
  end
52
72
  end
@@ -0,0 +1,35 @@
1
+ module Rung
2
+ class State
3
+ include ValueObject
4
+
5
+ def initialize(state, success, operation)
6
+ @success = success
7
+ @operation = operation
8
+ @state = state
9
+ end
10
+
11
+ def method_missing(method, *args)
12
+ return @state.send(method, *args) if @state.respond_to?(method)
13
+
14
+ super
15
+ end
16
+
17
+ def respond_to_missing?(method_name, include_private = false)
18
+ @state.respond_to?(method_name, include_private) || super
19
+ end
20
+
21
+ attr_reader :operation
22
+
23
+ def success?
24
+ @success
25
+ end
26
+
27
+ def fail?
28
+ !success?
29
+ end
30
+
31
+ alias failure? fail?
32
+ alias failed? fail?
33
+ alias successful? success?
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ module Rung
2
+ module ValueObject
3
+ def ==(other)
4
+ return false if self.class != other.class
5
+
6
+ instance_variables.all? do |variable|
7
+ instance_variable_get(variable) ==
8
+ other.send(:instance_variable_get, variable)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Rung
2
- VERSION = "0.0.1-alpha"
2
+ VERSION = '0.1'.freeze
3
3
  end
@@ -1,28 +1,27 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "rung/version"
3
+ require 'rung/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "rung"
6
+ spec.name = 'rung'
7
7
  spec.version = Rung::VERSION
8
- spec.authors = ["Jan Jędrychowski"]
9
- spec.email = ["jan@jedrychowski.org"]
10
-
11
- spec.summary = %q{Business operations DSL}
12
- spec.description = %q{Service object/business operation/Railway DSL, inspired by Trailblazer Operation}
13
- spec.homepage = "https://github.com/gogiel/rung"
14
- spec.license = "MIT"
8
+ spec.authors = ['Jan Jędrychowski']
9
+ spec.email = ['jan@jedrychowski.org']
15
10
 
11
+ spec.summary = 'Business operations DSL'
12
+ spec.description = 'Service object/business operation/Railway DSL, inspired by Trailblazer Operation'
13
+ spec.homepage = 'https://github.com/gogiel/rung'
14
+ spec.license = 'MIT'
16
15
 
17
16
  # Specify which files should be added to the gem when it is released.
18
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
19
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|bin)/}) }
21
20
  end
22
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
23
22
 
24
- spec.add_development_dependency "bundler", "~> 1.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
27
- spec.add_development_dependency "cucumber", "~> 3.1"
23
+ spec.add_development_dependency 'bundler', '~> 1.16'
24
+ spec.add_development_dependency 'cucumber', '~> 3.1'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
27
  end
@@ -0,0 +1 @@
1
+ ../README.adoc
@@ -0,0 +1,3 @@
1
+ .exampleblock .icon.green {
2
+ display: none;
3
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rung
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre.alpha
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Jędrychowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-27 00:00:00.000000000 Z
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,47 +25,47 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.16'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: cucumber
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '3.1'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '3.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '10.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: cucumber
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.1'
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.1'
68
+ version: '3.0'
69
69
  description: Service object/business operation/Railway DSL, inspired by Trailblazer
70
70
  Operation
71
71
  email:
@@ -74,32 +74,48 @@ executables: []
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
+ - ".circleci/config.yml"
78
+ - ".config/cucumber.yml"
79
+ - ".gitignore"
77
80
  - ".rspec"
81
+ - ".rubocop.yml"
78
82
  - Gemfile
79
83
  - Gemfile.lock
80
84
  - LICENSE.txt
81
- - README.md
85
+ - README.adoc
82
86
  - Rakefile
83
- - features/failure.feature
84
- - features/state.feature
87
+ - features/010_operation.feature
88
+ - features/020_state.feature
89
+ - features/030_failure.feature
90
+ - features/040_failure_step.feature
91
+ - features/050_other_steps.feature
92
+ - features/051_fail_fast.feature
93
+ - features/060_step_wrappers.feature
94
+ - features/070_operation_wrappers.feature
95
+ - features/080_exceptions_handling.feature
96
+ - features/090_around_step_wrapper.feature
97
+ - features/200_misc.feature
85
98
  - features/step_definitions/output.rb
86
99
  - features/step_definitions/temporary_code_scope.rb
87
- - features/steps_definition.feature
88
100
  - features/support/env.rb
89
101
  - lib/rung.rb
90
- - lib/rung/base.rb
91
- - lib/rung/definition/steps/nested_step.rb
92
- - lib/rung/definition/steps/step.rb
93
- - lib/rung/definition/steps_definition.rb
102
+ - lib/rung/definition/callback.rb
103
+ - lib/rung/definition/nested_step.rb
104
+ - lib/rung/definition/operation_dsl.rb
105
+ - lib/rung/definition/step.rb
94
106
  - lib/rung/definition/steps_dsl.rb
95
107
  - lib/rung/error.rb
108
+ - lib/rung/operation.rb
96
109
  - lib/rung/runner/call_helper.rb
97
- - lib/rung/runner/result.rb
98
110
  - lib/rung/runner/run_context.rb
99
- - lib/rung/runner/run_state.rb
100
111
  - lib/rung/runner/runner.rb
112
+ - lib/rung/state.rb
113
+ - lib/rung/value_object.rb
101
114
  - lib/rung/version.rb
102
115
  - rung.gemspec
116
+ - target/cukedoctor-intro.adoc
117
+ - target/cukedoctor.css
118
+ - tmp/.keep
103
119
  homepage: https://github.com/gogiel/rung
104
120
  licenses:
105
121
  - MIT
@@ -115,9 +131,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
131
  version: '0'
116
132
  required_rubygems_version: !ruby/object:Gem::Requirement
117
133
  requirements:
118
- - - ">"
134
+ - - ">="
119
135
  - !ruby/object:Gem::Version
120
- version: 1.3.1
136
+ version: '0'
121
137
  requirements: []
122
138
  rubyforge_project:
123
139
  rubygems_version: 2.5.2.1