convenient_service 0.3.1 → 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 +4 -4
- data/.dev/.tmuxinator.yml +17 -0
- data/CHANGELOG.md +22 -0
- data/README.md +8 -8
- data/Taskfile.yml +30 -0
- data/convenient_service.gemspec +1 -1
- data/lib/convenient_service/aliases.rb +5 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base.rb +245 -0
- data/lib/convenient_service/rspec/matchers/custom/results/be_error.rb +3 -139
- data/lib/convenient_service/rspec/matchers/custom/results/be_failure.rb +3 -106
- data/lib/convenient_service/rspec/matchers/custom/results/be_not_error.rb +20 -0
- data/lib/convenient_service/rspec/matchers/custom/results/be_not_failure.rb +20 -0
- data/lib/convenient_service/rspec/matchers/custom/results/be_not_success.rb +20 -0
- data/lib/convenient_service/rspec/matchers/custom/results/be_success.rb +3 -112
- data/lib/convenient_service/rspec/matchers/custom/results.rb +6 -0
- data/lib/convenient_service/rspec/matchers/results/be_not_error.rb +15 -0
- data/lib/convenient_service/rspec/matchers/results/be_not_failure.rb +15 -0
- data/lib/convenient_service/rspec/matchers/results/be_not_success.rb +15 -0
- data/lib/convenient_service/rspec/matchers/results.rb +8 -0
- data/lib/convenient_service/service/plugins/has_result/constants.rb +1 -4
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +8 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/status.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result_method_steps/middleware.rb +1 -4
- data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +8 -2
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +1 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +1 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +1 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +15 -8
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +0 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +15 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +10 -0
- data/lib/convenient_service/support/dependency_container/commands/create_methods_module.rb +27 -0
- data/lib/convenient_service/support/dependency_container/commands/import_method.rb +111 -0
- data/lib/convenient_service/support/dependency_container/commands.rb +4 -0
- data/lib/convenient_service/support/dependency_container/constants.rb +15 -0
- data/lib/convenient_service/support/dependency_container/entities/method.rb +121 -0
- data/lib/convenient_service/support/dependency_container/entities/method_collection.rb +98 -0
- data/lib/convenient_service/support/dependency_container/entities/namespace.rb +69 -0
- data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +103 -0
- data/lib/convenient_service/support/dependency_container/entities.rb +6 -0
- data/lib/convenient_service/support/dependency_container/errors.rb +49 -0
- data/lib/convenient_service/support/dependency_container/export.rb +30 -0
- data/lib/convenient_service/support/dependency_container/import.rb +30 -0
- data/lib/convenient_service/support/dependency_container.rb +9 -0
- data/lib/convenient_service/support/gems/rspec.rb +9 -2
- data/lib/convenient_service/support/not_passed.rb +7 -0
- data/lib/convenient_service/support/raw_value.rb +52 -0
- data/lib/convenient_service/support.rb +3 -0
- data/lib/convenient_service/utils/module/fetch_own_const.rb +88 -0
- data/lib/convenient_service/utils/module/include_module.rb +38 -0
- data/lib/convenient_service/utils/module.rb +10 -0
- data/lib/convenient_service/utils/proc/conjunct.rb +1 -1
- data/lib/convenient_service/utils/string/split.rb +41 -0
- data/lib/convenient_service/utils/string.rb +5 -0
- data/lib/convenient_service/version.rb +1 -1
- data/lib/convenient_service.rb +6 -0
- metadata +33 -8
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/raw.rb +0 -48
- 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 BeNotFailure < Results::Base
|
9
|
+
def statuses
|
10
|
+
[
|
11
|
+
Service::Plugins::HasResult::Constants::ERROR_STATUS,
|
12
|
+
Service::Plugins::HasResult::Constants::SUCCESS_STATUS
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -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
|
10
|
-
|
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"
|
@@ -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
|
@@ -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
|
-
|
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
|
-
#
|
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
|
-
|
45
|
+
Support::RawValue.wrap(value)
|
40
46
|
end
|
41
47
|
|
42
48
|
def steps
|
@@ -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,
|
29
|
+
step, key, method_name = steps[#{index}], :#{key}, :#{name}
|
30
30
|
|
31
|
-
|
31
|
+
raise #{not_completed_step_error}.new(step: step, method_name: method_name) unless step.completed?
|
32
32
|
|
33
|
-
raise
|
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
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
@@ -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.
|
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
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class CreateMethodsModule < Support::Command
|
8
|
+
##
|
9
|
+
# @return [Module]
|
10
|
+
#
|
11
|
+
def call
|
12
|
+
::Module.new do
|
13
|
+
class << self
|
14
|
+
##
|
15
|
+
# @return namespaces [ConvenientService::Support::DependencyContainer::Entities::NamespaceCollection]
|
16
|
+
#
|
17
|
+
def namespaces
|
18
|
+
@namespaces ||= Entities::NamespaceCollection.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class ImportMethod < Support::Command
|
8
|
+
##
|
9
|
+
# @!attribute [r] importing_module
|
10
|
+
# @return [Module]
|
11
|
+
#
|
12
|
+
attr_reader :importing_module
|
13
|
+
|
14
|
+
##
|
15
|
+
# @!attribute [r] exporting_module
|
16
|
+
# @return [Module]
|
17
|
+
#
|
18
|
+
attr_reader :exporting_module
|
19
|
+
|
20
|
+
##
|
21
|
+
# @!attribute [r] method
|
22
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
23
|
+
#
|
24
|
+
attr_reader :method
|
25
|
+
|
26
|
+
##
|
27
|
+
# @!attribute [r] scope
|
28
|
+
# @return [Symbol]
|
29
|
+
#
|
30
|
+
attr_reader :scope
|
31
|
+
|
32
|
+
##
|
33
|
+
# @!attribute [r] prepend
|
34
|
+
# @return [Boolean]
|
35
|
+
#
|
36
|
+
attr_reader :prepend
|
37
|
+
|
38
|
+
##
|
39
|
+
# @param importing_module [Module]
|
40
|
+
# @param exporting_module [Module]
|
41
|
+
# @param method [ConvenientService::Support::DependencyContainer::Method]
|
42
|
+
# @param scope [:instance, :class]
|
43
|
+
# @param prepend [Boolean]
|
44
|
+
#
|
45
|
+
def initialize(importing_module:, exporting_module:, method:, scope:, prepend:)
|
46
|
+
@importing_module = importing_module
|
47
|
+
@exporting_module = exporting_module
|
48
|
+
@method = method
|
49
|
+
@scope = scope
|
50
|
+
@prepend = prepend
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
55
|
+
#
|
56
|
+
def call
|
57
|
+
import imported_scoped_methods
|
58
|
+
|
59
|
+
method.define_in_module!(imported_scoped_methods)
|
60
|
+
|
61
|
+
method
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
##
|
67
|
+
# @return [Module]
|
68
|
+
#
|
69
|
+
def imported_scoped_methods
|
70
|
+
@imported_scoped_methods ||= Utils::Module.fetch_own_const(importing_module, :"Imported#{imported_prefix}#{scoped_prefix}Methods") { Commands::CreateMethodsModule.call }
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# @return [String]
|
75
|
+
#
|
76
|
+
def imported_prefix
|
77
|
+
prepend ? "Prepended" : "Included"
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# @return [String]
|
82
|
+
#
|
83
|
+
def scoped_prefix
|
84
|
+
case scope
|
85
|
+
when Constants::INSTANCE_SCOPE then "Instance"
|
86
|
+
when Constants::CLASS_SCOPE then "Class"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# @return [Module, Class]
|
92
|
+
#
|
93
|
+
def importer
|
94
|
+
case scope
|
95
|
+
when Constants::INSTANCE_SCOPE then importing_module
|
96
|
+
when Constants::CLASS_SCOPE then importing_module.singleton_class
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# @param mod [Module]
|
102
|
+
# @return [Module]
|
103
|
+
#
|
104
|
+
def import(mod)
|
105
|
+
prepend ? importer.prepend(mod) : importer.include(mod)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Constants
|
7
|
+
INSTANCE_SCOPE = :instance
|
8
|
+
CLASS_SCOPE = :class
|
9
|
+
|
10
|
+
DEFAULT_SCOPE = Constants::INSTANCE_SCOPE
|
11
|
+
DEFAULT_PREPEND = false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|