diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ff0606d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 + +updates: + - package-ecosystem: github-actions + directory: / + + - package-ecosystem: bundler + directory: / diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec3784b..e7841c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 with: ruby-version: '3.3' rubygems: latest @@ -39,22 +39,13 @@ jobs: - '3.1' - '3.2' - '3.3' - - jruby - truffleruby - include: - - ruby: jruby - os: ubuntu-22.04 - continue-on-error: true - - ruby: truffleruby - os: ubuntu-22.04 - continue-on-error: true runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.continue-on-error }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 with: ruby-version: ${{ matrix.ruby }} rubygems: latest @@ -84,7 +75,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 with: ruby-version: ${{ matrix.ruby }} rubygems: latest @@ -104,7 +95,6 @@ jobs: ruby: - '2.6' - '2.7' - - '3.0' - '3.1' - '3.2' - '3.3' @@ -113,12 +103,14 @@ jobs: include: - ruby: mingw os: windows-2022 + - ruby: '3.0' + os: windows-2022 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 with: ruby-version: ${{ matrix.ruby }} rubygems: latest @@ -127,6 +119,36 @@ jobs: - run: bundle exec ruby -S rake test --trace + # JRuby should NOT be optional, but I have not been able to make it work in quite + # a while. + jruby: + name: Ruby ${{ matrix.ruby }} - ${{ matrix.os }}) + + strategy: + fail-fast: false + + matrix: + ruby: + - jruby + os: + - ubuntu-20.04 + - ubuntu-22.04 + - ubuntu-24.04 + + continue-on-error: true + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 + with: + ruby-version: ${{ matrix.ruby }} + rubygems: latest + bundler: 2 + bundler-cache: true + + - run: bundle exec jruby -S rake test --trace + ruby-head-optional: name: Ruby ${{ matrix.ruby }} - ${{ matrix.os }} (optional) @@ -146,7 +168,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1 with: ruby-version: ${{ matrix.ruby }} rubygems: latest diff --git a/.hoerc b/.hoerc index 17059ec..55c87d2 100644 --- a/.hoerc +++ b/.hoerc @@ -30,6 +30,7 @@ exclude: !ruby/regexp '/ fasterer | pullreview | rubocop* | + standard* | travis | unused )\.yml$ diff --git a/History.md b/History.md index c7f2900..e362f61 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,23 @@ # Changelog +## 3.6 / 2024-10-02 + +- 2 deprecations: + + - Array-based MIME::Type initialization + - String-based MIME::Type initialization + + Use of these these will result in deprecation warnings. + +- Added `logger` to the gemspec to suppress a bundled gem warning with Ruby + 3.3.5. This warning should not be showing up until Ruby 3.4.0 is released and + will be suppressed in Ruby 3.3.6. + +- Reworked the deprecation message code to be somewhat more flexible and allow + for outputting certain warnings once. Because there will be at least one other + release after 3.6, we do not need to make the type initialization deprecations + frequent with this release. + ## 3.5.2 / 2024-01-02 There are no primary code changes, but we are releasing this as an update as diff --git a/Rakefile b/Rakefile index 15a8354..5c02db5 100644 --- a/Rakefile +++ b/Rakefile @@ -22,6 +22,7 @@ spec = Hoe.spec "mime-types" do spec_extras[:metadata] = ->(val) { val["rubygems_mfa_required"] = "true" } extra_deps << ["mime-types-data", "~> 3.2015"] + extra_deps << ["logger", ">= 0"] extra_dev_deps << ["hoe", ">= 3.0", "< 5"] extra_dev_deps << ["hoe-doofus", "~> 1.0"] diff --git a/lib/mime/type.rb b/lib/mime/type.rb index 9a086bf..983b64c 100644 --- a/lib/mime/type.rb +++ b/lib/mime/type.rb @@ -4,20 +4,22 @@ module MIME end +require "mime/types/deprecations" + # The definition of one MIME content-type. # # == Usage -# require 'mime/types' +# require "mime/types" # -# plaintext = MIME::Types['text/plain'] # => [ text/plain ] +# plaintext = MIME::Types["text/plain"] # => [ text/plain ] # text = plaintext.first -# puts text.media_type # => 'text' -# puts text.sub_type # => 'plain' +# puts text.media_type # => "text" +# puts text.sub_type # => "plain" # -# puts text.extensions.join(' ') # => 'txt asc c cc h hh cpp hpp dat hlp' -# puts text.preferred_extension # => 'txt' -# puts text.friendly # => 'Text Document' -# puts text.i18n_key # => 'text.plain' +# puts text.extensions.join(" ") # => "txt asc c cc h hh cpp hpp dat hlp" +# puts text.preferred_extension # => "txt" +# puts text.friendly # => "Text Document" +# puts text.i18n_key # => "text.plain" # # puts text.encoding # => quoted-printable # puts text.default_encoding # => quoted-printable @@ -28,45 +30,45 @@ module MIME # puts text.provisional? # => false # puts text.complete? # => true # -# puts text # => 'text/plain' +# puts text # => "text/plain" # -# puts text == 'text/plain' # => true -# puts 'text/plain' == text # => true -# puts text == 'text/x-plain' # => false -# puts 'text/x-plain' == text # => false +# puts text == "text/plain" # => true +# puts "text/plain" == text # => true +# puts text == "text/x-plain" # => false +# puts "text/x-plain" == text # => false # -# puts MIME::Type.simplified('x-appl/x-zip') # => 'x-appl/x-zip' -# puts MIME::Type.i18n_key('x-appl/x-zip') # => 'x-appl.x-zip' +# puts MIME::Type.simplified("x-appl/x-zip") # => "x-appl/x-zip" +# puts MIME::Type.i18n_key("x-appl/x-zip") # => "x-appl.x-zip" # -# puts text.like?('text/x-plain') # => true -# puts text.like?(MIME::Type.new('x-text/x-plain')) # => true +# puts text.like?("text/x-plain") # => true +# puts text.like?(MIME::Type.new("content-type" => "x-text/x-plain")) # => true # # puts text.xrefs.inspect # => { "rfc" => [ "rfc2046", "rfc3676", "rfc5147" ] } # puts text.xref_urls # => [ "http://www.iana.org/go/rfc2046", # # "http://www.iana.org/go/rfc3676", # # "http://www.iana.org/go/rfc5147" ] # -# xtext = MIME::Type.new('x-text/x-plain') -# puts xtext.media_type # => 'text' -# puts xtext.raw_media_type # => 'x-text' -# puts xtext.sub_type # => 'plain' -# puts xtext.raw_sub_type # => 'x-plain' +# xtext = MIME::Type.new("x-text/x-plain") +# puts xtext.media_type # => "text" +# puts xtext.raw_media_type # => "x-text" +# puts xtext.sub_type # => "plain" +# puts xtext.raw_sub_type # => "x-plain" # puts xtext.complete? # => false # -# puts MIME::Types.any? { |type| type.content_type == 'text/plain' } # => true +# puts MIME::Types.any? { |type| type.content_type == "text/plain" } # => true # puts MIME::Types.all?(&:registered?) # => false # # # Various string representations of MIME types -# qcelp = MIME::Types['audio/QCELP'].first # => audio/QCELP -# puts qcelp.content_type # => 'audio/QCELP' -# puts qcelp.simplified # => 'audio/qcelp' +# qcelp = MIME::Types["audio/QCELP"].first # => audio/QCELP +# puts qcelp.content_type # => "audio/QCELP" +# puts qcelp.simplified # => "audio/qcelp" # -# xwingz = MIME::Types['application/x-Wingz'].first # => application/x-Wingz -# puts xwingz.content_type # => 'application/x-Wingz' -# puts xwingz.simplified # => 'application/x-wingz' +# xwingz = MIME::Types["application/x-Wingz"].first # => application/x-Wingz +# puts xwingz.content_type # => "application/x-Wingz" +# puts xwingz.simplified # => "application/x-wingz" class MIME::Type # Reflects a MIME content-type specification that is not correctly - # formatted (it isn't +type+/+subtype+). + # formatted (it is not +type+/+subtype+). class InvalidContentType < ArgumentError # :stopdoc: def initialize(type_string) @@ -93,14 +95,20 @@ def to_s end # The released version of the mime-types library. - VERSION = "3.5.2" + VERSION = "3.6.0" include Comparable # :stopdoc: - # TODO verify mime-type character restrictions; I am pretty sure that this is - # too wide open. - MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}.freeze + # Full conformance with RFC 6838 §4.2 (the recommendation for < 64 characters is not + # enforced or reported because MIME::Types mostly deals with registered data). RFC 4288 + # §4.2 does not restrict the first character to alphanumeric, but the total length of + # each part is limited to 127 characters. RFCC 2045 §5.1 does not restrict the character + # composition except for whitespace, but MIME::Type was always more strict than this. + restricted_name_first = "[0-9a-zA-Z]" + restricted_name_chars = "[-!#{$&}^_.+0-9a-zA-Z]{0,126}" + restricted_name = "#{restricted_name_first}#{restricted_name_chars}" + MEDIA_TYPE_RE = %r{(#{restricted_name})/(#{restricted_name})}.freeze I18N_RE = /[^[:alnum:]]/.freeze BINARY_ENCODINGS = %w[base64 8bit].freeze ASCII_ENCODINGS = %w[7bit quoted-printable].freeze @@ -110,12 +118,15 @@ def to_s :ASCII_ENCODINGS # Builds a MIME::Type object from the +content_type+, a MIME Content Type - # value (e.g., 'text/plain' or 'application/x-eruby'). The constructed object + # value (e.g., "text/plain" or "application/x-eruby"). The constructed object # is yielded to an optional block for additional configuration, such as # associating extensions and encoding information. # # * When provided a Hash or a MIME::Type, the MIME::Type will be # constructed with #init_with. + # + # There are two deprecated initialization forms: + # # * When provided an Array, the MIME::Type will be constructed using # the first element as the content type and the remaining flattened # elements as extensions. @@ -132,11 +143,23 @@ def initialize(content_type) # :yields: self when Hash init_with(content_type) when Array + MIME::Types.deprecated( + class: MIME::Type, + method: :new, + pre: "when called with an Array", + once: true + ) self.content_type = content_type.shift self.extensions = content_type.flatten when MIME::Type init_with(content_type.to_h) else + MIME::Types.deprecated( + class: MIME::Type, + method: :new, + pre: "when called with a String", + once: true + ) self.content_type = content_type end @@ -181,7 +204,7 @@ def <=>(other) # comparisons involved are: # # 1. self.simplified <=> other.simplified (ensures that we - # don't try to compare different types) + # do not try to compare different types) # 2. IANA-registered definitions < other definitions. # 3. Complete definitions < incomplete definitions. # 4. Current definitions < obsolete definitions. @@ -243,7 +266,7 @@ def eql?(other) # +a.simplified+. # # Presumably, if a.simplified <=> b.simplified is +0+, then - # +a.simplified+ has the same hash as +b.simplified+. So we assume it's + # +a.simplified+ has the same hash as +b.simplified+. So we assume it is # suitable for #hash to delegate to #simplified in service of the #eql? # invariant. def hash @@ -319,7 +342,7 @@ def add_extensions(*extensions) # exceptions defined, the first extension will be used. # # When setting #preferred_extensions, if #extensions does not contain this - # extension, this will be added to #xtensions. + # extension, this will be added to #extensions. # # :attr_accessor: preferred_extension @@ -330,7 +353,9 @@ def preferred_extension ## def preferred_extension=(value) # :nodoc: - add_extensions(value) if value + if value + add_extensions(value) + end @preferred_extension = value end @@ -343,7 +368,7 @@ def preferred_extension=(value) # :nodoc: # provided is invalid. # # If the encoding is not provided on construction, this will be either - # 'quoted-printable' (for text/* media types) and 'base64' for eveything + # "quoted-printable" (for text/* media types) and "base64" for eveything # else. # # :attr_accessor: encoding @@ -393,7 +418,7 @@ def use_instead # # call-seq: # text_plain.friendly # => "Text File" - # text_plain.friendly('en') # => "Text File" + # text_plain.friendly("en") # => "Text File" def friendly(lang = "en") @friendly ||= {} @@ -486,7 +511,7 @@ def to_s # Returns the MIME::Type as a string for implicit conversions. This allows # MIME::Type objects to appear on either side of a comparison. # - # 'text/plain' == MIME::Type.new('text/plain') + # "text/plain" == MIME::Type.new("content-type" => "text/plain") def to_str content_type end @@ -627,7 +652,7 @@ def intern_string(string) -string end else - # MRI 2.2 and older don't have a method for string interning, + # MRI 2.2 and older do not have a method for string interning, # so we simply freeze them for keeping a similar interface def intern_string(string) string.freeze diff --git a/lib/mime/types/container.rb b/lib/mime/types/container.rb index 441debe..b167412 100644 --- a/lib/mime/types/container.rb +++ b/lib/mime/types/container.rb @@ -5,10 +5,10 @@ # MIME::Types requires a serializable keyed container that returns an empty Set # on a key miss. Hash#default_value cannot be used because, while it traverses -# the Marshal format correctly, it won't survive any other serialization +# the Marshal format correctly, it will not survive any other serialization # format (plus, a default of a mutable object resuls in a shared mess). # Hash#default_proc cannot be used without a wrapper because it prevents -# Marshal serialization (and doesn't survive the round-trip). +# Marshal serialization (and does not survive the round-trip). class MIME::Types::Container # :nodoc: extend Forwardable diff --git a/lib/mime/types/deprecations.rb b/lib/mime/types/deprecations.rb index dc869fa..944aee4 100644 --- a/lib/mime/types/deprecations.rb +++ b/lib/mime/types/deprecations.rb @@ -2,35 +2,55 @@ require "mime/types/logger" -# The namespace for MIME applications, tools, and libraries. -module MIME - ## - class Types - # Used to mark a method as deprecated in the mime-types interface. - def self.deprecated(klass, sym, message = nil, &block) # :nodoc: - level = - case klass +class << MIME::Types + # Used to mark a method as deprecated in the mime-types interface. + def deprecated(options = {}, &block) # :nodoc: + message = + if options[:message] + options[:message] + else + klass = options.fetch(:class) + + msep = case klass when Class, Module "." else klass = klass.class "#" end - message = - case message + + method = "#{klass}#{msep}#{options.fetch(:method)}" + pre = " #{options[:pre]}" if options[:pre] + post = case options[:next] when :private, :protected - "and will be #{message}" - when nil - "and will be removed" + " and will be made #{options[:next]}" + when :removed + " and will be removed" + when nil, "" + nil else - message + " #{options[:next]}" end - MIME::Types.logger.debug <<-WARNING.chomp.strip - #{caller(2..2).first}: #{klass}#{level}#{sym} is deprecated #{message}. - WARNING - return unless block - block.call + <<-WARNING.chomp.strip + #{caller(2..2).first}: #{klass}#{msep}#{method}#{pre} is deprecated#{post}. + WARNING + end + + if !__deprecation_logged?(message, options[:once]) + MIME::Types.logger.__send__(options[:level] || :debug, message) end + + return unless block + block.call + end + + private + + def __deprecation_logged?(message, once) + return false unless once + + @__deprecations_logged = {} unless defined?(@__deprecations_logged) + @__deprecations_logged.key?(message) end end diff --git a/lib/mime/types/loader.rb b/lib/mime/types/loader.rb index d6450c5..79c4f98 100644 --- a/lib/mime/types/loader.rb +++ b/lib/mime/types/loader.rb @@ -13,7 +13,7 @@ class MIME::Types; end # # The Loader will use one of the following paths: # 1. The +path+ provided in its constructor argument; -# 2. The value of ENV['RUBY_MIME_TYPES_DATA']; or +# 2. The value of ENV["RUBY_MIME_TYPES_DATA"]; or # 3. The value of MIME::Types::Data::PATH. # # When #load is called, the +path+ will be searched recursively for all YAML diff --git a/lib/mime/types/registry.rb b/lib/mime/types/registry.rb index eb27094..5010d31 100644 --- a/lib/mime/types/registry.rb +++ b/lib/mime/types/registry.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "mime/types/deprecations" + class << MIME::Types include Enumerable @@ -45,11 +47,11 @@ def add(*types) def lazy_load? return unless ENV.key?("RUBY_MIME_TYPES_LAZY_LOAD") - MIME::Types.logger.debug <<-WARNING.chomp.strip - Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed. - WARNING + deprecated( + message: "Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed." + ) - (lazy = ENV["RUBY_MIME_TYPES_LAZY_LOAD"]) && (lazy != "false") + ENV["RUBY_MIME_TYPES_LAZY_LOAD"] != "false" end def __types__ diff --git a/mime-types.gemspec b/mime-types.gemspec index bce4357..7208b7b 100644 --- a/mime-types.gemspec +++ b/mime-types.gemspec @@ -1,15 +1,15 @@ # -*- encoding: utf-8 -*- -# stub: mime-types 3.5.2 ruby lib +# stub: mime-types 3.6.0.beta1 ruby lib Gem::Specification.new do |s| s.name = "mime-types".freeze - s.version = "3.5.2".freeze + s.version = "3.6.0.beta1".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "bug_tracker_uri" => "https://github.com/mime-types/ruby-mime-types/issues", "changelog_uri" => "https://github.com/mime-types/ruby-mime-types/blob/master/History.md", "homepage_uri" => "https://github.com/mime-types/ruby-mime-types/", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/mime-types/ruby-mime-types/" } if s.respond_to? :metadata= s.require_paths = ["lib".freeze] s.authors = ["Austin Ziegler".freeze] - s.date = "2024-01-02" + s.date = "2024-09-22" s.description = "The mime-types library provides a library and registry for information about\nMIME content type definitions. It can be used to determine defined filename\nextensions for MIME types, or to use filename extensions to look up the likely\nMIME type definitions.\n\nVersion 3.0 is a major release that requires Ruby 2.0 compatibility and removes\ndeprecated functions. The columnar registry format introduced in 2.6 has been\nmade the primary format; the registry data has been extracted from this library\nand put into {mime-types-data}[https://github.com/mime-types/mime-types-data].\nAdditionally, mime-types is now licensed exclusively under the MIT licence and\nthere is a code of conduct in effect. There are a number of other smaller\nchanges described in the History file.".freeze s.email = ["halostatue@gmail.com".freeze] s.extra_rdoc_files = ["Code-of-Conduct.md".freeze, "Contributing.md".freeze, "History.md".freeze, "Licence.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze] @@ -18,13 +18,14 @@ Gem::Specification.new do |s| s.licenses = ["MIT".freeze] s.rdoc_options = ["--main".freeze, "README.rdoc".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze) - s.rubygems_version = "3.5.3".freeze + s.rubygems_version = "3.5.16".freeze s.summary = "The mime-types library provides a library and registry for information about MIME content type definitions".freeze s.specification_version = 4 s.add_runtime_dependency(%q.freeze, ["~> 3.2015".freeze]) - s.add_development_dependency(%q.freeze, ["~> 5.20".freeze]) + s.add_runtime_dependency(%q.freeze, [">= 0".freeze]) + s.add_development_dependency(%q.freeze, ["~> 5.25".freeze]) s.add_development_dependency(%q.freeze, [">= 3.0".freeze, "< 5".freeze]) s.add_development_dependency(%q.freeze, ["~> 1.0".freeze]) s.add_development_dependency(%q.freeze, ["~> 1.1".freeze]) diff --git a/test/test_mime_type.rb b/test/test_mime_type.rb index 16e80fb..a2349ca 100644 --- a/test/test_mime_type.rb +++ b/test/test_mime_type.rb @@ -9,13 +9,13 @@ def mime_type(content_type) end let(:x_appl_x_zip) { - mime_type("x-appl/x-zip") { |t| t.extensions = %w[zip zp] } + mime_type("content-type" => "x-appl/x-zip") { |t| t.extensions = %w[zip zp] } } - let(:text_plain) { mime_type("text/plain") } - let(:text_html) { mime_type("text/html") } - let(:image_jpeg) { mime_type("image/jpeg") } + let(:text_plain) { mime_type("content-type" => "text/plain") } + let(:text_html) { mime_type("content-type" => "text/html") } + let(:image_jpeg) { mime_type("content-type" => "image/jpeg") } let(:application_javascript) { - mime_type("application/javascript") do |js| + mime_type("content-type" => "application/javascript") do |js| js.friendly("en" => "JavaScript") js.xrefs = { "rfc" => %w[rfc4239 rfc4239], @@ -27,7 +27,7 @@ def mime_type(content_type) end } let(:text_x_yaml) { - mime_type("text/x-yaml") do |yaml| + mime_type("content-type" => "text/x-yaml") do |yaml| yaml.extensions = %w[yaml yml] yaml.encoding = "8bit" yaml.friendly("en" => "YAML Structured Document") @@ -88,20 +88,22 @@ def mime_type(content_type) describe ".new" do it "fails if an invalid content type is provided" do exception = assert_raises MIME::Type::InvalidContentType do - MIME::Type.new("apps") + MIME::Type.new("content-type" => "apps") end assert_equal 'Invalid Content-Type "apps"', exception.to_s end it "creates a valid content type just from a string" do - type = MIME::Type.new("text/x-yaml") + assert_output "", /MIME::Type.new when called with a String is deprecated\./ do + type = MIME::Type.new("text/x-yaml") - assert_instance_of MIME::Type, type - assert_equal "text/x-yaml", type.content_type + assert_instance_of MIME::Type, type + assert_equal "text/x-yaml", type.content_type + end end it "yields the content type in a block" do - MIME::Type.new("text/x-yaml") do |type| + MIME::Type.new("content-type" => "text/x-yaml") do |type| assert_instance_of MIME::Type, type assert_equal "text/x-yaml", type.content_type end @@ -118,10 +120,12 @@ def mime_type(content_type) end it "creates a valid content type from an array" do - type = MIME::Type.new(%w[text/x-yaml yaml yml yz]) - assert_instance_of MIME::Type, type - assert_equal "text/x-yaml", type.content_type - assert_equal %w[yaml yml yz], type.extensions + assert_output "", /MIME::Type.new when called with an Array is deprecated\./ do + type = MIME::Type.new(%w[text/x-yaml yaml yml yz]) + assert_instance_of MIME::Type, type + assert_equal "text/x-yaml", type.content_type + assert_equal %w[yaml yml yz], type.extensions + end end end @@ -143,7 +147,7 @@ def mime_type(content_type) end it "correctly compares equivalent types" do - right = mime_type("text/Plain") + right = mime_type("content-type" => "text/Plain") refute_same text_plain, right assert_equal text_plain, right end @@ -204,14 +208,14 @@ def mime_type(content_type) end it "is false when there are no extensions" do - refute mime_type("text/plain").complete? + refute mime_type("content-type" => "text/plain").complete? end end describe "#content_type" do it "preserves the original case" do assert_equal "text/plain", text_plain.content_type - assert_equal "text/vCard", mime_type("text/vCard").content_type + assert_equal "text/vCard", mime_type("content-type" => "text/vCard").content_type end it "does not remove x- prefixes" do @@ -266,27 +270,27 @@ def mime_type(content_type) end it "is true for an equivalent MIME::Type" do - assert text_plain.eql?(mime_type("text/Plain")) + assert text_plain.eql?(mime_type("content-type" => "text/Plain")) end it "is true for an equivalent subclass of MIME::Type" do subclass = Class.new(MIME::Type) - assert text_plain.eql?(subclass.new("text/plain")) + assert text_plain.eql?(subclass.new("content-type" => "text/plain")) end end describe "#hash" do it "is the same between #eql? MIME::Type instances" do - assert_equal text_plain.hash, mime_type("text/plain").hash + assert_equal text_plain.hash, mime_type("content-type" => "text/plain").hash end it "is the same between #eql? MIME::Type instances of different classes" do subclass = Class.new(MIME::Type) - assert_equal text_plain.hash, subclass.new("text/plain").hash + assert_equal text_plain.hash, subclass.new("content-type" => "text/plain").hash end it "uses the #simplified value" do - assert_equal text_plain.hash, mime_type("text/Plain").hash + assert_equal text_plain.hash, mime_type("content-type" => "text/Plain").hash end end @@ -340,9 +344,9 @@ def assert_priority(left, middle, right) assert_priority_more right, left end - let(:text_1) { mime_type("text/1") } - let(:text_1p) { mime_type("text/1") } - let(:text_2) { mime_type("text/2") } + let(:text_1) { mime_type("content-type" => "text/1") } + let(:text_1p) { mime_type("content-type" => "text/1") } + let(:text_2) { mime_type("content-type" => "text/2") } it "sorts (1) based on the simplified type" do assert_priority text_1, text_1p, text_2 @@ -395,7 +399,7 @@ def assert_priority(left, middle, right) describe "#raw_media_type" do it "extracts the media type as case-preserved" do - assert_equal "Text", mime_type("Text/plain").raw_media_type + assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type end it "does not remove x- prefixes" do @@ -415,7 +419,7 @@ def assert_priority(left, middle, right) describe "#raw_media_type" do it "extracts the media type as case-preserved" do - assert_equal "Text", mime_type("Text/plain").raw_media_type + assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type end it "does not remove x- prefixes" do @@ -435,7 +439,7 @@ def assert_priority(left, middle, right) describe "#raw_sub_type" do it "extracts the sub type as case-preserved" do - assert_equal "Plain", mime_type("text/Plain").raw_sub_type + assert_equal "Plain", mime_type("content-type" => "text/Plain").raw_sub_type end it "does not remove x- prefixes" do @@ -444,7 +448,7 @@ def assert_priority(left, middle, right) end describe "#to_h" do - let(:t) { mime_type("a/b") } + let(:t) { mime_type("content-type" => "a/b") } def assert_has_keys(wanted_keys, actual, msg = nil) wanted_keys = Array(wanted_keys).uniq.sort @@ -505,11 +509,11 @@ def assert_has_keys(wanted_keys, actual, msg = nil) } it "converts to JSON when requested" do - assert_equal expected_1, mime_type("a/b").to_json + assert_equal expected_1, mime_type("content-type" => "a/b").to_json end it "converts to JSON with provisional when requested" do - type = mime_type("a/b") do |t| + type = mime_type("content-type" => "a/b") do |t| t.registered = true t.provisional = true end @@ -559,7 +563,7 @@ def assert_has_keys(wanted_keys, actual, msg = nil) } let(:type) { - mime_type("a/b").tap do |t| + mime_type("content-type" => "a/b").tap do |t| t.xrefs = { "draft" => ["RFC1"], "template" => ["a/b"], diff --git a/test/test_mime_types.rb b/test/test_mime_types.rb index a0812a8..574be8a 100644 --- a/test/test_mime_types.rb +++ b/test/test_mime_types.rb @@ -6,19 +6,14 @@ describe MIME::Types do def mime_types @mime_types ||= MIME::Types.new.tap { |mt| - mt.add MIME::Type.new(["text/plain", %w[txt]]), - MIME::Type.new(["image/jpeg", %w[jpg jpeg]]), - MIME::Type.new("application/x-wordperfect6.1"), - MIME::Type.new( - "content-type" => "application/x-www-form-urlencoded", - "registered" => true - ), - MIME::Type.new(["application/x-gzip", %w[gz]]), - MIME::Type.new( - "content-type" => "application/gzip", - "extensions" => "gz", - "registered" => true - ) + mt.add( + MIME::Type.new("content-type" => "text/plain", "extensions" => %w[txt]), + MIME::Type.new("content-type" => "image/jpeg", "extensions" => %w[jpg jpeg]), + MIME::Type.new("content-type" => "application/x-wordperfect6.1"), + MIME::Type.new("content-type" => "application/x-www-form-urlencoded", "registered" => true), + MIME::Type.new("content-type" => "application/x-gzip", "extensions" => %w[gz]), + MIME::Type.new("content-type" => "application/gzip", "extensions" => "gz", "registered" => true) + ) } end @@ -45,7 +40,7 @@ def mime_types describe "#[]" do it "can be searched with a MIME::Type" do - text_plain = MIME::Type.new("text/plain") + text_plain = MIME::Type.new("content-type" => "text/plain") assert_includes mime_types[text_plain], "text/plain" assert_equal 1, mime_types[text_plain].size end @@ -92,8 +87,8 @@ def mime_types end describe "#add" do - let(:eruby) { MIME::Type.new("application/x-eruby") } - let(:jinja) { MIME::Type.new("application/jinja2") } + let(:eruby) { MIME::Type.new("content-type" => "application/x-eruby") } + let(:jinja) { MIME::Type.new("content-type" => "application/jinja2") } it "successfully adds a new type" do mime_types.add(eruby) diff --git a/test/test_mime_types_class.rb b/test/test_mime_types_class.rb index 08e9556..c4b8a33 100644 --- a/test/test_mime_types_class.rb +++ b/test/test_mime_types_class.rb @@ -31,7 +31,7 @@ def setup describe ".[]" do it "can be searched with a MIME::Type" do - text_plain = MIME::Type.new("text/plain") + text_plain = MIME::Type.new("content-type" => "text/plain") assert_includes MIME::Types[text_plain], "text/plain" assert_equal 1, MIME::Types[text_plain].size end @@ -119,8 +119,8 @@ def setup MIME::Types.send(:load_default_mime_types) end - let(:eruby) { MIME::Type.new("application/x-eruby") } - let(:jinja) { MIME::Type.new("application/jinja2") } + let(:eruby) { MIME::Type.new("content-type" => "application/x-eruby") } + let(:jinja) { MIME::Type.new("content-type" => "application/jinja2") } it "successfully adds a new type" do MIME::Types.add(eruby)