1 //! This tests that we compute the same hash as `derive(Hash)`.
2 
3 #[cfg(feature = "use_core")]
4 extern crate core;
5 
6 #[macro_use]
7 extern crate derivative;
8 
9 macro_rules! define {
10     ($kw:tt $($rest:tt)*) => {
11         #[derive(Derivative)]
12         #[derivative(Hash)]
13         $kw Ours $($rest)*
14 
15         #[derive(Hash)]
16         $kw Theirs $($rest)*
17     }
18 }
19 
20 struct FakeHasher<'a>(&'a mut Vec<u8>);
21 impl<'a> ::std::hash::Hasher for FakeHasher<'a> {
finish(&self) -> u6422     fn finish(&self) -> u64 {
23         unimplemented!()
24     }
25 
write(&mut self, bytes: &[u8])26     fn write(&mut self, bytes: &[u8]) {
27         self.0.extend(bytes);
28     }
29 }
30 
fake_hash<E: ::std::hash::Hash>(e: E) -> Vec<u8>31 fn fake_hash<E: ::std::hash::Hash>(e: E) -> Vec<u8> {
32     let mut v = Vec::new();
33     e.hash(&mut FakeHasher(&mut v));
34     v
35 }
36 
37 #[test]
main()38 fn main() {
39     {
40         define! {
41             struct;
42         }
43 
44         assert_eq!(fake_hash(Ours), fake_hash(Theirs));
45     }
46 
47     {
48         define! {
49             struct {
50                 foo: u8
51             }
52         }
53 
54         assert_eq!(fake_hash(Ours { foo: 0 }), fake_hash(Theirs { foo: 0 }));
55         assert_eq!(fake_hash(Ours { foo: 42 }), fake_hash(Theirs { foo: 42 }));
56     }
57 
58     {
59         define! {
60             struct<'a> {
61                 foo: u8,
62                 bar: &'a str,
63             }
64         }
65 
66         assert_eq!(fake_hash(Ours { foo: 0, bar: "bar" }), fake_hash(Theirs { foo: 0, bar: "bar" }));
67         assert_eq!(fake_hash(Ours { foo: 42, bar: "bar" }), fake_hash(Theirs { foo: 42, bar: "bar" }));
68     }
69 
70     {
71         define! {
72             struct<'a> (u8, &'a str);
73         }
74 
75         assert_eq!(fake_hash(Ours ( 0, "bar" )), fake_hash(Theirs ( 0, "bar" )));
76         assert_eq!(fake_hash(Ours ( 42, "bar" )), fake_hash(Theirs ( 42, "bar" )));
77     }
78 
79     {
80         define! {
81             enum {
82                 A, B, C
83             }
84         }
85 
86         assert_eq!(fake_hash(Ours::A), fake_hash(Theirs::A));
87         assert_eq!(fake_hash(Ours::B), fake_hash(Theirs::B));
88         assert_eq!(fake_hash(Ours::C), fake_hash(Theirs::C));
89     }
90 
91     {
92         define! {
93             enum {
94                 A, B = 42, C
95             }
96         }
97 
98         assert_eq!(fake_hash(Ours::A), fake_hash(Theirs::A));
99         assert_eq!(fake_hash(Ours::B), fake_hash(Theirs::B));
100         assert_eq!(fake_hash(Ours::C), fake_hash(Theirs::C));
101     }
102 
103     {
104         define! {
105             enum {
106                 A, B = 42, C=1
107             }
108         }
109 
110         assert_eq!(fake_hash(Ours::A), fake_hash(Theirs::A));
111         assert_eq!(fake_hash(Ours::B), fake_hash(Theirs::B));
112         assert_eq!(fake_hash(Ours::C), fake_hash(Theirs::C));
113     }
114 
115     {
116         #[derive(Derivative)]
117         #[derivative(Hash)]
118         struct Ours<'a> {
119             foo: u8,
120             #[derivative(Hash="ignore")]
121             bar: &'a str,
122             baz: i64,
123         }
124 
125         #[derive(Hash)]
126         struct Theirs {
127             foo: u8,
128             baz: i64,
129         }
130 
131         assert_eq!(fake_hash(Ours { foo: 0, bar: "bar", baz: 312 }), fake_hash(Theirs { foo: 0, baz: 312 }));
132         assert_eq!(fake_hash(Ours { foo: 42, bar: "bar", baz: 312 }), fake_hash(Theirs { foo: 42, baz: 312 }));
133     }
134 }
135