command_service_object 0.3.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb7c2967cb51ce592d31d4b34f08175449af0784d09a5a99d8d5ebd34cc94dd5
4
- data.tar.gz: f8ea42c732274054c729ded305f92f38de7b162cc959d96efa1d9b8c054cf982
3
+ metadata.gz: 4039a3dbbda00504a1bcecf192eeadbc2d713421a1a3abcbea48b42776a1c556
4
+ data.tar.gz: eb5e934d9f3ec8ef0d292d7f82b8330c334e6f595da77eee4519e9295b320786
5
5
  SHA512:
6
- metadata.gz: e3cfa831018cb98fe78a4118266a8059c336c771571b891d07cbac6f7015b6d6857cbb2c2afd22543a9f4b41dd86bcbd1e5eb368ca6b7103d3e5aac4434b6361
7
- data.tar.gz: 60e06975870a9557b169e2ad29e86b964f8d7e4a2ecf0a5d2886e4a462d4461280e50f010468e70045ca882e7b6fa81f1dae4f12e15d3b3f3101d0c5e2fcb3e4
6
+ metadata.gz: 946455406a4ce0008936b985daa3d7c586bf5aa34d80ff3d5a19cba568bd2ace83fb2fb3036e3a670491ce4d1a9e345fa262c497f49df4a2109c832fd5b8e1dd
7
+ data.tar.gz: 891e869e8f625a7d865462d388b4b86fd7d14bac5e6184710bf179dfdfe78234aaa8e39c92e46ab7ceb16584092f97b636f03b2d0120a73c1c7dd67defdc3023
@@ -1,3 +1,3 @@
1
1
  module CommandServiceObject
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.3.1'.freeze
3
3
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rubygems'
3
4
  require 'rails/generators/model_helpers'
4
5
 
5
6
  class ServiceGenerator < Rails::Generators::NamedBase
@@ -8,15 +9,17 @@ class ServiceGenerator < Rails::Generators::NamedBase
8
9
  source_root File.expand_path('templates', __dir__)
9
10
 
10
11
  argument :usecases, type: :array, default: [], banner: 'usecase usecase'
11
- class_option :skip_command, type: :boolean, default: false,
12
+ class_option :skip_command, type: :boolean, default: false, aliases: '-C',
12
13
  desc: 'skip command file generation'
13
- class_option :skip_error, type: :boolean, default: false,
14
+ class_option :skip_error, type: :boolean, default: false, aliases: '-E',
14
15
  desc: 'skip error file generation'
16
+ class_option :skip_test, type: :boolean, default: false, aliases: '-T',
17
+ desc: 'skip test file generation'
15
18
 
16
19
  def create_base_dir
17
20
  return if File.exist?('app/services')
18
21
 
19
- directory 'services', 'app/services'
22
+ directory 'base', 'app/services'
20
23
  end
21
24
 
22
25
  def create_service_dir
@@ -28,21 +31,67 @@ class ServiceGenerator < Rails::Generators::NamedBase
28
31
  empty_directory("app/services/#{service_name}/errors")
29
32
  end
30
33
 
31
- def create_usecases
34
+ def generate_usecases
32
35
  usecases.each do |usecase|
33
- @usecase = usecase
34
- u_path = "app/services/#{service_name}/usecases/#{usecase.underscore}.rb"
35
- c_path = "app/services/#{service_name}/commands/#{usecase.underscore}.rb"
36
- e_path = "app/services/#{service_name}/errors/#{usecase.underscore}.rb"
37
-
38
- template 'usecase.rb.erb', u_path
39
- template 'command.rb.erb', c_path unless options.skip_command?
40
- template 'error.rb.erb', e_path unless options.skip_error?
36
+ generate_usecase(usecase)
37
+ generate_command(usecase)
38
+ generate_error(usecase)
39
+ generate_test(usecase)
41
40
  end
42
41
  end
43
42
 
44
43
  private
45
44
 
45
+ def generate_usecase(usecase)
46
+ @usecase = usecase.classify
47
+ path = "app/services/#{service_name}/usecases/#{usecase.underscore}.rb"
48
+ template 'usecase.rb.erb', path
49
+ end
50
+
51
+ def generate_command(command)
52
+ @command = command.classify
53
+ path = "app/services/#{service_name}/commands/#{command.underscore}.rb"
54
+ template 'command.rb.erb', path unless options.skip_command?
55
+ end
56
+
57
+ def generate_error(error)
58
+ @error = error.classify
59
+ path = "app/services/#{service_name}/errors/#{error.underscore}.rb"
60
+ template 'error.rb.erb', path unless options.skip_error?
61
+ end
62
+
63
+ def generate_test(test)
64
+ return if options.skip_test?
65
+
66
+ if defined?(Minitest)
67
+ empty_directory('test/services')
68
+ generate_minitest_test_files(test)
69
+ elsif defined?(RSpec)
70
+ empty_directory('spec/services')
71
+ generate_rspec_test_files(test)
72
+ end
73
+ end
74
+
75
+ def generate_minitest_test_files(test)
76
+ dir = "test/services/#{service_name}"
77
+ empty_directory(dir)
78
+
79
+ @test = test.classify
80
+ path = "#{dir}/#{test.underscore}_test.rb"
81
+
82
+ template 'minitest.rb.erb', path
83
+ end
84
+
85
+ def generate_rspec_test_files(test)
86
+ dir = "spec/services/#{service_name}"
87
+ empty_directory(dir)
88
+
89
+ @test = test.classify
90
+ path = "#{dir}/#{test.underscore}_spec.rb"
91
+
92
+ template 'rspec.rb.erb', path
93
+ end
94
+
46
95
  def service_name
47
96
  "#{name.underscore}_service"
48
97
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationService < ServiceBase
4
+ def call
5
+ ServiceResult.new do
6
+ cmd.class.name.gsub('Commands', 'Usecases').constantize.call(cmd)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ServiceBase
4
+ attr_reader :cmd
5
+
6
+ def initialize(command)
7
+ @cmd = command
8
+ end
9
+
10
+ def self.call(command)
11
+ raise Errors::InvalidCommand, command.class if command.invalid?
12
+
13
+ new(command).call
14
+ end
15
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ServiceResult
4
+ attr_reader :error
5
+
6
+ def initialize
7
+ @value = yield
8
+ @error = nil
9
+ rescue StandardError => e
10
+ @error = e
11
+ end
12
+
13
+ def to_s
14
+ if ok?
15
+ format('#<Result:0x%x value: %s>', object_id, @value.inspect)
16
+ else
17
+ format('#<Result:0x%x error: %s>', object_id, @error.inspect)
18
+ end
19
+ end
20
+
21
+ alias inspect to_s
22
+
23
+ def then
24
+ return self unless ok?
25
+
26
+ result = yield(@value)
27
+ raise TypeError, 'block invoked in Result#then did not return Result' unless result.is_a?(Result)
28
+
29
+ result
30
+ end
31
+
32
+ def rescue
33
+ return self if ok?
34
+
35
+ result = yield(@error)
36
+ raise TypeError, 'block invoked in Result#rescue did not return Result' unless result.is_a?(Result)
37
+
38
+ result
39
+ end
40
+
41
+ def value
42
+ raise ArgumentError, 'must provide a block to Result#value to be invoked in case of error' unless block_given?
43
+
44
+ return @value if ok?
45
+
46
+ yield(@error)
47
+ end
48
+
49
+ def value!
50
+ raise @error unless ok?
51
+
52
+ @value
53
+ end
54
+
55
+ def ok?
56
+ !@error
57
+ end
58
+
59
+ def self.error(err)
60
+ result = allocate
61
+ result.instance_variable_set(:@error, err)
62
+ result
63
+ end
64
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module <%= service_name.classify %>::Commands
4
- class <%= @usecase.classify %>
4
+ class <%= @command %>
5
5
  # You can read Virtus gem doc for more info.
6
6
  # https://github.com/solnic/virtus
7
7
  include Virtus.model
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module <%= service_name.classify %>::Errors
4
- class <%= @usecase.classify %> < StandardError
4
+ class <%= @error %> < StandardError
5
5
  def initialize(msg = "custom message")
6
6
  super(msg)
7
7
  end
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -1,17 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module <%= service_name.classify %>::Usecases
4
- class <%= @usecase.classify %> < ServiceBase
4
+ class <%= @usecase %> < ServiceBase
5
5
  #
6
6
  # Your business logic goes here, keep [call] method clean by using private
7
7
  # methods for Business logic.
8
8
  #
9
9
  def call
10
- replace_me
10
+ begin
11
+ replace_me
12
+ rescue => e
13
+ rollback
14
+ raise e
15
+ end
11
16
  end
12
17
 
13
18
  private
14
19
 
20
+ def rollback;end
21
+
15
22
  def replace_me
16
23
  # [business logic]
17
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_service_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adham EL-Deeb
@@ -104,8 +104,13 @@ files:
104
104
  - lib/command_service_object/version.rb
105
105
  - lib/generators/service/USAGE
106
106
  - lib/generators/service/service_generator.rb
107
+ - lib/generators/service/templates/base/application_service.rb
108
+ - lib/generators/service/templates/base/service_base.rb
109
+ - lib/generators/service/templates/base/service_result.rb
107
110
  - lib/generators/service/templates/command.rb.erb
108
111
  - lib/generators/service/templates/error.rb.erb
112
+ - lib/generators/service/templates/minitest.rb.erb
113
+ - lib/generators/service/templates/rspec.rb.erb
109
114
  - lib/generators/service/templates/usecase.rb.erb
110
115
  homepage: https://github.com/adham90/command_service_object
111
116
  licenses: