diff --git a/.rubocop.yml b/.rubocop.yml index 0d43750..b791250 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,17 +1,357 @@ -inherit_gem: - google-style: google-style.yml +AllCops: + NewCops: disable + SuggestExtensions: false + TargetRubyVersion: 2.7 +Gemspec/AddRuntimeDependency: + Enabled: true +Gemspec/AttributeAssignment: + Enabled: true +Gemspec/DeprecatedAttributeAssignment: + Enabled: true +Gemspec/DevelopmentDependencies: + Enabled: true +Gemspec/RequireMFA: + Enabled: false + +Layout/EmptyLineAfterGuardClause: + Enabled: false +Layout/EmptyLinesAfterModuleInclusion: + Enabled: true +Layout/HashAlignment: + Enabled: false +Layout/LineContinuationLeadingSpace: + Enabled: true +Layout/LineContinuationSpacing: + Enabled: true +Layout/LineEndStringConcatenationIndentation: + Enabled: true +Layout/LineLength: + Max: 120 +Layout/SpaceBeforeBrackets: + Enabled: true +Layout/SpaceInsideHashLiteralBraces: + Enabled: false + + +Lint/AmbiguousAssignment: + Enabled: true +Lint/AmbiguousOperatorPrecedence: + Enabled: true +Lint/AmbiguousRange: + Enabled: true +Lint/ArrayLiteralInRegexp: + Enabled: true +Lint/ConstantOverwrittenInRescue: + Enabled: true +Lint/ConstantReassignment: + Enabled: true +Lint/CopDirectiveSyntax: + Enabled: true +Lint/DeprecatedConstants: + Enabled: true +Lint/DuplicateBranch: + Enabled: true +Lint/DuplicateMagicComment: + Enabled: true +Lint/DuplicateMatchPattern: + Enabled: true +Lint/DuplicateRegexpCharacterClassElement: + Enabled: true +Lint/DuplicateSetElement: + Enabled: true +Lint/EmptyBlock: + Enabled: true +Lint/EmptyClass: + AllowComments: true + Enabled: true +Lint/EmptyInPattern: + Enabled: true +Lint/HashNewWithKeywordArgumentsAsDefault: + Enabled: true +Lint/IncompatibleIoSelectWithFiberScheduler: + Enabled: true +Lint/ItWithoutArgumentsInBlock: + Enabled: true +Lint/LambdaWithoutLiteralBlock: + Enabled: true +Lint/LiteralAssignmentInCondition: + Enabled: true +Lint/MixedCaseRange: + Enabled: true +Lint/NonAtomicFileOperation: + Enabled: true +Lint/NoReturnInBeginEndBlocks: + Enabled: true +Lint/NumberedParameterAssignment: + Enabled: true +Lint/NumericOperationWithConstantResult: + Enabled: true +Lint/OrAssignmentToConstant: + Enabled: true +Lint/RedundantDirGlobSort: + Enabled: true +Lint/RedundantRegexpQuantifiers: + Enabled: true +Lint/RedundantTypeConversion: + Enabled: true +Lint/RefinementImportMethods: + Enabled: true +Lint/RequireRangeParentheses: + Enabled: true +Lint/RequireRelativeSelfPath: + Enabled: true +Lint/SharedMutableDefault: + Enabled: true +Lint/SuppressedExceptionInNumberConversion: + Enabled: true +Lint/SymbolConversion: + Enabled: true +Lint/ToEnumArguments: + Enabled: true +Lint/TripleQuotes: + Enabled: true +Lint/UnescapedBracketInRegexp: + Enabled: true +Lint/UnexpectedBlockArity: + Enabled: true +Lint/UnmodifiedReduceAccumulator: + Enabled: true Lint/UnusedMethodArgument: Exclude: - "lib/cloud_events/format.rb" +Lint/UselessConstantScoping: + Enabled: true +Lint/UselessDefaultValueArgument: + Enabled: true +Lint/UselessDefined: + Enabled: true +Lint/UselessNumericOperation: + Enabled: true +Lint/UselessOr: + Enabled: true +Lint/UselessRescue: + Enabled: true +Lint/UselessRuby2Keywords: + Enabled: true + +Metrics/AbcSize: + Max: 30 Metrics/BlockLength: Exclude: - "test/**/test_*.rb" Metrics/ClassLength: Max: 300 +Metrics/CollectionLiteralLength: + Enabled: true +Metrics/CyclomaticComplexity: + Max: 12 +Metrics/MethodLength: + Max: 25 Metrics/ModuleLength: Max: 300 -Naming/FileName: - Exclude: - - "examples/*/Gemfile" - - ".toys/**/*.rb" +Metrics/ParameterLists: + Enabled: false +Metrics/PerceivedComplexity: + Max: 12 + +Naming/BlockForwarding: + Enabled: true +Naming/PredicateMethod: + Enabled: true + +Security/CompoundHash: + Enabled: true +Security/IoMethods: + Enabled: true + +Style/AccessorGrouping: + Enabled: false +Style/AmbiguousEndlessMethodDefinition: + Enabled: true +Style/ArgumentsForwarding: + Enabled: true +Style/ArrayIntersect: + Enabled: true +Style/ArrayIntersectWithSingleElement: + Enabled: true +Style/BisectedAttrAccessor: + Enabled: false +Style/BitwisePredicate: + Enabled: true +Style/CaseEquality: + Enabled: false +Style/CollectionCompact: + Enabled: true +Style/CollectionQuerying: + Enabled: true +Style/CombinableDefined: + Enabled: true +Style/ComparableBetween: + Enabled: false +Style/ComparableClamp: + Enabled: true +Style/ConcatArrayLiterals: + Enabled: true +Style/DataInheritance: + Enabled: true +Style/DigChain: + Enabled: true +Style/DirEmpty: + Enabled: true +Style/DocumentDynamicEvalDefinition: + Enabled: true +Style/DocumentationMethod: + Enabled: false +Style/EmptyHeredoc: + Enabled: true +Style/EmptyStringInsideInterpolation: + Enabled: true +Style/EndlessMethod: + Enabled: true +Style/EnvHome: + Enabled: true +Style/ExactRegexpMatch: + Enabled: true +Style/FetchEnvVar: + Enabled: true +Style/FileEmpty: + Enabled: true +Style/FileNull: + Enabled: true +Style/FileRead: + Enabled: true +Style/FileTouch: + Enabled: true +Style/FileWrite: + Enabled: true +Style/GuardClause: + Enabled: false +Style/HashConversion: + Enabled: true +Style/HashExcept: + Enabled: true +Style/HashFetchChain: + Enabled: true +Style/HashSlice: + Enabled: true +Style/IfUnlessModifier: + Enabled: false +Style/IfWithBooleanLiteralBranches: + Enabled: true +Style/InPatternThen: + Enabled: true +Style/ItAssignment: + Enabled: true +Style/ItBlockParameter: + Enabled: true +Style/KeywordArgumentsMerging: + Enabled: true +Style/MagicCommentFormat: + Enabled: true +Style/MapCompactWithConditionalBlock: + Enabled: true +Style/MapIntoArray: + Enabled: true +Style/MapToHash: + Enabled: true +Style/MapToSet: + Enabled: true +Style/MethodCallWithArgsParentheses: + Enabled: true +Style/MinMaxComparison: + Enabled: true +Style/MultilineInPatternThen: + Enabled: true +Style/NegatedIfElseCondition: + Enabled: true +Style/Next: + Enabled: false +Style/NestedFileDirname: + Enabled: true +Style/NilLambda: + Enabled: true +Style/NumberedParameters: + Enabled: true +Style/NumberedParametersLimit: + Enabled: true +Style/ObjectThen: + Enabled: true +Style/OpenStructUse: + Enabled: true +Style/OperatorMethodCall: + Enabled: true +Style/OptionalBooleanParameter: + Enabled: false +Style/QuotedSymbols: + Enabled: true +Style/RedundantArgument: + Enabled: true +Style/RedundantArrayConstructor: + Enabled: true +Style/RedundantArrayFlatten: + Enabled: true +Style/RedundantConstantBase: + Enabled: false +Style/RedundantCurrentDirectoryInPath: + Enabled: true +Style/RedundantDoubleSplatHashBraces: + Enabled: true +Style/RedundantEach: + Enabled: true +Style/RedundantFilterChain: + Enabled: true +Style/RedundantFormat: + Enabled: true +Style/RedundantHeredocDelimiterQuotes: + Enabled: true +Style/RedundantInitialize: + Enabled: true +Style/RedundantInterpolationUnfreeze: + Enabled: true +Style/RedundantLineContinuation: + Enabled: true +Style/RedundantRegexpArgument: + Enabled: true +Style/RedundantRegexpConstructor: + Enabled: true +Style/RedundantSelfAssignmentBranch: + Enabled: true +Style/RedundantStringEscape: + Enabled: true +Style/RescueModifier: + Enabled: false +Style/ReturnNilInPredicateMethodDefinition: + Enabled: true +Style/SafeNavigationChainLength: + Enabled: true +Style/SelectByRegexp: + Enabled: true +Style/SendWithLiteralMethodName: + Enabled: true +Style/SingleLineDoEndBlock: + Enabled: true +Style/SoleNestedConditional: + Enabled: false +Style/StringChars: + Enabled: true +Style/StringLiterals: + EnforcedStyle: double_quotes +Style/SuperArguments: + Enabled: true +Style/SuperWithArgsParentheses: + Enabled: true +Style/SwapValues: + Enabled: true +Style/SymbolArray: + EnforcedStyle: brackets +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma +Style/WhileUntilModifier: + Enabled: false +Style/WordArray: + EnforcedStyle: brackets +Style/YAMLFileRead: + Enabled: true diff --git a/Gemfile b/Gemfile index 4572311..974f566 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,14 @@ +# frozen_string_literal: true + source "https://rubygems.org" gemspec gem "cucumber", "~> 9.2" -gem "google-style", "~> 1.27.1" gem "minitest", "~> 5.25" gem "minitest-focus", "~> 1.4" gem "minitest-rg", "~> 5.3" gem "rack", "~> 3.2" gem "redcarpet", "~> 3.6" unless ::RUBY_PLATFORM == "java" +gem "rubocop", "~> 1.81" gem "webrick", "~> 1.9" gem "yard", "~> 0.9.37" diff --git a/cloud_events.gemspec b/cloud_events.gemspec index 703c5f1..783e49f 100644 --- a/cloud_events.gemspec +++ b/cloud_events.gemspec @@ -21,7 +21,7 @@ version = ::CloudEvents::VERSION spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.7" - if spec.respond_to? :metadata + if spec.respond_to?(:metadata) spec.metadata["changelog_uri"] = "https://cloudevents.github.io/sdk-ruby/v#{version}/file.CHANGELOG.html" spec.metadata["source_code_uri"] = "https://github.com/cloudevents/sdk-ruby" spec.metadata["bug_tracker_uri"] = "https://github.com/cloudevents/sdk-ruby/issues" diff --git a/examples/client/Gemfile b/examples/client/Gemfile index 29160b0..d65f423 100644 --- a/examples/client/Gemfile +++ b/examples/client/Gemfile @@ -1,2 +1,4 @@ +# frozen_string_literal: true + source "https://rubygems.org" gem "cloud_events", path: "../.." diff --git a/examples/client/send.rb b/examples/client/send.rb index dacf27d..e313e85 100644 --- a/examples/client/send.rb +++ b/examples/client/send.rb @@ -1,16 +1,19 @@ +# frozen_string_literal: true + require "cloud_events" require "net/http" require "uri" data = { message: "Hello, CloudEvents!" } -event = CloudEvents::Event.create \ +event = CloudEvents::Event.create( spec_version: "1.0", id: "1234-1234-1234", source: "/mycontext", type: "com.example.someevent", data_content_type: "application/json", data: data +) cloud_events_http = CloudEvents::HttpBinding.default -headers, body = cloud_events_http.encode_event event -Net::HTTP.post URI("http://localhost:4567"), body, headers +headers, body = cloud_events_http.encode_event(event) +Net::HTTP.post(URI("http://localhost:4567"), body, headers) diff --git a/examples/server/Gemfile b/examples/server/Gemfile index 577c156..a700603 100644 --- a/examples/server/Gemfile +++ b/examples/server/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" gem "cloud_events", path: "../.." gem "sinatra", "~> 2.0" diff --git a/examples/server/app.rb b/examples/server/app.rb index 2a54118..33a5f8b 100644 --- a/examples/server/app.rb +++ b/examples/server/app.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require "sinatra" require "cloud_events" cloud_events_http = CloudEvents::HttpBinding.default post "/" do - event = cloud_events_http.decode_event request.env - logger.info "Received CloudEvent: #{event.to_h}" + event = cloud_events_http.decode_event(request.env) + logger.info("Received CloudEvent: #{event.to_h}") end diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb index 502138b..931b462 100644 --- a/features/step_definitions/steps.rb +++ b/features/step_definitions/steps.rb @@ -11,11 +11,11 @@ Given "an HTTP request" do |str| # WEBrick parsing wants the lines delimited by \r\n, but the input # content-length assumes \n within the body. - parts = str.split "\n\n" - parts[0].gsub! "\n", "\r\n" + parts = str.split("\n\n") + parts[0].gsub!("\n", "\r\n") str = "#{parts[0]}\r\n\r\n#{parts[1]}" - webrick_request = WEBrick::HTTPRequest.new WEBrick::Config::HTTP - webrick_request.parse StringIO.new str + webrick_request = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP) + webrick_request.parse(StringIO.new(str)) @rack_request = {} @rack_request[Rack::REQUEST_METHOD] = webrick_request.request_method @rack_request[Rack::SCRIPT_NAME] = webrick_request.script_name @@ -25,17 +25,17 @@ @rack_request[Rack::SERVER_PORT] = webrick_request.port @rack_request[Rack::RACK_VERSION] = Rack::VERSION @rack_request[Rack::RACK_URL_SCHEME] = webrick_request.ssl? ? "https" : "http" - @rack_request[Rack::RACK_INPUT] = StringIO.new webrick_request.body + @rack_request[Rack::RACK_INPUT] = StringIO.new(webrick_request.body) @rack_request[Rack::RACK_ERRORS] = StringIO.new webrick_request.each do |key, value| - key = key.upcase.tr "-", "_" + key = key.upcase.tr("-", "_") key = "HTTP_#{key}" unless key == "CONTENT_TYPE" @rack_request[key] = value end end When "parsed as HTTP request" do - @event = @http_binding.decode_event @rack_request + @event = @http_binding.decode_event(@rack_request) end Then "the attributes are:" do |table| @@ -45,7 +45,7 @@ end Then "the data is equal to the following JSON:" do |str| - json = JSON.parse str + json = JSON.parse(str) assert_equal json, @event.data end diff --git a/features/support/env.rb b/features/support/env.rb index 1510738..d792334 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1,3 +1,5 @@ -dir = ::File.expand_path "../../lib", __dir__ -$LOAD_PATH.unshift dir unless $LOAD_PATH.include? dir +# frozen_string_literal: true + +dir = ::File.expand_path("../../lib", __dir__) +$LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) require "cloud_events" diff --git a/lib/cloud_events/content_type.rb b/lib/cloud_events/content_type.rb index e7bcc26..6e20736 100644 --- a/lib/cloud_events/content_type.rb +++ b/lib/cloud_events/content_type.rb @@ -24,7 +24,7 @@ class ContentType # @param default_charset [String] Optional. The charset to use if none is # specified. Defaults to `us-ascii`. # - def initialize string, default_charset: nil + def initialize(string, default_charset: nil) @string = string.to_s @media_type = "text" @subtype_base = @subtype = "plain" @@ -32,9 +32,9 @@ def initialize string, default_charset: nil @params = [] @charset = default_charset || "us-ascii" @error_message = nil - parse consume_comments @string.strip + parse(consume_comments(@string.strip)) @canonical_string = "#{@media_type}/#{@subtype}" + - @params.map { |k, v| "; #{k}=#{maybe_quote v}" }.join + @params.map { |k, v| "; #{k}=#{maybe_quote(v)}" }.join full_freeze end @@ -102,13 +102,13 @@ def initialize string, default_charset: nil # @param key [String] # @return [Array] # - def param_values key + def param_values(key) key = key.downcase @params.inject([]) { |a, (k, v)| key == k ? a << v : a } end ## @private - def == other + def ==(other) other.is_a?(ContentType) && canonical_string == other.canonical_string end alias eql? == @@ -124,16 +124,16 @@ class ParseError < ::StandardError private - def parse str - @media_type, str = consume_token str, downcase: true, error_message: "Failed to parse media type" - str = consume_special str, "/" - @subtype, str = consume_token str, downcase: true, error_message: "Failed to parse subtype" - @subtype_base, @subtype_format = @subtype.split "+", 2 + def parse(str) + @media_type, str = consume_token(str, downcase: true, error_message: "Failed to parse media type") + str = consume_special(str, "/") + @subtype, str = consume_token(str, downcase: true, error_message: "Failed to parse subtype") + @subtype_base, @subtype_format = @subtype.split("+", 2) until str.empty? - str = consume_special str, ";" - name, str = consume_token str, downcase: true, error_message: "Faled to parse attribute name" - str = consume_special str, "=", error_message: "Failed to find value for attribute #{name}" - val, str = consume_token_or_quoted str, error_message: "Failed to parse value for attribute #{name}" + str = consume_special(str, ";") + name, str = consume_token(str, downcase: true, error_message: "Faled to parse attribute name") + str = consume_special(str, "=", error_message: "Failed to find value for attribute #{name}") + val, str = consume_token_or_quoted(str, error_message: "Failed to parse value for attribute #{name}") @params << [name, val] @charset = val if name == "charset" end @@ -141,34 +141,34 @@ def parse str @error_message = e.message end - def consume_token str, downcase: false, error_message: nil - match = /^([\w!#$%&'*+.\^`{|}-]+)(.*)$/.match str - raise ParseError, error_message || "Expected token" unless match + def consume_token(str, downcase: false, error_message: nil) + match = /^([\w!#$%&'*+.\^`{|}-]+)(.*)$/.match(str) + raise(ParseError, error_message || "Expected token") unless match token = match[1] token.downcase! if downcase - str = consume_comments match[2].strip + str = consume_comments(match[2].strip) [token, str] end - def consume_special str, expected, error_message: nil - raise ParseError, error_message || "Expected #{expected.inspect}" unless str.start_with? expected - consume_comments str[1..].strip + def consume_special(str, expected, error_message: nil) + raise(ParseError, error_message || "Expected #{expected.inspect}") unless str.start_with?(expected) + consume_comments(str[1..].strip) end - def consume_token_or_quoted str, error_message: nil - return consume_token str unless str.start_with? '"' + def consume_token_or_quoted(str, error_message: nil) + return consume_token(str) unless str.start_with?('"') arr = [] index = 1 loop do char = str[index] case char when nil - raise ParseError, error_message || "Quoted-string never finished" + raise(ParseError, error_message || "Quoted-string never finished") when "\"" break when "\\" char = str[index + 1] - raise ParseError, error_message || "Quoted-string never finished" unless char + raise(ParseError, error_message || "Quoted-string never finished") unless char arr << char index += 2 else @@ -177,34 +177,34 @@ def consume_token_or_quoted str, error_message: nil end end index += 1 - str = consume_comments str[index..].strip + str = consume_comments(str[index..].strip) [arr.join, str] end - def consume_comments str - return str unless str.start_with? "(" + def consume_comments(str) + return str unless str.start_with?("(") index = 1 loop do char = str[index] case char when nil - raise ParseError, "Comment never finished" + raise(ParseError, "Comment never finished") when ")" break when "\\" index += 2 when "(" - str = consume_comments str[index..] + str = consume_comments(str[index..]) index = 0 else index += 1 end end index += 1 - consume_comments str[index..].strip + consume_comments(str[index..].strip) end - def maybe_quote str + def maybe_quote(str) return str if /^[\w!#$%&'*+.\^`{|}-]+$/ =~ str str = str.gsub("\\", "\\\\\\\\").gsub("\"", "\\\\\"") "\"#{str}\"" diff --git a/lib/cloud_events/event.rb b/lib/cloud_events/event.rb index 60cad32..986cc02 100644 --- a/lib/cloud_events/event.rb +++ b/lib/cloud_events/event.rb @@ -61,11 +61,11 @@ class << self def create spec_version:, **kwargs case spec_version when "0.3" - V0.new spec_version: spec_version, **kwargs + V0.new(spec_version: spec_version, **kwargs) when /^1(\.|$)/ - V1.new spec_version: spec_version, **kwargs + V1.new(spec_version: spec_version, **kwargs) else - raise SpecVersionError, "Unrecognized specversion: #{spec_version}" + raise(SpecVersionError, "Unrecognized specversion: #{spec_version}") end end alias new create diff --git a/lib/cloud_events/event/field_interpreter.rb b/lib/cloud_events/event/field_interpreter.rb index c6323be..1b28986 100644 --- a/lib/cloud_events/event/field_interpreter.rb +++ b/lib/cloud_events/event/field_interpreter.rb @@ -9,8 +9,8 @@ module Event # @private # class FieldInterpreter - def initialize args - @args = Utils.keys_to_strings args + def initialize(args) + @args = Utils.keys_to_strings(args) @attributes = {} end @@ -22,47 +22,47 @@ def finish_attributes @attributes.freeze end - def string keys, required: false, allow_empty: false - object keys, required: required do |value| + def string(keys, required: false, allow_empty: false) + object(keys, required: required) do |value| case value when ::String - raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty? && !allow_empty + raise(AttributeError, "The #{keys.first} field cannot be empty") if value.empty? && !allow_empty value.freeze [value, value] else - raise AttributeError, "Illegal type for #{keys.first}: " \ - "String expected but #{value.class} found" + raise(AttributeError, "Illegal type for #{keys.first}: " \ + "String expected but #{value.class} found") end end end - def uri keys, required: false - object keys, required: required do |value| + def uri(keys, required: false) + object(keys, required: required) do |value| case value when ::String - raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty? + raise(AttributeError, "The #{keys.first} field cannot be empty") if value.empty? begin [Utils.deep_freeze(::URI.parse(value)), value.freeze] rescue ::URI::InvalidURIError => e - raise AttributeError, "Illegal format for #{keys.first}: #{e.message}" + raise(AttributeError, "Illegal format for #{keys.first}: #{e.message}") end when ::URI::Generic [Utils.deep_freeze(value), value.to_s.freeze] else - raise AttributeError, "Illegal type for #{keys.first}: " \ - "String or URI expected but #{value.class} found" + raise(AttributeError, "Illegal type for #{keys.first}: " \ + "String or URI expected but #{value.class} found") end end end - def rfc3339_date_time keys, required: false - object keys, required: required do |value| + def rfc3339_date_time(keys, required: false) + object(keys, required: required) do |value| case value when ::String begin [Utils.deep_freeze(::DateTime.rfc3339(value)), value.freeze] rescue ::Date::Error => e - raise AttributeError, "Illegal format for #{keys.first}: #{e.message}" + raise(AttributeError, "Illegal format for #{keys.first}: #{e.message}") end when ::DateTime [Utils.deep_freeze(value), value.rfc3339.freeze] @@ -70,44 +70,44 @@ def rfc3339_date_time keys, required: false value = value.to_datetime [Utils.deep_freeze(value), value.rfc3339.freeze] else - raise AttributeError, "Illegal type for #{keys.first}: " \ - "String, Time, or DateTime expected but #{value.class} found" + raise(AttributeError, "Illegal type for #{keys.first}: " \ + "String, Time, or DateTime expected but #{value.class} found") end end end - def content_type keys, required: false - object keys, required: required do |value| + def content_type(keys, required: false) + object(keys, required: required) do |value| case value when ::String - raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty? + raise(AttributeError, "The #{keys.first} field cannot be empty") if value.empty? [ContentType.new(value), value.freeze] when ContentType [value, value.to_s] else - raise AttributeError, "Illegal type for #{keys.first}: " \ - "String, or ContentType expected but #{value.class} found" + raise(AttributeError, "Illegal type for #{keys.first}: " \ + "String, or ContentType expected but #{value.class} found") end end end - def spec_version keys, accept: - object keys, required: true do |value| + def spec_version(keys, accept:) + object(keys, required: true) do |value| case value when ::String - raise SpecVersionError, "Unrecognized specversion: #{value}" unless accept =~ value + raise(SpecVersionError, "Unrecognized specversion: #{value}") unless accept =~ value value.freeze [value, value] else - raise AttributeError, "Illegal type for #{keys.first}: " \ - "String expected but #{value.class} found" + raise(AttributeError, "Illegal type for #{keys.first}: " \ + "String expected but #{value.class} found") end end end - def data_object keys, required: false - object keys, required: required, allow_nil: true do |value| - Utils.deep_freeze value + def data_object(keys, required: false) + object(keys, required: required, allow_nil: true) do |value| + Utils.deep_freeze(value) [value, value] end end @@ -116,18 +116,18 @@ def data_object keys, required: false private - def object keys, required: false, allow_nil: false + def object(keys, required: false, allow_nil: false) value = UNDEFINED keys.each do |key| - key_present = @args.key? key - val = @args.delete key + key_present = @args.key?(key) + val = @args.delete(key) value = val if (allow_nil && key_present) || (!allow_nil && !val.nil?) end if value == UNDEFINED - raise AttributeError, "The #{keys.first} field is required" if required + raise(AttributeError, "The #{keys.first} field is required") if required return allow_nil ? UNDEFINED : nil end - converted, raw = yield value + converted, raw = yield(value) @attributes[keys.first.freeze] = raw converted end diff --git a/lib/cloud_events/event/opaque.rb b/lib/cloud_events/event/opaque.rb index a8f38b1..aa05bfe 100644 --- a/lib/cloud_events/event/opaque.rb +++ b/lib/cloud_events/event/opaque.rb @@ -24,7 +24,7 @@ class Opaque # or not provided, the value will be inferred from the content type # if possible, or otherwise set to `nil` indicating not known. # - def initialize content, content_type, batch: nil + def initialize(content, content_type, batch: nil) @content = content.freeze @content_type = content_type if batch.nil? && content_type&.media_type == "application" @@ -63,7 +63,7 @@ def batch? end ## @private - def == other + def ==(other) Opaque === other && @content == other.content && @content_type == other.content_type && diff --git a/lib/cloud_events/event/utils.rb b/lib/cloud_events/event/utils.rb index 0711062..f48c266 100644 --- a/lib/cloud_events/event/utils.rb +++ b/lib/cloud_events/event/utils.rb @@ -8,37 +8,37 @@ module Event # module Utils class << self - def deep_freeze obj + def deep_freeze(obj) case obj when ::Hash obj.each do |key, val| - deep_freeze key - deep_freeze val + deep_freeze(key) + deep_freeze(val) end when ::Array obj.each do |val| - deep_freeze val + deep_freeze(val) end else obj.instance_variables.each do |iv| - deep_freeze obj.instance_variable_get iv + deep_freeze(obj.instance_variable_get(iv)) end end obj.freeze end - def deep_dup obj + def deep_dup(obj) case obj when ::Hash - obj.each_with_object({}) { |(key, val), hash| hash[deep_dup key] = deep_dup val } + obj.each_with_object({}) { |(key, val), hash| hash[deep_dup(key)] = deep_dup(val) } when ::Array - obj.map { |val| deep_dup val } + obj.map { |val| deep_dup(val) } else obj.dup end end - def keys_to_strings hash + def keys_to_strings(hash) result = {} hash.each do |key, val| result[key.to_s] = val diff --git a/lib/cloud_events/event/v0.rb b/lib/cloud_events/event/v0.rb index 3d7ddca..c306a93 100644 --- a/lib/cloud_events/event/v0.rb +++ b/lib/cloud_events/event/v0.rb @@ -76,18 +76,18 @@ class V0 # @param args [keywords] The data and attributes, as keyword arguments. # def initialize set_attributes: nil, attributes: nil, **args - interpreter = FieldInterpreter.new set_attributes || attributes || args - @spec_version = interpreter.spec_version ["specversion", "spec_version"], accept: /^0\.3$/ - @id = interpreter.string ["id"], required: true - @source = interpreter.uri ["source"], required: true - @type = interpreter.string ["type"], required: true - @data = interpreter.data_object ["data"] + interpreter = FieldInterpreter.new(set_attributes || attributes || args) + @spec_version = interpreter.spec_version(["specversion", "spec_version"], accept: /^0\.3$/) + @id = interpreter.string(["id"], required: true) + @source = interpreter.uri(["source"], required: true) + @type = interpreter.string(["type"], required: true) + @data = interpreter.data_object(["data"]) @data = nil if @data == FieldInterpreter::UNDEFINED - @data_content_encoding = interpreter.string ["datacontentencoding", "data_content_encoding"] - @data_content_type = interpreter.content_type ["datacontenttype", "data_content_type"] - @schema_url = interpreter.uri ["schemaurl", "schema_url"] - @subject = interpreter.string ["subject"] - @time = interpreter.rfc3339_date_time ["time"] + @data_content_encoding = interpreter.string(["datacontentencoding", "data_content_encoding"]) + @data_content_type = interpreter.content_type(["datacontenttype", "data_content_type"]) + @schema_url = interpreter.uri(["schemaurl", "schema_url"]) + @subject = interpreter.string(["subject"]) + @time = interpreter.rfc3339_date_time(["time"]) @attributes = interpreter.finish_attributes freeze end @@ -102,8 +102,8 @@ def initialize set_attributes: nil, attributes: nil, **args # @return [FunctionFramework::CloudEvents::Event] # def with **changes - attributes = @attributes.merge changes - V0.new set_attributes: attributes + attributes = @attributes.merge(changes) + V0.new(set_attributes: attributes) end ## @@ -125,7 +125,7 @@ def with **changes # @param key [String,Symbol] The attribute name. # @return [String,nil] # - def [] key + def [](key) @attributes[key.to_s] end @@ -136,7 +136,7 @@ def [] key # @return [Hash] # def to_h - Utils.deep_dup @attributes + Utils.deep_dup(@attributes) end ## @@ -225,7 +225,7 @@ def to_h attr_reader :time ## @private - def == other + def ==(other) other.is_a?(V0) && @attributes == other.instance_variable_get(:@attributes) end alias eql? == diff --git a/lib/cloud_events/event/v1.rb b/lib/cloud_events/event/v1.rb index 6480c35..0f4ed2b 100644 --- a/lib/cloud_events/event/v1.rb +++ b/lib/cloud_events/event/v1.rb @@ -137,23 +137,23 @@ class V1 # @param args [keywords] The data and attributes, as keyword arguments. # def initialize set_attributes: nil, attributes: nil, **args - interpreter = FieldInterpreter.new set_attributes || attributes || args - @spec_version = interpreter.spec_version ["specversion", "spec_version"], accept: /^1(\.|$)/ - @id = interpreter.string ["id"], required: true - @source = interpreter.uri ["source"], required: true - @type = interpreter.string ["type"], required: true - @data_encoded = interpreter.string ["data_encoded"], allow_empty: true - @data = interpreter.data_object ["data"] + interpreter = FieldInterpreter.new(set_attributes || attributes || args) + @spec_version = interpreter.spec_version(["specversion", "spec_version"], accept: /^1(\.|$)/) + @id = interpreter.string(["id"], required: true) + @source = interpreter.uri(["source"], required: true) + @type = interpreter.string(["type"], required: true) + @data_encoded = interpreter.string(["data_encoded"], allow_empty: true) + @data = interpreter.data_object(["data"]) if @data == FieldInterpreter::UNDEFINED @data = @data_encoded @data_decoded = false else @data_decoded = true end - @data_content_type = interpreter.content_type ["datacontenttype", "data_content_type"] - @data_schema = interpreter.uri ["dataschema", "data_schema"] - @subject = interpreter.string ["subject"] - @time = interpreter.rfc3339_date_time ["time"] + @data_content_type = interpreter.content_type(["datacontenttype", "data_content_type"]) + @data_schema = interpreter.uri(["dataschema", "data_schema"]) + @subject = interpreter.string(["subject"]) + @time = interpreter.rfc3339_date_time(["time"]) @attributes = interpreter.finish_attributes freeze end @@ -168,14 +168,14 @@ def initialize set_attributes: nil, attributes: nil, **args # @return [FunctionFramework::CloudEvents::Event] # def with **changes - changes = Utils.keys_to_strings changes + changes = Utils.keys_to_strings(changes) attributes = @attributes.dup if changes.key?("data") || changes.key?("data_encoded") - attributes.delete "data" - attributes.delete "data_encoded" + attributes.delete("data") + attributes.delete("data_encoded") end - attributes.merge! changes - V1.new set_attributes: attributes + attributes.merge!(changes) + V1.new(set_attributes: attributes) end ## @@ -197,7 +197,7 @@ def with **changes # @param key [String,Symbol] The attribute name. # @return [String,nil] # - def [] key + def [](key) @attributes[key.to_s] end @@ -208,7 +208,7 @@ def [] key # @return [Hash] # def to_h - Utils.deep_dup @attributes + Utils.deep_dup(@attributes) end ## @@ -330,7 +330,7 @@ def data? attr_reader :time ## @private - def == other + def ==(other) other.is_a?(V1) && @attributes == other.instance_variable_get(:@attributes) end alias eql? == diff --git a/lib/cloud_events/format.rb b/lib/cloud_events/format.rb index 550552c..31ee655 100644 --- a/lib/cloud_events/format.rb +++ b/lib/cloud_events/format.rb @@ -212,7 +212,7 @@ class Multi # format's result as an argument, and returns either the result to # indicate acceptability, or `nil` to indicate not. # - def initialize formats = [], &result_checker + def initialize(formats = [], &result_checker) @formats = formats @result_checker = result_checker end @@ -230,7 +230,7 @@ def initialize formats = [], &result_checker def decode_event **kwargs @formats.each do |elem| result = elem.decode_event(**kwargs) - result = @result_checker.call result if @result_checker + result = @result_checker.call(result) if @result_checker return result if result end nil @@ -242,7 +242,7 @@ def decode_event **kwargs def encode_event **kwargs @formats.each do |elem| result = elem.encode_event(**kwargs) - result = @result_checker.call result if @result_checker + result = @result_checker.call(result) if @result_checker return result if result end nil @@ -254,7 +254,7 @@ def encode_event **kwargs def decode_data **kwargs @formats.each do |elem| result = elem.decode_data(**kwargs) - result = @result_checker.call result if @result_checker + result = @result_checker.call(result) if @result_checker return result if result end nil @@ -266,7 +266,7 @@ def decode_data **kwargs def encode_data **kwargs @formats.each do |elem| result = elem.encode_data(**kwargs) - result = @result_checker.call result if @result_checker + result = @result_checker.call(result) if @result_checker return result if result end nil diff --git a/lib/cloud_events/http_binding.rb b/lib/cloud_events/http_binding.rb index eeba6d4..03e0fc2 100644 --- a/lib/cloud_events/http_binding.rb +++ b/lib/cloud_events/http_binding.rb @@ -31,7 +31,7 @@ class HttpBinding def self.default @default ||= begin http_binding = new - http_binding.register_formatter JsonFormat.new, encoder_name: JSON_FORMAT + http_binding.register_formatter(JsonFormat.new, encoder_name: JSON_FORMAT) http_binding.default_encoder_name = JSON_FORMAT http_binding end @@ -52,8 +52,8 @@ def initialize result&.key?(:content) && result.key?(:content_type) ? result : nil end text_format = TextFormat.new - @data_decoders.formats.replace [text_format, DefaultDataFormat] - @data_encoders.formats.replace [text_format, DefaultDataFormat] + @data_decoders.formats.replace([text_format, DefaultDataFormat]) + @data_encoders.formats.replace([text_format, DefaultDataFormat]) @default_encoder_name = nil end @@ -71,18 +71,18 @@ def initialize # and will be removed in version 1.0. Use encoder_name instead. # @return [self] # - def register_formatter formatter, deprecated_name = nil, encoder_name: nil + def register_formatter(formatter, deprecated_name = nil, encoder_name: nil) encoder_name ||= deprecated_name encoder_name = encoder_name.to_s.strip.downcase if encoder_name - decode_event = formatter.respond_to? :decode_event - encode_event = encoder_name if formatter.respond_to? :encode_event - decode_data = formatter.respond_to? :decode_data - encode_data = formatter.respond_to? :encode_data - register_formatter_methods formatter, + decode_event = formatter.respond_to?(:decode_event) + encode_event = encoder_name if formatter.respond_to?(:encode_event) + decode_data = formatter.respond_to?(:decode_data) + encode_data = formatter.respond_to?(:encode_data) + register_formatter_methods(formatter, decode_event: decode_event, encode_event: encode_event, decode_data: decode_data, - encode_data: encode_data + encode_data: encode_data) self end @@ -102,20 +102,20 @@ def register_formatter formatter, deprecated_name = nil, encoder_name: nil # {CloudEvents::Format#encode_data} method. # @return [self] # - def register_formatter_methods formatter, + def register_formatter_methods(formatter, decode_event: false, encode_event: nil, decode_data: false, - encode_data: false - @event_decoders.formats.unshift formatter if decode_event + encode_data: false) + @event_decoders.formats.unshift(formatter) if decode_event if encode_event encoders = @event_encoders[encode_event] ||= Format::Multi.new do |result| result&.key?(:content) && result.key?(:content_type) ? result : nil end - encoders.formats.unshift formatter + encoders.formats.unshift(formatter) end - @data_decoders.formats.unshift formatter if decode_data - @data_encoders.formats.unshift formatter if encode_data + @data_decoders.formats.unshift(formatter) if decode_data + @data_encoders.formats.unshift(formatter) if encode_data self end @@ -136,10 +136,10 @@ def register_formatter_methods formatter, # @param env [Hash] The Rack environment. # @return [boolean] Whether the request is likely a CloudEvent. # - def probable_event? env - return false if ILLEGAL_METHODS.include? env["REQUEST_METHOD"] + def probable_event?(env) + return false if ILLEGAL_METHODS.include?(env["REQUEST_METHOD"]) return true if env["HTTP_CE_SPECVERSION"] - content_type = ContentType.new env["CONTENT_TYPE"].to_s + content_type = ContentType.new(env["CONTENT_TYPE"].to_s) content_type.media_type == "application" && ["cloudevents", "cloudevents-batch"].include?(content_type.subtype_base) end @@ -168,15 +168,15 @@ def probable_event? env # def decode_event env, allow_opaque: false, **format_args request_method = env["REQUEST_METHOD"] - raise NotCloudEventError, "Request method is #{request_method}" if ILLEGAL_METHODS.include? request_method + raise(NotCloudEventError, "Request method is #{request_method}") if ILLEGAL_METHODS.include?(request_method) content_type_string = env["CONTENT_TYPE"] - content_type = ContentType.new content_type_string if content_type_string - content = read_with_charset env["rack.input"], content_type&.charset + content_type = ContentType.new(content_type_string) if content_type_string + content = read_with_charset(env["rack.input"], content_type&.charset) result = decode_binary_content(content, content_type, env, false, **format_args) || decode_structured_content(content, content_type, allow_opaque, **format_args) if result.nil? content_type_string = content_type_string ? content_type_string.inspect : "not present" - raise NotCloudEventError, "Content-Type is #{content_type_string}, and CE-SpecVersion is not present" + raise(NotCloudEventError, "Content-Type is #{content_type_string}, and CE-SpecVersion is not present") end result end @@ -205,23 +205,23 @@ def decode_event env, allow_opaque: false, **format_args # @return [Array(headers,String)] # def encode_event event, structured_format: false, **format_args - if event.is_a? Event::Opaque + if event.is_a?(Event::Opaque) [{ "Content-Type" => event.content_type.to_s }, event.content] elsif !structured_format - if event.is_a? ::Array - raise ::ArgumentError, "Encoding a batch requires structured_format" + if event.is_a?(::Array) + raise(::ArgumentError, "Encoding a batch requires structured_format") end - encode_binary_content event, legacy_data_encode: false, **format_args + encode_binary_content(event, legacy_data_encode: false, **format_args) else structured_format = default_encoder_name if structured_format == true - raise ::ArgumentError, "Format name not specified, and no default is set" unless structured_format + raise(::ArgumentError, "Format name not specified, and no default is set") unless structured_format case event when ::Array - encode_batched_content event, structured_format, **format_args + encode_batched_content(event, structured_format, **format_args) when Event - encode_structured_content event, structured_format, **format_args + encode_structured_content(event, structured_format, **format_args) else - raise ::ArgumentError, "Unknown event type: #{event.class}" + raise(::ArgumentError, "Unknown event type: #{event.class}") end end end @@ -245,8 +245,8 @@ def encode_event event, structured_format: false, **format_args # def decode_rack_env env, **format_args content_type_string = env["CONTENT_TYPE"] - content_type = ContentType.new content_type_string if content_type_string - content = read_with_charset env["rack.input"], content_type&.charset + content_type = ContentType.new(content_type_string) if content_type_string + content = read_with_charset(env["rack.input"], content_type&.charset) env["rack.input"].rewind rescue nil decode_binary_content(content, content_type, env, true, **format_args) || decode_structured_content(content, content_type, false, **format_args) @@ -263,11 +263,11 @@ def decode_rack_env env, **format_args # @return [Array(headers,String)] # def encode_structured_content event, format_name, **format_args - result = @event_encoders[format_name]&.encode_event event: event, + result = @event_encoders[format_name]&.encode_event(event: event, data_encoder: @data_encoders, - **format_args + **format_args) return [{ "Content-Type" => result[:content_type].to_s }, result[:content]] if result - raise ::ArgumentError, "Unknown format name: #{format_name.inspect}" + raise(::ArgumentError, "Unknown format name: #{format_name.inspect}") end ## @@ -281,11 +281,11 @@ def encode_structured_content event, format_name, **format_args # @return [Array(headers,String)] # def encode_batched_content event_batch, format_name, **format_args - result = @event_encoders[format_name]&.encode_event event_batch: event_batch, + result = @event_encoders[format_name]&.encode_event(event_batch: event_batch, data_encoder: @data_encoders, - **format_args + **format_args) return [{ "Content-Type" => result[:content_type].to_s }, result[:content]] if result - raise ::ArgumentError, "Unknown format name: #{format_name.inspect}" + raise(::ArgumentError, "Unknown format name: #{format_name.inspect}") end ## @@ -300,15 +300,15 @@ def encode_batched_content event_batch, format_name, **format_args def encode_binary_content event, legacy_data_encode: true, **format_args headers = {} event.to_h.each do |key, value| - unless ["data", "data_encoded", "datacontenttype"].include? key - headers["CE-#{key}"] = percent_encode value + unless ["data", "data_encoded", "datacontenttype"].include?(key) + headers["CE-#{key}"] = percent_encode(value) end end body, content_type = if legacy_data_encode || event.spec_version.start_with?("0.") - legacy_extract_event_data event + legacy_extract_event_data(event) else - normal_extract_event_data event, format_args + normal_extract_event_data(event, format_args) end headers["Content-Type"] = content_type.to_s if content_type [headers, body] @@ -323,10 +323,10 @@ def encode_binary_content event, legacy_data_encode: true, **format_args # cycle of percent-encoding. # @return [String] Resulting decoded string in UTF-8. # - def percent_decode str + def percent_decode(str) str = str.gsub(/"((?:[^"\\]|\\.)*)"/) { ::Regexp.last_match(1).gsub(/\\(.)/, '\1') } - decoded_str = str.gsub(/%[0-9a-fA-F]{2}/) { |m| [m[1..].to_i(16)].pack "C" } - decoded_str.force_encoding ::Encoding::UTF_8 + decoded_str = str.gsub(/%[0-9a-fA-F]{2}/) { |m| [m[1..].to_i(16)].pack("C") } + decoded_str.force_encoding(::Encoding::UTF_8) end ## @@ -340,9 +340,9 @@ def percent_decode str # in UTF-8. # @return [String] Resulting encoded string in ASCII. # - def percent_encode str + def percent_encode(str) arr = [] - utf_str = str.to_s.encode ::Encoding::UTF_8 + utf_str = str.to_s.encode(::Encoding::UTF_8) utf_str.each_byte do |byte| if byte >= 33 && byte <= 126 && byte != 34 && byte != 37 arr << byte @@ -354,15 +354,15 @@ def percent_encode str arr << 37 << hi << lo end end - arr.pack "C*" + arr.pack("C*") end private - def add_named_formatter collection, formatter, name + def add_named_formatter(collection, formatter, name) return unless name formatters = collection[name] ||= [] - formatters.unshift formatter unless formatters.include? formatter + formatters.unshift(formatter) unless formatters.include?(formatter) end ## @@ -370,15 +370,15 @@ def add_named_formatter collection, formatter, name # structured mode. # def decode_structured_content content, content_type, allow_opaque, **format_args - result = @event_decoders.decode_event content: content, + result = @event_decoders.decode_event(content: content, content_type: content_type, data_decoder: @data_decoders, - **format_args + **format_args) return result[:event] || result[:event_batch] if result if content_type&.media_type == "application" && ["cloudevents", "cloudevents-batch"].include?(content_type.subtype_base) - return Event::Opaque.new content, content_type if allow_opaque - raise UnsupportedFormatError, "Unknown cloudevents content type: #{content_type}" + return Event::Opaque.new(content, content_type) if allow_opaque + raise(UnsupportedFormatError, "Unknown cloudevents content type: #{content_type}") end nil end @@ -393,29 +393,29 @@ def decode_binary_content content, content_type, env, legacy_data_decode, **form spec_version = env["HTTP_CE_SPECVERSION"] return nil unless spec_version unless spec_version =~ /^0\.3|1(\.|$)/ - raise SpecVersionError, "Unrecognized specversion: #{spec_version}" + raise(SpecVersionError, "Unrecognized specversion: #{spec_version}") end attributes = { "spec_version" => spec_version } if legacy_data_decode || spec_version.start_with?("0.") - legacy_populate_data_attributes attributes, content, content_type + legacy_populate_data_attributes(attributes, content, content_type) else - normal_populate_data_attributes attributes, content, content_type, spec_version, format_args + normal_populate_data_attributes(attributes, content, content_type, spec_version, format_args) end - populate_attributes_from_env attributes, env - Event.create spec_version: spec_version, set_attributes: attributes + populate_attributes_from_env(attributes, env) + Event.create(spec_version: spec_version, set_attributes: attributes) end - def legacy_populate_data_attributes attributes, content, content_type + def legacy_populate_data_attributes(attributes, content, content_type) attributes["data"] = content attributes["data_content_type"] = content_type if content_type end - def normal_populate_data_attributes attributes, content, content_type, spec_version, format_args + def normal_populate_data_attributes(attributes, content, content_type, spec_version, format_args) attributes["data_encoded"] = content - result = @data_decoders.decode_data spec_version: spec_version, + result = @data_decoders.decode_data(spec_version: spec_version, content: content, content_type: content_type, - **format_args + **format_args) if result attributes["data"] = result[:data] content_type = result[:content_type] @@ -423,17 +423,17 @@ def normal_populate_data_attributes attributes, content, content_type, spec_vers attributes["data_content_type"] = content_type if content_type end - def populate_attributes_from_env attributes, env + def populate_attributes_from_env(attributes, env) omit_names = ["specversion", "spec_version", "data", "datacontenttype", "data_content_type"] env.each do |key, value| - match = /^HTTP_CE_(\w+)$/.match key + match = /^HTTP_CE_(\w+)$/.match(key) next unless match attr_name = match[1].downcase - attributes[attr_name] = percent_decode value unless omit_names.include? attr_name + attributes[attr_name] = percent_decode(value) unless omit_names.include?(attr_name) end end - def legacy_extract_event_data event + def legacy_extract_event_data(event) body = event.data content_type = event.data_content_type&.to_s case body @@ -446,31 +446,31 @@ def legacy_extract_event_data event end end - def normal_extract_event_data event, format_args + def normal_extract_event_data(event, format_args) body = event.data_encoded if body [body, event.data_content_type] elsif event.data? - result = @data_encoders.encode_data spec_version: event.spec_version, + result = @data_encoders.encode_data(spec_version: event.spec_version, data: event.data, content_type: event.data_content_type, - **format_args - raise UnsupportedFormatError, "Could not encode unknown content-type: #{content_type}" unless result + **format_args) + raise(UnsupportedFormatError, "Could not encode unknown content-type: #{content_type}") unless result [result[:content], result[:content_type]] else ["", nil] end end - def read_with_charset io, charset + def read_with_charset(io, charset) return nil if io.nil? str = io.read if charset begin - str.force_encoding charset + str.force_encoding(charset) rescue ::ArgumentError # Use binary for now if the charset is unrecognized - str.force_encoding ::Encoding::ASCII_8BIT + str.force_encoding(::Encoding::ASCII_8BIT) end end str diff --git a/lib/cloud_events/json_format.rb b/lib/cloud_events/json_format.rb index e825458..e2c442f 100644 --- a/lib/cloud_events/json_format.rb +++ b/lib/cloud_events/json_format.rb @@ -41,17 +41,17 @@ def decode_event content: nil, content_type: nil, data_decoder: nil, **_other_kw return nil unless content && content_type&.media_type == "application" && content_type&.subtype_format == "json" case content_type.subtype_base when "cloudevents" - event = decode_hash_structure ::JSON.parse(content), charset: charset_of(content), data_decoder: data_decoder + event = decode_hash_structure(::JSON.parse(content), charset: charset_of(content), data_decoder: data_decoder) { event: event } when "cloudevents-batch" - charset = charset_of content + charset = charset_of(content) batch = Array(::JSON.parse(content)).map do |structure| - decode_hash_structure structure, charset: charset, data_decoder: data_decoder + decode_hash_structure(structure, charset: charset, data_decoder: data_decoder) end { event_batch: batch } end rescue ::JSON::JSONError - raise FormatSyntaxError, "JSON syntax error" + raise(FormatSyntaxError, "JSON syntax error") end ## @@ -79,23 +79,23 @@ def decode_event content: nil, content_type: nil, data_decoder: nil, **_other_kw # def encode_event event: nil, event_batch: nil, data_encoder: nil, sort: false, **_other_kwargs if event && !event_batch - structure = encode_hash_structure event, data_encoder: data_encoder - structure = sort_keys structure if sort + structure = encode_hash_structure(event, data_encoder: data_encoder) + structure = sort_keys(structure) if sort subtype = "cloudevents" elsif event_batch && !event structure = event_batch.map do |elem| - structure_elem = encode_hash_structure elem, data_encoder: data_encoder + structure_elem = encode_hash_structure(elem, data_encoder: data_encoder) sort ? sort_keys(structure_elem) : structure_elem end subtype = "cloudevents-batch" else return nil end - content = ::JSON.dump structure - content_type = ContentType.new "application/#{subtype}+json; charset=#{charset_of content}" + content = ::JSON.dump(structure) + content_type = ContentType.new("application/#{subtype}+json; charset=#{charset_of(content)}") { content: content, content_type: content_type } rescue ::JSON::JSONError - raise FormatSyntaxError, "JSON syntax error" + raise(FormatSyntaxError, "JSON syntax error") end ## @@ -122,14 +122,14 @@ def encode_event event: nil, event_batch: nil, data_encoder: nil, sort: false, * def decode_data spec_version: nil, content: nil, content_type: nil, **_other_kwargs return nil unless spec_version return nil unless content - return nil unless json_content_type? content_type + return nil unless json_content_type?(content_type) unless spec_version =~ /^0\.3|1(\.|$)/ - raise SpecVersionError, "Unrecognized specversion: #{spec_version}" + raise(SpecVersionError, "Unrecognized specversion: #{spec_version}") end - data = ::JSON.parse content + data = ::JSON.parse(content) { data: data, content_type: content_type } rescue ::JSON::JSONError - raise FormatSyntaxError, "JSON syntax error" + raise(FormatSyntaxError, "JSON syntax error") end ## @@ -157,12 +157,12 @@ def decode_data spec_version: nil, content: nil, content_type: nil, **_other_kwa def encode_data spec_version: nil, data: UNSPECIFIED, content_type: nil, sort: false, **_other_kwargs return nil unless spec_version return nil if data == UNSPECIFIED - return nil unless json_content_type? content_type + return nil unless json_content_type?(content_type) unless spec_version =~ /^0\.3|1(\.|$)/ - raise SpecVersionError, "Unrecognized specversion: #{spec_version}" + raise(SpecVersionError, "Unrecognized specversion: #{spec_version}") end - data = sort_keys data if sort - content = ::JSON.dump data + data = sort_keys(data) if sort + content = ::JSON.dump(data) { content: content, content_type: content_type } end @@ -177,15 +177,15 @@ def encode_data spec_version: nil, data: UNSPECIFIED, content_type: nil, sort: f # non-JSON content types. # @return [CloudEvents::Event] # - def decode_hash_structure structure, charset: nil, data_decoder: nil + def decode_hash_structure(structure, charset: nil, data_decoder: nil) spec_version = structure["specversion"].to_s case spec_version when "0.3" - decode_hash_structure_v0 structure, charset + decode_hash_structure_v0(structure, charset) when /^1(\.|$)/ - decode_hash_structure_v1 structure, charset, spec_version, data_decoder + decode_hash_structure_v1(structure, charset, spec_version, data_decoder) else - raise SpecVersionError, "Unrecognized specversion: #{spec_version}" + raise(SpecVersionError, "Unrecognized specversion: #{spec_version}") end end @@ -198,33 +198,33 @@ def decode_hash_structure structure, charset: nil, data_decoder: nil # non-JSON content types. # @return [String] The hash structure. # - def encode_hash_structure event, data_encoder: nil + def encode_hash_structure(event, data_encoder: nil) case event when Event::V0 - encode_hash_structure_v0 event + encode_hash_structure_v0(event) when Event::V1 - encode_hash_structure_v1 event, data_encoder + encode_hash_structure_v1(event, data_encoder) else - raise SpecVersionError, "Unrecognized event type: #{event.class}" + raise(SpecVersionError, "Unrecognized event type: #{event.class}") end end private - def json_content_type? content_type + def json_content_type?(content_type) content_type&.subtype_base == "json" || content_type&.subtype_format == "json" end - def sort_keys obj - return obj unless obj.is_a? ::Hash + def sort_keys(obj) + return obj unless obj.is_a?(::Hash) result = {} obj.keys.sort.each do |key| - result[key] = sort_keys obj[key] + result[key] = sort_keys(obj[key]) end result end - def charset_of str + def charset_of(str) encoding = str.encoding if encoding == ::Encoding::ASCII_8BIT "binary" @@ -233,29 +233,29 @@ def charset_of str end end - def decode_hash_structure_v0 structure, charset - unless structure.key? "datacontenttype" + def decode_hash_structure_v0(structure, charset) + unless structure.key?("datacontenttype") structure = structure.dup content_type = "application/json" content_type = "#{content_type}; charset=#{charset}" if charset structure["datacontenttype"] = content_type end - Event::V0.new attributes: structure + Event::V0.new(attributes: structure) end - def decode_hash_structure_v1 structure, charset, spec_version, data_decoder + def decode_hash_structure_v1(structure, charset, spec_version, data_decoder) unless structure.key?("data") || structure.key?("data_base64") - return Event::V1.new set_attributes: structure + return Event::V1.new(set_attributes: structure) end structure = structure.dup - content, content_type = retrieve_content_from_data_fields structure, charset - populate_data_fields_from_content structure, content, content_type, spec_version, data_decoder - Event::V1.new set_attributes: structure + content, content_type = retrieve_content_from_data_fields(structure, charset) + populate_data_fields_from_content(structure, content, content_type, spec_version, data_decoder) + Event::V1.new(set_attributes: structure) end - def retrieve_content_from_data_fields structure, charset - if structure.key? "data_base64" - content = structure.delete("data_base64").unpack1 "m" + def retrieve_content_from_data_fields(structure, charset) + if structure.key?("data_base64") + content = structure.delete("data_base64").unpack1("m") content_type = structure["datacontenttype"] || "application/octet-stream" else content = structure["data"] @@ -265,60 +265,60 @@ def retrieve_content_from_data_fields structure, charset [content, ContentType.new(content_type)] end - def populate_data_fields_from_content structure, content, content_type, spec_version, data_decoder - if json_content_type? content_type - structure["data_encoded"] = ::JSON.dump content + def populate_data_fields_from_content(structure, content, content_type, spec_version, data_decoder) + if json_content_type?(content_type) + structure["data_encoded"] = ::JSON.dump(content) structure["data"] = content else structure["data_encoded"] = content = content.to_s - result = data_decoder&.decode_data spec_version: spec_version, content: content, content_type: content_type + result = data_decoder&.decode_data(spec_version: spec_version, content: content, content_type: content_type) if result structure["data"] = result[:data] content_type = result[:content_type] else - structure.delete "data" + structure.delete("data") end end structure["datacontenttype"] = content_type end - def encode_hash_structure_v0 event + def encode_hash_structure_v0(event) structure = event.to_h structure["datacontenttype"] ||= "application/json" structure end - def encode_hash_structure_v1 event, data_encoder + def encode_hash_structure_v1(event, data_encoder) structure = event.to_h return structure unless structure.key?("data") || structure.key?("data_encoded") content_type = event.data_content_type if content_type.nil? || json_content_type?(content_type) - encode_data_fields_for_json_content structure, event + encode_data_fields_for_json_content(structure, event) else - encode_data_fields_for_other_content structure, event, data_encoder + encode_data_fields_for_other_content(structure, event, data_encoder) end structure end - def encode_data_fields_for_json_content structure, event - structure["data"] = ::JSON.parse event.data unless event.data_decoded? - structure.delete "data_encoded" + def encode_data_fields_for_json_content(structure, event) + structure["data"] = ::JSON.parse(event.data) unless event.data_decoded? + structure.delete("data_encoded") structure["datacontenttype"] ||= "application/json" end - def encode_data_fields_for_other_content structure, event, data_encoder - data_encoded = structure.delete "data_encoded" + def encode_data_fields_for_other_content(structure, event, data_encoder) + data_encoded = structure.delete("data_encoded") unless data_encoded - result = data_encoder&.encode_data spec_version: event.spec_version, + result = data_encoder&.encode_data(spec_version: event.spec_version, data: event.data, - content_type: event.data_content_type - raise UnsupportedFormatError, "Unable to encode data of media type #{event.data_content_type}" unless result + content_type: event.data_content_type) + raise(UnsupportedFormatError, "Unable to encode data of media type #{event.data_content_type}") unless result data_encoded = result[:content] structure["datacontenttype"] = result[:content_type].to_s end if data_encoded.encoding == ::Encoding::ASCII_8BIT - structure["data_base64"] = [data_encoded].pack "m0" - structure.delete "data" + structure["data_base64"] = [data_encoded].pack("m0") + structure.delete("data") else structure["data"] = data_encoded end diff --git a/lib/cloud_events/text_format.rb b/lib/cloud_events/text_format.rb index e8afd4f..d4aced7 100644 --- a/lib/cloud_events/text_format.rb +++ b/lib/cloud_events/text_format.rb @@ -32,7 +32,7 @@ class TextFormat # def decode_data content: nil, content_type: nil, **_other_kwargs return nil unless content - return nil unless text_content_type? content_type + return nil unless text_content_type?(content_type) { data: content.to_s, content_type: content_type } end @@ -58,13 +58,13 @@ def decode_data content: nil, content_type: nil, **_other_kwargs # def encode_data data: UNSPECIFIED, content_type: nil, **_other_kwargs return nil if data == UNSPECIFIED - return nil unless text_content_type? content_type + return nil unless text_content_type?(content_type) { content: data.to_s, content_type: content_type } end private - def text_content_type? content_type + def text_content_type?(content_type) content_type&.media_type == "text" || (content_type&.media_type == "application" && content_type&.subtype == "octet-stream") end diff --git a/test/event/test_opaque.rb b/test/event/test_opaque.rb index 9da5439..4916f4e 100644 --- a/test/event/test_opaque.rb +++ b/test/event/test_opaque.rb @@ -4,29 +4,29 @@ describe CloudEvents::Event::Opaque do let(:my_content_type_string) { "text/plain; charset=us-ascii" } - let(:my_content_type) { CloudEvents::ContentType.new my_content_type_string } + let(:my_content_type) { CloudEvents::ContentType.new(my_content_type_string) } let(:my_content) { "12345" } it "handles non-batch" do - event = CloudEvents::Event::Opaque.new my_content, my_content_type + event = CloudEvents::Event::Opaque.new(my_content, my_content_type) assert_equal my_content, event.content assert_equal my_content_type, event.content_type refute event.batch? - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles batch" do - event = CloudEvents::Event::Opaque.new my_content, my_content_type, batch: true + event = CloudEvents::Event::Opaque.new(my_content, my_content_type, batch: true) assert_equal my_content, event.content assert_equal my_content_type, event.content_type assert event.batch? - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "checks equality" do - event1 = CloudEvents::Event::Opaque.new my_content, my_content_type - event2 = CloudEvents::Event::Opaque.new my_content, my_content_type - event3 = CloudEvents::Event::Opaque.new my_content, my_content_type, batch: true + event1 = CloudEvents::Event::Opaque.new(my_content, my_content_type) + event2 = CloudEvents::Event::Opaque.new(my_content, my_content_type) + event3 = CloudEvents::Event::Opaque.new(my_content, my_content_type, batch: true) assert_equal event1, event2 refute_equal event1, event3 end diff --git a/test/event/test_v0.rb b/test/event/test_v0.rb index d099165..4cd4530 100644 --- a/test/event/test_v0.rb +++ b/test/event/test_v0.rb @@ -8,26 +8,26 @@ describe CloudEvents::Event::V0 do let(:my_id) { "my_id" } let(:my_source_string) { "/my_source" } - let(:my_source) { URI.parse my_source_string } + let(:my_source) { URI.parse(my_source_string) } let(:my_source2_string) { "/my_source2" } - let(:my_source2) { URI.parse my_source2_string } + let(:my_source2) { URI.parse(my_source2_string) } let(:my_type) { "my_type" } let(:my_type2) { "my_type2" } let(:spec_version) { "0.3" } let(:my_simple_data) { "12345" } let(:my_content_encoding) { "base64" } let(:my_content_type_string) { "text/plain; charset=us-ascii" } - let(:my_content_type) { CloudEvents::ContentType.new my_content_type_string } + let(:my_content_type) { CloudEvents::ContentType.new(my_content_type_string) } let(:my_schema_string) { "/my_schema" } - let(:my_schema) { URI.parse my_schema_string } + let(:my_schema) { URI.parse(my_schema_string) } let(:my_subject) { "my_subject" } let(:my_time_string) { "2020-01-12T20:52:05-08:00" } - let(:my_date_time) { DateTime.rfc3339 my_time_string } + let(:my_date_time) { DateTime.rfc3339(my_time_string) } let(:my_time) { my_date_time.to_time } let(:my_trace_parent) { "12345678" } it "handles string inputs" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -36,7 +36,7 @@ data_content_type: my_content_type_string, schema_url: my_schema_string, subject: my_subject, - time: my_time_string + time: my_time_string) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -61,11 +61,11 @@ assert_nil event[:schema_url] assert_equal my_subject, event[:subject] assert_equal my_time_string, event[:time] - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles object inputs" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, @@ -73,7 +73,7 @@ data_content_type: my_content_type, schema_url: my_schema, subject: my_subject, - time: my_date_time + time: my_date_time) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -95,30 +95,30 @@ assert_nil event[:schema_url] assert_equal my_subject, event[:subject] assert_equal my_time_string, event[:time] - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles more object inputs" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, data: my_simple_data, - time: my_time + time: my_time) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type assert_equal spec_version, event.spec_version assert_equal my_simple_data, event.data assert_equal my_date_time, event.time - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "sets defaults when optional inputs are omitted" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version + spec_version: spec_version) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -143,11 +143,11 @@ assert_nil event[:schema_url] assert_nil event[:subject] assert_nil event[:time] - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "creates a modified copy" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -156,99 +156,99 @@ data_content_type: my_content_type_string, schema_url: my_schema_string, subject: my_subject, - time: my_time_string - event2 = event.with type: my_type2, source: my_source2 + time: my_time_string) + event2 = event.with(type: my_type2, source: my_source2) assert_equal my_id, event2.id assert_equal my_source2, event2.source assert_equal my_type2, event2.type assert_equal my_schema, event2.schema_url - assert Ractor.shareable? event2 if defined? Ractor + assert Ractor.shareable?(event2) if defined? Ractor end it "requires specversion" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V0.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V0.new(id: my_id, source: my_source, - type: my_type + type: my_type) end assert_equal "The specversion field is required", error.message end it "errors when the wrong specversion is given" do - error = assert_raises CloudEvents::SpecVersionError do - CloudEvents::Event::V0.new id: my_id, + error = assert_raises(CloudEvents::SpecVersionError) do + CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, - spec_version: "1.0" + spec_version: "1.0") end assert_equal "Unrecognized specversion: 1.0", error.message end it "requires id" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V0.new source: my_source, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V0.new(source: my_source, type: my_type, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The id field is required", error.message end it "requires source" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V0.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V0.new(id: my_id, type: my_type, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The source field is required", error.message end it "requires type" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V0.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V0.new(id: my_id, source: my_source, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The type field is required", error.message end it "handles extension attributes" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - traceparent: my_trace_parent + traceparent: my_trace_parent) assert_equal my_trace_parent, event[:traceparent] assert_equal my_trace_parent, event.to_h["traceparent"] end it "handles nonstring extension attributes" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - dataref: my_source + dataref: my_source) assert_equal my_source_string, event[:dataref] assert_equal my_source_string, event.to_h["dataref"] end it "handles nil extension attributes" do - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - traceparent: nil + traceparent: nil) assert_nil event[:traceparent] refute_includes event.to_h, "traceparent" end it "returns a deep copy from to_h" do my_data = { "a" => [1, 2, 3, 4] } - event = CloudEvents::Event::V0.new id: my_id, + event = CloudEvents::Event::V0.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, - data: my_data - assert Ractor.shareable? event if defined? Ractor + data: my_data) + assert Ractor.shareable?(event) if defined? Ractor data_from_getter = event.data assert_equal my_data, data_from_getter @@ -262,18 +262,18 @@ end it "checks equality" do - event1 = CloudEvents::Event::V0.new id: my_id, + event1 = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version - event2 = CloudEvents::Event::V0.new id: my_id, + spec_version: spec_version) + event2 = CloudEvents::Event::V0.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version - event3 = CloudEvents::Event::V0.new id: my_id, + spec_version: spec_version) + event3 = CloudEvents::Event::V0.new(id: my_id, source: my_source2, type: my_type, - spec_version: spec_version + spec_version: spec_version) assert_equal event1, event2 refute_equal event1, event3 end diff --git a/test/event/test_v1.rb b/test/event/test_v1.rb index 77251cc..b18ee66 100644 --- a/test/event/test_v1.rb +++ b/test/event/test_v1.rb @@ -8,29 +8,29 @@ describe CloudEvents::Event::V1 do let(:my_id) { "my_id" } let(:my_source_string) { "/my_source" } - let(:my_source) { URI.parse my_source_string } + let(:my_source) { URI.parse(my_source_string) } let(:my_source2_string) { "/my_source2" } - let(:my_source2) { URI.parse my_source2_string } + let(:my_source2) { URI.parse(my_source2_string) } let(:my_type) { "my_type" } let(:my_type2) { "my_type2" } let(:spec_version) { "1.0" } let(:my_simple_data) { "12345" } let(:my_content_type_string) { "text/plain; charset=us-ascii" } - let(:my_content_type) { CloudEvents::ContentType.new my_content_type_string } + let(:my_content_type) { CloudEvents::ContentType.new(my_content_type_string) } let(:my_object_data) { { "foo" => "bar" } } let(:my_object_data_encoded) { '{"foo":"bar"}' } let(:my_json_content_type_string) { "application/json; charset=us-ascii" } - let(:my_json_content_type) { CloudEvents::ContentType.new my_json_content_type_string } + let(:my_json_content_type) { CloudEvents::ContentType.new(my_json_content_type_string) } let(:my_schema_string) { "/my_schema" } - let(:my_schema) { URI.parse my_schema_string } + let(:my_schema) { URI.parse(my_schema_string) } let(:my_subject) { "my_subject" } let(:my_time_string) { "2020-01-12T20:52:05-08:00" } - let(:my_date_time) { DateTime.rfc3339 my_time_string } + let(:my_date_time) { DateTime.rfc3339(my_time_string) } let(:my_time) { my_date_time.to_time } let(:my_trace_parent) { "12345678" } it "handles string inputs" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -39,7 +39,7 @@ data_content_type: my_content_type_string, data_schema: my_schema_string, subject: my_subject, - time: my_time_string + time: my_time_string) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -64,11 +64,11 @@ assert_nil event[:data_schema] assert_equal my_subject, event[:subject] assert_equal my_time_string, event[:time] - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles object inputs" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, @@ -77,7 +77,7 @@ data_content_type: my_json_content_type, data_schema: my_schema, subject: my_subject, - time: my_date_time + time: my_date_time) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -102,30 +102,30 @@ assert_nil event[:data_schema] assert_equal my_subject, event[:subject] assert_equal my_time_string, event[:time] - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles more object inputs" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, data: my_simple_data, - time: my_time + time: my_time) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type assert_equal spec_version, event.spec_version assert_equal my_simple_data, event.data assert_equal my_date_time, event.time - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "sets defaults when optional inputs are omitted" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version + spec_version: spec_version) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -151,11 +151,11 @@ assert_nil event[:subject] assert_nil event[:time] assert_equal ["id", "source", "specversion", "type"], event.to_h.keys.sort - assert Ractor.shareable? event if defined? Ractor + assert Ractor.shareable?(event) if defined? Ractor end it "handles data set but not data_encoded" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -163,7 +163,7 @@ data_content_type: my_content_type_string, data_schema: my_schema_string, subject: my_subject, - time: my_time_string + time: my_time_string) assert_equal my_simple_data, event.data assert_nil event.data_encoded assert event.data_decoded? @@ -172,7 +172,7 @@ end it "handles data_encoded set but not data" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -180,7 +180,7 @@ data_content_type: my_content_type_string, data_schema: my_schema_string, subject: my_subject, - time: my_time_string + time: my_time_string) assert_equal my_simple_data, event.data_encoded assert_equal my_simple_data, event.data refute event.data_decoded? @@ -189,7 +189,7 @@ end it "creates a modified copy" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -197,17 +197,17 @@ data_content_type: my_content_type_string, data_schema: my_schema_string, subject: my_subject, - time: my_time_string - event2 = event.with type: my_type2, source: my_source2 + time: my_time_string) + event2 = event.with(type: my_type2, source: my_source2) assert_equal my_id, event2.id assert_equal my_source2, event2.source assert_equal my_type2, event2.type assert_equal my_schema, event2.data_schema - assert Ractor.shareable? event2 if defined? Ractor + assert Ractor.shareable?(event2) if defined? Ractor end it "creates a modified copy changing the data" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, @@ -215,101 +215,101 @@ data_content_type: my_content_type_string, data_schema: my_schema_string, subject: my_subject, - time: my_time_string + time: my_time_string) assert_equal my_simple_data, event.data assert_equal my_simple_data, event.data_encoded refute event.data_decoded? - event2 = event.with data: my_simple_data + event2 = event.with(data: my_simple_data) assert_nil event2.data_encoded assert_equal my_simple_data, event2.data assert event2.data_decoded? - assert Ractor.shareable? event2 if defined? Ractor + assert Ractor.shareable?(event2) if defined? Ractor end it "requires specversion" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V1.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V1.new(id: my_id, source: my_source, - type: my_type + type: my_type) end assert_equal "The specversion field is required", error.message end it "errors when the wrong specversion is given" do - error = assert_raises CloudEvents::SpecVersionError do - CloudEvents::Event::V1.new id: my_id, + error = assert_raises(CloudEvents::SpecVersionError) do + CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, - spec_version: "0.3" + spec_version: "0.3") end assert_equal "Unrecognized specversion: 0.3", error.message end it "requires id" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V1.new source: my_source, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V1.new(source: my_source, type: my_type, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The id field is required", error.message end it "requires source" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V1.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V1.new(id: my_id, type: my_type, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The source field is required", error.message end it "requires type" do - error = assert_raises CloudEvents::AttributeError do - CloudEvents::Event::V1.new id: my_id, + error = assert_raises(CloudEvents::AttributeError) do + CloudEvents::Event::V1.new(id: my_id, source: my_source, - spec_version: spec_version + spec_version: spec_version) end assert_equal "The type field is required", error.message end it "handles extension attributes" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - traceparent: my_trace_parent + traceparent: my_trace_parent) assert_equal my_trace_parent, event[:traceparent] assert_equal my_trace_parent, event.to_h["traceparent"] end it "handles nonstring extension attributes" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - dataref: my_source + dataref: my_source) assert_equal my_source_string, event[:dataref] assert_equal my_source_string, event.to_h["dataref"] end it "handles nil extension attributes" do - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, spec_version: spec_version, - traceparent: nil + traceparent: nil) assert_nil event[:traceparent] refute_includes event.to_h, "traceparent" end it "returns a deep copy from to_h" do my_data = { "a" => [1, 2, 3, 4] } - event = CloudEvents::Event::V1.new id: my_id, + event = CloudEvents::Event::V1.new(id: my_id, source: my_source_string, type: my_type, spec_version: spec_version, - data: my_data - assert Ractor.shareable? event if defined? Ractor + data: my_data) + assert Ractor.shareable?(event) if defined? Ractor data_from_getter = event.data assert_equal my_data, data_from_getter @@ -323,18 +323,18 @@ end it "checks equality" do - event1 = CloudEvents::Event::V1.new id: my_id, + event1 = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version - event2 = CloudEvents::Event::V1.new id: my_id, + spec_version: spec_version) + event2 = CloudEvents::Event::V1.new(id: my_id, source: my_source, type: my_type, - spec_version: spec_version - event3 = CloudEvents::Event::V1.new id: my_id, + spec_version: spec_version) + event3 = CloudEvents::Event::V1.new(id: my_id, source: my_source2, type: my_type, - spec_version: spec_version + spec_version: spec_version) assert_equal event1, event2 refute_equal event1, event3 end diff --git a/test/test_content_type.rb b/test/test_content_type.rb index fc5f86b..73c35ec 100644 --- a/test/test_content_type.rb +++ b/test/test_content_type.rb @@ -4,114 +4,114 @@ describe CloudEvents::ContentType do it "recognizes simple media type and subtype" do - content_type = CloudEvents::ContentType.new "application/cloudevents" + content_type = CloudEvents::ContentType.new("application/cloudevents") assert_equal "application", content_type.media_type assert_equal "cloudevents", content_type.subtype assert_equal "cloudevents", content_type.subtype_base assert_nil content_type.subtype_format - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "normalizes media type and subtype case" do - content_type = CloudEvents::ContentType.new "Application/CloudEvents" + content_type = CloudEvents::ContentType.new("Application/CloudEvents") assert_equal "application", content_type.media_type assert_equal "cloudevents", content_type.subtype assert_equal "cloudevents", content_type.subtype_base assert_nil content_type.subtype_format - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "recognizes extended subtype" do - content_type = CloudEvents::ContentType.new "application/cloudevents+json" + content_type = CloudEvents::ContentType.new("application/cloudevents+json") assert_equal "cloudevents+json", content_type.subtype assert_equal "cloudevents", content_type.subtype_base assert_equal "json", content_type.subtype_format - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "defaults to us-ascii charset" do - content_type = CloudEvents::ContentType.new "application/json" + content_type = CloudEvents::ContentType.new("application/json") assert_equal "us-ascii", content_type.charset - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "defaults to a given charset" do - content_type = CloudEvents::ContentType.new "application/json", default_charset: "utf-8" + content_type = CloudEvents::ContentType.new("application/json", default_charset: "utf-8") assert_equal "utf-8", content_type.charset - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "recognizes charseet param" do - content_type = CloudEvents::ContentType.new "application/json; charset=utf-8" + content_type = CloudEvents::ContentType.new("application/json; charset=utf-8") assert_equal [["charset", "utf-8"]], content_type.params assert_equal "utf-8", content_type.charset - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "recognizes quoted charset param" do - content_type = CloudEvents::ContentType.new "application/json; charset=\"utf-8\"" + content_type = CloudEvents::ContentType.new("application/json; charset=\"utf-8\"") assert_equal [["charset", "utf-8"]], content_type.params assert_equal "utf-8", content_type.charset - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "recognizes arbitrary quoted param values" do - content_type = CloudEvents::ContentType.new "application/json; foo=\"hi\\\"\\\\ \" ;bar=ho" + content_type = CloudEvents::ContentType.new("application/json; foo=\"hi\\\"\\\\ \" ;bar=ho") assert_equal [["foo", "hi\"\\ "], ["bar", "ho"]], content_type.params - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "handles nil content" do - content_type = CloudEvents::ContentType.new nil + content_type = CloudEvents::ContentType.new(nil) assert_equal "text", content_type.media_type assert_equal "plain", content_type.subtype assert_equal "plain", content_type.subtype_base assert_nil content_type.subtype_format - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "remembers the input string" do header = "Application/CloudEvents+JSON; charset=utf-8" - content_type = CloudEvents::ContentType.new header + content_type = CloudEvents::ContentType.new(header) assert_equal header, content_type.string - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "produces a case-normalized canonical string" do header = "Application/CloudEvents+JSON; charset=utf-8" - content_type = CloudEvents::ContentType.new header + content_type = CloudEvents::ContentType.new(header) assert_equal header.downcase, content_type.canonical_string - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "produces canonical string with spaces normalized" do header = "Application /CloudEvents+JSON ; charset=utf-8 " - content_type = CloudEvents::ContentType.new header + content_type = CloudEvents::ContentType.new(header) assert_equal "application/cloudevents+json; charset=utf-8", content_type.canonical_string - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "produces canonical string with quoted values" do header = "application/cloudevents+json; foo=\"utf-8 \"; bar=\"hi\" ;baz=\"hi\\\"\"" - content_type = CloudEvents::ContentType.new header + content_type = CloudEvents::ContentType.new(header) assert_equal "application/cloudevents+json; foo=\"utf-8 \"; bar=hi; baz=\"hi\\\"\"", content_type.canonical_string - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "drops comments" do header = "application/json (JSON rulz); ((oh btw) Ruby \\( rocks) charset=utf-8 (and so does unicode)(srsly)" - content_type = CloudEvents::ContentType.new header + content_type = CloudEvents::ContentType.new(header) assert_equal "application/json; charset=utf-8", content_type.canonical_string - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end it "uses the default in case of a parse error" do - content_type = CloudEvents::ContentType.new "" + content_type = CloudEvents::ContentType.new("") assert_equal "text", content_type.media_type assert_equal "plain", content_type.subtype assert_equal "us-ascii", content_type.charset assert_equal "text/plain", content_type.canonical_string assert_equal "Failed to parse media type", content_type.error_message - assert Ractor.shareable? content_type if defined? Ractor + assert Ractor.shareable?(content_type) if defined? Ractor end end diff --git a/test/test_event.rb b/test/test_event.rb index 72e8fd6..8458115 100644 --- a/test/test_event.rb +++ b/test/test_event.rb @@ -8,27 +8,27 @@ let(:my_type) { "my_type" } it "recognizes spec version 0" do - event = CloudEvents::Event.create id: my_id, + event = CloudEvents::Event.create(id: my_id, source: my_source, type: my_type, - spec_version: "0.3" + spec_version: "0.3") assert_instance_of CloudEvents::Event::V0, event end it "recognizes spec version 1" do - event = CloudEvents::Event.create id: my_id, + event = CloudEvents::Event.create(id: my_id, source: my_source, type: my_type, - spec_version: "1.0" + spec_version: "1.0") assert_instance_of CloudEvents::Event::V1, event end it "rejects spec version 2" do assert_raises CloudEvents::SpecVersionError do - CloudEvents::Event.create id: my_id, + CloudEvents::Event.create(id: my_id, source: my_source, type: my_type, - spec_version: "2.0" + spec_version: "2.0") end end end diff --git a/test/test_http_binding.rb b/test/test_http_binding.rb index 8153ee6..6cce2f8 100644 --- a/test/test_http_binding.rb +++ b/test/test_http_binding.rb @@ -12,7 +12,7 @@ let(:minimal_http_binding) { CloudEvents::HttpBinding.new } let(:my_id) { "my_id" } let(:my_source_string) { "/my_source" } - let(:my_source) { URI.parse my_source_string } + let(:my_source) { URI.parse(my_source_string) } let(:my_type) { "my_type" } let(:weird_type) { "¡Hola!\n\"100%\" 😀 " } let(:encoded_weird_type) { "%C2%A1Hola!%0A%22100%25%22%20%F0%9F%98%80%20" } @@ -22,14 +22,14 @@ let(:my_simple_data) { "12345" } let(:my_json_escaped_simple_data) { '"12345"' } let(:my_content_type_string) { "text/plain; charset=us-ascii" } - let(:my_content_type) { CloudEvents::ContentType.new my_content_type_string } + let(:my_content_type) { CloudEvents::ContentType.new(my_content_type_string) } let(:my_json_content_type_string) { "application/json; charset=us-ascii" } - let(:my_json_content_type) { CloudEvents::ContentType.new my_json_content_type_string } + let(:my_json_content_type) { CloudEvents::ContentType.new(my_json_content_type_string) } let(:my_schema_string) { "/my_schema" } - let(:my_schema) { URI.parse my_schema_string } + let(:my_schema) { URI.parse(my_schema_string) } let(:my_subject) { "my_subject" } let(:my_time_string) { "2020-01-12T20:52:05-08:00" } - let(:my_time) { DateTime.rfc3339 my_time_string } + let(:my_time) { DateTime.rfc3339(my_time_string) } let(:my_trace_context) { "1234567890;9876543210" } let :my_json_struct do { @@ -41,11 +41,11 @@ "specversion" => spec_version, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end - let(:my_json_struct_encoded) { JSON.dump my_json_struct } - let(:my_json_batch_encoded) { JSON.dump [my_json_struct] } + let(:my_json_struct_encoded) { JSON.dump(my_json_struct) } + let(:my_json_batch_encoded) { JSON.dump([my_json_struct]) } let :my_json_data_struct do { "data" => my_simple_data, @@ -56,10 +56,10 @@ "specversion" => spec_version, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end - let(:my_json_data_struct_encoded) { JSON.dump my_json_data_struct } + let(:my_json_data_struct_encoded) { JSON.dump(my_json_data_struct) } let :my_simple_binary_mode do { "rack.input" => StringIO.new(my_simple_data), @@ -70,7 +70,7 @@ "CONTENT_TYPE" => my_content_type_string, "HTTP_CE_DATASCHEMA" => my_schema_string, "HTTP_CE_SUBJECT" => my_subject, - "HTTP_CE_TIME" => my_time_string + "HTTP_CE_TIME" => my_time_string, } end let :my_json_binary_mode do @@ -83,7 +83,7 @@ "CONTENT_TYPE" => my_json_content_type_string, "HTTP_CE_DATASCHEMA" => my_schema_string, "HTTP_CE_SUBJECT" => my_subject, - "HTTP_CE_TIME" => my_time_string + "HTTP_CE_TIME" => my_time_string, } end let :my_minimal_binary_mode do @@ -92,7 +92,7 @@ "HTTP_CE_ID" => my_id, "HTTP_CE_SOURCE" => my_source_string, "HTTP_CE_TYPE" => my_type, - "HTTP_CE_SPECVERSION" => spec_version + "HTTP_CE_SPECVERSION" => spec_version, } end let :my_extensions_binary_mode do @@ -106,7 +106,7 @@ "HTTP_CE_DATASCHEMA" => my_schema_string, "HTTP_CE_SUBJECT" => my_subject, "HTTP_CE_TIME" => my_time_string, - "HTTP_CE_TRACECONTEXT" => my_trace_context + "HTTP_CE_TRACECONTEXT" => my_trace_context, } end let :my_nonascii_binary_mode do @@ -119,11 +119,11 @@ "CONTENT_TYPE" => my_content_type_string, "HTTP_CE_DATASCHEMA" => my_schema_string, "HTTP_CE_SUBJECT" => my_subject, - "HTTP_CE_TIME" => my_time_string + "HTTP_CE_TIME" => my_time_string, } end let :my_simple_event do - CloudEvents::Event::V1.new data_encoded: my_simple_data, + CloudEvents::Event::V1.new(data_encoded: my_simple_data, data: my_simple_data, datacontenttype: my_content_type_string, dataschema: my_schema_string, @@ -132,10 +132,10 @@ specversion: spec_version, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_json_event do - CloudEvents::Event::V1.new data_encoded: my_json_escaped_simple_data, + CloudEvents::Event::V1.new(data_encoded: my_json_escaped_simple_data, data: my_simple_data, datacontenttype: my_json_content_type_string, dataschema: my_schema_string, @@ -144,18 +144,18 @@ specversion: spec_version, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_minimal_event do - CloudEvents::Event::V1.new data_encoded: "", + CloudEvents::Event::V1.new(data_encoded: "", data: "", id: my_id, source: my_source_string, specversion: spec_version, - type: my_type + type: my_type) end let :my_extensions_event do - CloudEvents::Event::V1.new data_encoded: my_simple_data, + CloudEvents::Event::V1.new(data_encoded: my_simple_data, data: my_simple_data, datacontenttype: my_content_type_string, dataschema: my_schema_string, @@ -165,10 +165,10 @@ subject: my_subject, time: my_time_string, tracecontext: my_trace_context, - type: my_type + type: my_type) end let :my_nonascii_event do - CloudEvents::Event::V1.new data_encoded: my_simple_data, + CloudEvents::Event::V1.new(data_encoded: my_simple_data, data: my_simple_data, datacontenttype: my_content_type_string, dataschema: my_schema_string, @@ -177,46 +177,46 @@ specversion: spec_version, subject: my_subject, time: my_time_string, - type: weird_type + type: weird_type) end - def assert_request_matches env, headers, body + def assert_request_matches(env, headers, body) env = env.dup - assert_equal env.delete("rack.input").read, body + assert_equal(env.delete("rack.input").read, body) headers_env = {} headers.each do |k, v| k = k.tr("-", "_").upcase k = "HTTP_#{k}" unless k == "CONTENT_TYPE" headers_env[k] = v end - assert_equal env, headers_env + assert_equal(env, headers_env) end describe "percent_encode" do it "percent-encodes an ascii string" do - str = http_binding.percent_encode my_simple_data + str = http_binding.percent_encode(my_simple_data) assert_equal my_simple_data, str end it "percent-encodes a string with special characters" do - str = http_binding.percent_encode weird_type + str = http_binding.percent_encode(weird_type) assert_equal encoded_weird_type, str end end describe "percent_decode" do it "percent-decodes an ascii string" do - str = http_binding.percent_decode my_simple_data + str = http_binding.percent_decode(my_simple_data) assert_equal my_simple_data, str end it "percent-decodes a string with special characters" do - str = http_binding.percent_decode encoded_weird_type + str = http_binding.percent_decode(encoded_weird_type) assert_equal weird_type, str end it "percent-decodes a string with quoted tokens" do - str = http_binding.percent_decode encoded_quoted_type + str = http_binding.percent_decode(encoded_quoted_type) assert_equal quoted_type, str end end @@ -225,67 +225,67 @@ def assert_request_matches env, headers, body it "decodes a json-structured rack env with text content type" do env = { "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } - event = http_binding.decode_event env + event = http_binding.decode_event(env) assert_equal my_simple_event, event end it "decodes a json-structured rack env with json content type" do env = { "rack.input" => StringIO.new(my_json_data_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } - event = http_binding.decode_event env + event = http_binding.decode_event(env) assert_equal my_json_event, event end it "decodes a json-batch rack env with text content type" do env = { "rack.input" => StringIO.new(my_json_batch_encoded), - "CONTENT_TYPE" => "application/cloudevents-batch+json" + "CONTENT_TYPE" => "application/cloudevents-batch+json", } - events = http_binding.decode_event env + events = http_binding.decode_event(env) assert_equal [my_simple_event], events end it "decodes a binary mode rack env with text content type" do - event = http_binding.decode_event my_simple_binary_mode + event = http_binding.decode_event(my_simple_binary_mode) assert_equal my_simple_event, event end it "decodes a binary mode rack env with json content type" do - event = http_binding.decode_event my_json_binary_mode + event = http_binding.decode_event(my_json_binary_mode) assert_equal my_json_event, event end it "decodes a binary mode rack env using an InputWrapper" do - my_simple_binary_mode["rack.input"] = StringIO.new my_simple_data - event = http_binding.decode_event my_simple_binary_mode + my_simple_binary_mode["rack.input"] = StringIO.new(my_simple_data) + event = http_binding.decode_event(my_simple_binary_mode) assert_equal my_simple_event, event end it "decodes a binary mode rack env omitting optional headers" do - event = http_binding.decode_event my_minimal_binary_mode + event = http_binding.decode_event(my_minimal_binary_mode) assert_equal my_minimal_event, event end it "decodes a binary mode rack env with extension headers" do - event = http_binding.decode_event my_extensions_binary_mode + event = http_binding.decode_event(my_extensions_binary_mode) assert_equal my_extensions_event, event end it "decodes a binary mode rack env with non-ascii characters in a header" do - event = http_binding.decode_event my_nonascii_binary_mode + event = http_binding.decode_event(my_nonascii_binary_mode) assert_equal my_nonascii_event, event end it "decodes a structured event using opaque" do env = { "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } - event = minimal_http_binding.decode_event env, allow_opaque: true + event = minimal_http_binding.decode_event(env, allow_opaque: true) assert_kind_of CloudEvents::Event::Opaque, event refute event.batch? assert_equal my_json_struct_encoded, event.content @@ -295,9 +295,9 @@ def assert_request_matches env, headers, body it "decodes a structured batch using opaque" do env = { "rack.input" => StringIO.new(my_json_batch_encoded), - "CONTENT_TYPE" => "application/cloudevents-batch+json" + "CONTENT_TYPE" => "application/cloudevents-batch+json", } - event = minimal_http_binding.decode_event env, allow_opaque: true + event = minimal_http_binding.decode_event(env, allow_opaque: true) assert_kind_of CloudEvents::Event::Opaque, event assert event.batch? assert_equal my_json_batch_encoded, event.content @@ -307,20 +307,20 @@ def assert_request_matches env, headers, body it "raises UnsupportedFormatError when a format is not recognized" do env = { "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+hello" + "CONTENT_TYPE" => "application/cloudevents+hello", } assert_raises CloudEvents::UnsupportedFormatError do - http_binding.decode_event env + http_binding.decode_event(env) end end it "raises FormatSyntaxError when decoding malformed JSON event" do env = { "rack.input" => StringIO.new("!!!"), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } - error = assert_raises CloudEvents::FormatSyntaxError do - http_binding.decode_event env + error = assert_raises(CloudEvents::FormatSyntaxError) do + http_binding.decode_event(env) end assert_kind_of JSON::ParserError, error.cause end @@ -328,10 +328,10 @@ def assert_request_matches env, headers, body it "raises FormatSyntaxError when decoding malformed JSON batch" do env = { "rack.input" => StringIO.new("!!!"), - "CONTENT_TYPE" => "application/cloudevents-batch+json" + "CONTENT_TYPE" => "application/cloudevents-batch+json", } - error = assert_raises CloudEvents::FormatSyntaxError do - http_binding.decode_event env + error = assert_raises(CloudEvents::FormatSyntaxError) do + http_binding.decode_event(env) end assert_kind_of JSON::ParserError, error.cause end @@ -341,20 +341,20 @@ def assert_request_matches env, headers, body "HTTP_CE_ID" => my_id, "HTTP_CE_SOURCE" => my_source_string, "HTTP_CE_TYPE" => my_type, - "HTTP_CE_SPECVERSION" => "0.1" + "HTTP_CE_SPECVERSION" => "0.1", } assert_raises CloudEvents::SpecVersionError do - http_binding.decode_event env + http_binding.decode_event(env) end end it "raises NotCloudEventError when a content-type is not recognized" do env = { "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/json" + "CONTENT_TYPE" => "application/json", } assert_raises CloudEvents::NotCloudEventError do - http_binding.decode_event env + http_binding.decode_event(env) end end @@ -362,10 +362,10 @@ def assert_request_matches env, headers, body env = { "REQUEST_METHOD" => "GET", "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } assert_raises CloudEvents::NotCloudEventError do - http_binding.decode_event env + http_binding.decode_event(env) end end @@ -373,70 +373,70 @@ def assert_request_matches env, headers, body env = { "REQUEST_METHOD" => "HEAD", "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/cloudevents+json" + "CONTENT_TYPE" => "application/cloudevents+json", } assert_raises CloudEvents::NotCloudEventError do - http_binding.decode_event env + http_binding.decode_event(env) end end end describe "encode_event" do it "encodes an event with text contenxt type to json-structured mode" do - headers, body = http_binding.encode_event my_simple_event, structured_format: true, sort: true + headers, body = http_binding.encode_event(my_simple_event, structured_format: true, sort: true) assert_equal({ "Content-Type" => "application/cloudevents+json; charset=utf-8" }, headers) assert_equal my_json_struct_encoded, body end it "encodes an event with json contenxt type to json-structured mode" do - headers, body = http_binding.encode_event my_json_event, structured_format: true, sort: true + headers, body = http_binding.encode_event(my_json_event, structured_format: true, sort: true) assert_equal({ "Content-Type" => "application/cloudevents+json; charset=utf-8" }, headers) assert_equal my_json_data_struct_encoded, body end it "encodes a batch of events to json-structured mode" do - headers, body = http_binding.encode_event [my_simple_event], structured_format: true, sort: true + headers, body = http_binding.encode_event([my_simple_event], structured_format: true, sort: true) assert_equal({ "Content-Type" => "application/cloudevents-batch+json; charset=utf-8" }, headers) assert_equal my_json_batch_encoded, body end it "encodes an event with text content type to binary mode" do - headers, body = http_binding.encode_event my_simple_event + headers, body = http_binding.encode_event(my_simple_event) assert_request_matches my_simple_binary_mode, headers, body end it "encodes an event with json content type to binary mode" do - headers, body = http_binding.encode_event my_json_event + headers, body = http_binding.encode_event(my_json_event) assert_request_matches my_json_binary_mode, headers, body end it "encodes an event omitting optional attributes to binary mode" do - headers, body = http_binding.encode_event my_minimal_event + headers, body = http_binding.encode_event(my_minimal_event) assert_request_matches my_minimal_binary_mode, headers, body end it "encodes an event with extension attributes to binary mode" do - headers, body = http_binding.encode_event my_extensions_event + headers, body = http_binding.encode_event(my_extensions_event) assert_request_matches my_extensions_binary_mode, headers, body end it "encodes an event with non-ascii attribute characters to binary mode" do - headers, body = http_binding.encode_event my_nonascii_event + headers, body = http_binding.encode_event(my_nonascii_event) assert_request_matches my_nonascii_binary_mode, headers, body end it "decodes a structured event using opaque" do - event = CloudEvents::Event::Opaque.new my_json_struct_encoded, - CloudEvents::ContentType.new("application/cloudevents+json") - headers, body = minimal_http_binding.encode_event event + event = CloudEvents::Event::Opaque.new(my_json_struct_encoded, + CloudEvents::ContentType.new("application/cloudevents+json")) + headers, body = minimal_http_binding.encode_event(event) assert_equal({ "Content-Type" => "application/cloudevents+json" }, headers) assert_equal my_json_struct_encoded, body end it "decodes a structured batch using opaque" do - event = CloudEvents::Event::Opaque.new my_json_batch_encoded, - CloudEvents::ContentType.new("application/cloudevents-batch+json") - headers, body = minimal_http_binding.encode_event event + event = CloudEvents::Event::Opaque.new(my_json_batch_encoded, + CloudEvents::ContentType.new("application/cloudevents-batch+json")) + headers, body = minimal_http_binding.encode_event(event) assert_equal({ "Content-Type" => "application/cloudevents-batch+json" }, headers) assert_equal my_json_batch_encoded, body end @@ -444,69 +444,69 @@ def assert_request_matches env, headers, body describe "deprecated methods" do it "decodes a binary mode rack env with text content type" do - event = http_binding.decode_rack_env my_simple_binary_mode + event = http_binding.decode_rack_env(my_simple_binary_mode) expected_attributes = my_simple_event.to_h - expected_attributes.delete "data_encoded" + expected_attributes.delete("data_encoded") assert_equal expected_attributes, event.to_h end it "encodes an event with text contenxt type to binary mode" do - headers, body = http_binding.encode_binary_content my_simple_event, sort: true + headers, body = http_binding.encode_binary_content(my_simple_event, sort: true) assert_request_matches my_simple_binary_mode, headers, body end it "returns nil from the legacy decode method when a content-type is not recognized" do env = { "rack.input" => StringIO.new(my_json_struct_encoded), - "CONTENT_TYPE" => "application/json" + "CONTENT_TYPE" => "application/json", } - assert_nil http_binding.decode_rack_env env + assert_nil http_binding.decode_rack_env(env) end end describe "probable_event?" do it "detects a probable binary event" do env = { - "HTTP_CE_SPECVERSION" => "1.0" + "HTTP_CE_SPECVERSION" => "1.0", } - assert http_binding.probable_event? env + assert http_binding.probable_event?(env) end it "detects a probable structured event" do env = { - "CONTENT_TYPE" => "application/cloudevents+myformat" + "CONTENT_TYPE" => "application/cloudevents+myformat", } - assert http_binding.probable_event? env + assert http_binding.probable_event?(env) end it "detects a probable batch event" do env = { - "CONTENT_TYPE" => "application/cloudevents-batch+myformat" + "CONTENT_TYPE" => "application/cloudevents-batch+myformat", } - assert http_binding.probable_event? env + assert http_binding.probable_event?(env) end it "detects a content type that is unlikely an event" do env = { - "CONTENT_TYPE" => "application/json" + "CONTENT_TYPE" => "application/json", } - refute http_binding.probable_event? env + refute http_binding.probable_event?(env) end it "detects that an HTTP GET unlikely an event" do env = { "REQUEST_METHOD" => "GET", - "HTTP_CE_SPECVERSION" => "1.0" + "HTTP_CE_SPECVERSION" => "1.0", } - refute http_binding.probable_event? env + refute http_binding.probable_event?(env) end it "detects that an HTTP HEAD unlikely an event" do env = { "REQUEST_METHOD" => "HEAD", - "HTTP_CE_SPECVERSION" => "1.0" + "HTTP_CE_SPECVERSION" => "1.0", } - refute http_binding.probable_event? env + refute http_binding.probable_event?(env) end end end diff --git a/test/test_json_format.rb b/test/test_json_format.rb index 2dd7496..e83b7a8 100644 --- a/test/test_json_format.rb +++ b/test/test_json_format.rb @@ -11,31 +11,31 @@ let(:json_format) { CloudEvents::JsonFormat.new } let(:my_id) { "my_id" } let(:my_source_string) { "/my_source" } - let(:my_source) { URI.parse my_source_string } + let(:my_source) { URI.parse(my_source_string) } let(:my_type) { "my_type" } let(:my_json_data) { { "a" => 12_345, "b" => "hello", "c" => [true, false, nil] } } - let(:my_json_string_data) { JSON.dump my_json_data } - let(:my_doubly_encoded_json_string_data) { JSON.dump my_json_string_data } + let(:my_json_string_data) { JSON.dump(my_json_data) } + let(:my_doubly_encoded_json_string_data) { JSON.dump(my_json_string_data) } let(:my_data_string) { "12345" } let(:my_json_encoded_data_string) { '"12345"' } let(:my_base64_data) { "/w==" } - let(:my_binary_string) { my_base64_data.unpack1 "m" } + let(:my_binary_string) { my_base64_data.unpack1("m") } let(:my_content_encoding) { "8bit" } let(:my_content_type_string) { "text/plain; charset=us-ascii" } - let(:my_content_type) { CloudEvents::ContentType.new my_content_type_string } + let(:my_content_type) { CloudEvents::ContentType.new(my_content_type_string) } let(:my_json_content_type_string) { "application/json; charset=us-ascii" } - let(:my_json_content_type) { CloudEvents::ContentType.new my_json_content_type_string } + let(:my_json_content_type) { CloudEvents::ContentType.new(my_json_content_type_string) } let(:my_binary_content_type_string) { "application/octet-stream" } - let(:my_binary_content_type) { CloudEvents::ContentType.new my_binary_content_type_string } + let(:my_binary_content_type) { CloudEvents::ContentType.new(my_binary_content_type_string) } let(:my_schema_string) { "/my_schema" } - let(:my_schema) { URI.parse my_schema_string } + let(:my_schema) { URI.parse(my_schema_string) } let(:my_subject) { "my_subject" } let(:my_time_string) { "2020-01-12T20:52:05-08:00" } - let(:my_time) { DateTime.rfc3339 my_time_string } + let(:my_time) { DateTime.rfc3339(my_time_string) } let(:structured_content_type_string) { "application/cloudevents+json; charset=utf-8" } - let(:structured_content_type) { CloudEvents::ContentType.new structured_content_type_string } + let(:structured_content_type) { CloudEvents::ContentType.new(structured_content_type_string) } let(:batched_content_type_string) { "application/cloudevents-batch+json; charset=utf-8" } - let(:batched_content_type) { CloudEvents::ContentType.new batched_content_type_string } + let(:batched_content_type) { CloudEvents::ContentType.new(batched_content_type_string) } describe "v0" do let(:spec_version_v0) { "0.3" } @@ -50,7 +50,7 @@ "specversion" => spec_version_v0, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end let :my_string_struct_v0 do @@ -64,14 +64,14 @@ "specversion" => spec_version_v0, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end - let(:my_json_struct_v0_string) { JSON.dump my_json_struct_v0 } - let(:my_batch_v0_string) { JSON.dump [my_string_struct_v0, my_json_struct_v0] } + let(:my_json_struct_v0_string) { JSON.dump(my_json_struct_v0) } + let(:my_batch_v0_string) { JSON.dump([my_string_struct_v0, my_json_struct_v0]) } it "decodes and encodes a struct with string data" do - event = json_format.decode_hash_structure my_string_struct_v0 + event = json_format.decode_hash_structure(my_string_struct_v0) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -82,12 +82,12 @@ assert_equal my_schema, event.schema_url assert_equal my_subject, event.subject assert_equal my_time, event.time - struct = json_format.encode_hash_structure event + struct = json_format.encode_hash_structure(event) assert_equal my_string_struct_v0, struct end it "decodes and encodes a struct with json data" do - event = json_format.decode_hash_structure my_json_struct_v0 + event = json_format.decode_hash_structure(my_json_struct_v0) assert_equal my_id, event.id assert_equal my_source, event.source assert_equal my_type, event.type @@ -98,12 +98,12 @@ assert_equal my_schema, event.schema_url assert_equal my_subject, event.subject assert_equal my_time, event.time - struct = json_format.encode_hash_structure event + struct = json_format.encode_hash_structure(event) assert_equal my_json_struct_v0, struct end it "decodes and encodes json-encoded content" do - result = json_format.decode_event content: my_json_struct_v0_string, content_type: structured_content_type + result = json_format.decode_event(content: my_json_struct_v0_string, content_type: structured_content_type) event = result[:event] assert_kind_of CloudEvents::Event, event assert_equal my_id, event.id @@ -116,7 +116,7 @@ assert_equal my_schema, event.schema_url assert_equal my_subject, event.subject assert_equal my_time, event.time - result = json_format.encode_event event: event, sort: true + result = json_format.encode_event(event: event, sort: true) string = result[:content] content_type = result[:content_type] assert_equal my_json_struct_v0_string, string @@ -124,7 +124,7 @@ end it "decodes and encodes json-encoded batch" do - result = json_format.decode_event content: my_batch_v0_string, content_type: batched_content_type + result = json_format.decode_event(content: my_batch_v0_string, content_type: batched_content_type) events = result[:event_batch] assert_kind_of Array, events assert_equal 2, events.size @@ -150,7 +150,7 @@ assert_equal my_schema, event.schema_url assert_equal my_subject, event.subject assert_equal my_time, event.time - result = json_format.encode_event event_batch: events, sort: true + result = json_format.encode_event(event_batch: events, sort: true) string = result[:content] content_type = result[:content_type] assert_equal my_batch_v0_string, string @@ -158,7 +158,7 @@ end it "refuses to decode non-json content types" do - assert_nil json_format.decode_event content: my_json_struct_v0_string, content_type: my_content_type + assert_nil json_format.decode_event(content: my_json_struct_v0_string, content_type: my_content_type) end end @@ -174,11 +174,11 @@ "specversion" => spec_version_v1, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end let :my_json_event_v1 do - CloudEvents::Event::V1.new data: my_json_data, + CloudEvents::Event::V1.new(data: my_json_data, data_encoded: my_json_string_data, datacontenttype: my_json_content_type_string, dataschema: my_schema_string, @@ -187,7 +187,7 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_json_string_struct_v1 do { @@ -199,11 +199,11 @@ "specversion" => spec_version_v1, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end let :my_json_string_event_v1 do - CloudEvents::Event::V1.new data: my_json_string_data, + CloudEvents::Event::V1.new(data: my_json_string_data, data_encoded: my_doubly_encoded_json_string_data, datacontenttype: my_json_content_type_string, dataschema: my_schema_string, @@ -212,7 +212,7 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_string_struct_v1 do { @@ -224,11 +224,11 @@ "specversion" => spec_version_v1, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end let :my_string_event_v1 do - CloudEvents::Event::V1.new data_encoded: my_data_string, + CloudEvents::Event::V1.new(data_encoded: my_data_string, datacontenttype: my_content_type_string, dataschema: my_schema_string, id: my_id, @@ -236,10 +236,10 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_decoded_string_event_v1 do - CloudEvents::Event::V1.new data_encoded: my_data_string, + CloudEvents::Event::V1.new(data_encoded: my_data_string, data: my_data_string, datacontenttype: my_content_type_string, dataschema: my_schema_string, @@ -248,10 +248,10 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_nonencoded_string_event_v1 do - CloudEvents::Event::V1.new data: my_data_string, + CloudEvents::Event::V1.new(data: my_data_string, datacontenttype: my_content_type_string, dataschema: my_schema_string, id: my_id, @@ -259,7 +259,7 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_base64_struct_v1 do { @@ -271,11 +271,11 @@ "specversion" => spec_version_v1, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end let :my_binary_event_v1 do - CloudEvents::Event::V1.new data_encoded: my_binary_string, + CloudEvents::Event::V1.new(data_encoded: my_binary_string, datacontenttype: my_binary_content_type_string, dataschema: my_schema_string, id: my_id, @@ -283,7 +283,7 @@ specversion: spec_version_v1, subject: my_subject, time: my_time_string, - type: my_type + type: my_type) end let :my_incomplete_struct_with_nils_v1 do { @@ -294,34 +294,34 @@ "source" => my_source_string, "specversion" => spec_version_v1, "time" => nil, - "type" => my_type + "type" => my_type, } end let :my_incomplete_struct_v1 do my_incomplete_struct_with_nils_v1.delete_if { |_k, v| v.nil? } end let :my_incomplete_event_v1 do - CloudEvents::Event::V1.new data: my_json_data, + CloudEvents::Event::V1.new(data: my_json_data, data_encoded: my_json_string_data, datacontenttype: my_json_content_type_string, id: my_id, source: my_source_string, specversion: spec_version_v1, - type: my_type + type: my_type) end let :my_minimal_struct_v1 do { "id" => my_id, "source" => my_source_string, "specversion" => spec_version_v1, - "type" => my_type + "type" => my_type, } end let :my_minimal_event_v1 do - CloudEvents::Event::V1.new id: my_id, + CloudEvents::Event::V1.new(id: my_id, source: my_source_string, specversion: spec_version_v1, - type: my_type + type: my_type) end let :my_typeless_struct_v1 do { @@ -332,64 +332,64 @@ "specversion" => spec_version_v1, "subject" => my_subject, "time" => my_time_string, - "type" => my_type + "type" => my_type, } end - let(:my_json_struct_v1_string) { JSON.dump my_json_struct_v1 } - let(:my_batch_v1_string) { JSON.dump [my_base64_struct_v1, my_json_struct_v1] } + let(:my_json_struct_v1_string) { JSON.dump(my_json_struct_v1) } + let(:my_batch_v1_string) { JSON.dump([my_base64_struct_v1, my_json_struct_v1]) } describe "decode_hash_structure" do it "decodes a struct with string data" do - event = json_format.decode_hash_structure my_string_struct_v1 + event = json_format.decode_hash_structure(my_string_struct_v1) assert_equal my_string_event_v1, event refute event.data_decoded? end it "decodes a struct with string data and a decoder" do text_decoder = CloudEvents::TextFormat.new - event = json_format.decode_hash_structure my_string_struct_v1, data_decoder: text_decoder + event = json_format.decode_hash_structure(my_string_struct_v1, data_decoder: text_decoder) assert_equal my_decoded_string_event_v1, event assert event.data_decoded? end it "decodes a struct with base64 data" do - event = json_format.decode_hash_structure my_base64_struct_v1 + event = json_format.decode_hash_structure(my_base64_struct_v1) assert_equal my_binary_event_v1, event refute event.data_decoded? end it "decodes a struct with json object data" do - event = json_format.decode_hash_structure my_json_struct_v1 + event = json_format.decode_hash_structure(my_json_struct_v1) assert_equal my_json_event_v1, event assert event.data_decoded? end it "decodes a struct with json string data" do - event = json_format.decode_hash_structure my_json_string_struct_v1 + event = json_format.decode_hash_structure(my_json_string_struct_v1) assert_equal my_json_string_event_v1, event assert event.data_decoded? end it "decodes a struct without content type" do - event = json_format.decode_hash_structure my_typeless_struct_v1, charset: "us-ascii" + event = json_format.decode_hash_structure(my_typeless_struct_v1, charset: "us-ascii") assert_equal my_json_event_v1, event assert event.data_decoded? assert_equal my_json_content_type, event.data_content_type end it "decodes a struct with nulls" do - event = json_format.decode_hash_structure my_incomplete_struct_with_nils_v1 + event = json_format.decode_hash_structure(my_incomplete_struct_with_nils_v1) assert_equal my_incomplete_event_v1, event assert_nil event.data_schema assert_nil event.subject assert_nil event.time hash = event.to_h - refute hash.include? "subject" - refute hash.include? "time" + refute hash.include?("subject") + refute hash.include?("time") end it "decodes a minimal struct" do - event = json_format.decode_hash_structure my_minimal_struct_v1 + event = json_format.decode_hash_structure(my_minimal_struct_v1) assert_equal my_minimal_event_v1, event refute event.data_decoded? end @@ -399,16 +399,16 @@ "text/json", "application/json; charset=utf-8", "application/blah+json", - "application/blah+json; foo=bar" + "application/blah+json; foo=bar", ].each do |content_type| it "recognizes #{content_type} as a json-object-data special case" do my_struct = my_minimal_struct_v1.merge( { "data" => my_json_string_data, - "datacontenttype" => content_type + "datacontenttype" => content_type, } ) - event = json_format.decode_hash_structure my_struct + event = json_format.decode_hash_structure(my_struct) assert_equal my_json_string_data, event.data assert_equal my_doubly_encoded_json_string_data, event.data_encoded assert event.data_decoded? @@ -418,48 +418,48 @@ describe "encode_hash_structure" do it "encodes an event with string data" do - struct = json_format.encode_hash_structure my_string_event_v1 + struct = json_format.encode_hash_structure(my_string_event_v1) assert_equal my_string_struct_v1, struct end it "encodes an event with string data and an encoder" do text_encoder = CloudEvents::TextFormat.new - struct = json_format.encode_hash_structure my_nonencoded_string_event_v1, data_encoder: text_encoder + struct = json_format.encode_hash_structure(my_nonencoded_string_event_v1, data_encoder: text_encoder) assert_equal my_string_struct_v1, struct end it "encodes an event with binary data" do - struct = json_format.encode_hash_structure my_binary_event_v1 + struct = json_format.encode_hash_structure(my_binary_event_v1) assert_equal my_base64_struct_v1, struct end it "encodes an event with json object data" do - struct = json_format.encode_hash_structure my_json_event_v1 + struct = json_format.encode_hash_structure(my_json_event_v1) assert_equal my_json_struct_v1, struct end it "encodes an event with json string data" do - struct = json_format.encode_hash_structure my_json_string_event_v1 + struct = json_format.encode_hash_structure(my_json_string_event_v1) assert_equal my_json_string_struct_v1, struct end it "encodes an event without content type" do - event = CloudEvents::Event.create spec_version: spec_version_v1, + event = CloudEvents::Event.create(spec_version: spec_version_v1, id: my_id, source: my_source, type: my_type, - data: my_json_data - struct = json_format.encode_hash_structure event + data: my_json_data) + struct = json_format.encode_hash_structure(event) assert_equal "application/json", struct["datacontenttype"] end it "encodes an event with nulls" do - struct = json_format.encode_hash_structure my_incomplete_event_v1 + struct = json_format.encode_hash_structure(my_incomplete_event_v1) assert_equal my_incomplete_struct_v1, struct end it "encodes a minimal event" do - struct = json_format.encode_hash_structure my_minimal_event_v1 + struct = json_format.encode_hash_structure(my_minimal_event_v1) assert_equal my_minimal_struct_v1, struct end @@ -468,18 +468,18 @@ "text/json", "application/json; charset=utf-8", "application/blah+json", - "application/blah+json; foo=bar" + "application/blah+json; foo=bar", ].each do |content_type| it "encodes a string data value when content type is #{content_type}" do - event = my_minimal_event_v1.with data: my_json_string_data, data_content_type: content_type - struct = json_format.encode_hash_structure event + event = my_minimal_event_v1.with(data: my_json_string_data, data_content_type: content_type) + struct = json_format.encode_hash_structure(event) assert_equal my_json_string_data, struct["data"] end it "encodes a data_encoded value when content type is #{content_type}" do - event = my_minimal_event_v1.with data_encoded: my_doubly_encoded_json_string_data, - data_content_type: content_type - struct = json_format.encode_hash_structure event + event = my_minimal_event_v1.with(data_encoded: my_doubly_encoded_json_string_data, + data_content_type: content_type) + struct = json_format.encode_hash_structure(event) assert_equal my_json_string_data, struct["data"] end end @@ -487,17 +487,17 @@ describe "decode_event" do it "decodes a single event" do - result = json_format.decode_event content: my_json_struct_v1_string, content_type: structured_content_type + result = json_format.decode_event(content: my_json_struct_v1_string, content_type: structured_content_type) assert_equal my_json_event_v1, result[:event] end it "decodes a batch event" do - result = json_format.decode_event content: my_batch_v1_string, content_type: batched_content_type + result = json_format.decode_event(content: my_batch_v1_string, content_type: batched_content_type) assert_equal [my_binary_event_v1, my_json_event_v1], result[:event_batch] end it "refuses to decode non-json content types" do - assert_nil json_format.decode_event content: my_json_struct_v1_string, content_type: my_content_type + assert_nil json_format.decode_event(content: my_json_struct_v1_string, content_type: my_content_type) end it "raises SpecVersionError when JSON input has a bad specversion" do @@ -507,11 +507,11 @@ "id" => my_id, "source" => my_source_string, "specversion" => "0.1", - "type" => my_type + "type" => my_type, } - malformed_input_string = JSON.dump malformed_input + malformed_input_string = JSON.dump(malformed_input) assert_raises CloudEvents::SpecVersionError do - json_format.decode_event content: malformed_input_string, content_type: structured_content_type + json_format.decode_event(content: malformed_input_string, content_type: structured_content_type) end end @@ -521,24 +521,24 @@ "datacontenttype" => my_content_type_string, "source" => my_source_string, "specversion" => "1.0", - "type" => my_type + "type" => my_type, } - malformed_input_string = JSON.dump malformed_input + malformed_input_string = JSON.dump(malformed_input) assert_raises CloudEvents::AttributeError do - json_format.decode_event content: malformed_input_string, content_type: structured_content_type + json_format.decode_event(content: malformed_input_string, content_type: structured_content_type) end end it "raises FormatSyntaxError when decoding malformed JSON event" do - error = assert_raises CloudEvents::FormatSyntaxError do - json_format.decode_event content: "!!!", content_type: structured_content_type + error = assert_raises(CloudEvents::FormatSyntaxError) do + json_format.decode_event(content: "!!!", content_type: structured_content_type) end assert_kind_of JSON::ParserError, error.cause end it "raises FormatSyntaxError when decoding malformed JSON batch" do - error = assert_raises CloudEvents::FormatSyntaxError do - json_format.decode_event content: "!!!", content_type: batched_content_type + error = assert_raises(CloudEvents::FormatSyntaxError) do + json_format.decode_event(content: "!!!", content_type: batched_content_type) end assert_kind_of JSON::ParserError, error.cause end @@ -546,21 +546,21 @@ describe "encode_event" do it "encodes a single event" do - result = json_format.encode_event event: my_json_event_v1, sort: true + result = json_format.encode_event(event: my_json_event_v1, sort: true) assert_equal my_json_struct_v1_string, result[:content] assert_equal structured_content_type, result[:content_type] end it "encodes a batch event" do - result = json_format.encode_event event_batch: [my_binary_event_v1, my_json_event_v1], sort: true + result = json_format.encode_event(event_batch: [my_binary_event_v1, my_json_event_v1], sort: true) assert_equal my_batch_v1_string, result[:content] assert_equal batched_content_type, result[:content_type] end it "raises UnsupportedFormatError on missing data_encoded and an unrecognized media type" do - event = my_string_event_v1.with data: "hello", data_content_type: "application/blah" + event = my_string_event_v1.with(data: "hello", data_content_type: "application/blah") assert_raises CloudEvents::UnsupportedFormatError do - json_format.encode_event event: event, sort: true + json_format.encode_event(event: event, sort: true) end end end @@ -569,12 +569,12 @@ describe "data conversion" do let(:my_json_string) { '{"foo":"bar"}' } let(:my_json_object) { { "foo" => "bar" } } - let(:spec_version_1) { "1.0" } + let(:spec_version1) { "1.0" } it "decodes a JSON object" do - result = json_format.decode_data spec_version: spec_version_1, + result = json_format.decode_data(spec_version: spec_version1, content: my_json_string, - content_type: my_json_content_type + content_type: my_json_content_type) obj = result[:data] content_type = result[:content_type] assert_equal my_json_object, obj @@ -582,18 +582,18 @@ end it "raises FormatSyntaxError when decoding malformed JSON" do - error = assert_raises CloudEvents::FormatSyntaxError do - json_format.decode_data spec_version: spec_version_1, + error = assert_raises(CloudEvents::FormatSyntaxError) do + json_format.decode_data(spec_version: spec_version1, content: "!!!", - content_type: my_json_content_type + content_type: my_json_content_type) end assert_kind_of JSON::ParserError, error.cause end it "encodes a JSON object" do - result = json_format.encode_data spec_version: spec_version_1, + result = json_format.encode_data(spec_version: spec_version1, data: my_json_object, - content_type: my_json_content_type + content_type: my_json_content_type) str = result[:content] content_type = result[:content_type] assert_equal my_json_string, str @@ -601,15 +601,15 @@ end it "declines to decode when given a non-JSON content type" do - assert_nil json_format.decode_data spec_version: spec_version_1, + assert_nil json_format.decode_data(spec_version: spec_version1, content: my_json_string, - content_type: my_content_type + content_type: my_content_type) end it "declines to encode when given a non-JSON content type" do - assert_nil json_format.encode_data spec_version: spec_version_1, + assert_nil json_format.encode_data(spec_version: spec_version1, data: my_json_object, - content_type: my_content_type + content_type: my_content_type) end end end diff --git a/test/test_text_format.rb b/test/test_text_format.rb index aebf499..ece0bd3 100644 --- a/test/test_text_format.rb +++ b/test/test_text_format.rb @@ -16,19 +16,19 @@ "text/plain", "text/plain; charset=utf-8", "text/html", - "application/octet-stream" + "application/octet-stream", ].each do |content_type| it "decodes content type #{content_type}" do - content_type = CloudEvents::ContentType.new content_type - result = text_format.decode_data content: content, content_type: content_type + content_type = CloudEvents::ContentType.new(content_type) + result = text_format.decode_data(content: content, content_type: content_type) assert_equal content, result[:data] assert_equal content_type, result[:content_type] end end it "fails to decode content type application/json" do - content_type = CloudEvents::ContentType.new "application/json" - result = text_format.decode_data content: content, content_type: content_type + content_type = CloudEvents::ContentType.new("application/json") + result = text_format.decode_data(content: content, content_type: content_type) assert_nil result end end @@ -38,19 +38,19 @@ "text/plain", "text/plain; charset=utf-8", "text/html", - "application/octet-stream" + "application/octet-stream", ].each do |content_type| it "encodes content type #{content_type}" do - content_type = CloudEvents::ContentType.new content_type - result = text_format.encode_data data: content, content_type: content_type + content_type = CloudEvents::ContentType.new(content_type) + result = text_format.encode_data(data: content, content_type: content_type) assert_equal content, result[:content] assert_equal content_type, result[:content_type] end end it "fails to encode content type application/json" do - content_type = CloudEvents::ContentType.new "application/json" - result = text_format.encode_data data: content, content_type: content_type + content_type = CloudEvents::ContentType.new("application/json") + result = text_format.encode_data(data: content, content_type: content_type) assert_nil result end end