From 42603254fac8d4c446183cba73bbaeb2c3b416c2 Mon Sep 17 00:00:00 2001 From: Guillaume Charmetant Date: Fri, 5 May 2017 13:34:42 +0200 Subject: [PATCH] derive hash trait for Origin --- src/origin.rs | 4 ++-- tests/unit.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/origin.rs b/src/origin.rs index ee540b60..e19a2857 100644 --- a/src/origin.rs +++ b/src/origin.rs @@ -50,7 +50,7 @@ pub fn url_origin(url: &Url) -> Origin { /// the URL does not have the same origin as any other URL. /// /// For more information see https://url.spec.whatwg.org/#origin -#[derive(PartialEq, Eq, Clone, Debug)] +#[derive(PartialEq, Eq, Hash, Clone, Debug)] pub enum Origin { /// A globally unique identifier Opaque(OpaqueOrigin), @@ -123,7 +123,7 @@ impl Origin { } /// Opaque identifier for URLs that have file or other schemes -#[derive(Eq, PartialEq, Clone, Debug)] +#[derive(Eq, PartialEq, Hash, Clone, Debug)] pub struct OpaqueOrigin(usize); #[cfg(feature = "heapsize")] diff --git a/tests/unit.rs b/tests/unit.rs index c2aa93ab..a787bc09 100644 --- a/tests/unit.rs +++ b/tests/unit.rs @@ -372,3 +372,45 @@ fn define_encode_set_scopes() { m::test(); } + +#[test] +/// https://github.com/servo/rust-url/issues/302 +fn test_origin_hash() { + use std::hash::{Hash,Hasher}; + use std::collections::hash_map::DefaultHasher; + + fn hash(value: &T) -> u64 { + let mut hasher = DefaultHasher::new(); + value.hash(&mut hasher); + hasher.finish() + } + + let origin = &Url::parse("http://example.net/").unwrap().origin(); + + let origins_to_compare = [ + Url::parse("http://example.net:80/").unwrap().origin(), + Url::parse("http://example.net:81/").unwrap().origin(), + Url::parse("http://example.net").unwrap().origin(), + Url::parse("http://example.net/hello").unwrap().origin(), + Url::parse("https://example.net").unwrap().origin(), + Url::parse("ftp://example.net").unwrap().origin(), + Url::parse("file://example.net").unwrap().origin(), + Url::parse("http://user@example.net/").unwrap().origin(), + Url::parse("http://user:pass@example.net/").unwrap().origin(), + ]; + + for origin_to_compare in &origins_to_compare { + if origin == origin_to_compare { + assert_eq!(hash(origin), hash(origin_to_compare)); + } else { + assert_ne!(hash(origin), hash(origin_to_compare)); + } + } + + let opaque_origin = Url::parse("file://example.net").unwrap().origin(); + let same_opaque_origin = Url::parse("file://example.net").unwrap().origin(); + let other_opaque_origin = Url::parse("file://other").unwrap().origin(); + + assert_ne!(hash(&opaque_origin), hash(&same_opaque_origin)); + assert_ne!(hash(&opaque_origin), hash(&other_opaque_origin)); +}