1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use core::mem;
10 use uguid::{guid, Guid, GuidFromStrError, Variant};
11 
12 #[test]
test_guid()13 fn test_guid() {
14     assert_eq!(mem::size_of::<Guid>(), 16);
15     assert_eq!(mem::align_of::<Guid>(), 4);
16 
17     // Constructors.
18     let guid = Guid::new(
19         0x01234567_u32.to_le_bytes(),
20         0x89ab_u16.to_le_bytes(),
21         0xcdef_u16.to_le_bytes(),
22         0x01,
23         0x23,
24         [0x45, 0x67, 0x89, 0xab, 0xcd, 0xef],
25     );
26     let guid2 = Guid::from_bytes([
27         0x67, 0x45, 0x23, 0x01, 0xab, 0x89, 0xef, 0xcd, 0x01, 0x23, 0x45, 0x67,
28         0x89, 0xab, 0xcd, 0xef,
29     ]);
30     assert_eq!(guid, guid2);
31 
32     // Accessors.
33     assert_eq!(guid.time_low(), [0x67, 0x45, 0x23, 0x01]);
34     assert_eq!(guid.time_mid(), [0xab, 0x89]);
35     assert_eq!(guid.time_high_and_version(), [0xef, 0xcd]);
36     assert_eq!(guid.clock_seq_high_and_reserved(), 0x01);
37     assert_eq!(guid.clock_seq_low(), 0x23);
38     assert_eq!(guid.node(), [0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
39 
40     // To byte array.
41     assert_eq!(
42         guid.to_bytes(),
43         [
44             0x67, 0x45, 0x23, 0x01, 0xab, 0x89, 0xef, 0xcd, 0x01, 0x23, 0x45,
45             0x67, 0x89, 0xab, 0xcd, 0xef
46         ]
47     );
48 
49     // Formatting.
50     assert_eq!(
51         guid.to_ascii_hex_lower(),
52         *b"01234567-89ab-cdef-0123-456789abcdef"
53     );
54     assert_eq!(guid.to_string(), "01234567-89ab-cdef-0123-456789abcdef");
55 
56     // Parsing.
57     assert_eq!(
58         "01234567-89ab-cdef-0123-456789abcdef"
59             .parse::<Guid>()
60             .unwrap(),
61         guid
62     );
63     assert_eq!(
64         Guid::try_parse("01234567-89ab-cdef-0123-456789abcdef").unwrap(),
65         guid
66     );
67 
68     // Macro.
69     assert_eq!(guid!("01234567-89ab-cdef-0123-456789abcdef"), guid);
70 }
71 
72 #[test]
test_from_random_bytes()73 fn test_from_random_bytes() {
74     let random_bytes = [
75         0x68, 0xc0, 0x5f, 0xd7, 0x78, 0x21, 0xf9, 0x01, 0x66, 0x15, 0xab, 0x54,
76         0xe9, 0xcc, 0x44, 0xb0,
77     ];
78     let expected_bytes = [
79         0x68, 0xc0, 0x5f, 0xd7, 0x78, 0x21, 0xf9, 0x4f, 0xa6, 0x15, 0xab, 0x54,
80         0xe9, 0xcc, 0x44, 0xb0,
81     ];
82 
83     let guid = Guid::from_random_bytes(random_bytes);
84     assert_eq!(guid.to_bytes(), expected_bytes);
85     assert_eq!(guid.variant(), Variant::Rfc4122);
86     assert_eq!(guid.version(), 4);
87 }
88 
89 #[test]
test_parse_or_panic_success()90 fn test_parse_or_panic_success() {
91     let _g = Guid::parse_or_panic("01234567-89ab-cdef-0123-456789abcdef");
92 }
93 
94 #[test]
95 #[should_panic]
test_parse_or_panic_len()96 fn test_parse_or_panic_len() {
97     let _g = Guid::parse_or_panic("01234567-89ab-cdef-0123-456789abcdef0");
98 }
99 
100 #[test]
101 #[should_panic]
test_parse_or_panic_sep()102 fn test_parse_or_panic_sep() {
103     let _g = Guid::parse_or_panic("01234567089ab-cdef-0123-456789abcdef");
104 }
105 
106 #[test]
107 #[should_panic]
test_parse_or_panic_hex()108 fn test_parse_or_panic_hex() {
109     let _g = Guid::parse_or_panic("g1234567-89ab-cdef-0123-456789abcdef");
110 }
111 
112 #[test]
test_guid_error()113 fn test_guid_error() {
114     // Wrong length.
115     let s = "01234567-89ab-cdef-0123-456789abcdef0";
116     assert_eq!(s.len(), 37);
117     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Length));
118 
119     // Wrong separator.
120     let s = "01234567089ab-cdef-0123-456789abcdef";
121     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Separator(8)));
122     let s = "01234567-89ab0cdef-0123-456789abcdef";
123     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Separator(13)));
124     let s = "01234567-89ab-cdef00123-456789abcdef";
125     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Separator(18)));
126     let s = "01234567-89ab-cdef-01230456789abcdef";
127     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Separator(23)));
128 
129     // Invalid hex.
130     let s = "g1234567-89ab-cdef-0123-456789abcdef";
131     assert_eq!(s.parse::<Guid>(), Err(GuidFromStrError::Hex(0)));
132 
133     assert_eq!(
134         GuidFromStrError::Length.to_string(),
135         "GUID string has wrong length (expected 36 bytes)"
136     );
137     assert_eq!(
138         GuidFromStrError::Separator(8).to_string(),
139         "GUID string is missing a separator (`-`) at index 8"
140     );
141     assert_eq!(
142         GuidFromStrError::Hex(10).to_string(),
143         "GUID string contains invalid ASCII hex at index 10"
144     );
145 }
146 
147 #[test]
test_guid_variant()148 fn test_guid_variant() {
149     assert_eq!(
150         guid!("00000000-0000-0000-0000-000000000000").variant(),
151         Variant::ReservedNcs
152     );
153     assert_eq!(
154         guid!("00000000-0000-0000-8000-000000000000").variant(),
155         Variant::Rfc4122
156     );
157     assert_eq!(
158         guid!("00000000-0000-0000-c000-000000000000").variant(),
159         Variant::ReservedMicrosoft
160     );
161     assert_eq!(
162         guid!("00000000-0000-0000-e000-000000000000").variant(),
163         Variant::ReservedFuture
164     );
165 }
166 
167 #[test]
test_guid_version()168 fn test_guid_version() {
169     assert_eq!(guid!("00000000-0000-0000-8000-000000000000").version(), 0);
170     assert_eq!(guid!("00000000-0000-1000-8000-000000000000").version(), 1);
171     assert_eq!(guid!("00000000-0000-2000-8000-000000000000").version(), 2);
172     assert_eq!(guid!("00000000-0000-4000-8000-000000000000").version(), 4);
173 }
174 
175 #[test]
test_guid_is_zero()176 fn test_guid_is_zero() {
177     assert!(guid!("00000000-0000-0000-0000-000000000000").is_zero());
178     assert!(!guid!("308bbc16-a308-47e8-8977-5e5646c5291f").is_zero());
179 }
180 
181 /// Inner module that only imports the `guid!` macro.
182 mod inner {
183     use uguid::guid;
184 
185     /// Test that the `guid!` macro works without importing anything
186     /// else.
187     #[test]
test_guid_macro_paths()188     fn test_guid_macro_paths() {
189         let _g = guid!("01234567-89ab-cdef-0123-456789abcdef");
190     }
191 }
192