Class: SpecForge::Attribute::Matcher
- Inherits:
-
Parameterized
- Object
- Attribute
- Parameterized
- SpecForge::Attribute::Matcher
- Defined in:
- lib/spec_forge/attribute/matcher.rb
Overview
Represents an attribute that uses RSpec matchers for response validation
This class allows SpecForge to integrate with RSpec's powerful matchers for flexible response validation. It supports most of the built-in RSpec matchers and most custom matchers, assuming they do not require more Ruby code
Defined Under Namespace
Classes: RSpecMatchers
Constant Summary collapse
- KEYWORD_REGEX =
Regular expression pattern that matches attribute keywords with this prefix Used for identifying this attribute type during parsing
/^matchers?\.|^be\.|^kind_of\./i- MATCHER_METHODS =
Instance of Methods providing access to all RSpec matchers
RSpecMatchers.new.freeze
- LITERAL_MAPPINGS =
Mapping of literal string values to their Ruby equivalents Used for be.nil, be.true, and be.false matchers
{ "nil" => nil, "true" => true, "false" => false }.freeze
Instance Attribute Summary collapse
-
#matcher_method ⇒ Object
readonly
The resolved RSpec matcher method to call.
Attributes inherited from Parameterized
Instance Method Summary collapse
-
#initialize ⇒ Matcher
constructor
Creates a new matcher attribute with the specified matcher and arguments.
-
#resolve_as_matcher ⇒ RSpec::Matchers::BuiltIn::BaseMatcher
Ensures proper conversion of nested matcher arguments based on context.
-
#value ⇒ RSpec::Matchers::BuiltIn::BaseMatcher
Returns the result of applying the matcher with the given arguments Creates an RSpec matcher that can be used in expectations.
Methods inherited from Parameterized
Constructor Details
#initialize ⇒ Matcher
Creates a new matcher attribute with the specified matcher and arguments
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/spec_forge/attribute/matcher.rb', line 69 def initialize(...) super namespace, method = extract_namespace_and_method @matcher_method = case namespace when "be" resolve_be_matcher(method) when "kind_of" resolve_kind_of_matcher(method) else resolve_base_matcher(method) end prepare_arguments # An argument can be an expanded version of something (such as matcher.include) # Move it to where it belongs if (keyword = arguments[:keyword]) && !keyword.is_a?(Hash) arguments[:positional] << keyword arguments[:keyword] = {} end end |
Instance Attribute Details
#matcher_method ⇒ Object (readonly)
The resolved RSpec matcher method to call
60 61 62 |
# File 'lib/spec_forge/attribute/matcher.rb', line 60 def matcher_method @matcher_method end |
Instance Method Details
#resolve_as_matcher ⇒ RSpec::Matchers::BuiltIn::BaseMatcher
Ensures proper conversion of nested matcher arguments based on context
This method overrides handles a special case of matchers that take arguments which themselves might need to be converted to matchers. It skips conversion for string arguments that should remain strings (like with include, start_with, and end_with) while correctly handling nested matchers and other argument types.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/spec_forge/attribute/matcher.rb', line 136 def resolve_as_matcher # Argument conversion only matters for the base matchers if input.start_with?("matcher") block = lambda do |argument| next argument unless convert_argument?(argument) argument.resolve_as_matcher end arguments[:positional].map!(&block) arguments[:keyword].transform_values!(&block) end super end |
#value ⇒ RSpec::Matchers::BuiltIn::BaseMatcher
Returns the result of applying the matcher with the given arguments Creates an RSpec matcher that can be used in expectations
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/spec_forge/attribute/matcher.rb', line 100 def value if (positional = arguments[:positional]) && positional.present? positional = positional.resolved.each do |value| value.deep_stringify_keys! if value.respond_to?(:deep_stringify_keys!) end matcher_method.call(*positional) elsif (keyword = arguments[:keyword]) && keyword.present? matcher_method.call(**keyword.resolved.deep_stringify_keys) else matcher_method.call end end |