From 083e7575d998c544a04ea063f535c2551d8a58d7 Mon Sep 17 00:00:00 2001 From: 0x1eef <0x1eef@protonmail.com> Date: Sat, 14 Jan 2023 09:06:38 -0300 Subject: [PATCH] Add the standardrb linter standardrb provides a relaxed set of linting rules that provide the benefits of a linter without the headaches that can come from the slightly excessive rubocop defaults. New rules we'd like to adopt can be enabled in `.rubocop.yml`, and similarly rules we don't want to adopt can be disabled in `.rubocop.yml`. --- .rubocop.yml | 54 + Gemfile | 14 +- Guardfile | 10 +- Rakefile | 24 +- examples/debugger.rb | 8 +- examples/logging.rb | 4 +- examples/webrick.rb | 4 +- lib/webmachine/adapters/rack.rb | 72 +- lib/webmachine/adapters/rack_mapped.rb | 2 +- lib/webmachine/adapters/webrick.rb | 23 +- lib/webmachine/configuration.rb | 2 +- lib/webmachine/constants.rb | 24 +- lib/webmachine/cookie.rb | 30 +- lib/webmachine/decision/conneg.rb | 48 +- lib/webmachine/decision/flow.rb | 39 +- lib/webmachine/decision/fsm.rb | 8 +- lib/webmachine/decision/helpers.rb | 42 +- lib/webmachine/dispatcher/route.rb | 54 +- lib/webmachine/errors.rb | 15 +- lib/webmachine/media_type.rb | 10 +- lib/webmachine/quoted_string.rb | 6 +- lib/webmachine/request.rb | 17 +- lib/webmachine/resource/authentication.rb | 7 +- lib/webmachine/resource/encodings.rb | 12 +- lib/webmachine/response.rb | 16 +- lib/webmachine/spec/adapter_lint.rb | 122 +-- lib/webmachine/spec/test_resource.rb | 44 +- lib/webmachine/streaming/encoder.rb | 4 +- lib/webmachine/streaming/io_encoder.rb | 7 +- lib/webmachine/trace/fsm.rb | 43 +- lib/webmachine/trace/resource_proxy.rb | 2 +- lib/webmachine/trace/trace_resource.rb | 46 +- lib/webmachine/translation.rb | 2 +- lib/webmachine/version.rb | 2 +- memory_test.rb | 5 +- spec/spec_helper.rb | 18 +- spec/webmachine/adapter_spec.rb | 14 +- spec/webmachine/adapters/rack_mapped_spec.rb | 38 +- spec/webmachine/adapters/rack_spec.rb | 46 +- spec/webmachine/adapters/webrick_spec.rb | 12 +- spec/webmachine/application_spec.rb | 22 +- spec/webmachine/chunked_body_spec.rb | 12 +- spec/webmachine/configuration_spec.rb | 10 +- spec/webmachine/cookie_spec.rb | 88 +- spec/webmachine/decision/conneg_spec.rb | 151 ++- spec/webmachine/decision/flow_spec.rb | 921 +++++++++++------- spec/webmachine/decision/fsm_spec.rb | 28 +- spec/webmachine/decision/helpers_spec.rb | 101 +- spec/webmachine/dispatcher/route_spec.rb | 172 ++-- spec/webmachine/dispatcher_spec.rb | 56 +- spec/webmachine/errors_spec.rb | 8 +- spec/webmachine/etags_spec.rb | 14 +- spec/webmachine/events_spec.rb | 34 +- spec/webmachine/headers_spec.rb | 46 +- spec/webmachine/media_type_spec.rb | 92 +- spec/webmachine/request_spec.rb | 177 ++-- spec/webmachine/rescueable_exception_spec.rb | 6 +- .../resource/authentication_spec.rb | 34 +- spec/webmachine/response_spec.rb | 43 +- spec/webmachine/trace/fsm_spec.rb | 14 +- spec/webmachine/trace/resource_proxy_spec.rb | 23 +- spec/webmachine/trace/trace_store_spec.rb | 26 +- spec/webmachine/trace_spec.rb | 8 +- webmachine.gemspec | 41 +- 64 files changed, 1688 insertions(+), 1389 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..70b0b6bc --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,54 @@ +## +# Plugins +require: + - standard + +## +# Defaults: standardrb +inherit_gem: + standard: config/base.yml + +## +# Rules that break from standardrb defaults +Style/StringLiterals: + EnforcedStyle: single_quotes + +## +# Disabled rules +Lint/AssignmentInCondition: + Enabled: false +Lint/FloatComparison: + Enabled: false +Lint/ConstantDefinitionInBlock: + Enabled: false +Lint/EmptyWhen: + Exclude: + - "lib/webmachine/dispatcher/route.rb" +Lint/DuplicateMethods: + Exclude: + - "lib/webmachine/application.rb" +Lint/UnderscorePrefixedVariableName: + Exclude: + - "lib/webmachine/trace/resource_proxy.rb" + - "spec/webmachine/dispatcher_spec.rb" +Lint/NestedMethodDefinition: + Exclude: + - "spec/webmachine/decision/flow_spec.rb" +Lint/RescueException: + Exclude: + - "spec/webmachine/decision/fsm_spec.rb" +Lint/RaiseException: + Exclude: + - "spec/webmachine/decision/fsm_spec.rb" +Style/MissingRespondToMissing: + Exclude: + - "lib/webmachine/request.rb" +Style/NilComparison: + Exclude: + - "spec/webmachine/decision/falsey_spec.rb" +Style/GlobalVars: + Exclude: + - "lib/webmachine/decision/conneg.rb" + +AllCops: + SuggestExtensions: false diff --git a/Gemfile b/Gemfile index b0bcff49..013e857b 100644 --- a/Gemfile +++ b/Gemfile @@ -3,16 +3,16 @@ source 'https://rubygems.org' gemspec group :development do - gem "yard", "~> 0.9" - gem "rake", "~> 12.0" + gem 'yard', '~> 0.9' + gem 'rake', '~> 12.0' end group :test do - gem "rspec", "~> 3.0", ">= 3.6.0" - gem "rspec-its", "~> 1.2" - gem "rack", "~> 2.0" - gem "rack-test", "~> 0.7" - gem "websocket_parser", "~>1.0" + gem 'rspec', '~> 3.0', '>= 3.6.0' + gem 'rspec-its', '~> 1.2' + gem 'rack', '~> 2.0' + gem 'rack-test', '~> 0.7' + gem 'websocket_parser', '~>1.0' end group :guard do diff --git a/Guardfile b/Guardfile index 357f38e2..1d7af7b7 100644 --- a/Guardfile +++ b/Guardfile @@ -1,11 +1,11 @@ gemset = ENV['RVM_GEMSET'] || 'webmachine' gemset = "@#{gemset}" unless gemset.to_s == '' -rvms = %W[ 1.8.7 1.9.2 1.9.3 jruby rbx ].map {|v| "#{v}#{gemset}" } +rvms = %W[1.8.7 1.9.2 1.9.3 jruby rbx].map { |v| "#{v}#{gemset}" } -guard 'rspec', :cli => "--color --profile", :growl => true, :rvm => rvms do - watch(%r{^lib/webmachine/locale/.+$}) { "spec" } +guard 'rspec', cli: '--color --profile', growl: true, rvm: rvms do + watch(%r{^lib/webmachine/locale/.+$}) { 'spec' } watch(%r{^spec/.+_spec\.rb$}) - watch(%r{^lib/(.+)\.rb$}){ |m| "spec/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { 'spec' } end diff --git a/Rakefile b/Rakefile index 9c5f3a5e..c9f54e96 100644 --- a/Rakefile +++ b/Rakefile @@ -1,44 +1,44 @@ -require "bundler/gem_tasks" +require 'bundler/gem_tasks' begin require 'yard' require 'yard/rake/yardoc_task' YARD::Rake::YardocTask.new do |doc| - doc.files = Dir["lib/**/*.rb"] + ['README.md'] - doc.options = ["-m", "markdown"] + doc.files = Dir['lib/**/*.rb'] + ['README.md'] + doc.options = ['-m', 'markdown'] end rescue LoadError end -desc "Validate the gemspec file." +desc 'Validate the gemspec file.' task :validate_gemspec do - Gem::Specification.load("webmachine.gemspec").validate + Gem::Specification.load('webmachine.gemspec').validate end -task :build => :validate_gemspec +task build: :validate_gemspec -desc "Cleans up white space in source files" +desc 'Cleans up white space in source files' task :clean_whitespace do no_file_cleaned = true - Dir["**/*.rb"].each do |file| + Dir['**/*.rb'].each do |file| contents = File.read(file) cleaned_contents = contents.gsub(/([ \t]+)$/, '') unless cleaned_contents == contents no_file_cleaned = false puts " - Cleaned #{file}" - File.open(file, 'w') { |f| f.write(cleaned_contents) } + File.write(file, cleaned_contents) end end if no_file_cleaned - puts "No files with trailing whitespace found" + puts 'No files with trailing whitespace found' end end require 'rspec/core/rake_task' -desc "Run specs" +desc 'Run specs' RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :spec diff --git a/examples/debugger.rb b/examples/debugger.rb index cff11c90..ec4bffa5 100644 --- a/examples/debugger.rb +++ b/examples/debugger.rb @@ -2,21 +2,23 @@ require 'webmachine/trace' class MyTracedResource < Webmachine::Resource - def trace?; true; end + def trace? + true + end def resource_exists? case request.query['e'] when 'true' true when 'fail' - raise "BOOM" + raise 'BOOM' else false end end def to_html - "You found me." + 'You found me.' end end diff --git a/examples/logging.rb b/examples/logging.rb index 24ceac7f..82e27c3a 100644 --- a/examples/logging.rb +++ b/examples/logging.rb @@ -18,7 +18,7 @@ def handle_event(event) resource = event.payload[:resource] code = event.payload[:code] - puts "[%s] method=%s uri=%s code=%d resource=%s time=%.4f" % [ + puts '[%s] method=%s uri=%s code=%d resource=%s time=%.4f' % [ Time.now.iso8601, request.method, request.uri.to_s, code, resource, event.duration ] @@ -34,7 +34,7 @@ def handle_event(event) app.configure do |config| config.adapter = :WEBrick - config.adapter_options = {:AccessLog => [], :Logger => Logger.new('/dev/null')} + config.adapter_options = {AccessLog: [], Logger: Logger.new('/dev/null')} end end diff --git a/examples/webrick.rb b/examples/webrick.rb index 3c899ca8..a6a81268 100644 --- a/examples/webrick.rb +++ b/examples/webrick.rb @@ -6,11 +6,11 @@ def last_modified end def encodings_provided - { "gzip" => :encode_gzip, "identity" => :encode_identity } + {'gzip' => :encode_gzip, 'identity' => :encode_identity} end def to_html - "Hello from WebmachineHello, world!" + 'Hello from WebmachineHello, world!' end end diff --git a/lib/webmachine/adapters/rack.rb b/lib/webmachine/adapters/rack.rb index 50c7a0c8..6148b4b3 100644 --- a/lib/webmachine/adapters/rack.rb +++ b/lib/webmachine/adapters/rack.rb @@ -47,9 +47,9 @@ class Rack < Adapter # Start the Rack adapter def run options = DEFAULT_OPTIONS.merge({ - :app => self, - :Port => application.configuration.port, - :Host => application.configuration.ip + app: self, + Port: application.configuration.port, + Host: application.configuration.ip }).merge(application.configuration.adapter_options) @server = ::Rack::Server.new(options) @@ -69,33 +69,34 @@ def call(env) response.headers[SERVER] = VERSION_STRING - rack_status = response.code + rack_status = response.code rack_headers = response.headers.flattened(NEWLINE) rack_body = case response.body - when String # Strings are enumerable in ruby 1.8 - [response.body] - else - if (io_body = IO.try_convert(response.body)) - io_body - elsif response.body.respond_to?(:call) - Webmachine::ChunkedBody.new(Array(response.body.call)) - elsif response.body.respond_to?(:each) - # This might be an IOEncoder with a Content-Length, which shouldn't be chunked. - if response.headers[TRANSFER_ENCODING] == "chunked" - Webmachine::ChunkedBody.new(response.body) - else - response.body - end - else - [response.body.to_s] - end - end + when String # Strings are enumerable in ruby 1.8 + [response.body] + else + if (io_body = IO.try_convert(response.body)) + io_body + elsif response.body.respond_to?(:call) + Webmachine::ChunkedBody.new(Array(response.body.call)) + elsif response.body.respond_to?(:each) + # This might be an IOEncoder with a Content-Length, which shouldn't be chunked. + if response.headers[TRANSFER_ENCODING] == 'chunked' + Webmachine::ChunkedBody.new(response.body) + else + response.body + end + else + [response.body.to_s] + end + end rack_res = RackResponse.new(rack_body, rack_status, rack_headers) rack_res.finish end protected + def routing_tokens(rack_req) nil # no-op for default, un-mapped rack adapter end @@ -105,15 +106,15 @@ def base_uri(rack_req) end private + def build_webmachine_request(rack_req, headers) RackRequest.new(rack_req.request_method, - rack_req.url, - headers, - RequestBody.new(rack_req), - routing_tokens(rack_req), - base_uri(rack_req), - rack_req.env - ) + rack_req.url, + headers, + RequestBody.new(rack_req), + routing_tokens(rack_req), + base_uri(rack_req), + rack_req.env) end class RackRequest < Webmachine::Request @@ -129,14 +130,14 @@ class RackResponse ONE_FIVE = '1.5'.freeze def initialize(body, status, headers) - @body = body - @status = status + @body = body + @status = status @headers = headers end def finish @headers[CONTENT_TYPE] ||= TEXT_HTML if rack_release_enforcing_content_type - @headers.delete(CONTENT_TYPE) if response_without_body + @headers.delete(CONTENT_TYPE) if response_without_body [@status, @headers, @body] end @@ -188,10 +189,13 @@ def to_s # @yieldparam [String] chunk a chunk of the request body def each if @value - @value.each {|chunk| yield chunk } + @value.each { |chunk| yield chunk } else @value = [] - @request.body.each {|chunk| @value << chunk; yield chunk } + @request.body.each { |chunk| + @value << chunk + yield chunk + } end end end # class RequestBody diff --git a/lib/webmachine/adapters/rack_mapped.rb b/lib/webmachine/adapters/rack_mapped.rb index 01b1bd8b..c924c867 100644 --- a/lib/webmachine/adapters/rack_mapped.rb +++ b/lib/webmachine/adapters/rack_mapped.rb @@ -26,7 +26,7 @@ class RackMapped < Rack def routing_tokens(rack_req) routing_match = rack_req.path_info.match(Webmachine::Request::ROUTING_PATH_MATCH) - routing_path = routing_match ? routing_match[1] : "" + routing_path = routing_match ? routing_match[1] : '' routing_path.split(SLASH) end diff --git a/lib/webmachine/adapters/webrick.rb b/lib/webmachine/adapters/webrick.rb index 5967787b..d6a3e90e 100644 --- a/lib/webmachine/adapters/webrick.rb +++ b/lib/webmachine/adapters/webrick.rb @@ -17,9 +17,9 @@ class WEBrick < Adapter # Starts the WEBrick adapter def run options = DEFAULT_OPTIONS.merge({ - :Port => application.configuration.port, - :BindAddress => application.configuration.ip, - :application => application + Port: application.configuration.port, + BindAddress: application.configuration.ip, + application: application }).merge(application.configuration.adapter_options) @server = Server.new(options) @server.start @@ -27,7 +27,6 @@ def run # WEBRick::HTTPServer that is run by the WEBrick adapter. class Server < ::WEBrick::HTTPServer - def initialize(options) @application = options[:application] super(options) @@ -36,29 +35,29 @@ def initialize(options) # Handles a request def service(wreq, wres) header = Webmachine::Headers.new - wreq.each {|k,v| header[k] = v } + wreq.each { |k, v| header[k] = v } request = Webmachine::Request.new(wreq.request_method, - wreq.request_uri, - header, - LazyRequestBody.new(wreq)) + wreq.request_uri, + header, + LazyRequestBody.new(wreq)) response = Webmachine::Response.new @application.dispatcher.dispatch(request, response) wres.status = response.code.to_i - headers = response.headers.flattened.reject { |k,v| k == 'Set-Cookie' } - headers.each { |k,v| wres[k] = v } + headers = response.headers.flattened.reject { |k, v| k == 'Set-Cookie' } + headers.each { |k, v| wres[k] = v } cookies = [response.headers['Set-Cookie'] || []].flatten cookies.each { |c| wres.cookies << c } - wres[SERVER] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(" ") + wres[SERVER] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(' ') case response.body when String wres.body << response.body when Enumerable wres.chunked = response.headers[TRANSFER_ENCODING] == 'chunked' - response.body.each {|part| wres.body << part } + response.body.each { |part| wres.body << part } else if response.body.respond_to?(:call) wres.chunked = true diff --git a/lib/webmachine/configuration.rb b/lib/webmachine/configuration.rb index d64e6847..5555a92c 100644 --- a/lib/webmachine/configuration.rb +++ b/lib/webmachine/configuration.rb @@ -12,7 +12,7 @@ module Webmachine # @return [Configuration] the default configuration def Configuration.default - new("0.0.0.0", 8080, :WEBrick, {}) + new('0.0.0.0', 8080, :WEBrick, {}) end # Yields the current configuration to the passed block. diff --git a/lib/webmachine/constants.rb b/lib/webmachine/constants.rb index 8541cc65..444f4eb8 100644 --- a/lib/webmachine/constants.rb +++ b/lib/webmachine/constants.rb @@ -28,20 +28,20 @@ MATCHES_ALL = '*/*'.freeze - GET_METHOD = "GET" - HEAD_METHOD = "HEAD" - POST_METHOD = "POST" - PUT_METHOD = "PUT" - DELETE_METHOD = "DELETE" - OPTIONS_METHOD = "OPTIONS" - TRACE_METHOD = "TRACE" - CONNECT_METHOD = "CONNECT" + GET_METHOD = 'GET' + HEAD_METHOD = 'HEAD' + POST_METHOD = 'POST' + PUT_METHOD = 'PUT' + DELETE_METHOD = 'DELETE' + OPTIONS_METHOD = 'OPTIONS' + TRACE_METHOD = 'TRACE' + CONNECT_METHOD = 'CONNECT' STANDARD_HTTP_METHODS = [ - GET_METHOD, HEAD_METHOD, POST_METHOD, - PUT_METHOD, DELETE_METHOD, TRACE_METHOD, - CONNECT_METHOD, OPTIONS_METHOD - ].map!(&:freeze) + GET_METHOD, HEAD_METHOD, POST_METHOD, + PUT_METHOD, DELETE_METHOD, TRACE_METHOD, + CONNECT_METHOD, OPTIONS_METHOD + ].map!(&:freeze) STANDARD_HTTP_METHODS.freeze # A colon diff --git a/lib/webmachine/cookie.rb b/lib/webmachine/cookie.rb index b30535de..dfb07990 100644 --- a/lib/webmachine/cookie.rb +++ b/lib/webmachine/cookie.rb @@ -11,7 +11,7 @@ class Cookie def self.parse(cstr, include_dups = false) cookies = {} (cstr || '').split(/\s*[;,]\s*/n).each { |c| - k,v = c.split(/\s*=\s*/, 2).map { |s| unescape(s) } + k, v = c.split(/\s*=\s*/, 2).map { |s| unescape(s) } case cookies[k] when nil @@ -31,7 +31,7 @@ def self.parse(cstr, include_dups = false) # Allowed keys for the attributes parameter of # {Webmachine::Cookie#initialize} ALLOWED_ATTRIBUTES = [:secure, :httponly, :path, :domain, - :comment, :maxage, :expires, :version] + :comment, :maxage, :expires, :version] # If the cookie is HTTP only def http_only? @@ -83,21 +83,21 @@ def to_s attributes = ALLOWED_ATTRIBUTES.select { |a| @attributes[a] }.map do |a| case a when :httponly - "HttpOnly" if @attributes[a] + 'HttpOnly' if @attributes[a] when :secure - "Secure" if @attributes[a] + 'Secure' if @attributes[a] when :maxage - "Max-Age=" + @attributes[a].to_s + 'Max-Age=' + @attributes[a].to_s when :expires - "Expires=" + rfc2822(@attributes[a]) + 'Expires=' + rfc2822(@attributes[a]) when :comment - "Comment=" + escape(@attributes[a].to_s) + 'Comment=' + escape(@attributes[a].to_s) else - a.to_s.sub(/^\w/) { $&.capitalize } + "=" + @attributes[a].to_s + a.to_s.sub(/^\w/) { $&.capitalize } + '=' + @attributes[a].to_s end end - ([escape(name) + "=" + escape(value)] + attributes).join("; ") + ([escape(name) + '=' + escape(value)] + attributes).join('; ') end private @@ -110,7 +110,7 @@ def rfc2822(time) time.strftime('%a, %d %b %Y %T GMT') end - if URI.respond_to?(:decode_www_form_component) and defined?(::Encoding) + if URI.respond_to?(:decode_www_form_component) && defined?(::Encoding) # Escape a cookie def escape(s) URI.encode_www_form_component(s) @@ -134,7 +134,7 @@ def self.unescape(s, encoding = Encoding::UTF_8) # @private TBLDECWWWCOMP_ = {} 256.times do |i| - h, l = i>>4, i&15 + h, l = i >> 4, i & 15 TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr @@ -148,9 +148,9 @@ def self.unescape(s, encoding = Encoding::UTF_8) # This decodes + to SP. # # @private - def self.unescape(str, enc=nil) - raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%\h\h|[^%]+)*\z/ =~ str - str.gsub(/\+|%\h\h/){|c| TBLDECWWWCOMP_[c] } + def self.unescape(str, enc = nil) + raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%\h\h|[^%]+)*\z/.match?(str) + str.gsub(/\+|%\h\h/) { |c| TBLDECWWWCOMP_[c] } end # Encode given +str+ to URL-encoded form data. @@ -163,7 +163,7 @@ def self.unescape(str, enc=nil) # # @private def escape(str) - str.to_s.gsub(/[^*\-.0-9A-Z_a-z]/){|c| TBLENCWWWCOMP_[c] } + str.to_s.gsub(/[^*\-.0-9A-Z_a-z]/) { |c| TBLENCWWWCOMP_[c] } end end end diff --git a/lib/webmachine/decision/conneg.rb b/lib/webmachine/decision/conneg.rb index 30e85b05..204634de 100644 --- a/lib/webmachine/decision/conneg.rb +++ b/lib/webmachine/decision/conneg.rb @@ -14,7 +14,7 @@ module Conneg # appropriate media type. # @api private def choose_media_type(provided, header) - types = Array(header).map{|h| h.split(SPLIT_COMMA) }.flatten + types = Array(header).map { |h| h.split(SPLIT_COMMA) }.flatten requested = MediaTypeList.build(types) provided = provided.map do |p| # normalize_provided MediaType.parse(p) @@ -43,7 +43,7 @@ def choose_encoding(provided, header) # @api private def choose_charset(provided, header) if provided && !provided.empty? - charsets = provided.map {|c| c.first } + charsets = provided.map { |c| c.first } if charset = do_choose(charsets, header, HAS_ENCODING ? Encoding.default_external.name : kcode_charset) metadata[CHARSET] = charset end @@ -62,17 +62,17 @@ def choose_language(provided, header) any_ok = star_priority && star_priority > 0.0 accepted = requested.find do |priority, range| if priority == 0.0 - provided.delete_if {|tag| language_match(range, tag) } + provided.delete_if { |tag| language_match(range, tag) } false else - provided.any? {|tag| language_match(range, tag) } + provided.any? { |tag| language_match(range, tag) } end end chosen = if accepted - provided.find {|tag| language_match(accepted.last, tag) } - elsif any_ok - provided.first - end + provided.find { |tag| language_match(accepted.last, tag) } + elsif any_ok + provided.first + end if chosen metadata['Language'] = chosen response.headers['Content-Language'] = chosen @@ -91,14 +91,14 @@ def choose_language(provided, header) # is "-". # @api private def language_match(range, tag) - range.downcase == tag.downcase || tag =~ /^#{Regexp.escape(range)}\-/i + range.downcase == tag.downcase || tag =~ /^#{Regexp.escape(range)}-/i end # Makes an conneg choice based what is accepted and what is # provided. # @api private def do_choose(choices, header, default) - choices = choices.dup.map {|s| s.downcase } + choices = choices.dup.map { |s| s.downcase } accepted = PriorityList.build(header.split(SPLIT_COMMA)) default_priority = accepted.priority_of(default) star_priority = accepted.priority_of(STAR) @@ -112,12 +112,13 @@ def do_choose(choices, header, default) choices.include?(acceptable.downcase) end end - (chosen && chosen.last) || # Use the matching one + chosen&.last || # Use the matching one (any_ok && choices.first) || # Or first if "*" (default_ok && choices.include?(default) && default) # Or default end private + # Matches acceptable items that include 'q' values CONNEG_REGEX = /^\s*(\S+);\s*q=(\S*)\s*$/.freeze @@ -138,13 +139,13 @@ def media_match(requested, provided) def kcode_charset case $KCODE when /^U/i - "UTF-8" + 'UTF-8' when /^S/i - "Shift-JIS" + 'Shift-JIS' when /^B/i - "Big5" - else #when /^A/i, nil - "ASCII" + 'Big5' + else # when /^A/i, nil + 'ASCII' end end @@ -157,7 +158,7 @@ class PriorityList # Given an acceptance list, create a PriorityList from them. def self.build(list) new.tap do |plist| - list.each {|item| plist.add_header_val(item) } + list.each { |item| plist.add_header_val(item) } end end @@ -166,7 +167,7 @@ def self.build(list) # Creates a {PriorityList}. # @see PriorityList::build def initialize - @hash = Hash.new {|h,k| h[k] = [] } + @hash = Hash.new { |h, k| h[k] = [] } @index = {} end @@ -185,8 +186,8 @@ def add(q, choice) def add_header_val(c) if c =~ CONNEG_REGEX choice, q = $1, $2 - q = "0" << q if q =~ /^\./ # handle strange FeedBurner Accept - add(q.to_f,choice) + q = '0' << q if /^\./.match?(q) # handle strange FeedBurner Accept + add(q.to_f, choice) else add(1.0, c) end @@ -212,8 +213,8 @@ def priority_of(choice) # @yieldparam [Float] q the acceptable item's priority # @yieldparam [String] v the acceptable item def each - @hash.to_a.sort.reverse_each do |q,l| - l.each {|v| yield q, v } + @hash.to_a.sort.reverse_each do |q, l| + l.each { |v| yield q, v } end end end @@ -232,10 +233,9 @@ def add_header_val(c) q = mt.params.delete('q') || 1.0 add(q.to_f, mt) rescue ArgumentError - raise MalformedRequest, t('invalid_media_type', :type => c) + raise MalformedRequest, t('invalid_media_type', type: c) end end - end # module Conneg end # module Decision end # module Webmachine diff --git a/lib/webmachine/decision/flow.rb b/lib/webmachine/decision/flow.rb index 87d264dd..5ecc8f54 100644 --- a/lib/webmachine/decision/flow.rb +++ b/lib/webmachine/decision/flow.rb @@ -64,7 +64,7 @@ def b10 if resource.allowed_methods.include?(request.method) :b9 else - response.headers["Allow"] = resource.allowed_methods.join(", ") + response.headers['Allow'] = resource.allowed_methods.join(', ') 405 end end @@ -82,13 +82,13 @@ def b9a when true :b9b when false - response.body = "Content-MD5 header does not match request body." + response.body = 'Content-MD5 header does not match request body.' 400 else # not_validated if decode64(request.content_md5) == Digest::MD5.hexdigest(request.body) :b9b else - response.body = "Content-MD5 header does not match request body." + response.body = 'Content-MD5 header does not match request body.' 400 end end @@ -123,7 +123,7 @@ def b7 CONTENT = /content-/.freeze # Okay Content-* Headers? def b6 - decision_test(resource.valid_content_headers?(request.headers.grep(CONTENT)), :b5, 501) + decision_test(resource.valid_content_headers?(request.headers.grep(CONTENT)), :b5, 501) end # Known Content-Type? @@ -158,7 +158,7 @@ def c3 # Acceptable media type available? def c4 - types = resource.content_types_provided.map {|pair| pair.first } + types = resource.content_types_provided.map { |pair| pair.first } chosen_type = choose_media_type(types, request.accept) if !chosen_type 406 @@ -215,7 +215,7 @@ def f6 end response.headers[CONTENT_TYPE] = chosen_type.to_s if !request.accept_encoding - choose_encoding(resource.encodings_provided, "identity;q=1.0,*;q=0.5") ? :g7 : 406 + choose_encoding(resource.encodings_provided, 'identity;q=1.0,*;q=0.5') ? :g7 : 406 else :f7 end @@ -229,7 +229,7 @@ def f7 # Resource exists? def g7 # This is the first place after all conneg, so set Vary here - response.headers['Vary'] = variances.join(", ") if variances.any? + response.headers['Vary'] = variances.join(', ') if variances.any? decision_test(resource.resource_exists?, :g8, :h7) end @@ -240,12 +240,12 @@ def g8 # If-Match: * exists? def g9 - quote(request.if_match) == '"*"' ? :h10 : :g11 + (quote(request.if_match) == '"*"') ? :h10 : :g11 end # ETag in If-Match def g11 - request_etags = request.if_match.split(SPLIT_COMMA).map {|etag| ETag.new(etag) } + request_etags = request.if_match.split(SPLIT_COMMA).map { |etag| ETag.new(etag) } request_etags.include?(ETag.new(resource.generate_etag)) ? :h10 : 412 end @@ -271,7 +271,7 @@ def h11 # Last-Modified > I-UM-S? def h12 - resource.last_modified > metadata['If-Unmodified-Since'] ? 412 : :i12 + (resource.last_modified > metadata['If-Unmodified-Since']) ? 412 : :i12 end # Moved permanently? (apply PUT to different URI) @@ -299,7 +299,7 @@ def i12 # If-none-match: * exists? def i13 - quote(request.if_none_match) == '"*"' ? :j18 : :k13 + (quote(request.if_none_match) == '"*"') ? :j18 : :k13 end # GET or HEAD? @@ -327,10 +327,10 @@ def k7 # Etag in if-none-match? def k13 - request_etags = request.if_none_match.split(SPLIT_COMMA).map {|etag| ETag.new(etag) } + request_etags = request.if_none_match.split(SPLIT_COMMA).map { |etag| ETag.new(etag) } resource_etag = resource.generate_etag if resource_etag && request_etags.include?(ETag.new(resource_etag)) - :j18 + :j18 else :l13 end @@ -371,12 +371,12 @@ def l14 # IMS > Now? def l15 - metadata['If-Modified-Since'] > Time.now ? :m16 : :l17 + (metadata['If-Modified-Since'] > Time.now) ? :m16 : :l17 end # Last-Modified > IMS? def l17 - resource.last_modified.nil? || resource.last_modified > metadata['If-Modified-Since'] ? :m16 : 304 + (resource.last_modified.nil? || resource.last_modified > metadata['If-Modified-Since']) ? :m16 : 304 end # POST? @@ -415,7 +415,7 @@ def n11 if resource.post_is_create? case uri = resource.create_path when nil - raise InvalidResource, t('create_path_nil', :class => resource.class) + raise InvalidResource, t('create_path_nil', class: resource.class) when URI, String base_uri = resource.base_uri || request.base_uri new_uri = URI.join(base_uri.to_s, uri) @@ -431,7 +431,7 @@ def n11 when Integer return result else - raise InvalidResource, t('process_post_invalid', :result => result.inspect) + raise InvalidResource, t('process_post_invalid', result: result.inspect) end end if response.is_redirect? @@ -471,7 +471,7 @@ def o18 if request.get? || request.head? add_caching_headers content_type = metadata[CONTENT_TYPE] - handler = resource.content_types_provided.find {|ct, _| content_type.type_matches?(MediaType.parse(ct)) }.last + handler = resource.content_types_provided.find { |ct, _| content_type.type_matches?(MediaType.parse(ct)) }.last result = resource.send(handler) if Integer === result result @@ -507,9 +507,8 @@ def p3 # New resource? def p11 - !response.headers[LOCATION] ? :o20 : 201 + (!response.headers[LOCATION]) ? :o20 : 201 end - end # module Flow end # module Decision end # module Webmachine diff --git a/lib/webmachine/decision/fsm.rb b/lib/webmachine/decision/fsm.rb index f3252551..44ec2484 100644 --- a/lib/webmachine/decision/fsm.rb +++ b/lib/webmachine/decision/fsm.rb @@ -36,11 +36,11 @@ def run when Symbol # Next state state = result else # You bwoke it - raise InvalidResource, t('fsm_broke', :state => state, :result => result.inspect) + raise InvalidResource, t('fsm_broke', state: state, result: result.inspect) end end rescue => e - Webmachine.render_error(500, request, response, :message => e.message) + Webmachine.render_error(500, request, response, message: e.message) ensure trace_response(response) end @@ -53,11 +53,11 @@ def handle_exceptions resource.handle_exception(e) 500 rescue MalformedRequest => e - Webmachine.render_error(400, request, response, :message => e.message) + Webmachine.render_error(400, request, response, message: e.message) 400 end - def respond(code, headers={}) + def respond(code, headers = {}) response.code = code response.headers.merge!(headers) case code diff --git a/lib/webmachine/decision/helpers.rb b/lib/webmachine/decision/helpers.rb index f445175a..892ad063 100644 --- a/lib/webmachine/decision/helpers.rb +++ b/lib/webmachine/decision/helpers.rb @@ -31,24 +31,24 @@ def encode_body body = response.body chosen_charset = metadata[CHARSET] chosen_encoding = metadata[CONTENT_ENCODING] - charsetter = resource.charsets_provided && resource.charsets_provided.find {|c,_| c == chosen_charset }.last || :charset_nop + charsetter = resource.charsets_provided&.find { |c, _| c == chosen_charset }&.last || :charset_nop encoder = resource.encodings_provided[chosen_encoding] response.body = case body - when String # 1.8 treats Strings as Enumerable - resource.send(encoder, resource.send(charsetter, body)) - when IO, StringIO - IOEncoder.new(resource, encoder, charsetter, body) - when Fiber - FiberEncoder.new(resource, encoder, charsetter, body) - when Enumerable - EnumerableEncoder.new(resource, encoder, charsetter, body) - else - if body.respond_to?(:call) - CallableEncoder.new(resource, encoder, charsetter, body) - else - resource.send(encoder, resource.send(charsetter, body)) - end - end + when String # 1.8 treats Strings as Enumerable + resource.send(encoder, resource.send(charsetter, body)) + when IO, StringIO + IOEncoder.new(resource, encoder, charsetter, body) + when Fiber + FiberEncoder.new(resource, encoder, charsetter, body) + when Enumerable + EnumerableEncoder.new(resource, encoder, charsetter, body) + else + if body.respond_to?(:call) + CallableEncoder.new(resource, encoder, charsetter, body) + else + resource.send(encoder, resource.send(charsetter, body)) + end + end if body_is_fixed_length? ensure_content_length(response) else @@ -60,7 +60,7 @@ def encode_body # Assists in receiving request bodies def accept_helper content_type = MediaType.parse(request.content_type || 'application/octet-stream') - acceptable = resource.content_types_accepted.find {|ct, _| content_type.match?(ct) } + acceptable = resource.content_types_accepted.find { |ct, _| content_type.match?(ct) } if acceptable resource.send(acceptable.last) else @@ -71,10 +71,10 @@ def accept_helper # Computes the entries for the 'Vary' response header def variances resource.variances.tap do |v| - v.unshift "Accept-Language" if resource.languages_provided.size > 1 - v.unshift "Accept-Charset" if resource.charsets_provided && resource.charsets_provided.size > 1 - v.unshift "Accept-Encoding" if resource.encodings_provided.size > 1 - v.unshift "Accept" if resource.content_types_provided.size > 1 + v.unshift 'Accept-Language' if resource.languages_provided.size > 1 + v.unshift 'Accept-Charset' if resource.charsets_provided && resource.charsets_provided.size > 1 + v.unshift 'Accept-Encoding' if resource.encodings_provided.size > 1 + v.unshift 'Accept' if resource.content_types_provided.size > 1 end end diff --git a/lib/webmachine/dispatcher/route.rb b/lib/webmachine/dispatcher/route.rb index 0f4b82ee..b7a27ce3 100644 --- a/lib/webmachine/dispatcher/route.rb +++ b/lib/webmachine/dispatcher/route.rb @@ -28,6 +28,21 @@ class Route # String version of MATCH_ALL, deprecated. Use the symbol instead. MATCH_ALL_STR = '*'.freeze + # Decode a string using the scheme described in RFC 3986 2.1. Percent-Encoding (https://www.ietf.org/rfc/rfc3986.txt) + def self.rfc3986_percent_decode(value) + s = StringScanner.new(value) + result = '' + until s.eos? + encoded_val = s.scan(/%([0-9a-fA-F]){2}/) + result << if encoded_val.nil? + s.getch + else + [encoded_val[1..-1]].pack('H*') + end + end + result + end + # Creates a new Route that will associate a pattern to a # {Resource}. # @@ -59,24 +74,24 @@ class Route # @yieldparam [Request] req the request object # @see Dispatcher#add_route def initialize(path_spec, *args, &block) - if args.last.is_a? Hash - bindings = args.pop + bindings = if args.last.is_a? Hash + args.pop else - bindings = {} + {} end resource = args.pop guards = args - guards << block if block_given? + guards << block if block warn t('match_all_symbol') if path_spec.include? MATCH_ALL_STR @path_spec = path_spec - @guards = guards - @resource = resource - @bindings = bindings + @guards = guards + @resource = resource + @bindings = bindings - raise ArgumentError, t('not_resource_class', :class => resource.name) unless resource < Resource + raise ArgumentError, t('not_resource_class', class: resource.name) unless resource < Resource end # Determines whether the given request matches this route and @@ -94,11 +109,12 @@ def apply(request) request.disp_path = request.routing_tokens.join(SLASH) request.path_info = @bindings.dup tokens = request.routing_tokens - depth, trailing = bind(tokens, request.path_info) + _depth, trailing = bind(tokens, request.path_info) request.path_tokens = trailing || [] end private + # Attempts to match the path spec against the path tokens, while # accumulating variable bindings. # @param [Array] tokens the list of path segments @@ -125,9 +141,8 @@ def bind(tokens, bindings) if spec.first.named_captures.empty? bindings[:captures] = (bindings[:captures] || []) + matches.captures else - spec.first.named_captures.reduce(bindings) do |bindings, (name, idxs)| - bindings[name.to_sym] = matches.captures[idxs.first-1] - bindings + spec.first.named_captures.each_with_object(bindings) do |(name, idxs), bindings| + bindings[name.to_sym] = matches.captures[idxs.first - 1] end end else @@ -144,21 +159,6 @@ def bind(tokens, bindings) depth += 1 end end - - # Decode a string using the scheme described in RFC 3986 2.1. Percent-Encoding (https://www.ietf.org/rfc/rfc3986.txt) - def self.rfc3986_percent_decode(value) - s = StringScanner.new(value) - result = '' - until s.eos? - encoded_val = s.scan(/%([0-9a-fA-F]){2}/) - result << if encoded_val.nil? - s.getch - else - [encoded_val[1..-1]].pack('H*') - end - end - result - end end # class Route end # module Dispatcher end # module Webmachine diff --git a/lib/webmachine/errors.rb b/lib/webmachine/errors.rb index 72477c73..8ebb1c9f 100644 --- a/lib/webmachine/errors.rb +++ b/lib/webmachine/errors.rb @@ -14,23 +14,22 @@ module Webmachine # @param [Response] req the response object # @param [Hash] options keys to override the defaults when rendering # the response body - def self.render_error(code, req, res, options={}) + def self.render_error(code, req, res, options = {}) res.code = code unless res.body title, message = t(["errors.#{code}.title", "errors.#{code}.message"], - { :method => req.method, - :error => res.error}.merge(options)) - res.body = t("errors.standard_body", - {:title => title, - :message => message, - :version => Webmachine::SERVER_STRING}.merge(options)) + {method: req.method, + error: res.error}.merge(options)) + res.body = t('errors.standard_body', + {title: title, + message: message, + version: Webmachine::SERVER_STRING}.merge(options)) res.headers[CONTENT_TYPE] = TEXT_HTML end ensure_content_length(res) ensure_date_header(res) end - # Superclass of all errors generated by Webmachine. class Error < ::StandardError; end diff --git a/lib/webmachine/media_type.rb b/lib/webmachine/media_type.rb index d6bdf988..da0c12d0 100644 --- a/lib/webmachine/media_type.rb +++ b/lib/webmachine/media_type.rb @@ -23,11 +23,11 @@ def self.parse(obj) obj when MEDIA_TYPE_REGEX type, raw_params = $1, $2 - params = Hash[raw_params.scan(PARAMS_REGEX).map { |m| [m[0], m[2].to_s] }] + params = raw_params.scan(PARAMS_REGEX).map { |m| [m[0], m[2].to_s] }.to_h new(type, params) else unless Array === obj && String === obj[0] && Hash === obj[1] - raise ArgumentError, t('invalid_media_type', :type => obj.inspect) + raise ArgumentError, t('invalid_media_type', type: obj.inspect) end type = parse(obj[0]) type.params.merge!(obj[1]) @@ -43,7 +43,7 @@ def self.parse(obj) # @param [String] type the main media type, e.g. application/json # @param [Hash] params the media type parameters - def initialize(type, params={}) + def initialize(type, params = {}) @type, @params = type, params end @@ -88,13 +88,13 @@ def match?(other) # @param [Hash] params the requested params # @return [true,false] whether it is an acceptable match def params_match?(other) - other.all? {|k,v| params[k] == v } + other.all? { |k, v| params[k] == v } end # Reconstitutes the type into a String # @return [String] the type as a String def to_s - [type, *params.map {|k,v| "#{k}=#{v}" }].join(";") + [type, *params.map { |k, v| "#{k}=#{v}" }].join(';') end # @return [String] The major type, e.g. "application", "text", "image" diff --git a/lib/webmachine/quoted_string.rb b/lib/webmachine/quoted_string.rb index 7c09a91c..dd5039e0 100644 --- a/lib/webmachine/quoted_string.rb +++ b/lib/webmachine/quoted_string.rb @@ -19,10 +19,10 @@ def unquote(str) # Ensures that quotes exist around a quoted-string def quote(str) - if str =~ QS_ANCHORED + if QS_ANCHORED.match?(str) str else - %Q{"#{escape_quotes str}"} + %("#{escape_quotes str}") end end @@ -33,7 +33,7 @@ def escape_quotes(str) # Unescapes quotes within a quoted string def unescape_quotes(str) - str.gsub(%r{\\}, '') + str.delete('\\') end end end diff --git a/lib/webmachine/request.rb b/lib/webmachine/request.rb index bad4f1f3..f8f3b771 100644 --- a/lib/webmachine/request.rb +++ b/lib/webmachine/request.rb @@ -21,7 +21,7 @@ class Request # @param [Headers] headers the HTTP request headers # @param [String,#to_s,#each,nil] body the entity included in the # request, if present - def initialize(method, uri, headers, body, routing_tokens=nil, base_uri=nil) + def initialize(method, uri, headers, body, routing_tokens = nil, base_uri = nil) @method, @headers, @body = method, headers, body @uri = build_uri(uri, headers) @routing_tokens = routing_tokens || @uri.path.match(ROUTING_PATH_MATCH)[1].split(SLASH) @@ -37,12 +37,12 @@ def initialize(method, uri, headers, body, routing_tokens=nil, base_uri=nil) # lowercased-underscored version of the header name, e.g. # `if_unmodified_since`. def method_missing(m, *args, &block) - if m =~ HTTP_HEADERS_MATCH + if HTTP_HEADERS_MATCH.match?(m) # Access headers more easily as underscored methods. header_name = m.to_s.tr(UNDERSCORE, DASH) if (header_value = @headers[header_name]) # Make future lookups faster. - self.class.class_eval <<-RUBY, __FILE__, __LINE__ + self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{m} @headers["#{header_name}"] end @@ -66,8 +66,8 @@ def has_body? def query unless @query @query = {} - (uri.query || '').split(/&/).each do |kv| - key, value = kv.split(/=/) + (uri.query || '').split('&').each do |kv| + key, value = kv.split('=') if key && value key, value = CGI.unescape(key), CGI.unescape(value) @query[key] = value @@ -82,9 +82,7 @@ def query # @return [Hash] # {} if no Cookies header set def cookies - unless @cookies - @cookies = Webmachine::Cookie.parse(headers['Cookie']) - end + @cookies ||= Webmachine::Cookie.parse(headers['Cookie']) @cookies end @@ -93,7 +91,7 @@ def cookies # @return [Boolean] # true if this request was made via HTTPS def https? - uri.scheme == "https" + uri.scheme == 'https' end # Is this a GET request? @@ -191,6 +189,5 @@ def build_uri(uri, headers) parse_host(uri, headers.fetch(HOST)) end - end # class Request end # module Webmachine diff --git a/lib/webmachine/resource/authentication.rb b/lib/webmachine/resource/authentication.rb index d3a3e976..427c9a36 100644 --- a/lib/webmachine/resource/authentication.rb +++ b/lib/webmachine/resource/authentication.rb @@ -23,14 +23,13 @@ module Authentication # @yieldparam [String] user the passed username # @yieldparam [String] password the passed password # @yieldreturn [true,false] whether the username/password is correct - def basic_auth(header, realm="Webmachine") - if header =~ BASIC_HEADER && (yield *$1.unpack('m*').first.split(/:/,2)) + def basic_auth(header, realm = 'Webmachine') + if header =~ BASIC_HEADER && yield(*$1.unpack1('m*').split(/:/, 2)) true else - %Q[Basic realm="#{realm}"] + %(Basic realm="#{realm}") end end - end # module Authentication end # class Resource end # module Webmachine diff --git a/lib/webmachine/resource/encodings.rb b/lib/webmachine/resource/encodings.rb index 40987f1e..3e6c0cad 100644 --- a/lib/webmachine/resource/encodings.rb +++ b/lib/webmachine/resource/encodings.rb @@ -15,23 +15,17 @@ def encode_identity(data) # The 'deflate' encoding, which uses libz's DEFLATE compression. def encode_deflate(data) # The deflate options were borrowed from Rack and Mongrel1. - Zlib::Deflate.deflate(data, *[Zlib::DEFAULT_COMPRESSION, - # drop the zlib header which causes both Safari and IE to choke - -Zlib::MAX_WBITS, - Zlib::DEF_MEM_LEVEL, - Zlib::DEFAULT_STRATEGY - ]) + Zlib::Deflate.deflate(data, Zlib::DEFAULT_COMPRESSION, -Zlib::MAX_WBITS, Zlib::DEF_MEM_LEVEL, Zlib::DEFAULT_STRATEGY) end # The 'gzip' encoding, which uses GNU Zip (via libz). # @note Because of the header/checksum requirements, gzip cannot # be used on streamed responses. def encode_gzip(data) - "".tap do |out| - Zlib::GzipWriter.wrap(StringIO.new(out)){|gz| gz << data } + ''.tap do |out| + Zlib::GzipWriter.wrap(StringIO.new(out)) { |gz| gz << data } end end - end # module Encodings end # class Resource end # module Webmachine diff --git a/lib/webmachine/response.rb b/lib/webmachine/response.rb index f1812259..73fee48e 100644 --- a/lib/webmachine/response.rb +++ b/lib/webmachine/response.rb @@ -35,7 +35,7 @@ def initialize # of the target resource, or manually set the Location header # using {#headers}. # @param [String, URI] location the target of the redirection - def do_redirect(location=nil) + def do_redirect(location = nil) headers['Location'] = location.to_s if location self.redirect = true end @@ -54,8 +54,8 @@ def set_cookie(name, value, attributes = {}) end end - alias :is_redirect? :redirect - alias :redirect_to :do_redirect + alias_method :is_redirect?, :redirect + alias_method :redirect_to, :do_redirect # A {Hash} that can flatten array values into single values with a separator class HeaderHash < ::Hash @@ -63,17 +63,15 @@ class HeaderHash < ::Hash # @param [String] The separator used to join Array values # @return [HeaderHash] A new {HeaderHash} with Array values flattened def flattened(separator = ',') - Hash[self.collect { |k,v| + collect { |k, v| case v when Array - [k,v.join(separator)] + [k, v.join(separator)] else - [k,v] + [k, v] end - }] - + }.to_h end end - end # class Response end # module Webmachine diff --git a/lib/webmachine/spec/adapter_lint.rb b/lib/webmachine/spec/adapter_lint.rb index 3bb08359..8a32b809 100644 --- a/lib/webmachine/spec/adapter_lint.rb +++ b/lib/webmachine/spec/adapter_lint.rb @@ -1,7 +1,7 @@ -require "webmachine/spec/test_resource" -require "net/http" +require 'webmachine/spec/test_resource' +require 'net/http' -ADDRESS = "127.0.0.1" +ADDRESS = '127.0.0.1' shared_examples_for :adapter_lint do attr_reader :client @@ -20,7 +20,7 @@ def find_free_port def create_test_application(port) Webmachine::Application.new.tap do |application| - application.dispatcher.add_route ["test"], Test::Resource + application.dispatcher.add_route ['test'], Test::Resource application.configure do |c| c.ip = ADDRESS @@ -62,9 +62,9 @@ def wait_until_server_responds_to(client) @server_thread.kill end - it "provides the request URI" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.request_uri" + it 'provides the request URI' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.request_uri' response = client.request(request) expect(response.body).to eq("http://#{ADDRESS}:#{@port}/test") end @@ -80,92 +80,92 @@ def wait_until_server_responds_to(client) # end # end - it "provides a string-like request body" do - request = Net::HTTP::Put.new("/test") - request.body = "Hello, World!" - request["Content-Type"] = "test/request.stringbody" + it 'provides a string-like request body' do + request = Net::HTTP::Put.new('/test') + request.body = 'Hello, World!' + request['Content-Type'] = 'test/request.stringbody' response = client.request(request) - expect(response["Content-Length"]).to eq("21") - expect(response.body).to eq("String: Hello, World!") + expect(response['Content-Length']).to eq('21') + expect(response.body).to eq('String: Hello, World!') end - it "provides an enumerable request body" do - request = Net::HTTP::Put.new("/test") - request.body = "Hello, World!" - request["Content-Type"] = "test/request.enumbody" + it 'provides an enumerable request body' do + request = Net::HTTP::Put.new('/test') + request.body = 'Hello, World!' + request['Content-Type'] = 'test/request.enumbody' response = client.request(request) - expect(response["Content-Length"]).to eq("19") - expect(response.body).to eq("Enum: Hello, World!") + expect(response['Content-Length']).to eq('19') + expect(response.body).to eq('Enum: Hello, World!') end - it "handles missing pages" do - request = Net::HTTP::Get.new("/missing") + it 'handles missing pages' do + request = Net::HTTP::Get.new('/missing') response = client.request(request) - expect(response.code).to eq("404") - expect(response["Content-Type"]).to eq("text/html") + expect(response.code).to eq('404') + expect(response['Content-Type']).to eq('text/html') end - it "handles empty response bodies" do - request = Net::HTTP::Post.new("/test") - request.body = "" + it 'handles empty response bodies' do + request = Net::HTTP::Post.new('/test') + request.body = '' response = client.request(request) - expect(response.code).to eq("204") - expect(["0", nil]).to include(response["Content-Length"]) + expect(response.code).to eq('204') + expect(['0', nil]).to include(response['Content-Length']) expect(response.body).to be_nil end - it "handles string response bodies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.stringbody" + it 'handles string response bodies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.stringbody' response = client.request(request) - expect(response["Content-Length"]).to eq("20") - expect(response.body).to eq("String response body") + expect(response['Content-Length']).to eq('20') + expect(response.body).to eq('String response body') end - it "handles enumerable response bodies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.enumbody" + it 'handles enumerable response bodies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.enumbody' response = client.request(request) - expect(response["Transfer-Encoding"]).to eq("chunked") - expect(response.body).to eq("Enumerable response body") + expect(response['Transfer-Encoding']).to eq('chunked') + expect(response.body).to eq('Enumerable response body') end - it "handles proc response bodies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.procbody" + it 'handles proc response bodies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.procbody' response = client.request(request) - expect(response["Transfer-Encoding"]).to eq("chunked") - expect(response.body).to eq("Proc response body") + expect(response['Transfer-Encoding']).to eq('chunked') + expect(response.body).to eq('Proc response body') end - it "handles fiber response bodies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.fiberbody" + it 'handles fiber response bodies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.fiberbody' response = client.request(request) - expect(response["Transfer-Encoding"]).to eq("chunked") - expect(response.body).to eq("Fiber response body") + expect(response['Transfer-Encoding']).to eq('chunked') + expect(response.body).to eq('Fiber response body') end - it "handles io response bodies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.iobody" + it 'handles io response bodies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.iobody' response = client.request(request) - expect(response["Content-Length"]).to eq("17") + expect(response['Content-Length']).to eq('17') expect(response.body).to eq("IO response body\n") end - it "handles request cookies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.cookies" - request["Cookie"] = "echo=echocookie" + it 'handles request cookies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.cookies' + request['Cookie'] = 'echo=echocookie' response = client.request(request) - expect(response.body).to eq("echocookie") + expect(response.body).to eq('echocookie') end - it "handles response cookies" do - request = Net::HTTP::Get.new("/test") - request["Accept"] = "test/response.cookies" + it 'handles response cookies' do + request = Net::HTTP::Get.new('/test') + request['Accept'] = 'test/response.cookies' response = client.request(request) - expect(response["Set-Cookie"]).to eq("cookie=monster, rodeo=clown") + expect(response['Set-Cookie']).to eq('cookie=monster, rodeo=clown') end end diff --git a/lib/webmachine/spec/test_resource.rb b/lib/webmachine/spec/test_resource.rb index 92895d83..cc949216 100644 --- a/lib/webmachine/spec/test_resource.rb +++ b/lib/webmachine/spec/test_resource.rb @@ -1,35 +1,35 @@ module Test class Resource < Webmachine::Resource def allowed_methods - ["GET", "PUT", "POST"] + ['GET', 'PUT', 'POST'] end def content_types_accepted [ - ["test/request.stringbody", :from_string], - ["test/request.enumbody", :from_enum] + ['test/request.stringbody', :from_string], + ['test/request.enumbody', :from_enum] ] end def content_types_provided [ - ["test/response.stringbody", :to_string], - ["test/response.enumbody", :to_enum], - ["test/response.procbody", :to_proc], - ["test/response.fiberbody", :to_fiber], - ["test/response.iobody", :to_io_body], - ["test/response.cookies", :to_cookies], - ["test/response.request_uri", :to_request_uri], - ["test/response.rack_env", :to_rack_env] + ['test/response.stringbody', :to_string], + ['test/response.enumbody', :to_enum], + ['test/response.procbody', :to_proc], + ['test/response.fiberbody', :to_fiber], + ['test/response.iobody', :to_io_body], + ['test/response.cookies', :to_cookies], + ['test/response.request_uri', :to_request_uri], + ['test/response.rack_env', :to_rack_env] ] end def from_string - response.body = "String: #{request.body.to_s}" + response.body = "String: #{request.body}" end def from_enum - response.body = "Enum: " + response.body = 'Enum: ' request.body.each do |part| response.body += part end @@ -41,22 +41,22 @@ def process_post end def to_string - "String response body" + 'String response body' end def to_enum - ["Enumerable ", "response " "body"] + ['Enumerable ', 'response ', 'body'] end def to_proc - Proc.new { "Proc response body" } + proc { 'Proc response body' } end def to_fiber Fiber.new do - Fiber.yield "Fiber " - Fiber.yield "response " - "body" + Fiber.yield 'Fiber ' + Fiber.yield 'response ' + 'body' end end @@ -65,12 +65,12 @@ def to_io_body end def to_cookies - response.set_cookie("cookie", "monster") - response.set_cookie("rodeo", "clown") + response.set_cookie('cookie', 'monster') + response.set_cookie('rodeo', 'clown') # FIXME: Mongrel/WEBrick fail if this method returns nil # Might be a net/http issue. Is this a bug? # @see Flow#o18, Helpers#encode_body_if_set - request.cookies["echo"] || "" + request.cookies['echo'] || '' end def to_request_uri diff --git a/lib/webmachine/streaming/encoder.rb b/lib/webmachine/streaming/encoder.rb index 0ad9f9e3..da7f139f 100644 --- a/lib/webmachine/streaming/encoder.rb +++ b/lib/webmachine/streaming/encoder.rb @@ -16,8 +16,8 @@ def initialize(resource, encoder, charsetter, body) # the encoder and/or charsetter. Only returns true if using the # built-in "encode_identity" and "charset_nop" methods. def is_unencoded? - encoder.to_s == "encode_identity" && - charsetter.to_s == "charset_nop" + encoder.to_s == 'encode_identity' && + charsetter.to_s == 'charset_nop' end end # class Encoder end # module Streaming diff --git a/lib/webmachine/streaming/io_encoder.rb b/lib/webmachine/streaming/io_encoder.rb index 4c058f97..d3d94456 100644 --- a/lib/webmachine/streaming/io_encoder.rb +++ b/lib/webmachine/streaming/io_encoder.rb @@ -13,7 +13,7 @@ class IOEncoder < Encoder # @yield [chunk] # @yieldparam [String] chunk a chunk of the response, encoded def each - while chunk = body.read(CHUNK_SIZE) and chunk != "" + while (chunk = body.read(CHUNK_SIZE)) && (chunk != '') yield resource.send(encoder, resource.send(charsetter, chunk)) end end @@ -26,7 +26,7 @@ def copy_stream(outstream) if can_copy_stream? IO.copy_stream(body, outstream) else - each {|chunk| outstream << chunk } + each { |chunk| outstream << chunk } end end @@ -60,9 +60,10 @@ def empty? size == 0 end - alias bytesize size + alias_method :bytesize, :size private + def can_copy_stream? IO.respond_to?(:copy_stream) && is_unencoded? && !is_string_io? end diff --git a/lib/webmachine/trace/fsm.rb b/lib/webmachine/trace/fsm.rb index 49b24ae1..d01b86ca 100644 --- a/lib/webmachine/trace/fsm.rb +++ b/lib/webmachine/trace/fsm.rb @@ -23,39 +23,46 @@ def trace? # Adds the request to the trace. # @param [Webmachine::Request] request the request to be traced def trace_request(request) - response.trace << { - :type => :request, - :method => request.method, - :path => request.uri.request_uri.to_s, - :headers => request.headers, - :body => request.body.to_s - } if trace? + if trace? + response.trace << { + type: :request, + method: request.method, + path: request.uri.request_uri.to_s, + headers: request.headers, + body: request.body.to_s + } + end end # Adds the response to the trace and then commits the trace to # separate storage which can be discovered by the debugger. # @param [Webmachine::Response] response the response to be traced def trace_response(response) - response.trace << { - :type => :response, - :code => response.code.to_s, - :headers => response.headers, - :body => trace_response_body(response.body) - } if trace? + if trace? + response.trace << { + type: :response, + code: response.code.to_s, + headers: response.headers, + body: trace_response_body(response.body) + } + end ensure - Webmachine::Events.publish('wm.trace.record', { - :trace_id => resource.object_id.to_s, - :trace => response.trace - }) if trace? + if trace? + Webmachine::Events.publish('wm.trace.record', { + trace_id: resource.object_id.to_s, + trace: response.trace + }) + end end # Adds a decision to the trace. # @param [Symbol] decision the decision being processed def trace_decision(decision) - response.trace << {:type => :decision, :decision => decision} if trace? + response.trace << {type: :decision, decision: decision} if trace? end private + # Works around streaming encoders where possible def trace_response_body(body) case body diff --git a/lib/webmachine/trace/resource_proxy.rb b/lib/webmachine/trace/resource_proxy.rb index 71cca9b1..bc9b02bf 100644 --- a/lib/webmachine/trace/resource_proxy.rb +++ b/lib/webmachine/trace/resource_proxy.rb @@ -69,7 +69,7 @@ def attempt(callback, args) log[:name] = "(default)##{method.name}" else log[:name] = "#{method.owner.name}##{method.name}" - log[:source] = method.source_location.join(":") if method.respond_to?(:source_location) + log[:source] = method.source_location.join(':') if method.respond_to?(:source_location) end unless args.empty? log[:args] = args diff --git a/lib/webmachine/trace/trace_resource.rb b/lib/webmachine/trace/trace_resource.rb index e8d60d6b..be9855c2 100644 --- a/lib/webmachine/trace/trace_resource.rb +++ b/lib/webmachine/trace/trace_resource.rb @@ -7,15 +7,14 @@ module Trace # includes serving the static files (the PNG flow diagram, CSS and # JS for the UI) and the HTML for the individual traces. class TraceResource < Resource - - MAP_EXTERNAL = %w{static map.png} - MAP_FILE = File.expand_path("../static/http-headers-status-v3.png", __FILE__) - SCRIPT_EXTERNAL = %w{static wmtrace.js} - SCRIPT_FILE = File.expand_path("../#{SCRIPT_EXTERNAL.join '/'}", __FILE__) - STYLE_EXTERNAL = %w{static wmtrace.css} - STYLE_FILE = File.expand_path("../#{STYLE_EXTERNAL.join '/'}", __FILE__) - TRACELIST_ERB = File.expand_path("../static/tracelist.erb", __FILE__) - TRACE_ERB = File.expand_path("../static/trace.erb", __FILE__) + MAP_EXTERNAL = %w[static map.png] + MAP_FILE = File.expand_path('../static/http-headers-status-v3.png', __FILE__) + SCRIPT_EXTERNAL = %w[static wmtrace.js] + SCRIPT_FILE = File.expand_path("../#{SCRIPT_EXTERNAL.join "/"}", __FILE__) + STYLE_EXTERNAL = %w[static wmtrace.css] + STYLE_FILE = File.expand_path("../#{STYLE_EXTERNAL.join "/"}", __FILE__) + TRACELIST_ERB = File.expand_path('../static/tracelist.erb', __FILE__) + TRACE_ERB = File.expand_path('../static/trace.erb', __FILE__) # The ERB template for the trace list def self.tracelist @@ -30,15 +29,15 @@ def self.trace def content_types_provided case request.path_tokens when [] - [["text/html", :produce_list]] + [['text/html', :produce_list]] when MAP_EXTERNAL - [["image/png", :produce_file]] + [['image/png', :produce_file]] when SCRIPT_EXTERNAL - [["text/javascript", :produce_file]] + [['text/javascript', :produce_file]] when STYLE_EXTERNAL - [["text/css", :produce_file]] + [['text/css', :produce_file]] else - [["text/html", :produce_trace]] + [['text/html', :produce_trace]] end end @@ -73,12 +72,12 @@ def produce_file # TODO: Add support for IO objects as response bodies, # allowing server optimizations like sendfile or chunked # downloads - open(@file, "rb") {|io| io.read } + File.binread(@file) end def produce_list - base = request.uri.path.chomp("/") - traces = Trace.traces.map {|t| [ t, "#{base}/#{t}" ] } + base = request.uri.path.chomp('/') + traces = Trace.traces.map { |t| [t, "#{base}/#{t}"] } self.class.tracelist.result(binding) end @@ -96,22 +95,22 @@ def encode_trace(data) tres = data.pop.dup treq.delete :type tres.delete :type - [ MultiJson.dump(treq), MultiJson.dump(tres), MultiJson.dump(encode_decisions(data)) ] + [MultiJson.dump(treq), MultiJson.dump(tres), MultiJson.dump(encode_decisions(data))] end def encode_decisions(decisions) - decisions.inject([]) do |list, event| + decisions.each_with_object([]) do |event, list| case event[:type] when :decision # Don't produce new decisions for sub-steps in the graph - unless event[:decision].to_s =~ /[a-z]$/ + unless /[a-z]$/.match?(event[:decision].to_s) list << {'d' => event[:decision], 'calls' => []} end when :attempt list.last['calls'] << { - "call" => event[:name], - "source" => event[:source], - "input" => event[:args] && event[:args].inspect + 'call' => event[:name], + 'source' => event[:source], + 'input' => event[:args] && event[:args].inspect } when :result list.last['calls'].last['output'] = event[:value].inspect @@ -122,7 +121,6 @@ def encode_decisions(decisions) 'message' => event[:message] } end - list end end end diff --git a/lib/webmachine/translation.rb b/lib/webmachine/translation.rb index 9d72c459..2c437ba7 100644 --- a/lib/webmachine/translation.rb +++ b/lib/webmachine/translation.rb @@ -1,7 +1,7 @@ require 'set' require 'i18n' I18n.enforce_available_locales = true if I18n.respond_to?(:enforce_available_locales) -I18n.config.load_path << File.expand_path("../locale/en.yml", __FILE__) +I18n.config.load_path << File.expand_path('../locale/en.yml', __FILE__) module Webmachine # Provides an interface to the I18n library specifically for diff --git a/lib/webmachine/version.rb b/lib/webmachine/version.rb index 02210c54..d38fd901 100644 --- a/lib/webmachine/version.rb +++ b/lib/webmachine/version.rb @@ -1,6 +1,6 @@ module Webmachine # Library version - VERSION = "1.6.0".freeze + VERSION = '1.6.0'.freeze # String for use in "Server" HTTP response header, which includes # the {VERSION}. diff --git a/memory_test.rb b/memory_test.rb index 1bf0246e..29abc5ff 100644 --- a/memory_test.rb +++ b/memory_test.rb @@ -1,8 +1,8 @@ -$:.push File.expand_path("../lib", __FILE__) +$:.push File.expand_path('../lib', __FILE__) require 'webmachine' class Constantized < Webmachine::Resource - HELLO_WORLD = "Hello World".freeze + HELLO_WORLD = 'Hello World'.freeze ALLOWED_METHODS = ['GET'.freeze].freeze CONTENT_TYPES_PROVIDED = [['text/html'.freeze, :to_html].freeze].freeze @@ -34,4 +34,3 @@ def to_html end report.pretty_print - diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 00eaf7c6..a63215df 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,15 +1,15 @@ -require "bundler/setup" +require 'bundler/setup' Bundler.require :default, :test require 'logger' class NullLogger < Logger - def add(severity, message=nil, progname=nil, &block) + def add(severity, message = nil, progname = nil, &block) end end RSpec.configure do |config| config.mock_with :rspec - config.filter_run :focus => true + config.filter_run focus: true config.run_all_when_everything_filtered = true config.formatter = :documentation if ENV['CI'] if defined?(::Java) @@ -28,8 +28,8 @@ def add(severity, message=nil, progname=nil, &block) config.before(:suite) do options = { - :Logger => NullLogger.new(STDERR), - :AccessLog => [] + Logger: NullLogger.new($stderr), + AccessLog: [] } Webmachine::Adapters::WEBrick::DEFAULT_OPTIONS.merge! options Webmachine::Adapters::Rack::DEFAULT_OPTIONS.merge! options if defined?(Webmachine::Adapters::Rack) @@ -37,18 +37,18 @@ def add(severity, message=nil, progname=nil, &block) end # For use in specs that need a fully initialized resource -shared_context "default resource" do +shared_context 'default resource' do let(:method) { 'GET' } - let(:uri) { URI.parse("http://localhost/") } + let(:uri) { URI.parse('http://localhost/') } let(:headers) { Webmachine::Headers.new } - let(:body) { "" } + let(:body) { '' } let(:request) { Webmachine::Request.new(method, uri, headers, body) } let(:response) { Webmachine::Response.new } let(:resource_class) do Class.new(Webmachine::Resource) do def to_html - "Hello, world!" + 'Hello, world!' end end end diff --git a/spec/webmachine/adapter_spec.rb b/spec/webmachine/adapter_spec.rb index 28b5d7c3..b366d3cc 100644 --- a/spec/webmachine/adapter_spec.rb +++ b/spec/webmachine/adapter_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require 'spec_helper' describe Webmachine::Adapter do let(:application) { Webmachine::Application.new } @@ -10,14 +10,14 @@ described_class.new(application) end - describe "#initialize" do - it "stores the provided application" do + describe '#initialize' do + it 'stores the provided application' do expect(adapter.application).to eq(application) end end - describe ".run" do - it "creates a new adapter and runs it" do + describe '.run' do + it 'creates a new adapter and runs it' do adapter = double(described_class) expect(described_class).to receive(:new). @@ -30,8 +30,8 @@ end end - describe "#run" do - it "raises a NotImplementedError" do + describe '#run' do + it 'raises a NotImplementedError' do expect { adapter.run }.to raise_exception(NotImplementedError) end end diff --git a/spec/webmachine/adapters/rack_mapped_spec.rb b/spec/webmachine/adapters/rack_mapped_spec.rb index 6e82848f..ca944639 100644 --- a/spec/webmachine/adapters/rack_mapped_spec.rb +++ b/spec/webmachine/adapters/rack_mapped_spec.rb @@ -6,10 +6,10 @@ describe Webmachine::Adapters::RackMapped do it_should_behave_like :adapter_lint do - it "should set Server header" do - response = client.request(Net::HTTP::Get.new("/test")) - expect(response["Server"]).to match(/Webmachine/) - expect(response["Server"]).to match(/Rack/) + it 'should set Server header' do + response = client.request(Net::HTTP::Get.new('/test')) + expect(response['Server']).to match(/Webmachine/) + expect(response['Server']).to match(/Rack/) end end end @@ -17,15 +17,15 @@ describe Webmachine::Adapters::RackMapped do class CreateResource < Webmachine::Resource def allowed_methods - ["POST"] + ['POST'] end def content_types_accepted - [["application/json", :from_json]] + [['application/json', :from_json]] end def content_types_provided - [["application/json", :to_json]] + [['application/json', :to_json]] end def post_is_create? @@ -33,11 +33,11 @@ def post_is_create? end def create_path - "created_path_here/123" + 'created_path_here/123' end def from_json - response.body = %{ {"foo": "bar"} } + response.body = %( {"foo": "bar"} ) end end @@ -45,9 +45,9 @@ def from_json Rack::Builder.new do map '/some/route' do run(Webmachine::Application.new do |app| - app.add_route(["test"], Test::Resource) - app.add_route(["create_test"], CreateResource) - app.configure do | config | + app.add_route(['test'], Test::Resource) + app.add_route(['create_test'], CreateResource) + app.configure do |config| config.adapter = :RackMapped end end.adapter) @@ -55,17 +55,17 @@ def from_json end end - context "using Rack::Test" do + context 'using Rack::Test' do include Rack::Test::Methods - it "provides the full request URI" do - rack_response = get "some/route/test", nil, {"HTTP_ACCEPT" => "test/response.request_uri"} - expect(rack_response.body).to eq "http://example.org/some/route/test" + it 'provides the full request URI' do + rack_response = get 'some/route/test', nil, {'HTTP_ACCEPT' => 'test/response.request_uri'} + expect(rack_response.body).to eq 'http://example.org/some/route/test' end - it "provides LOCATION header using custom base_uri when creating from POST request" do - rack_response = post "/some/route/create_test", %{{"foo": "bar"}}, {"HTTP_ACCEPT" => "application/json", "CONTENT_TYPE" => "application/json"} - expect(rack_response.headers["Location"]).to eq("http://example.org/some/route/created_path_here/123") + it 'provides LOCATION header using custom base_uri when creating from POST request' do + rack_response = post '/some/route/create_test', %({"foo": "bar"}), {'HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json'} + expect(rack_response.headers['Location']).to eq('http://example.org/some/route/created_path_here/123') end end end diff --git a/spec/webmachine/adapters/rack_spec.rb b/spec/webmachine/adapters/rack_spec.rb index c7771910..837a1e03 100644 --- a/spec/webmachine/adapters/rack_spec.rb +++ b/spec/webmachine/adapters/rack_spec.rb @@ -6,32 +6,32 @@ describe Webmachine::Adapters::Rack do it_should_behave_like :adapter_lint do - it "should set Server header" do - response = client.request(Net::HTTP::Get.new("/test")) - expect(response["Server"]).to match(/Webmachine/) - expect(response["Server"]).to match(/Rack/) + it 'should set Server header' do + response = client.request(Net::HTTP::Get.new('/test')) + expect(response['Server']).to match(/Webmachine/) + expect(response['Server']).to match(/Rack/) end end end describe Webmachine::Adapters::Rack::RackResponse do - context "on Rack < 1.5 release" do - before { allow(Rack).to receive_messages(:release => "1.4") } + context 'on Rack < 1.5 release' do + before { allow(Rack).to receive_messages(release: '1.4') } - it "should add Content-Type header on not acceptable response" do + it 'should add Content-Type header on not acceptable response' do rack_response = described_class.new(double(:body), 406, {}) - rack_status, rack_headers, rack_body = rack_response.finish - expect(rack_headers).to have_key("Content-Type") + _rack_status, rack_headers, _rack_body = rack_response.finish + expect(rack_headers).to have_key('Content-Type') end end - context "on Rack >= 1.5 release" do - before { allow(Rack).to receive_messages(:release => "1.5") } + context 'on Rack >= 1.5 release' do + before { allow(Rack).to receive_messages(release: '1.5') } - it "should not add Content-Type header on not acceptable response" do + it 'should not add Content-Type header on not acceptable response' do rack_response = described_class.new(double(:body), 406, {}) - rack_status, rack_headers, rack_body = rack_response.finish - expect(rack_headers).not_to have_key("Content-Type") + _rack_status, rack_headers, _rack_body = rack_response.finish + expect(rack_headers).not_to have_key('Content-Type') end end end @@ -39,24 +39,24 @@ describe Webmachine::Adapters::Rack do let(:app) do Webmachine::Application.new do |app| - app.add_route(["test"], Test::Resource) - app.configure do | config | + app.add_route(['test'], Test::Resource) + app.configure do |config| config.adapter = :Rack end end.adapter end - context "using Rack::Test" do + context 'using Rack::Test' do include Rack::Test::Methods - it "provides the full request URI" do - rack_response = get "test", nil, {"HTTP_ACCEPT" => "test/response.request_uri"} - expect(rack_response.body).to eq "http://example.org/test" + it 'provides the full request URI' do + rack_response = get 'test', nil, {'HTTP_ACCEPT' => 'test/response.request_uri'} + expect(rack_response.body).to eq 'http://example.org/test' end - it "provides the rack env on the request" do - rack_response = get "test", nil, {"HTTP_ACCEPT" => "test/response.rack_env"} - expect(JSON.parse(rack_response.body).keys).to include "rack.input" + it 'provides the rack env on the request' do + rack_response = get 'test', nil, {'HTTP_ACCEPT' => 'test/response.rack_env'} + expect(JSON.parse(rack_response.body).keys).to include 'rack.input' end end end diff --git a/spec/webmachine/adapters/webrick_spec.rb b/spec/webmachine/adapters/webrick_spec.rb index 2beb0c32..dfdc8489 100644 --- a/spec/webmachine/adapters/webrick_spec.rb +++ b/spec/webmachine/adapters/webrick_spec.rb @@ -1,12 +1,12 @@ -require "spec_helper" -require "webmachine/spec/adapter_lint" +require 'spec_helper' +require 'webmachine/spec/adapter_lint' describe Webmachine::Adapters::WEBrick do it_should_behave_like :adapter_lint do - it "should set Server header" do - response = client.request(Net::HTTP::Get.new("/test")) - expect(response["Server"]).to match(/Webmachine/) - expect(response["Server"]).to match(/WEBrick/) + it 'should set Server header' do + response = client.request(Net::HTTP::Get.new('/test')) + expect(response['Server']).to match(/Webmachine/) + expect(response['Server']).to match(/WEBrick/) end end end diff --git a/spec/webmachine/application_spec.rb b/spec/webmachine/application_spec.rb index e7894bb8..2469b2bb 100644 --- a/spec/webmachine/application_spec.rb +++ b/spec/webmachine/application_spec.rb @@ -4,12 +4,12 @@ let(:application) { described_class.new } let(:test_resource) { Class.new(Webmachine::Resource) } - it "accepts a Configuration when initialized" do + it 'accepts a Configuration when initialized' do config = Webmachine::Configuration.new('1.1.1.1', 9999, :Reel, {}) expect(described_class.new(config).configuration).to be(config) end - it "is yielded into a block provided during initialization" do + it 'is yielded into a block provided during initialization' do yielded_app = nil returned_app = described_class.new do |app| expect(app).to be_kind_of(Webmachine::Application) @@ -18,25 +18,25 @@ expect(returned_app).to be(yielded_app) end - it "is initialized with the default Configration if none is given" do + it 'is initialized with the default Configration if none is given' do expect(application.configuration).to eq(Webmachine::Configuration.default) end - it "returns the receiver from the configure call so you can chain it" do + it 'returns the receiver from the configure call so you can chain it' do expect(application.configure { |c| }).to equal(application) end - it "is configurable" do + it 'is configurable' do application.configure do |config| expect(config).to be_kind_of(Webmachine::Configuration) end end - it "is initialized with an empty Dispatcher" do + it 'is initialized with an empty Dispatcher' do expect(application.dispatcher.routes).to be_empty end - it "can have routes added" do + it 'can have routes added' do route = nil resource = test_resource # overcome instance_eval :/ @@ -50,24 +50,24 @@ expect(application.routes).to eq([route]) end - describe "#adapter" do + describe '#adapter' do let(:adapter_class) { application.adapter_class } it "returns an instance of it's adapter class" do expect(application.adapter).to be_an_instance_of(adapter_class) end - it "is memoized" do + it 'is memoized' do expect(application.adapter).to eql application.adapter end end - it "can be run" do + it 'can be run' do expect(application.adapter).to receive(:run) application.run end - it "can be queried about its configured adapter" do + it 'can be queried about its configured adapter' do expected = Webmachine::Adapters.const_get(application.configuration.adapter) expect(application.adapter_class).to equal(expected) end diff --git a/spec/webmachine/chunked_body_spec.rb b/spec/webmachine/chunked_body_spec.rb index 96bbf163..0a0620f7 100644 --- a/spec/webmachine/chunked_body_spec.rb +++ b/spec/webmachine/chunked_body_spec.rb @@ -2,7 +2,7 @@ require 'webmachine/chunked_body' describe Webmachine::ChunkedBody do - it "builds a proper body" do + it 'builds a proper body' do body = '' Webmachine::ChunkedBody.new(['foo', 'bar', '', 'j', 'webmachine']).each do |chunk| body << chunk @@ -10,8 +10,8 @@ expect(body).to eq("3\r\nfoo\r\n3\r\nbar\r\n1\r\nj\r\na\r\nwebmachine\r\n0\r\n\r\n") end - context "with an empty body" do - it "builds a proper body" do + context 'with an empty body' do + it 'builds a proper body' do body = '' Webmachine::ChunkedBody.new([]).each do |chunk| body << chunk @@ -20,9 +20,9 @@ end end - describe "#each" do - context "without a block given" do - it "returns an Enumerator" do + describe '#each' do + context 'without a block given' do + it 'returns an Enumerator' do expect(Webmachine::ChunkedBody.new([]).each).to respond_to(:next) end end diff --git a/spec/webmachine/configuration_spec.rb b/spec/webmachine/configuration_spec.rb index b97e65c6..4148e2ea 100644 --- a/spec/webmachine/configuration_spec.rb +++ b/spec/webmachine/configuration_spec.rb @@ -3,25 +3,25 @@ describe Webmachine::Configuration do before { Webmachine.configuration = nil } - %w{ip port adapter adapter_options}.each do |field| + %w[ip port adapter adapter_options].each do |field| it { is_expected.to respond_to(field) } it { is_expected.to respond_to("#{field}=") } end - it "should yield configuration to the block" do + it 'should yield configuration to the block' do Webmachine.configure do |config| expect(config).to be_kind_of(described_class) end end - it "should set the global configuration from the yielded instance" do + it 'should set the global configuration from the yielded instance' do Webmachine.configure do |config| @config = config end expect(@config).to eq Webmachine.configuration end - it "should return the module from the configure call so you can chain it" do - expect(Webmachine.configure {|c|}).to eq Webmachine + it 'should return the module from the configure call so you can chain it' do + expect(Webmachine.configure { |c| }).to eq Webmachine end end diff --git a/spec/webmachine/cookie_spec.rb b/spec/webmachine/cookie_spec.rb index 217ff4bb..de815c1f 100644 --- a/spec/webmachine/cookie_spec.rb +++ b/spec/webmachine/cookie_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe Webmachine::Cookie do - describe "creating a cookie" do - let(:name) { "monster" } - let(:value) { "mash" } + describe 'creating a cookie' do + let(:name) { 'monster' } + let(:value) { 'mash' } let(:attributes) { {} } let(:cookie) { Webmachine::Cookie.new(name, value, attributes) } @@ -13,32 +13,32 @@ its(:name) { should == name } its(:value) { should == value } - its(:to_s) { should == "monster=mash" } + its(:to_s) { should == 'monster=mash' } - describe "a cookie with whitespace in name and value" do - let(:name) { "cookie name" } - let(:value) { "cookie value" } + describe 'a cookie with whitespace in name and value' do + let(:name) { 'cookie name' } + let(:value) { 'cookie value' } - its(:to_s) { should == "cookie+name=cookie+value" } + its(:to_s) { should == 'cookie+name=cookie+value' } end - describe "a cookie with attributes set" do - let(:domain) { "www.server.com" } - let(:path) { "/" } - let(:comment) { "comment with spaces" } + describe 'a cookie with attributes set' do + let(:domain) { 'www.server.com' } + let(:path) { '/' } + let(:comment) { 'comment with spaces' } let(:version) { 1 } let(:maxage) { 60 } - let(:expires) { Time.gm(2010,3,14, 3, 14, 0) } + let(:expires) { Time.gm(2010, 3, 14, 3, 14, 0) } let(:attributes) { { - :comment => comment, - :domain => domain, - :path => path, - :secure => true, - :httponly => true, - :version => version, - :maxage => maxage, - :expires => expires + comment: comment, + domain: domain, + path: path, + secure: true, + httponly: true, + version: version, + maxage: maxage, + expires: expires } } @@ -51,49 +51,49 @@ its(:maxage) { should == maxage } its(:expires) { should == expires } - it "should include the attributes in its string version" do + it 'should include the attributes in its string version' do str = subject.to_s - expect(str).to include "Secure" - expect(str).to include "HttpOnly" - expect(str).to include "Comment=comment+with+spaces" - expect(str).to include "Domain=www.server.com" - expect(str).to include "Path=/" - expect(str).to include "Version=1" - expect(str).to include "Max-Age=60" - expect(str).to include "Expires=Sun, 14 Mar 2010 03:14:00 GMT" + expect(str).to include 'Secure' + expect(str).to include 'HttpOnly' + expect(str).to include 'Comment=comment+with+spaces' + expect(str).to include 'Domain=www.server.com' + expect(str).to include 'Path=/' + expect(str).to include 'Version=1' + expect(str).to include 'Max-Age=60' + expect(str).to include 'Expires=Sun, 14 Mar 2010 03:14:00 GMT' end end end - describe "parsing a cookie parameter" do - let(:str) { "cookie = monster" } + describe 'parsing a cookie parameter' do + let(:str) { 'cookie = monster' } subject { Webmachine::Cookie.parse(str) } - it("should have the cookie") { expect(subject).to eq({ "cookie" => "monster" }) } + it('should have the cookie') { expect(subject).to eq({'cookie' => 'monster'}) } - describe "parsing multiple cookie parameters" do - let(:str) { "cookie=monster; monster=mash" } + describe 'parsing multiple cookie parameters' do + let(:str) { 'cookie=monster; monster=mash' } - it("should have both cookies") { expect(subject).to eq({ "cookie" => "monster", "monster" => "mash" }) } + it('should have both cookies') { expect(subject).to eq({'cookie' => 'monster', 'monster' => 'mash'}) } end - describe "parsing an encoded cookie" do - let(:str) { "cookie=yum+yum" } + describe 'parsing an encoded cookie' do + let(:str) { 'cookie=yum+yum' } - it("should decode the cookie") { expect(subject).to eq({ "cookie" => "yum yum" }) } + it('should decode the cookie') { expect(subject).to eq({'cookie' => 'yum yum'}) } end - describe "parsing nil" do + describe 'parsing nil' do let(:str) { nil } - it("should return empty hash") { expect(subject).to eq({}) } + it('should return empty hash') { expect(subject).to eq({}) } end - describe "parsing duplicate cookies" do - let(:str) { "cookie=monster; cookie=yum+yum" } + describe 'parsing duplicate cookies' do + let(:str) { 'cookie=monster; cookie=yum+yum' } - it("should return the first instance of the cookie") { expect(subject).to eq({ "cookie" => "monster" }) } + it('should return the first instance of the cookie') { expect(subject).to eq({'cookie' => 'monster'}) } end end end diff --git a/spec/webmachine/decision/conneg_spec.rb b/spec/webmachine/decision/conneg_spec.rb index af2d5255..58b9f846 100644 --- a/spec/webmachine/decision/conneg_spec.rb +++ b/spec/webmachine/decision/conneg_spec.rb @@ -1,163 +1,160 @@ require 'spec_helper' describe Webmachine::Decision::Conneg do - include_context "default resource" + include_context 'default resource' subject do Webmachine::Decision::FSM.new(resource, request, response) end - context "choosing a media type" do - it "should not choose a type when none are provided" do - expect(subject.choose_media_type([], "*/*")).to be_nil + context 'choosing a media type' do + it 'should not choose a type when none are provided' do + expect(subject.choose_media_type([], '*/*')).to be_nil end - it "should not choose a type when none are acceptable" do - expect(subject.choose_media_type(["text/html"], "application/json")).to be_nil + it 'should not choose a type when none are acceptable' do + expect(subject.choose_media_type(['text/html'], 'application/json')).to be_nil end - it "should choose the first acceptable type" do - expect(subject.choose_media_type(["text/html", "application/xml"], - "application/xml, text/html, */*")).to eq("application/xml") + it 'should choose the first acceptable type' do + expect(subject.choose_media_type(['text/html', 'application/xml'], + 'application/xml, text/html, */*')).to eq('application/xml') end - it "should choose the type that matches closest when matching subparams" do - expect(subject.choose_media_type(["text/html", - ["text/html", {"charset" => "iso8859-1"}]], - "text/html;charset=iso8859-1, application/xml")). - to eq("text/html;charset=iso8859-1") + it 'should choose the type that matches closest when matching subparams' do + expect(subject.choose_media_type(['text/html', + ['text/html', {'charset' => 'iso8859-1'}]], + 'text/html;charset=iso8859-1, application/xml')) + .to eq('text/html;charset=iso8859-1') end - it "should choose a type more specific than requested when an exact match is not present" do - expect(subject.choose_media_type(["application/json;v=3;foo=bar", "application/json;v=2"], - "text/html, application/json")). - to eq("application/json;v=3;foo=bar") + it 'should choose a type more specific than requested when an exact match is not present' do + expect(subject.choose_media_type(['application/json;v=3;foo=bar', 'application/json;v=2'], + 'text/html, application/json')) + .to eq('application/json;v=3;foo=bar') end - - it "should choose the preferred type over less-preferred types" do - expect(subject.choose_media_type(["text/html", "application/xml"], - "application/xml;q=0.7, text/html, */*")).to eq("text/html") - + it 'should choose the preferred type over less-preferred types' do + expect(subject.choose_media_type(['text/html', 'application/xml'], + 'application/xml;q=0.7, text/html, */*')).to eq('text/html') end - it "should raise an error when a media-type is improperly formatted" do + it 'should raise an error when a media-type is improperly formatted' do expect { - subject.choose_media_type(["text/html", "application/xml"], - "bah;") + subject.choose_media_type(['text/html', 'application/xml'], + 'bah;') }.to raise_error(Webmachine::MalformedRequest) end - it "should choose a type when more than one accept header is present" do - expect(subject.choose_media_type(["text/html"], - ["text/html", "text/plain"])).to eq("text/html") - + it 'should choose a type when more than one accept header is present' do + expect(subject.choose_media_type(['text/html'], + ['text/html', 'text/plain'])).to eq('text/html') end end - context "choosing an encoding" do - it "should not set the encoding when none are provided" do - subject.choose_encoding({}, "identity, gzip") + context 'choosing an encoding' do + it 'should not set the encoding when none are provided' do + subject.choose_encoding({}, 'identity, gzip') expect(subject.metadata['Content-Encoding']).to be_nil expect(subject.response.headers['Content-Encoding']).to be_nil end - it "should not set the Content-Encoding header when it is identity" do - subject.choose_encoding({"gzip"=> :encode_gzip, "identity" => :encode_identity}, "identity") + it 'should not set the Content-Encoding header when it is identity' do + subject.choose_encoding({'gzip' => :encode_gzip, 'identity' => :encode_identity}, 'identity') expect(subject.metadata['Content-Encoding']).to eq('identity') expect(response.headers['Content-Encoding']).to be_nil end - it "should choose the first acceptable encoding" do - subject.choose_encoding({"gzip" => :encode_gzip}, "identity, gzip") + it 'should choose the first acceptable encoding' do + subject.choose_encoding({'gzip' => :encode_gzip}, 'identity, gzip') expect(subject.metadata['Content-Encoding']).to eq('gzip') expect(response.headers['Content-Encoding']).to eq('gzip') end - it "should choose the first acceptable encoding" \ - ", even when no white space after comma" do - subject.choose_encoding({"gzip" => :encode_gzip}, "identity,gzip") + it 'should choose the first acceptable encoding' \ + ', even when no white space after comma' do + subject.choose_encoding({'gzip' => :encode_gzip}, 'identity,gzip') expect(subject.metadata['Content-Encoding']).to eq('gzip') expect(response.headers['Content-Encoding']).to eq('gzip') end - it "should choose the preferred encoding over less-preferred encodings" do - subject.choose_encoding({"gzip" => :encode_gzip, "identity" => :encode_identity}, "gzip, identity;q=0.7") + it 'should choose the preferred encoding over less-preferred encodings' do + subject.choose_encoding({'gzip' => :encode_gzip, 'identity' => :encode_identity}, 'gzip, identity;q=0.7') expect(subject.metadata['Content-Encoding']).to eq('gzip') expect(response.headers['Content-Encoding']).to eq('gzip') end - it "should not set the encoding if none are acceptable" do - subject.choose_encoding({"gzip" => :encode_gzip}, "identity") + it 'should not set the encoding if none are acceptable' do + subject.choose_encoding({'gzip' => :encode_gzip}, 'identity') expect(subject.metadata['Content-Encoding']).to be_nil expect(response.headers['Content-Encoding']).to be_nil end end - context "choosing a charset" do - it "should not set the charset when none are provided" do - subject.choose_charset([], "ISO-8859-1") + context 'choosing a charset' do + it 'should not set the charset when none are provided' do + subject.choose_charset([], 'ISO-8859-1') expect(subject.metadata['Charset']).to be_nil end - it "should choose the first acceptable charset" do - subject.choose_charset([["UTF-8", :to_utf8],["US-ASCII", :to_ascii]], "US-ASCII, UTF-8") - expect(subject.metadata['Charset']).to eq("US-ASCII") + it 'should choose the first acceptable charset' do + subject.choose_charset([['UTF-8', :to_utf8], ['US-ASCII', :to_ascii]], 'US-ASCII, UTF-8') + expect(subject.metadata['Charset']).to eq('US-ASCII') end - it "should choose the preferred charset over less-preferred charsets" do - subject.choose_charset([["UTF-8", :to_utf8],["US-ASCII", :to_ascii]], "US-ASCII;q=0.7, UTF-8") - expect(subject.metadata['Charset']).to eq("UTF-8") + it 'should choose the preferred charset over less-preferred charsets' do + subject.choose_charset([['UTF-8', :to_utf8], ['US-ASCII', :to_ascii]], 'US-ASCII;q=0.7, UTF-8') + expect(subject.metadata['Charset']).to eq('UTF-8') end - it "should not set the charset if none are acceptable" do - subject.choose_charset([["UTF-8", :to_utf8],["US-ASCII", :to_ascii]], "ISO-8859-1") + it 'should not set the charset if none are acceptable' do + subject.choose_charset([['UTF-8', :to_utf8], ['US-ASCII', :to_ascii]], 'ISO-8859-1') expect(subject.metadata['Charset']).to be_nil end - it "should choose a charset case-insensitively" do - subject.choose_charset([["UtF-8", :to_utf8],["US-ASCII", :to_ascii]], "iso-8859-1, utf-8") - expect(subject.metadata['Charset']).to eq("utf-8") + it 'should choose a charset case-insensitively' do + subject.choose_charset([['UtF-8', :to_utf8], ['US-ASCII', :to_ascii]], 'iso-8859-1, utf-8') + expect(subject.metadata['Charset']).to eq('utf-8') end end - context "choosing a language" do - it "should not set the language when none are provided" do - subject.choose_language([], "en") + context 'choosing a language' do + it 'should not set the language when none are provided' do + subject.choose_language([], 'en') expect(subject.metadata['Language']).to be_nil end - it "should choose the first acceptable language" do - subject.choose_language(['en', 'en-US', 'es'], "en-US, es") - expect(subject.metadata['Language']).to eq("en-US") - expect(response.headers['Content-Language']).to eq("en-US") + it 'should choose the first acceptable language' do + subject.choose_language(['en', 'en-US', 'es'], 'en-US, es') + expect(subject.metadata['Language']).to eq('en-US') + expect(response.headers['Content-Language']).to eq('en-US') end - it "should choose the preferred language over less-preferred languages" do - subject.choose_language(['en', 'en-US', 'es'], "en-US;q=0.6, es") - expect(subject.metadata['Language']).to eq("es") - expect(response.headers['Content-Language']).to eq("es") + it 'should choose the preferred language over less-preferred languages' do + subject.choose_language(['en', 'en-US', 'es'], 'en-US;q=0.6, es') + expect(subject.metadata['Language']).to eq('es') + expect(response.headers['Content-Language']).to eq('es') end - it "should select the first language if all are acceptable" do - subject.choose_language(['en', 'fr', 'es'], "*") - expect(subject.metadata['Language']).to eq("en") - expect(response.headers['Content-Language']).to eq("en") + it 'should select the first language if all are acceptable' do + subject.choose_language(['en', 'fr', 'es'], '*') + expect(subject.metadata['Language']).to eq('en') + expect(response.headers['Content-Language']).to eq('en') end - it "should select the closest acceptable language when an exact match is not available" do - subject.choose_language(['en-US', 'es'], "en, fr") + it 'should select the closest acceptable language when an exact match is not available' do + subject.choose_language(['en-US', 'es'], 'en, fr') expect(subject.metadata['Language']).to eq('en-US') expect(response.headers['Content-Language']).to eq('en-US') end - it "should not set the language if none are acceptable" do + it 'should not set the language if none are acceptable' do subject.choose_language(['en'], 'es') expect(subject.metadata['Language']).to be_nil expect(response.headers).not_to include('Content-Language') end - it "should choose a language case-insensitively" do + it 'should choose a language case-insensitively' do subject.choose_language(['en-US', 'ZH'], 'zh-ch, EN') expect(subject.metadata['Language']).to eq('en-US') expect(response.headers['Content-Language']).to eq('en-US') diff --git a/spec/webmachine/decision/flow_spec.rb b/spec/webmachine/decision/flow_spec.rb index 80a53369..d1e696f6 100644 --- a/spec/webmachine/decision/flow_spec.rb +++ b/spec/webmachine/decision/flow_spec.rb @@ -3,9 +3,9 @@ describe Webmachine::Decision::Flow do subject { Webmachine::Decision::FSM.new(resource, request, response) } let(:method) { 'GET' } - let(:uri) { URI.parse("http://localhost/") } + let(:uri) { URI.parse('http://localhost/') } let(:headers) { Webmachine::Headers.new } - let(:body) { "" } + let(:body) { '' } let(:request) { Webmachine::Request.new(method, uri, headers, body) } let(:response) { Webmachine::Response.new } let(:default_resource) { resource_with } @@ -22,207 +22,246 @@ def resource_with(&block) klass = Class.new(Webmachine::Resource) do - def to_html; "test resource"; end + def to_html + 'test resource' + end end - klass.module_eval(&block) if block_given? + klass.module_eval(&block) if block klass.new(request, response) end def missing_resource_with(&block) resource_with do - def resource_exists?; false; end - self.module_eval(&block) if block + def resource_exists? + false + end + module_eval(&block) if block end end - describe "#b13 (Service Available?)" do + describe '#b13 (Service Available?)' do let(:resource) do resource_with do attr_accessor :available - def service_available?; @available; end + def service_available? + @available + end end end - it "should respond with 503 when the service is unavailable" do + it 'should respond with 503 when the service is unavailable' do resource.available = false subject.run expect(response.code).to eq 503 end end - describe "#b12 (Known method?)" do + describe '#b12 (Known method?)' do let(:resource) do resource_with do - def known_methods; ['HEAD']; end + def known_methods + ['HEAD'] + end end end - it "should respond with 501 when the method is unknown" do + it 'should respond with 501 when the method is unknown' do subject.run expect(response.code).to eq 501 end end - describe "#b11 (URI too long?)" do + describe '#b11 (URI too long?)' do let(:resource) do resource_with do - def uri_too_long?(uri); true; end + def uri_too_long?(uri) + true + end end end - it "should respond with 414 when the URI is too long" do + it 'should respond with 414 when the URI is too long' do subject.run expect(response.code).to eq 414 end end - describe "#b10 (Method allowed?)" do + describe '#b10 (Method allowed?)' do let(:resource) do resource_with do - def allowed_methods; ['POST']; end + def allowed_methods + ['POST'] + end end end - it "should respond with 405 when the method is not allowed" do + it 'should respond with 405 when the method is not allowed' do subject.run expect(response.code).to eq 405 - expect(response.headers['Allow']).to eq "POST" + expect(response.headers['Allow']).to eq 'POST' end end - describe "#b9 (Malformed request?)" do - let(:resource) { resource_with { def malformed_request?; true; end } } + describe '#b9 (Malformed request?)' do + let(:resource) { + resource_with { + def malformed_request? + true + end + } + } - it "should respond with 400 when the request is malformed" do + it 'should respond with 400 when the request is malformed' do subject.run expect(response.code).to eq 400 end - context "when the Content-MD5 header is present" do + context 'when the Content-MD5 header is present' do let(:resource) do resource_with do - def allowed_methods; ['POST']; end; - def process_post; true; end; + def allowed_methods + ['POST'] + end + + def process_post + true + end attr_accessor :validation - def validate_content_checksum; @validation; end + def validate_content_checksum + @validation + end end end - let(:method) { "POST" } - let(:body) { "This is the body." } - let(:headers) { Webmachine::Headers["Content-Type" => "text/plain"] } + let(:method) { 'POST' } + let(:body) { 'This is the body.' } + let(:headers) { Webmachine::Headers['Content-Type' => 'text/plain'] } - it "should respond with 204 when the request body does match the header" do + it 'should respond with 204 when the request body does match the header' do headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest(body) subject.run expect(response.code).to eq 204 end - it "should bypass validation when the header has a nil value" do + it 'should bypass validation when the header has a nil value' do headers['Content-MD5'] = nil subject.run expect(response.code).to eq 204 end - it "should respond with 400 when the header has a empty string value" do - headers['Content-MD5'] = "" + it 'should respond with 400 when the header has a empty string value' do + headers['Content-MD5'] = '' subject.run expect(response.code).to eq 400 end - it "should respond with 400 when the header has a non-hashed, non-encoded value" do - headers["Content-MD5"] = body + it 'should respond with 400 when the header has a non-hashed, non-encoded value' do + headers['Content-MD5'] = body subject.run expect(response.code).to eq 400 end - it "should respond with 400 when the header is not encoded as Base64 but digest matches the body" do + it 'should respond with 400 when the header is not encoded as Base64 but digest matches the body' do headers['Content-MD5'] = Digest::MD5.hexdigest(body) subject.run expect(response.code).to eq 400 end - it "should respond with 400 when the request body does not match the header" do - headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash") + it 'should respond with 400 when the request body does not match the header' do + headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest('thiswillnotmatchthehash') subject.run expect(response.code).to eq 400 end - it "should respond with 400 when the resource invalidates the checksum" do + it 'should respond with 400 when the resource invalidates the checksum' do resource.validation = false - headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash") + headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest('thiswillnotmatchthehash') subject.run expect(response.code).to eq 400 end - it "should not respond with 400 when the resource validates the checksum" do + it 'should not respond with 400 when the resource validates the checksum' do resource.validation = true - headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash") + headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest('thiswillnotmatchthehash') subject.run expect(response.code).to_not eq 400 end - it "should respond with the given code when the resource returns a code while validating" do + it 'should respond with the given code when the resource returns a code while validating' do resource.validation = 500 - headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash") + headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest('thiswillnotmatchthehash') subject.run expect(response.code).to eq 500 end end end - describe "#b8 (Authorized?)" do - let(:resource) { resource_with { attr_accessor :auth; def is_authorized?(header); @auth; end } } + describe '#b8 (Authorized?)' do + let(:resource) { + resource_with { + attr_accessor :auth + def is_authorized?(header) + @auth + end + } + } - it "should reply with 401 when the client is unauthorized" do + it 'should reply with 401 when the client is unauthorized' do resource.auth = false subject.run expect(response.code).to eq 401 end - it "should reply with 401 when the resource gives a challenge" do - resource.auth = "Basic realm=Webmachine" + it 'should reply with 401 when the resource gives a challenge' do + resource.auth = 'Basic realm=Webmachine' subject.run expect(response.code).to eq 401 - expect(response.headers['WWW-Authenticate']).to eq "Basic realm=Webmachine" + expect(response.headers['WWW-Authenticate']).to eq 'Basic realm=Webmachine' end - it "should halt with the given code when the resource returns a status code" do + it 'should halt with the given code when the resource returns a status code' do resource.auth = 400 subject.run expect(response.code).to eq 400 end - it "should not reply with 401 when the client is authorized" do + it 'should not reply with 401 when the client is authorized' do resource.auth = true subject.run expect(response.code).to_not eq 401 end end - describe "#b7 (Forbidden?)" do - let(:resource) { resource_with { attr_accessor :forbid; def forbidden?; @forbid; end } } + describe '#b7 (Forbidden?)' do + let(:resource) { + resource_with { + attr_accessor :forbid + def forbidden? + @forbid + end + } + } - it "should reply with 403 when the request is forbidden" do + it 'should reply with 403 when the request is forbidden' do resource.forbid = true subject.run expect(response.code).to eq 403 end - it "should not reply with 403 when the request is permitted" do + it 'should not reply with 403 when the request is permitted' do resource.forbid = false subject.run expect(response.code).to_not eq 403 end - it "should halt with the given code when the resource returns a status code" do + it 'should halt with the given code when the resource returns a status code' do resource.forbid = 400 subject.run expect(response.code).to eq 400 end end - describe "#b6 (Unsupported Content-* header?)" do + describe '#b6 (Unsupported Content-* header?)' do let(:resource) do resource_with do def valid_content_headers?(contents) @@ -231,101 +270,126 @@ def valid_content_headers?(contents) end end - it "should reply with 501 when an invalid Content-* header is present" do - headers['Content-Fail'] = "yup" + it 'should reply with 501 when an invalid Content-* header is present' do + headers['Content-Fail'] = 'yup' subject.run expect(response.code).to eq 501 end - it "should not reply with 501 when all Content-* headers are valid" do + it 'should not reply with 501 when all Content-* headers are valid' do subject.run expect(response.code).to_not eq 501 end end - describe "#b5 (Known Content-Type?)" do - let(:method) { "POST" } - let(:body) { "This is the body." } + describe '#b5 (Known Content-Type?)' do + let(:method) { 'POST' } + let(:body) { 'This is the body.' } let(:resource) do resource_with do - def known_content_type?(type) type !~ /unknown/; end; - def process_post; true; end - def allowed_methods; %w{POST}; end + def known_content_type?(type) + type !~ /unknown/ + end + + def process_post + true + end + + def allowed_methods + %w[POST] + end end end before { headers['Content-Length'] = body.length.to_s } - it "should reply with 415 when the Content-Type is unknown" do - headers['Content-Type'] = "application/x-unknown-type" + it 'should reply with 415 when the Content-Type is unknown' do + headers['Content-Type'] = 'application/x-unknown-type' subject.run expect(response.code).to eq 415 end - it "should not reply with 415 when the Content-Type is known" do - headers['Content-Type'] = "text/plain" + it 'should not reply with 415 when the Content-Type is known' do + headers['Content-Type'] = 'text/plain' subject.run expect(response.code).to_not eq 415 end end - describe "#b4 (Request entity too large?)" do + describe '#b4 (Request entity too large?)' do let(:resource) do resource_with do - def allowed_methods; %w{POST}; end - def process_post; true; end - def valid_entity_length?(length); length.to_i < 100; end + def allowed_methods + %w[POST] + end + + def process_post + true + end + + def valid_entity_length?(length) + length.to_i < 100 + end end end - let(:method) { "POST" } - before { headers['Content-Type'] = "text/plain"; headers['Content-Length'] = body.size.to_s } + let(:method) { 'POST' } + before { + headers['Content-Type'] = 'text/plain' + headers['Content-Length'] = body.size.to_s + } - context "when the request body is too large" do - let(:body) { "Big" * 100 } - it "should reply with 413" do + context 'when the request body is too large' do + let(:body) { 'Big' * 100 } + it 'should reply with 413' do subject.run expect(response.code).to eq 413 end end - context "when the request body is not too large" do - let(:body) { "small" } + context 'when the request body is not too large' do + let(:body) { 'small' } - it "should not reply with 413" do + it 'should not reply with 413' do subject.run expect(response.code).to_not eq 413 end end end - describe "#b3 (OPTIONS?)" do - let(:method){ "OPTIONS" } - let(:resource){ resource_with { def allowed_methods; %w[GET HEAD OPTIONS]; end } } - it "should reply with 200 when the request method is OPTIONS" do + describe '#b3 (OPTIONS?)' do + let(:method) { 'OPTIONS' } + let(:resource) { + resource_with { + def allowed_methods + %w[GET HEAD OPTIONS] + end + } + } + it 'should reply with 200 when the request method is OPTIONS' do subject.run expect(response.code).to eq 200 end end - describe "#c3, #c4 (Acceptable media types)" do + describe '#c3, #c4 (Acceptable media types)' do let(:resource) { default_resource } - context "when the Accept header exists" do - it "should reply with 406 when the type is unacceptable" do - headers['Accept'] = "text/plain" + context 'when the Accept header exists' do + it 'should reply with 406 when the type is unacceptable' do + headers['Accept'] = 'text/plain' subject.run expect(response.code).to eq 406 end - it "should not reply with 406 when the type is acceptable" do - headers['Accept'] = "text/*" + it 'should not reply with 406 when the type is acceptable' do + headers['Accept'] = 'text/*' subject.run expect(response.code).to_not eq 406 - expect(response.headers['Content-Type']).to eq "text/html" + expect(response.headers['Content-Type']).to eq 'text/html' end end - context "when the Accept header does not exist" do - it "should not negotiate a media type" do + context 'when the Accept header does not exist' do + it 'should not negotiate a media type' do expect(headers['Accept']).to be_nil expect(subject).to_not receive(:c4) subject.run @@ -334,26 +398,32 @@ def valid_entity_length?(length); length.to_i < 100; end end end - describe "#d4, #d5 (Acceptable languages)" do - let(:resource) { resource_with { def languages_provided; %w{en-US fr}; end } } - context "when the Accept-Language header exists" do - it "should reply with 406 when the language is unacceptable" do - headers['Accept-Language'] = "es, de" + describe '#d4, #d5 (Acceptable languages)' do + let(:resource) { + resource_with { + def languages_provided + %w[en-US fr] + end + } + } + context 'when the Accept-Language header exists' do + it 'should reply with 406 when the language is unacceptable' do + headers['Accept-Language'] = 'es, de' subject.run expect(response.code).to eq 406 end - it "should not reply with 406 when the language is acceptable" do - headers['Accept-Language'] = "en-GB, en;q=0.7" + it 'should not reply with 406 when the language is acceptable' do + headers['Accept-Language'] = 'en-GB, en;q=0.7' subject.run expect(response.code).to_not eq 406 - expect(response.headers['Content-Language']).to eq "en-US" + expect(response.headers['Content-Language']).to eq 'en-US' expect(resource.instance_variable_get(:@language)).to eq 'en-US' end end - context "when the Accept-Language header is absent" do - it "should not negotiate the language" do + context 'when the Accept-Language header is absent' do + it 'should not negotiate the language' do expect(headers['Accept-Language']).to be_nil expect(subject).to_not receive(:d5) subject.run @@ -363,34 +433,40 @@ def valid_entity_length?(length); length.to_i < 100; end end end - describe "#e5, #e6 (Acceptable charsets)" do + describe '#e5, #e6 (Acceptable charsets)' do let(:resource) do resource_with do def charsets_provided - [["iso8859-1", :to_iso],["utf-8", :to_utf]]; + [['iso8859-1', :to_iso], ['utf-8', :to_utf]] + end + + def to_iso(chunk) + chunk + end + + def to_utf(chunk) + chunk end - def to_iso(chunk); chunk; end - def to_utf(chunk); chunk; end end end - context "when the Accept-Charset header exists" do - it "should reply with 406 when the charset is unacceptable" do - headers['Accept-Charset'] = "utf-16" + context 'when the Accept-Charset header exists' do + it 'should reply with 406 when the charset is unacceptable' do + headers['Accept-Charset'] = 'utf-16' subject.run expect(response.code).to eq 406 end - it "should not reply with 406 when the charset is acceptable" do - headers['Accept-Charset'] = "iso8859-1" + it 'should not reply with 406 when the charset is acceptable' do + headers['Accept-Charset'] = 'iso8859-1' subject.run expect(response.code).to_not eq 406 - expect(response.headers['Content-Type']).to eq "text/html;charset=iso8859-1" + expect(response.headers['Content-Type']).to eq 'text/html;charset=iso8859-1' end end - context "when the Accept-Charset header is absent" do - it "should not negotiate the language" do + context 'when the Accept-Charset header is absent' do + it 'should not negotiate the language' do expect(headers['Accept-Charset']).to be_nil expect(subject).to_not receive(:e6) subject.run @@ -399,23 +475,23 @@ def to_utf(chunk); chunk; end end end - describe "#f6, #f7 (Acceptable encodings)" do + describe '#f6, #f7 (Acceptable encodings)' do let(:resource) do resource_with do def encodings_provided - super.merge("gzip" => :encode_gzip) + super.merge('gzip' => :encode_gzip) end end end - context "when the Accept-Encoding header is present" do - it "should reply with 406 if the encoding is unacceptable" do + context 'when the Accept-Encoding header is present' do + it 'should reply with 406 if the encoding is unacceptable' do headers['Accept-Encoding'] = 'deflate, identity;q=0.0' subject.run expect(response.code).to eq 406 end - it "should not reply with 406 if the encoding is acceptable" do + it 'should not reply with 406 if the encoding is acceptable' do headers['Accept-Encoding'] = 'gzip, deflate' subject.run expect(response.code).to_not eq 406 @@ -425,8 +501,8 @@ def encodings_provided end end - context "when the Accept-Encoding header is not present" do - it "should not negotiate an encoding" do + context 'when the Accept-Encoding header is not present' do + it 'should not negotiate an encoding' do expect(headers['Accept-Encoding']).to be_nil expect(subject).to_not receive(:f7) subject.run @@ -437,30 +513,37 @@ def encodings_provided end end - describe "#g7 (Resource exists?)" do - let(:resource) { resource_with { attr_accessor :exist; def resource_exists?; @exist; end } } + describe '#g7 (Resource exists?)' do + let(:resource) { + resource_with { + attr_accessor :exist + def resource_exists? + @exist + end + } + } - it "should not enter conditional requests if missing (and eventually reply with 404)" do + it 'should not enter conditional requests if missing (and eventually reply with 404)' do resource.exist = false expect(subject).to_not receive(:g8) subject.run expect(response.code).to eq 404 end - it "should not reply with 404 if it does exist" do + it 'should not reply with 404 if it does exist' do resource.exist = true expect(subject).to_not receive(:h7) subject.run expect(response.code).to_not eq 404 end - it "should not reply with 404 for truthy non-booleans" do + it 'should not reply with 404 for truthy non-booleans' do resource.exist = [] subject.run expect(response.code).to_not eq 404 end - it "should reply with 404 for nil" do + it 'should reply with 404 for nil' do resource.exist = nil subject.run expect(response.code).to eq 404 @@ -468,37 +551,50 @@ def encodings_provided end # Conditional requests/preconditions - describe "#g8, #g9, #g10 (ETag match)" do - let(:resource) { resource_with { def generate_etag; "etag"; end } } - it "should skip ETag matching when If-Match is missing" do + describe '#g8, #g9, #g10 (ETag match)' do + let(:resource) { + resource_with { + def generate_etag + 'etag' + end + } + } + it 'should skip ETag matching when If-Match is missing' do expect(headers['If-Match']).to be_nil expect(subject).to_not receive(:g9) expect(subject).to_not receive(:g11) subject.run expect(response.code).to_not eq 412 end - it "should not reply with 304 when If-Match is *" do - headers['If-Match'] = "*" + it 'should not reply with 304 when If-Match is *' do + headers['If-Match'] = '*' subject.run expect(response.code).to_not eq 412 end - it "should reply with 412 if the ETag is not in If-Match" do + it 'should reply with 412 if the ETag is not in If-Match' do headers['If-Match'] = '"notetag"' subject.run expect(response.code).to eq 412 end - it "should not reply with 412 if the ETag is in If-Match" do + it 'should not reply with 412 if the ETag is in If-Match' do headers['If-Match'] = '"etag"' subject.run expect(response.code).to_not eq 412 end end - describe "#h10, #h11, #h12 (If-Unmodified-Since match [IUMS])" do - let(:resource) { resource_with { attr_accessor :now; def last_modified; @now; end } } + describe '#h10, #h11, #h12 (If-Unmodified-Since match [IUMS])' do + let(:resource) { + resource_with { + attr_accessor :now + def last_modified + @now + end + } + } before { @now = resource.now = Time.now } - it "should skip LM matching if IUMS is missing" do + it 'should skip LM matching if IUMS is missing' do expect(headers['If-Unmodified-Since']).to be_nil expect(subject).to_not receive(:h11) expect(subject).to_not receive(:h12) @@ -506,90 +602,106 @@ def encodings_provided expect(response.code).to_not eq 412 end - it "should skip LM matching if IUMS is an invalid date" do - headers['If-Unmodified-Since'] = "garbage" + it 'should skip LM matching if IUMS is an invalid date' do + headers['If-Unmodified-Since'] = 'garbage' expect(subject).to_not receive(:h12) subject.run expect(response.code).to_not eq 412 end - it "should not reply with 412 if LM is <= IUMS" do + it 'should not reply with 412 if LM is <= IUMS' do headers['If-Unmodified-Since'] = (@now + 100).httpdate subject.run expect(response.code).to_not eq 412 end - it "should reply with 412 if LM is > IUMS" do + it 'should reply with 412 if LM is > IUMS' do headers['If-Unmodified-Since'] = (@now - 100).httpdate subject.run expect(response.code).to eq 412 end end - describe "#i12, #i13, #k13, #j18 (If-None-Match match)" do + describe '#i12, #i13, #k13, #j18 (If-None-Match match)' do let(:resource) do resource_with do - def generate_etag; "etag"; end; - def process_post; true; end - def allowed_methods; %w{GET HEAD POST}; end + def generate_etag + 'etag' + end + + def process_post + true + end + + def allowed_methods + %w[GET HEAD POST] + end end end - it "should skip ETag matching if If-None-Match is missing" do + it 'should skip ETag matching if If-None-Match is missing' do expect(headers['If-None-Match']).to be_nil - %w{i13 k13 j18}.each do |m| + %w[i13 k13 j18].each do |m| expect(subject).to_not receive(m.to_sym) end subject.run expect([304, 412]).to_not include(response.code) end - it "should not reply with 412 or 304 if the ETag is not in If-None-Match" do + it 'should not reply with 412 or 304 if the ETag is not in If-None-Match' do headers['If-None-Match'] = '"notetag"' subject.run expect([304, 412]).to_not include(response.code) end - context "when the method is GET or HEAD" do - let(:method){ %w{GET HEAD}[rand(1)] } - it "should reply with 304 when If-None-Match is *" do + context 'when the method is GET or HEAD' do + let(:method) { %w[GET HEAD][rand(2)] } + it 'should reply with 304 when If-None-Match is *' do headers['If-None-Match'] = '*' end - it "should reply with 304 when the ETag is in If-None-Match" do + it 'should reply with 304 when the ETag is in If-None-Match' do headers['If-None-Match'] = '"etag", "foobar"' end - after { subject.run; expect(response.code).to eq 304 } + after { + subject.run + expect(response.code).to eq 304 + } end - context "when the method is not GET or HEAD" do - let(:method){ "POST" } - let(:body) { "This is the body." } - let(:headers){ Webmachine::Headers["Content-Type" => "text/plain"] } + context 'when the method is not GET or HEAD' do + let(:method) { 'POST' } + let(:body) { 'This is the body.' } + let(:headers) { Webmachine::Headers['Content-Type' => 'text/plain'] } - it "should reply with 412 when If-None-Match is *" do + it 'should reply with 412 when If-None-Match is *' do headers['If-None-Match'] = '*' end - it "should reply with 412 when the ETag is in If-None-Match" do + it 'should reply with 412 when the ETag is in If-None-Match' do headers['If-None-Match'] = '"etag"' end - after { subject.run; expect(response.code).to eq 412 } + after { + subject.run + expect(response.code).to eq 412 + } end - context "when the resource does not define an ETag" do + context 'when the resource does not define an ETag' do let(:resource) do resource_with do - def generate_etag; nil; end + def generate_etag + nil + end end end - it "should reply with 200 when If-None-Match is missing" do + it 'should reply with 200 when If-None-Match is missing' do headers.delete 'If-None-Match' subject.run expect(response.code).to eq 200 end - it "should reply with 200 when If-None-Match is present" do + it 'should reply with 200 when If-None-Match is present' do headers['If-None-Match'] = '"etag"' subject.run expect(response.code).to eq 200 @@ -597,42 +709,49 @@ def generate_etag; nil; end end end - describe "#l13, #l14, #l15, #l17 (If-Modified-Since match)" do - let(:resource) { resource_with { attr_accessor :now; def last_modified; @now; end } } + describe '#l13, #l14, #l15, #l17 (If-Modified-Since match)' do + let(:resource) { + resource_with { + attr_accessor :now + def last_modified + @now + end + } + } before { @now = resource.now = Time.now } - it "should skip LM matching if IMS is missing" do + it 'should skip LM matching if IMS is missing' do expect(headers['If-Modified-Since']).to be_nil - %w{l14 l15 l17}.each do |m| + %w[l14 l15 l17].each do |m| expect(subject).to_not receive(m.to_sym) end subject.run expect(response.code).to_not eq 304 end - it "should skip LM matching if IMS is an invalid date" do - headers['If-Modified-Since'] = "garbage" - %w{l15 l17}.each do |m| + it 'should skip LM matching if IMS is an invalid date' do + headers['If-Modified-Since'] = 'garbage' + %w[l15 l17].each do |m| expect(subject).to_not receive(m.to_sym) end subject.run expect(response.code).to_not eq 304 end - it "should skip LM matching if IMS is later than current time" do + it 'should skip LM matching if IMS is later than current time' do headers['If-Modified-Since'] = (@now + 1000).httpdate expect(subject).to_not receive(:l17) subject.run expect(response.code).to_not eq 304 end - it "should reply with 304 if LM is <= IMS" do + it 'should reply with 304 if LM is <= IMS' do headers['If-Modified-Since'] = (@now - 1).httpdate resource.now = @now - 1000 subject.run expect(response.code).to eq 304 end - it "should not reply with 304 if LM is > IMS" do + it 'should not reply with 304 if LM is > IMS' do headers['If-Modified-Since'] = (@now - 1000).httpdate subject.run expect(response.code).to_not eq 304 @@ -640,35 +759,40 @@ def generate_etag; nil; end end # Resource missing branch (upper right) - describe "#h7 (If-Match: * exists?)" do + describe '#h7 (If-Match: * exists?)' do let(:resource) { missing_resource } - it "should reply with 412 when the If-Match header is *" do + it 'should reply with 412 when the If-Match header is *' do headers['If-Match'] = '"*"' subject.run expect(response.code).to eq 412 end - it "should not reply with 412 when the If-Match header is missing or not *" do - headers['If-Match'] = ['"etag"', nil][rand(1)] + it 'should not reply with 412 when the If-Match header is missing or not *' do + headers['If-Match'] = ['"etag"', nil][rand(2)] subject.run expect(response.code).to_not eq 412 end end - describe "#i7 (PUT?)" do + describe '#i7 (PUT?)' do let(:resource) do missing_resource_with do - def allowed_methods; %w{GET HEAD PUT POST}; end - def process_post; true; end + def allowed_methods + %w[GET HEAD PUT POST] + end + + def process_post + true + end end end - let(:body) { %W{GET HEAD DELETE}.include?(method) ? nil : "This is the body." } + let(:body) { %W[GET HEAD DELETE].include?(method) ? nil : 'This is the body.' } before { headers['Content-Type'] = 'text/plain' } - context "when the method is PUT" do - let(:method){ "PUT" } + context 'when the method is PUT' do + let(:method) { 'PUT' } - it "should not reach state k7" do + it 'should not reach state k7' do expect(subject).to_not receive(:k7) subject.run end @@ -676,10 +800,10 @@ def process_post; true; end after { expect([404, 410, 303]).to_not include(response.code) } end - context "when the method is not PUT" do - let(:method){ %W{GET HEAD POST DELETE}[rand(4)] } + context 'when the method is not PUT' do + let(:method) { %W[GET HEAD POST DELETE][rand(4)] } - it "should not reach state i4" do + it 'should not reach state i4' do expect(subject).to_not receive(:i4) subject.run end @@ -688,90 +812,112 @@ def process_post; true; end end end - describe "#i4 (Apply to a different URI?)" do + describe '#i4 (Apply to a different URI?)' do let(:resource) do missing_resource_with do attr_accessor :location - def moved_permanently?; @location; end - def allowed_methods; %w[PUT]; end + def moved_permanently? + @location + end + + def allowed_methods + %w[PUT] + end end end - let(:method){ "PUT" } - let(:body){ "This is the body." } - let(:headers) { Webmachine::Headers["Content-Type" => "text/plain", "Content-Length" => body.size.to_s] } + let(:method) { 'PUT' } + let(:body) { 'This is the body.' } + let(:headers) { Webmachine::Headers['Content-Type' => 'text/plain', 'Content-Length' => body.size.to_s] } - it "should reply with 301 when the resource has moved" do - resource.location = URI.parse("http://localhost:8098/newuri") + it 'should reply with 301 when the resource has moved' do + resource.location = URI.parse('http://localhost:8098/newuri') subject.run expect(response.code).to eq 301 expect(response.headers['Location']).to eq resource.location.to_s end - it "should not reply with 301 when resource has not moved" do + it 'should not reply with 301 when resource has not moved' do resource.location = false subject.run expect(response.code).to_not eq 301 end end - describe "Redirection (Resource previously existed)" do + describe 'Redirection (Resource previously existed)' do let(:resource) do missing_resource_with do attr_writer :moved_perm, :moved_temp, :allow_missing - def previously_existed?; true; end - def moved_permanently?; @moved_perm; end - def moved_temporarily?; @moved_temp; end - def allow_missing_post?; @allow_missing; end - def allowed_methods; %W{GET POST}; end - def process_post; true; end + def previously_existed? + true + end + + def moved_permanently? + @moved_perm + end + + def moved_temporarily? + @moved_temp + end + + def allow_missing_post? + @allow_missing + end + + def allowed_methods + %W[GET POST] + end + + def process_post + true + end end end - let(:method){ @method || "GET" } + let(:method) { @method || 'GET' } - describe "#k5 (Moved permanently?)" do - it "should reply with 301 when the resource has moved permanently" do - uri = resource.moved_perm = URI.parse("http://www.google.com/") + describe '#k5 (Moved permanently?)' do + it 'should reply with 301 when the resource has moved permanently' do + uri = resource.moved_perm = URI.parse('http://www.google.com/') subject.run expect(response.code).to eq 301 expect(response.headers['Location']).to eq uri.to_s end - it "should not reply with 301 when the resource has not moved permanently" do + it 'should not reply with 301 when the resource has not moved permanently' do resource.moved_perm = false subject.run expect(response.code).to_not eq 301 end end - describe "#l5 (Moved temporarily?)" do + describe '#l5 (Moved temporarily?)' do before { resource.moved_perm = false } - it "should reply with 307 when the resource has moved temporarily" do - uri = resource.moved_temp = URI.parse("http://www.basho.com/") + it 'should reply with 307 when the resource has moved temporarily' do + uri = resource.moved_temp = URI.parse('http://www.basho.com/') subject.run expect(response.code).to eq 307 expect(response.headers['Location']).to eq uri.to_s end - it "should not reply with 307 when the resource has not moved temporarily" do + it 'should not reply with 307 when the resource has not moved temporarily' do resource.moved_temp = false subject.run expect(response.code).to_not eq 307 end end - describe "#m5 (POST?), #n5 (POST to missing resource?)" do + describe '#m5 (POST?), #n5 (POST to missing resource?)' do before { resource.moved_perm = resource.moved_temp = false } - it "should reply with 410 when the method is not POST" do - expect(method).to_not eq "POST" + it 'should reply with 410 when the method is not POST' do + expect(method).to_not eq 'POST' subject.run expect(response.code).to eq 410 end - it "should reply with 410 when the resource disallows missing POSTs" do - @method = "POST" + it 'should reply with 410 when the resource disallows missing POSTs' do + @method = 'POST' resource.allow_missing = false subject.run expect(response.code).to eq 410 end - it "should not reply with 410 when the resource allows missing POSTs" do - @method = "POST" + it 'should not reply with 410 when the resource allows missing POSTs' do + @method = 'POST' resource.allow_missing = true subject.run expect(response.code).to eq 410 @@ -779,51 +925,67 @@ def process_post; true; end end end - describe "#l7 (POST?), #m7 (POST to missing resource?)" do + describe '#l7 (POST?), #m7 (POST to missing resource?)' do let(:resource) do missing_resource_with do attr_accessor :allow_missing - def allowed_methods; %W{GET POST}; end - def previously_existed?; false; end - def allow_missing_post?; @allow_missing; end - def process_post; true; end + def allowed_methods + %W[GET POST] + end + + def previously_existed? + false + end + + def allow_missing_post? + @allow_missing + end + + def process_post + true + end end end - let(:method){ @method || "GET" } - it "should reply with 404 when the method is not POST" do - expect(method).to_not eq "POST" + let(:method) { @method || 'GET' } + it 'should reply with 404 when the method is not POST' do + expect(method).to_not eq 'POST' subject.run expect(response.code).to eq 404 end - it "should reply with 404 when the resource disallows missing POSTs" do - @method = "POST" + it 'should reply with 404 when the resource disallows missing POSTs' do + @method = 'POST' resource.allow_missing = false subject.run expect(response.code).to eq 404 end - it "should not reply with 404 when the resource allows missing POSTs" do - @method = "POST" + it 'should not reply with 404 when the resource allows missing POSTs' do + @method = 'POST' resource.allow_missing = true subject.run expect(response.code).to_not eq 404 end end - describe "#p3 (Conflict?)" do + describe '#p3 (Conflict?)' do let(:resource) do missing_resource_with do attr_writer :conflict - def allowed_methods; %W{PUT}; end - def is_conflict?; @conflict; end + def allowed_methods + %W[PUT] + end + + def is_conflict? + @conflict + end end end - let(:method){ "PUT" } - it "should reply with 409 if the resource is in conflict" do + let(:method) { 'PUT' } + it 'should reply with 409 if the resource is in conflict' do resource.conflict = true subject.run expect(response.code).to eq 409 end - it "should not reply with 409 if the resource is in conflict" do + it 'should not reply with 409 if the resource is in conflict' do resource.conflict = false subject.run expect(response.code).to_not eq 409 @@ -831,13 +993,19 @@ def is_conflict?; @conflict; end end # Bottom right - describe "#n11 (Redirect?)" do - let(:method) { "POST" } + describe '#n11 (Redirect?)' do + let(:method) { 'POST' } let(:resource) do resource_with do attr_writer :new_loc, :exist - def allowed_methods; %w{POST}; end - def allow_missing_post?; true; end + def allowed_methods + %w[POST] + end + + def allow_missing_post? + true + end + def process_post response.redirect_to(@new_loc) if @new_loc true @@ -845,17 +1013,17 @@ def process_post end end [true, false].each do |e| - context "and the resource #{ e ? "does not exist" : 'exists'}" do + context "and the resource #{e ? "does not exist" : "exists"}" do before { resource.exist = e } - it "should reply with 303 if the resource redirected" do - resource.new_loc = URI.parse("/foo/bar") + it 'should reply with 303 if the resource redirected' do + resource.new_loc = URI.parse('/foo/bar') subject.run expect(response.code).to eq 303 - expect(response.headers['Location']).to eq "/foo/bar" + expect(response.headers['Location']).to eq '/foo/bar' end - it "should not reply with 303 if the resource did not redirect" do + it 'should not reply with 303 if the resource did not redirect' do resource.new_loc = nil subject.run expect(response.code).to_not eq 303 @@ -864,40 +1032,61 @@ def process_post end end - describe "#p11 (New resource?)" do + describe '#p11 (New resource?)' do let(:resource) do resource_with do attr_writer :exist, :new_loc, :create - def allowed_methods; %W{PUT POST}; end - def resource_exists?; @exist; end - def process_post; true; end - def allow_missing_post?; true; end - def post_is_create?; @create; end - def create_path; @new_loc; end - def content_types_accepted; [["text/plain", :accept_text]]; end + def allowed_methods + %W[PUT POST] + end + + def resource_exists? + @exist + end + + def process_post + true + end + + def allow_missing_post? + true + end + + def post_is_create? + @create + end + + def create_path + @new_loc + end + + def content_types_accepted + [['text/plain', :accept_text]] + end + def accept_text response.headers['Location'] = @new_loc.to_s if @new_loc true end end end - let(:body) { "new content" } - let(:headers){ Webmachine::Headers['content-type' => 'text/plain'] } + let(:body) { 'new content' } + let(:headers) { Webmachine::Headers['content-type' => 'text/plain'] } - context "when the method is PUT" do - let(:method){ "PUT" } + context 'when the method is PUT' do + let(:method) { 'PUT' } [true, false].each do |e| - context "and the resource #{ e ? "does not exist" : 'exists'}" do + context "and the resource #{e ? "does not exist" : "exists"}" do before { resource.exist = e } - it "should reply with 201 when the Location header has been set" do + it 'should reply with 201 when the Location header has been set' do resource.exist = e - resource.new_loc = "http://ruby-doc.org/" + resource.new_loc = 'http://ruby-doc.org/' subject.run expect(response.code).to eq 201 end - it "should not reply with 201 when the Location header has been set" do + it 'should not reply with 201 when the Location header has been set' do resource.exist = e subject.run expect(response.headers['Location']).to be_nil @@ -907,25 +1096,25 @@ def accept_text end end - context "when the method is POST" do - let(:method){ "POST" } + context 'when the method is POST' do + let(:method) { 'POST' } [true, false].each do |e| - context "and the resource #{ e ? 'exists' : "does not exist"}" do + context "and the resource #{e ? "exists" : "does not exist"}" do before { resource.exist = e } - it "should reply with 201 when post_is_create is true and create_path returns a URI" do - resource.new_loc = created = "/foo/bar/baz" + it 'should reply with 201 when post_is_create is true and create_path returns a URI' do + resource.new_loc = created = '/foo/bar/baz' resource.create = true subject.run expect(response.code).to eq 201 expect(response.headers['Location']).to eq created end - it "should reply with 500 when post_is_create is true and create_path returns nil" do + it 'should reply with 500 when post_is_create is true and create_path returns nil' do resource.create = true subject.run expect(response.code).to eq 500 expect(response.error).to_not be_nil end - it "should not reply with 201 when post_is_create is false" do + it 'should not reply with 201 when post_is_create is false' do resource.create = false subject.run expect(response.code).to_not eq 201 @@ -935,54 +1124,67 @@ def accept_text end end - describe "#o14 (Conflict?)" do + describe '#o14 (Conflict?)' do let(:resource) do resource_with do attr_writer :conflict - def allowed_methods; %W{PUT}; end - def is_conflict?; @conflict; end + def allowed_methods + %W[PUT] + end + + def is_conflict? + @conflict + end end end - let(:method){ "PUT" } - it "should reply with 409 if the resource is in conflict" do + let(:method) { 'PUT' } + it 'should reply with 409 if the resource is in conflict' do resource.conflict = true subject.run expect(response.code).to eq 409 end - it "should not reply with 409 if the resource is in conflict" do + it 'should not reply with 409 if the resource is in conflict' do resource.conflict = false subject.run expect(response.code).to_not eq 409 end end - describe "#m16 (DELETE?), #m20 (Delete enacted?)" do - let(:method){ @method || "DELETE" } + describe '#m16 (DELETE?), #m20 (Delete enacted?)' do + let(:method) { @method || 'DELETE' } let(:resource) do resource_with do attr_writer :deleted, :completed - def allowed_methods; %w{GET DELETE}; end - def delete_resource; @deleted; end - def delete_completed?; @completed; end + def allowed_methods + %w[GET DELETE] + end + + def delete_resource + @deleted + end + + def delete_completed? + @completed + end end end - it "should not reply with 202 if the method is not DELETE" do - @method = "GET" + it 'should not reply with 202 if the method is not DELETE' do + @method = 'GET' subject.run expect(response.code).to_not eq 202 end - it "should reply with 500 if the DELETE fails" do + it 'should reply with 500 if the DELETE fails' do resource.deleted = false subject.run expect(response.code).to eq 500 end - it "should reply with 202 if the DELETE succeeds but is not complete" do + it 'should reply with 202 if the DELETE succeeds but is not complete' do resource.deleted = true resource.completed = false subject.run expect(response.code).to eq 202 end - it "should not reply with 202 if the DELETE succeeds and completes" do + it 'should not reply with 202 if the DELETE succeeds and completes' do resource.completed = resource.deleted = true subject.run expect(response.code).to_not eq 202 @@ -994,45 +1196,65 @@ def delete_completed?; @completed; end # describe "#n16 (POST?)" do it; end # describe "#o16 (PUT?)" do it; end - describe "#o18 (Multiple representations?)" do + describe '#o18 (Multiple representations?)' do let(:resource) do resource_with do attr_writer :exist, :multiple def delete_resource - response.body = "Response content." + response.body = 'Response content.' + true + end + + def delete_completed? true end - def delete_completed?; true; end - def allowed_methods; %W{GET HEAD PUT POST DELETE}; end - def resource_exists?; @exist; end - def allow_missing_post?; true; end - def content_types_accepted; [[request.content_type, :accept_all]]; end - def multiple_choices?; @multiple; end + + def allowed_methods + %W[GET HEAD PUT POST DELETE] + end + + def resource_exists? + @exist + end + + def allow_missing_post? + true + end + + def content_types_accepted + [[request.content_type, :accept_all]] + end + + def multiple_choices? + @multiple + end + def process_post - response.body = "Response content." + response.body = 'Response content.' true end + def accept_all - response.body = "Response content." + response.body = 'Response content.' true end end end - [["GET", true],["HEAD", true],["PUT", true],["PUT", false],["POST",true],["POST",false], - ["DELETE", true]].each do |m, e| - context "when the method is #{m} and the resource #{e ? 'exists' : 'does not exist' }" do - let(:method){ m } - let(:body) { %W{PUT POST}.include?(m) ? "request body" : "" } - let(:headers) { %W{PUT POST}.include?(m) ? Webmachine::Headers['content-type' => 'text/plain'] : Webmachine::Headers.new } + [['GET', true], ['HEAD', true], ['PUT', true], ['PUT', false], ['POST', true], ['POST', false], + ['DELETE', true]].each do |m, e| + context "when the method is #{m} and the resource #{e ? "exists" : "does not exist"}" do + let(:method) { m } + let(:body) { %W[PUT POST].include?(m) ? 'request body' : '' } + let(:headers) { %W[PUT POST].include?(m) ? Webmachine::Headers['content-type' => 'text/plain'] : Webmachine::Headers.new } before { resource.exist = e } - it "should reply with 200 if there are not multiple representations" do + it 'should reply with 200 if there are not multiple representations' do resource.multiple = false subject.run puts response.error if response.code == 500 expect(response.code).to eq 200 end - it "should reply with 300 if there are multiple representations" do + it 'should reply with 300 if there are multiple representations' do resource.multiple = true subject.run puts response.error if response.code == 500 @@ -1042,37 +1264,56 @@ def accept_all end end - describe "#o20 (Response has entity?)" do + describe '#o20 (Response has entity?)' do let(:resource) do resource_with do attr_writer :exist, :body - def delete_resource; true; end - def delete_completed?; true; end - def allowed_methods; %{GET PUT POST DELETE}; end - def resource_exists?; @exist; end - def allow_missing_post?; true; end - def content_types_accepted; [[request.content_type, :accept_all]]; end + def delete_resource + true + end + + def delete_completed? + true + end + + def allowed_methods + %(GET PUT POST DELETE) + end + + def resource_exists? + @exist + end + + def allow_missing_post? + true + end + + def content_types_accepted + [[request.content_type, :accept_all]] + end + def process_post response.body = @body if @body true end + def accept_all response.body = @body if @body true end end end - let(:method) { @method || "GET" } - let(:headers) { %{PUT POST}.include?(method) ? Webmachine::Headers["content-type" => "text/plain"] : Webmachine::Headers.new } - let(:body) { %{PUT POST}.include?(method) ? "This is the body." : nil } - context "when a response body is present" do - before { resource.body = "Hello, world!" } + let(:method) { @method || 'GET' } + let(:headers) { %(PUT POST).include?(method) ? Webmachine::Headers['content-type' => 'text/plain'] : Webmachine::Headers.new } + let(:body) { %(PUT POST).include?(method) ? 'This is the body.' : nil } + context 'when a response body is present' do + before { resource.body = 'Hello, world!' } [ - ["PUT", false], - ["POST", false], - ["DELETE", true], - ["POST", true], - ["PUT", true] + ['PUT', false], + ['POST', false], + ['DELETE', true], + ['POST', true], + ['PUT', true] ].each do |m, e| it "should not reply with 204 (via exists:#{e}, #{m})" do @method = m @@ -1082,13 +1323,13 @@ def accept_all end end end - context "when a response body is not present" do + context 'when a response body is not present' do [ - ["PUT", false], - ["POST", false], - ["DELETE", true], - ["POST", true], - ["PUT", true] + ['PUT', false], + ['POST', false], + ['DELETE', true], + ['POST', true], + ['PUT', true] ].each do |m, e| it "should reply with 204 (via exists:#{e}, #{m})" do @method = m @@ -1100,8 +1341,8 @@ def accept_all end end - describe "On error" do - context "handle_exception is inherited." do + describe 'On error' do + context 'handle_exception is inherited.' do let :resource do resource_with do def to_html @@ -1110,22 +1351,22 @@ def to_html end end - it "calls handle_exception" do + it 'calls handle_exception' do expect(resource).to receive(:handle_exception).with instance_of(RuntimeError) subject.run end - it "sets the response code to 500" do + it 'sets the response code to 500' do subject.run expect(response.code).to eq 500 end end - context "handle_exception is defined" do + context 'handle_exception is defined' do let :resource do resource_with do def handle_exception(e) - response.body = "error" + response.body = 'error' end def to_html @@ -1134,12 +1375,12 @@ def to_html end end - it "can define a response body" do + it 'can define a response body' do subject.run - expect(response.body).to eq "error" + expect(response.body).to eq 'error' end - it "sets the response code to 500" do + it 'sets the response code to 500' do subject.run expect(response.code).to eq 500 end diff --git a/spec/webmachine/decision/fsm_spec.rb b/spec/webmachine/decision/fsm_spec.rb index 957b841b..e1f8e800 100644 --- a/spec/webmachine/decision/fsm_spec.rb +++ b/spec/webmachine/decision/fsm_spec.rb @@ -6,10 +6,8 @@ subject { described_class.new(resource, request, response) } let(:run_with_exception) do - begin - subject.run - rescue Exception - end + subject.run + rescue Exception end describe 'handling of exceptions from decision methods' do @@ -17,7 +15,7 @@ Webmachine::RescuableException::UNRESCUABLE end - describe "rescueable exceptions" do + describe 'rescueable exceptions' do it 'does rescue Exception' do allow(subject).to receive(Webmachine::Decision::Flow::START) { raise(Exception) } expect(resource).to receive(:handle_exception).with instance_of(Exception) @@ -31,10 +29,10 @@ end end - describe "UNRESCUABLE exceptions" do - shared_examples "UNRESCUABLE" do |e| + describe 'UNRESCUABLE exceptions' do + shared_examples 'UNRESCUABLE' do |e| specify "#{e} is not rescued" do - allow(subject).to receive(Webmachine::Decision::Flow::START) {raise(e)} + allow(subject).to receive(Webmachine::Decision::Flow::START) { raise(e) } expect(resource).to_not receive(:handle_exception).with instance_of(e) expect { subject.run }.to raise_error(e) end @@ -42,9 +40,9 @@ eary = Webmachine::RescuableException::UNRESCUABLE_DEFAULTS - [ Webmachine::MalformedRequest, # Webmachine rescues by default, so it won't re-raise. SignalException # Requires raise in form 'raise SignalException, "SIGSOMESIGNAL"'. - # Haven't found a good no-op signal to use here. + # Haven't found a good no-op signal to use here. ] - eary.each{|e| include_examples "UNRESCUABLE", e} + eary.each { |e| include_examples 'UNRESCUABLE', e } end end @@ -85,15 +83,15 @@ end it 'renders an error' do - expect(Webmachine). - to receive(:render_error). - with(500, request, response, { :message => error.message }) + expect(Webmachine) + .to receive(:render_error) + .with(500, request, response, {message: error.message}) subject.run end end describe 'handling of exceptions from resource.finish_request' do - let(:exception) { Class.new(Exception).new } + let(:exception) { Class.new(RuntimeError).new } before do Webmachine::RescuableException.remove(exception) @@ -129,7 +127,7 @@ end end - it "sets the response code before calling finish_request" do + it 'sets the response code before calling finish_request' do resource_class.class_eval do class << self attr_accessor :current_response_code diff --git a/spec/webmachine/decision/helpers_spec.rb b/spec/webmachine/decision/helpers_spec.rb index d495e045..4caab4bb 100644 --- a/spec/webmachine/decision/helpers_spec.rb +++ b/spec/webmachine/decision/helpers_spec.rb @@ -1,20 +1,22 @@ require 'spec_helper' describe Webmachine::Decision::Helpers do - include_context "default resource" + include_context 'default resource' subject { Webmachine::Decision::FSM.new(resource, request, response) } def resource_with(&block) klass = Class.new(Webmachine::Resource) do - def to_html; "test resource"; end + def to_html + 'test resource' + end end - klass.module_eval(&block) if block_given? + klass.module_eval(&block) if block klass.new(request, response) end let(:resource) { resource_with } - describe "accepting request bodies" do + describe 'accepting request bodies' do let(:resource) do resource_with do def initialize @@ -22,31 +24,34 @@ def initialize end attr_accessor :accepted, :result def content_types_accepted - (accepted || []).map {|t| Array === t ? t : [t, :accept_doc] } + (accepted || []).map { |t| (Array === t) ? t : [t, :accept_doc] } + end + + def accept_doc + result end - def accept_doc; result; end end end - it "should return 415 when no types are accepted" do + it 'should return 415 when no types are accepted' do expect(subject.accept_helper).to eq 415 end - it "should return 415 when the posted type is not acceptable" do - resource.accepted = %W{application/json} - headers['Content-Type'] = "text/xml" + it 'should return 415 when the posted type is not acceptable' do + resource.accepted = %W[application/json] + headers['Content-Type'] = 'text/xml' expect(subject.accept_helper).to eq 415 end - it "should call the method for the first acceptable type, taking into account params" do - resource.accepted = ["application/json;v=3", ["application/json", :other]] + it 'should call the method for the first acceptable type, taking into account params' do + resource.accepted = ['application/json;v=3', ['application/json', :other]] expect(resource).to receive(:other).and_return(true) headers['Content-Type'] = 'application/json;v=2' expect(subject.accept_helper).to be(true) end end - context "setting the Content-Length header when responding" do + context 'setting the Content-Length header when responding' do [204, 205, 304].each do |code| it "removes the header for entity-less response code #{code}" do response.headers['Content-Length'] = '0' @@ -81,82 +86,82 @@ def accept_doc; result; end end end - describe "#encode_body" do + describe '#encode_body' do before { subject.run } - context "with a String body" do + context 'with a String body' do before { response.body = '' } - it "does not modify the response body" do + it 'does not modify the response body' do subject.encode_body expect(response.body).to be_instance_of(String) end - it "sets the Content-Length header in the response" do + it 'sets the Content-Length header in the response' do subject.encode_body expect(response.headers['Content-Length']).to eq response.body.bytesize.to_s end end - shared_examples_for "a non-String body" do - it "does not set the Content-Length header in the response" do + shared_examples_for 'a non-String body' do + it 'does not set the Content-Length header in the response' do subject.encode_body expect(response.headers).to_not have_key('Content-Length') end - it "sets the Transfer-Encoding response header to chunked" do + it 'sets the Transfer-Encoding response header to chunked' do subject.encode_body expect(response.headers['Transfer-Encoding']).to eq 'chunked' end end - context "with an Enumerable body" do + context 'with an Enumerable body' do before { response.body = ['one', 'two'] } - it "wraps the response body in an EnumerableEncoder" do + it 'wraps the response body in an EnumerableEncoder' do subject.encode_body expect(response.body).to be_instance_of(Webmachine::Streaming::EnumerableEncoder) end - it_should_behave_like "a non-String body" + it_should_behave_like 'a non-String body' end - context "with a callable body" do - before { response.body = Proc.new { 'proc' } } + context 'with a callable body' do + before { response.body = proc { 'proc' } } - it "wraps the response body in a CallableEncoder" do + it 'wraps the response body in a CallableEncoder' do subject.encode_body expect(response.body).to be_instance_of(Webmachine::Streaming::CallableEncoder) end - it_should_behave_like "a non-String body" + it_should_behave_like 'a non-String body' end - context "with a Fiber body" do - before { response.body = Fiber.new { Fiber.yield "foo" } } + context 'with a Fiber body' do + before { response.body = Fiber.new { Fiber.yield 'foo' } } - it "wraps the response body in a FiberEncoder" do + it 'wraps the response body in a FiberEncoder' do subject.encode_body expect(response.body).to be_instance_of(Webmachine::Streaming::FiberEncoder) end - it_should_behave_like "a non-String body" + it_should_behave_like 'a non-String body' end - context "with a File body" do - before { response.body = File.open("spec/spec_helper.rb", "r") } + context 'with a File body' do + before { response.body = File.open('spec/spec_helper.rb', 'r') } - it "wraps the response body in an IOEncoder" do + it 'wraps the response body in an IOEncoder' do subject.encode_body expect(response.body).to be_instance_of(Webmachine::Streaming::IOEncoder) end - it "sets the Content-Length header to the size of the file" do + it 'sets the Content-Length header to the size of the file' do subject.encode_body expect(response.headers['Content-Length']).to eq File.stat('spec/spec_helper.rb').size.to_s end - it "progressively yields file contents for each enumeration" do + it 'progressively yields file contents for each enumeration' do subject.encode_body body_size = 0 response.body.each do |chunk| @@ -166,50 +171,50 @@ def accept_doc; result; end expect(body_size).to eq File.stat('spec/spec_helper.rb').size end - context "when the resource provides a non-identity encoding that the client accepts" do + context 'when the resource provides a non-identity encoding that the client accepts' do let(:resource) do resource_with do def encodings_provided - { "deflate" => :encode_deflate, "identity" => :encode_identity } + {'deflate' => :encode_deflate, 'identity' => :encode_identity} end end end let(:headers) do - Webmachine::Headers.new({"Accept-Encoding" => "deflate, identity"}) + Webmachine::Headers.new({'Accept-Encoding' => 'deflate, identity'}) end - it_should_behave_like "a non-String body" + it_should_behave_like 'a non-String body' end end - context "with a StringIO body" do - before { response.body = StringIO.new("A VERY LONG STRING, NOT") } + context 'with a StringIO body' do + before { response.body = StringIO.new('A VERY LONG STRING, NOT') } - it "wraps the response body in an IOEncoder" do + it 'wraps the response body in an IOEncoder' do subject.encode_body expect(response.body).to be_instance_of(Webmachine::Streaming::IOEncoder) end - it "sets the Content-Length header to the size of the string" do + it 'sets the Content-Length header to the size of the string' do subject.encode_body expect(response.headers['Content-Length']).to eq response.body.size.to_s end - context "when the resource provides a non-identity encoding that the client accepts" do + context 'when the resource provides a non-identity encoding that the client accepts' do let(:resource) do resource_with do def encodings_provided - { "deflate" => :encode_deflate, "identity" => :encode_identity } + {'deflate' => :encode_deflate, 'identity' => :encode_identity} end end end let(:headers) do - Webmachine::Headers.new({"Accept-Encoding" => "deflate, identity"}) + Webmachine::Headers.new({'Accept-Encoding' => 'deflate, identity'}) end - it_should_behave_like "a non-String body" + it_should_behave_like 'a non-String body' end end end diff --git a/spec/webmachine/dispatcher/route_spec.rb b/spec/webmachine/dispatcher/route_spec.rb index 0a43d810..27272ad0 100644 --- a/spec/webmachine/dispatcher/route_spec.rb +++ b/spec/webmachine/dispatcher/route_spec.rb @@ -1,15 +1,17 @@ require 'spec_helper' Webmachine::Dispatcher::Route.class_eval do - def warn(*msgs); end # silence warnings for tests + # silence warnings for tests + def warn(*msgs) + end end describe Webmachine::Dispatcher::Route do - let(:method) { "GET" } - let(:uri) { URI.parse("http://localhost:8080/") } + let(:method) { 'GET' } + let(:uri) { URI.parse('http://localhost:8080/') } let(:routing_tokens) { nil } - let(:request){ Webmachine::Request.new(method, uri, Webmachine::Headers.new, "", routing_tokens) } - let(:resource){ Class.new(Webmachine::Resource) } + let(:request) { Webmachine::Request.new(method, uri, Webmachine::Headers.new, '', routing_tokens) } + let(:resource) { Class.new(Webmachine::Resource) } describe '#apply' do let(:route) { @@ -17,11 +19,11 @@ def warn(*msgs); end # silence warnings for tests } describe 'a path_info fragment' do - let(:uri) { URI.parse("http://localhost:8080/hello/planet%20earth%20++") } + let(:uri) { URI.parse('http://localhost:8080/hello/planet%20earth%20++') } it 'should decode the value' do route.apply(request) - expect(request.path_info).to eq({:string => 'planet earth ++'}) + expect(request.path_info).to eq({string: 'planet earth ++'}) end end end @@ -29,9 +31,9 @@ def warn(*msgs); end # silence warnings for tests matcher :match_route do |*expected| route = Webmachine::Dispatcher::Route.new(expected[0], Class.new(Webmachine::Resource), expected[1] || {}) match do |actual| - uri = URI.parse("http://localhost:8080") + uri = URI.parse('http://localhost:8080') uri.path = actual - req = Webmachine::Request.new("GET", uri, Webmachine::Headers.new, "", routing_tokens) + req = Webmachine::Request.new('GET', uri, Webmachine::Headers.new, '', routing_tokens) route.match?(req) end @@ -43,61 +45,61 @@ def warn(*msgs); end # silence warnings for tests end end - it "warns about the deprecated string splat when initializing" do - [["*"],["foo", "*"],["foo", :bar, "*"]].each do |path| + it 'warns about the deprecated string splat when initializing' do + [['*'], ['foo', '*'], ['foo', :bar, '*']].each do |path| route = described_class.allocate expect(route).to receive(:warn) route.send :initialize, path, resource, {} end end - context "matching a request" do - context "on the root path" do - subject { "/" } + context 'matching a request' do + context 'on the root path' do + subject { '/' } it { is_expected.to match_route([]) } it { is_expected.to match_route ['*'] } it { is_expected.to match_route [:*] } - it { is_expected.not_to match_route %w{foo} } + it { is_expected.not_to match_route %w[foo] } it { is_expected.not_to match_route [:id] } end - context "on a deep path" do - subject { "/foo/bar/baz" } - it { is_expected.to match_route %w{foo bar baz} } - it { is_expected.to match_route ['foo', :id, "baz"] } + context 'on a deep path' do + subject { '/foo/bar/baz' } + it { is_expected.to match_route %w[foo bar baz] } + it { is_expected.to match_route ['foo', :id, 'baz'] } it { is_expected.to match_route ['foo', :*] } it { is_expected.to match_route [:id, :*] } it { is_expected.not_to match_route [] } it { is_expected.not_to match_route ['bar', :*] } end - context "with a guard on the request method" do - let(:uri){ URI.parse("http://localhost:8080/notes") } + context 'with a guard on the request method' do + let(:uri) { URI.parse('http://localhost:8080/notes') } let(:route) do described_class.new( - ["notes"], - lambda { |request| request.method == "POST" }, - resource - ) + ['notes'], + lambda { |request| request.method == 'POST' }, + resource + ) end subject { route } - context "when guard passes" do - let(:method){ "POST" } + context 'when guard passes' do + let(:method) { 'POST' } it { is_expected.to be_match(request) } - context "but the path match fails" do - let(:uri){ URI.parse("http://localhost:8080/other") } + context 'but the path match fails' do + let(:uri) { URI.parse('http://localhost:8080/other') } it { is_expected.not_to be_match(request) } end end - context "when guard fails" do - let(:method) { "GET" } + context 'when guard fails' do + let(:method) { 'GET' } it { is_expected.not_to be_match(request) } end - context "when the guard responds to #call" do + context 'when the guard responds to #call' do let(:guard_class) do Class.new do def initialize(method) @@ -111,136 +113,136 @@ def call(request) end let(:route) do - described_class.new(["notes"], guard_class.new("POST"), resource) + described_class.new(['notes'], guard_class.new('POST'), resource) end - context "when the guard passes" do - let(:method){ "POST" } + context 'when the guard passes' do + let(:method) { 'POST' } it { is_expected.to be_match(request) } end - context "when the guard fails" do + context 'when the guard fails' do # let(:method){ "GET" } it { is_expected.not_to be_match(request) } end end end - context "with a request with explicitly specified routing tokens" do - subject { "/some/route/foo/bar" } - let(:routing_tokens) { ["foo", "bar"] } - it { is_expected.to match_route(["foo", "bar"]) } - it { is_expected.to match_route(["foo", :id]) } + context 'with a request with explicitly specified routing tokens' do + subject { '/some/route/foo/bar' } + let(:routing_tokens) { ['foo', 'bar'] } + it { is_expected.to match_route(['foo', 'bar']) } + it { is_expected.to match_route(['foo', :id]) } it { is_expected.to match_route ['*'] } it { is_expected.to match_route [:*] } - it { is_expected.not_to match_route(["some", "route", "foo", "bar"]) } - it { is_expected.not_to match_route %w{foo} } + it { is_expected.not_to match_route(['some', 'route', 'foo', 'bar']) } + it { is_expected.not_to match_route %w[foo] } it { is_expected.not_to match_route [:id] } end end - context "applying bindings" do - context "on the root path" do + context 'applying bindings' do + context 'on the root path' do subject { described_class.new([], resource) } before { subject.apply(request) } - it "should assign the dispatched path to the empty string" do - expect(request.disp_path).to eq("") + it 'should assign the dispatched path to the empty string' do + expect(request.disp_path).to eq('') end - it "should assign empty bindings" do + it 'should assign empty bindings' do expect(request.path_info).to eq({}) end - it "should assign empty path tokens" do + it 'should assign empty path tokens' do expect(request.path_tokens).to eq([]) end - context "with extra user-defined bindings" do - subject { described_class.new([], resource, "bar" => "baz") } + context 'with extra user-defined bindings' do + subject { described_class.new([], resource, 'bar' => 'baz') } - it "should assign the user-defined bindings" do - expect(request.path_info).to eq({"bar" => "baz"}) + it 'should assign the user-defined bindings' do + expect(request.path_info).to eq({'bar' => 'baz'}) end end - context "with a splat" do + context 'with a splat' do subject { described_class.new([:*], resource) } - it "should assign empty path tokens" do + it 'should assign empty path tokens' do expect(request.path_tokens).to eq([]) end end - context "with a deprecated splat string" do + context 'with a deprecated splat string' do subject { described_class.new(['*'], resource) } - it "should assign empty path tokens" do + it 'should assign empty path tokens' do expect(request.path_tokens).to eq([]) end end end - context "on a deep path" do - subject { described_class.new(%w{foo bar baz}, resource) } - let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz") } + context 'on a deep path' do + subject { described_class.new(%w[foo bar baz], resource) } + let(:uri) { URI.parse('http://localhost:8080/foo/bar/baz') } before { subject.apply(request) } - it "should assign the dispatched path as the path past the initial slash" do - expect(request.disp_path).to eq("foo/bar/baz") + it 'should assign the dispatched path as the path past the initial slash' do + expect(request.disp_path).to eq('foo/bar/baz') end - it "should assign empty bindings" do + it 'should assign empty bindings' do expect(request.path_info).to eq({}) end - it "should assign empty path tokens" do + it 'should assign empty path tokens' do expect(request.path_tokens).to eq([]) end - context "with path variables" do + context 'with path variables' do subject { described_class.new(['foo', :id, 'baz'], resource) } - it "should assign the path variables in the bindings" do - expect(request.path_info).to eq({:id => "bar"}) + it 'should assign the path variables in the bindings' do + expect(request.path_info).to eq({id: 'bar'}) end end - context "with regex" do + context 'with regex' do subject { described_class.new([/foo/, /(.*)/, 'baz'], resource) } - it "should assign the captures path variables" do - expect(request.path_info).to eq({:captures => ["bar"]}) + it 'should assign the captures path variables' do + expect(request.path_info).to eq({captures: ['bar']}) end end - context "with multi-capture regex" do + context 'with multi-capture regex' do subject { described_class.new([/foo/, /(.*)/, /baz\.(.*)/], resource) } - let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz.json") } + let(:uri) { URI.parse('http://localhost:8080/foo/bar/baz.json') } - it "should assign the captures path variables" do - expect(request.path_info).to eq({:captures => ["bar", "json"]}) + it 'should assign the captures path variables' do + expect(request.path_info).to eq({captures: ['bar', 'json']}) end end - context "with named capture regex" do + context 'with named capture regex' do subject { described_class.new(['foo', :bar, /(?[^.]+)\.(?.*)/], resource) } - let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz.json") } + let(:uri) { URI.parse('http://localhost:8080/foo/bar/baz.json') } - it "should assign the captures path variables" do - expect(request.path_info).to eq({bar: 'bar', baz: 'baz', format: "json"}) + it 'should assign the captures path variables' do + expect(request.path_info).to eq({bar: 'bar', baz: 'baz', format: 'json'}) end end - context "with a splat" do + context 'with a splat' do subject { described_class.new(['foo', :*], resource) } - it "should capture the path tokens matched by the splat" do - expect(request.path_tokens).to eq(%w{ bar baz }) + it 'should capture the path tokens matched by the splat' do + expect(request.path_tokens).to eq(%w[bar baz]) end end - context "with a deprecated splat string" do - subject { described_class.new(%w{foo *}, resource) } + context 'with a deprecated splat string' do + subject { described_class.new(%w[foo *], resource) } - it "should capture the path tokens matched by the splat" do - expect(request.path_tokens).to eq(%w{ bar baz }) + it 'should capture the path tokens matched by the splat' do + expect(request.path_tokens).to eq(%w[bar baz]) end end end diff --git a/spec/webmachine/dispatcher_spec.rb b/spec/webmachine/dispatcher_spec.rb index 229f3991..795ff0ab 100644 --- a/spec/webmachine/dispatcher_spec.rb +++ b/spec/webmachine/dispatcher_spec.rb @@ -2,17 +2,21 @@ describe Webmachine::Dispatcher do let(:dispatcher) { Webmachine.application.dispatcher } - let(:request) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/"), Webmachine::Headers["accept" => "*/*"], "") } - let(:request2) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/hello/bob.html"), Webmachine::Headers["accept" => "*/*"], "") } + let(:request) { Webmachine::Request.new('GET', URI.parse('http://localhost:8080/'), Webmachine::Headers['accept' => '*/*'], '') } + let(:request2) { Webmachine::Request.new('GET', URI.parse('http://localhost:8080/hello/bob.html'), Webmachine::Headers['accept' => '*/*'], '') } let(:response) { Webmachine::Response.new } let(:resource) do Class.new(Webmachine::Resource) do - def to_html; "hello world!"; end + def to_html + 'hello world!' + end end end let(:resource2) do Class.new(Webmachine::Resource) do - def to_html; "goodbye, cruel world"; end + def to_html + 'goodbye, cruel world' + end end end let(:resource3) do @@ -23,11 +27,11 @@ def to_html end end end - let(:fsm){ double } + let(:fsm) { double } before { dispatcher.reset } - it "should add routes from a block" do + it 'should add routes from a block' do _resource = resource expect(Webmachine.routes do add [:*], _resource @@ -35,33 +39,33 @@ def to_html expect(dispatcher.routes.size).to eq(1) end - it "should add routes" do + it 'should add routes' do expect { dispatcher.add_route [:*], resource }.to_not raise_error end - it "should have add_route return the newly created route" do + it 'should have add_route return the newly created route' do route = dispatcher.add_route [:*], resource expect(route).to be_instance_of Webmachine::Dispatcher::Route end - it "should route to the proper resource" do - dispatcher.add_route ["goodbye"], resource2 + it 'should route to the proper resource' do + dispatcher.add_route ['goodbye'], resource2 dispatcher.add_route [:*], resource expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource), request, response).and_return(fsm) expect(fsm).to receive(:run) dispatcher.dispatch(request, response) end - it "should handle regex path segments in route definition" do - dispatcher.add_route ["hello", /(.*)\.(.*)/], resource3 + it 'should handle regex path segments in route definition' do + dispatcher.add_route ['hello', /(.*)\.(.*)/], resource3 expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource3), request2, response).and_return(fsm) expect(fsm).to receive(:run) dispatcher.dispatch(request2, response) end - it "should apply route to request before creating the resource" do - route = dispatcher.add_route [:*], resource + it 'should apply route to request before creating the resource' do + route = dispatcher.add_route [:*], resource applied = false expect(route).to receive(:apply) { applied = true } @@ -73,32 +77,32 @@ def to_html dispatcher.dispatch(request, response) end - it "should add routes with guards" do - dispatcher.add [], lambda {|req| req.method == "POST" }, resource + it 'should add routes with guards' do + dispatcher.add [], lambda { |req| req.method == 'POST' }, resource dispatcher.add [:*], resource2 do |req| !req.query.empty? end - request.uri.query = "?foo=bar" + request.uri.query = '?foo=bar' expect(dispatcher.routes.size).to eq(2) expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource2), request, response).and_return(fsm) expect(fsm).to receive(:run) dispatcher.dispatch(request, response) end - it "should respond with a valid resource for a 404" do + it 'should respond with a valid resource for a 404' do dispatcher.dispatch(request, response) - expect(response.code).to eq(404) + expect(response.code).to eq(404) expect(response.body).to_not be_empty - expect(response.headers).to have_key('Content-Length') - expect(response.headers).to have_key('Date') + expect(response.headers).to have_key('Content-Length') + expect(response.headers).to have_key('Date') end - it "should respond with a valid resource for a 404 with a custom Accept header" do - request.headers['Accept'] = "application/json" + it 'should respond with a valid resource for a 404 with a custom Accept header' do + request.headers['Accept'] = 'application/json' dispatcher.dispatch(request, response) - expect(response.code).to eq(404) + expect(response.code).to eq(404) expect(response.body).to_not be_empty - expect(response.headers).to have_key('Content-Length') - expect(response.headers).to have_key('Date') + expect(response.headers).to have_key('Content-Length') + expect(response.headers).to have_key('Date') end end diff --git a/spec/webmachine/errors_spec.rb b/spec/webmachine/errors_spec.rb index 84b9c493..2b10ae59 100644 --- a/spec/webmachine/errors_spec.rb +++ b/spec/webmachine/errors_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' -describe "Webmachine errors" do - describe ".render_error" do - it "sets the given response code on the response object" do - req = double('request', :method => 'GET').as_null_object +describe 'Webmachine errors' do + describe '.render_error' do + it 'sets the given response code on the response object' do + req = double('request', method: 'GET').as_null_object res = Webmachine::Response.new Webmachine.render_error(404, req, res) diff --git a/spec/webmachine/etags_spec.rb b/spec/webmachine/etags_spec.rb index c3266c03..e8e65629 100644 --- a/spec/webmachine/etags_spec.rb +++ b/spec/webmachine/etags_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Webmachine::ETag do - let(:etag_str){ '"deadbeef12345678"' } + let(:etag_str) { '"deadbeef12345678"' } let(:etag) { described_class.new etag_str } subject { etag } @@ -12,7 +12,7 @@ its(:etag) { should == '"deadbeef12345678"' } it { is_expected.to eq(described_class.new(etag_str.dup)) } - context "when the original etag is unquoted" do + context 'when the original etag is unquoted' do let(:etag_str) { 'deadbeef12345678' } it { is_expected.to eq(etag_str) } @@ -21,7 +21,7 @@ it { is_expected.to eq(described_class.new(etag_str.dup)) } end - context "when the original etag contains unbalanced quotes" do + context 'when the original etag contains unbalanced quotes' do let(:etag_str) { 'deadbeef"12345678' } it { is_expected.to eq(etag_str) } @@ -32,7 +32,7 @@ end describe Webmachine::WeakETag do - let(:strong_etag){ '"deadbeef12345678"' } + let(:strong_etag) { '"deadbeef12345678"' } let(:weak_etag) { described_class.new strong_etag } subject { weak_etag } @@ -43,7 +43,7 @@ its(:etag) { should == '"deadbeef12345678"' } it { is_expected.to eq(described_class.new(strong_etag.dup)) } - context "when the original etag is unquoted" do + context 'when the original etag is unquoted' do let(:strong_etag) { 'deadbeef12345678' } it { is_expected.to eq(strong_etag) } @@ -53,7 +53,7 @@ it { is_expected.to eq(described_class.new(strong_etag.dup)) } end - context "when the original etag contains unbalanced quotes" do + context 'when the original etag contains unbalanced quotes' do let(:strong_etag) { 'deadbeef"12345678' } it { is_expected.to eq(strong_etag) } @@ -63,7 +63,7 @@ it { is_expected.to eq(described_class.new(strong_etag.dup)) } end - context "when the original etag is already a weak tag" do + context 'when the original etag is already a weak tag' do let(:strong_etag) { 'W/"deadbeef12345678"' } it { is_expected.to eq(strong_etag) } diff --git a/spec/webmachine/events_spec.rb b/spec/webmachine/events_spec.rb index aa703476..889802be 100644 --- a/spec/webmachine/events_spec.rb +++ b/spec/webmachine/events_spec.rb @@ -1,54 +1,54 @@ require 'spec_helper' describe Webmachine::Events do - describe ".backend" do - it "defaults to AS::Notifications" do + describe '.backend' do + it 'defaults to AS::Notifications' do expect(described_class.backend).to be(AS::Notifications) end end - describe ".publish" do - it "calls the backend" do + describe '.publish' do + it 'calls the backend' do expect(described_class.backend).to receive(:publish).with('test.event', 1, 'two') described_class.publish('test.event', 1, 'two') end end - describe ".instrument" do - it "calls the backend" do + describe '.instrument' do + it 'calls the backend' do expect(described_class.backend).to receive(:instrument).with( 'test.event', {} ).and_yield - described_class.instrument('test.event') { } + described_class.instrument('test.event') {} end end - describe ".subscribe" do - it "calls the backend" do + describe '.subscribe' do + it 'calls the backend' do expect(described_class.backend).to receive(:subscribe).with( 'test.event' ).and_yield - described_class.subscribe('test.event') { } + described_class.subscribe('test.event') {} end end - describe ".subscribed" do - it "calls the backend" do - callback = Proc.new { } + describe '.subscribed' do + it 'calls the backend' do + callback = proc {} expect(described_class.backend).to receive(:subscribed).with( callback, 'test.event' ).and_yield - described_class.subscribed(callback, 'test.event') { } + described_class.subscribed(callback, 'test.event') {} end end - describe ".unsubscribe" do - it "calls the backend" do - subscriber = described_class.subscribe('test.event') { } + describe '.unsubscribe' do + it 'calls the backend' do + subscriber = described_class.subscribe('test.event') {} expect(described_class.backend).to receive(:unsubscribe).with(subscriber) diff --git a/spec/webmachine/headers_spec.rb b/spec/webmachine/headers_spec.rb index bc2c497c..fe1107ae 100644 --- a/spec/webmachine/headers_spec.rb +++ b/spec/webmachine/headers_spec.rb @@ -1,22 +1,22 @@ require 'spec_helper' describe Webmachine::Headers do - it "should set and access values insensitive to case" do - subject['Content-TYPE'] = "text/plain" + it 'should set and access values insensitive to case' do + subject['Content-TYPE'] = 'text/plain' expect(subject['CONTENT-TYPE']).to eq('text/plain') expect(subject.delete('CoNtEnT-tYpE')).to eq('text/plain') end - describe "#from_cgi" do - it "should understand the Content-Length header" do - headers = described_class.from_cgi("CONTENT_LENGTH" => 14) - expect(headers["content-length"]).to eq(14) + describe '#from_cgi' do + it 'should understand the Content-Length header' do + headers = described_class.from_cgi('CONTENT_LENGTH' => 14) + expect(headers['content-length']).to eq(14) end end - describe ".[]" do + describe '.[]' do context "Webmachine::Headers['Content-Type', 'application/json']" do - it "creates a hash with lowercase keys" do + it 'creates a hash with lowercase keys' do headers = described_class[ 'Content-Type', 'application/json', 'Accept', 'application/json' @@ -30,7 +30,7 @@ end context "Webmachine::Headers[[['Content-Type', 'application/json']]]" do - it "creates a hash with lowercase keys" do + it 'creates a hash with lowercase keys' do headers = described_class[ [ ['Content-Type', 'application/json'], @@ -46,7 +46,7 @@ end context "Webmachine::Headers['Content-Type' => 'application/json']" do - it "creates a hash with lowercase keys" do + it 'creates a hash with lowercase keys' do headers = described_class[ 'Content-Type' => 'application/json', 'Accept' => 'application/json' @@ -60,39 +60,39 @@ end end - describe "#fetch" do + describe '#fetch' do subject { described_class['Content-Type' => 'application/json'] } - it "returns the value for the given key" do + it 'returns the value for the given key' do expect(subject.fetch('conTent-tYpe')).to eq('application/json') end - context "acessing a missing key" do - it "raises an IndexError" do + context 'acessing a missing key' do + it 'raises an IndexError' do expect { subject.fetch('accept') }.to raise_error(IndexError) end - context "and a default value given" do - it "returns the default value if the key does not exist" do + context 'and a default value given' do + it 'returns the default value if the key does not exist' do expect(subject.fetch('accept', 'text/html')).to eq('text/html') end end - context "and a block given" do + context 'and a block given' do it "passes the value to the block and returns the block's result" do - expect(subject.fetch('access') {|k| "#{k} not found"}).to eq('access not found') + expect(subject.fetch('access') { |k| "#{k} not found" }).to eq('access not found') end end end end - context "filtering with #grep" do - subject { described_class["content-type" => "text/plain", "etag" => '"abcdef1234567890"'] } - it "should filter keys by the given pattern" do - expect(subject.grep(/content/i)).to include("content-type") + context 'filtering with #grep' do + subject { described_class['content-type' => 'text/plain', 'etag' => '"abcdef1234567890"'] } + it 'should filter keys by the given pattern' do + expect(subject.grep(/content/i)).to include('content-type') end - it "should return a Headers instance" do + it 'should return a Headers instance' do expect(subject.grep(/etag/i)).to be_instance_of(described_class) end end diff --git a/spec/webmachine/media_type_spec.rb b/spec/webmachine/media_type_spec.rb index 9d7b7598..e9cc4144 100644 --- a/spec/webmachine/media_type_spec.rb +++ b/spec/webmachine/media_type_spec.rb @@ -1,85 +1,85 @@ require 'spec_helper' describe Webmachine::MediaType do - let(:raw_type){ "application/xml;charset=UTF-8" } - subject { described_class.new("application/xml", {"charset" => "UTF-8"}) } + let(:raw_type) { 'application/xml;charset=UTF-8' } + subject { described_class.new('application/xml', {'charset' => 'UTF-8'}) } - context "equivalence" do + context 'equivalence' do it { is_expected.to eq(raw_type) } it { is_expected.to eq(described_class.parse(raw_type)) } end - context "when it is the wildcard type" do - subject { described_class.new("*/*") } + context 'when it is the wildcard type' do + subject { described_class.new('*/*') } it { is_expected.to be_matches_all } end - context "parsing a type" do - it "should return MediaTypes untouched" do + context 'parsing a type' do + it 'should return MediaTypes untouched' do expect(described_class.parse(subject)).to equal(subject) end - it "should parse a String" do + it 'should parse a String' do type = described_class.parse(raw_type) expect(type).to be_kind_of(described_class) - expect(type.type).to eq("application/xml") - expect(type.params).to eq({"charset" => "UTF-8"}) + expect(type.type).to eq('application/xml') + expect(type.params).to eq({'charset' => 'UTF-8'}) end - it "should parse a type/params pair" do - type = described_class.parse(["application/xml", {"charset" => "UTF-8"}]) + it 'should parse a type/params pair' do + type = described_class.parse(['application/xml', {'charset' => 'UTF-8'}]) expect(type).to be_kind_of(described_class) - expect(type.type).to eq("application/xml") - expect(type.params).to eq({"charset" => "UTF-8"}) + expect(type.type).to eq('application/xml') + expect(type.params).to eq({'charset' => 'UTF-8'}) end - it "should parse a type/params pair where the type has some params in the string" do - type = described_class.parse(["application/xml;version=1", {"charset" => "UTF-8"}]) + it 'should parse a type/params pair where the type has some params in the string' do + type = described_class.parse(['application/xml;version=1', {'charset' => 'UTF-8'}]) expect(type).to be_kind_of(described_class) - expect(type.type).to eq("application/xml") - expect(type.params).to eq({"charset" => "UTF-8", "version" => "1"}) + expect(type.type).to eq('application/xml') + expect(type.params).to eq({'charset' => 'UTF-8', 'version' => '1'}) end - it "should parse a type/params pair with params and whitespace in the string" do - type = described_class.parse(["multipart/form-data; boundary=----------------------------2c46a7bec2b9", {"charset" => "UTF-8"}]) + it 'should parse a type/params pair with params and whitespace in the string' do + type = described_class.parse(['multipart/form-data; boundary=----------------------------2c46a7bec2b9', {'charset' => 'UTF-8'}]) expect(type).to be_kind_of(described_class) - expect(type.type).to eq("multipart/form-data") - expect(type.params).to eq({"boundary" => "----------------------------2c46a7bec2b9", "charset" => "UTF-8"}) + expect(type.type).to eq('multipart/form-data') + expect(type.params).to eq({'boundary' => '----------------------------2c46a7bec2b9', 'charset' => 'UTF-8'}) end - it "should parse a type/params pair where type has single-token params" do - type = described_class.parse(["text/html;q=1;rdfa", {"charset" => "UTF-8"}]) + it 'should parse a type/params pair where type has single-token params' do + type = described_class.parse(['text/html;q=1;rdfa', {'charset' => 'UTF-8'}]) expect(type).to be_kind_of(described_class) - expect(type.type).to eq("text/html") - expect(type.params).to eq({"q" => "1", "rdfa" => "", "charset" => "UTF-8"}) + expect(type.type).to eq('text/html') + expect(type.params).to eq({'q' => '1', 'rdfa' => '', 'charset' => 'UTF-8'}) end - it "should raise an error when given an invalid type/params pair" do + it 'should raise an error when given an invalid type/params pair' do expect { - described_class.parse([false, "blah"]) + described_class.parse([false, 'blah']) }.to raise_error(ArgumentError) end end - describe "matching a requested type" do - it { is_expected.to be_exact_match("application/xml;charset=UTF-8") } - it { is_expected.to be_exact_match("application/*;charset=UTF-8") } - it { is_expected.to be_exact_match("*/*;charset=UTF-8") } - it { is_expected.to be_exact_match("*;charset=UTF-8") } - it { is_expected.not_to be_exact_match("text/xml") } - it { is_expected.not_to be_exact_match("application/xml") } - it { is_expected.not_to be_exact_match("application/xml;version=1") } + describe 'matching a requested type' do + it { is_expected.to be_exact_match('application/xml;charset=UTF-8') } + it { is_expected.to be_exact_match('application/*;charset=UTF-8') } + it { is_expected.to be_exact_match('*/*;charset=UTF-8') } + it { is_expected.to be_exact_match('*;charset=UTF-8') } + it { is_expected.not_to be_exact_match('text/xml') } + it { is_expected.not_to be_exact_match('application/xml') } + it { is_expected.not_to be_exact_match('application/xml;version=1') } - it { is_expected.to be_type_matches("application/xml") } - it { is_expected.to be_type_matches("application/*") } - it { is_expected.to be_type_matches("*/*") } - it { is_expected.to be_type_matches("*") } - it { is_expected.not_to be_type_matches("text/xml") } - it { is_expected.not_to be_type_matches("text/*") } + it { is_expected.to be_type_matches('application/xml') } + it { is_expected.to be_type_matches('application/*') } + it { is_expected.to be_type_matches('*/*') } + it { is_expected.to be_type_matches('*') } + it { is_expected.not_to be_type_matches('text/xml') } + it { is_expected.not_to be_type_matches('text/*') } - it { is_expected.to be_params_match({}) } - it { is_expected.to be_params_match({"charset" => "UTF-8"}) } - it { is_expected.not_to be_params_match({"charset" => "Windows-1252"}) } - it { is_expected.not_to be_params_match({"version" => "3"}) } + it { is_expected.to be_params_match({}) } + it { is_expected.to be_params_match({'charset' => 'UTF-8'}) } + it { is_expected.not_to be_params_match({'charset' => 'Windows-1252'}) } + it { is_expected.not_to be_params_match({'version' => '3'}) } end end diff --git a/spec/webmachine/request_spec.rb b/spec/webmachine/request_spec.rb index bfcab25c..28c93596 100644 --- a/spec/webmachine/request_spec.rb +++ b/spec/webmachine/request_spec.rb @@ -3,64 +3,64 @@ describe Webmachine::Request do subject { request } - let(:uri) { URI.parse("http://localhost:8080/some/resource") } - let(:http_method) { "GET" } - let(:headers) { Webmachine::Headers.new } - let(:body) { "" } - let(:routing_tokens) { nil } - let(:base_uri) { nil } - let(:request) { Webmachine::Request.new(http_method, uri, headers, body, routing_tokens, base_uri) } - - it "should provide access to the headers via brackets" do - subject.headers['Accept'] = "*/*" - expect(subject["accept"]).to eq("*/*") + let(:uri) { URI.parse('http://localhost:8080/some/resource') } + let(:http_method) { 'GET' } + let(:headers) { Webmachine::Headers.new } + let(:body) { '' } + let(:routing_tokens) { nil } + let(:base_uri) { nil } + let(:request) { Webmachine::Request.new(http_method, uri, headers, body, routing_tokens, base_uri) } + + it 'should provide access to the headers via brackets' do + subject.headers['Accept'] = '*/*' + expect(subject['accept']).to eq('*/*') end - it "should provide access to the cookies" do - subject.headers['Cookie'] = 'name=value;name2=value2'; - expect(subject.cookies).to eq({ 'name' => 'value', 'name2' => 'value2' }) + it 'should provide access to the cookies' do + subject.headers['Cookie'] = 'name=value;name2=value2' + expect(subject.cookies).to eq({'name' => 'value', 'name2' => 'value2'}) end - it "should handle cookies with extra whitespace" do - subject.headers['Cookie'] = 'name = value; name2 = value2'; - expect(subject.cookies).to eq({ 'name' => 'value', 'name2' => 'value2' }) + it 'should handle cookies with extra whitespace' do + subject.headers['Cookie'] = 'name = value; name2 = value2' + expect(subject.cookies).to eq({'name' => 'value', 'name2' => 'value2'}) end - it "should provide access to the headers via underscored methods" do - subject.headers["Accept-Encoding"] = "identity" - expect(subject.accept_encoding).to eq("identity") + it 'should provide access to the headers via underscored methods' do + subject.headers['Accept-Encoding'] = 'identity' + expect(subject.accept_encoding).to eq('identity') expect(subject.content_md5).to be_nil end - context "base_uri" do - it "should calculate a base URI" do - expect(subject.base_uri).to eq(URI.parse("http://localhost:8080/")) + context 'base_uri' do + it 'should calculate a base URI' do + expect(subject.base_uri).to eq(URI.parse('http://localhost:8080/')) end - context "when base_uri has been explicitly set" do - let(:base_uri) { URI.parse("http://localhost:8080/some_base_uri/here") } - it "should use the provided base_uri" do - expect(subject.base_uri).to eq(URI.parse("http://localhost:8080/some_base_uri/here")) + context 'when base_uri has been explicitly set' do + let(:base_uri) { URI.parse('http://localhost:8080/some_base_uri/here') } + it 'should use the provided base_uri' do + expect(subject.base_uri).to eq(URI.parse('http://localhost:8080/some_base_uri/here')) end end end - it "should provide a hash of query parameters" do - subject.uri.query = "foo=bar&baz=bam" - expect(subject.query).to eq({"foo" => "bar", "baz" => "bam"}) + it 'should provide a hash of query parameters' do + subject.uri.query = 'foo=bar&baz=bam' + expect(subject.query).to eq({'foo' => 'bar', 'baz' => 'bam'}) end - it "should handle = being encoded as a query value." do - subject.uri.query = "foo=bar%3D%3D" - expect(subject.query).to eq({ "foo" => "bar=="}) + it 'should handle = being encoded as a query value.' do + subject.uri.query = 'foo=bar%3D%3D' + expect(subject.query).to eq({'foo' => 'bar=='}) end it "should treat '+' characters in query parameters as spaces" do - subject.uri.query = "a%20b=foo+bar&c+d=baz%20quux" - expect(subject.query).to eq({"a b" => "foo bar", "c d" => "baz quux"}) + subject.uri.query = 'a%20b=foo+bar&c+d=baz%20quux' + expect(subject.query).to eq({'a b' => 'foo bar', 'c d' => 'baz quux'}) end - it "should handle a query parameter value of nil" do + it 'should handle a query parameter value of nil' do subject.uri.query = nil expect(subject.query).to eq({}) end @@ -68,38 +68,43 @@ describe '#has_body?' do let(:wreq) do Class.new { - def initialize(body); @body = body; end - def body; block_given? ? yield(@body) : @body; end + def initialize(body) + @body = body + end + + def body + block_given? ? yield(@body) : @body + end } end subject { request.has_body? } - context "when body is nil" do + context 'when body is nil' do let(:body) { nil } it { is_expected.to be(false) } end - context "when body is an empty string" do + context 'when body is an empty string' do let(:body) { '' } it { is_expected.to be(false) } end - context "when body is not empty" do + context 'when body is not empty' do let(:body) { 'foo' } it { is_expected.to be(true) } end - context "when body is an empty LazyRequestBody" do + context 'when body is an empty LazyRequestBody' do let(:body) { Webmachine::Adapters::LazyRequestBody.new(wreq.new('')) } it { is_expected.to be(false) } end - context "when body is a LazyRequestBody" do + context 'when body is a LazyRequestBody' do let(:body) { Webmachine::Adapters::LazyRequestBody.new(wreq.new('foo')) } it { is_expected.to be(true) } @@ -109,14 +114,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#https?' do subject { request.https? } - context "when the request was issued via HTTPS" do - let(:uri) { URI.parse("https://localhost.com:8080/some/resource") } + context 'when the request was issued via HTTPS' do + let(:uri) { URI.parse('https://localhost.com:8080/some/resource') } it { is_expected.to be(true) } end - context "when the request was not issued via HTTPS" do - let(:uri) { URI.parse("http://localhost.com:8080/some/resource") } + context 'when the request was not issued via HTTPS' do + let(:uri) { URI.parse('http://localhost.com:8080/some/resource') } it { is_expected.to be(false) } end @@ -125,14 +130,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#get?' do subject { request.get? } - context "when the request method is GET" do - let(:http_method) { "GET" } + context 'when the request method is GET' do + let(:http_method) { 'GET' } it { is_expected.to be(true) } end - context "when the request method is not GET" do - let(:http_method) { "POST" } + context 'when the request method is not GET' do + let(:http_method) { 'POST' } it { is_expected.to be(false) } end @@ -141,14 +146,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#head?' do subject { request.head? } - context "when the request method is HEAD" do - let(:http_method) { "HEAD" } + context 'when the request method is HEAD' do + let(:http_method) { 'HEAD' } it { is_expected.to be(true) } end - context "when the request method is not HEAD" do - let(:http_method) { "GET" } + context 'when the request method is not HEAD' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -157,14 +162,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#post?' do subject { request.post? } - context "when the request method is POST" do - let(:http_method) { "POST" } + context 'when the request method is POST' do + let(:http_method) { 'POST' } it { is_expected.to be(true) } end - context "when the request method is not POST" do - let(:http_method) { "GET" } + context 'when the request method is not POST' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -173,14 +178,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#put?' do subject { request.put? } - context "when the request method is PUT" do - let(:http_method) { "PUT" } + context 'when the request method is PUT' do + let(:http_method) { 'PUT' } it { is_expected.to be(true) } end - context "when the request method is not PUT" do - let(:http_method) { "GET" } + context 'when the request method is not PUT' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -189,14 +194,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#delete?' do subject { request.delete? } - context "when the request method is DELETE" do - let(:http_method) { "DELETE" } + context 'when the request method is DELETE' do + let(:http_method) { 'DELETE' } it { is_expected.to be(true) } end - context "when the request method is not DELETE" do - let(:http_method) { "GET" } + context 'when the request method is not DELETE' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -205,14 +210,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#trace?' do subject { request.trace? } - context "when the request method is TRACE" do - let(:http_method) { "TRACE" } + context 'when the request method is TRACE' do + let(:http_method) { 'TRACE' } it { is_expected.to be(true) } end - context "when the request method is not TRACE" do - let(:http_method) { "GET" } + context 'when the request method is not TRACE' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -221,14 +226,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#connect?' do subject { request.connect? } - context "when the request method is CONNECT" do - let(:http_method) { "CONNECT" } + context 'when the request method is CONNECT' do + let(:http_method) { 'CONNECT' } it { is_expected.to be(true) } end - context "when the request method is not CONNECT" do - let(:http_method) { "GET" } + context 'when the request method is not CONNECT' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -237,14 +242,14 @@ def body; block_given? ? yield(@body) : @body; end describe '#options?' do subject { request.options? } - context "when the request method is OPTIONS" do - let(:http_method) { "OPTIONS" } + context 'when the request method is OPTIONS' do + let(:http_method) { 'OPTIONS' } it { is_expected.to be(true) } end - context "when the request method is not OPTIONS" do - let(:http_method) { "GET" } + context 'when the request method is not OPTIONS' do + let(:http_method) { 'GET' } it { is_expected.to be(false) } end @@ -255,19 +260,17 @@ def body; block_given? ? yield(@body) : @body; end context "haven't been explicitly set" do let(:routing_tokens) { nil } - it "extracts the routing tokens from the path portion of the uri" do - expect(subject).to eq(["some", "resource"]) + it 'extracts the routing tokens from the path portion of the uri' do + expect(subject).to eq(['some', 'resource']) end end - context "have been explicitly set" do - let(:routing_tokens) { ["foo", "bar"] } + context 'have been explicitly set' do + let(:routing_tokens) { ['foo', 'bar'] } - it "uses the specified routing_tokens" do - expect(subject).to eq(["foo", "bar"]) + it 'uses the specified routing_tokens' do + expect(subject).to eq(['foo', 'bar']) end end - end - end diff --git a/spec/webmachine/rescueable_exception_spec.rb b/spec/webmachine/rescueable_exception_spec.rb index 819c3bad..0147d2ed 100644 --- a/spec/webmachine/rescueable_exception_spec.rb +++ b/spec/webmachine/rescueable_exception_spec.rb @@ -2,12 +2,12 @@ RSpec.describe Webmachine::RescuableException do before { described_class.default! } - describe ".UNRESCUABLEs" do - specify "returns an array of UNRESCUABLE exceptions" do + describe '.UNRESCUABLEs' do + specify 'returns an array of UNRESCUABLE exceptions' do expect(described_class.UNRESCUABLEs).to eq(described_class::UNRESCUABLE_DEFAULTS) end - specify "returns an array of UNRESCUABLE exceptions, with custom exceptions added" do + specify 'returns an array of UNRESCUABLE exceptions, with custom exceptions added' do described_class.remove(Exception) expect(described_class.UNRESCUABLEs).to eq(described_class::UNRESCUABLE_DEFAULTS.dup.concat([Exception])) end diff --git a/spec/webmachine/resource/authentication_spec.rb b/spec/webmachine/resource/authentication_spec.rb index 8dad61bc..cf9ebb58 100644 --- a/spec/webmachine/resource/authentication_spec.rb +++ b/spec/webmachine/resource/authentication_spec.rb @@ -3,63 +3,65 @@ describe Webmachine::Resource::Authentication do subject { Webmachine::Decision::FSM.new(resource, request, response) } let(:method) { 'GET' } - let(:uri) { URI.parse("http://localhost/") } + let(:uri) { URI.parse('http://localhost/') } let(:headers) { Webmachine::Headers.new } - let(:body) { "" } + let(:body) { '' } let(:request) { Webmachine::Request.new(method, uri, headers, body) } let(:response) { Webmachine::Response.new } def resource_with(&block) klass = Class.new(Webmachine::Resource) do - def to_html; "test resource"; end + def to_html + 'test resource' + end end - klass.module_eval(&block) if block_given? + klass.module_eval(&block) if block klass.new(request, response) end - describe "Basic authentication" do + describe 'Basic authentication' do let(:resource) do resource_with do include Webmachine::Resource::Authentication attr_accessor :realm def is_authorized?(auth) - basic_auth(auth, @realm || "Webmachine") {|u,p| u == "webmachine" && p == "http" } + basic_auth(auth, @realm || 'Webmachine') { |u, p| u == 'webmachine' && p == 'http' } end end end - context "when no authorization is sent by the client" do - it "should reply with a 401 Unauthorized and a WWW-Authenticate header using Basic" do + context 'when no authorization is sent by the client' do + it 'should reply with a 401 Unauthorized and a WWW-Authenticate header using Basic' do subject.run expect(response.code).to eq(401) expect(response.headers['WWW-Authenticate']).to eq('Basic realm="Webmachine"') end - it "should use the specified realm in the WWW-Authenticate header" do - resource.realm = "My App" + it 'should use the specified realm in the WWW-Authenticate header' do + resource.realm = 'My App' subject.run expect(response.headers['WWW-Authenticate']).to eq('Basic realm="My App"') end end - context "when the client sends invalid authorization" do + context 'when the client sends invalid authorization' do before do - headers['Authorization'] = "Basic " + ["invalid:auth"].pack('m*').chomp + headers['Authorization'] = 'Basic ' + ['invalid:auth'].pack('m*').chomp end - it "should reply with a 401 Unauthorized and a WWW-Authenticate header using Basic" do + it 'should reply with a 401 Unauthorized and a WWW-Authenticate header using Basic' do subject.run expect(response.code).to eq(401) expect(response.headers['WWW-Authenticate']).to eq('Basic realm="Webmachine"') end end - context "when the client sends valid authorization" do + context 'when the client sends valid authorization' do before do - headers['Authorization'] = "Basic " + ["webmachine:http"].pack('m*').chomp + headers['Authorization'] = 'Basic ' + ['webmachine:http'].pack('m*').chomp end - it "should not reply with 401 Unauthorized" do + it 'should not reply with 401 Unauthorized' do subject.run expect(response.code).not_to eq(401) end diff --git a/spec/webmachine/response_spec.rb b/spec/webmachine/response_spec.rb index b6fc1e5e..4a81e060 100644 --- a/spec/webmachine/response_spec.rb +++ b/spec/webmachine/response_spec.rb @@ -1,50 +1,49 @@ require 'spec_helper' describe Webmachine::Response do - - it "should have sane default values" do + it 'should have sane default values' do expect(subject.code).to eq(200) expect(subject.is_redirect?).to be(false) expect(subject.headers).to be_empty end - describe "a redirected response" do - let(:redirect_url) { "/" } + describe 'a redirected response' do + let(:redirect_url) { '/' } before(:each) { subject.redirect_to redirect_url } its(:is_redirect?) { should be(true) } - it "should have a proper Location header" do - expect(subject.headers["Location"]).to eq(redirect_url) + it 'should have a proper Location header' do + expect(subject.headers['Location']).to eq(redirect_url) end end - describe "setting a cookie" do - let(:cookie) { "monster" } - let(:cookie_value) { "mash" } + describe 'setting a cookie' do + let(:cookie) { 'monster' } + let(:cookie_value) { 'mash' } before(:each) { subject.set_cookie(cookie, cookie_value) } - it "should have a proper Set-Cookie header" do - expect(subject.headers["Set-Cookie"]).to include "monster=mash" + it 'should have a proper Set-Cookie header' do + expect(subject.headers['Set-Cookie']).to include 'monster=mash' end - describe "setting multiple cookies" do - let(:cookie2) { "rodeo" } - let(:cookie2_value) { "clown" } - let(:cookie3) {"color"} - let(:cookie3_value) {"blue"} - before(:each) do + describe 'setting multiple cookies' do + let(:cookie2) { 'rodeo' } + let(:cookie2_value) { 'clown' } + let(:cookie3) { 'color' } + let(:cookie3_value) { 'blue' } + before(:each) do subject.set_cookie(cookie2, cookie2_value) subject.set_cookie(cookie3, cookie3_value) end - it "should have a proper Set-Cookie header" do - expect(subject.headers["Set-Cookie"]).to be_a Array - expect(subject.headers["Set-Cookie"]).to include "rodeo=clown" - expect(subject.headers["Set-Cookie"]).to include "monster=mash" - expect(subject.headers["Set-Cookie"]).to include "color=blue" + it 'should have a proper Set-Cookie header' do + expect(subject.headers['Set-Cookie']).to be_a Array + expect(subject.headers['Set-Cookie']).to include 'rodeo=clown' + expect(subject.headers['Set-Cookie']).to include 'monster=mash' + expect(subject.headers['Set-Cookie']).to include 'color=blue' end end end diff --git a/spec/webmachine/trace/fsm_spec.rb b/spec/webmachine/trace/fsm_spec.rb index 0ecc8a29..6e7a6a57 100644 --- a/spec/webmachine/trace/fsm_spec.rb +++ b/spec/webmachine/trace/fsm_spec.rb @@ -1,34 +1,34 @@ require 'spec_helper' describe Webmachine::Trace::FSM do - include_context "default resource" + include_context 'default resource' subject { Webmachine::Decision::FSM.new(resource, request, response) } before { Webmachine::Trace.trace_store = :memory } - context "when tracing is enabled" do + context 'when tracing is enabled' do before { allow(Webmachine::Trace).to receive(:trace?).and_return(true) } - it "proxies the resource" do + it 'proxies the resource' do expect(subject.resource).to be_kind_of(Webmachine::Trace::ResourceProxy) end - it "records a trace" do + it 'records a trace' do subject.run expect(response.trace).to_not be_empty expect(Webmachine::Trace.traces.size).to eq(1) end - it "commits the trace to separate storage when the request has finished processing" do + it 'commits the trace to separate storage when the request has finished processing' do expect(Webmachine::Trace).to receive(:record).with(subject.resource.object_id.to_s, response.trace).and_return(true) subject.run end end - context "when tracing is disabled" do + context 'when tracing is disabled' do before { allow(Webmachine::Trace).to receive(:trace?).and_return(false) } - it "leaves no trace" do + it 'leaves no trace' do subject.run expect(response.trace).to be_empty expect(Webmachine::Trace.traces).to be_empty diff --git a/spec/webmachine/trace/resource_proxy_spec.rb b/spec/webmachine/trace/resource_proxy_spec.rb index 4d87bf32..86e9cc3f 100644 --- a/spec/webmachine/trace/resource_proxy_spec.rb +++ b/spec/webmachine/trace/resource_proxy_spec.rb @@ -2,33 +2,32 @@ require 'webmachine/trace/resource_proxy' describe Webmachine::Trace::ResourceProxy do - include_context "default resource" + include_context 'default resource' subject { described_class.new(resource) } - it "duck-types all callback methods" do + it 'duck-types all callback methods' do Webmachine::Resource::Callbacks.instance_methods(false).each do |m| expect(subject).to respond_to(m) end end - it "logs invocations of callbacks" do + it 'logs invocations of callbacks' do subject.generate_etag - expect(response.trace).to eq([{:type => :attempt, :name => "(default)#generate_etag"}, - {:type => :result, :value => nil}]) - + expect(response.trace).to eq([{type: :attempt, name: '(default)#generate_etag'}, + {type: :result, value: nil}]) end - it "logs invocations of body-producing methods" do - expect(subject.content_types_provided).to eq([["text/html", :to_html]]) + it 'logs invocations of body-producing methods' do + expect(subject.content_types_provided).to eq([['text/html', :to_html]]) subject.to_html expect(response.trace[-2][:type]).to eq(:attempt) expect(response.trace[-2][:name]).to match(/to_html$/) - expect(response.trace[-2][:source]).to include("spec_helper.rb") if response.trace[-2][:source] - expect(response.trace[-1]).to eq({:type => :result, :value => "Hello, world!"}) + expect(response.trace[-2][:source]).to include('spec_helper.rb') if response.trace[-2][:source] + expect(response.trace[-1]).to eq({type: :result, value: 'Hello, world!'}) end - it "sets the trace id header when the request has finished processing" do + it 'sets the trace id header when the request has finished processing' do subject.finish_request - expect(response.headers["X-Webmachine-Trace-Id"]).to eq(subject.object_id.to_s) + expect(response.headers['X-Webmachine-Trace-Id']).to eq(subject.object_id.to_s) end end diff --git a/spec/webmachine/trace/trace_store_spec.rb b/spec/webmachine/trace/trace_store_spec.rb index 324d80fa..9b4692e3 100644 --- a/spec/webmachine/trace/trace_store_spec.rb +++ b/spec/webmachine/trace/trace_store_spec.rb @@ -1,29 +1,29 @@ require 'spec_helper' require 'fileutils' -shared_examples_for "trace storage" do +shared_examples_for 'trace storage' do it { is_expected.to respond_to(:[]=) } it { is_expected.to respond_to(:keys) } it { is_expected.to respond_to(:fetch) } - it "stores a trace" do - subject["foo"] = [:bar] - expect(subject.fetch("foo")).to eq([:bar]) + it 'stores a trace' do + subject['foo'] = [:bar] + expect(subject.fetch('foo')).to eq([:bar]) end - it "lists a stored trace in the keys" do - subject["foo"] = [:bar] - expect(subject.keys).to eq(["foo"]) + it 'lists a stored trace in the keys' do + subject['foo'] = [:bar] + expect(subject.keys).to eq(['foo']) end end describe Webmachine::Trace::PStoreTraceStore do - subject { described_class.new("./wmtrace") } - after { FileUtils.rm_rf("./wmtrace") } - it_behaves_like "trace storage" + subject { described_class.new('./wmtrace') } + after { FileUtils.rm_rf('./wmtrace') } + it_behaves_like 'trace storage' end -describe "Webmachine::Trace :memory Trace Store (Hash)" do - subject { Hash.new } - it_behaves_like "trace storage" +describe 'Webmachine::Trace :memory Trace Store (Hash)' do + subject { {} } + it_behaves_like 'trace storage' end diff --git a/spec/webmachine/trace_spec.rb b/spec/webmachine/trace_spec.rb index 346e8d27..d855a34d 100644 --- a/spec/webmachine/trace_spec.rb +++ b/spec/webmachine/trace_spec.rb @@ -3,13 +3,13 @@ describe Webmachine::Trace do subject { described_class } - context "determining whether the resource should be traced" do - include_context "default resource" - it "does not trace by default" do + context 'determining whether the resource should be traced' do + include_context 'default resource' + it 'does not trace by default' do expect(subject.trace?(resource)).to be(false) end - it "traces when the resource enables tracing" do + it 'traces when the resource enables tracing' do expect(resource).to receive(:trace?).and_return(true) expect(subject.trace?(resource)).to be(true) end diff --git a/webmachine.gemspec b/webmachine.gemspec index 0c048872..d134fa3c 100644 --- a/webmachine.gemspec +++ b/webmachine.gemspec @@ -1,34 +1,33 @@ -$:.push File.expand_path("../lib", __FILE__) +$:.push File.expand_path('../lib', __FILE__) require 'webmachine/version' Gem::Specification.new do |gem| - gem.name = "webmachine" + gem.name = 'webmachine' gem.version = Webmachine::VERSION - gem.summary = %Q{webmachine is a toolkit for building HTTP applications,} + gem.summary = %(webmachine is a toolkit for building HTTP applications,) gem.description = <<-DESC.gsub(/\s+/, ' ') webmachine is a toolkit for building HTTP applications in a declarative fashion, that avoids the confusion of going through a CGI-style interface like Rack. It is strongly influenced by the original Erlang project of the same name and shares its opinionated nature about HTTP. DESC - gem.homepage = "https://github.com/webmachine/webmachine-ruby" - gem.authors = ["Sean Cribbs"] - gem.email = ["sean@basho.com"] - gem.license = "Apache-2.0" + gem.homepage = 'https://github.com/webmachine/webmachine-ruby' + gem.authors = ['Sean Cribbs'] + gem.email = ['sean@basho.com'] + gem.license = 'Apache-2.0' - gem.metadata["bug_tracker_uri"] = "#{gem.homepage}/issues" - gem.metadata["changelog_uri"] = "#{gem.homepage}/blob/HEAD/CHANGELOG.md" - gem.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/webmachine/#{gem.version}" - gem.metadata["homepage_uri"] = gem.homepage - gem.metadata["source_code_uri"] = gem.homepage - gem.metadata["wiki_uri"] = "#{gem.homepage}/wiki" + gem.metadata['bug_tracker_uri'] = "#{gem.homepage}/issues" + gem.metadata['changelog_uri'] = "#{gem.homepage}/blob/HEAD/CHANGELOG.md" + gem.metadata['documentation_uri'] = "https://www.rubydoc.info/gems/webmachine/#{gem.version}" + gem.metadata['homepage_uri'] = gem.homepage + gem.metadata['source_code_uri'] = gem.homepage + gem.metadata['wiki_uri'] = "#{gem.homepage}/wiki" - gem.add_runtime_dependency(%q, [">= 0.4.0"]) - gem.add_runtime_dependency(%q) - gem.add_runtime_dependency(%q, [">= 1.0.2", "< 2.0"]) + gem.add_runtime_dependency('i18n', ['>= 0.4.0']) + gem.add_runtime_dependency('multi_json') + gem.add_runtime_dependency('as-notifications', ['>= 1.0.2', '< 2.0']) - gem.add_development_dependency(%q, ["~> 1.7.0"]) - - ignores = File.read(".gitignore").split(/\r?\n/).reject{ |f| f =~ /^(#.+|\s*)$/ }.map {|f| Dir[f] }.flatten - gem.files = (Dir['**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) } - gem.test_files = (Dir['spec/**/*','features/**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) } + gem.add_development_dependency('webrick', ['~> 1.7.0']) + gem.add_development_dependency('standard', ['~> 1.21']) + ignores = File.read('.gitignore').split(/\r?\n/).reject { |f| f =~ /^(#.+|\s*)$/ }.map { |f| Dir[f] }.flatten + gem.files = (Dir['**/*', '.gitignore'] - ignores).reject { |f| !File.file?(f) } end