servactory 2.16.0 → 3.0.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.
- checksums.yaml +4 -4
- data/README.md +38 -9
- data/config/locales/de.yml +134 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/es.yml +134 -0
- data/config/locales/fr.yml +134 -0
- data/config/locales/it.yml +134 -0
- data/config/locales/ru.yml +15 -0
- data/lib/generators/README.md +45 -0
- data/lib/generators/servactory/base.rb +82 -0
- data/lib/generators/servactory/extension/USAGE +54 -0
- data/lib/generators/servactory/extension/extension_generator.rb +41 -0
- data/lib/generators/servactory/extension/templates/extension.rb.tt +62 -0
- data/lib/generators/servactory/install/USAGE +27 -0
- data/lib/generators/servactory/install/install_generator.rb +94 -0
- data/lib/generators/servactory/{templates/services/application_service/base.rb → install/templates/application_service/base.rb.tt} +29 -19
- data/lib/generators/servactory/{templates/services/application_service/exceptions.rb → install/templates/application_service/exceptions.rb.tt} +1 -1
- data/lib/generators/servactory/{templates/services/application_service/result.rb → install/templates/application_service/result.rb.tt} +1 -1
- data/lib/generators/servactory/rspec/USAGE +46 -0
- data/lib/generators/servactory/rspec/rspec_generator.rb +95 -0
- data/lib/generators/servactory/rspec/templates/service_spec.rb.tt +58 -0
- data/lib/generators/servactory/service/USAGE +51 -0
- data/lib/generators/servactory/service/service_generator.rb +56 -0
- data/lib/generators/servactory/service/templates/service.rb.tt +22 -0
- data/lib/servactory/actions/collection.rb +56 -1
- data/lib/servactory/actions/dsl.rb +11 -11
- data/lib/servactory/actions/tools/rules.rb +1 -1
- data/lib/servactory/actions/tools/runner.rb +111 -28
- data/lib/servactory/base.rb +1 -7
- data/lib/servactory/configuration/actions/aliases/collection.rb +5 -0
- data/lib/servactory/configuration/actions/rescue_handlers/collection.rb +5 -0
- data/lib/servactory/configuration/actions/shortcuts/collection.rb +5 -0
- data/lib/servactory/configuration/collection_mode/class_names_collection.rb +5 -0
- data/lib/servactory/configuration/config.rb +36 -0
- data/lib/servactory/configuration/configurable.rb +95 -0
- data/lib/servactory/configuration/dsl.rb +3 -27
- data/lib/servactory/configuration/factory.rb +20 -20
- data/lib/servactory/configuration/hash_mode/class_names_collection.rb +5 -0
- data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +5 -0
- data/lib/servactory/context/warehouse/inputs.rb +2 -2
- data/lib/servactory/context/workspace/inputs.rb +2 -2
- data/lib/servactory/context/workspace/internals.rb +2 -2
- data/lib/servactory/context/workspace/outputs.rb +2 -2
- data/lib/servactory/context/workspace.rb +11 -7
- data/lib/servactory/dsl.rb +10 -8
- data/lib/servactory/maintenance/attributes/tools/validation.rb +1 -1
- data/lib/servactory/result.rb +2 -2
- data/lib/servactory/stroma/dsl.rb +118 -0
- data/lib/servactory/stroma/entry.rb +32 -0
- data/lib/servactory/stroma/exceptions/base.rb +45 -0
- data/lib/servactory/stroma/exceptions/invalid_hook_type.rb +29 -0
- data/lib/servactory/stroma/exceptions/key_already_registered.rb +32 -0
- data/lib/servactory/stroma/exceptions/registry_frozen.rb +33 -0
- data/lib/servactory/stroma/exceptions/registry_not_finalized.rb +33 -0
- data/lib/servactory/stroma/exceptions/unknown_hook_target.rb +39 -0
- data/lib/servactory/stroma/hooks/applier.rb +63 -0
- data/lib/servactory/stroma/hooks/collection.rb +103 -0
- data/lib/servactory/stroma/hooks/factory.rb +80 -0
- data/lib/servactory/stroma/hooks/hook.rb +74 -0
- data/lib/servactory/stroma/registry.rb +94 -0
- data/lib/servactory/stroma/settings/collection.rb +90 -0
- data/lib/servactory/stroma/settings/registry_settings.rb +88 -0
- data/lib/servactory/stroma/settings/setting.rb +113 -0
- data/lib/servactory/stroma/state.rb +59 -0
- data/lib/servactory/test_kit/fake_type.rb +23 -0
- data/lib/servactory/test_kit/result.rb +45 -0
- data/lib/servactory/test_kit/rspec/helpers/argument_matchers.rb +97 -0
- data/lib/servactory/test_kit/rspec/helpers/concerns/error_messages.rb +179 -0
- data/lib/servactory/test_kit/rspec/helpers/concerns/service_class_validation.rb +74 -0
- data/lib/servactory/test_kit/rspec/helpers/fluent.rb +110 -0
- data/lib/servactory/test_kit/rspec/helpers/input_validator.rb +149 -0
- data/lib/servactory/test_kit/rspec/helpers/legacy.rb +228 -0
- data/lib/servactory/test_kit/rspec/helpers/mock_executor.rb +256 -0
- data/lib/servactory/test_kit/rspec/helpers/output_validator.rb +121 -0
- data/lib/servactory/test_kit/rspec/helpers/service_mock_builder.rb +422 -0
- data/lib/servactory/test_kit/rspec/helpers/service_mock_config.rb +129 -0
- data/lib/servactory/test_kit/rspec/helpers.rb +51 -84
- data/lib/servactory/test_kit/rspec/matchers/base/attribute_matcher.rb +324 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher.rb +133 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher_context.rb +101 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher_registry.rb +205 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/attribute_data_access.rb +100 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/error_message_builder.rb +106 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/value_comparison.rb +97 -0
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matcher.rb +89 -219
- data/lib/servactory/test_kit/rspec/matchers/have_service_internal_matcher.rb +74 -166
- data/lib/servactory/test_kit/rspec/matchers/have_service_output_matcher.rb +238 -0
- data/lib/servactory/test_kit/rspec/matchers/result/be_failure_service_matcher.rb +257 -0
- data/lib/servactory/test_kit/rspec/matchers/result/be_success_service_matcher.rb +185 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/default_submatcher.rb +81 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/optional_submatcher.rb +62 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/required_submatcher.rb +93 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/valid_with_submatcher.rb +271 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/consists_of_submatcher.rb +85 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/inclusion_submatcher.rb +120 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/message_submatcher.rb +115 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/must_submatcher.rb +82 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/schema_submatcher.rb +102 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/target_submatcher.rb +125 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/types_submatcher.rb +77 -0
- data/lib/servactory/test_kit/rspec/matchers.rb +126 -285
- data/lib/servactory/test_kit/utils/faker.rb +62 -2
- data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +166 -0
- data/lib/servactory/tool_kit/dynamic_options/format.rb +195 -8
- data/lib/servactory/tool_kit/dynamic_options/inclusion.rb +219 -17
- data/lib/servactory/tool_kit/dynamic_options/max.rb +143 -0
- data/lib/servactory/tool_kit/dynamic_options/min.rb +143 -0
- data/lib/servactory/tool_kit/dynamic_options/multiple_of.rb +157 -8
- data/lib/servactory/tool_kit/dynamic_options/must.rb +194 -0
- data/lib/servactory/tool_kit/dynamic_options/schema.rb +226 -2
- data/lib/servactory/tool_kit/dynamic_options/target.rb +252 -0
- data/lib/servactory/version.rb +3 -3
- data/lib/servactory.rb +4 -0
- metadata +73 -25
- data/lib/generators/servactory/install_generator.rb +0 -21
- data/lib/generators/servactory/rspec_generator.rb +0 -88
- data/lib/generators/servactory/service_generator.rb +0 -49
- data/lib/servactory/configuration/setup.rb +0 -97
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/consists_of_matcher.rb +0 -68
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/inclusion_matcher.rb +0 -73
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/message_matcher.rb +0 -91
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/must_matcher.rb +0 -72
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/schema_matcher.rb +0 -92
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/types_matcher.rb +0 -72
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/default_matcher.rb +0 -69
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/optional_matcher.rb +0 -63
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/required_matcher.rb +0 -81
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/valid_with_matcher.rb +0 -199
|
@@ -1,310 +1,151 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# RSpec matchers for testing Servactory service definitions and results.
|
|
4
|
+
#
|
|
5
|
+
# ## Purpose
|
|
6
|
+
#
|
|
7
|
+
# This module provides custom RSpec matchers for validating:
|
|
8
|
+
# - Service attribute definitions (inputs, internals, outputs)
|
|
9
|
+
# - Service execution results (success/failure)
|
|
10
|
+
#
|
|
11
|
+
# ## Usage
|
|
12
|
+
#
|
|
13
|
+
# Include matchers in RSpec configuration:
|
|
14
|
+
#
|
|
15
|
+
# ```ruby
|
|
16
|
+
# RSpec.configure do |config|
|
|
17
|
+
# config.include Servactory::TestKit::Rspec::Matchers, type: :service
|
|
18
|
+
# end
|
|
19
|
+
# ```
|
|
20
|
+
#
|
|
21
|
+
# Then use in specs:
|
|
22
|
+
#
|
|
23
|
+
# ```ruby
|
|
24
|
+
# RSpec.describe MyService, type: :service do
|
|
25
|
+
# it { is_expected.to have_service_input(:user_id).type(Integer).required }
|
|
26
|
+
# it { is_expected.to have_service_output(:result).type(String) }
|
|
27
|
+
#
|
|
28
|
+
# it "succeeds with valid input" do
|
|
29
|
+
# result = described_class.call(user_id: 123)
|
|
30
|
+
# expect(result).to be_success_service.with_output(:data, "value")
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
# ```
|
|
34
|
+
#
|
|
35
|
+
# ## Available Matchers
|
|
36
|
+
#
|
|
37
|
+
# - `have_service_input` / `have_input` - validates input attribute definitions
|
|
38
|
+
# - `have_service_internal` / `have_internal` - validates internal attribute definitions
|
|
39
|
+
# - `have_service_output` / `have_output` - validates output values on results
|
|
40
|
+
# - `be_success_service` - validates successful service result
|
|
41
|
+
# - `be_failure_service` - validates failed service result
|
|
42
|
+
|
|
43
|
+
# Concerns (must be loaded first, as they are used in Base classes)
|
|
44
|
+
require_relative "matchers/concerns/attribute_data_access"
|
|
45
|
+
require_relative "matchers/concerns/error_message_builder"
|
|
46
|
+
require_relative "matchers/concerns/value_comparison"
|
|
47
|
+
|
|
48
|
+
# Base classes (loaded after concerns)
|
|
49
|
+
require_relative "matchers/base/submatcher_context"
|
|
50
|
+
require_relative "matchers/base/submatcher"
|
|
51
|
+
require_relative "matchers/base/submatcher_registry"
|
|
52
|
+
require_relative "matchers/base/attribute_matcher"
|
|
53
|
+
|
|
54
|
+
# Shared submatchers
|
|
55
|
+
require_relative "matchers/submatchers/shared/types_submatcher"
|
|
56
|
+
require_relative "matchers/submatchers/shared/consists_of_submatcher"
|
|
57
|
+
require_relative "matchers/submatchers/shared/schema_submatcher"
|
|
58
|
+
require_relative "matchers/submatchers/shared/inclusion_submatcher"
|
|
59
|
+
require_relative "matchers/submatchers/shared/must_submatcher"
|
|
60
|
+
require_relative "matchers/submatchers/shared/message_submatcher"
|
|
61
|
+
require_relative "matchers/submatchers/shared/target_submatcher"
|
|
62
|
+
|
|
63
|
+
# Input submatchers
|
|
64
|
+
require_relative "matchers/submatchers/input/required_submatcher"
|
|
65
|
+
require_relative "matchers/submatchers/input/optional_submatcher"
|
|
66
|
+
require_relative "matchers/submatchers/input/default_submatcher"
|
|
67
|
+
require_relative "matchers/submatchers/input/valid_with_submatcher"
|
|
68
|
+
|
|
69
|
+
# Main matchers
|
|
3
70
|
require_relative "matchers/have_service_input_matcher"
|
|
4
71
|
require_relative "matchers/have_service_internal_matcher"
|
|
72
|
+
require_relative "matchers/have_service_output_matcher"
|
|
73
|
+
|
|
74
|
+
# Result matchers
|
|
75
|
+
require_relative "matchers/result/be_success_service_matcher"
|
|
76
|
+
require_relative "matchers/result/be_failure_service_matcher"
|
|
5
77
|
|
|
6
78
|
module Servactory
|
|
7
79
|
module TestKit
|
|
8
80
|
module Rspec
|
|
9
|
-
|
|
81
|
+
# RSpec matchers for Servactory service testing.
|
|
82
|
+
module Matchers
|
|
83
|
+
# Creates a matcher for validating service input attribute definitions.
|
|
84
|
+
#
|
|
85
|
+
# @param input_name [Symbol] The name of the input to validate
|
|
86
|
+
# @return [HaveServiceInputMatcher] Matcher with fluent chain methods
|
|
87
|
+
#
|
|
88
|
+
# @example
|
|
89
|
+
# expect(MyService).to have_service_input(:user_id)
|
|
90
|
+
# .type(Integer)
|
|
91
|
+
# .required
|
|
10
92
|
def have_service_input(input_name) # rubocop:disable Naming/PredicatePrefix
|
|
11
93
|
HaveServiceInputMatcher.new(described_class, input_name)
|
|
12
94
|
end
|
|
13
95
|
|
|
14
|
-
|
|
15
|
-
|
|
96
|
+
# Creates a matcher for validating service internal attribute definitions.
|
|
97
|
+
#
|
|
98
|
+
# @param internal_name [Symbol] The name of the internal to validate
|
|
99
|
+
# @return [HaveServiceInternalMatcher] Matcher with fluent chain methods
|
|
100
|
+
#
|
|
101
|
+
# @example
|
|
102
|
+
# expect(MyService).to have_service_internal(:processed_data)
|
|
103
|
+
# .type(Hash)
|
|
16
104
|
def have_service_internal(internal_name) # rubocop:disable Naming/PredicatePrefix
|
|
17
105
|
HaveServiceInternalMatcher.new(described_class, internal_name)
|
|
18
106
|
end
|
|
19
107
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
chain :instance_of do |class_or_name|
|
|
34
|
-
@instance_of = Servactory::Utils.constantize_class(class_or_name)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
chain :nested do |*values|
|
|
38
|
-
@nested = values
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
chain :contains do |value|
|
|
42
|
-
@value = value
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
failure_message do |actual|
|
|
46
|
-
match_for(actual, output_name)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
50
|
-
def match_for(actual, output_name)
|
|
51
|
-
given_value = actual.public_send(output_name)
|
|
52
|
-
|
|
53
|
-
if defined?(@instance_of)
|
|
54
|
-
expect(given_value).to(
|
|
55
|
-
RSpec::Matchers::BuiltIn::BeAnInstanceOf.new(@instance_of)
|
|
56
|
-
)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
if defined?(@nested) && @nested.present?
|
|
60
|
-
@nested.each do |method_name|
|
|
61
|
-
next unless given_value.respond_to?(method_name)
|
|
62
|
-
|
|
63
|
-
given_value = given_value.public_send(method_name)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
return true if !defined?(@value) && @value.nil?
|
|
68
|
-
|
|
69
|
-
expect(given_value).to(
|
|
70
|
-
case @value
|
|
71
|
-
when Array
|
|
72
|
-
RSpec::Matchers::BuiltIn::ContainExactly.new(@value)
|
|
73
|
-
when Hash
|
|
74
|
-
RSpec::Matchers::BuiltIn::Match.new(@value)
|
|
75
|
-
when TrueClass, FalseClass
|
|
76
|
-
RSpec::Matchers::BuiltIn::Equal.new(@value)
|
|
77
|
-
when NilClass
|
|
78
|
-
RSpec::Matchers::BuiltIn::BeNil.new(@value)
|
|
79
|
-
else
|
|
80
|
-
RSpec::Matchers::BuiltIn::Eq.new(@value)
|
|
81
|
-
end
|
|
82
|
-
)
|
|
83
|
-
end
|
|
108
|
+
# Creates a matcher for validating service result output values.
|
|
109
|
+
#
|
|
110
|
+
# @param output_name [Symbol] The name of the output to validate
|
|
111
|
+
# @return [HaveServiceOutputMatcher] Matcher with fluent chain methods
|
|
112
|
+
#
|
|
113
|
+
# @example
|
|
114
|
+
# expect(result).to have_service_output(:user)
|
|
115
|
+
# .instance_of(User)
|
|
116
|
+
# .contains(name: "John")
|
|
117
|
+
def have_service_output(output_name) # rubocop:disable Naming/PredicatePrefix
|
|
118
|
+
HaveServiceOutputMatcher.new(output_name)
|
|
84
119
|
end
|
|
85
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
86
|
-
|
|
87
|
-
RSpec::Matchers.alias_matcher :have_output, :have_service_output
|
|
88
|
-
|
|
89
|
-
RSpec::Matchers.define :be_success_service do # rubocop:disable Metrics/BlockLength
|
|
90
|
-
description { "service success" }
|
|
91
|
-
|
|
92
|
-
def expected_data
|
|
93
|
-
@expected_data ||= {}
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
match do |actual|
|
|
97
|
-
matched = actual.is_a?(Servactory::Result)
|
|
98
|
-
matched &&= actual.success?
|
|
99
|
-
matched &&= !actual.failure?
|
|
100
|
-
|
|
101
|
-
if defined?(expected_data)
|
|
102
|
-
matched &&= expected_data.all? do |key, value|
|
|
103
|
-
if actual.respond_to?(key)
|
|
104
|
-
actual.public_send(key) == value
|
|
105
|
-
else
|
|
106
|
-
false
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
matched
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
chain :with_output do |key, value|
|
|
115
|
-
expected_data[key] = value
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
chain :with_outputs do |attributes|
|
|
119
|
-
attributes.each do |key, value|
|
|
120
|
-
expected_data[key] = value
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
failure_message do |actual| # rubocop:disable Metrics/BlockLength
|
|
125
|
-
unless actual.is_a?(Servactory::Result)
|
|
126
|
-
break <<~MESSAGE
|
|
127
|
-
Incorrect service result:
|
|
128
|
-
|
|
129
|
-
expected Servactory::Result
|
|
130
|
-
got #{actual.class.name}
|
|
131
|
-
MESSAGE
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
if actual.failure?
|
|
135
|
-
break <<~MESSAGE
|
|
136
|
-
Incorrect service result:
|
|
137
|
-
|
|
138
|
-
expected success
|
|
139
|
-
got failure
|
|
140
|
-
MESSAGE
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
if defined?(expected_data)
|
|
144
|
-
message = expected_data.each do |key, value|
|
|
145
|
-
unless actual.respond_to?(key)
|
|
146
|
-
break <<~MESSAGE
|
|
147
|
-
Non-existent value key in result:
|
|
148
|
-
|
|
149
|
-
expected #{actual.inspect}
|
|
150
|
-
got #{key}
|
|
151
|
-
MESSAGE
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
received_value = actual.public_send(key)
|
|
155
|
-
next if actual.public_send(key) == value
|
|
156
|
-
|
|
157
|
-
break <<~MESSAGE
|
|
158
|
-
Incorrect result value for #{key}:
|
|
159
120
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Unexpected case when using `be_success_service`.
|
|
170
|
-
|
|
171
|
-
Please try to build an example based on the documentation.
|
|
172
|
-
Or report your problem to us:
|
|
173
|
-
|
|
174
|
-
https://github.com/servactory/servactory/issues
|
|
175
|
-
MESSAGE
|
|
176
|
-
end
|
|
121
|
+
# Creates a matcher for validating successful service results.
|
|
122
|
+
#
|
|
123
|
+
# @return [Result::BeSuccessServiceMatcher] Matcher with output chain methods
|
|
124
|
+
#
|
|
125
|
+
# @example
|
|
126
|
+
# expect(result).to be_success_service
|
|
127
|
+
# .with_output(:data, "value")
|
|
128
|
+
def be_success_service
|
|
129
|
+
Result::BeSuccessServiceMatcher.new
|
|
177
130
|
end
|
|
178
131
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
matched = actual.is_a?(Servactory::Result)
|
|
191
|
-
matched &&= !actual.success?
|
|
192
|
-
matched &&= actual.failure?
|
|
193
|
-
matched &&= actual.error.is_a?(Servactory::Exceptions::Failure)
|
|
194
|
-
matched &&= actual.error.is_a?(expected_failure_class)
|
|
195
|
-
matched &&= actual.error.type == expected_type
|
|
196
|
-
matched &&= actual.error.message == expected_message if defined?(@expected_message)
|
|
197
|
-
matched &&= actual.error.meta == expected_meta if defined?(@expected_meta)
|
|
198
|
-
matched
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
chain :with do |expected_failure_class|
|
|
202
|
-
@expected_failure_class = expected_failure_class
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
chain :type do |expected_type|
|
|
206
|
-
@expected_type = expected_type
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
chain :message do |expected_message|
|
|
210
|
-
@expected_message = expected_message
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
chain :meta do |expected_meta|
|
|
214
|
-
@expected_meta = expected_meta
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
failure_message do |actual| # rubocop:disable Metrics/BlockLength
|
|
218
|
-
unless actual.is_a?(Servactory::Result)
|
|
219
|
-
break <<~MESSAGE
|
|
220
|
-
Incorrect service result:
|
|
221
|
-
|
|
222
|
-
expected Servactory::Result
|
|
223
|
-
got #{actual.class.name}
|
|
224
|
-
MESSAGE
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
if actual.success?
|
|
228
|
-
break <<~MESSAGE
|
|
229
|
-
Incorrect service result:
|
|
230
|
-
|
|
231
|
-
expected failure
|
|
232
|
-
got success
|
|
233
|
-
MESSAGE
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
unless actual.error.is_a?(Servactory::Exceptions::Failure)
|
|
237
|
-
break <<~MESSAGE
|
|
238
|
-
Incorrect error object:
|
|
239
|
-
|
|
240
|
-
expected Servactory::Exceptions::Failure
|
|
241
|
-
got #{actual.error.class.name}
|
|
242
|
-
MESSAGE
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
if defined?(@expected_failure_class)
|
|
246
|
-
unless actual.error.is_a?(@expected_failure_class)
|
|
247
|
-
break <<~MESSAGE
|
|
248
|
-
Incorrect instance error:
|
|
249
|
-
|
|
250
|
-
expected #{@expected_failure_class}
|
|
251
|
-
got #{actual.error.class.name}
|
|
252
|
-
MESSAGE
|
|
253
|
-
end
|
|
254
|
-
else
|
|
255
|
-
unless actual.error.is_a?(Servactory::Exceptions::Failure)
|
|
256
|
-
break <<~MESSAGE
|
|
257
|
-
Incorrect error object:
|
|
258
|
-
|
|
259
|
-
expected Servactory::Exceptions::Failure
|
|
260
|
-
got #{actual.error.class.name}
|
|
261
|
-
MESSAGE
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
if defined?(@expected_type) && actual.error.type != @expected_type
|
|
266
|
-
break <<~MESSAGE
|
|
267
|
-
Incorrect error type:
|
|
268
|
-
|
|
269
|
-
expected #{actual.error.type.inspect}
|
|
270
|
-
got #{@expected_type.inspect}
|
|
271
|
-
MESSAGE
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
if defined?(@expected_message) && actual.error.message != @expected_message
|
|
275
|
-
break <<~MESSAGE
|
|
276
|
-
Incorrect error message:
|
|
277
|
-
|
|
278
|
-
expected #{actual.error.message.inspect}
|
|
279
|
-
got #{@expected_message.inspect}
|
|
280
|
-
MESSAGE
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
if defined?(@expected_meta) && actual.error.meta != @expected_meta
|
|
284
|
-
break <<~MESSAGE
|
|
285
|
-
Incorrect error meta:
|
|
286
|
-
|
|
287
|
-
expected #{actual.error.meta.inspect}
|
|
288
|
-
got #{@expected_meta.inspect}
|
|
289
|
-
MESSAGE
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
<<~MESSAGE
|
|
293
|
-
Unexpected case when using `be_failure_service`.
|
|
294
|
-
|
|
295
|
-
Exception: #{actual.error.inspect}
|
|
296
|
-
Type: #{actual.error.type.inspect}
|
|
297
|
-
Message: #{actual.error.message.inspect}
|
|
298
|
-
Meta: #{actual.error.meta.inspect}
|
|
299
|
-
|
|
300
|
-
Please try to build an example based on the documentation.
|
|
301
|
-
Or report your problem to us:
|
|
302
|
-
|
|
303
|
-
https://github.com/servactory/servactory/issues
|
|
304
|
-
MESSAGE
|
|
305
|
-
end
|
|
132
|
+
# Creates a matcher for validating failed service results.
|
|
133
|
+
#
|
|
134
|
+
# @return [Result::BeFailureServiceMatcher] Matcher with error chain methods
|
|
135
|
+
#
|
|
136
|
+
# @example
|
|
137
|
+
# expect(result).to be_failure_service
|
|
138
|
+
# .type(:validation_error)
|
|
139
|
+
# .message("Invalid input")
|
|
140
|
+
def be_failure_service
|
|
141
|
+
Result::BeFailureServiceMatcher.new
|
|
306
142
|
end
|
|
307
143
|
end
|
|
308
144
|
end
|
|
309
145
|
end
|
|
310
146
|
end
|
|
147
|
+
|
|
148
|
+
# Register shorter aliases for convenience.
|
|
149
|
+
RSpec::Matchers.alias_matcher :have_input, :have_service_input
|
|
150
|
+
RSpec::Matchers.alias_matcher :have_internal, :have_service_internal
|
|
151
|
+
RSpec::Matchers.alias_matcher :have_output, :have_service_output
|
|
@@ -3,9 +3,43 @@
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module TestKit
|
|
5
5
|
module Utils
|
|
6
|
+
# Generates fake test values for different Ruby types.
|
|
7
|
+
#
|
|
8
|
+
# ## Purpose
|
|
9
|
+
#
|
|
10
|
+
# Provides fake values for testing input validations. Used by
|
|
11
|
+
# ValidWithSubmatcher to generate values that will trigger specific
|
|
12
|
+
# validation failures (e.g., wrong inclusion values).
|
|
13
|
+
#
|
|
14
|
+
# ## Usage
|
|
15
|
+
#
|
|
16
|
+
# ```ruby
|
|
17
|
+
# # Get a fake value for a type
|
|
18
|
+
# Faker.fetch_value_for(String) # => "fake"
|
|
19
|
+
# Faker.fetch_value_for(Integer) # => 123
|
|
20
|
+
# Faker.fetch_value_for(Array, of: :integer) # => [1, 2, 3]
|
|
21
|
+
# ```
|
|
22
|
+
#
|
|
23
|
+
# ## Supported Types
|
|
24
|
+
#
|
|
25
|
+
# - Symbol - returns `:fake`
|
|
26
|
+
# - String - returns `"fake"`
|
|
27
|
+
# - Integer - returns `123`
|
|
28
|
+
# - Float - returns `12.3`
|
|
29
|
+
# - Range - returns `1..3`
|
|
30
|
+
# - Array - returns `["fake"]` or `[1, 2, 3]` based on `of:` param
|
|
31
|
+
# - Hash - returns `{ fake: :yes }` or `{ fake: 1 }` based on `of:` param
|
|
32
|
+
# - TrueClass - returns `true`
|
|
33
|
+
# - FalseClass - returns `false`
|
|
34
|
+
# - NilClass - returns `nil`
|
|
6
35
|
module Faker
|
|
7
36
|
extend self
|
|
8
37
|
|
|
38
|
+
# Generates a fake value for the given type.
|
|
39
|
+
#
|
|
40
|
+
# @param class_or_name [Class, String] Type to generate value for
|
|
41
|
+
# @param of [Symbol] Element type for Array/Hash (:string or :integer)
|
|
42
|
+
# @return [Object] Fake value of the requested type
|
|
9
43
|
def fetch_value_for(class_or_name, of: :string) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
10
44
|
class_for_fake = Servactory::Utils.constantize_class(class_or_name)
|
|
11
45
|
of = of.to_sym
|
|
@@ -23,52 +57,78 @@ module Servactory
|
|
|
23
57
|
NilClass => method(:fake_nil_class)
|
|
24
58
|
}
|
|
25
59
|
|
|
26
|
-
|
|
27
|
-
|
|
60
|
+
fake_class = faker[class_for_fake] || -> { unsupported_faker(class_for_fake) }
|
|
61
|
+
fake_class.call
|
|
28
62
|
end
|
|
29
63
|
|
|
30
64
|
private
|
|
31
65
|
|
|
66
|
+
# Returns fake Symbol value.
|
|
67
|
+
# @return [Symbol]
|
|
32
68
|
def fake_symbol
|
|
33
69
|
:fake
|
|
34
70
|
end
|
|
35
71
|
|
|
72
|
+
# Returns fake String value.
|
|
73
|
+
# @return [String]
|
|
36
74
|
def fake_string
|
|
37
75
|
"fake"
|
|
38
76
|
end
|
|
39
77
|
|
|
78
|
+
# Returns fake Integer value.
|
|
79
|
+
# @return [Integer]
|
|
40
80
|
def fake_integer
|
|
41
81
|
123
|
|
42
82
|
end
|
|
43
83
|
|
|
84
|
+
# Returns fake Float value.
|
|
85
|
+
# @return [Float]
|
|
44
86
|
def fake_float
|
|
45
87
|
12.3
|
|
46
88
|
end
|
|
47
89
|
|
|
90
|
+
# Returns fake Range value.
|
|
91
|
+
# @return [Range]
|
|
48
92
|
def fake_range
|
|
49
93
|
1..3
|
|
50
94
|
end
|
|
51
95
|
|
|
96
|
+
# Returns fake Array value.
|
|
97
|
+
# @param of [Symbol] Element type (:string or :integer)
|
|
98
|
+
# @return [Array]
|
|
52
99
|
def fake_array(of)
|
|
53
100
|
of == :integer ? [1, 2, 3] : ["fake"]
|
|
54
101
|
end
|
|
55
102
|
|
|
103
|
+
# Returns fake Hash value.
|
|
104
|
+
# @param of [Symbol] Value type (:string or :integer)
|
|
105
|
+
# @return [Hash]
|
|
56
106
|
def fake_hash(of)
|
|
57
107
|
of == :integer ? { fake: 1 } : { fake: :yes }
|
|
58
108
|
end
|
|
59
109
|
|
|
110
|
+
# Returns true (fake TrueClass value).
|
|
111
|
+
# @return [Boolean]
|
|
60
112
|
def fake_true_class # rubocop:disable Naming/PredicateMethod
|
|
61
113
|
true
|
|
62
114
|
end
|
|
63
115
|
|
|
116
|
+
# Returns false (fake FalseClass value).
|
|
117
|
+
# @return [Boolean]
|
|
64
118
|
def fake_false_class # rubocop:disable Naming/PredicateMethod
|
|
65
119
|
false
|
|
66
120
|
end
|
|
67
121
|
|
|
122
|
+
# Returns nil (fake NilClass value).
|
|
123
|
+
# @return [nil]
|
|
68
124
|
def fake_nil_class
|
|
69
125
|
nil
|
|
70
126
|
end
|
|
71
127
|
|
|
128
|
+
# Handles unsupported types by attempting to instantiate them.
|
|
129
|
+
#
|
|
130
|
+
# @param class_for_fake [Class] The unsupported type class
|
|
131
|
+
# @return [Object] New instance or the class itself
|
|
72
132
|
def unsupported_faker(class_for_fake)
|
|
73
133
|
class_for_fake.respond_to?(:new) ? class_for_fake.new : class_for_fake
|
|
74
134
|
end
|