rung 0.0.1.pre.alpha → 0.1

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