serviz 0.4.0 → 0.5.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
  SHA256:
3
- metadata.gz: 996c470857cef304582ab365344d4918e3ee35c5baacd64b2d5b068a2b323707
4
- data.tar.gz: 3c77f8932bee0fb30543975094f8d1ce025e8455ca031e028b9b97f1a134835d
3
+ metadata.gz: 4ac56a9462d7a2bc3b2b169cb1edb1c9d7102bc2266e7f947f08c85e1ba4dab8
4
+ data.tar.gz: e4ec1c19c41c32f779c3bc2127baec37f8e99f6c667d534b0c6d8e05cd9d1060
5
5
  SHA512:
6
- metadata.gz: d5b429c64601d9a4b9f829cb723e99c995659c64cf5901eb34240047ee2611ab7b10bd2aa27a2ab54339e99c6b63466deab752d5998f3a74efd528d4d16afb9a
7
- data.tar.gz: 7a89f2b36fe02e78d75cec00280659ae0fc7f740730a373c07e62b444534b844a784b1b828acb0291b9f8328833466d66bcbb1fd476f85337aaefab6604cc7ab
6
+ metadata.gz: 520b3c0d7ef65166ce098b6214f4f6a3a720dee5290cf7ff865e6453955bf8072a00419a729d12d88e28c4d1094b48269436aacabac9f61ff60b0c6cb9f22fdf
7
+ data.tar.gz: 939b2c3fe3fc39955fba3a25f8622cd319e4ef6b903e666ba315f93abb3cc3a4ffc9dfe8856dbb7d8ee1c5e68eff92c764707994aba7d40582d1a326c659eb27
@@ -0,0 +1,36 @@
1
+ module Serviz
2
+ class Base
3
+ attr_accessor :errors, :result
4
+
5
+ def self.call(...)
6
+ instance = new(...)
7
+ instance.call
8
+
9
+ yield(instance) if block_given?
10
+
11
+ instance
12
+ end
13
+
14
+ def call
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def errors
19
+ @errors ||= []
20
+ end
21
+
22
+ def error_messages(separator = ", ")
23
+ errors.join(separator)
24
+ end
25
+
26
+ def success?
27
+ !failure?
28
+ end
29
+ alias_method :ok?, :success?
30
+
31
+ def failure?
32
+ errors.any?
33
+ end
34
+ alias_method :error?, :failure?
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module Serviz
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -0,0 +1,55 @@
1
+ module Serviz
2
+ class Workflow < Base
3
+ def self.step(service_class, params: nil, if: nil)
4
+ steps << {
5
+ service_class: service_class,
6
+ params: params,
7
+ condition: binding.local_variable_get(:if)
8
+ }
9
+ end
10
+
11
+ def self.steps
12
+ @steps ||= []
13
+ end
14
+
15
+ def initialize(*args, **kwargs)
16
+ @last_step = nil
17
+ @args = args
18
+ @kwargs = kwargs
19
+ end
20
+
21
+ def call
22
+ self.class.steps.each do |step_config|
23
+ # Check if condition is provided and evaluate it
24
+ if step_config[:condition] && !step_config[:condition].call(@last_step)
25
+ next
26
+ end
27
+
28
+ # Determine parameters to use
29
+ operation = if step_config[:params]
30
+ # Use step-specific params
31
+ step_params = if step_config[:params].is_a?(Proc)
32
+ step_config[:params].call(self)
33
+ else
34
+ step_config[:params]
35
+ end
36
+ step_config[:service_class].call(**step_params)
37
+ else
38
+ # Use workflow args/kwargs
39
+ step_config[:service_class].call(*@args, **@kwargs)
40
+ end
41
+
42
+ # Accumulate errors if the service failed
43
+ if operation.failure?
44
+ self.errors.concat(operation.errors)
45
+ end
46
+
47
+ # Update last result and overall result
48
+ @last_step = operation
49
+ self.result = operation.result
50
+ end
51
+
52
+ self
53
+ end
54
+ end
55
+ end
data/lib/serviz.rb CHANGED
@@ -1,44 +1,3 @@
1
1
  require 'serviz/version'
2
-
3
- module Serviz
4
- class Base
5
- attr_accessor :errors, :result
6
-
7
- def self.call(*args, **kwargs)
8
- instance = if args.length > 0 && kwargs.length > 0
9
- new(*args, **kwargs)
10
- elsif kwargs.length > 0
11
- new(**kwargs)
12
- else
13
- new(*args)
14
- end
15
- instance.call
16
-
17
- yield(instance) if block_given?
18
-
19
- instance
20
- end
21
-
22
- def call
23
- raise NotImplementedError
24
- end
25
-
26
- def errors
27
- @errors ||= []
28
- end
29
-
30
- def error_messages(separator = ", ")
31
- errors.join(separator)
32
- end
33
-
34
- def success?
35
- !failure?
36
- end
37
- alias_method :ok?, :success?
38
-
39
- def failure?
40
- errors.any?
41
- end
42
- alias_method :error?, :failure?
43
- end
44
- end
2
+ require 'serviz/base'
3
+ require 'serviz/workflow'
data/spec/scenarios.rb CHANGED
@@ -25,3 +25,32 @@ end
25
25
 
26
26
  class NoCall < Serviz::Base
27
27
  end
28
+
29
+ # Test services for Workflow
30
+ class Step1 < Serviz::Base
31
+ def initialize(some_flag: nil)
32
+ @some_flag = some_flag
33
+ end
34
+
35
+ def call
36
+ if @some_flag
37
+ self.result = "step1_#{@some_flag}"
38
+ else
39
+ self.errors << 'Step1 failed'
40
+ end
41
+ end
42
+ end
43
+
44
+ class Step2 < Serviz::Base
45
+ def initialize(some_flag: nil)
46
+ @some_flag = some_flag
47
+ end
48
+
49
+ def call
50
+ if @some_flag
51
+ self.result = "step2_#{@some_flag}"
52
+ else
53
+ self.errors << 'Step2 failed'
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,60 @@
1
+ RSpec.describe Serviz::Workflow do
2
+ describe "basic workflow execution" do
3
+ it "executes steps in sequence and returns the last result" do
4
+ workflow = Class.new(Serviz::Workflow) do
5
+ step Step1, params: ->(instance) { { some_flag: instance.instance_variable_get(:@arg1) } }
6
+ step Step2, params: ->(instance) { { some_flag: instance.instance_variable_get(:@arg2) } }
7
+
8
+ def initialize(arg1, arg2)
9
+ super()
10
+ @arg1 = arg1
11
+ @arg2 = arg2
12
+ end
13
+ end
14
+
15
+ operation = workflow.call("test1", "test2")
16
+
17
+ expect(operation.success?).to eq true
18
+ expect(operation.result).to eq "step2_test2"
19
+ end
20
+
21
+ it "accumulates errors from failed steps" do
22
+ workflow = Class.new(Serviz::Workflow) do
23
+ step Step1, params: { some_flag: nil } # This will fail
24
+ step Step2, params: { some_flag: "test" }
25
+ end
26
+
27
+ operation = workflow.call
28
+
29
+ expect(operation.failure?).to eq true
30
+ expect(operation.errors).to include('Step1 failed')
31
+ end
32
+ end
33
+
34
+ describe "conditional execution" do
35
+ it "skips steps when condition is false" do
36
+ workflow = Class.new(Serviz::Workflow) do
37
+ step Step1, params: { some_flag: nil } # This will fail
38
+ step Step2, params: { some_flag: "test" }, if: ->(operation) { operation.success? }
39
+ end
40
+
41
+ operation = workflow.call
42
+
43
+ expect(operation.failure?).to eq true
44
+ expect(operation.errors).to eq(['Step1 failed'])
45
+ expect(operation.result).to be_nil
46
+ end
47
+
48
+ it "executes steps when condition is true" do
49
+ workflow = Class.new(Serviz::Workflow) do
50
+ step Step1, params: { some_flag: "test1" } # This will succeed
51
+ step Step2, params: { some_flag: "test2" }, if: ->(operation) { operation.success? }
52
+ end
53
+
54
+ operation = workflow.call
55
+
56
+ expect(operation.success?).to eq true
57
+ expect(operation.result).to eq "step2_test2"
58
+ end
59
+ end
60
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serviz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - markets
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-19 00:00:00.000000000 Z
11
+ date: 2025-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,10 +60,13 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - lib/serviz.rb
63
+ - lib/serviz/base.rb
63
64
  - lib/serviz/version.rb
65
+ - lib/serviz/workflow.rb
66
+ - spec/base_spec.rb
64
67
  - spec/scenarios.rb
65
- - spec/serviz_spec.rb
66
68
  - spec/spec_helper.rb
69
+ - spec/workflow_spec.rb
67
70
  homepage: https://github.com/markets/serviz
68
71
  licenses:
69
72
  - MIT
@@ -88,6 +91,7 @@ signing_key:
88
91
  specification_version: 4
89
92
  summary: Command object Interface for Ruby
90
93
  test_files:
94
+ - spec/base_spec.rb
91
95
  - spec/scenarios.rb
92
- - spec/serviz_spec.rb
93
96
  - spec/spec_helper.rb
97
+ - spec/workflow_spec.rb
File without changes