servactory 2.5.1 → 2.6.0.rc1

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/en.yml +9 -10
  3. data/config/locales/ru.yml +9 -11
  4. data/lib/generators/servactory/templates/services/application_service/base.rb +2 -2
  5. data/lib/servactory/actions/tools/rules.rb +2 -3
  6. data/lib/servactory/configuration/dsl.rb +0 -2
  7. data/lib/servactory/configuration/factory.rb +19 -6
  8. data/lib/servactory/configuration/setup.rb +18 -10
  9. data/lib/servactory/context/workspace/inputs.rb +2 -3
  10. data/lib/servactory/context/workspace/internals.rb +2 -3
  11. data/lib/servactory/context/workspace/outputs.rb +2 -3
  12. data/lib/servactory/context/workspace.rb +23 -3
  13. data/lib/servactory/info/dsl.rb +3 -9
  14. data/lib/servactory/inputs/dsl.rb +0 -1
  15. data/lib/servactory/inputs/input.rb +2 -6
  16. data/lib/servactory/inputs/tools/rules.rb +2 -3
  17. data/lib/servactory/inputs/tools/unnecessary.rb +2 -3
  18. data/lib/servactory/inputs/translator/required.rb +3 -7
  19. data/lib/servactory/inputs/validations/required.rb +2 -14
  20. data/lib/servactory/internals/dsl.rb +0 -1
  21. data/lib/servactory/internals/internal.rb +2 -6
  22. data/lib/servactory/maintenance/attributes/options/registrar.rb +2 -34
  23. data/lib/servactory/maintenance/attributes/translator/inclusion.rb +3 -4
  24. data/lib/servactory/maintenance/attributes/translator/must.rb +8 -10
  25. data/lib/servactory/maintenance/attributes/translator/type.rb +11 -46
  26. data/lib/servactory/maintenance/attributes/validations/inclusion.rb +1 -1
  27. data/lib/servactory/maintenance/attributes/validations/must.rb +2 -2
  28. data/lib/servactory/maintenance/validations/types.rb +4 -30
  29. data/lib/servactory/outputs/dsl.rb +0 -1
  30. data/lib/servactory/outputs/output.rb +2 -6
  31. data/lib/servactory/result.rb +2 -3
  32. data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/consists_of_matcher.rb +8 -56
  33. data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/must_matcher.rb +7 -2
  34. data/lib/servactory/test_kit/rspec/matchers/have_service_input_matcher.rb +5 -0
  35. data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/required_matcher.rb +5 -2
  36. data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/valid_with_matcher.rb +18 -62
  37. data/lib/servactory/test_kit/rspec/matchers/have_service_internal_matcher.rb +5 -0
  38. data/lib/servactory/test_kit/rspec/matchers.rb +2 -1
  39. data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +92 -0
  40. data/lib/servactory/tool_kit/dynamic_options/format.rb +9 -12
  41. data/lib/servactory/tool_kit/dynamic_options/max.rb +9 -12
  42. data/lib/servactory/tool_kit/dynamic_options/min.rb +9 -12
  43. data/lib/servactory/utils.rb +3 -3
  44. data/lib/servactory/version.rb +3 -3
  45. data/lib/servactory.rb +1 -0
  46. metadata +3 -4
  47. data/lib/servactory/maintenance/collection_mode/class_names_collection.rb +0 -16
  48. data/lib/servactory/maintenance/validations/collection.rb +0 -86
@@ -20,7 +20,6 @@ module Servactory
20
20
  required: false,
21
21
  types: false,
22
22
  default: false,
23
- collection: false,
24
23
  hash: false,
25
24
  inclusion: false,
26
25
  must: false,
@@ -33,9 +32,8 @@ module Servactory
33
32
  new(...).register
34
33
  end
35
34
 
36
- def initialize(attribute:, collection_mode_class_names:, hash_mode_class_names:, options:, features:)
35
+ def initialize(attribute:, hash_mode_class_names:, options:, features:)
37
36
  @attribute = attribute
38
- @collection_mode_class_names = collection_mode_class_names
39
37
  @hash_mode_class_names = hash_mode_class_names
40
38
  @options = options
41
39
  @features = DEFAULT_FEATURES.merge(features)
@@ -43,14 +41,13 @@ module Servactory
43
41
 
44
42
  ########################################################################
45
43
 
46
- def register # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
44
+ def register # rubocop:disable Metrics/CyclomaticComplexity
47
45
  # Validation Class: Servactory::Inputs::Validations::Required
48
46
  register_required_option if @features.fetch(:required)
49
47
 
50
48
  # Validation Class: Servactory::Maintenance::Attributes::Validations::Type
51
49
  register_types_option if @features.fetch(:types)
52
50
  register_default_option if @features.fetch(:default)
53
- register_collection_option if @features.fetch(:collection)
54
51
  register_hash_option if @features.fetch(:hash)
55
52
 
56
53
  # Validation Class: Servactory::Maintenance::Attributes::Validations::Inclusion
@@ -124,35 +121,6 @@ module Servactory
124
121
  )
125
122
  end
126
123
 
127
- def register_collection_option # rubocop:disable Metrics/MethodLength
128
- collection << Servactory::Maintenance::Attributes::Option.new(
129
- name: :consists_of,
130
- attribute: @attribute,
131
- validation_class: Servactory::Maintenance::Attributes::Validations::Type,
132
- define_methods: [
133
- Servactory::Maintenance::Attributes::DefineMethod.new(
134
- name: :collection_mode?,
135
- content: lambda do |**|
136
- @collection_mode_class_names.include?(@options.fetch(:type)) &&
137
- @options.fetch(:consists_of, true) != false
138
- end
139
- )
140
- ],
141
- define_conflicts: [
142
- Servactory::Maintenance::Attributes::DefineConflict.new(
143
- content: lambda {
144
- :collection_vs_inclusion if @attribute.collection_mode? && @attribute.inclusion_present?
145
- }
146
- )
147
- ],
148
- need_for_checks: false,
149
- body_key: :type,
150
- body_value: String,
151
- body_fallback: String,
152
- **@options
153
- )
154
- end
155
-
156
124
  def register_hash_option # rubocop:disable Metrics/MethodLength
157
125
  collection << Servactory::Maintenance::Attributes::Option.new(
158
126
  name: :schema,
@@ -8,12 +8,11 @@ module Servactory
8
8
  module_function
9
9
 
10
10
  def default_message
11
- lambda do |service_class_name:, value:, input: nil, internal: nil, output: nil|
11
+ lambda do |service:, value:, input: nil, internal: nil, output: nil|
12
12
  attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
13
13
 
14
- I18n.t(
15
- "servactory.#{attribute.i18n_name}.validations.inclusion.default_error",
16
- service_class_name: service_class_name,
14
+ service.translate(
15
+ "#{attribute.i18n_name}.validations.inclusion.default_error",
17
16
  "#{attribute.system_name}_name": attribute.name,
18
17
  "#{attribute.system_name}_inclusion": attribute.inclusion[:in],
19
18
  value: value
@@ -7,13 +7,12 @@ module Servactory
7
7
  module Must
8
8
  module_function
9
9
 
10
- def default_message # rubocop:disable Metrics/MethodLength
11
- lambda do |service_class_name:, value:, code:, input: nil, internal: nil, output: nil, reason: nil|
10
+ def default_message
11
+ lambda do |service:, value:, code:, input: nil, internal: nil, output: nil, reason: nil|
12
12
  attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
13
13
 
14
- I18n.t(
15
- "servactory.#{attribute.i18n_name}.validations.must.default_error",
16
- service_class_name: service_class_name,
14
+ service.translate(
15
+ "#{attribute.i18n_name}.validations.must.default_error",
17
16
  "#{attribute.system_name}_name": attribute.name,
18
17
  value: value,
19
18
  code: code,
@@ -22,13 +21,12 @@ module Servactory
22
21
  end
23
22
  end
24
23
 
25
- def syntax_error_message # rubocop:disable Metrics/MethodLength
26
- lambda do |service_class_name:, value:, code:, exception_message:, input: nil, internal: nil, output: nil|
24
+ def syntax_error_message
25
+ lambda do |service:, value:, code:, exception_message:, input: nil, internal: nil, output: nil|
27
26
  attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
28
27
 
29
- I18n.t(
30
- "servactory.#{attribute.i18n_name}.validations.must.syntax_error",
31
- service_class_name: service_class_name,
28
+ service.translate(
29
+ "#{attribute.i18n_name}.validations.must.syntax_error",
32
30
  "#{attribute.system_name}_name": attribute.name,
33
31
  value: value,
34
32
  code: code,
@@ -7,16 +7,13 @@ module Servactory
7
7
  module Type
8
8
  extend self
9
9
 
10
- def default_message # rubocop:disable Metrics/MethodLength
11
- lambda do |service_class_name:, attribute:, value:, key_name:, expected_type:, given_type:|
12
- if attribute.collection_mode?
13
- for_collection_mode_with(service_class_name: service_class_name, attribute: attribute, value: value,
14
- expected_type: expected_type, given_type: given_type)
15
- elsif attribute.hash_mode? && key_name.present?
16
- for_hash_mode_with(service_class_name: service_class_name, attribute: attribute, key_name: key_name,
10
+ def default_message
11
+ lambda do |service:, attribute:, key_name:, expected_type:, given_type:, **|
12
+ if attribute.hash_mode? && key_name.present?
13
+ for_hash_mode_with(service: service, attribute: attribute, key_name: key_name,
17
14
  expected_type: expected_type, given_type: given_type)
18
15
  else
19
- for_others_with(service_class_name: service_class_name, attribute: attribute,
16
+ for_others_with(service: service, attribute: attribute,
20
17
  expected_type: expected_type, given_type: given_type)
21
18
  end
22
19
  end
@@ -24,37 +21,7 @@ module Servactory
24
21
 
25
22
  private
26
23
 
27
- def for_collection_mode_with(service_class_name:, attribute:, value:, expected_type:, given_type:) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
28
- collection_message = attribute.consists_of.fetch(:message)
29
-
30
- if collection_message.is_a?(Proc)
31
- collection_message.call(
32
- **Servactory::Utils.fetch_hash_with_desired_attribute(attribute),
33
- expected_type: expected_type,
34
- given_type: given_type
35
- )
36
- elsif collection_message.is_a?(String) && collection_message.present?
37
- collection_message
38
- elsif value.is_a?(attribute.types.fetch(0, Array))
39
- I18n.t(
40
- "servactory.#{attribute.i18n_name}.validations.type.default_error.for_collection.wrong_element_type",
41
- service_class_name: service_class_name,
42
- "#{attribute.system_name}_name": attribute.name,
43
- expected_type: expected_type,
44
- given_type: given_type
45
- )
46
- else
47
- I18n.t(
48
- "servactory.#{attribute.i18n_name}.validations.type.default_error.for_collection.wrong_type",
49
- service_class_name: service_class_name,
50
- "#{attribute.system_name}_name": attribute.name,
51
- expected_type: attribute.types.fetch(0, Array),
52
- given_type: value.class.name
53
- )
54
- end
55
- end
56
-
57
- def for_hash_mode_with(service_class_name:, attribute:, key_name:, expected_type:, given_type:) # rubocop:disable Metrics/MethodLength
24
+ def for_hash_mode_with(service:, attribute:, key_name:, expected_type:, given_type:) # rubocop:disable Metrics/MethodLength
58
25
  hash_message = attribute.schema.fetch(:message)
59
26
 
60
27
  if hash_message.is_a?(Proc)
@@ -67,9 +34,8 @@ module Servactory
67
34
  elsif hash_message.is_a?(String) && hash_message.present?
68
35
  hash_message
69
36
  else
70
- I18n.t(
71
- "servactory.#{attribute.i18n_name}.validations.type.default_error.for_hash.wrong_element_type",
72
- service_class_name: service_class_name,
37
+ service.translate(
38
+ "#{attribute.i18n_name}.validations.type.default_error.for_hash.wrong_element_type",
73
39
  "#{attribute.system_name}_name": attribute.name,
74
40
  key_name: key_name,
75
41
  expected_type: expected_type,
@@ -78,10 +44,9 @@ module Servactory
78
44
  end
79
45
  end
80
46
 
81
- def for_others_with(service_class_name:, attribute:, expected_type:, given_type:)
82
- I18n.t(
83
- "servactory.#{attribute.i18n_name}.validations.type.default_error.default",
84
- service_class_name: service_class_name,
47
+ def for_others_with(service:, attribute:, expected_type:, given_type:)
48
+ service.translate(
49
+ "#{attribute.i18n_name}.validations.type.default_error.default",
85
50
  "#{attribute.system_name}_name": attribute.name,
86
51
  expected_type: expected_type,
87
52
  given_type: given_type
@@ -51,7 +51,7 @@ module Servactory
51
51
  def add_error_with(message)
52
52
  add_error(
53
53
  message: message.presence || Servactory::Maintenance::Attributes::Translator::Inclusion.default_message,
54
- service_class_name: @context.class.name,
54
+ service: @context.send(:servactory_service_info),
55
55
  **Servactory::Utils.fetch_hash_with_desired_attribute(@attribute),
56
56
  value: @value
57
57
  )
@@ -65,7 +65,7 @@ module Servactory
65
65
  def add_error_with(message, code, reason)
66
66
  add_error(
67
67
  message: message,
68
- service_class_name: @context.class.name,
68
+ service: @context.send(:servactory_service_info),
69
69
  **Servactory::Utils.fetch_hash_with_desired_attribute(@attribute),
70
70
  value: @value,
71
71
  code: code,
@@ -76,7 +76,7 @@ module Servactory
76
76
  def add_syntax_error_with(message, code, exception_message)
77
77
  add_error(
78
78
  message: message,
79
- service_class_name: @context.class.name,
79
+ service: @context.send(:servactory_service_info),
80
80
  **Servactory::Utils.fetch_hash_with_desired_attribute(@attribute),
81
81
  value: @value,
82
82
  code: code,
@@ -17,18 +17,9 @@ module Servactory
17
17
  end
18
18
 
19
19
  def validate! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
20
- collection_validator = nil
21
20
  object_schema_validator = nil
22
21
 
23
- if @attribute.collection_mode?
24
- collection_validator = Servactory::Maintenance::Validations::Collection.validate(
25
- types: @types,
26
- value: @value,
27
- consists_of: @attribute.consists_of
28
- )
29
-
30
- return if collection_validator.valid?
31
- elsif @attribute.hash_mode?
22
+ if @attribute.hash_mode?
32
23
  object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
33
24
  object: @value,
34
25
  schema: @attribute.schema
@@ -41,22 +32,10 @@ module Servactory
41
32
  end
42
33
  end
43
34
 
44
- if (first_error = collection_validator&.errors&.first).present?
45
- return @error_callback.call(
46
- message: Servactory::Maintenance::Attributes::Translator::Type.default_message,
47
- service_class_name: @context.class.name,
48
- attribute: @attribute,
49
- value: @value,
50
- key_name: nil,
51
- expected_type: first_error.fetch(:expected_type),
52
- given_type: first_error.fetch(:given_type)
53
- )
54
- end
55
-
56
35
  if (first_error = object_schema_validator&.errors&.first).present?
57
36
  return @error_callback.call(
58
37
  message: Servactory::Maintenance::Attributes::Translator::Type.default_message,
59
- service_class_name: @context.class.name,
38
+ service: @context.send(:servactory_service_info),
60
39
  attribute: @attribute,
61
40
  value: @value,
62
41
  key_name: first_error.fetch(:key_name),
@@ -67,7 +46,7 @@ module Servactory
67
46
 
68
47
  @error_callback.call(
69
48
  message: Servactory::Maintenance::Attributes::Translator::Type.default_message,
70
- service_class_name: @context.class.name,
49
+ service: @context.send(:servactory_service_info),
71
50
  attribute: @attribute,
72
51
  value: @value,
73
52
  key_name: nil,
@@ -79,12 +58,7 @@ module Servactory
79
58
  private
80
59
 
81
60
  def prepared_types
82
- @prepared_types ||=
83
- if @attribute.collection_mode?
84
- prepared_types_from(Array(@attribute.consists_of.fetch(:type, [])))
85
- else
86
- prepared_types_from(@types)
87
- end
61
+ @prepared_types ||= prepared_types_from(@types)
88
62
  end
89
63
 
90
64
  def prepared_types_from(types)
@@ -20,7 +20,6 @@ module Servactory
20
20
  collection_of_outputs << Output.new(
21
21
  name,
22
22
  *helpers,
23
- collection_mode_class_names: config.collection_mode_class_names,
24
23
  hash_mode_class_names: config.hash_mode_class_names,
25
24
  option_helpers: config.output_option_helpers,
26
25
  **options
@@ -3,7 +3,7 @@
3
3
  module Servactory
4
4
  module Outputs
5
5
  class Output
6
- class Work
6
+ class Actor
7
7
  attr_reader :name,
8
8
  :types,
9
9
  :inclusion
@@ -28,13 +28,11 @@ module Servactory
28
28
  def initialize(
29
29
  name,
30
30
  *helpers,
31
- collection_mode_class_names:,
32
31
  hash_mode_class_names:,
33
32
  option_helpers:,
34
33
  **options
35
34
  )
36
35
  @name = name
37
- @collection_mode_class_names = collection_mode_class_names
38
36
  @hash_mode_class_names = hash_mode_class_names
39
37
  @option_helpers = option_helpers
40
38
 
@@ -61,12 +59,10 @@ module Servactory
61
59
 
62
60
  options_registrar = Servactory::Maintenance::Attributes::Options::Registrar.register(
63
61
  attribute: self,
64
- collection_mode_class_names: @collection_mode_class_names,
65
62
  hash_mode_class_names: @hash_mode_class_names,
66
63
  options: options,
67
64
  features: {
68
65
  types: true,
69
- collection: true,
70
66
  hash: true,
71
67
  inclusion: true,
72
68
  must: true
@@ -94,7 +90,7 @@ module Servactory
94
90
  prepared_options.deep_merge!(prepared_option)
95
91
  end
96
92
 
97
- options.merge(prepared_options)
93
+ options.deep_merge(prepared_options)
98
94
  end
99
95
 
100
96
  def options_for_checks
@@ -121,9 +121,8 @@ module Servactory
121
121
 
122
122
  raise @context.class.config.failure_class.new(
123
123
  type: :base,
124
- message: I18n.t(
125
- "servactory.common.undefined_method.missing_name",
126
- service_class_name: @context.class.name,
124
+ message: @context.send(:servactory_service_info).translate(
125
+ "common.undefined_method.missing_name",
127
126
  error_text: exception.message
128
127
  ),
129
128
  meta: {
@@ -50,68 +50,20 @@ module Servactory
50
50
  :attribute_data
51
51
 
52
52
  def submatcher_passes?(_subject)
53
- attribute_consists_of = Array(attribute_data.fetch(:consists_of).fetch(:type) || [])
53
+ attribute_must = attribute_data.fetch(:must)
54
54
 
55
- matched = attribute_consists_of.difference(consists_of_types).empty?
55
+ attribute_must_keys = attribute_must.keys
56
56
 
57
- matched &&= attribute_consists_of_message.casecmp(custom_message).zero? if custom_message.present?
57
+ expected_keys = %i[consists_of]
58
58
 
59
- matched
60
- end
61
-
62
- def attribute_consists_of_message # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
63
- attribute_consists_of_message = attribute_data.fetch(:consists_of).fetch(:message)
59
+ attribute_must_keys = attribute_must_keys.select { |key| expected_keys.include?(key) }
64
60
 
65
- if attribute_consists_of_message.nil?
66
- I18n.t(
67
- "servactory.#{attribute_type_plural}.validations.required.default_error.for_collection",
68
- service_class_name: described_class.name,
69
- "#{attribute_type}_name": attribute_name
70
- )
71
- elsif attribute_consists_of_message.is_a?(Proc)
72
- input_work = attribute_data.fetch(:work)
73
-
74
- attribute_consists_of_message.call(
75
- input: input_work,
76
- expected_type: String,
77
- given_type: Servactory::TestKit::FakeType.new.class.name
78
- )
79
- else
80
- attribute_consists_of_message
81
- end
61
+ attribute_must_keys.difference(expected_keys).empty? &&
62
+ expected_keys.difference(attribute_must_keys).empty?
82
63
  end
83
64
 
84
- def build_missing_option # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
85
- attribute_consists_of = Array(attribute_data.fetch(:consists_of).fetch(:type) || [])
86
-
87
- unless attribute_consists_of.difference(consists_of_types).empty?
88
- text_about_types = option_types.size > 1 ? "the following types" : "type"
89
-
90
- return <<~MESSAGE
91
- should be a collection consisting of #{text_about_types}
92
-
93
- expected #{consists_of_types.inspect}
94
- got #{attribute_consists_of.inspect}
95
- MESSAGE
96
- end
97
-
98
- if custom_message.present? && !attribute_consists_of_message.casecmp(custom_message).zero?
99
- return <<~MESSAGE
100
- should be a collection with a message
101
-
102
- expected #{custom_message.inspect}
103
- got #{attribute_consists_of_message.inspect}
104
- MESSAGE
105
- end
106
-
107
- <<~MESSAGE
108
- got an unexpected case when using `consists_of`
109
-
110
- Please try to build an example based on the documentation.
111
- Or report your problem to us:
112
-
113
- https://github.com/servactory/servactory/issues
114
- MESSAGE
65
+ def build_missing_option
66
+ "should be consists_of"
115
67
  end
116
68
  end
117
69
  end
@@ -46,8 +46,13 @@ module Servactory
46
46
  def submatcher_passes?(_subject)
47
47
  attribute_must = attribute_data.fetch(:must)
48
48
 
49
- attribute_must.keys.difference(must_names).empty? &&
50
- must_names.difference(attribute_must.keys).empty?
49
+ attribute_must_keys = attribute_must.keys
50
+
51
+ # NOTE: Even though the dynamic option `consists_of` is a `must`, here we are testing explicit `must`.
52
+ attribute_must_keys.delete(:consists_of)
53
+
54
+ attribute_must_keys.difference(must_names).empty? &&
55
+ must_names.difference(attribute_must_keys).empty?
51
56
  end
52
57
 
53
58
  def build_missing_option
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "have_service_input_matchers/default_matcher"
4
+ require_relative "have_service_input_matchers/optional_matcher"
5
+ require_relative "have_service_input_matchers/required_matcher"
6
+ require_relative "have_service_input_matchers/valid_with_matcher"
7
+
3
8
  module Servactory
4
9
  module TestKit
5
10
  module Rspec
@@ -17,6 +17,8 @@ module Servactory
17
17
 
18
18
  @attribute_data = described_class.info.public_send(attribute_type_plural).fetch(attribute_name)
19
19
 
20
+ @i18n_root_key = described_class.config.i18n_root_key
21
+
20
22
  @missing_option = ""
21
23
  end
22
24
 
@@ -41,7 +43,8 @@ module Servactory
41
43
  :attribute_type_plural,
42
44
  :attribute_name,
43
45
  :custom_message,
44
- :attribute_data
46
+ :attribute_data,
47
+ :i18n_root_key
45
48
 
46
49
  def submatcher_passes?(_subject) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
47
50
  attribute_required = attribute_data.fetch(:required).fetch(:is)
@@ -51,7 +54,7 @@ module Servactory
51
54
 
52
55
  if attribute_required_message.nil?
53
56
  attribute_required_message = I18n.t(
54
- "servactory.#{attribute_type_plural}.validations.required.default_error.default",
57
+ "#{i18n_root_key}.#{attribute_type_plural}.validations.required.default_error.default",
55
58
  service_class_name: described_class.name,
56
59
  "#{attribute_type}_name": attribute_name
57
60
  )
@@ -17,6 +17,8 @@ module Servactory
17
17
 
18
18
  @attribute_data = described_class.info.public_send(attribute_type_plural).fetch(attribute_name)
19
19
 
20
+ @i18n_root_key = described_class.config.i18n_root_key
21
+
20
22
  @missing_option = ""
21
23
  end
22
24
 
@@ -41,7 +43,8 @@ module Servactory
41
43
  :attribute_type_plural,
42
44
  :attribute_name,
43
45
  :attributes,
44
- :attribute_data
46
+ :attribute_data,
47
+ :i18n_root_key
45
48
 
46
49
  def submatcher_passes?(_subject) # rubocop:disable Metrics/CyclomaticComplexity
47
50
  success_passes? &&
@@ -60,41 +63,18 @@ module Servactory
60
63
 
61
64
  def failure_type_passes? # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
62
65
  option_types = attribute_data.fetch(:types)
63
- input_first_type = option_types.first
64
- input_required = attribute_data.fetch(:required).fetch(:is)
65
- attribute_consists_of_types = Array(attribute_data.fetch(:consists_of).fetch(:type))
66
- attribute_consists_of_first_type = attribute_consists_of_types.first
67
66
 
68
67
  prepared_attributes = attributes.dup
69
68
  prepared_attributes[attribute_name] = Servactory::TestKit::FakeType.new
70
69
 
71
70
  input_required_message =
72
- if described_class.config.collection_mode_class_names.include?(input_first_type) &&
73
- attribute_consists_of_first_type != false
74
- if input_required
75
- I18n.t(
76
- "servactory.#{attribute_type_plural}.validations.required.default_error.for_collection",
77
- service_class_name: described_class.name,
78
- "#{attribute_type}_name": attribute_name
79
- )
80
- else
81
- I18n.t(
82
- "servactory.#{attribute_type_plural}.validations.type.default_error.for_collection.wrong_type",
83
- service_class_name: described_class.name,
84
- "#{attribute_type}_name": attribute_name,
85
- expected_type: option_types.join(", "),
86
- given_type: Servactory::TestKit::FakeType.new.class.name
87
- )
88
- end
89
- else
90
- I18n.t(
91
- "servactory.#{attribute_type_plural}.validations.type.default_error.default",
92
- service_class_name: described_class.name,
93
- "#{attribute_type}_name": attribute_name,
94
- expected_type: option_types.join(", "),
95
- given_type: Servactory::TestKit::FakeType.new.class.name
96
- )
97
- end
71
+ I18n.t(
72
+ "#{i18n_root_key}.#{attribute_type_plural}.validations.type.default_error.default",
73
+ service_class_name: described_class.name,
74
+ "#{attribute_type}_name": attribute_name,
75
+ expected_type: option_types.join(", "),
76
+ given_type: Servactory::TestKit::FakeType.new.class.name
77
+ )
98
78
 
99
79
  expect_failure_with!(prepared_attributes, input_required_message)
100
80
  end
@@ -111,7 +91,7 @@ module Servactory
111
91
 
112
92
  if input_required_message.nil?
113
93
  input_required_message = I18n.t(
114
- "servactory.#{attribute_type_plural}.validations.required.default_error.default",
94
+ "#{i18n_root_key}.#{attribute_type_plural}.validations.required.default_error.default",
115
95
  service_class_name: described_class.name,
116
96
  "#{attribute_type}_name": attribute_name
117
97
  )
@@ -131,38 +111,14 @@ module Servactory
131
111
  expect_failure_with!(prepared_attributes, nil)
132
112
  end
133
113
 
134
- def failure_format_passes?
135
- # NOTE: Checking for negative cases is not implemented for `format`
114
+ def failure_consists_of_passes?
115
+ # NOTE: Checking for negative cases is not implemented for `consists_of`
136
116
  true
137
117
  end
138
118
 
139
- def failure_consists_of_passes? # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
140
- option_types = attribute_data.fetch(:types)
141
- input_first_type = option_types.first
142
-
143
- return true unless described_class.config.collection_mode_class_names.include?(input_first_type)
144
-
145
- prepared_attributes = attributes.dup
146
- prepared_attributes[attribute_name] = input_first_type[Servactory::TestKit::FakeType.new]
147
-
148
- attribute_consists_of_types = Array(attribute_data.fetch(:consists_of).fetch(:type))
149
- attribute_consists_of_first_type = attribute_consists_of_types.first
150
-
151
- return true if attribute_consists_of_first_type == false
152
-
153
- attribute_consists_of_message = attribute_data.fetch(:consists_of).fetch(:message)
154
-
155
- if attribute_consists_of_message.nil?
156
- attribute_consists_of_message = I18n.t(
157
- "servactory.#{attribute_type_plural}.validations.type.default_error.for_collection.wrong_element_type", # rubocop:disable Layout/LineLength
158
- service_class_name: described_class.name,
159
- "#{attribute_type}_name": attribute_name,
160
- expected_type: attribute_consists_of_types.join(", "),
161
- given_type: prepared_attributes[attribute_name].map { _1.class.name }.join(", ")
162
- )
163
- end
164
-
165
- expect_failure_with!(prepared_attributes, attribute_consists_of_message)
119
+ def failure_format_passes?
120
+ # NOTE: Checking for negative cases is not implemented for `format`
121
+ true
166
122
  end
167
123
 
168
124
  def failure_inclusion_passes? # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
@@ -179,7 +135,7 @@ module Servactory
179
135
 
180
136
  if input_required_message.nil?
181
137
  input_required_message = I18n.t(
182
- "servactory.#{attribute_type_plural}.validations.inclusion.default_error",
138
+ "#{i18n_root_key}.#{attribute_type_plural}.validations.inclusion.default_error",
183
139
  service_class_name: described_class.name,
184
140
  "#{attribute_type}_name": attribute_name,
185
141
  "#{attribute_type}_inclusion": input_inclusion_in,
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "have_service_attribute_matchers/types_matcher"
4
+ require_relative "have_service_attribute_matchers/consists_of_matcher"
5
+ require_relative "have_service_attribute_matchers/inclusion_matcher"
6
+ require_relative "have_service_attribute_matchers/must_matcher"
7
+
3
8
  module Servactory
4
9
  module TestKit
5
10
  module Rspec
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rspec/expectations"
3
+ require_relative "matchers/have_service_input_matcher"
4
+ require_relative "matchers/have_service_internal_matcher"
4
5
 
5
6
  module Servactory
6
7
  module TestKit