convenient_service 0.3.1 → 0.4.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.dev/.tmuxinator.yml +17 -0
  3. data/CHANGELOG.md +15 -0
  4. data/README.md +8 -8
  5. data/Taskfile.yml +30 -0
  6. data/lib/convenient_service/rspec/matchers/custom/results/base.rb +245 -0
  7. data/lib/convenient_service/rspec/matchers/custom/results/be_error.rb +3 -139
  8. data/lib/convenient_service/rspec/matchers/custom/results/be_failure.rb +3 -106
  9. data/lib/convenient_service/rspec/matchers/custom/results/be_not_error.rb +20 -0
  10. data/lib/convenient_service/rspec/matchers/custom/results/be_not_failure.rb +20 -0
  11. data/lib/convenient_service/rspec/matchers/custom/results/be_not_success.rb +20 -0
  12. data/lib/convenient_service/rspec/matchers/custom/results/be_success.rb +3 -112
  13. data/lib/convenient_service/rspec/matchers/custom/results.rb +6 -0
  14. data/lib/convenient_service/rspec/matchers/results/be_not_error.rb +15 -0
  15. data/lib/convenient_service/rspec/matchers/results/be_not_failure.rb +15 -0
  16. data/lib/convenient_service/rspec/matchers/results/be_not_success.rb +15 -0
  17. data/lib/convenient_service/rspec/matchers/results.rb +8 -0
  18. data/lib/convenient_service/service/plugins/has_result/constants.rb +1 -4
  19. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +8 -0
  20. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/status.rb +4 -0
  21. data/lib/convenient_service/service/plugins/has_result_method_steps/middleware.rb +1 -4
  22. data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +8 -2
  23. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +1 -1
  24. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +1 -1
  25. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +1 -1
  26. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +15 -8
  27. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +0 -1
  28. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +15 -1
  29. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +10 -0
  30. data/lib/convenient_service/support/gems/rspec.rb +9 -2
  31. data/lib/convenient_service/support/raw_value.rb +52 -0
  32. data/lib/convenient_service/support.rb +1 -0
  33. data/lib/convenient_service/version.rb +1 -1
  34. metadata +11 -4
  35. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/raw.rb +0 -48
  36. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb +0 -3
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Custom
7
+ module Results
8
+ class BeNotSuccess < Results::Base
9
+ def statuses
10
+ [
11
+ Service::Plugins::HasResult::Constants::ERROR_STATUS,
12
+ Service::Plugins::HasResult::Constants::FAILURE_STATUS
13
+ ]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,118 +5,9 @@ module ConvenientService
5
5
  module Matchers
6
6
  module Custom
7
7
  module Results
8
- class BeSuccess
9
- def matches?(result)
10
- @result = result
11
-
12
- rules = []
13
-
14
- rules << ->(result) { result.class.include?(ConvenientService::Service::Plugins::HasResult::Entities::Result::Concern) }
15
- rules << ->(result) { result.success? }
16
- rules << ->(result) { result.service.instance_of?(service_class) } if used_of?
17
- rules << ->(result) { result.data == data } if used_data?
18
-
19
- condition = ConvenientService::Utils::Proc.conjunct(rules)
20
-
21
- condition.call(result)
22
- end
23
-
24
- def with_data(data)
25
- chain[:data] = data
26
-
27
- self
28
- end
29
-
30
- def without_data
31
- chain[:data] = {}
32
-
33
- self
34
- end
35
-
36
- def of(service_class)
37
- chain[:service_class] = service_class
38
-
39
- self
40
- end
41
-
42
- def description
43
- ##
44
- # TODO: of
45
- #
46
- parts = []
47
-
48
- parts << "be a `success`"
49
- parts << "of `#{service_class}`" if used_of?
50
- parts << "with data `#{data}`" if used_data?
51
- parts << "\n\n"
52
- parts << "got `#{result.status}`"
53
- parts << "of `#{result.service.class}`" if used_of?
54
- parts << "with data `#{result.data.to_h}`" if used_data?
55
-
56
- parts.join(" ")
57
- end
58
-
59
- def failure_message
60
- ##
61
- # TODO: got text after expect text.
62
- #
63
- parts = []
64
-
65
- parts << "expected that `#{result}` would be a `success`"
66
- parts << "of `#{service_class}`" if used_of?
67
- parts << "with data `#{data}`" if used_data?
68
- parts << "\n\n"
69
- parts << "got `#{result.status}`"
70
- parts << "of `#{result.service.class}`" if used_of?
71
- parts << "with data `#{result.data.to_h}`" if used_data?
72
-
73
- parts.join(" ")
74
- end
75
-
76
- ##
77
- # https://relishapp.com/rspec/rspec-expectations/v/3-11/docs/custom-matchers/define-a-custom-matcher#overriding-the-failure-message-when-negated
78
- #
79
- def failure_message_when_negated
80
- ##
81
- # TODO: got text after expect text.
82
- #
83
- parts = []
84
-
85
- parts << "expected that #{result} would NOT be a `success`"
86
- parts << "of `#{service_class}`" if used_of?
87
- parts << "with data `#{data}`" if used_data?
88
- parts << "\n\n"
89
- parts << "got `#{result.status}`"
90
- parts << "of `#{result.service.class}`" if used_of?
91
- parts << "with data `#{result.data.to_h}`" if used_data?
92
-
93
- parts.join(" ")
94
- end
95
-
96
- private
97
-
98
- attr_reader :result
99
-
100
- def used_data?
101
- chain.key?(:data)
102
- end
103
-
104
- def used_of?
105
- chain.key?(:service_class)
106
- end
107
-
108
- def chain
109
- @chain ||= {}
110
- end
111
-
112
- def data
113
- @data ||= chain[:data] || {}
114
- end
115
-
116
- def service_class
117
- return @service_class if defined? @service_class
118
-
119
- @service_class = chain[:service_class]
8
+ class BeSuccess < Results::Base
9
+ def statuses
10
+ [Service::Plugins::HasResult::Constants::SUCCESS_STATUS]
120
11
  end
121
12
  end
122
13
  end
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "results/base"
4
+
3
5
  require_relative "results/be_error"
4
6
  require_relative "results/be_failure"
5
7
  require_relative "results/be_success"
8
+
9
+ require_relative "results/be_not_error"
10
+ require_relative "results/be_not_failure"
11
+ require_relative "results/be_not_success"
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Results
7
+ module BeNotError
8
+ def be_not_error(...)
9
+ Custom::Results::BeNotError.new(...)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Results
7
+ module BeNotFailure
8
+ def be_not_failure(...)
9
+ Custom::Results::BeNotFailure.new(...)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Results
7
+ module BeNotSuccess
8
+ def be_not_success(...)
9
+ Custom::Results::BeNotSuccess.new(...)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,6 +4,10 @@ require_relative "results/be_error"
4
4
  require_relative "results/be_failure"
5
5
  require_relative "results/be_success"
6
6
 
7
+ require_relative "results/be_not_error"
8
+ require_relative "results/be_not_failure"
9
+ require_relative "results/be_not_success"
10
+
7
11
  module ConvenientService
8
12
  module RSpec
9
13
  module Matchers
@@ -14,6 +18,10 @@ module ConvenientService
14
18
  include Results::BeError
15
19
  include Results::BeFailure
16
20
  include Results::BeSuccess
21
+
22
+ include Results::BeNotError
23
+ include Results::BeNotFailure
24
+ include Results::BeNotSuccess
17
25
  end
18
26
  end
19
27
  end
@@ -5,10 +5,7 @@ module ConvenientService
5
5
  module Plugins
6
6
  module HasResult
7
7
  module Constants
8
- ##
9
- # TODO: Consider to include `::ConvenientService::Configs::Minimal`
10
- #
11
- DEFAULT_SERVICE_CLASS = ::Class.new { include ::ConvenientService::Core }
8
+ DEFAULT_SERVICE_CLASS = ::Class.new { include ::ConvenientService::Service::Plugins::HasResult::Concern }
12
9
  DEFAULT_SERVICE_INSTANCE = DEFAULT_SERVICE_CLASS.new
13
10
 
14
11
  SUCCESS_STATUS = :success
@@ -22,6 +22,14 @@ module ConvenientService
22
22
  @value = value
23
23
  end
24
24
 
25
+ ##
26
+ # @param key [String, Symbol]
27
+ # @return [Boolean]
28
+ #
29
+ def has_attribute?(key)
30
+ value.has_key?(key.to_sym)
31
+ end
32
+
25
33
  def ==(other)
26
34
  casted = cast(other)
27
35
 
@@ -54,6 +54,10 @@ module ConvenientService
54
54
  !error?
55
55
  end
56
56
 
57
+ def in?(statuses)
58
+ statuses.any? { |status| self == status }
59
+ end
60
+
57
61
  def to_s
58
62
  @to_s ||= value.to_s
59
63
  end
@@ -24,11 +24,8 @@ module ConvenientService
24
24
 
25
25
  private
26
26
 
27
- ##
28
- # TODO: `Plugins::HasResultSteps::Entities::Method.raw_value`.
29
- #
30
27
  def raw(object)
31
- Plugins::HasResultSteps::Entities::Method::Entities::Values::Raw.wrap(object)
28
+ Support::RawValue.wrap(object)
32
29
  end
33
30
  end
34
31
  end
@@ -33,10 +33,16 @@ module ConvenientService
33
33
  end
34
34
 
35
35
  ##
36
- # NOTE: Allows to pass a value to `in` method without processing it.
36
+ # Allows to pass a value to `in` method without its intermediate processing.
37
+ # @see https://marian13.github.io/convenient_service_docs/basics/step_to_result_translation_table
38
+ #
39
+ # @example `:chat_v2` is passed to `AssertFeatureEnabled` as it is.
40
+ # step AssertFeatureEnabled, in: {name: raw(:chat_v2)}
41
+ # # that is converted to the following service invocation:
42
+ # AssertFeatureEnabled.result(name: :chat_v2)
37
43
  #
38
44
  def raw(value)
39
- Entities::Method::Entities::Values::Raw.wrap(value)
45
+ Support::RawValue.wrap(value)
40
46
  end
41
47
 
42
48
  def steps
@@ -49,7 +49,7 @@ module ConvenientService
49
49
  Entities::Callers::Alias.new(value)
50
50
  when ::Proc
51
51
  Entities::Callers::Proc.new(value)
52
- when Entities::Values::Raw
52
+ when Support::RawValue
53
53
  Entities::Callers::Raw.new(value)
54
54
  end
55
55
  end
@@ -53,7 +53,7 @@ module ConvenientService
53
53
  Entities::Key.new(key)
54
54
  when ::Proc
55
55
  Entities::Key.new(key)
56
- when Entities::Values::Raw
56
+ when Support::RawValue
57
57
  Entities::Key.new(key)
58
58
  end
59
59
  end
@@ -53,7 +53,7 @@ module ConvenientService
53
53
  Entities::Name.new(value)
54
54
  when ::Proc
55
55
  Entities::Name.new(key)
56
- when Entities::Values::Raw
56
+ when Support::RawValue
57
57
  Entities::Name.new(key)
58
58
  end
59
59
  end
@@ -26,11 +26,13 @@ module ConvenientService
26
26
  #
27
27
  <<~RUBY.tap { |code| container.klass.class_eval(code, __FILE__, __LINE__ + 1) }
28
28
  def #{name}
29
- step, key, name, error = steps[#{index}], :#{key}, :#{name}, #{error}
29
+ step, key, method_name = steps[#{index}], :#{key}, :#{name}
30
30
 
31
- return step.result.data[key] if step.completed?
31
+ raise #{not_completed_step_error}.new(step: step, method_name: method_name) unless step.completed?
32
32
 
33
- raise ::#{error}.new(step: step, method_name: name)
33
+ raise #{not_existing_step_result_data_attribute_error}.new(step: step, key: key) unless step.result.data.has_attribute?(key)
34
+
35
+ step.result.data[key]
34
36
  end
35
37
  RUBY
36
38
 
@@ -39,11 +41,16 @@ module ConvenientService
39
41
 
40
42
  private
41
43
 
42
- def error
43
- @error ||=
44
- <<~RUBY.chomp
45
- ConvenientService::Service::Plugins::HasResultSteps::Entities::Method::Errors::NotCompletedStep
46
- RUBY
44
+ def not_completed_step_error
45
+ <<~RUBY.chomp
46
+ ::ConvenientService::Service::Plugins::HasResultSteps::Entities::Method::Errors::NotCompletedStep
47
+ RUBY
48
+ end
49
+
50
+ def not_existing_step_result_data_attribute_error
51
+ <<~RUBY.chomp
52
+ ::ConvenientService::Service::Plugins::HasResultSteps::Entities::Method::Errors::NotExistingStepResultDataAttribute
53
+ RUBY
47
54
  end
48
55
  end
49
56
  end
@@ -4,4 +4,3 @@ require_relative "entities/directions"
4
4
  require_relative "entities/callers"
5
5
  require_relative "entities/key"
6
6
  require_relative "entities/name"
7
- require_relative "entities/values"
@@ -110,7 +110,7 @@ module ConvenientService
110
110
  class NotCompletedStep < ConvenientService::Error
111
111
  def initialize(method_name:, step:)
112
112
  message = <<~TEXT
113
- `out` method `#{method_name}` is called before its corresponding step `#{step.service}` is completed.
113
+ `out` method `#{method_name}` is called before its corresponding step `#{step.printable_service}` is completed.
114
114
 
115
115
  Maybe it makes sense to change the steps order?
116
116
  TEXT
@@ -118,6 +118,20 @@ module ConvenientService
118
118
  super(message)
119
119
  end
120
120
  end
121
+
122
+ class NotExistingStepResultDataAttribute < ConvenientService::Error
123
+ def initialize(key:, step:)
124
+ message = <<~TEXT
125
+ Step `#{step.printable_service}` result does NOT return `#{key}` data attribute.
126
+
127
+ Maybe there is a typo in `out` definition?
128
+
129
+ Or `success` of `#{step.printable_service}` accepts a wrong key?
130
+ TEXT
131
+
132
+ super(message)
133
+ end
134
+ end
121
135
  end
122
136
  end
123
137
  end
@@ -70,6 +70,16 @@ module ConvenientService
70
70
  @result ||= calculate_result
71
71
  end
72
72
 
73
+ ##
74
+ # @return [String]
75
+ #
76
+ # @internal
77
+ # TODO: printable service for methods steps.
78
+ #
79
+ def printable_service
80
+ service.klass.to_s
81
+ end
82
+
73
83
  def validate!
74
84
  inputs.each { |input| input.validate_as_input_for_container!(container) }
75
85
 
@@ -34,7 +34,7 @@ module ConvenientService
34
34
  # @return [RSpec::Core::Example, nil]
35
35
  #
36
36
  # @internal
37
- # NOTE: Returns `nil` in a non-test environment
37
+ # NOTE: Returns `nil` in environments where RSpec is NOT fully loaded, e.g: irb, rails console, etc.
38
38
  #
39
39
  # `::RSpec.current_example` docs:
40
40
  # - https://www.rubydoc.info/github/rspec/rspec-core/RSpec.current_example
@@ -42,7 +42,14 @@ module ConvenientService
42
42
  # - https://relishapp.com/rspec/rspec-core/docs/metadata/current-example
43
43
  #
44
44
  def current_example
45
- ::RSpec.current_example if loaded?
45
+ return unless loaded?
46
+
47
+ ##
48
+ # NOTE: This happens in Ruby-only projects where RSpec is loaded by `Bundler.require`, not by `bundle exec rspec`.
49
+ #
50
+ return unless ::RSpec.respond_to?(:current_example)
51
+
52
+ ::RSpec.current_example
46
53
  end
47
54
  end
48
55
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Support
5
+ class RawValue
6
+ ##
7
+ # @param object [Object] Can be any type.
8
+ # @return [void]
9
+ #
10
+ def initialize(object)
11
+ @object = object
12
+ end
13
+
14
+ class << self
15
+ ##
16
+ # @param object [Object] Can be any type.
17
+ # @return [ConvenientService::Support::RawValue]
18
+ #
19
+ def wrap(object)
20
+ new(object)
21
+ end
22
+
23
+ private :new
24
+ end
25
+
26
+ ##
27
+ # @return [Object] Can be any type.
28
+ #
29
+ def unwrap
30
+ object
31
+ end
32
+
33
+ ##
34
+ # @return [Boolean, nil]
35
+ #
36
+ def ==(other)
37
+ return unless other.instance_of?(self.class)
38
+
39
+ return false if object != other.object
40
+
41
+ true
42
+ end
43
+
44
+ protected
45
+
46
+ ##
47
+ # @return [Object] Can be any type.
48
+ #
49
+ attr_reader :object
50
+ end
51
+ end
52
+ end
@@ -11,5 +11,6 @@ require_relative "support/delegate"
11
11
  require_relative "support/finite_loop"
12
12
  require_relative "support/gems"
13
13
  require_relative "support/middleware"
14
+ require_relative "support/raw_value"
14
15
  require_relative "support/ruby"
15
16
  require_relative "support/version"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConvenientService
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: convenient_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marian Kostyk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-19 00:00:00.000000000 Z
11
+ date: 2023-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -301,6 +301,7 @@ executables: []
301
301
  extensions: []
302
302
  extra_rdoc_files: []
303
303
  files:
304
+ - ".dev/.tmuxinator.yml"
304
305
  - ".dockerignore"
305
306
  - ".gem_release.yml"
306
307
  - ".github/issue_template.md"
@@ -529,8 +530,12 @@ files:
529
530
  - lib/convenient_service/rspec/matchers/custom/include_module.rb
530
531
  - lib/convenient_service/rspec/matchers/custom/prepend_module.rb
531
532
  - lib/convenient_service/rspec/matchers/custom/results.rb
533
+ - lib/convenient_service/rspec/matchers/custom/results/base.rb
532
534
  - lib/convenient_service/rspec/matchers/custom/results/be_error.rb
533
535
  - lib/convenient_service/rspec/matchers/custom/results/be_failure.rb
536
+ - lib/convenient_service/rspec/matchers/custom/results/be_not_error.rb
537
+ - lib/convenient_service/rspec/matchers/custom/results/be_not_failure.rb
538
+ - lib/convenient_service/rspec/matchers/custom/results/be_not_success.rb
534
539
  - lib/convenient_service/rspec/matchers/custom/results/be_success.rb
535
540
  - lib/convenient_service/rspec/matchers/delegate_to.rb
536
541
  - lib/convenient_service/rspec/matchers/extend_module.rb
@@ -544,6 +549,9 @@ files:
544
549
  - lib/convenient_service/rspec/matchers/results.rb
545
550
  - lib/convenient_service/rspec/matchers/results/be_error.rb
546
551
  - lib/convenient_service/rspec/matchers/results/be_failure.rb
552
+ - lib/convenient_service/rspec/matchers/results/be_not_error.rb
553
+ - lib/convenient_service/rspec/matchers/results/be_not_failure.rb
554
+ - lib/convenient_service/rspec/matchers/results/be_not_success.rb
547
555
  - lib/convenient_service/rspec/matchers/results/be_success.rb
548
556
  - lib/convenient_service/service.rb
549
557
  - lib/convenient_service/service/plugins.rb
@@ -660,8 +668,6 @@ files:
660
668
  - lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/directions/output.rb
661
669
  - lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/key.rb
662
670
  - lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/name.rb
663
- - lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb
664
- - lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/raw.rb
665
671
  - lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb
666
672
  - lib/convenient_service/service/plugins/has_result_steps/entities/service.rb
667
673
  - lib/convenient_service/service/plugins/has_result_steps/entities/service/class_methods.rb
@@ -702,6 +708,7 @@ files:
702
708
  - lib/convenient_service/support/gems/rspec.rb
703
709
  - lib/convenient_service/support/middleware.rb
704
710
  - lib/convenient_service/support/middleware/stack_builder.rb
711
+ - lib/convenient_service/support/raw_value.rb
705
712
  - lib/convenient_service/support/ruby.rb
706
713
  - lib/convenient_service/support/version.rb
707
714
  - lib/convenient_service/support/version/null_version.rb
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ConvenientService
4
- module Service
5
- module Plugins
6
- module HasResultSteps
7
- module Entities
8
- class Method
9
- module Entities
10
- module Values
11
- ##
12
- # TODO: Specs.
13
- #
14
- class Raw
15
- def initialize(object)
16
- @object = object
17
- end
18
-
19
- class << self
20
- def wrap(object)
21
- new(object)
22
- end
23
-
24
- private :new
25
- end
26
-
27
- def unwrap
28
- object
29
- end
30
-
31
- def ==(other)
32
- return unless other.instance_of?(self.class)
33
-
34
- object == other.object
35
- end
36
-
37
- protected
38
-
39
- attr_reader :object
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "values/raw"