summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Vondrak <ajvondrak@gmail.com>2022-07-01 16:54:06 -0700
committerAlex Vondrak <alex.vondrak@goat.com>2022-07-01 16:54:06 -0700
commit446d7d78b332b764d7af6ad1a38efea2a67c4416 (patch)
tree74a1e2a213e3edb953ddf1768ac7751521591bde
parent5b931d70d74f3d1ba25babac03237ae450ca5c5b (diff)
downloadmime-types-446d7d78b332b764d7af6ad1a38efea2a67c4416.tar.gz
Define MIME::Type#hash
Fixes #166.
-rw-r--r--lib/mime/type.rb26
-rw-r--r--test/test_mime_type.rb22
2 files changed, 47 insertions, 1 deletions
diff --git a/lib/mime/type.rb b/lib/mime/type.rb
index db1cb20..d40b9b1 100644
--- a/lib/mime/type.rb
+++ b/lib/mime/type.rb
@@ -224,6 +224,32 @@ class MIME::Type
other.is_a?(MIME::Type) && (self == other)
end
+ # Returns a hash based on the #simplified value.
+ #
+ # This maintains the invariant that two #eql? instances must have the same
+ # #hash (although having the same #hash does *not* imply that the objects are
+ # #eql?).
+ #
+ # To see why, suppose a MIME::Type instance +a+ is compared to another object
+ # +b+, and that <code>a.eql?(b)</code> is true. By the definition of #eql?,
+ # we know the following:
+ #
+ # 1. +b+ is a MIME::Type instance itself.
+ # 2. <code>a == b</code> is true.
+ #
+ # Due to the first point, we know that +b+ should respond to the #simplified
+ # method. Thus, per the definition of #<=>, we know that +a.simplified+ must
+ # be equal to +b.simplified+, as compared by the <=> method corresponding to
+ # +a.simplified+.
+ #
+ # Presumably, if <code>a.simplified <=> b.simplified</code> is +0+, then
+ # +a.simplified+ has the same hash as +b.simplified+. So we assume it's
+ # suitable for #hash to delegate to #simplified in service of the #eql?
+ # invariant.
+ def hash
+ simplified.hash
+ end
+
# Returns the whole MIME content-type string.
#
# The content type is a presentation value from the MIME type registry and
diff --git a/test/test_mime_type.rb b/test/test_mime_type.rb
index 5ef4aeb..25f0a07 100644
--- a/test/test_mime_type.rb
+++ b/test/test_mime_type.rb
@@ -266,7 +266,27 @@ describe MIME::Type do
end
it "is true for an equivalent MIME::Type" do
- assert text_plain, mime_type("text/Plain")
+ assert text_plain.eql?(mime_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"))
+ 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
+ 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
+ end
+
+ it "uses the #simplified value" do
+ assert_equal text_plain.hash, mime_type("text/Plain").hash
end
end