servactory 3.1.0.rc2 → 3.1.0.rc3
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/LICENSE +21 -0
- data/README.md +2 -2
- data/config/locales/ja.yml +134 -0
- data/lib/generators/README.md +1 -1
- data/lib/servactory/configuration/config.rb +16 -0
- data/lib/servactory/configuration/configurable.rb +6 -3
- data/lib/servactory/configuration/hash_mode/class_names_collection.rb +4 -1
- data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +14 -0
- data/lib/servactory/inputs/tools/validation.rb +10 -18
- data/lib/servactory/maintenance/options/collection.rb +26 -16
- data/lib/servactory/maintenance/options/registrar.rb +1 -1
- data/lib/servactory/maintenance/validations/performer.rb +12 -23
- data/lib/servactory/test_kit/rspec/helpers/mock_executor.rb +6 -2
- data/lib/servactory/test_kit/rspec/helpers/service_mock_builder.rb +78 -8
- data/lib/servactory/test_kit/rspec/helpers/service_mock_config.rb +19 -2
- data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +5 -3
- data/lib/servactory/tool_kit/dynamic_options/format.rb +1 -1
- data/lib/servactory/tool_kit/dynamic_options/inclusion.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/max.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/min.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/multiple_of.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/schema.rb +6 -4
- data/lib/servactory/tool_kit/dynamic_options/target.rb +3 -3
- data/lib/servactory/version.rb +1 -1
- data/lib/servactory.rb +0 -4
- metadata +12 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5acfb374e0e85d7779b99658fcb899007ca346ca63c71344800490428ac61dd
|
|
4
|
+
data.tar.gz: 94ff484e768908909aa856d63310af3c896f198357b88c3089fe9393de53bc88
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61facdd48b89752c3f2bfe0735c87c24f83c225c2474608c9aa871f150003a996b2b4775ef25941f0916f45524383cdf1e1814a237b522add763782c2ec03e9b
|
|
7
|
+
data.tar.gz: 13202fe9276b8323cd83fc2c0919613eeabfd9d99b4d1cfac541ef7ed88739a84c6d5719a44ca76fe960c33aaf6a66b1b9c9353e12a1e5662b8e19df05a68fd3
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Anton Sokolov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -52,7 +52,7 @@ gem "servactory"
|
|
|
52
52
|
### Define service
|
|
53
53
|
|
|
54
54
|
```ruby
|
|
55
|
-
class
|
|
55
|
+
class Users::Authenticate < Servactory::Base
|
|
56
56
|
input :email, type: String
|
|
57
57
|
input :password, type: String
|
|
58
58
|
|
|
@@ -77,7 +77,7 @@ end
|
|
|
77
77
|
```ruby
|
|
78
78
|
class SessionsController < ApplicationController
|
|
79
79
|
def create
|
|
80
|
-
service =
|
|
80
|
+
service = Users::Authenticate.call(**session_params)
|
|
81
81
|
|
|
82
82
|
if service.success?
|
|
83
83
|
session[:current_user_id] = service.user.id
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
ja:
|
|
2
|
+
servactory:
|
|
3
|
+
common:
|
|
4
|
+
undefined_method:
|
|
5
|
+
missing_name: "[%{service_class_name}] %{error_text}"
|
|
6
|
+
methods:
|
|
7
|
+
call:
|
|
8
|
+
not_used: "[%{service_class_name}] 実行する処理がありません。`make`を使用するか、`call`メソッドを作成してください。"
|
|
9
|
+
cannot_be_overwritten: "[%{service_class_name}] 次のメソッドは上書きできません: %{list_of_methods}"
|
|
10
|
+
inputs:
|
|
11
|
+
undefined:
|
|
12
|
+
for_fetch: "[%{service_class_name}] 未定義の入力`%{input_name}`"
|
|
13
|
+
for_assign: "[%{service_class_name}] 未定義の入力`%{input_name}`"
|
|
14
|
+
validations:
|
|
15
|
+
must:
|
|
16
|
+
default_error: "[%{service_class_name}] 入力`%{input_name}`は「%{code}」を満たす必要があります"
|
|
17
|
+
syntax_error: "[%{service_class_name}] 入力`%{input_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
18
|
+
dynamic_options:
|
|
19
|
+
consists_of:
|
|
20
|
+
required: "[%{service_class_name}] 入力コレクション`%{input_name}`の必須要素が不足しています"
|
|
21
|
+
wrong_type: "[%{service_class_name}] 入力コレクション`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
22
|
+
wrong_element_type: "[%{service_class_name}] 入力コレクション`%{input_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
23
|
+
format:
|
|
24
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマットに一致しません"
|
|
25
|
+
wrong_pattern: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマットに一致しません"
|
|
26
|
+
wrong_type: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
27
|
+
unknown: "[%{service_class_name}] 入力`%{input_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
28
|
+
inclusion:
|
|
29
|
+
default: "[%{service_class_name}] `%{input_name}`の値が不正です。`%{input_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
30
|
+
invalid_option: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに値がありません"
|
|
31
|
+
min:
|
|
32
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
33
|
+
max:
|
|
34
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
35
|
+
multiple_of:
|
|
36
|
+
default: "[%{service_class_name}] 入力`%{input_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
37
|
+
blank: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
38
|
+
divided_by_0: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
39
|
+
schema:
|
|
40
|
+
wrong_type: "[%{service_class_name}] 入力`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
41
|
+
wrong_element_type: "[%{service_class_name}] 入力ハッシュ`%{input_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
42
|
+
wrong_element_value: "[%{service_class_name}] 入力ハッシュ`%{input_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
43
|
+
target:
|
|
44
|
+
default: "[%{service_class_name}] 入力`%{input_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
45
|
+
invalid_option: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに値がありません"
|
|
46
|
+
required:
|
|
47
|
+
default_error:
|
|
48
|
+
default: "[%{service_class_name}] 必須の入力`%{input_name}`が不足しています"
|
|
49
|
+
type:
|
|
50
|
+
default_error:
|
|
51
|
+
default: "[%{service_class_name}] 入力`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
52
|
+
tools:
|
|
53
|
+
find_unnecessary:
|
|
54
|
+
error: "[%{service_class_name}] 予期しない属性: `%{unnecessary_attributes}`"
|
|
55
|
+
rules:
|
|
56
|
+
error: "[%{service_class_name}] 入力`%{input_name}`のオプションに競合があります: `%{conflict_code}`"
|
|
57
|
+
internals:
|
|
58
|
+
undefined:
|
|
59
|
+
for_fetch: "[%{service_class_name}] 未定義の内部属性`%{internal_name}`"
|
|
60
|
+
for_assign: "[%{service_class_name}] 未定義の内部属性`%{internal_name}`"
|
|
61
|
+
validations:
|
|
62
|
+
must:
|
|
63
|
+
default_error: "[%{service_class_name}] 内部属性`%{internal_name}`は「%{code}」を満たす必要があります"
|
|
64
|
+
syntax_error: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
65
|
+
dynamic_options:
|
|
66
|
+
consists_of:
|
|
67
|
+
required: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の必須要素が不足しています"
|
|
68
|
+
wrong_type: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
69
|
+
wrong_element_type: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
70
|
+
format:
|
|
71
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマットに一致しません"
|
|
72
|
+
wrong_pattern: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマットに一致しません"
|
|
73
|
+
wrong_type: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
74
|
+
unknown: "[%{service_class_name}] 内部属性`%{internal_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
75
|
+
inclusion:
|
|
76
|
+
default: "[%{service_class_name}] `%{internal_name}`の値が不正です。`%{internal_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
77
|
+
invalid_option: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに値がありません"
|
|
78
|
+
min:
|
|
79
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
80
|
+
max:
|
|
81
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
82
|
+
multiple_of:
|
|
83
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
84
|
+
blank: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
85
|
+
divided_by_0: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
86
|
+
schema:
|
|
87
|
+
wrong_type: "[%{service_class_name}] 内部属性`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
88
|
+
wrong_element_type: "[%{service_class_name}] 内部属性ハッシュ`%{internal_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
89
|
+
wrong_element_value: "[%{service_class_name}] 内部属性ハッシュ`%{internal_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
90
|
+
target:
|
|
91
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
92
|
+
invalid_option: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに値がありません"
|
|
93
|
+
type:
|
|
94
|
+
default_error:
|
|
95
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
96
|
+
outputs:
|
|
97
|
+
undefined:
|
|
98
|
+
for_fetch: "[%{service_class_name}] 未定義の出力属性`%{output_name}`"
|
|
99
|
+
for_assign: "[%{service_class_name}] 未定義の出力属性`%{output_name}`"
|
|
100
|
+
validations:
|
|
101
|
+
must:
|
|
102
|
+
default_error: "[%{service_class_name}] 出力属性`%{output_name}`は「%{code}」を満たす必要があります"
|
|
103
|
+
syntax_error: "[%{service_class_name}] 出力属性`%{output_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
104
|
+
dynamic_options:
|
|
105
|
+
consists_of:
|
|
106
|
+
required: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の必須要素が不足しています"
|
|
107
|
+
wrong_type: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
108
|
+
wrong_element_type: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
109
|
+
format:
|
|
110
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマットに一致しません"
|
|
111
|
+
wrong_pattern: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマットに一致しません"
|
|
112
|
+
wrong_type: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
113
|
+
unknown: "[%{service_class_name}] 出力属性`%{output_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
114
|
+
inclusion:
|
|
115
|
+
default: "[%{service_class_name}] `%{output_name}`の値が不正です。`%{output_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
116
|
+
invalid_option: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに値がありません"
|
|
117
|
+
min:
|
|
118
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
119
|
+
max:
|
|
120
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
121
|
+
multiple_of:
|
|
122
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
123
|
+
blank: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
124
|
+
divided_by_0: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
125
|
+
schema:
|
|
126
|
+
wrong_type: "[%{service_class_name}] 出力属性`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
127
|
+
wrong_element_type: "[%{service_class_name}] 出力属性ハッシュ`%{output_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
128
|
+
wrong_element_value: "[%{service_class_name}] 出力属性ハッシュ`%{output_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
129
|
+
target:
|
|
130
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
131
|
+
invalid_option: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに値がありません"
|
|
132
|
+
type:
|
|
133
|
+
default_error:
|
|
134
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
data/lib/generators/README.md
CHANGED
|
@@ -9,7 +9,7 @@ rails generate servactory:install [options]
|
|
|
9
9
|
**Options:**
|
|
10
10
|
- `--namespace` — Base namespace (default: `ApplicationService`)
|
|
11
11
|
- `--path` — Path to install service files (default: `app/services`)
|
|
12
|
-
- `--locales` — Locales to install (available: `en`, `ru`, `de`, `fr`, `es`, `it`)
|
|
12
|
+
- `--locales` — Locales to install (available: `en`, `ru`, `de`, `fr`, `es`, `it`, `ja`)
|
|
13
13
|
- `--minimal` — Generate minimal setup without configuration examples
|
|
14
14
|
|
|
15
15
|
## Service
|
|
@@ -30,6 +30,22 @@ module Servactory
|
|
|
30
30
|
@collection_mode_class_names = original.collection_mode_class_names.dup
|
|
31
31
|
@hash_mode_class_names = original.hash_mode_class_names.dup
|
|
32
32
|
@action_rescue_handlers = original.action_rescue_handlers.dup
|
|
33
|
+
|
|
34
|
+
rebind_dynamic_option_helpers!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def rebind_dynamic_option_helpers!
|
|
40
|
+
new_consists_of = Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
41
|
+
.use(collection_mode_class_names: @collection_mode_class_names)
|
|
42
|
+
new_schema = Servactory::ToolKit::DynamicOptions::Schema
|
|
43
|
+
.use(default_hash_mode_class_names: @hash_mode_class_names)
|
|
44
|
+
|
|
45
|
+
[@input_option_helpers, @internal_option_helpers, @output_option_helpers].each do |helpers|
|
|
46
|
+
helpers.replace(name: :consists_of, with: new_consists_of)
|
|
47
|
+
helpers.replace(name: :schema, with: new_schema)
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
end
|
|
@@ -67,7 +67,8 @@ module Servactory
|
|
|
67
67
|
.new(name: :optional, equivalent: { required: false }),
|
|
68
68
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
69
69
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
70
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
70
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
71
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
71
72
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
72
73
|
]
|
|
73
74
|
end
|
|
@@ -76,7 +77,8 @@ module Servactory
|
|
|
76
77
|
Set[
|
|
77
78
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
78
79
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
79
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
80
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
81
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
80
82
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
81
83
|
]
|
|
82
84
|
end
|
|
@@ -85,7 +87,8 @@ module Servactory
|
|
|
85
87
|
Set[
|
|
86
88
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
87
89
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
88
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
90
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
91
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
89
92
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
90
93
|
]
|
|
91
94
|
end
|
|
@@ -72,6 +72,20 @@ module Servactory
|
|
|
72
72
|
helpers_index[name]
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
# Replaces a helper by name with a new one, invalidating the index cache.
|
|
76
|
+
#
|
|
77
|
+
# @param name [Symbol] the helper name to replace
|
|
78
|
+
# @param with [Maintenance::Attributes::OptionHelper] the replacement helper
|
|
79
|
+
# @return [void]
|
|
80
|
+
def replace(name:, with:)
|
|
81
|
+
old = find_by(name:)
|
|
82
|
+
return unless old
|
|
83
|
+
|
|
84
|
+
@collection.delete(old)
|
|
85
|
+
@collection.add(with)
|
|
86
|
+
@helpers_index = nil
|
|
87
|
+
end
|
|
88
|
+
|
|
75
89
|
private
|
|
76
90
|
|
|
77
91
|
# Builds and caches a hash index for O(1) helper lookups.
|
|
@@ -29,30 +29,22 @@ module Servactory
|
|
|
29
29
|
def process_input(context, warehouse, input)
|
|
30
30
|
value = warehouse.fetch_input(input.name)
|
|
31
31
|
|
|
32
|
-
input.
|
|
33
|
-
error = process_option(context, input, value, check_key, check_options)
|
|
32
|
+
input.collection_of_options.validations_for_checks.each do |check_key, check_options, validation_class|
|
|
33
|
+
error = process_option(context, input, value, check_key, check_options, validation_class)
|
|
34
34
|
return error if error.present?
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
nil
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
def process_option(context, input, value, check_key, check_options)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
value:,
|
|
49
|
-
check_key:,
|
|
50
|
-
check_options:
|
|
51
|
-
)
|
|
52
|
-
return error_message if error_message.present?
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
nil
|
|
40
|
+
def process_option(context, input, value, check_key, check_options, validation_class)
|
|
41
|
+
validation_class.check(
|
|
42
|
+
context:,
|
|
43
|
+
attribute: input,
|
|
44
|
+
value:,
|
|
45
|
+
check_key:,
|
|
46
|
+
check_options:
|
|
47
|
+
)
|
|
56
48
|
end
|
|
57
49
|
end
|
|
58
50
|
end
|
|
@@ -38,8 +38,8 @@ module Servactory
|
|
|
38
38
|
def_delegators :@collection,
|
|
39
39
|
:<<,
|
|
40
40
|
:filter,
|
|
41
|
-
:each_with_object,
|
|
42
|
-
:map,
|
|
41
|
+
:each, :each_with_object,
|
|
42
|
+
:map,
|
|
43
43
|
:size,
|
|
44
44
|
:empty?
|
|
45
45
|
|
|
@@ -76,13 +76,33 @@ module Servactory
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
# Returns options that need validation checks as an array of tuples.
|
|
80
|
+
# Each tuple contains [check_key, check_options, validation_class],
|
|
81
|
+
# enabling direct dispatch without nested iteration.
|
|
82
|
+
#
|
|
83
|
+
# @return [Array<Array(Symbol, Object, Class)>] tuples for direct validation dispatch
|
|
84
|
+
def validations_for_checks
|
|
85
|
+
@validations_for_checks ||= filter(&:need_for_checks?).filter_map do |option|
|
|
86
|
+
next if option.validation_class.nil?
|
|
87
|
+
|
|
88
|
+
[option.name, extract_normalized_body_from(option:), option.validation_class]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
79
92
|
# Returns the first conflict code found among options.
|
|
80
93
|
#
|
|
81
|
-
# @return [
|
|
94
|
+
# @return [Symbol, nil] conflict code or nil if no conflicts
|
|
82
95
|
def defined_conflict_code
|
|
83
|
-
|
|
84
|
-
.
|
|
85
|
-
|
|
96
|
+
each do |option|
|
|
97
|
+
next unless option.define_conflicts
|
|
98
|
+
|
|
99
|
+
option.define_conflicts.each do |conflict|
|
|
100
|
+
code = conflict.content.call
|
|
101
|
+
return code if code.present?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
nil
|
|
86
106
|
end
|
|
87
107
|
|
|
88
108
|
# Finds an option by its name using indexed lookup.
|
|
@@ -111,16 +131,6 @@ module Servactory
|
|
|
111
131
|
def extract_normalized_body_from(option:)
|
|
112
132
|
option.value
|
|
113
133
|
end
|
|
114
|
-
|
|
115
|
-
# Resolves conflict codes from an option's define_conflicts.
|
|
116
|
-
#
|
|
117
|
-
# @param option [Option] the option to check for conflicts
|
|
118
|
-
# @return [Array<Object>] array of conflict codes (may contain nils/blanks)
|
|
119
|
-
def resolve_conflicts_from(option:)
|
|
120
|
-
return [] unless option.define_conflicts
|
|
121
|
-
|
|
122
|
-
option.define_conflicts.map { |conflict| conflict.content.call }
|
|
123
|
-
end
|
|
124
134
|
end
|
|
125
135
|
end
|
|
126
136
|
end
|
|
@@ -19,14 +19,11 @@ module Servactory
|
|
|
19
19
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
|
-
def process(context:, attribute:, value:)
|
|
23
|
-
attribute.
|
|
22
|
+
def process(context:, attribute:, value:)
|
|
23
|
+
attribute.collection_of_options.validations_for_checks.each do |check_key, check_options, validation_class|
|
|
24
24
|
error = process_option(
|
|
25
|
-
context:,
|
|
26
|
-
|
|
27
|
-
value:,
|
|
28
|
-
check_key:,
|
|
29
|
-
check_options:
|
|
25
|
+
context:, attribute:, value:,
|
|
26
|
+
check_key:, check_options:, validation_class:
|
|
30
27
|
)
|
|
31
28
|
return error if error.present?
|
|
32
29
|
end
|
|
@@ -34,22 +31,14 @@ module Servactory
|
|
|
34
31
|
nil
|
|
35
32
|
end
|
|
36
33
|
|
|
37
|
-
def process_option(context:, attribute:, value:, check_key:, check_options:)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
value:,
|
|
46
|
-
check_key:,
|
|
47
|
-
check_options:
|
|
48
|
-
)
|
|
49
|
-
return error_message if error_message.present?
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
nil
|
|
34
|
+
def process_option(context:, attribute:, value:, check_key:, check_options:, validation_class:)
|
|
35
|
+
validation_class.check(
|
|
36
|
+
context:,
|
|
37
|
+
attribute:,
|
|
38
|
+
value:,
|
|
39
|
+
check_key:,
|
|
40
|
+
check_options:
|
|
41
|
+
)
|
|
53
42
|
end
|
|
54
43
|
end
|
|
55
44
|
end
|
|
@@ -37,7 +37,7 @@ module Servactory
|
|
|
37
37
|
# - ServiceMockConfig - provides configuration for each stub
|
|
38
38
|
# - ServiceMockBuilder - creates executor with configs
|
|
39
39
|
# - RSpec Context - provides allow/receive/etc. methods
|
|
40
|
-
class MockExecutor
|
|
40
|
+
class MockExecutor # rubocop:disable Metrics/ClassLength
|
|
41
41
|
include Concerns::ErrorMessages
|
|
42
42
|
|
|
43
43
|
# Creates a new mock executor.
|
|
@@ -170,7 +170,11 @@ module Servactory
|
|
|
170
170
|
# @param config [ServiceMockConfig] Configuration with result/exception
|
|
171
171
|
# @return [void]
|
|
172
172
|
def apply_return_behavior(message_expectation, config)
|
|
173
|
-
if config.
|
|
173
|
+
if config.call_original?
|
|
174
|
+
message_expectation.and_call_original
|
|
175
|
+
elsif config.wrap_original?
|
|
176
|
+
message_expectation.and_wrap_original(&config.wrap_block)
|
|
177
|
+
elsif config.failure? && config.bang_method?
|
|
174
178
|
message_expectation.and_raise(config.exception)
|
|
175
179
|
else
|
|
176
180
|
message_expectation.and_return(config.build_result)
|
|
@@ -77,6 +77,15 @@ module Servactory
|
|
|
77
77
|
include Concerns::ServiceClassValidation
|
|
78
78
|
include Concerns::ErrorMessages
|
|
79
79
|
|
|
80
|
+
RESULT_TYPE_TO_METHOD = {
|
|
81
|
+
success: :succeeds,
|
|
82
|
+
failure: :fails,
|
|
83
|
+
call_original: :and_call_original,
|
|
84
|
+
wrap_original: :and_wrap_original
|
|
85
|
+
}.freeze
|
|
86
|
+
|
|
87
|
+
private_constant :RESULT_TYPE_TO_METHOD
|
|
88
|
+
|
|
80
89
|
# @return [Class] The Servactory service class being mocked
|
|
81
90
|
attr_reader :service_class
|
|
82
91
|
|
|
@@ -188,6 +197,51 @@ module Servactory
|
|
|
188
197
|
self
|
|
189
198
|
end
|
|
190
199
|
|
|
200
|
+
# ============================================================
|
|
201
|
+
# RSpec Pass-Through API
|
|
202
|
+
# ============================================================
|
|
203
|
+
|
|
204
|
+
# Delegates to the original unmodified method.
|
|
205
|
+
# Useful for spy pattern or selective mocking.
|
|
206
|
+
#
|
|
207
|
+
# @return [ServiceMockBuilder] self for method chaining
|
|
208
|
+
#
|
|
209
|
+
# @example Pass-through (spy)
|
|
210
|
+
# allow_service(S).and_call_original
|
|
211
|
+
#
|
|
212
|
+
# @example Selective mocking with input matching
|
|
213
|
+
# allow_service(S).with(id: 1).and_call_original
|
|
214
|
+
def and_call_original
|
|
215
|
+
validate_not_in_sequential_mode!(:and_call_original)
|
|
216
|
+
validate_result_type_not_switched!(:and_call_original)
|
|
217
|
+
|
|
218
|
+
@config.result_type = :call_original
|
|
219
|
+
execute_or_re_execute_mock
|
|
220
|
+
self
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Wraps the original method with custom logic.
|
|
224
|
+
# Block receives the original method and call arguments.
|
|
225
|
+
#
|
|
226
|
+
# @yield [original, **inputs] Block wrapping the original
|
|
227
|
+
# @return [ServiceMockBuilder] self for method chaining
|
|
228
|
+
#
|
|
229
|
+
# @example Modify result
|
|
230
|
+
# allow_service(S).and_wrap_original do |original, **inputs|
|
|
231
|
+
# result = original.call(**inputs)
|
|
232
|
+
# # custom logic
|
|
233
|
+
# result
|
|
234
|
+
# end
|
|
235
|
+
def and_wrap_original(&block)
|
|
236
|
+
validate_not_in_sequential_mode!(:and_wrap_original)
|
|
237
|
+
validate_result_type_not_switched!(:and_wrap_original)
|
|
238
|
+
|
|
239
|
+
@config.result_type = :wrap_original
|
|
240
|
+
@config.wrap_block = block
|
|
241
|
+
execute_or_re_execute_mock
|
|
242
|
+
self
|
|
243
|
+
end
|
|
244
|
+
|
|
191
245
|
# ============================================================
|
|
192
246
|
# Sequential Call API
|
|
193
247
|
# ============================================================
|
|
@@ -208,6 +262,7 @@ module Servactory
|
|
|
208
262
|
# @raise [ArgumentError] if called without first calling succeeds/fails
|
|
209
263
|
# @raise [OutputValidator::ValidationError] if outputs don't match service definition
|
|
210
264
|
def then_succeeds(outputs_hash = {})
|
|
265
|
+
validate_not_passthrough!(:then_succeeds)
|
|
211
266
|
validate_result_type_defined!(:then_succeeds)
|
|
212
267
|
|
|
213
268
|
validate_outputs!(outputs_hash)
|
|
@@ -237,6 +292,7 @@ module Servactory
|
|
|
237
292
|
#
|
|
238
293
|
# @raise [ArgumentError] if called without first calling succeeds/fails
|
|
239
294
|
def then_fails(exception_class = nil, type: :base, message:, meta: nil) # rubocop:disable Style/KeywordParametersOrder
|
|
295
|
+
validate_not_passthrough!(:then_fails)
|
|
240
296
|
validate_result_type_defined!(:then_fails)
|
|
241
297
|
|
|
242
298
|
finalize_current_to_sequence
|
|
@@ -281,22 +337,36 @@ module Servactory
|
|
|
281
337
|
|
|
282
338
|
# Validates that result type is not being switched.
|
|
283
339
|
#
|
|
284
|
-
# Prevents accidental switching between
|
|
340
|
+
# Prevents accidental switching between different result types.
|
|
285
341
|
#
|
|
286
|
-
# @param new_type [Symbol] :succeeds or :
|
|
342
|
+
# @param new_type [Symbol] :succeeds, :fails, :and_call_original, or :and_wrap_original
|
|
287
343
|
# @raise [ArgumentError] if trying to switch result type
|
|
288
344
|
# @return [void]
|
|
289
|
-
def validate_result_type_not_switched!(new_type)
|
|
345
|
+
def validate_result_type_not_switched!(new_type)
|
|
290
346
|
return unless @config.result_type_defined?
|
|
291
347
|
|
|
292
|
-
current_type = @config.
|
|
293
|
-
return if
|
|
294
|
-
(new_type == :fails && current_type == :fails)
|
|
348
|
+
current_type = RESULT_TYPE_TO_METHOD[@config.result_type]
|
|
349
|
+
return if new_type == current_type
|
|
295
350
|
|
|
296
351
|
raise ArgumentError,
|
|
297
352
|
"Cannot call #{new_type}() after #{current_type}() was already called. " \
|
|
298
|
-
"
|
|
299
|
-
"
|
|
353
|
+
"This replaces the result type, which is likely a mistake. " \
|
|
354
|
+
"Create a new mock if you need different behavior."
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Validates that pass-through methods are not mixed with sequential responses.
|
|
358
|
+
#
|
|
359
|
+
# @param method_name [Symbol] The method being called
|
|
360
|
+
# @raise [ArgumentError] if current config is a pass-through type
|
|
361
|
+
# @return [void]
|
|
362
|
+
def validate_not_passthrough!(method_name)
|
|
363
|
+
return unless @config.call_original? || @config.wrap_original?
|
|
364
|
+
|
|
365
|
+
passthrough = @config.call_original? ? :and_call_original : :and_wrap_original
|
|
366
|
+
|
|
367
|
+
raise ArgumentError,
|
|
368
|
+
"Cannot call #{method_name}() after #{passthrough}(). " \
|
|
369
|
+
"Pass-through methods are not compatible with sequential responses."
|
|
300
370
|
end
|
|
301
371
|
|
|
302
372
|
# Validates outputs against service definition.
|
|
@@ -38,7 +38,8 @@ module Servactory
|
|
|
38
38
|
:method_type,
|
|
39
39
|
:outputs,
|
|
40
40
|
:exception,
|
|
41
|
-
:argument_matcher
|
|
41
|
+
:argument_matcher,
|
|
42
|
+
:wrap_block
|
|
42
43
|
|
|
43
44
|
# Creates a new mock configuration.
|
|
44
45
|
#
|
|
@@ -51,6 +52,7 @@ module Servactory
|
|
|
51
52
|
@outputs = {}
|
|
52
53
|
@exception = nil
|
|
53
54
|
@argument_matcher = nil
|
|
55
|
+
@wrap_block = nil
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
# Checks if this is a success mock.
|
|
@@ -67,6 +69,20 @@ module Servactory
|
|
|
67
69
|
result_type == :failure
|
|
68
70
|
end
|
|
69
71
|
|
|
72
|
+
# Checks if this is a call_original mock.
|
|
73
|
+
#
|
|
74
|
+
# @return [Boolean] True if result_type is :call_original
|
|
75
|
+
def call_original?
|
|
76
|
+
result_type == :call_original
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Checks if this is a wrap_original mock.
|
|
80
|
+
#
|
|
81
|
+
# @return [Boolean] True if result_type is :wrap_original
|
|
82
|
+
def wrap_original?
|
|
83
|
+
result_type == :wrap_original
|
|
84
|
+
end
|
|
85
|
+
|
|
70
86
|
# Checks if this mocks the .call! method.
|
|
71
87
|
#
|
|
72
88
|
# @return [Boolean] True if method_type is :call!
|
|
@@ -113,13 +129,14 @@ module Servactory
|
|
|
113
129
|
# Creates a deep copy of this config.
|
|
114
130
|
#
|
|
115
131
|
# @return [ServiceMockConfig] New config with copied values
|
|
116
|
-
def dup
|
|
132
|
+
def dup # rubocop:disable Metrics/AbcSize
|
|
117
133
|
copy = self.class.new(service_class:)
|
|
118
134
|
copy.result_type = result_type
|
|
119
135
|
copy.method_type = method_type
|
|
120
136
|
copy.outputs = outputs.dup
|
|
121
137
|
copy.exception = exception
|
|
122
138
|
copy.argument_matcher = argument_matcher
|
|
139
|
+
copy.wrap_block = wrap_block
|
|
123
140
|
copy
|
|
124
141
|
end
|
|
125
142
|
end
|
|
@@ -31,7 +31,7 @@ module Servactory
|
|
|
31
31
|
# Specify type directly as the option value:
|
|
32
32
|
#
|
|
33
33
|
# ```ruby
|
|
34
|
-
# class
|
|
34
|
+
# class Users::Process < ApplicationService::Base
|
|
35
35
|
# input :user_ids, type: Array, consists_of: Integer
|
|
36
36
|
# input :tags, type: Array, consists_of: [String, Symbol]
|
|
37
37
|
# input :scores, type: Array, consists_of: Float
|
|
@@ -88,7 +88,8 @@ module Servactory
|
|
|
88
88
|
# Creates a ConsistsOf validator instance.
|
|
89
89
|
#
|
|
90
90
|
# @param option_name [Symbol] The option name (default: :consists_of)
|
|
91
|
-
# @param collection_mode_class_names [
|
|
91
|
+
# @param collection_mode_class_names [Servactory::Configuration::CollectionMode::ClassNamesCollection]
|
|
92
|
+
# Valid collection types
|
|
92
93
|
# @return [Servactory::Maintenance::Attributes::OptionHelper]
|
|
93
94
|
def self.use(option_name = :consists_of, collection_mode_class_names:)
|
|
94
95
|
instance = new(option_name, :type, false)
|
|
@@ -98,7 +99,8 @@ module Servactory
|
|
|
98
99
|
|
|
99
100
|
# Assigns the list of valid collection class names.
|
|
100
101
|
#
|
|
101
|
-
# @param collection_mode_class_names [
|
|
102
|
+
# @param collection_mode_class_names [Servactory::Configuration::CollectionMode::ClassNamesCollection]
|
|
103
|
+
# Collection types to accept
|
|
102
104
|
# @return [void]
|
|
103
105
|
def assign(collection_mode_class_names)
|
|
104
106
|
@collection_mode_class_names = collection_mode_class_names
|
|
@@ -72,7 +72,7 @@ module Servactory
|
|
|
72
72
|
# Specify format directly as the option value:
|
|
73
73
|
#
|
|
74
74
|
# ```ruby
|
|
75
|
-
# class
|
|
75
|
+
# class Users::Validate < ApplicationService::Base
|
|
76
76
|
# input :uuid, type: String, format: :uuid
|
|
77
77
|
# input :email, type: String, format: :email
|
|
78
78
|
# input :password, type: String, format: :password
|
|
@@ -20,7 +20,7 @@ module Servactory
|
|
|
20
20
|
# Use in your service definition:
|
|
21
21
|
#
|
|
22
22
|
# ```ruby
|
|
23
|
-
# class
|
|
23
|
+
# class Users::Create < ApplicationService::Base
|
|
24
24
|
# input :role, type: String, inclusion: { in: %w[admin user guest] }
|
|
25
25
|
# input :status, type: Symbol, inclusion: { in: [:active, :inactive] }
|
|
26
26
|
# input :level, type: Integer, inclusion: { in: [1, 2, 3, 4, 5] }
|
|
@@ -32,7 +32,7 @@ module Servactory
|
|
|
32
32
|
# Specify inclusion values directly:
|
|
33
33
|
#
|
|
34
34
|
# ```ruby
|
|
35
|
-
# class
|
|
35
|
+
# class Users::Create < ApplicationService::Base
|
|
36
36
|
# input :role, type: String, inclusion: %w[admin user guest]
|
|
37
37
|
# input :status, type: Symbol, inclusion: [:active, :inactive]
|
|
38
38
|
# input :level, type: Integer, inclusion: 1..10
|
|
@@ -35,7 +35,7 @@ module Servactory
|
|
|
35
35
|
# Use in your service definition:
|
|
36
36
|
#
|
|
37
37
|
# ```ruby
|
|
38
|
-
# class
|
|
38
|
+
# class Data::Process < ApplicationService::Base
|
|
39
39
|
# input :count, type: Integer, max: 100
|
|
40
40
|
# input :name, type: String, max: 255
|
|
41
41
|
# input :items, type: Array, max: 50
|
|
@@ -47,7 +47,7 @@ module Servactory
|
|
|
47
47
|
# Specify maximum value directly:
|
|
48
48
|
#
|
|
49
49
|
# ```ruby
|
|
50
|
-
# class
|
|
50
|
+
# class Data::Process < ApplicationService::Base
|
|
51
51
|
# input :count, type: Integer, max: 100
|
|
52
52
|
# input :name, type: String, max: 255
|
|
53
53
|
# input :items, type: Array, max: 50
|
|
@@ -35,7 +35,7 @@ module Servactory
|
|
|
35
35
|
# Use in your service definition:
|
|
36
36
|
#
|
|
37
37
|
# ```ruby
|
|
38
|
-
# class
|
|
38
|
+
# class Data::Process < ApplicationService::Base
|
|
39
39
|
# input :age, type: Integer, min: 18
|
|
40
40
|
# input :password, type: String, min: 8
|
|
41
41
|
# input :tags, type: Array, min: 1
|
|
@@ -47,7 +47,7 @@ module Servactory
|
|
|
47
47
|
# Specify minimum value directly:
|
|
48
48
|
#
|
|
49
49
|
# ```ruby
|
|
50
|
-
# class
|
|
50
|
+
# class Data::Process < ApplicationService::Base
|
|
51
51
|
# input :age, type: Integer, min: 18
|
|
52
52
|
# input :password, type: String, min: 8
|
|
53
53
|
# input :tags, type: Array, min: 1
|
|
@@ -35,7 +35,7 @@ module Servactory
|
|
|
35
35
|
# Use in your service definition:
|
|
36
36
|
#
|
|
37
37
|
# ```ruby
|
|
38
|
-
# class
|
|
38
|
+
# class Orders::Process < ApplicationService::Base
|
|
39
39
|
# input :quantity, type: Integer, multiple_of: 5
|
|
40
40
|
# input :price, type: Float, multiple_of: 0.25
|
|
41
41
|
# input :batch_size, type: Integer, multiple_of: 100
|
|
@@ -47,7 +47,7 @@ module Servactory
|
|
|
47
47
|
# Specify divisor directly:
|
|
48
48
|
#
|
|
49
49
|
# ```ruby
|
|
50
|
-
# class
|
|
50
|
+
# class Orders::Process < ApplicationService::Base
|
|
51
51
|
# input :quantity, type: Integer, multiple_of: 5
|
|
52
52
|
# input :price, type: Float, multiple_of: 0.25
|
|
53
53
|
# input :batch_size, type: Integer, multiple_of: 100
|
|
@@ -29,7 +29,7 @@ module Servactory
|
|
|
29
29
|
# Define schema in your service:
|
|
30
30
|
#
|
|
31
31
|
# ```ruby
|
|
32
|
-
# class
|
|
32
|
+
# class Users::Create < ApplicationService::Base
|
|
33
33
|
# input :user_data,
|
|
34
34
|
# type: Hash,
|
|
35
35
|
# schema: {
|
|
@@ -49,7 +49,7 @@ module Servactory
|
|
|
49
49
|
# Specify schema definition directly:
|
|
50
50
|
#
|
|
51
51
|
# ```ruby
|
|
52
|
-
# class
|
|
52
|
+
# class Users::Create < ApplicationService::Base
|
|
53
53
|
# input :user_data,
|
|
54
54
|
# type: Hash,
|
|
55
55
|
# schema: {
|
|
@@ -127,7 +127,8 @@ module Servactory
|
|
|
127
127
|
# Creates a Schema validator instance.
|
|
128
128
|
#
|
|
129
129
|
# @param option_name [Symbol] The option name (default: :schema)
|
|
130
|
-
# @param default_hash_mode_class_names [
|
|
130
|
+
# @param default_hash_mode_class_names [Servactory::Configuration::HashMode::ClassNamesCollection]
|
|
131
|
+
# Valid Hash-like types
|
|
131
132
|
# @return [Servactory::Maintenance::Attributes::OptionHelper]
|
|
132
133
|
def self.use(option_name = :schema, default_hash_mode_class_names:)
|
|
133
134
|
instance = new(option_name, :is, false)
|
|
@@ -137,7 +138,8 @@ module Servactory
|
|
|
137
138
|
|
|
138
139
|
# Assigns the list of valid Hash-compatible class names.
|
|
139
140
|
#
|
|
140
|
-
# @param default_hash_mode_class_names [
|
|
141
|
+
# @param default_hash_mode_class_names [Servactory::Configuration::HashMode::ClassNamesCollection]
|
|
142
|
+
# Hash-like types to accept
|
|
141
143
|
# @return [void]
|
|
142
144
|
def assign(default_hash_mode_class_names)
|
|
143
145
|
@default_hash_mode_class_names = default_hash_mode_class_names
|
|
@@ -37,8 +37,8 @@ module Servactory
|
|
|
37
37
|
# Use in your service definition:
|
|
38
38
|
#
|
|
39
39
|
# ```ruby
|
|
40
|
-
# class
|
|
41
|
-
# input :service_class, type: Class, target:
|
|
40
|
+
# class Orders::Process < ApplicationService::Base
|
|
41
|
+
# input :service_class, type: Class, target: Payments::Charge
|
|
42
42
|
# input :handler_class, type: Class, target: [CreateHandler, UpdateHandler]
|
|
43
43
|
# end
|
|
44
44
|
# ```
|
|
@@ -48,7 +48,7 @@ module Servactory
|
|
|
48
48
|
# Specify target class directly or as an array:
|
|
49
49
|
#
|
|
50
50
|
# ```ruby
|
|
51
|
-
# input :service_class, type: Class, target:
|
|
51
|
+
# input :service_class, type: Class, target: Payments::Charge
|
|
52
52
|
# input :handler_class, type: Class, target: [CreateHandler, UpdateHandler]
|
|
53
53
|
# ```
|
|
54
54
|
#
|
data/lib/servactory/version.rb
CHANGED
data/lib/servactory.rb
CHANGED
|
@@ -16,10 +16,6 @@ loader.inflector.inflect(
|
|
|
16
16
|
)
|
|
17
17
|
loader.setup
|
|
18
18
|
|
|
19
|
-
# Eager load DSL to initialize Stroma::Registry.
|
|
20
|
-
# Registry must be populated before any service class is defined.
|
|
21
|
-
require_relative "servactory/dsl"
|
|
22
|
-
|
|
23
19
|
module Servactory; end
|
|
24
20
|
|
|
25
21
|
require "servactory/engine" if defined?(Rails::Engine)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: servactory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.0.
|
|
4
|
+
version: 3.1.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Sokolov
|
|
@@ -43,14 +43,20 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0.
|
|
46
|
+
version: '0.5'
|
|
47
|
+
- - "<"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '1.0'
|
|
47
50
|
type: :runtime
|
|
48
51
|
prerelease: false
|
|
49
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
53
|
requirements:
|
|
51
54
|
- - ">="
|
|
52
55
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0.
|
|
56
|
+
version: '0.5'
|
|
57
|
+
- - "<"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '1.0'
|
|
54
60
|
- !ruby/object:Gem::Dependency
|
|
55
61
|
name: zeitwerk
|
|
56
62
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -184,6 +190,7 @@ executables: []
|
|
|
184
190
|
extensions: []
|
|
185
191
|
extra_rdoc_files: []
|
|
186
192
|
files:
|
|
193
|
+
- LICENSE
|
|
187
194
|
- README.md
|
|
188
195
|
- Rakefile
|
|
189
196
|
- config/locales/de.yml
|
|
@@ -191,6 +198,7 @@ files:
|
|
|
191
198
|
- config/locales/es.yml
|
|
192
199
|
- config/locales/fr.yml
|
|
193
200
|
- config/locales/it.yml
|
|
201
|
+
- config/locales/ja.yml
|
|
194
202
|
- config/locales/ru.yml
|
|
195
203
|
- lib/generators/README.md
|
|
196
204
|
- lib/generators/servactory/base.rb
|
|
@@ -357,7 +365,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
357
365
|
- !ruby/object:Gem::Version
|
|
358
366
|
version: '0'
|
|
359
367
|
requirements: []
|
|
360
|
-
rubygems_version: 4.0.
|
|
368
|
+
rubygems_version: 4.0.6
|
|
361
369
|
specification_version: 4
|
|
362
370
|
summary: A set of tools for building reliable services of any complexity
|
|
363
371
|
test_files: []
|