]> git.lizzy.rs Git - rust.git/blob - library/core/tests/option.rs
cfg-step code
[rust.git] / library / core / tests / option.rs
1 use core::cell::Cell;
2 use core::clone::Clone;
3 use core::mem;
4 use core::ops::DerefMut;
5 use core::option::*;
6
7 #[test]
8 fn test_get_ptr() {
9     unsafe {
10         let x: Box<_> = Box::new(0);
11         let addr_x: *const isize = mem::transmute(&*x);
12         let opt = Some(x);
13         let y = opt.unwrap();
14         let addr_y: *const isize = mem::transmute(&*y);
15         assert_eq!(addr_x, addr_y);
16     }
17 }
18
19 #[test]
20 fn test_get_str() {
21     let x = "test".to_string();
22     let addr_x = x.as_ptr();
23     let opt = Some(x);
24     let y = opt.unwrap();
25     let addr_y = y.as_ptr();
26     assert_eq!(addr_x, addr_y);
27 }
28
29 #[test]
30 fn test_get_resource() {
31     use core::cell::RefCell;
32     use std::rc::Rc;
33
34     struct R {
35         i: Rc<RefCell<isize>>,
36     }
37
38     impl Drop for R {
39         fn drop(&mut self) {
40             let ii = &*self.i;
41             let i = *ii.borrow();
42             *ii.borrow_mut() = i + 1;
43         }
44     }
45
46     fn r(i: Rc<RefCell<isize>>) -> R {
47         R { i }
48     }
49
50     let i = Rc::new(RefCell::new(0));
51     {
52         let x = r(i.clone());
53         let opt = Some(x);
54         let _y = opt.unwrap();
55     }
56     assert_eq!(*i.borrow(), 1);
57 }
58
59 #[test]
60 #[allow(for_loops_over_fallibles)]
61 fn test_option_dance() {
62     let x = Some(());
63     let mut y = Some(5);
64     let mut y2 = 0;
65     for _x in x {
66         y2 = y.take().unwrap();
67     }
68     assert_eq!(y2, 5);
69     assert!(y.is_none());
70 }
71
72 #[test]
73 #[should_panic]
74 fn test_option_too_much_dance() {
75     struct A;
76     let mut y = Some(A);
77     let _y2 = y.take().unwrap();
78     let _y3 = y.take().unwrap();
79 }
80
81 #[test]
82 fn test_and() {
83     let x: Option<isize> = Some(1);
84     assert_eq!(x.and(Some(2)), Some(2));
85     assert_eq!(x.and(None::<isize>), None);
86
87     let x: Option<isize> = None;
88     assert_eq!(x.and(Some(2)), None);
89     assert_eq!(x.and(None::<isize>), None);
90
91     const FOO: Option<isize> = Some(1);
92     const A: Option<isize> = FOO.and(Some(2));
93     const B: Option<isize> = FOO.and(None);
94     assert_eq!(A, Some(2));
95     assert_eq!(B, None);
96
97     const BAR: Option<isize> = None;
98     const C: Option<isize> = BAR.and(Some(2));
99     const D: Option<isize> = BAR.and(None);
100     assert_eq!(C, None);
101     assert_eq!(D, None);
102 }
103
104 #[test]
105 fn test_and_then() {
106     const fn plus_one(x: isize) -> Option<isize> {
107         Some(x + 1)
108     }
109
110     const fn none(_: isize) -> Option<isize> {
111         None
112     }
113
114     let x: Option<isize> = Some(1);
115     assert_eq!(x.and_then(plus_one), Some(2));
116     assert_eq!(x.and_then(none), None);
117
118     let x: Option<isize> = None;
119     assert_eq!(x.and_then(plus_one), None);
120     assert_eq!(x.and_then(none), None);
121
122     const FOO: Option<isize> = Some(1);
123     const A: Option<isize> = FOO.and_then(plus_one);
124     const B: Option<isize> = FOO.and_then(none);
125     assert_eq!(A, Some(2));
126     assert_eq!(B, None);
127
128     const BAR: Option<isize> = None;
129     const C: Option<isize> = BAR.and_then(plus_one);
130     const D: Option<isize> = BAR.and_then(none);
131     assert_eq!(C, None);
132     assert_eq!(D, None);
133 }
134
135 #[test]
136 fn test_or() {
137     let x: Option<isize> = Some(1);
138     assert_eq!(x.or(Some(2)), Some(1));
139     assert_eq!(x.or(None), Some(1));
140
141     let x: Option<isize> = None;
142     assert_eq!(x.or(Some(2)), Some(2));
143     assert_eq!(x.or(None), None);
144
145     const FOO: Option<isize> = Some(1);
146     const A: Option<isize> = FOO.or(Some(2));
147     const B: Option<isize> = FOO.or(None);
148     assert_eq!(A, Some(1));
149     assert_eq!(B, Some(1));
150
151     const BAR: Option<isize> = None;
152     const C: Option<isize> = BAR.or(Some(2));
153     const D: Option<isize> = BAR.or(None);
154     assert_eq!(C, Some(2));
155     assert_eq!(D, None);
156 }
157
158 #[test]
159 fn test_or_else() {
160     const fn two() -> Option<isize> {
161         Some(2)
162     }
163
164     const fn none() -> Option<isize> {
165         None
166     }
167
168     let x: Option<isize> = Some(1);
169     assert_eq!(x.or_else(two), Some(1));
170     assert_eq!(x.or_else(none), Some(1));
171
172     let x: Option<isize> = None;
173     assert_eq!(x.or_else(two), Some(2));
174     assert_eq!(x.or_else(none), None);
175
176     const FOO: Option<isize> = Some(1);
177     const A: Option<isize> = FOO.or_else(two);
178     const B: Option<isize> = FOO.or_else(none);
179     assert_eq!(A, Some(1));
180     assert_eq!(B, Some(1));
181
182     const BAR: Option<isize> = None;
183     const C: Option<isize> = BAR.or_else(two);
184     const D: Option<isize> = BAR.or_else(none);
185     assert_eq!(C, Some(2));
186     assert_eq!(D, None);
187 }
188
189 #[test]
190 fn test_unwrap() {
191     assert_eq!(Some(1).unwrap(), 1);
192     let s = Some("hello".to_string()).unwrap();
193     assert_eq!(s, "hello");
194 }
195
196 #[test]
197 #[should_panic]
198 fn test_unwrap_panic1() {
199     let x: Option<isize> = None;
200     x.unwrap();
201 }
202
203 #[test]
204 #[should_panic]
205 fn test_unwrap_panic2() {
206     let x: Option<String> = None;
207     x.unwrap();
208 }
209
210 #[test]
211 fn test_unwrap_or() {
212     let x: Option<isize> = Some(1);
213     assert_eq!(x.unwrap_or(2), 1);
214
215     let x: Option<isize> = None;
216     assert_eq!(x.unwrap_or(2), 2);
217
218     const A: isize = Some(1).unwrap_or(2);
219     const B: isize = None.unwrap_or(2);
220     assert_eq!(A, 1);
221     assert_eq!(B, 2);
222 }
223
224 #[test]
225 fn test_unwrap_or_else() {
226     const fn two() -> isize {
227         2
228     }
229
230     let x: Option<isize> = Some(1);
231     assert_eq!(x.unwrap_or_else(two), 1);
232
233     let x: Option<isize> = None;
234     assert_eq!(x.unwrap_or_else(two), 2);
235
236     const A: isize = Some(1).unwrap_or_else(two);
237     const B: isize = None.unwrap_or_else(two);
238     assert_eq!(A, 1);
239     assert_eq!(B, 2);
240 }
241
242 #[test]
243 fn test_unwrap_unchecked() {
244     assert_eq!(unsafe { Some(1).unwrap_unchecked() }, 1);
245     let s = unsafe { Some("hello".to_string()).unwrap_unchecked() };
246     assert_eq!(s, "hello");
247 }
248
249 #[test]
250 fn test_iter() {
251     let val = 5;
252
253     let x = Some(val);
254     let mut it = x.iter();
255
256     assert_eq!(it.size_hint(), (1, Some(1)));
257     assert_eq!(it.next(), Some(&val));
258     assert_eq!(it.size_hint(), (0, Some(0)));
259     assert!(it.next().is_none());
260
261     let mut it = (&x).into_iter();
262     assert_eq!(it.next(), Some(&val));
263 }
264
265 #[test]
266 fn test_mut_iter() {
267     let mut val = 5;
268     let new_val = 11;
269
270     let mut x = Some(val);
271     {
272         let mut it = x.iter_mut();
273
274         assert_eq!(it.size_hint(), (1, Some(1)));
275
276         match it.next() {
277             Some(interior) => {
278                 assert_eq!(*interior, val);
279                 *interior = new_val;
280             }
281             None => assert!(false),
282         }
283
284         assert_eq!(it.size_hint(), (0, Some(0)));
285         assert!(it.next().is_none());
286     }
287     assert_eq!(x, Some(new_val));
288
289     let mut y = Some(val);
290     let mut it = (&mut y).into_iter();
291     assert_eq!(it.next(), Some(&mut val));
292 }
293
294 #[test]
295 fn test_ord() {
296     let small = Some(1.0f64);
297     let big = Some(5.0f64);
298     let nan = Some(0.0f64 / 0.0);
299     assert!(!(nan < big));
300     assert!(!(nan > big));
301     assert!(small < big);
302     assert!(None < big);
303     assert!(big > None);
304 }
305
306 #[test]
307 fn test_collect() {
308     let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
309     assert!(v == Some(vec![]));
310
311     let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
312     assert!(v == Some(vec![0, 1, 2]));
313
314     let v: Option<Vec<isize>> = (0..3).map(|x| if x > 1 { None } else { Some(x) }).collect();
315     assert!(v == None);
316
317     // test that it does not take more elements than it needs
318     let mut functions: [Box<dyn Fn() -> Option<()>>; 3] =
319         [Box::new(|| Some(())), Box::new(|| None), Box::new(|| panic!())];
320
321     let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
322
323     assert!(v == None);
324 }
325
326 #[test]
327 fn test_copied() {
328     let val = 1;
329     let val_ref = &val;
330     let opt_none: Option<&'static u32> = None;
331     let opt_ref = Some(&val);
332     let opt_ref_ref = Some(&val_ref);
333
334     // None works
335     assert_eq!(opt_none.clone(), None);
336     assert_eq!(opt_none.copied(), None);
337
338     // Immutable ref works
339     assert_eq!(opt_ref.clone(), Some(&val));
340     assert_eq!(opt_ref.copied(), Some(1));
341
342     // Double Immutable ref works
343     assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
344     assert_eq!(opt_ref_ref.clone().copied(), Some(&val));
345     assert_eq!(opt_ref_ref.copied().copied(), Some(1));
346 }
347
348 #[test]
349 fn test_cloned() {
350     let val = 1;
351     let val_ref = &val;
352     let opt_none: Option<&'static u32> = None;
353     let opt_ref = Some(&val);
354     let opt_ref_ref = Some(&val_ref);
355
356     // None works
357     assert_eq!(opt_none.clone(), None);
358     assert_eq!(opt_none.cloned(), None);
359
360     // Immutable ref works
361     assert_eq!(opt_ref.clone(), Some(&val));
362     assert_eq!(opt_ref.cloned(), Some(1));
363
364     // Double Immutable ref works
365     assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
366     assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
367     assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
368 }
369
370 #[test]
371 fn test_try() {
372     fn try_option_some() -> Option<u8> {
373         let val = Some(1)?;
374         Some(val)
375     }
376     assert_eq!(try_option_some(), Some(1));
377
378     fn try_option_none() -> Option<u8> {
379         let val = None?;
380         Some(val)
381     }
382     assert_eq!(try_option_none(), None);
383 }
384
385 #[test]
386 fn test_option_as_deref() {
387     // Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
388     let ref_option = &Some(&42);
389     assert_eq!(ref_option.as_deref(), Some(&42));
390
391     let ref_option = &Some(String::from("a result"));
392     assert_eq!(ref_option.as_deref(), Some("a result"));
393
394     let ref_option = &Some(vec![1, 2, 3, 4, 5]);
395     assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice()));
396
397     // None: &Option<T: Deref>>::None -> None
398     let ref_option: &Option<&i32> = &None;
399     assert_eq!(ref_option.as_deref(), None);
400 }
401
402 #[test]
403 fn test_option_as_deref_mut() {
404     // Some: &mut Option<T: Deref>::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T)
405     let mut val = 42;
406     let ref_option = &mut Some(&mut val);
407     assert_eq!(ref_option.as_deref_mut(), Some(&mut 42));
408
409     let ref_option = &mut Some(String::from("a result"));
410     assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut()));
411
412     let ref_option = &mut Some(vec![1, 2, 3, 4, 5]);
413     assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice()));
414
415     // None: &mut Option<T: Deref>>::None -> None
416     let ref_option: &mut Option<&mut i32> = &mut None;
417     assert_eq!(ref_option.as_deref_mut(), None);
418 }
419
420 #[test]
421 fn test_replace() {
422     let mut x = Some(2);
423     let old = x.replace(5);
424
425     assert_eq!(x, Some(5));
426     assert_eq!(old, Some(2));
427
428     let mut x = None;
429     let old = x.replace(3);
430
431     assert_eq!(x, Some(3));
432     assert_eq!(old, None);
433 }
434
435 #[test]
436 fn option_const() {
437     // test that the methods of `Option` are usable in a const context
438
439     const OPTION: Option<usize> = Some(32);
440     assert_eq!(OPTION, Some(32));
441
442     const OPTION_FROM: Option<usize> = Option::from(32);
443     assert_eq!(OPTION_FROM, Some(32));
444
445     const REF: Option<&usize> = OPTION.as_ref();
446     assert_eq!(REF, Some(&32));
447
448     const REF_FROM: Option<&usize> = Option::from(&OPTION);
449     assert_eq!(REF_FROM, Some(&32));
450
451     const IS_SOME: bool = OPTION.is_some();
452     assert!(IS_SOME);
453
454     const IS_NONE: bool = OPTION.is_none();
455     assert!(!IS_NONE);
456
457     const COPIED: Option<usize> = OPTION.as_ref().copied();
458     assert_eq!(COPIED, OPTION);
459 }
460
461 #[test]
462 const fn option_const_mut() {
463     // test that the methods of `Option` that take mutable references are usable in a const context
464
465     let mut option: Option<usize> = Some(32);
466
467     let _take = option.take();
468     let _replace = option.replace(42);
469
470     {
471         let as_mut = option.as_mut();
472         match as_mut {
473             Some(v) => *v = 32,
474             None => unreachable!(),
475         }
476     }
477
478     {
479         let as_mut: Option<&mut usize> = Option::from(&mut option);
480         match as_mut {
481             Some(v) => *v = 42,
482             None => unreachable!(),
483         }
484     }
485 }
486
487 #[test]
488 fn test_unwrap_drop() {
489     struct Dtor<'a> {
490         x: &'a Cell<isize>,
491     }
492
493     impl<'a> std::ops::Drop for Dtor<'a> {
494         fn drop(&mut self) {
495             self.x.set(self.x.get() - 1);
496         }
497     }
498
499     fn unwrap<T>(o: Option<T>) -> T {
500         match o {
501             Some(v) => v,
502             None => panic!(),
503         }
504     }
505
506     let x = &Cell::new(1);
507
508     {
509         let b = Some(Dtor { x });
510         let _c = unwrap(b);
511     }
512
513     assert_eq!(x.get(), 0);
514 }
515
516 #[test]
517 fn option_ext() {
518     let thing = "{{ f }}";
519     let f = thing.find("{{");
520
521     if f.is_none() {
522         println!("None!");
523     }
524 }
525
526 #[test]
527 fn zip_options() {
528     let x = Some(10);
529     let y = Some("foo");
530     let z: Option<usize> = None;
531
532     assert_eq!(x.zip(y), Some((10, "foo")));
533     assert_eq!(x.zip(z), None);
534     assert_eq!(z.zip(x), None);
535 }
536
537 #[test]
538 fn unzip_options() {
539     let x = Some((10, "foo"));
540     let y = None::<(bool, i32)>;
541
542     assert_eq!(x.unzip(), (Some(10), Some("foo")));
543     assert_eq!(y.unzip(), (None, None));
544 }
545
546 #[test]
547 fn zip_unzip_roundtrip() {
548     let x = Some(10);
549     let y = Some("foo");
550
551     let z = x.zip(y);
552     assert_eq!(z, Some((10, "foo")));
553
554     let a = z.unzip();
555     assert_eq!(a, (x, y));
556 }