diff --git a/codegen/projections/rails_json/lib/rails_json/auth.rb b/codegen/projections/rails_json/lib/rails_json/auth.rb index da65bad8a..63edb7f96 100644 --- a/codegen/projections/rails_json/lib/rails_json/auth.rb +++ b/codegen/projections/rails_json/lib/rails_json/auth.rb @@ -9,7 +9,13 @@ module RailsJson module Auth - Params = Struct.new(:operation_name, keyword_init: true) + class Params + def initialize(operation_name: nil) + @operation_name = operation_name + end + + attr_accessor :operation_name + end SCHEMES = [ Hearth::AuthSchemes::Anonymous.new diff --git a/codegen/projections/rails_json/lib/rails_json/config.rb b/codegen/projections/rails_json/lib/rails_json/config.rb index 23583ac59..2a06bb5d6 100644 --- a/codegen/projections/rails_json/lib/rails_json/config.rb +++ b/codegen/projections/rails_json/lib/rails_json/config.rb @@ -91,26 +91,29 @@ module RailsJson # @return [Hearth::Stubs] # @!attribute validate_input # @return [Boolean] - Config = ::Struct.new( - :auth_resolver, - :auth_schemes, - :disable_host_prefix, - :disable_request_compression, - :endpoint, - :endpoint_resolver, - :http_client, - :interceptors, - :logger, - :plugins, - :request_min_compression_size_bytes, - :retry_strategy, - :stub_responses, - :stubs, - :validate_input, - keyword_init: true - ) do + class Config include Hearth::Configuration + MEMBERS = %i[ + auth_resolver + auth_schemes + disable_host_prefix + disable_request_compression + endpoint + endpoint_resolver + http_client + interceptors + logger + plugins + request_min_compression_size_bytes + retry_strategy + stub_responses + stubs + validate_input + ].freeze + + attr_accessor(*MEMBERS) + # Validates the configuration. def validate! Hearth::Validator.validate_responds_to!(auth_resolver, :resolve, context: 'config[:auth_resolver]') diff --git a/codegen/projections/rails_json/lib/rails_json/endpoint.rb b/codegen/projections/rails_json/lib/rails_json/endpoint.rb index 378dbea6b..30bcee06e 100644 --- a/codegen/projections/rails_json/lib/rails_json/endpoint.rb +++ b/codegen/projections/rails_json/lib/rails_json/endpoint.rb @@ -9,11 +9,12 @@ module RailsJson module Endpoint - Params = ::Struct.new( - :endpoint, - keyword_init: true - ) do - include Hearth::Structure + class Params + def initialize(endpoint: nil) + @endpoint = endpoint + end + + attr_accessor :endpoint end class Resolver diff --git a/codegen/projections/rails_json/lib/rails_json/plugins/global_config.rb b/codegen/projections/rails_json/lib/rails_json/plugins/global_config.rb index 8114b8745..fa257f629 100644 --- a/codegen/projections/rails_json/lib/rails_json/plugins/global_config.rb +++ b/codegen/projections/rails_json/lib/rails_json/plugins/global_config.rb @@ -17,7 +17,7 @@ class GlobalConfig def call(config) options = config.options ::Hearth.config.each do |key, value| - config[key] = value unless options.key?(key) + config.send("#{key}=", value) unless options.key?(key) end end diff --git a/codegen/projections/rails_json/lib/rails_json/types.rb b/codegen/projections/rails_json/lib/rails_json/types.rb index e2e0f443e..c3f783dc7 100644 --- a/codegen/projections/rails_json/lib/rails_json/types.rb +++ b/codegen/projections/rails_json/lib/rails_json/types.rb @@ -1925,50 +1925,30 @@ class StringValue < MyUnion def to_h { string_value: super(__getobj__) } end - - def to_s - "#" - end end class BooleanValue < MyUnion def to_h { boolean_value: super(__getobj__) } end - - def to_s - "#" - end end class NumberValue < MyUnion def to_h { number_value: super(__getobj__) } end - - def to_s - "#" - end end class BlobValue < MyUnion def to_h { blob_value: super(__getobj__) } end - - def to_s - "#" - end end class TimestampValue < MyUnion def to_h { timestamp_value: super(__getobj__) } end - - def to_s - "#" - end end # Enum, one of: ["Foo", "Baz", "Bar", "1", "0"] @@ -1976,50 +1956,30 @@ class EnumValue < MyUnion def to_h { enum_value: super(__getobj__) } end - - def to_s - "#" - end end class ListValue < MyUnion def to_h { list_value: super(__getobj__) } end - - def to_s - "#" - end end class MapValue < MyUnion def to_h { map_value: super(__getobj__) } end - - def to_s - "#" - end end class StructureValue < MyUnion def to_h { structure_value: super(__getobj__) } end - - def to_s - "#" - end end class RenamedStructureValue < MyUnion def to_h { renamed_structure_value: super(__getobj__) } end - - def to_s - "#" - end end class Unknown < MyUnion @@ -2519,10 +2479,6 @@ class Quit < PlayerAction def to_h { quit: super(__getobj__) } end - - def to_s - "#" - end end class Unknown < PlayerAction @@ -3424,10 +3380,6 @@ class Greeting < UnionPayload def to_h { greeting: super(__getobj__) } end - - def to_s - "#" - end end class Unknown < UnionPayload @@ -3450,30 +3402,18 @@ class Foo < UnionWithJsonName def to_h { foo: super(__getobj__) } end - - def to_s - "#" - end end class Bar < UnionWithJsonName def to_h { bar: super(__getobj__) } end - - def to_s - "#" - end end class Baz < UnionWithJsonName def to_h { baz: super(__getobj__) } end - - def to_s - "#" - end end class Unknown < UnionWithJsonName diff --git a/codegen/projections/rails_json/sig/rails_json/auth.rbs b/codegen/projections/rails_json/sig/rails_json/auth.rbs index cc320c39f..da5377dae 100644 --- a/codegen/projections/rails_json/sig/rails_json/auth.rbs +++ b/codegen/projections/rails_json/sig/rails_json/auth.rbs @@ -9,7 +9,8 @@ module RailsJson module Auth - class Params < ::Struct[untyped] + class Params + def initialize: (?operation_name: ::Symbol?) -> void attr_accessor operation_name (): ::Symbol end diff --git a/codegen/projections/rails_json/sig/rails_json/config.rbs b/codegen/projections/rails_json/sig/rails_json/config.rbs index 4637ef242..ef2d8eaa1 100644 --- a/codegen/projections/rails_json/sig/rails_json/config.rbs +++ b/codegen/projections/rails_json/sig/rails_json/config.rbs @@ -1,22 +1,21 @@ module RailsJson - class Config < ::Struct[untyped] + class Config include Hearth::Configuration[instance] - - attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params] - attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base] - attr_accessor disable_host_prefix (): bool - attr_accessor disable_request_compression (): bool - attr_accessor endpoint (): String - attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params] - attr_accessor http_client (): Hearth::HTTP::Client - attr_accessor interceptors (): Hearth::InterceptorList[Config] - attr_accessor logger (): Logger - attr_accessor plugins (): Hearth::PluginList[Config] - attr_accessor request_min_compression_size_bytes (): Integer - attr_accessor retry_strategy (): Hearth::_RetryStrategy - attr_accessor stub_responses (): bool - attr_accessor stubs (): Hearth::Stubs - attr_accessor validate_input (): bool + attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params]? + attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base]? + attr_accessor disable_host_prefix (): bool? + attr_accessor disable_request_compression (): bool? + attr_accessor endpoint (): String? + attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params]? + attr_accessor http_client (): Hearth::HTTP::Client? + attr_accessor interceptors (): Hearth::InterceptorList[Config]? + attr_accessor logger (): Logger? + attr_accessor plugins (): Hearth::PluginList[Config]? + attr_accessor request_min_compression_size_bytes (): Integer? + attr_accessor retry_strategy (): Hearth::_RetryStrategy? + attr_accessor stub_responses (): bool? + attr_accessor stubs (): Hearth::Stubs? + attr_accessor validate_input (): bool? def validate!: () -> void end diff --git a/codegen/projections/rails_json/sig/rails_json/endpoint.rbs b/codegen/projections/rails_json/sig/rails_json/endpoint.rbs index 85ca39059..5894355ce 100644 --- a/codegen/projections/rails_json/sig/rails_json/endpoint.rbs +++ b/codegen/projections/rails_json/sig/rails_json/endpoint.rbs @@ -9,8 +9,9 @@ module RailsJson module Endpoint - class Params < ::Struct[untyped] - attr_accessor endpoint: ::String + class Params + def initialize: (?endpoint: ::String?) -> void + attr_accessor endpoint (): ::String? end class Resolver diff --git a/codegen/projections/rails_json/sig/rails_json/types.rbs b/codegen/projections/rails_json/sig/rails_json/types.rbs index 62d9fee19..9174074ce 100644 --- a/codegen/projections/rails_json/sig/rails_json/types.rbs +++ b/codegen/projections/rails_json/sig/rails_json/types.rbs @@ -68,7 +68,7 @@ module RailsJson class ConstantQueryStringInput include Hearth::Structure - attr_accessor hello (): ::String + attr_accessor hello (): ::String? end class ConstantQueryStringOutput @@ -173,7 +173,7 @@ module RailsJson class EndpointWithHostLabelOperationInput include Hearth::Structure - attr_accessor label (): ::String + attr_accessor label (): ::String? end class EndpointWithHostLabelOperationOutput @@ -315,8 +315,8 @@ module RailsJson class HttpRequestWithFloatLabelsInput include Hearth::Structure - attr_accessor float (): ::Float - attr_accessor double (): ::Float + attr_accessor float (): ::Float? + attr_accessor double (): ::Float? end class HttpRequestWithFloatLabelsOutput @@ -325,8 +325,8 @@ module RailsJson class HttpRequestWithGreedyLabelInPathInput include Hearth::Structure - attr_accessor foo (): ::String - attr_accessor baz (): ::String + attr_accessor foo (): ::String? + attr_accessor baz (): ::String? end class HttpRequestWithGreedyLabelInPathOutput @@ -335,13 +335,13 @@ module RailsJson class HttpRequestWithLabelsAndTimestampFormatInput include Hearth::Structure - attr_accessor member_epoch_seconds (): ::Time - attr_accessor member_http_date (): ::Time - attr_accessor member_date_time (): ::Time - attr_accessor default_format (): ::Time - attr_accessor target_epoch_seconds (): ::Time - attr_accessor target_http_date (): ::Time - attr_accessor target_date_time (): ::Time + attr_accessor member_epoch_seconds (): ::Time? + attr_accessor member_http_date (): ::Time? + attr_accessor member_date_time (): ::Time? + attr_accessor default_format (): ::Time? + attr_accessor target_epoch_seconds (): ::Time? + attr_accessor target_http_date (): ::Time? + attr_accessor target_date_time (): ::Time? end class HttpRequestWithLabelsAndTimestampFormatOutput @@ -350,14 +350,14 @@ module RailsJson class HttpRequestWithLabelsInput include Hearth::Structure - attr_accessor string (): ::String - attr_accessor short (): ::Integer - attr_accessor integer (): ::Integer - attr_accessor long (): ::Integer - attr_accessor float (): ::Float - attr_accessor double (): ::Float - attr_accessor boolean (): bool - attr_accessor timestamp (): ::Time + attr_accessor string (): ::String? + attr_accessor short (): ::Integer? + attr_accessor integer (): ::Integer? + attr_accessor long (): ::Integer? + attr_accessor float (): ::Float? + attr_accessor double (): ::Float? + attr_accessor boolean (): bool? + attr_accessor timestamp (): ::Time? end class HttpRequestWithLabelsOutput @@ -366,7 +366,7 @@ module RailsJson class HttpRequestWithRegexLiteralInput include Hearth::Structure - attr_accessor str (): ::String + attr_accessor str (): ::String? end class HttpRequestWithRegexLiteralOutput @@ -768,12 +768,12 @@ module RailsJson class OperationWithNestedStructureInput include Hearth::Structure - attr_accessor top_level (): Types::TopLevel + attr_accessor top_level (): Types::TopLevel? end class OperationWithNestedStructureOutput include Hearth::Structure - attr_accessor dialog (): Types::Dialog + attr_accessor dialog (): Types::Dialog? attr_accessor dialog_list (): ::Array[Types::Dialog]? attr_accessor dialog_map (): ::Hash[::String, Types::Dialog]? end @@ -802,7 +802,7 @@ module RailsJson class PostPlayerActionOutput include Hearth::Structure - attr_accessor action (): Types::PlayerAction + attr_accessor action (): Types::PlayerAction? end class PostUnionWithJsonNameInput @@ -812,7 +812,7 @@ module RailsJson class PostUnionWithJsonNameOutput include Hearth::Structure - attr_accessor value (): Types::UnionWithJsonName + attr_accessor value (): Types::UnionWithJsonName? end class PutWithContentEncodingInput @@ -1070,7 +1070,7 @@ module RailsJson class TopLevel include Hearth::Structure - attr_accessor dialog (): Types::Dialog + attr_accessor dialog (): Types::Dialog? attr_accessor dialog_list (): ::Array[Types::Dialog]? attr_accessor dialog_map (): ::Hash[::String, Types::Dialog]? end diff --git a/codegen/projections/rails_json/spec/protocol_spec.rb b/codegen/projections/rails_json/spec/protocol_spec.rb index 91bc08244..929b62dcd 100644 --- a/codegen/projections/rails_json/spec/protocol_spec.rb +++ b/codegen/projections/rails_json/spec/protocol_spec.rb @@ -478,7 +478,7 @@ module RailsJson describe 'stubs' do # Ensures that clients can correctly parse datetime (timestamps) with offsets - it 'stubs RailsJsonDateTimeWithNegativeOffset' do + it 'RailsJsonDateTimeWithNegativeOffset' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -494,7 +494,7 @@ module RailsJson end # Ensures that clients can correctly parse datetime (timestamps) with offsets - it 'stubs RailsJsonDateTimeWithPositiveOffset' do + it 'RailsJsonDateTimeWithPositiveOffset' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -743,7 +743,7 @@ module RailsJson describe 'stubs' do # Serializes documents as part of the JSON response payload with no escaping. - it 'stubs RailsJsonDocumentOutput' do + it 'RailsJsonDocumentOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -761,7 +761,7 @@ module RailsJson end # Document types can be JSON scalars too. - it 'stubs RailsJsonDocumentOutputString' do + it 'RailsJsonDocumentOutputString' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -779,7 +779,7 @@ module RailsJson end # Document types can be JSON scalars too. - it 'stubs RailsJsonDocumentOutputNumber' do + it 'RailsJsonDocumentOutputNumber' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -797,7 +797,7 @@ module RailsJson end # Document types can be JSON scalars too. - it 'stubs RailsJsonDocumentOutputBoolean' do + it 'RailsJsonDocumentOutputBoolean' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -815,7 +815,7 @@ module RailsJson end # Document types can be JSON arrays. - it 'stubs RailsJsonDocumentOutputArray' do + it 'RailsJsonDocumentOutputArray' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -900,7 +900,7 @@ module RailsJson describe 'stubs' do # Serializes a map that uses documents as the value. - it 'stubs RailsJsonDocumentTypeAsMapValueOutput' do + it 'RailsJsonDocumentTypeAsMapValueOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1006,7 +1006,7 @@ module RailsJson describe 'stubs' do # Serializes a document as the target of the httpPayload trait. - it 'stubs RailsJsonDocumentTypeAsPayloadOutput' do + it 'RailsJsonDocumentTypeAsPayloadOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1022,7 +1022,7 @@ module RailsJson end # Serializes a document as a payload string. - it 'stubs RailsJsonDocumentTypeAsPayloadOutputString' do + it 'RailsJsonDocumentTypeAsPayloadOutputString' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1099,7 +1099,7 @@ module RailsJson # As of January 2021, server implementations are expected to # respond with a JSON object regardless of if the output # parameters are empty. - it 'stubs RailsJsonEmptyInputAndEmptyOutput' do + it 'RailsJsonEmptyInputAndEmptyOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1112,7 +1112,7 @@ module RailsJson # This test ensures that clients can gracefully handle # situations where a service omits a JSON payload entirely. - it 'stubs RailsJsonEmptyInputAndEmptyOutputJsonObjectOutput' do + it 'RailsJsonEmptyInputAndEmptyOutputJsonObjectOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1204,7 +1204,7 @@ module RailsJson describe 'stubs' do # Ensures that clients can correctly parse datetime timestamps with fractional seconds - it 'stubs RailsJsonDateTimeWithFractionalSeconds' do + it 'RailsJsonDateTimeWithFractionalSeconds' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1272,7 +1272,7 @@ module RailsJson # server implementations are expected to respond with a # JSON object regardless of if the output parameters are # empty. - it 'stubs RailsJsonGreetingWithErrors' do + it 'RailsJsonGreetingWithErrors' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1290,7 +1290,7 @@ module RailsJson # This test is similar to RailsJsonGreetingWithErrors, but it # ensures that clients can gracefully deal with a server # omitting a response payload. - it 'stubs RailsJsonGreetingWithErrorsNoPayload' do + it 'RailsJsonGreetingWithErrorsNoPayload' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1525,7 +1525,7 @@ module RailsJson describe 'stubs' do # - it 'stubs RailsJsonEnumPayloadResponse' do + it 'RailsJsonEnumPayloadResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1622,7 +1622,7 @@ module RailsJson describe 'stubs' do # Serializes a blob in the HTTP payload - it 'stubs RailsJsonHttpPayloadTraitsWithBlob' do + it 'RailsJsonHttpPayloadTraitsWithBlob' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1640,7 +1640,7 @@ module RailsJson end # Serializes an empty blob in the HTTP payload - it 'stubs RailsJsonHttpPayloadTraitsWithNoBlobBody' do + it 'RailsJsonHttpPayloadTraitsWithNoBlobBody' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1707,7 +1707,7 @@ module RailsJson describe 'stubs' do # Serializes a blob in the HTTP payload with a content-type - it 'stubs RailsJsonHttpPayloadTraitsWithMediaTypeWithBlob' do + it 'RailsJsonHttpPayloadTraitsWithMediaTypeWithBlob' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1785,7 +1785,7 @@ module RailsJson describe 'stubs' do # Serializes a structure in the payload - it 'stubs RailsJsonHttpPayloadWithStructure' do + it 'RailsJsonHttpPayloadWithStructure' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1889,7 +1889,7 @@ module RailsJson describe 'stubs' do # Serializes a union in the payload. - it 'stubs RailsJsonHttpPayloadWithUnion' do + it 'RailsJsonHttpPayloadWithUnion' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1909,7 +1909,7 @@ module RailsJson end # No payload is sent if the union has no value. - it 'stubs RailsJsonHttpPayloadWithUnsetUnion' do + it 'RailsJsonHttpPayloadWithUnsetUnion' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1995,7 +1995,7 @@ module RailsJson describe 'stubs' do # Adds headers by prefix - it 'stubs RailsJsonHttpPrefixHeadersArePresent' do + it 'RailsJsonHttpPrefixHeadersArePresent' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2048,7 +2048,7 @@ module RailsJson describe 'stubs' do # (de)serializes all response headers - it 'stubs RailsJsonHttpPrefixHeadersResponse' do + it 'RailsJsonHttpPrefixHeadersResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2305,7 +2305,7 @@ module RailsJson # empty JSON object is serialized in the response. However, # clients should be able to handle an empty JSON object or an # empty payload without failing to deserialize a response. - it 'stubs RailsJsonHttpResponseCode' do + it 'RailsJsonHttpResponseCode' do proc = proc do |context| expect(context.response.status).to eq(201) end @@ -2323,7 +2323,7 @@ module RailsJson # This test ensures that clients gracefully handle cases where # the service responds with no payload rather than an empty JSON # object. - it 'stubs RailsJsonHttpResponseCodeWithNoPayload' do + it 'RailsJsonHttpResponseCodeWithNoPayload' do proc = proc do |context| expect(context.response.status).to eq(201) end @@ -2384,7 +2384,7 @@ module RailsJson describe 'stubs' do # - it 'stubs RailsJsonStringPayloadResponse' do + it 'RailsJsonStringPayloadResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2445,7 +2445,7 @@ module RailsJson # of an operation. As of January 2021, server implementations # are expected to respond with a JSON object regardless of # if the output parameters are empty. - it 'stubs RailsJsonIgnoreQueryParamsInResponse' do + it 'RailsJsonIgnoreQueryParamsInResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2459,7 +2459,7 @@ module RailsJson # This test is similar to RailsJsonIgnoreQueryParamsInResponse, # but it ensures that clients gracefully handle responses from # the server that do not serialize an empty JSON object. - it 'stubs RailsJsonIgnoreQueryParamsInResponseNoPayload' do + it 'RailsJsonIgnoreQueryParamsInResponseNoPayload' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2884,7 +2884,7 @@ module RailsJson describe 'stubs' do # Tests responses with string header bindings - it 'stubs RailsJsonInputAndOutputWithStringHeaders' do + it 'RailsJsonInputAndOutputWithStringHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2920,7 +2920,7 @@ module RailsJson end # Tests responses with string list header bindings that require quoting - it 'stubs RailsJsonInputAndOutputWithQuotedStringHeaders' do + it 'RailsJsonInputAndOutputWithQuotedStringHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2944,7 +2944,7 @@ module RailsJson end # Tests responses with numeric header bindings - it 'stubs RailsJsonInputAndOutputWithNumericHeaders' do + it 'RailsJsonInputAndOutputWithNumericHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2980,7 +2980,7 @@ module RailsJson end # Tests responses with boolean header bindings - it 'stubs RailsJsonInputAndOutputWithBooleanHeaders' do + it 'RailsJsonInputAndOutputWithBooleanHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3008,7 +3008,7 @@ module RailsJson end # Tests responses with timestamp header bindings - it 'stubs RailsJsonInputAndOutputWithTimestampHeaders' do + it 'RailsJsonInputAndOutputWithTimestampHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3030,7 +3030,7 @@ module RailsJson end # Tests responses with enum header bindings - it 'stubs RailsJsonInputAndOutputWithEnumHeaders' do + it 'RailsJsonInputAndOutputWithEnumHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3056,7 +3056,7 @@ module RailsJson end # Tests responses with intEnum header bindings - it 'stubs RailsJsonInputAndOutputWithIntEnumHeaders' do + it 'RailsJsonInputAndOutputWithIntEnumHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3082,7 +3082,7 @@ module RailsJson end # Supports handling NaN float header values. - it 'stubs RailsJsonSupportsNaNFloatHeaderOutputs' do + it 'RailsJsonSupportsNaNFloatHeaderOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3100,7 +3100,7 @@ module RailsJson end # Supports handling Infinity float header values. - it 'stubs RailsJsonSupportsInfinityFloatHeaderOutputs' do + it 'RailsJsonSupportsInfinityFloatHeaderOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3118,7 +3118,7 @@ module RailsJson end # Supports handling -Infinity float header values. - it 'stubs RailsJsonSupportsNegativeInfinityFloatHeaderOutputs' do + it 'RailsJsonSupportsNegativeInfinityFloatHeaderOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3187,7 +3187,7 @@ module RailsJson describe 'stubs' do # Blobs are base64 encoded - it 'stubs RailsJsonBlobs' do + it 'RailsJsonBlobs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3310,7 +3310,7 @@ module RailsJson describe 'stubs' do # Serializes simple scalar properties - it 'stubs RailsJsonEnums' do + it 'RailsJsonEnums' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3465,7 +3465,7 @@ module RailsJson describe 'stubs' do # Serializes intEnums as integers - it 'stubs RailsJsonIntEnums' do + it 'RailsJsonIntEnums' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3789,7 +3789,7 @@ module RailsJson describe 'stubs' do # Serializes JSON lists - it 'stubs RailsJsonLists' do + it 'RailsJsonLists' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -3899,7 +3899,7 @@ module RailsJson end # Serializes empty JSON lists - it 'stubs RailsJsonListsEmpty' do + it 'RailsJsonListsEmpty' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4140,7 +4140,7 @@ module RailsJson describe 'stubs' do # Deserializes JSON maps - it 'stubs RailsJsonMaps' do + it 'RailsJsonMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4170,7 +4170,7 @@ module RailsJson end # Ensure that 0 and false are sent over the wire in all maps and lists - it 'stubs RailsJsonDeserializesZeroValuesInMaps' do + it 'RailsJsonDeserializesZeroValuesInMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4196,7 +4196,7 @@ module RailsJson end # A response that contains a dense map of sets. - it 'stubs RailsJsonDeserializesDenseSetMap' do + it 'RailsJsonDeserializesDenseSetMap' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4229,7 +4229,7 @@ module RailsJson # Clients SHOULD tolerate seeing a null value in a dense map, and they SHOULD # drop the null key-value pair. - it 'stubs RailsJsonDeserializesDenseSetMapAndSkipsNull' do + it 'RailsJsonDeserializesDenseSetMapAndSkipsNull' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4522,7 +4522,7 @@ module RailsJson describe 'stubs' do # Tests how normal timestamps are serialized - it 'stubs RailsJsonTimestamps' do + it 'RailsJsonTimestamps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4538,7 +4538,7 @@ module RailsJson end # Ensures that the timestampFormat of date-time works like normal timestamps - it 'stubs RailsJsonTimestampsWithDateTimeFormat' do + it 'RailsJsonTimestampsWithDateTimeFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4554,7 +4554,7 @@ module RailsJson end # Ensures that the timestampFormat of date-time on the target shape works like normal timestamps - it 'stubs RailsJsonTimestampsWithDateTimeOnTargetFormat' do + it 'RailsJsonTimestampsWithDateTimeOnTargetFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4570,7 +4570,7 @@ module RailsJson end # Ensures that the timestampFormat of epoch-seconds works - it 'stubs RailsJsonTimestampsWithEpochSecondsFormat' do + it 'RailsJsonTimestampsWithEpochSecondsFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4586,7 +4586,7 @@ module RailsJson end # Ensures that the timestampFormat of epoch-seconds on the target shape works - it 'stubs RailsJsonTimestampsWithEpochSecondsOnTargetFormat' do + it 'RailsJsonTimestampsWithEpochSecondsOnTargetFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4602,7 +4602,7 @@ module RailsJson end # Ensures that the timestampFormat of http-date works - it 'stubs RailsJsonTimestampsWithHttpDateFormat' do + it 'RailsJsonTimestampsWithHttpDateFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -4618,7 +4618,7 @@ module RailsJson end # Ensures that the timestampFormat of http-date on the target shape works - it 'stubs RailsJsonTimestampsWithHttpDateOnTargetFormat' do + it 'RailsJsonTimestampsWithHttpDateOnTargetFormat' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5089,7 +5089,7 @@ module RailsJson describe 'stubs' do # Deserializes a string union value - it 'stubs RailsJsonDeserializeStringUnionValue' do + it 'RailsJsonDeserializeStringUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5109,7 +5109,7 @@ module RailsJson end # Deserializes a boolean union value - it 'stubs RailsJsonDeserializeBooleanUnionValue' do + it 'RailsJsonDeserializeBooleanUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5129,7 +5129,7 @@ module RailsJson end # Deserializes a number union value - it 'stubs RailsJsonDeserializeNumberUnionValue' do + it 'RailsJsonDeserializeNumberUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5149,7 +5149,7 @@ module RailsJson end # Deserializes a blob union value - it 'stubs RailsJsonDeserializeBlobUnionValue' do + it 'RailsJsonDeserializeBlobUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5169,7 +5169,7 @@ module RailsJson end # Deserializes a timestamp union value - it 'stubs RailsJsonDeserializeTimestampUnionValue' do + it 'RailsJsonDeserializeTimestampUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5189,7 +5189,7 @@ module RailsJson end # Deserializes an enum union value - it 'stubs RailsJsonDeserializeEnumUnionValue' do + it 'RailsJsonDeserializeEnumUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5209,7 +5209,7 @@ module RailsJson end # Deserializes a list union value - it 'stubs RailsJsonDeserializeListUnionValue' do + it 'RailsJsonDeserializeListUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5235,7 +5235,7 @@ module RailsJson end # Deserializes a map union value - it 'stubs RailsJsonDeserializeMapUnionValue' do + it 'RailsJsonDeserializeMapUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5261,7 +5261,7 @@ module RailsJson end # Deserializes a structure union value - it 'stubs RailsJsonDeserializeStructureUnionValue' do + it 'RailsJsonDeserializeStructureUnionValue' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5330,7 +5330,7 @@ module RailsJson describe 'stubs' do # Headers that target strings with a mediaType are base64 encoded - it 'stubs RailsJsonMediaTypeHeaderOutputBase64' do + it 'RailsJsonMediaTypeHeaderOutputBase64' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5393,7 +5393,7 @@ module RailsJson # When an operation does not define output, the service will respond # with an empty payload, and may optionally include the content-type # header. - it 'stubs RailsJsonNoInputAndNoOutput' do + it 'RailsJsonNoInputAndNoOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5465,7 +5465,7 @@ module RailsJson # Operations that define output and do not bind anything to # the payload return a JSON object in the response. - it 'stubs RailsJsonNoInputAndOutputWithJson' do + it 'RailsJsonNoInputAndOutputWithJson' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5479,7 +5479,7 @@ module RailsJson # This test is similar to RailsJsonNoInputAndOutputWithJson, but # it ensures that clients can gracefully handle responses that # omit a JSON payload. - it 'stubs RailsJsonNoInputAndOutputNoPayload' do + it 'RailsJsonNoInputAndOutputNoPayload' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -5932,7 +5932,7 @@ module RailsJson describe 'stubs' do # Client populates default values when missing in response. - it 'stubs RailsJsonClientPopulatesDefaultsValuesWhenMissingInResponse' do + it 'RailsJsonClientPopulatesDefaultsValuesWhenMissingInResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6008,7 +6008,7 @@ module RailsJson end # Client ignores default values if member values are present in the response. - it 'stubs RailsJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse' do + it 'RailsJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6277,7 +6277,7 @@ module RailsJson describe 'stubs' do # Client populates nested default values when missing in response body. - it 'stubs RailsJsonClientPopulatesNestedDefaultsWhenMissingInResponseBody' do + it 'RailsJsonClientPopulatesNestedDefaultsWhenMissingInResponseBody' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6430,7 +6430,7 @@ module RailsJson describe 'stubs' do # Unit types in unions are serialized like normal structures in responses. - it 'stubs RailsJsonOutputUnionWithUnitMember' do + it 'RailsJsonOutputUnionWithUnitMember' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6595,7 +6595,7 @@ module RailsJson describe 'stubs' do # Tests that jsonName works with union members. - it 'stubs RailsJsonPostUnionWithJsonNameResponse1' do + it 'RailsJsonPostUnionWithJsonNameResponse1' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6615,7 +6615,7 @@ module RailsJson end # Tests that jsonName works with union members. - it 'stubs RailsJsonPostUnionWithJsonNameResponse2' do + it 'RailsJsonPostUnionWithJsonNameResponse2' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6635,7 +6635,7 @@ module RailsJson end # Tests that jsonName works with union members. - it 'stubs RailsJsonPostUnionWithJsonNameResponse3' do + it 'RailsJsonPostUnionWithJsonNameResponse3' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -6906,7 +6906,7 @@ module RailsJson describe 'stubs' do # Serializes recursive structures - it 'stubs RailsJsonRecursiveShapes' do + it 'RailsJsonRecursiveShapes' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7178,7 +7178,7 @@ module RailsJson describe 'stubs' do # Serializes simple scalar properties - it 'stubs RailsJsonSimpleScalarProperties' do + it 'RailsJsonSimpleScalarProperties' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7212,7 +7212,7 @@ module RailsJson end # Rails Json should not deserialize null structure values - it 'stubs RailsJsonDoesntDeserializeNullStructureValues' do + it 'RailsJsonDoesntDeserializeNullStructureValues' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7224,7 +7224,7 @@ module RailsJson end # Supports handling NaN float values. - it 'stubs RailsJsonSupportsNaNFloatInputs' do + it 'RailsJsonSupportsNaNFloatInputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7242,7 +7242,7 @@ module RailsJson end # Supports handling Infinity float values. - it 'stubs RailsJsonSupportsInfinityFloatInputs' do + it 'RailsJsonSupportsInfinityFloatInputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7260,7 +7260,7 @@ module RailsJson end # Supports handling -Infinity float values. - it 'stubs RailsJsonSupportsNegativeInfinityFloatInputs' do + it 'RailsJsonSupportsNegativeInfinityFloatInputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7341,7 +7341,7 @@ module RailsJson describe 'stubs' do # Serializes null values in sparse lists - it 'stubs RailsJsonSparseListsSerializeNull' do + it 'RailsJsonSparseListsSerializeNull' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7694,7 +7694,7 @@ module RailsJson describe 'stubs' do # Deserializes JSON maps - it 'stubs RailsJsonSparseJsonMaps' do + it 'RailsJsonSparseJsonMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7724,7 +7724,7 @@ module RailsJson end # Deserializes null JSON map values - it 'stubs RailsJsonDeserializesSparseNullMapValues' do + it 'RailsJsonDeserializesSparseNullMapValues' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7762,7 +7762,7 @@ module RailsJson end # Ensure that 0 and false are sent over the wire in all maps and lists - it 'stubs RailsJsonDeserializesZeroValuesInSparseMaps' do + it 'RailsJsonDeserializesZeroValuesInSparseMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7788,7 +7788,7 @@ module RailsJson end # A response that contains a sparse map of sets - it 'stubs RailsJsonDeserializesSparseSetMap' do + it 'RailsJsonDeserializesSparseSetMap' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7820,7 +7820,7 @@ module RailsJson end # A response that contains a sparse map of sets. - it 'stubs RailsJsonDeserializesSparseSetMapAndRetainsNull' do + it 'RailsJsonDeserializesSparseSetMapAndRetainsNull' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7941,7 +7941,7 @@ module RailsJson describe 'stubs' do # Serializes a blob in the HTTP payload - it 'stubs RailsJsonStreamingTraitsWithBlob', rbs_test: :skip do + it 'RailsJsonStreamingTraitsWithBlob', rbs_test: :skip do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -7962,7 +7962,7 @@ module RailsJson end # Serializes an empty blob in the HTTP payload - it 'stubs RailsJsonStreamingTraitsWithNoBlobBody', rbs_test: :skip do + it 'RailsJsonStreamingTraitsWithNoBlobBody', rbs_test: :skip do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -8076,7 +8076,7 @@ module RailsJson describe 'stubs' do # Serializes a blob in the HTTP payload with a content-type - it 'stubs RailsJsonStreamingTraitsWithMediaTypeWithBlob', rbs_test: :skip do + it 'RailsJsonStreamingTraitsWithMediaTypeWithBlob', rbs_test: :skip do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -8343,7 +8343,7 @@ module RailsJson describe 'stubs' do # Tests how timestamp response headers are serialized - it 'stubs RailsJsonTimestampFormatHeaders' do + it 'RailsJsonTimestampFormatHeaders' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -8418,7 +8418,7 @@ module RailsJson # When an operation defines Unit output, the service will respond # with an empty payload, and may optionally include the content-type # header. - it 'stubs RailsJsonUnitInputAndOutputNoOutput' do + it 'RailsJsonUnitInputAndOutputNoOutput' do proc = proc do |context| expect(context.response.status).to eq(200) end diff --git a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/auth.rb b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/auth.rb index 29d14dd29..4370af115 100644 --- a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/auth.rb +++ b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/auth.rb @@ -9,7 +9,13 @@ module Rpcv2Cbor module Auth - Params = Struct.new(:operation_name, keyword_init: true) + class Params + def initialize(operation_name: nil) + @operation_name = operation_name + end + + attr_accessor :operation_name + end SCHEMES = [ Hearth::AuthSchemes::Anonymous.new diff --git a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/config.rb b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/config.rb index 74d498c6f..1720178b6 100644 --- a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/config.rb +++ b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/config.rb @@ -82,24 +82,27 @@ module Rpcv2Cbor # @return [Hearth::Stubs] # @!attribute validate_input # @return [Boolean] - Config = ::Struct.new( - :auth_resolver, - :auth_schemes, - :disable_host_prefix, - :endpoint, - :endpoint_resolver, - :http_client, - :interceptors, - :logger, - :plugins, - :retry_strategy, - :stub_responses, - :stubs, - :validate_input, - keyword_init: true - ) do + class Config include Hearth::Configuration + MEMBERS = %i[ + auth_resolver + auth_schemes + disable_host_prefix + endpoint + endpoint_resolver + http_client + interceptors + logger + plugins + retry_strategy + stub_responses + stubs + validate_input + ].freeze + + attr_accessor(*MEMBERS) + # Validates the configuration. def validate! Hearth::Validator.validate_responds_to!(auth_resolver, :resolve, context: 'config[:auth_resolver]') diff --git a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/endpoint.rb b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/endpoint.rb index e1dc58d03..1230c1f21 100644 --- a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/endpoint.rb +++ b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/endpoint.rb @@ -9,11 +9,12 @@ module Rpcv2Cbor module Endpoint - Params = ::Struct.new( - :endpoint, - keyword_init: true - ) do - include Hearth::Structure + class Params + def initialize(endpoint: nil) + @endpoint = endpoint + end + + attr_accessor :endpoint end class Resolver diff --git a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/plugins/global_config.rb b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/plugins/global_config.rb index ade9ac355..fece29c29 100644 --- a/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/plugins/global_config.rb +++ b/codegen/projections/rpcv2_cbor/lib/rpcv2_cbor/plugins/global_config.rb @@ -17,7 +17,7 @@ class GlobalConfig def call(config) options = config.options ::Hearth.config.each do |key, value| - config[key] = value unless options.key?(key) + config.send("#{key}=", value) unless options.key?(key) end end diff --git a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/auth.rbs b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/auth.rbs index 134c58757..7de734db6 100644 --- a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/auth.rbs +++ b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/auth.rbs @@ -9,7 +9,8 @@ module Rpcv2Cbor module Auth - class Params < ::Struct[untyped] + class Params + def initialize: (?operation_name: ::Symbol?) -> void attr_accessor operation_name (): ::Symbol end diff --git a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/config.rbs b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/config.rbs index ab6dcc1e3..9dfd2854c 100644 --- a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/config.rbs +++ b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/config.rbs @@ -1,20 +1,19 @@ module Rpcv2Cbor - class Config < ::Struct[untyped] + class Config include Hearth::Configuration[instance] - - attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params] - attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base] - attr_accessor disable_host_prefix (): bool - attr_accessor endpoint (): String - attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params] - attr_accessor http_client (): Hearth::HTTP::Client - attr_accessor interceptors (): Hearth::InterceptorList[Config] - attr_accessor logger (): Logger - attr_accessor plugins (): Hearth::PluginList[Config] - attr_accessor retry_strategy (): Hearth::_RetryStrategy - attr_accessor stub_responses (): bool - attr_accessor stubs (): Hearth::Stubs - attr_accessor validate_input (): bool + attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params]? + attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base]? + attr_accessor disable_host_prefix (): bool? + attr_accessor endpoint (): String? + attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params]? + attr_accessor http_client (): Hearth::HTTP::Client? + attr_accessor interceptors (): Hearth::InterceptorList[Config]? + attr_accessor logger (): Logger? + attr_accessor plugins (): Hearth::PluginList[Config]? + attr_accessor retry_strategy (): Hearth::_RetryStrategy? + attr_accessor stub_responses (): bool? + attr_accessor stubs (): Hearth::Stubs? + attr_accessor validate_input (): bool? def validate!: () -> void end diff --git a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/endpoint.rbs b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/endpoint.rbs index 84005eb83..92e364f37 100644 --- a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/endpoint.rbs +++ b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/endpoint.rbs @@ -9,8 +9,9 @@ module Rpcv2Cbor module Endpoint - class Params < ::Struct[untyped] - attr_accessor endpoint: ::String + class Params + def initialize: (?endpoint: ::String?) -> void + attr_accessor endpoint (): ::String? end class Resolver diff --git a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/types.rbs b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/types.rbs index 690288180..e0a72cbf3 100644 --- a/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/types.rbs +++ b/codegen/projections/rpcv2_cbor/sig/rpcv2_cbor/types.rbs @@ -319,14 +319,14 @@ module Rpcv2Cbor class ValidationException include Hearth::Structure - attr_accessor message (): ::String + attr_accessor message (): ::String? attr_accessor field_list (): ::Array[Types::ValidationExceptionField]? end class ValidationExceptionField include Hearth::Structure - attr_accessor path (): ::String - attr_accessor message (): ::String + attr_accessor path (): ::String? + attr_accessor message (): ::String? end end diff --git a/codegen/projections/rpcv2_cbor/spec/protocol_spec.rb b/codegen/projections/rpcv2_cbor/spec/protocol_spec.rb index b1accac27..3d9666385 100644 --- a/codegen/projections/rpcv2_cbor/spec/protocol_spec.rb +++ b/codegen/projections/rpcv2_cbor/spec/protocol_spec.rb @@ -80,7 +80,7 @@ module Rpcv2Cbor describe 'stubs' do # When output structure is empty we write CBOR equivalent of {} - it 'stubs empty_output' do + it 'empty_output' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -92,7 +92,7 @@ module Rpcv2Cbor end # When output structure is empty the client should accept an empty body - it 'stubs empty_output_no_body' do + it 'empty_output_no_body' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -196,7 +196,7 @@ module Rpcv2Cbor describe 'stubs' do # Ensures that clients can correctly parse float16 +Inf. - it 'stubs RpcV2CborFloat16Inf' do + it 'RpcV2CborFloat16Inf' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -212,7 +212,7 @@ module Rpcv2Cbor end # Ensures that clients can correctly parse float16 -Inf. - it 'stubs RpcV2CborFloat16NegInf' do + it 'RpcV2CborFloat16NegInf' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -228,7 +228,7 @@ module Rpcv2Cbor end # Ensures that clients can correctly parse float16 NaN with high LSB. - it 'stubs RpcV2CborFloat16LSBNaN' do + it 'RpcV2CborFloat16LSBNaN' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -244,7 +244,7 @@ module Rpcv2Cbor end # Ensures that clients can correctly parse float16 NaN with high MSB. - it 'stubs RpcV2CborFloat16MSBNaN' do + it 'RpcV2CborFloat16MSBNaN' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -260,7 +260,7 @@ module Rpcv2Cbor end # Ensures that clients can correctly parse a subnormal float16. - it 'stubs RpcV2CborFloat16Subnormal' do + it 'RpcV2CborFloat16Subnormal' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -304,7 +304,7 @@ module Rpcv2Cbor describe 'stubs' do # Ensures that clients can correctly parse timestamps with fractional seconds - it 'stubs RpcV2CborDateTimeWithFractionalSeconds' do + it 'RpcV2CborDateTimeWithFractionalSeconds' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -511,7 +511,7 @@ module Rpcv2Cbor describe 'stubs' do # A `Content-Type` header should not be set if the response body is empty. - it 'stubs no_output' do + it 'no_output' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -523,7 +523,7 @@ module Rpcv2Cbor end # Clients should accept a CBOR empty struct if there is no output. - it 'stubs NoOutputClientAllowsEmptyCbor' do + it 'NoOutputClientAllowsEmptyCbor' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -536,7 +536,7 @@ module Rpcv2Cbor # Clients should accept an empty body if there is no output and # should not raise an error if the `Content-Type` header is set. - it 'stubs NoOutputClientAllowsEmptyBody' do + it 'NoOutputClientAllowsEmptyBody' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -760,7 +760,7 @@ module Rpcv2Cbor describe 'stubs' do # Client populates default values when missing in response. - it 'stubs RpcV2CborClientPopulatesDefaultsValuesWhenMissingInResponse' do + it 'RpcV2CborClientPopulatesDefaultsValuesWhenMissingInResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -828,7 +828,7 @@ module Rpcv2Cbor end # Client ignores default values if member values are present in the response. - it 'stubs RpcV2CborClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse' do + it 'RpcV2CborClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -941,7 +941,7 @@ module Rpcv2Cbor describe 'stubs' do # When output is empty we write CBOR equivalent of {} - it 'stubs optional_output' do + it 'optional_output' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1051,7 +1051,7 @@ module Rpcv2Cbor describe 'stubs' do # Serializes recursive structures - it 'stubs RpcV2CborRecursiveShapes' do + it 'RpcV2CborRecursiveShapes' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1089,7 +1089,7 @@ module Rpcv2Cbor end # Deserializes recursive structures encoded using a map with definite length - it 'stubs RpcV2CborRecursiveShapesUsingDefiniteLength' do + it 'RpcV2CborRecursiveShapesUsingDefiniteLength' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1307,7 +1307,7 @@ module Rpcv2Cbor describe 'stubs' do # Deserializes maps - it 'stubs RpcV2CborMaps' do + it 'RpcV2CborMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1337,7 +1337,7 @@ module Rpcv2Cbor end # Ensure that 0 and false are sent over the wire in all maps and lists - it 'stubs RpcV2CborDeserializesZeroValuesInMaps' do + it 'RpcV2CborDeserializesZeroValuesInMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1363,7 +1363,7 @@ module Rpcv2Cbor end # A response that contains a dense map of sets - it 'stubs RpcV2CborDeserializesDenseSetMap' do + it 'RpcV2CborDeserializesDenseSetMap' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1396,7 +1396,7 @@ module Rpcv2Cbor # Clients SHOULD tolerate seeing a null value in a dense map, and they SHOULD # drop the null key-value pair. - it 'stubs RpcV2CborDeserializesDenseSetMapAndSkipsNull' do + it 'RpcV2CborDeserializesDenseSetMapAndSkipsNull' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1675,7 +1675,7 @@ module Rpcv2Cbor describe 'stubs' do # Serializes RpcV2 Cbor lists - it 'stubs RpcV2CborLists' do + it 'RpcV2CborLists' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1793,7 +1793,7 @@ module Rpcv2Cbor end # Serializes empty RpcV2 Cbor lists - it 'stubs RpcV2CborListsEmpty' do + it 'RpcV2CborListsEmpty' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1813,7 +1813,7 @@ module Rpcv2Cbor end # Can deserialize indefinite length text strings inside an indefinite length list - it 'stubs RpcV2CborIndefiniteStringInsideIndefiniteListCanDeserialize' do + it 'RpcV2CborIndefiniteStringInsideIndefiniteListCanDeserialize' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -1837,7 +1837,7 @@ module Rpcv2Cbor end # Can deserialize indefinite length text strings inside a definite length list - it 'stubs RpcV2CborIndefiniteStringInsideDefiniteListCanDeserialize' do + it 'RpcV2CborIndefiniteStringInsideDefiniteListCanDeserialize' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2122,7 +2122,7 @@ module Rpcv2Cbor describe 'stubs' do # Deserializes sparse maps - it 'stubs RpcV2CborSparseJsonMaps' do + it 'RpcV2CborSparseJsonMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2152,7 +2152,7 @@ module Rpcv2Cbor end # Deserializes null map values - it 'stubs RpcV2CborDeserializesNullMapValues' do + it 'RpcV2CborDeserializesNullMapValues' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2190,7 +2190,7 @@ module Rpcv2Cbor end # A response that contains a sparse map of sets - it 'stubs RpcV2CborDeserializesSparseSetMap' do + it 'RpcV2CborDeserializesSparseSetMap' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2222,7 +2222,7 @@ module Rpcv2Cbor end # A response that contains a sparse map of sets with a null - it 'stubs RpcV2CborDeserializesSparseSetMapAndRetainsNull' do + it 'RpcV2CborDeserializesSparseSetMapAndRetainsNull' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2256,7 +2256,7 @@ module Rpcv2Cbor end # Ensure that 0 and false are sent over the wire in all maps and lists - it 'stubs RpcV2CborDeserializesZeroValuesInSparseMaps' do + it 'RpcV2CborDeserializesZeroValuesInSparseMaps' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2555,7 +2555,7 @@ module Rpcv2Cbor describe 'stubs' do # Serializes simple scalar properties - it 'stubs RpcV2CborSimpleScalarProperties' do + it 'RpcV2CborSimpleScalarProperties' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2587,7 +2587,7 @@ module Rpcv2Cbor end # Deserializes simple scalar properties encoded using a map with definite length - it 'stubs RpcV2CborSimpleScalarPropertiesUsingDefiniteLength' do + it 'RpcV2CborSimpleScalarPropertiesUsingDefiniteLength' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2619,7 +2619,7 @@ module Rpcv2Cbor end # RpcV2 Cbor should not deserialize null structure values - it 'stubs RpcV2CborClientDoesntDeserializeNullStructureValues' do + it 'RpcV2CborClientDoesntDeserializeNullStructureValues' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2631,7 +2631,7 @@ module Rpcv2Cbor end # Supports handling NaN float values. - it 'stubs RpcV2CborSupportsNaNFloatOutputs' do + it 'RpcV2CborSupportsNaNFloatOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2649,7 +2649,7 @@ module Rpcv2Cbor end # Supports handling Infinity float values. - it 'stubs RpcV2CborSupportsInfinityFloatOutputs' do + it 'RpcV2CborSupportsInfinityFloatOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2667,7 +2667,7 @@ module Rpcv2Cbor end # Supports handling Negative Infinity float values. - it 'stubs RpcV2CborSupportsNegativeInfinityFloatOutputs' do + it 'RpcV2CborSupportsNegativeInfinityFloatOutputs' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2685,7 +2685,7 @@ module Rpcv2Cbor end # Supports upcasting from a smaller byte representation of the same data type. - it 'stubs RpcV2CborSupportsUpcastingDataOnDeserialize' do + it 'RpcV2CborSupportsUpcastingDataOnDeserialize' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2711,7 +2711,7 @@ module Rpcv2Cbor # The client should skip over additional fields that are not part of the structure. This allows a # client generated against an older Smithy model to be able to communicate with a server that is # generated against a newer Smithy model. - it 'stubs RpcV2CborExtraFieldsInTheBodyShouldBeSkippedByClients' do + it 'RpcV2CborExtraFieldsInTheBodyShouldBeSkippedByClients' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2835,7 +2835,7 @@ module Rpcv2Cbor describe 'stubs' do # Deserializes null values in maps - it 'stubs RpcV2CborSparseMapsDeserializeNullValues' do + it 'RpcV2CborSparseMapsDeserializeNullValues' do proc = proc do |context| expect(context.response.status).to eq(200) end @@ -2855,7 +2855,7 @@ module Rpcv2Cbor end # Deserializes null values in lists - it 'stubs RpcV2CborSparseListsDeserializeNull' do + it 'RpcV2CborSparseListsDeserializeNull' do proc = proc do |context| expect(context.response.status).to eq(200) end diff --git a/codegen/projections/white_label/lib/white_label/auth.rb b/codegen/projections/white_label/lib/white_label/auth.rb index cf77b3602..df8f7d767 100644 --- a/codegen/projections/white_label/lib/white_label/auth.rb +++ b/codegen/projections/white_label/lib/white_label/auth.rb @@ -11,7 +11,14 @@ module WhiteLabel module Auth - Params = Struct.new(:custom_param, :operation_name, keyword_init: true) + class Params + def initialize(custom_param: nil, operation_name: nil) + @custom_param = custom_param + @operation_name = operation_name + end + + attr_accessor :custom_param, :operation_name + end SCHEMES = [ Hearth::AuthSchemes::HTTPApiKey.new, diff --git a/codegen/projections/white_label/lib/white_label/config.rb b/codegen/projections/white_label/lib/white_label/config.rb index 1ee875e3b..63d320f14 100644 --- a/codegen/projections/white_label/lib/white_label/config.rb +++ b/codegen/projections/white_label/lib/white_label/config.rb @@ -119,33 +119,36 @@ module WhiteLabel # @return [String] # @!attribute validate_input # @return [Boolean] - Config = ::Struct.new( - :auth_resolver, - :auth_schemes, - :disable_host_prefix, - :disable_request_compression, - :endpoint, - :endpoint_resolver, - :http2_client, - :http_api_key_provider, - :http_bearer_provider, - :http_client, - :http_custom_key_provider, - :http_login_provider, - :interceptors, - :logger, - :plugins, - :request_min_compression_size_bytes, - :retry_strategy, - :stage, - :stub_responses, - :stubs, - :test_config, - :validate_input, - keyword_init: true - ) do + class Config include Hearth::Configuration + MEMBERS = %i[ + auth_resolver + auth_schemes + disable_host_prefix + disable_request_compression + endpoint + endpoint_resolver + http2_client + http_api_key_provider + http_bearer_provider + http_client + http_custom_key_provider + http_login_provider + interceptors + logger + plugins + request_min_compression_size_bytes + retry_strategy + stage + stub_responses + stubs + test_config + validate_input + ].freeze + + attr_accessor(*MEMBERS) + # Validates the configuration. def validate! Hearth::Validator.validate_responds_to!(auth_resolver, :resolve, context: 'config[:auth_resolver]') diff --git a/codegen/projections/white_label/lib/white_label/endpoint.rb b/codegen/projections/white_label/lib/white_label/endpoint.rb index 5a0b88aa9..f68ed7d7d 100644 --- a/codegen/projections/white_label/lib/white_label/endpoint.rb +++ b/codegen/projections/white_label/lib/white_label/endpoint.rb @@ -9,14 +9,15 @@ module WhiteLabel module Endpoint - Params = ::Struct.new( - :stage, - :dataplane, - :resource_url, - :endpoint, - keyword_init: true - ) do - include Hearth::Structure + class Params + def initialize(stage: nil, dataplane: nil, resource_url: nil, endpoint: nil) + @stage = stage + @dataplane = dataplane + @resource_url = resource_url + @endpoint = endpoint + end + + attr_accessor :stage, :dataplane, :resource_url, :endpoint end class Resolver diff --git a/codegen/projections/white_label/lib/white_label/plugins/global_config.rb b/codegen/projections/white_label/lib/white_label/plugins/global_config.rb index a7ca383c8..e001e5f85 100644 --- a/codegen/projections/white_label/lib/white_label/plugins/global_config.rb +++ b/codegen/projections/white_label/lib/white_label/plugins/global_config.rb @@ -17,7 +17,7 @@ class GlobalConfig def call(config) options = config.options ::Hearth.config.each do |key, value| - config[key] = value unless options.key?(key) + config.send("#{key}=", value) unless options.key?(key) end end diff --git a/codegen/projections/white_label/lib/white_label/types.rb b/codegen/projections/white_label/lib/white_label/types.rb index fc54755c2..cf4ad2270 100644 --- a/codegen/projections/white_label/lib/white_label/types.rb +++ b/codegen/projections/white_label/lib/white_label/types.rb @@ -175,26 +175,26 @@ class Defaults attr_accessor(*MEMBERS) def to_s - "#" end @@ -348,26 +348,26 @@ class DefaultsTestOutput attr_accessor(*MEMBERS) def to_s - "#" end @@ -697,17 +697,17 @@ class KitchenSinkInput attr_accessor(*MEMBERS) def to_s - "#" + '#' end end @@ -812,17 +812,17 @@ class KitchenSinkOutput attr_accessor(*MEMBERS) def to_s - "#" + '#' end end @@ -1281,10 +1281,6 @@ class String < Union def to_h { string: super(__getobj__) } end - - def to_s - "#" - end end # This docstring should be different than KitchenSink struct member. diff --git a/codegen/projections/white_label/sig/white_label/auth.rbs b/codegen/projections/white_label/sig/white_label/auth.rbs index 6327e27f7..06da5ffe8 100644 --- a/codegen/projections/white_label/sig/white_label/auth.rbs +++ b/codegen/projections/white_label/sig/white_label/auth.rbs @@ -9,7 +9,8 @@ module WhiteLabel module Auth - class Params < ::Struct[untyped] + class Params + def initialize: (?custom_param: ::String?, ?operation_name: ::Symbol?) -> void attr_accessor custom_param (): ::String attr_accessor operation_name (): ::Symbol end diff --git a/codegen/projections/white_label/sig/white_label/client.rbs b/codegen/projections/white_label/sig/white_label/client.rbs index a98e6342f..be84b0719 100644 --- a/codegen/projections/white_label/sig/white_label/client.rbs +++ b/codegen/projections/white_label/sig/white_label/client.rbs @@ -24,7 +24,7 @@ module WhiteLabel ?http_api_key_provider: Hearth::IdentityProvider, ?http_bearer_provider: Hearth::IdentityProvider, ?http_client: Hearth::HTTP::Client, - ?http_custom_key_provider: untyped, + ?http_custom_key_provider: Hearth::IdentityProvider, ?http_login_provider: Hearth::IdentityProvider, ?interceptors: Hearth::InterceptorList[Config], ?logger: Logger, diff --git a/codegen/projections/white_label/sig/white_label/config.rbs b/codegen/projections/white_label/sig/white_label/config.rbs index 79979eee8..046e0b4be 100644 --- a/codegen/projections/white_label/sig/white_label/config.rbs +++ b/codegen/projections/white_label/sig/white_label/config.rbs @@ -1,29 +1,28 @@ module WhiteLabel - class Config < ::Struct[untyped] + class Config include Hearth::Configuration[instance] - - attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params] - attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base] - attr_accessor disable_host_prefix (): bool - attr_accessor disable_request_compression (): bool - attr_accessor endpoint (): String - attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params] - attr_accessor http2_client (): Hearth::HTTP2::Client - attr_accessor http_api_key_provider (): Hearth::IdentityProvider - attr_accessor http_bearer_provider (): Hearth::IdentityProvider - attr_accessor http_client (): Hearth::HTTP::Client - attr_accessor http_custom_key_provider (): untyped - attr_accessor http_login_provider (): Hearth::IdentityProvider - attr_accessor interceptors (): Hearth::InterceptorList[Config] - attr_accessor logger (): Logger - attr_accessor plugins (): Hearth::PluginList[Config] - attr_accessor request_min_compression_size_bytes (): Integer - attr_accessor retry_strategy (): Hearth::_RetryStrategy - attr_accessor stage (): String - attr_accessor stub_responses (): bool - attr_accessor stubs (): Hearth::Stubs - attr_accessor test_config (): untyped - attr_accessor validate_input (): bool + attr_accessor auth_resolver (): Hearth::_AuthResolver[Auth::Params]? + attr_accessor auth_schemes (): Array[Hearth::AuthSchemes::Base]? + attr_accessor disable_host_prefix (): bool? + attr_accessor disable_request_compression (): bool? + attr_accessor endpoint (): String? + attr_accessor endpoint_resolver (): Hearth::_EndpointResolver[Endpoint::Params]? + attr_accessor http2_client (): Hearth::HTTP2::Client? + attr_accessor http_api_key_provider (): Hearth::IdentityProvider? + attr_accessor http_bearer_provider (): Hearth::IdentityProvider? + attr_accessor http_client (): Hearth::HTTP::Client? + attr_accessor http_custom_key_provider (): Hearth::IdentityProvider? + attr_accessor http_login_provider (): Hearth::IdentityProvider? + attr_accessor interceptors (): Hearth::InterceptorList[Config]? + attr_accessor logger (): Logger? + attr_accessor plugins (): Hearth::PluginList[Config]? + attr_accessor request_min_compression_size_bytes (): Integer? + attr_accessor retry_strategy (): Hearth::_RetryStrategy? + attr_accessor stage (): String? + attr_accessor stub_responses (): bool? + attr_accessor stubs (): Hearth::Stubs? + attr_accessor test_config (): untyped? + attr_accessor validate_input (): bool? def validate!: () -> void end diff --git a/codegen/projections/white_label/sig/white_label/endpoint.rbs b/codegen/projections/white_label/sig/white_label/endpoint.rbs index 2fa3c8bfc..52035906a 100644 --- a/codegen/projections/white_label/sig/white_label/endpoint.rbs +++ b/codegen/projections/white_label/sig/white_label/endpoint.rbs @@ -9,11 +9,12 @@ module WhiteLabel module Endpoint - class Params < ::Struct[untyped] - attr_accessor dataplane: bool - attr_accessor resource_url: ::String - attr_accessor endpoint: ::String - attr_accessor stage: ::String + class Params + def initialize: (?dataplane: bool?, ?resource_url: ::String?, ?endpoint: ::String?, ?stage: ::String?) -> void + attr_accessor dataplane (): bool? + attr_accessor resource_url (): ::String? + attr_accessor endpoint (): ::String? + attr_accessor stage (): ::String? end class Resolver diff --git a/codegen/projections/white_label/sig/white_label/types.rbs b/codegen/projections/white_label/sig/white_label/types.rbs index ee56a61a7..b734e4748 100644 --- a/codegen/projections/white_label/sig/white_label/types.rbs +++ b/codegen/projections/white_label/sig/white_label/types.rbs @@ -37,22 +37,22 @@ module WhiteLabel attr_accessor struct (): Types::Struct? attr_accessor un_required_number (): ::Integer? attr_accessor un_required_bool (): bool? - attr_accessor number (): ::Integer - attr_accessor bool (): bool - attr_accessor hello (): ::String - attr_accessor simple_enum (): ::String - attr_accessor valued_enum (): ::String - attr_accessor int_enum (): ::Integer - attr_accessor null_document (): Hearth::document - attr_accessor string_document (): Hearth::document - attr_accessor boolean_document (): Hearth::document - attr_accessor numbers_document (): Hearth::document - attr_accessor list_document (): Hearth::document - attr_accessor map_document (): Hearth::document - attr_accessor list_of_strings (): ::Array[::String] - attr_accessor map_of_strings (): ::Hash[::String, ::String] - attr_accessor iso8601_timestamp (): ::Time - attr_accessor epoch_timestamp (): ::Time + attr_accessor number (): ::Integer? + attr_accessor bool (): bool? + attr_accessor hello (): ::String? + attr_accessor simple_enum (): ::String? + attr_accessor valued_enum (): ::String? + attr_accessor int_enum (): ::Integer? + attr_accessor null_document (): Hearth::document? + attr_accessor string_document (): Hearth::document? + attr_accessor boolean_document (): Hearth::document? + attr_accessor numbers_document (): Hearth::document? + attr_accessor list_document (): Hearth::document? + attr_accessor map_document (): Hearth::document? + attr_accessor list_of_strings (): ::Array[::String]? + attr_accessor map_of_strings (): ::Hash[::String, ::String]? + attr_accessor iso8601_timestamp (): ::Time? + attr_accessor epoch_timestamp (): ::Time? end class DefaultsTestInput @@ -66,22 +66,22 @@ module WhiteLabel attr_accessor struct (): Types::Struct? attr_accessor un_required_number (): ::Integer? attr_accessor un_required_bool (): bool? - attr_accessor number (): ::Integer - attr_accessor bool (): bool - attr_accessor hello (): ::String - attr_accessor simple_enum (): ::String - attr_accessor valued_enum (): ::String - attr_accessor int_enum (): ::Integer - attr_accessor null_document (): Hearth::document - attr_accessor string_document (): Hearth::document - attr_accessor boolean_document (): Hearth::document - attr_accessor numbers_document (): Hearth::document - attr_accessor list_document (): Hearth::document - attr_accessor map_document (): Hearth::document - attr_accessor list_of_strings (): ::Array[::String] - attr_accessor map_of_strings (): ::Hash[::String, ::String] - attr_accessor iso8601_timestamp (): ::Time - attr_accessor epoch_timestamp (): ::Time + attr_accessor number (): ::Integer? + attr_accessor bool (): bool? + attr_accessor hello (): ::String? + attr_accessor simple_enum (): ::String? + attr_accessor valued_enum (): ::String? + attr_accessor int_enum (): ::Integer? + attr_accessor null_document (): Hearth::document? + attr_accessor string_document (): Hearth::document? + attr_accessor boolean_document (): Hearth::document? + attr_accessor numbers_document (): Hearth::document? + attr_accessor list_document (): Hearth::document? + attr_accessor map_document (): Hearth::document? + attr_accessor list_of_strings (): ::Array[::String]? + attr_accessor map_of_strings (): ::Hash[::String, ::String]? + attr_accessor iso8601_timestamp (): ::Time? + attr_accessor epoch_timestamp (): ::Time? end class EndpointOperationInput @@ -94,7 +94,7 @@ module WhiteLabel class EndpointWithHostLabelOperationInput include Hearth::Structure - attr_accessor label_member (): ::String + attr_accessor label_member (): ::String? end class EndpointWithHostLabelOperationOutput @@ -277,7 +277,7 @@ module WhiteLabel class RequestCompressionStreamingInput include Hearth::Structure - attr_accessor body (): (Hearth::_ReadableIO | Hearth::_WritableIO) + attr_accessor body (): (Hearth::_ReadableIO | Hearth::_WritableIO)? end class RequestCompressionStreamingOutput @@ -286,7 +286,7 @@ module WhiteLabel class ResourceEndpointInput include Hearth::Structure - attr_accessor resource_url (): ::String + attr_accessor resource_url (): ::String? end class ResourceEndpointOutput @@ -320,17 +320,17 @@ module WhiteLabel class StreamingInput include Hearth::Structure - attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO) + attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO)? end class StreamingOutput include Hearth::Structure - attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO) + attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO)? end class StreamingWithLengthInput include Hearth::Structure - attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO) + attr_accessor stream (): (Hearth::_ReadableIO | Hearth::_WritableIO)? end class StreamingWithLengthOutput diff --git a/codegen/projections/white_label/spec/auth_spec.rb b/codegen/projections/white_label/spec/auth_spec.rb index 35f767b89..2996539e8 100644 --- a/codegen/projections/white_label/spec/auth_spec.rb +++ b/codegen/projections/white_label/spec/auth_spec.rb @@ -158,7 +158,7 @@ module Auth end describe Config do - it 'validates identity resolvers' do + it 'validates identity resolvers', rbs_test: :skip do msg = /to be in \[Hearth::IdentityProvider\], got String/ expect do Config.new(http_api_key_provider: 'foo').validate! diff --git a/codegen/projections/white_label/spec/client_spec.rb b/codegen/projections/white_label/spec/client_spec.rb index 2b27755c6..fa0316de2 100644 --- a/codegen/projections/white_label/spec/client_spec.rb +++ b/codegen/projections/white_label/spec/client_spec.rb @@ -19,7 +19,7 @@ module WhiteLabel client.kitchen_sink end - it 'validates config' do + it 'validates config', rbs_test: :skip do expect do Client.new(stub_responses: 'false') end.to raise_error(ArgumentError, /config\[:stub_responses\]/) @@ -34,7 +34,7 @@ module WhiteLabel expect(client.config.logger).to eq(logger) end - it 'validates global config values' do + it 'validates global config values', rbs_test: :skip do Hearth.config[:logger] = 'logger' expect do Client.new @@ -50,7 +50,7 @@ module WhiteLabel end context 'operation overrides' do - it 'validates config' do + it 'validates config', rbs_test: :skip do expect do client.kitchen_sink({}, endpoint: 1) end.to raise_error(ArgumentError, /config\[:endpoint\]/) diff --git a/codegen/projections/white_label/spec/compression_spec.rb b/codegen/projections/white_label/spec/compression_spec.rb index 163e27ae6..60345383b 100644 --- a/codegen/projections/white_label/spec/compression_spec.rb +++ b/codegen/projections/white_label/spec/compression_spec.rb @@ -5,7 +5,7 @@ module WhiteLabel describe Config do context 'disable_request_compression' do - it 'raises error when given an invalid input' do + it 'raises when given an invalid input', rbs_test: :skip do expect { Config.new(disable_request_compression: 'string').validate! } .to raise_error( ArgumentError, @@ -16,7 +16,7 @@ module WhiteLabel end context 'request_min_compression_size_bytes' do - it 'raises error when given invalid integer' do + it 'raises when given invalid integer' do expect { Config.new(request_min_compression_size_bytes: -1).validate! } .to raise_error( ArgumentError, diff --git a/codegen/projections/white_label/spec/config_spec.rb b/codegen/projections/white_label/spec/config_spec.rb index ea029ace1..a4a5497ec 100644 --- a/codegen/projections/white_label/spec/config_spec.rb +++ b/codegen/projections/white_label/spec/config_spec.rb @@ -31,7 +31,7 @@ module WhiteLabel expect(config.request_min_compression_size_bytes).to be_a(Integer) end - it 'validates types' do + it 'validates types', rbs_test: :skip do config = Config.new(logger: 'foo') expect { config.validate! } .to raise_error(ArgumentError, /config\[:logger\]/) @@ -39,7 +39,7 @@ module WhiteLabel it 'raises on unknown keys' do expect { Config.new(foo: 'bar') } - .to raise_error(ArgumentError, /unknown keywords: foo/) + .to raise_error(ArgumentError, /config\[:foo\]/) end end end diff --git a/codegen/projections/white_label/spec/endpoint_spec.rb b/codegen/projections/white_label/spec/endpoint_spec.rb index 584341383..cda2fddab 100644 --- a/codegen/projections/white_label/spec/endpoint_spec.rb +++ b/codegen/projections/white_label/spec/endpoint_spec.rb @@ -28,7 +28,8 @@ module Endpoint endpoint = subject.resolve(params) expect(endpoint.uri).to eq(expected[:url]) expect(endpoint.headers).to eq(expected[:headers]) - expect(endpoint.auth_schemes).to eq(expected[:auth_schemes]) + expect(endpoint.auth_schemes.map(&:scheme_id)).to eq(expected[:auth_schemes].map(&:scheme_id)) + expect(endpoint.auth_schemes.map(&:properties)).to eq(expected[:auth_schemes].map(&:properties)) end it 'produces the correct output from the client when calling endpoint_operation' do @@ -67,7 +68,8 @@ module Endpoint endpoint = subject.resolve(params) expect(endpoint.uri).to eq(expected[:url]) expect(endpoint.headers).to eq(expected[:headers]) - expect(endpoint.auth_schemes).to eq(expected[:auth_schemes]) + expect(endpoint.auth_schemes.map(&:scheme_id)).to eq(expected[:auth_schemes].map(&:scheme_id)) + expect(endpoint.auth_schemes.map(&:properties)).to eq(expected[:auth_schemes].map(&:properties)) end end @@ -98,7 +100,8 @@ module Endpoint endpoint = subject.resolve(params) expect(endpoint.uri).to eq(expected[:url]) expect(endpoint.headers).to eq(expected[:headers]) - expect(endpoint.auth_schemes).to eq(expected[:auth_schemes]) + expect(endpoint.auth_schemes.map(&:scheme_id)).to eq(expected[:auth_schemes].map(&:scheme_id)) + expect(endpoint.auth_schemes.map(&:properties)).to eq(expected[:auth_schemes].map(&:properties)) end it 'produces the correct output from the client when calling endpoint_operation' do @@ -136,7 +139,8 @@ module Endpoint endpoint = subject.resolve(params) expect(endpoint.uri).to eq(expected[:url]) expect(endpoint.headers).to eq(expected[:headers]) - expect(endpoint.auth_schemes).to eq(expected[:auth_schemes]) + expect(endpoint.auth_schemes.map(&:scheme_id)).to eq(expected[:auth_schemes].map(&:scheme_id)) + expect(endpoint.auth_schemes.map(&:properties)).to eq(expected[:auth_schemes].map(&:properties)) end it 'produces the correct output from the client when calling resource_endpoint' do @@ -176,7 +180,8 @@ module Endpoint endpoint = subject.resolve(params) expect(endpoint.uri).to eq(expected[:url]) expect(endpoint.headers).to eq(expected[:headers]) - expect(endpoint.auth_schemes).to eq(expected[:auth_schemes]) + expect(endpoint.auth_schemes.map(&:scheme_id)).to eq(expected[:auth_schemes].map(&:scheme_id)) + expect(endpoint.auth_schemes.map(&:properties)).to eq(expected[:auth_schemes].map(&:properties)) end it 'produces the correct output from the client when calling dataplane_endpoint' do diff --git a/codegen/smithy-ruby-codegen-test-utils/src/main/java/software/amazon/smithy/ruby/codegen/integrations/WhiteLabelTestIntegration.java b/codegen/smithy-ruby-codegen-test-utils/src/main/java/software/amazon/smithy/ruby/codegen/integrations/WhiteLabelTestIntegration.java index f955344ac..e159863ad 100644 --- a/codegen/smithy-ruby-codegen-test-utils/src/main/java/software/amazon/smithy/ruby/codegen/integrations/WhiteLabelTestIntegration.java +++ b/codegen/smithy-ruby-codegen-test-utils/src/main/java/software/amazon/smithy/ruby/codegen/integrations/WhiteLabelTestIntegration.java @@ -117,6 +117,7 @@ public List getAdditionalAuthSchemes(GenerationContext context) { identityType, HttpBasicAuthTrait.ID)) .documentationType(Hearth.IDENTITY_PROVIDER.toString()) + .rbsType(Hearth.IDENTITY_PROVIDER.toString()) .defaultDynamicValue(defaultConfigValue) .constraint(new TypeConstraint(Hearth.IDENTITY_PROVIDER.toString())) .build(); diff --git a/codegen/smithy-ruby-codegen-test/integration-specs/auth_spec.rb b/codegen/smithy-ruby-codegen-test/integration-specs/auth_spec.rb index 35f767b89..2996539e8 100644 --- a/codegen/smithy-ruby-codegen-test/integration-specs/auth_spec.rb +++ b/codegen/smithy-ruby-codegen-test/integration-specs/auth_spec.rb @@ -158,7 +158,7 @@ module Auth end describe Config do - it 'validates identity resolvers' do + it 'validates identity resolvers', rbs_test: :skip do msg = /to be in \[Hearth::IdentityProvider\], got String/ expect do Config.new(http_api_key_provider: 'foo').validate! diff --git a/codegen/smithy-ruby-codegen-test/integration-specs/client_spec.rb b/codegen/smithy-ruby-codegen-test/integration-specs/client_spec.rb index 2b27755c6..fa0316de2 100644 --- a/codegen/smithy-ruby-codegen-test/integration-specs/client_spec.rb +++ b/codegen/smithy-ruby-codegen-test/integration-specs/client_spec.rb @@ -19,7 +19,7 @@ module WhiteLabel client.kitchen_sink end - it 'validates config' do + it 'validates config', rbs_test: :skip do expect do Client.new(stub_responses: 'false') end.to raise_error(ArgumentError, /config\[:stub_responses\]/) @@ -34,7 +34,7 @@ module WhiteLabel expect(client.config.logger).to eq(logger) end - it 'validates global config values' do + it 'validates global config values', rbs_test: :skip do Hearth.config[:logger] = 'logger' expect do Client.new @@ -50,7 +50,7 @@ module WhiteLabel end context 'operation overrides' do - it 'validates config' do + it 'validates config', rbs_test: :skip do expect do client.kitchen_sink({}, endpoint: 1) end.to raise_error(ArgumentError, /config\[:endpoint\]/) diff --git a/codegen/smithy-ruby-codegen-test/integration-specs/compression_spec.rb b/codegen/smithy-ruby-codegen-test/integration-specs/compression_spec.rb index 163e27ae6..60345383b 100644 --- a/codegen/smithy-ruby-codegen-test/integration-specs/compression_spec.rb +++ b/codegen/smithy-ruby-codegen-test/integration-specs/compression_spec.rb @@ -5,7 +5,7 @@ module WhiteLabel describe Config do context 'disable_request_compression' do - it 'raises error when given an invalid input' do + it 'raises when given an invalid input', rbs_test: :skip do expect { Config.new(disable_request_compression: 'string').validate! } .to raise_error( ArgumentError, @@ -16,7 +16,7 @@ module WhiteLabel end context 'request_min_compression_size_bytes' do - it 'raises error when given invalid integer' do + it 'raises when given invalid integer' do expect { Config.new(request_min_compression_size_bytes: -1).validate! } .to raise_error( ArgumentError, diff --git a/codegen/smithy-ruby-codegen-test/integration-specs/config_spec.rb b/codegen/smithy-ruby-codegen-test/integration-specs/config_spec.rb index ea029ace1..a4a5497ec 100644 --- a/codegen/smithy-ruby-codegen-test/integration-specs/config_spec.rb +++ b/codegen/smithy-ruby-codegen-test/integration-specs/config_spec.rb @@ -31,7 +31,7 @@ module WhiteLabel expect(config.request_min_compression_size_bytes).to be_a(Integer) end - it 'validates types' do + it 'validates types', rbs_test: :skip do config = Config.new(logger: 'foo') expect { config.validate! } .to raise_error(ArgumentError, /config\[:logger\]/) @@ -39,7 +39,7 @@ module WhiteLabel it 'raises on unknown keys' do expect { Config.new(foo: 'bar') } - .to raise_error(ArgumentError, /unknown keywords: foo/) + .to raise_error(ArgumentError, /config\[:foo\]/) end end end diff --git a/codegen/smithy-ruby-codegen/CHANGELOG.md b/codegen/smithy-ruby-codegen/CHANGELOG.md index 5a0e4ef77..d04a7af7b 100644 --- a/codegen/smithy-ruby-codegen/CHANGELOG.md +++ b/codegen/smithy-ruby-codegen/CHANGELOG.md @@ -1,7 +1,8 @@ Unreleased Changes ------------------ -* Issue - Remove `Struct` from generated Types. +* Issue - Add `to_s` to `Structure`. +* Issue - Remove `Struct` from generated Types, Config, and other places to allow for better RBS typing as well as less reserved words. * Feature - Add support for stringArray Endpoint parameters + operationContextParams binding. * Issue - Update reserved member names for new Struct methods. * Feature - Add support for Smithy RPC v2 CBOR protocol. diff --git a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/AuthGenerator.java b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/AuthGenerator.java index c49e412f1..0a5f3e43d 100644 --- a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/AuthGenerator.java +++ b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/AuthGenerator.java @@ -98,15 +98,32 @@ public void renderRbs() { } private void renderAuthParamsClass(RubyCodeWriter writer) { - writer.write("Params = Struct.new($L, keyword_init: true)", - context.getAuthParams().stream() + writer + .openBlock("class Params") + .openBlock("def initialize($L)", context.getAuthParams().stream() + .map(p -> "%s: nil".formatted(RubyFormatter.toSnakeCase(p.getName()))) + .collect(Collectors.joining(", "))) + .call(() -> { + context.getAuthParams().forEach(p -> { + String authParam = RubyFormatter.toSnakeCase(p.getName()); + writer.write("@$L = $L", authParam, authParam); + }); + }) + .closeBlock("end") + .write("") + .write("attr_accessor $L", context.getAuthParams().stream() .map(p -> RubyFormatter.asSymbol(p.getName())) - .collect(Collectors.joining(", "))); + .collect(Collectors.joining(", "))) + .closeBlock("end"); } private void renderRbsAuthParamsClass(RubyCodeWriter writer) { writer - .openBlock("class Params < ::Struct[untyped]") + .openBlock("class Params") + .write("def initialize: ($L) -> void", + context.getAuthParams().stream() + .map(p -> "?%s: %s?".formatted(p.getName(), p.getRbsType())) + .collect(Collectors.joining(", "))) .call(() -> { context.getAuthParams().forEach(p -> { writer.write("attr_accessor $L (): $L", p.getName(), p.getRbsType()); diff --git a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/ConfigGenerator.java b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/ConfigGenerator.java index 4af31c737..85d6c9cfa 100644 --- a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/ConfigGenerator.java +++ b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/ConfigGenerator.java @@ -51,28 +51,36 @@ protected String getModule() { public void render() { write(writer -> { - String membersBlock = "nil"; + String membersBlock; if (!clientConfigList.isEmpty()) { membersBlock = clientConfigList .stream() - .map(clientConfig -> RubyFormatter.asSymbol( - RubySymbolProvider.toMemberName(clientConfig.getName()))) - .collect(Collectors.joining(",\n")); + .map(clientConfig -> RubySymbolProvider.toMemberName(clientConfig.getName())) + .collect(Collectors.joining("\n")); + } else { + membersBlock = ""; } - membersBlock += ","; writer .preamble() .includeRequires() .openBlock("module $L", settings.getModule()) .call(() -> renderConfigDocumentation(writer)) - .openBlock("Config = ::Struct.new(") - .write(membersBlock) - .write("keyword_init: true") - .closeBlock(") do") - .indent() + .openBlock("class Config") .write("include $T", Hearth.CONFIGURATION) .write("") + .call(() -> { + if (membersBlock.isBlank()) { + writer.write("MEMBERS = [].freeze"); + } else { + writer.openBlock("MEMBERS = %i["); + writer.write(membersBlock); + writer.closeBlock("].freeze"); + } + }) + .write("") + .write("attr_accessor(*MEMBERS)") + .write("") .call(() -> renderValidateMethod(writer)) .write("\nprivate\n") .call(() -> renderDefaultsMethod(writer)) @@ -89,14 +97,13 @@ public void renderRbs() { writeRbs(writer -> { writer .openBlock("module $L", settings.getModule()) - .openBlock("class Config < ::Struct[untyped]") + .openBlock("class Config") .write("include $T[instance]", Hearth.CONFIGURATION) - .write("") .call(() -> { clientConfigList.forEach((clientConfig) -> { String member = RubySymbolProvider.toMemberName(clientConfig.getName()); String rbsType = clientConfig.getRbsType(); - writer.write("attr_accessor $L (): $L", member, rbsType); + writer.write("attr_accessor $L (): $L?", member, rbsType); }); }) .write("") diff --git a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/EndpointGenerator.java b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/EndpointGenerator.java index 5f696f418..8cd08a7a4 100644 --- a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/EndpointGenerator.java +++ b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/EndpointGenerator.java @@ -230,7 +230,7 @@ private void renderEndpointParamsClass(RubyCodeWriter writer) { Map defaultParams = new LinkedHashMap<>(); endpointRuleSet.getParameters().forEach((parameter -> { String rubyParamName = RubyFormatter.toSnakeCase(parameter.getName().getName().getValue()); - params.add(RubyFormatter.asSymbol(rubyParamName)); + params.add(rubyParamName); if (parameter.getDefault().isPresent()) { if (parameter.getType() == ParameterType.STRING) { defaultParams.put(rubyParamName, @@ -250,29 +250,26 @@ private void renderEndpointParamsClass(RubyCodeWriter writer) { })); writer - .openBlock("Params = ::Struct.new(") - .write(String.join(",\n", params) + ", ") - .write("keyword_init: true") - .closeBlock(") do") - .indent() - .write("include $T", Hearth.STRUCTURE) + .openBlock("class Params") + .openBlock("def initialize($L)", params.stream() + .map(p -> "%s: nil".formatted(RubyFormatter.toSnakeCase(p))) + .collect(Collectors.joining(", "))) .call(() -> { - if (!defaultParams.isEmpty()) { - writer - .write("") - .openBlock("def initialize(*)") - .write("super") - .call(() -> { - defaultParams.forEach((param, defaultValue) -> { - writer.write("self.$1L = $2L if self.$1L.nil?", - param, - defaultValue); - }); - }) - .closeBlock("end"); - } - + params.forEach(p -> { + String endpointParam = RubyFormatter.toSnakeCase(p); + if (defaultParams.containsKey(endpointParam)) { + writer.write("@$1L = $1L.nil? ? $2L : $1L", + endpointParam, defaultParams.get(endpointParam)); + } else { + writer.write("@$L = $L", endpointParam, endpointParam); + } + }); }) + .closeBlock("end") + .write("") + .write("attr_accessor $L", params.stream() + .map(p -> RubyFormatter.asSymbol(p)) + .collect(Collectors.joining(", "))) .closeBlock("end"); } @@ -292,10 +289,14 @@ private void renderRbsEndpointParamsClass(RubyCodeWriter writer) { })); writer - .openBlock("class Params < ::Struct[untyped]") + .openBlock("class Params") + .write("def initialize: ($L) -> void", + paramsToTypes.entrySet().stream() + .map(e -> "?%s: %s?".formatted(e.getKey(), e.getValue())) + .collect(Collectors.joining(", "))) .call(() -> { paramsToTypes.forEach((param, rbsType) -> { - writer.write("attr_accessor $L: $L", param, rbsType); + writer.write("attr_accessor $L (): $L?", param, rbsType); }); }) .closeBlock("end"); @@ -518,7 +519,10 @@ private void renderEndpointTestCases(RubyCodeWriter writer, List renderResponseStubInterceptor(testCase)) .write("interceptor = $T.new(read_after_transmit: proc)", Hearth.INTERCEPTOR) diff --git a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/StructureGenerator.java b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/StructureGenerator.java index eca3a953b..996e86f9f 100644 --- a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/StructureGenerator.java +++ b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/StructureGenerator.java @@ -26,7 +26,6 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.ShapeVisitor; import software.amazon.smithy.model.shapes.StructureShape; -import software.amazon.smithy.model.traits.RequiredTrait; import software.amazon.smithy.model.traits.SensitiveTrait; import software.amazon.smithy.ruby.codegen.GenerationContext; import software.amazon.smithy.ruby.codegen.Hearth; @@ -103,8 +102,7 @@ public void render() { Shape target = model.expectShape(memberShape.getTarget()); Symbol symbol = symbolProvider.toSymbol(target); String rbsType = symbol.getProperty("rbsType").get().toString(); - String required = memberShape.hasTrait(RequiredTrait.class) ? "" : "?"; - writer.write("attr_accessor $L (): $L$L", memberName, rbsType, required); + writer.write("attr_accessor $L (): $L?", memberName, rbsType); }); }) .closeBlock("end"); @@ -191,25 +189,29 @@ private void renderToSMethod(RubyCodeWriter writer) { writer .openBlock("\ndef to_s") - .write("\"#<$L \"\\", fullQualifiedShapeName) + .write("'#<$L ' \\", fullQualifiedShapeName) .indent(); while (iterator.hasNext()) { MemberShape memberShape = iterator.next(); String key = symbolProvider.toMemberName(memberShape); String value = "#{" + key + " || 'nil'}"; + boolean memberLiteral = false; if (memberShape.isBlobShape() || memberShape.isStringShape()) { // Strings are wrapped in quotes value = "\"" + value + "\""; + memberLiteral = true; } else if (memberShape.getMemberTrait(model, SensitiveTrait.class).isPresent()) { - value = "\\\"[SENSITIVE]\\\""; + value = "[SENSITIVE]"; + memberLiteral = true; } + String quote = memberLiteral ? "'" : "\""; if (iterator.hasNext()) { - writer.write("\"$L=$L, \"\\", key, value); + writer.write("$3L$1L=$2L, $3L \\", key, value, quote); } else { - writer.write("\"$L=$L>\"", key, value); + writer.write("$3L$1L=$2L>$3L", key, value, quote); } } writer diff --git a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/UnionGenerator.java b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/UnionGenerator.java index bda9accfa..df0bb69a8 100644 --- a/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/UnionGenerator.java +++ b/codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/types/UnionGenerator.java @@ -112,19 +112,17 @@ public void render() { } private void renderUnionToSMethod(RubyCodeWriter writer, MemberShape memberShape) { - String fullQualifiedShapeName = settings.getModule() + "::Types::" - + symbolProvider.toMemberName(memberShape); - - writer.write("") - .openBlock("def to_s"); - - if (memberShape.getMemberTrait(model, SensitiveTrait.class).isPresent()) { - writer.write("\"#<$L [SENSITIVE]>\"", fullQualifiedShapeName); - } else { - writer.write("\"#<$L #{__getobj__ || 'nil'}>\"", fullQualifiedShapeName); + if (!memberShape.getMemberTrait(model, SensitiveTrait.class).isPresent()) { + return; } - writer.closeBlock("end"); + String fullQualifiedShapeName = settings.getModule() + "::Types::" + + symbolProvider.toMemberName(memberShape); + writer + .write("") + .openBlock("def to_s") + .write("\"#<$L [SENSITIVE]>\"", fullQualifiedShapeName) + .closeBlock("end"); } private class UnionToHValueRbsVisitor extends ShapeVisitor.Default { diff --git a/hearth/CHANGELOG.md b/hearth/CHANGELOG.md index 7c035b433..eb8dc58d5 100644 --- a/hearth/CHANGELOG.md +++ b/hearth/CHANGELOG.md @@ -1,7 +1,7 @@ Unreleased Changes ------------------ -* Issue - Remove `Struct` from generated Types. +* Issue - Remove `Struct` from generated Types, Config, and other places to allow for better RBS typing as well as less reserved words. * Feature - Add `Hearth::Cbor.encode` and `Hearth::Cbor.decode`. * Issue - Fix query param `to_s` for empty arrays. * Feature - [Breaking Change] Add `config` to `Hearth::Context` and refactor `logger` and `interceptors` inside of it. diff --git a/hearth/lib/hearth/cbor.rb b/hearth/lib/hearth/cbor.rb index 754bc8ba6..bd8a26379 100644 --- a/hearth/lib/hearth/cbor.rb +++ b/hearth/lib/hearth/cbor.rb @@ -13,16 +13,22 @@ module CBOR # A Tag consists of a tag number and a value. # In the extended generic data model, a tag number's definition # describes the additional semantics conveyed with the tag number. - # # @!method initialize(*args) - # @option args [Integer] :tag The tag number. - # @option args [Object] :value The tag's content. - # @!attribute tag - # The tag number. - # @return [Integer] - # @!attribute value - # The tag's content. - # @return [Object] - Tagged = Struct.new(:tag, :value) + class Tagged + # @param [Integer] :tag The tag number. + # @param [Object] :value The tag's content. + def initialize(tag:, value:) + @tag = tag + @value = value + end + + # The tag number. + # @return [Integer] + attr_accessor :tag + + # The tag's content. + # @return [Object] + attr_accessor :value + end # Generic Cbor error, super class for specific encode/decode related errors. class Error < StandardError; end diff --git a/hearth/lib/hearth/cbor/decoder.rb b/hearth/lib/hearth/cbor/decoder.rb index c60e8cd65..84d1c231c 100644 --- a/hearth/lib/hearth/cbor/decoder.rb +++ b/hearth/lib/hearth/cbor/decoder.rb @@ -72,7 +72,7 @@ def decode_item when TAG_TYPE_BIGDEC read_big_decimal else - Tagged.new(tag, decode_item) + Tagged.new(tag: tag, value: decode_item) end when :break_stop_code raise UnexpectedBreakCodeError diff --git a/hearth/lib/hearth/config/resolver.rb b/hearth/lib/hearth/config/resolver.rb index 9fa528c43..1771f55c5 100644 --- a/hearth/lib/hearth/config/resolver.rb +++ b/hearth/lib/hearth/config/resolver.rb @@ -7,10 +7,10 @@ module Config class Resolver private_class_method :new - # @param config [Struct] + # @param config [Configuration] # @param options [Hash] # @param defaults [Hash>] - # @return [Struct] + # @return [Configuration] def self.resolve(config, options, defaults = {}) new(config).send(:resolve, options, defaults) end @@ -30,8 +30,8 @@ def initialize(config) def resolve(options, defaults) @options = options @defaults = defaults - @config.members.each do |key| - @config[key] = self[key] + @config.class::MEMBERS.each do |key| + @config.send("#{key}=", self[key]) end end diff --git a/hearth/lib/hearth/configuration.rb b/hearth/lib/hearth/configuration.rb index 3df757abc..998f7577f 100644 --- a/hearth/lib/hearth/configuration.rb +++ b/hearth/lib/hearth/configuration.rb @@ -5,13 +5,21 @@ module Hearth module Configuration def initialize(**options) @options = options.dup + Hearth::Validator.validate_unknown!(self, options, context: 'config') Hearth::Config::Resolver.resolve(self, options, _defaults) - super end # @return [Hash] The original configuration options. attr_reader :options + # @return [Hash] The configuration options. + def to_h(obj = self) + obj.class::MEMBERS.each_with_object({}) do |member, hash| + hash[member] = obj.send(member) + end + end + alias to_hash to_h + def merge(configuration) self.class.new(**to_h.merge(configuration.to_h)) end diff --git a/hearth/lib/hearth/dns/host_address.rb b/hearth/lib/hearth/dns/host_address.rb index b175fac19..7d931455f 100644 --- a/hearth/lib/hearth/dns/host_address.rb +++ b/hearth/lib/hearth/dns/host_address.rb @@ -3,25 +3,28 @@ module Hearth module DNS # Address results from a DNS lookup in {HostResolver}. - # @!method initialize(*args) - # @option args [Symbol] :address_type The type of address. For example, - # :A or :AAAA. - # @option args [String] :address The IP address. - # @option args [String] :hostname The hostname that was resolved. - # @!attribute address_type - # The type of address. For example, :A or :AAAA. - # @return [Symbol] - # @!attribute address - # The IP address. - # @return [String] - # @!attribute hostname - # The hostname that was resolved. - # @return [String] - HostAddress = Struct.new( - :address_type, - :address, - :hostname, - keyword_init: true - ) + class HostAddress + # @param [Symbol] :address_type The type of address. For example, + # :A or :AAAA. + # @param [String] :address The IP address. + # @param [String] :hostname The hostname that was resolved. + def initialize(address_type:, address:, hostname:) + @address_type = address_type + @address = address + @hostname = hostname + end + + # The type of address. For example, :A or :AAAA. + # @return [Symbol] + attr_accessor :address_type + + # The IP address. + # @return [String] + attr_accessor :address + + # The hostname that was resolved. + # @return [String] + attr_accessor :hostname + end end end diff --git a/hearth/lib/hearth/endpoint_rules.rb b/hearth/lib/hearth/endpoint_rules.rb index 6044812d4..2cb9d420f 100644 --- a/hearth/lib/hearth/endpoint_rules.rb +++ b/hearth/lib/hearth/endpoint_rules.rb @@ -11,49 +11,45 @@ module Hearth # invoked without additional dependencies, called the standard library. module EndpointRules # An Authentication Scheme supported by an Endpoint - # @!attribute scheme_id - # The identifier of the authentication scheme. - # @return [String] - # @!attribute properties - # Additional properties of the authentication scheme. - # @return [Hash] - AuthScheme = Struct.new( - :scheme_id, - :properties, - keyword_init: true - ) do - # @option args [String] :scheme_id - # @option args [Hash] :properties ({}) - def initialize(*args) - super - self.properties ||= {} + class AuthScheme + # @param [String] :scheme_id + # @param [Hash] :properties ({}) + def initialize(scheme_id:, properties: {}) + @scheme_id = scheme_id + @properties = properties end + + # The identifier of the authentication scheme. + # @return [String] + attr_accessor :scheme_id + + # Additional properties of the authentication scheme. + # @return [Hash] + attr_accessor :properties end # An Endpoint resolved by an EndpointProvider - # @!attribute uri - # The URI of the endpoint. - # @return [String] - # @!attribute auth_schemes - # The authentication schemes supported by the endpoint. - # @return [Array] - # @!attribute headers - # The headers to include in requests to the endpoint. - # @return [Hash] - Endpoint = Struct.new( - :uri, - :auth_schemes, - :headers, - keyword_init: true - ) do - # @option args [String] :uri - # @option args [Array] :auth_schemes ([]) - # @option args [Hash] :headers ({}) - def initialize(*args) - super - self.auth_schemes ||= [] - self.headers ||= {} + class Endpoint + # @param [String] :uri + # @param [Array] :auth_schemes ([]) + # @param [Hash] :headers ({}) + def initialize(uri:, auth_schemes: [], headers: {}) + @uri = uri + @auth_schemes = auth_schemes + @headers = headers end + + # The URI of the endpoint. + # @return [String] + attr_accessor :uri + + # The authentication schemes supported by the endpoint. + # @return [Array] + attr_accessor :auth_schemes + + # The headers to include in requests to the endpoint. + # @return [Hash] + attr_accessor :headers end # Evaluates whether the input string is a compliant RFC 1123 host segment. diff --git a/hearth/lib/hearth/http/client.rb b/hearth/lib/hearth/http/client.rb index 938d39230..05542a260 100644 --- a/hearth/lib/hearth/http/client.rb +++ b/hearth/lib/hearth/http/client.rb @@ -10,7 +10,7 @@ module HTTP # An HTTP client that uses Net::HTTP to send requests. class Client # @api private - OPTIONS = { + MEMBERS = { logger: nil, debug_output: nil, proxy: nil, @@ -84,16 +84,16 @@ class Client # optionally other keyword args similar to Addrinfo.getaddrinfo's # positional parameters. def initialize(options = {}) - unknown = options.keys - OPTIONS.keys + unknown = options.keys - MEMBERS.keys raise ArgumentError, "Unknown options: #{unknown}" unless unknown.empty? - OPTIONS.each_pair do |opt_name, default_value| + MEMBERS.each_pair do |opt_name, default_value| value = options.key?(opt_name) ? options[opt_name] : default_value instance_variable_set("@#{opt_name}", value) end end - OPTIONS.each_key do |attr_name| + MEMBERS.each_key do |attr_name| attr_reader(attr_name) end @@ -254,7 +254,7 @@ def proxy_parts # Config options for the HTTP client used for connection pooling # @return [Hash] def pool_config - OPTIONS.each_key.with_object({}) do |option_name, hash| + MEMBERS.each_key.with_object({}) do |option_name, hash| hash[option_name] = instance_variable_get("@#{option_name}") end end diff --git a/hearth/lib/hearth/middleware/auth.rb b/hearth/lib/hearth/middleware/auth.rb index b1c054911..b350a92f9 100644 --- a/hearth/lib/hearth/middleware/auth.rb +++ b/hearth/lib/hearth/middleware/auth.rb @@ -44,14 +44,20 @@ def call(input, context) private - ResolvedAuth = Struct.new( - :scheme_id, - :signer, - :signer_properties, - :identity, - :identity_properties, - keyword_init: true - ) + # @api private + class ResolvedAuth + def initialize(scheme_id:, signer:, signer_properties:, + identity:, identity_properties:) + @scheme_id = scheme_id + @signer = signer + @signer_properties = signer_properties + @identity = identity + @identity_properties = identity_properties + end + + attr_accessor :scheme_id, :signer, :signer_properties, + :identity, :identity_properties + end def resolve_auth(auth_options) failures = [] diff --git a/hearth/lib/hearth/retry.rb b/hearth/lib/hearth/retry.rb index cdfe23c3c..ddc632ec1 100644 --- a/hearth/lib/hearth/retry.rb +++ b/hearth/lib/hearth/retry.rb @@ -10,20 +10,19 @@ module Hearth module Retry # Represents a token that can be used to retry an operation. - # @!attribute retry_count - # The number of times the operation has been retried. - # @return [Integer] - # @!attribute retry_delay - # The delay before the next retry. - # @return [Numeric] - Token = Struct.new(:retry_count, :retry_delay, keyword_init: true) do - # @option args [Integer] :retry_count (0) - # @option args [Numeric] :retry_delay (0) - def initialize(*args) - super - self.retry_count ||= 0 - self.retry_delay ||= 0 + class Token + def initialize(retry_count: 0, retry_delay: 0) + @retry_count = retry_count + @retry_delay = retry_delay end + + # The number of times the operation has been retried. + # @return [Integer] + attr_accessor :retry_count + + # The delay before the next retry. + # @return [Numeric] + attr_accessor :retry_delay end end end diff --git a/hearth/lib/hearth/structure.rb b/hearth/lib/hearth/structure.rb index a6b2efec3..1ab2db4a9 100644 --- a/hearth/lib/hearth/structure.rb +++ b/hearth/lib/hearth/structure.rb @@ -23,7 +23,7 @@ def initialize(options = {}) # Deeply converts the Struct into a hash. Structure members that # are `nil` are omitted from the resultant hash. # - # @return [Hash, Structure, Object] + # @return [Hash, Structure] def to_h(obj = self) case obj when Union @@ -40,6 +40,23 @@ def to_h(obj = self) end alias to_hash to_h + # Returns a string representation of the Structure. + def to_s(obj = self) + case obj + when Union + "#<#{obj.class.name} #{obj.__getobj__ || 'nil'}>" + when Structure + _to_s_structure(obj) + when Hash + _to_s_hash(obj).to_s + when Array + _to_s_array(obj).to_s + else + obj.to_s + end + end + alias to_string to_s + private def _to_h_structure(obj) @@ -58,5 +75,23 @@ def _to_h_hash(obj) def _to_h_array(obj) obj.collect { |value| to_hash(value) } end + + def _to_s_structure(obj) + members = obj.class::MEMBERS.map do |member| + value = to_string(obj.send(member)) + " #{member}=#{value.empty? ? 'nil' : value}" + end + "#<#{self.class.name}#{members.join(',')}>" + end + + def _to_s_hash(obj) + obj.transform_values do |value| + to_string(value) + end + end + + def _to_s_array(obj) + obj.collect { |value| to_string(value) } + end end end diff --git a/hearth/lib/hearth/validator.rb b/hearth/lib/hearth/validator.rb index 90bad2201..7b4ae2be5 100755 --- a/hearth/lib/hearth/validator.rb +++ b/hearth/lib/hearth/validator.rb @@ -59,12 +59,12 @@ def self.validate_types!(value, *types, context:) end # Validate unknown parameters are not present for a given Type. - # @param type [Structure] The Type to validate against. + # @param klass [Structure, Configuration] The class to validate against. # @param params [Hash] The parameters to validate. # @param context [String] The context of the value being validated. # @raise [ArgumentError] Raises when unknown parameters are present. - def self.validate_unknown!(type, params, context:) - unknown = params.keys - type.class::MEMBERS + def self.validate_unknown!(klass, params, context:) + unknown = params.keys - klass.class::MEMBERS return if unknown.empty? unknown = unknown.map { |key| "#{context}[:#{key}]" } diff --git a/hearth/sig/lib/hearth/configuration.rbs b/hearth/sig/lib/hearth/configuration.rbs index 6e537a36d..efb600d79 100644 --- a/hearth/sig/lib/hearth/configuration.rbs +++ b/hearth/sig/lib/hearth/configuration.rbs @@ -4,6 +4,9 @@ module Hearth attr_reader options: Hash[Symbol, untyped] + def to_h: (self) -> (Hash[Symbol, untyped] | self) + alias to_hash to_h + def merge: (Hash[Symbol, untyped] configuration) -> ServiceConfig end end diff --git a/hearth/sig/lib/hearth/dns/host_address.rbs b/hearth/sig/lib/hearth/dns/host_address.rbs index 9d1987043..ed0b8847f 100644 --- a/hearth/sig/lib/hearth/dns/host_address.rbs +++ b/hearth/sig/lib/hearth/dns/host_address.rbs @@ -1,11 +1,13 @@ module Hearth module DNS - class HostAddress < Struct[untyped] - attr_reader address_type: Symbol + class HostAddress + def initialize: (address_type: Symbol, address: String, hostname: String) -> void - attr_reader address: String + attr_accessor address_type: Symbol - attr_reader hostname: String + attr_accessor address: String + + attr_accessor hostname: String end end end diff --git a/hearth/sig/lib/hearth/endpoint_rules.rbs b/hearth/sig/lib/hearth/endpoint_rules.rbs index 85cb1b9d9..ea634257a 100644 --- a/hearth/sig/lib/hearth/endpoint_rules.rbs +++ b/hearth/sig/lib/hearth/endpoint_rules.rbs @@ -1,12 +1,16 @@ module Hearth module EndpointRules - class AuthScheme < Struct[untyped] + class AuthScheme + def initialize: (scheme_id: String, ?properties: ::Hash[String, untyped]) -> void + attr_accessor scheme_id: String attr_accessor properties: Hash[String, untyped] end - class Endpoint < Struct[untyped] + class Endpoint + def initialize: (uri: String, ?auth_schemes: Array[AuthScheme], ?headers: Hash[String, String | Array[String]]) -> void + attr_accessor uri: String attr_accessor auth_schemes: Array[AuthScheme] diff --git a/hearth/sig/lib/hearth/retry.rbs b/hearth/sig/lib/hearth/retry.rbs index 375b4422f..176fa41ff 100644 --- a/hearth/sig/lib/hearth/retry.rbs +++ b/hearth/sig/lib/hearth/retry.rbs @@ -1,6 +1,8 @@ module Hearth module Retry - class Token < Struct[untyped] + class Token + def initialize: (?retry_count: Integer, ?retry_delay: Numeric) -> void + attr_accessor retry_count (): Integer attr_accessor retry_delay (): Numeric diff --git a/hearth/sig/lib/hearth/structure.rbs b/hearth/sig/lib/hearth/structure.rbs index 67e76e0d5..3f2984385 100644 --- a/hearth/sig/lib/hearth/structure.rbs +++ b/hearth/sig/lib/hearth/structure.rbs @@ -1,6 +1,9 @@ module Hearth module Structure - def to_h: (self) -> (Hash[Symbol, untyped] | self) + def to_h: (self) -> Hash[Symbol, untyped] alias to_hash to_h + + def to_s: (self) -> String + alias to_string to_s end end diff --git a/hearth/spec/hearth/cbor/cbor_spec.rb b/hearth/spec/hearth/cbor/cbor_spec.rb index 14f104429..679dae760 100644 --- a/hearth/spec/hearth/cbor/cbor_spec.rb +++ b/hearth/spec/hearth/cbor/cbor_spec.rb @@ -22,7 +22,7 @@ def expected_value(expect) end when 'tag' value = expected_value(expect['tag']['value']) - CBOR::Tagged.new(expect['tag']['id'], value) + CBOR::Tagged.new(tag: expect['tag']['id'], value: value) when 'bool' then expect['bool'] when 'null' then nil when 'undefined' then :undefined @@ -34,16 +34,20 @@ def expected_value(expect) end def assert(actual, expected) - if expected.is_a?(Float) && expected.nan? - expect(actual.nan?).to be true - elsif expected.is_a?(Array) + case expected + when Array expected.each_with_index do |item, i| assert(actual[i], item) end - elsif expected.is_a?(Hash) + when Hash expected.each do |key, value| assert(actual[key], value) end + when Float + expect(actual.nan?).to be true if expected.nan? + when CBOR::Tagged + expect(actual.tag).to eq(expected.tag) + expect(actual.value).to eq(expected.value) else expect(actual).to eq(expected) end diff --git a/hearth/spec/hearth/cbor/encoder_spec.rb b/hearth/spec/hearth/cbor/encoder_spec.rb index fde5141aa..2f9960848 100644 --- a/hearth/spec/hearth/cbor/encoder_spec.rb +++ b/hearth/spec/hearth/cbor/encoder_spec.rb @@ -59,7 +59,7 @@ def cbor64_encode(value) end it 'encodes Tagged items' do - expect(cbor64_encode(Tagged.new(0, 0))).to eq('wAA=') + expect(cbor64_encode(Tagged.new(tag: 0, value: 0))).to eq('wAA=') end it 'encodes arrays' do diff --git a/hearth/spec/hearth/client_spec.rb b/hearth/spec/hearth/client_spec.rb index 90c12327d..8ab004e4c 100644 --- a/hearth/spec/hearth/client_spec.rb +++ b/hearth/spec/hearth/client_spec.rb @@ -1,15 +1,23 @@ # frozen_string_literal: true module Hearth - module Test - Config = Struct.new( - :stub_responses, :stubs, :plugins, :interceptors, keyword_init: true - ) do + module TestClient + class Config + MEMBERS = %i[ + stub_responses + stubs + plugins + interceptors + ].freeze + include Hearth::Configuration + + attr_accessor(*MEMBERS) + def validate! Hearth::Validator.validate_types!( - stub_responses, TrueClass, - FalseClass, context: 'config[:stub_responses]' + stub_responses, TrueClass, FalseClass, + context: 'config[:stub_responses]' ) Hearth::Validator.validate_types!( stubs, Hearth::Stubs, @@ -20,8 +28,8 @@ def validate! context: 'config[:plugins]' ) Hearth::Validator.validate_types!( - interceptors, - Hearth::InterceptorList, context: 'config[:interceptors]' + interceptors, Hearth::InterceptorList, + context: 'config[:interceptors]' ) end @@ -53,7 +61,7 @@ def operation_body_stream(_params = {}, options = {}, &block) end describe Client do - let(:subject) { Test::Client.new(stub_responses: true) } + let(:subject) { TestClient::Client.new(stub_responses: true) } let(:plugin) { proc { |_cfg| } } let(:interceptor) do Class.new do @@ -63,7 +71,7 @@ def read_before_signing(*args); end after(:each) do # cleanup any class plugins - Test::Client.instance_variable_set(:@plugins, nil) + TestClient::Client.instance_variable_set(:@plugins, nil) end describe '#initialize' do @@ -73,23 +81,23 @@ def read_before_signing(*args); end it 'validates config' do expect do - Test::Client.new(stub_responses: 'not a boolean') + TestClient::Client.new(stub_responses: 'not a boolean') end.to raise_error(ArgumentError, /config\[:stub_responses\]/) end it 'calls each Class plugin' do - Test::Client.plugins << plugin + TestClient::Client.plugins << plugin expect(plugin).to receive(:call) - Test::Client.new + TestClient::Client.new end it 'calls each plugin from initialize' do expect(plugin).to receive(:call) - Test::Client.new(plugins: PluginList.new([plugin])) + TestClient::Client.new(plugins: PluginList.new([plugin])) end it 'appends interceptors' do - client = Test::Client.new(interceptors: [interceptor]) + client = TestClient::Client.new(interceptors: [interceptor]) expect(client.config.interceptors.to_a).to include(interceptor) end @@ -100,7 +108,7 @@ def read_before_signing(*args); end describe '#inspect' do it 'is the class name without instance variables' do - expect(subject.inspect).to eq('#') + expect(subject.inspect).to eq('#') end end @@ -118,11 +126,15 @@ def read_before_signing(*args); end end it 'returns a config object' do - expect(subject.operation).to be_a(Test::Config) + expect(subject.operation).to be_a(TestClient::Config) end it 'has the same values as the client config' do - expect(subject.operation).to eq(subject.config) + actual = subject.operation + expected = subject.config + actual.class::MEMBERS.each do |member| + expect(actual.send(member)).to eq(expected.send(member)) + end end it 'calls operation plugins' do diff --git a/hearth/spec/hearth/config/resolver_spec.rb b/hearth/spec/hearth/config/resolver_spec.rb index e1702292c..ee2ce893e 100644 --- a/hearth/spec/hearth/config/resolver_spec.rb +++ b/hearth/spec/hearth/config/resolver_spec.rb @@ -2,23 +2,24 @@ module Hearth module Config + class TestResolverConfig + MEMBERS = %i[ + option1 + option2 + ].freeze + + attr_accessor(*MEMBERS) + end + describe Resolver do subject { Resolver } - let(:config_class) do - Struct.new( - :option1, - :option2, - keyword_init: true - ) - end - it 'cannot be initialized' do expect { subject.new }.to raise_error(NoMethodError) end describe '.resolve' do - let(:config) { config_class.new } + let(:config) { TestResolverConfig.new } it 'creates the config with provided options' do defaults = { option1: ['should not be used'] } diff --git a/hearth/spec/hearth/configuration_spec.rb b/hearth/spec/hearth/configuration_spec.rb index f4a39079d..4ec5ecea1 100644 --- a/hearth/spec/hearth/configuration_spec.rb +++ b/hearth/spec/hearth/configuration_spec.rb @@ -1,62 +1,92 @@ # frozen_string_literal: true module Hearth - describe Configuration do - let(:config_class) do - Struct.new(:simple_option, keyword_init: true) do - include Hearth::Configuration + class TestConfiguration + MEMBERS = %i[ + simple_option + complex_option + ].freeze - def validate! - Hearth::Validator.validate_types!( - simple_option, String, context: 'config[:simple_option]' - ) - end + include Hearth::Configuration - private + attr_accessor(*MEMBERS) - def _defaults - { simple_option: ['default'] } - end - end + def validate! + Hearth::Validator.validate_types!( + simple_option, String, + context: 'config[:simple_option]' + ) + Hearth::Validator.validate_types!( + complex_option, Object, + context: 'config[:complex_option]' + ) + end + + private + + def _defaults + { + simple_option: ['default'], + complex_option: [Object.new] + }.freeze end + end + describe Configuration do describe '#initialize' do it 'uses the config resolver' do options = { simple_option: 'test' } expect(Hearth::Config::Resolver).to receive(:resolve) .with( - an_instance_of(config_class), + an_instance_of(TestConfiguration), options, - { simple_option: ['default'] } + { + simple_option: ['default'], + complex_option: [an_instance_of(Object)] + } ).and_call_original - config = config_class.new(**options) + config = TestConfiguration.new(**options) expect(config.simple_option).to eq('test') end it 'resolves correctly when not passed any options' do expect(Hearth::Config::Resolver).to receive(:resolve) .with( - an_instance_of(config_class), + an_instance_of(TestConfiguration), {}, - { simple_option: ['default'] } + { + simple_option: ['default'], + complex_option: [an_instance_of(Object)] + } ).and_call_original - config = config_class.new + config = TestConfiguration.new expect(config.simple_option).to eq('default') end it 'raises on unknown options' do expect do - config_class.new(unknown_option: 'test') - end.to raise_error(ArgumentError, /unknown_option/) + TestConfiguration.new(unknown_option: 'test') + end.to raise_error(ArgumentError, /config\[:unknown_option\]/) + end + end + + describe '#to_h' do + it 'returns the configuration as a hash' do + object = Object.new + config = TestConfiguration.new( + simple_option: 'test', + complex_option: object + ) + expect(config.to_h).to eq(simple_option: 'test', complex_option: object) end end describe '#merge' do it 'merges the configuration' do - config = config_class.new(simple_option: 'test') - merged = config.merge(config_class.new(simple_option: 'test2')) + config = TestConfiguration.new(simple_option: 'test') + merged = config.merge(TestConfiguration.new(simple_option: 'test2')) expect(merged.simple_option).to eq('test2') end end diff --git a/hearth/spec/hearth/context_spec.rb b/hearth/spec/hearth/context_spec.rb index 8e61ab049..b3de52707 100644 --- a/hearth/spec/hearth/context_spec.rb +++ b/hearth/spec/hearth/context_spec.rb @@ -48,7 +48,13 @@ module Hearth describe '#auth' do it 'allows for auth to be set' do - resolved_auth = Hearth::Middleware::Auth::ResolvedAuth.new + resolved_auth = Hearth::Middleware::Auth::ResolvedAuth.new( + scheme_id: double, + signer: double, + signer_properties: double, + identity: double, + identity_properties: double + ) subject.auth = resolved_auth expect(subject.auth).to eq(resolved_auth) end diff --git a/hearth/spec/hearth/dns/host_address_spec.rb b/hearth/spec/hearth/dns/host_address_spec.rb index e87f46852..44fed5caa 100644 --- a/hearth/spec/hearth/dns/host_address_spec.rb +++ b/hearth/spec/hearth/dns/host_address_spec.rb @@ -3,13 +3,35 @@ module Hearth module DNS describe HostAddress do - it 'can be initialized' do + let(:address_type) { :A } + let(:address) { '123.123.123.123' } + let(:hostname) { 'example.com' } + + subject do HostAddress.new( - address_type: :A, - address: '123.123.123.123', - hostname: 'example.com' + address_type: address_type, + address: address, + hostname: hostname ) end + + describe '#address_type' do + it 'returns the address type' do + expect(subject.address_type).to eq(address_type) + end + end + + describe '#address' do + it 'returns the address' do + expect(subject.address).to eq(address) + end + end + + describe '#hostname' do + it 'returns the hostname' do + expect(subject.hostname).to eq(hostname) + end + end end end end diff --git a/hearth/spec/hearth/http/error_parser_spec.rb b/hearth/spec/hearth/http/error_parser_spec.rb index 24633d52d..3902e3f47 100644 --- a/hearth/spec/hearth/http/error_parser_spec.rb +++ b/hearth/spec/hearth/http/error_parser_spec.rb @@ -22,13 +22,13 @@ class ApiClientError < ApiError; end class ApiServerError < ApiError; end - class TestModeledError < ApiClientError; end + class ModeledError < ApiClientError; end end describe ErrorParser do let(:error_module) { TestErrors } let(:success_status) { 200 } - let(:errors) { [TestErrors::TestModeledError] } + let(:errors) { [TestErrors::ModeledError] } let(:resp_status) { 200 } let(:fields) { Fields.new } @@ -98,7 +98,7 @@ class TestModeledError < ApiClientError; end context 'error code on response' do before do expect(TestErrors).to receive(:error_code) - .with(http_resp).and_return('TestModeledError') + .with(http_resp).and_return('ModeledError') end context 'error response: 2XX with error code' do @@ -106,7 +106,7 @@ class TestModeledError < ApiClientError; end it 'returns the modeled error' do error = subject.parse(http_resp, metadata) - expect(error).to be_a(TestErrors::TestModeledError) + expect(error).to be_a(TestErrors::ModeledError) end context 'Modeled error not in errors' do @@ -124,7 +124,7 @@ class TestModeledError < ApiClientError; end it 'returns the modeled error' do error = subject.parse(http_resp, metadata) - expect(error).to be_a(TestErrors::TestModeledError) + expect(error).to be_a(TestErrors::ModeledError) end end end diff --git a/hearth/spec/hearth/middleware/endpoint_spec.rb b/hearth/spec/hearth/middleware/endpoint_spec.rb index d99866d3e..e54dff1a6 100644 --- a/hearth/spec/hearth/middleware/endpoint_spec.rb +++ b/hearth/spec/hearth/middleware/endpoint_spec.rb @@ -2,10 +2,17 @@ module Hearth module Middleware + class TestEndpointInput + include Hearth::Structure + + MEMBERS = %i[foo].freeze + + attr_accessor(*MEMBERS) + end + describe Endpoint do let(:app) { double('app', call: output) } - let(:struct) { Struct.new(:foo, keyword_init: true) } - let(:input) { struct.new } + let(:input) { TestEndpointInput.new } let(:output) { double('output') } let(:endpoint_resolver) { double } let(:param_builder) { double } diff --git a/hearth/spec/hearth/middleware/host_prefix_spec.rb b/hearth/spec/hearth/middleware/host_prefix_spec.rb index 89f97a72a..0335c6369 100644 --- a/hearth/spec/hearth/middleware/host_prefix_spec.rb +++ b/hearth/spec/hearth/middleware/host_prefix_spec.rb @@ -2,10 +2,17 @@ module Hearth module Middleware + class TestHostPrefixInput + include Hearth::Structure + + MEMBERS = %i[foo].freeze + + attr_accessor(*MEMBERS) + end + describe HostPrefix do let(:app) { double('app', call: output) } - let(:struct) { Struct.new(:foo, keyword_init: true) } - let(:input) { struct.new } + let(:input) { TestHostPrefixInput.new } let(:output) { double('output') } let(:host_prefix) { 'foo.' } @@ -42,7 +49,7 @@ module Middleware context 'host prefix has labels' do let(:host_prefix) { '{foo}.' } - let(:input) { struct.new(foo: 'bar') } + let(:input) { TestHostPrefixInput.new(foo: 'bar') } it 'populates the label with input' do expect(app).to receive(:call).with(input, context) @@ -53,7 +60,7 @@ module Middleware end context 'input does not have the label' do - let(:input) { struct.new } + let(:input) { TestHostPrefixInput.new } it 'raises an ArgumentError' do expect do @@ -63,7 +70,7 @@ module Middleware end context 'input has an empty label' do - let(:input) { struct.new(foo: '') } + let(:input) { TestHostPrefixInput.new(foo: '') } it 'raises an ArgumentError' do expect do diff --git a/hearth/spec/hearth/middleware/send_spec.rb b/hearth/spec/hearth/middleware/send_spec.rb index 995bb918f..cc07f1305 100644 --- a/hearth/spec/hearth/middleware/send_spec.rb +++ b/hearth/spec/hearth/middleware/send_spec.rb @@ -2,34 +2,44 @@ module Hearth module Middleware - module Types - StubData = ::Struct.new(:member, keyword_init: true) do - include Hearth::Structure - end + module TestStubs + module Types + class StubData + include Hearth::Structure - StubErrorData = ::Struct.new(:message, keyword_init: true) do - include Hearth::Structure - end - end + MEMBERS = %i[member].freeze - module Errors - class StubError < StandardError; end - class OtherError < StandardError; end - end + attr_accessor(*MEMBERS) + end + + class StubErrorData + include Hearth::Structure + + MEMBERS = %i[message].freeze - module Stubs - class StubData - def self.build(params, context:); end - def self.validate!(output, context:); end - def self.default(visited = []); end - def self.stub(resp, stub:); end + attr_accessor(*MEMBERS) + end end - class StubError - def self.build(params, context:); end - def self.validate!(output, context:); end - def self.default(visited = []); end - def self.stub(resp, stub:); end + module Errors + class StubError < StandardError; end + class OtherError < StandardError; end + end + + module Stubs + class StubData + def self.build(params, context:); end + def self.validate!(output, context:); end + def self.default(visited = []); end + def self.stub(resp, stub:); end + end + + class StubError + def self.build(params, context:); end + def self.validate!(output, context:); end + def self.default(visited = []); end + def self.stub(resp, stub:); end + end end end @@ -46,8 +56,8 @@ def self.stub(resp, stub:); end app, client: client, stub_responses: stub_responses, - stub_data_class: Stubs::StubData, - stub_error_classes: [Stubs::StubError], + stub_data_class: TestStubs::Stubs::StubData, + stub_error_classes: [TestStubs::Stubs::StubError], stubs: stubs ) end @@ -241,17 +251,17 @@ def self.stub(resp, stub:); end context 'stub is a hash' do context 'data stub' do let(:stub_hash) { { member: 'value' } } - let(:stub_data) { Types::StubData.new(**stub_hash) } + let(:stub_data) { TestStubs::Types::StubData.new(**stub_hash) } before { stubs.set_stubs(operation, [{ data: stub_hash }]) } it 'uses the data hash to stub the response' do - expect(Stubs::StubData).to receive(:build) + expect(TestStubs::Stubs::StubData).to receive(:build) .with(stub_hash, context: 'stub') .and_return(stub_data) - expect(Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:validate!) .with(stub_data, context: 'stub') - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end @@ -262,12 +272,12 @@ def self.stub(resp, stub:); end before { stubs.set_stubs(operation, [stub_proc]) } it 'uses the data hash to stub the response' do - expect(Stubs::StubData).to receive(:build) + expect(TestStubs::Stubs::StubData).to receive(:build) .with(stub_hash, context: 'stub') .and_return(stub_data) - expect(Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:validate!) .with(stub_data, context: 'stub') - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end @@ -276,20 +286,22 @@ def self.stub(resp, stub:); end context 'error stub' do let(:stub_hash) do - { class: Errors::StubError, data: stub_error_data } + { class: TestStubs::Errors::StubError, data: stub_error_data } end let(:stub_error_data) { { message: 'error' } } - let(:stub_error) { Types::StubErrorData.new(**stub_error_data) } + let(:stub_error) do + TestStubs::Types::StubErrorData.new(**stub_error_data) + end before { stubs.set_stubs(operation, [{ error: stub_hash }]) } it 'uses the error hash to stub the response' do - expect(Stubs::StubError).to receive(:build) + expect(TestStubs::Stubs::StubError).to receive(:build) .with(stub_error_data, context: 'stub') .and_return(stub_error) - expect(Stubs::StubError).to receive(:validate!) + expect(TestStubs::Stubs::StubError).to receive(:validate!) .with(stub_error, context: 'stub') - expect(Stubs::StubError).to receive(:stub) + expect(TestStubs::Stubs::StubError).to receive(:stub) .with(response, stub: stub_error) subject.call(input, context) end @@ -300,12 +312,12 @@ def self.stub(resp, stub:); end before { stubs.set_stubs(operation, [stub_proc]) } it 'uses the error hash to stub the response' do - expect(Stubs::StubError).to receive(:build) + expect(TestStubs::Stubs::StubError).to receive(:build) .with(stub_error_data, context: 'stub') .and_return(stub_error) - expect(Stubs::StubError).to receive(:validate!) + expect(TestStubs::Stubs::StubError).to receive(:validate!) .with(stub_error, context: 'stub') - expect(Stubs::StubError).to receive(:stub) + expect(TestStubs::Stubs::StubError).to receive(:stub) .with(response, stub: stub_error) subject.call(input, context) end @@ -332,7 +344,7 @@ def self.stub(resp, stub:); end end it 'raises with unknown error class' do - stub_hash[:class] = Errors::OtherError + stub_hash[:class] = TestStubs::Errors::OtherError expect do subject.call(input, context) end.to raise_error( @@ -363,18 +375,18 @@ def self.stub(resp, stub:); end context 'stub is nil' do let(:stub_hash) { { member: 'value' } } - let(:stub_data) { Types::StubData.new(**stub_hash) } + let(:stub_data) { TestStubs::Types::StubData.new(**stub_hash) } before { stubs.set_stubs(operation, [nil]) } it 'uses the stub class default' do - expect(Stubs::StubData).to receive(:default) + expect(TestStubs::Stubs::StubData).to receive(:default) .and_return(stub_hash) - expect(Stubs::StubData).to receive(:build) + expect(TestStubs::Stubs::StubData).to receive(:build) .with(stub_hash, context: 'stub') .and_return(stub_data) - expect(Stubs::StubData).to receive(:validate!) - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end @@ -385,13 +397,13 @@ def self.stub(resp, stub:); end before { stubs.set_stubs(operation, [stub_proc]) } it 'uses the stub class default' do - expect(Stubs::StubData).to receive(:default) + expect(TestStubs::Stubs::StubData).to receive(:default) .and_return(stub_hash) - expect(Stubs::StubData).to receive(:build) + expect(TestStubs::Stubs::StubData).to receive(:build) .with(stub_hash, context: 'stub') .and_return(stub_data) - expect(Stubs::StubData).to receive(:validate!) - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end @@ -399,14 +411,14 @@ def self.stub(resp, stub:); end end context 'stub is a Hearth::Structure' do - let(:stub_data) { Types::StubData.new(member: 'value') } + let(:stub_data) { TestStubs::Types::StubData.new(member: 'value') } before { stubs.set_stubs(operation, [stub_data]) } it 'uses the stub class to stub the response' do - expect(Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:validate!) .with(stub_data, context: 'stub') - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end @@ -417,9 +429,9 @@ def self.stub(resp, stub:); end before { stubs.set_stubs(operation, [stub_proc]) } it 'uses the stub class to stub the response' do - expect(Stubs::StubData).to receive(:validate!) + expect(TestStubs::Stubs::StubData).to receive(:validate!) .with(stub_data, context: 'stub') - expect(Stubs::StubData).to receive(:stub) + expect(TestStubs::Stubs::StubData).to receive(:stub) .with(response, stub: stub_data) subject.call(input, context) end diff --git a/hearth/spec/hearth/structure_spec.rb b/hearth/spec/hearth/structure_spec.rb index f835de22b..e1a70e944 100644 --- a/hearth/spec/hearth/structure_spec.rb +++ b/hearth/spec/hearth/structure_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Hearth - class MyStructure + class TestStructure include Hearth::Structure MEMBERS = %i[ @@ -27,15 +27,15 @@ def _defaults describe Structure do subject do - MyStructure.new( - struct_value: MyStructure.new(value: 'foo'), + TestStructure.new( + struct_value: TestStructure.new(value: 'foo'), array_value: [ - MyStructure.new(value: 'foo'), - MyStructure.new(value: 'bar') + TestStructure.new(value: 'foo'), + TestStructure.new(value: 'bar') ], - hash_value: { key: MyStructure.new(value: 'value') }, + hash_value: { key: TestStructure.new(value: 'value') }, value: 'value', - union_value: MyUnion::StringValue.new('union'), + union_value: TestUnion::StringValue.new('union'), some_object: Object.new ) end @@ -46,7 +46,7 @@ def _defaults end end - describe '#to_hash' do + describe '#to_h' do it 'serializes nested structs to a hash' do expected = { struct_value: { value: 'foo', default_value: 'default' }, @@ -65,5 +65,20 @@ def _defaults expect(subject.to_h).to eq expected end end + + describe '#to_s' do + it 'returns a string representation of the structure' do + actual = subject.to_s + expect(actual).to include(subject.class.name) + expect(actual).to include(subject.struct_value.to_s) + expect(actual).to include(subject.array_value.first.to_s) + expect(actual).to include(subject.array_value.last.to_s) + expect(actual).to include(subject.hash_value[:key].to_s) + expect(actual).to include(subject.value) + expect(actual).to include(subject.union_value.to_s) + expect(actual).to include(subject.some_object.to_s) + expect(actual).to include(subject.default_value) + end + end end end diff --git a/hearth/spec/hearth/stubbing/client_stubs_spec.rb b/hearth/spec/hearth/stubbing/client_stubs_spec.rb index 0a2a1eae6..fb7a1489f 100644 --- a/hearth/spec/hearth/stubbing/client_stubs_spec.rb +++ b/hearth/spec/hearth/stubbing/client_stubs_spec.rb @@ -1,15 +1,31 @@ # frozen_string_literal: true module Hearth - module ClientStubTest - Config = Struct.new(:stub_responses, :stubs, keyword_init: true) + module TestClientStubs + class Config + MEMBERS = %i[ + stub_responses + stubs + ].freeze + + include Hearth::Configuration + + attr_accessor(*MEMBERS) + + private + + def _defaults + { + stubs: [Hearth::Stubs.new] + }.freeze + end + end class Client include ClientStubs def initialize(config = Config.new) @config = config - @config.stubs = Hearth::Stubs.new end attr_accessor :config @@ -17,8 +33,11 @@ def initialize(config = Config.new) end describe ClientStubs do - let(:config) { ClientStubTest::Config.new(stub_responses: stub_responses) } - subject { ClientStubTest::Client.new(config) } + let(:config) do + TestClientStubs::Config.new(stub_responses: stub_responses) + end + + subject { TestClientStubs::Client.new(config) } describe '#stub_responses' do context 'stub_responses is true' do diff --git a/hearth/spec/hearth/union_spec.rb b/hearth/spec/hearth/union_spec.rb index 58875f651..5146fa66c 100644 --- a/hearth/spec/hearth/union_spec.rb +++ b/hearth/spec/hearth/union_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module Hearth - class MyUnion < Hearth::Union - class StringValue < MyUnion + class TestUnion < Hearth::Union + class StringValue < TestUnion def to_h { string_value: super(__getobj__) } end @@ -10,7 +10,7 @@ def to_h end describe Union do - subject { MyUnion::StringValue.new('union') } + subject { TestUnion::StringValue.new('union') } it 'uses simple delegator and structure' do expect(subject).to be_a(SimpleDelegator) @@ -22,5 +22,12 @@ def to_h expect(subject.to_h).to eq(string_value: 'union') end end + + describe '#to_s' do + it 'returns a string representation' do + expect(subject.to_s) + .to eq('#') + end + end end end diff --git a/hearth/spec/hearth/validator_spec.rb b/hearth/spec/hearth/validator_spec.rb index b944794a4..ef18bd228 100644 --- a/hearth/spec/hearth/validator_spec.rb +++ b/hearth/spec/hearth/validator_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Hearth - class MyType + class TestValidatorInput include Hearth::Structure MEMBERS = %i[foo].freeze @@ -10,7 +10,7 @@ class MyType end describe Validator do - let(:input) { MyType.new(params) } + let(:input) { TestValidatorInput.new(params) } let(:context) { 'input' } describe '.validate_range!' do @@ -180,7 +180,7 @@ class MyType end describe '.validate_unknown!' do - let(:input) { MyType.new } + let(:input) { TestValidatorInput.new } context 'all members are known' do let(:params) { { foo: 'bar' } } diff --git a/hearth/spec/hearth/waiters/poller_spec.rb b/hearth/spec/hearth/waiters/poller_spec.rb index 57ae5bcb3..0acba65c9 100644 --- a/hearth/spec/hearth/waiters/poller_spec.rb +++ b/hearth/spec/hearth/waiters/poller_spec.rb @@ -2,6 +2,14 @@ module Hearth module Waiters + class TestWaiterInput + include Hearth::Structure + + MEMBERS = %i[string boolean all_string any_string].freeze + + attr_accessor(*MEMBERS) + end + describe Poller do subject do Poller.new( @@ -12,18 +20,8 @@ module Waiters let(:client) { double('client') } let(:input_output_interceptor) { double('input_output_interceptor') } - - let(:test_operation_struct) do - Struct.new( - :string, - :boolean, - :all_string, - :any_string, - keyword_init: true - ) - end - let(:struct) do - test_operation_struct.new( + let(:input) do + TestWaiterInput.new( string: 'peccy', boolean: true, all_string: %w[foo foo], @@ -32,7 +30,7 @@ module Waiters end let(:interceptor_context) do - double('ictx', input: struct) + double('ictx', input: input) end let(:error) do @@ -73,9 +71,9 @@ module Waiters it 'returns retry state with response' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:retry, struct] + expect(subject.call(client, {}, {})).to eq [:retry, input] end end end @@ -90,9 +88,9 @@ module Waiters it 'can match success' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -132,9 +130,9 @@ module Waiters it 'can match string equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -157,9 +155,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -182,9 +180,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -207,9 +205,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end end @@ -234,9 +232,9 @@ module Waiters it 'can match string equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -259,9 +257,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -284,9 +282,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end @@ -309,9 +307,9 @@ module Waiters it 'can match boolean equals' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end end @@ -345,9 +343,9 @@ module Waiters it 'iterates all matchers' do expect(client).to receive(:test_operation) .with({}, { interceptors: [input_output_interceptor] }) - .and_return(struct) + .and_return(input) - expect(subject.call(client, {}, {})).to eq [:success, struct] + expect(subject.call(client, {}, {})).to eq [:success, input] end end end diff --git a/hearth/spec/hearth/waiters/waiter_spec.rb b/hearth/spec/hearth/waiters/waiter_spec.rb index aaf9f83fb..4ef1330ce 100644 --- a/hearth/spec/hearth/waiters/waiter_spec.rb +++ b/hearth/spec/hearth/waiters/waiter_spec.rb @@ -26,6 +26,14 @@ module Waiters end end + class TestWaiterOutput + include Hearth::Structure + + MEMBERS = %i[member].freeze + + attr_accessor(*MEMBERS) + end + describe Waiter do subject do Waiter.new( @@ -38,9 +46,7 @@ module Waiters let(:poller) { double('poller') } let(:client) { double('client') } - - let(:response_struct) { Struct.new(:member, keyword_init: true) } - let(:response) { response_struct.new(member: 'foo') } + let(:response) { TestWaiterOutput.new(member: 'foo') } let(:error) do Hearth::ApiError.new(