]> git.lizzy.rs Git - rust.git/blob - library/alloc/tests/string.rs
Rollup merge of #76430 - pickfire:patch-7, r=steveklabnik
[rust.git] / library / alloc / tests / string.rs
1 use std::borrow::Cow;
2 use std::collections::TryReserveError::*;
3 use std::mem::size_of;
4
5 pub trait IntoCow<'a, B: ?Sized>
6 where
7     B: ToOwned,
8 {
9     fn into_cow(self) -> Cow<'a, B>;
10 }
11
12 impl<'a> IntoCow<'a, str> for String {
13     fn into_cow(self) -> Cow<'a, str> {
14         Cow::Owned(self)
15     }
16 }
17
18 impl<'a> IntoCow<'a, str> for &'a str {
19     fn into_cow(self) -> Cow<'a, str> {
20         Cow::Borrowed(self)
21     }
22 }
23
24 #[test]
25 fn test_from_str() {
26     let owned: Option<std::string::String> = "string".parse().ok();
27     assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
28 }
29
30 #[test]
31 fn test_from_cow_str() {
32     assert_eq!(String::from(Cow::Borrowed("string")), "string");
33     assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
34 }
35
36 #[test]
37 fn test_unsized_to_string() {
38     let s: &str = "abc";
39     let _: String = (*s).to_string();
40 }
41
42 #[test]
43 fn test_from_utf8() {
44     let xs = b"hello".to_vec();
45     assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
46
47     let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
48     assert_eq!(String::from_utf8(xs).unwrap(), String::from("ศไทย中华Việt Nam"));
49
50     let xs = b"hello\xFF".to_vec();
51     let err = String::from_utf8(xs).unwrap_err();
52     assert_eq!(err.as_bytes(), b"hello\xff");
53     let err_clone = err.clone();
54     assert_eq!(err, err_clone);
55     assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
56     assert_eq!(err_clone.utf8_error().valid_up_to(), 5);
57 }
58
59 #[test]
60 fn test_from_utf8_lossy() {
61     let xs = b"hello";
62     let ys: Cow<'_, str> = "hello".into_cow();
63     assert_eq!(String::from_utf8_lossy(xs), ys);
64
65     let xs = "ศไทย中华Việt Nam".as_bytes();
66     let ys: Cow<'_, str> = "ศไทย中华Việt Nam".into_cow();
67     assert_eq!(String::from_utf8_lossy(xs), ys);
68
69     let xs = b"Hello\xC2 There\xFF Goodbye";
70     assert_eq!(
71         String::from_utf8_lossy(xs),
72         String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow()
73     );
74
75     let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
76     assert_eq!(
77         String::from_utf8_lossy(xs),
78         String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow()
79     );
80
81     let xs = b"\xF5foo\xF5\x80bar";
82     assert_eq!(
83         String::from_utf8_lossy(xs),
84         String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow()
85     );
86
87     let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
88     assert_eq!(
89         String::from_utf8_lossy(xs),
90         String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow()
91     );
92
93     let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
94     assert_eq!(
95         String::from_utf8_lossy(xs),
96         String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow()
97     );
98
99     let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
100     assert_eq!(
101         String::from_utf8_lossy(xs),
102         String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow()
103     );
104
105     // surrogates
106     let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
107     assert_eq!(
108         String::from_utf8_lossy(xs),
109         String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow()
110     );
111 }
112
113 #[test]
114 fn test_from_utf16() {
115     let pairs = [
116         (
117             String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
118             vec![
119                 0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39,
120                 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a,
121             ],
122         ),
123         (
124             String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
125             vec![
126                 0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32,
127                 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
128             ],
129         ),
130         (
131             String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
132             vec![
133                 0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11,
134                 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800,
135                 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
136             ],
137         ),
138         (
139             String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
140             vec![
141                 0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, 0xdc9b,
142                 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, 0xd801, 0xdc88,
143                 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, 0xd801, 0xdc9c, 0xd801,
144                 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc86,
145                 0x000a,
146             ],
147         ),
148         // Issue #12318, even-numbered non-BMP planes
149         (String::from("\u{20000}"), vec![0xD840, 0xDC00]),
150     ];
151
152     for p in &pairs {
153         let (s, u) = (*p).clone();
154         let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
155         let u_as_string = String::from_utf16(&u).unwrap();
156
157         assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
158         assert_eq!(s_as_utf16, u);
159
160         assert_eq!(u_as_string, s);
161         assert_eq!(String::from_utf16_lossy(&u), s);
162
163         assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
164         assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
165     }
166 }
167
168 #[test]
169 fn test_utf16_invalid() {
170     // completely positive cases tested above.
171     // lead + eof
172     assert!(String::from_utf16(&[0xD800]).is_err());
173     // lead + lead
174     assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
175
176     // isolated trail
177     assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
178
179     // general
180     assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
181 }
182
183 #[test]
184 fn test_from_utf16_lossy() {
185     // completely positive cases tested above.
186     // lead + eof
187     assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
188     // lead + lead
189     assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), String::from("\u{FFFD}\u{FFFD}"));
190
191     // isolated trail
192     assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
193
194     // general
195     assert_eq!(
196         String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
197         String::from("\u{FFFD}𐒋\u{FFFD}")
198     );
199 }
200
201 #[test]
202 fn test_push_bytes() {
203     let mut s = String::from("ABC");
204     unsafe {
205         let mv = s.as_mut_vec();
206         mv.extend_from_slice(&[b'D']);
207     }
208     assert_eq!(s, "ABCD");
209 }
210
211 #[test]
212 fn test_push_str() {
213     let mut s = String::new();
214     s.push_str("");
215     assert_eq!(&s[0..], "");
216     s.push_str("abc");
217     assert_eq!(&s[0..], "abc");
218     s.push_str("ประเทศไทย中华Việt Nam");
219     assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
220 }
221
222 #[test]
223 fn test_add_assign() {
224     let mut s = String::new();
225     s += "";
226     assert_eq!(s.as_str(), "");
227     s += "abc";
228     assert_eq!(s.as_str(), "abc");
229     s += "ประเทศไทย中华Việt Nam";
230     assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
231 }
232
233 #[test]
234 fn test_push() {
235     let mut data = String::from("ประเทศไทย中");
236     data.push('华');
237     data.push('b'); // 1 byte
238     data.push('¢'); // 2 byte
239     data.push('€'); // 3 byte
240     data.push('𤭢'); // 4 byte
241     assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
242 }
243
244 #[test]
245 fn test_pop() {
246     let mut data = String::from("ประเทศไทย中华b¢€𤭢");
247     assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
248     assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
249     assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
250     assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
251     assert_eq!(data.pop().unwrap(), '华');
252     assert_eq!(data, "ประเทศไทย中");
253 }
254
255 #[test]
256 fn test_split_off_empty() {
257     let orig = "Hello, world!";
258     let mut split = String::from(orig);
259     let empty: String = split.split_off(orig.len());
260     assert!(empty.is_empty());
261 }
262
263 #[test]
264 #[should_panic]
265 fn test_split_off_past_end() {
266     let orig = "Hello, world!";
267     let mut split = String::from(orig);
268     let _ = split.split_off(orig.len() + 1);
269 }
270
271 #[test]
272 #[should_panic]
273 fn test_split_off_mid_char() {
274     let mut orig = String::from("山");
275     let _ = orig.split_off(1);
276 }
277
278 #[test]
279 fn test_split_off_ascii() {
280     let mut ab = String::from("ABCD");
281     let cd = ab.split_off(2);
282     assert_eq!(ab, "AB");
283     assert_eq!(cd, "CD");
284 }
285
286 #[test]
287 fn test_split_off_unicode() {
288     let mut nihon = String::from("日本語");
289     let go = nihon.split_off("日本".len());
290     assert_eq!(nihon, "日本");
291     assert_eq!(go, "語");
292 }
293
294 #[test]
295 fn test_str_truncate() {
296     let mut s = String::from("12345");
297     s.truncate(5);
298     assert_eq!(s, "12345");
299     s.truncate(3);
300     assert_eq!(s, "123");
301     s.truncate(0);
302     assert_eq!(s, "");
303
304     let mut s = String::from("12345");
305     let p = s.as_ptr();
306     s.truncate(3);
307     s.push_str("6");
308     let p_ = s.as_ptr();
309     assert_eq!(p_, p);
310 }
311
312 #[test]
313 fn test_str_truncate_invalid_len() {
314     let mut s = String::from("12345");
315     s.truncate(6);
316     assert_eq!(s, "12345");
317 }
318
319 #[test]
320 #[should_panic]
321 fn test_str_truncate_split_codepoint() {
322     let mut s = String::from("\u{FC}"); // ü
323     s.truncate(1);
324 }
325
326 #[test]
327 fn test_str_clear() {
328     let mut s = String::from("12345");
329     s.clear();
330     assert_eq!(s.len(), 0);
331     assert_eq!(s, "");
332 }
333
334 #[test]
335 fn test_str_add() {
336     let a = String::from("12345");
337     let b = a + "2";
338     let b = b + "2";
339     assert_eq!(b.len(), 7);
340     assert_eq!(b, "1234522");
341 }
342
343 #[test]
344 fn remove() {
345     let mut s = "ศไทย中华Việt Nam; foobar".to_string();
346     assert_eq!(s.remove(0), 'ศ');
347     assert_eq!(s.len(), 33);
348     assert_eq!(s, "ไทย中华Việt Nam; foobar");
349     assert_eq!(s.remove(17), 'ệ');
350     assert_eq!(s, "ไทย中华Vit Nam; foobar");
351 }
352
353 #[test]
354 #[should_panic]
355 fn remove_bad() {
356     "ศ".to_string().remove(1);
357 }
358
359 #[test]
360 fn test_retain() {
361     let mut s = String::from("α_β_γ");
362
363     s.retain(|_| true);
364     assert_eq!(s, "α_β_γ");
365
366     s.retain(|c| c != '_');
367     assert_eq!(s, "αβγ");
368
369     s.retain(|c| c != 'β');
370     assert_eq!(s, "αγ");
371
372     s.retain(|c| c == 'α');
373     assert_eq!(s, "α");
374
375     s.retain(|_| false);
376     assert_eq!(s, "");
377 }
378
379 #[test]
380 fn insert() {
381     let mut s = "foobar".to_string();
382     s.insert(0, 'ệ');
383     assert_eq!(s, "ệfoobar");
384     s.insert(6, 'ย');
385     assert_eq!(s, "ệfooยbar");
386 }
387
388 #[test]
389 #[should_panic]
390 fn insert_bad1() {
391     "".to_string().insert(1, 't');
392 }
393 #[test]
394 #[should_panic]
395 fn insert_bad2() {
396     "ệ".to_string().insert(1, 't');
397 }
398
399 #[test]
400 fn test_slicing() {
401     let s = "foobar".to_string();
402     assert_eq!("foobar", &s[..]);
403     assert_eq!("foo", &s[..3]);
404     assert_eq!("bar", &s[3..]);
405     assert_eq!("oob", &s[1..4]);
406 }
407
408 #[test]
409 fn test_simple_types() {
410     assert_eq!(1.to_string(), "1");
411     assert_eq!((-1).to_string(), "-1");
412     assert_eq!(200.to_string(), "200");
413     assert_eq!(2.to_string(), "2");
414     assert_eq!(true.to_string(), "true");
415     assert_eq!(false.to_string(), "false");
416     assert_eq!(("hi".to_string()).to_string(), "hi");
417 }
418
419 #[test]
420 fn test_vectors() {
421     let x: Vec<i32> = vec![];
422     assert_eq!(format!("{:?}", x), "[]");
423     assert_eq!(format!("{:?}", vec![1]), "[1]");
424     assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
425     assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
426 }
427
428 #[test]
429 fn test_from_iterator() {
430     let s = "ศไทย中华Việt Nam".to_string();
431     let t = "ศไทย中华";
432     let u = "Việt Nam";
433
434     let a: String = s.chars().collect();
435     assert_eq!(s, a);
436
437     let mut b = t.to_string();
438     b.extend(u.chars());
439     assert_eq!(s, b);
440
441     let c: String = vec![t, u].into_iter().collect();
442     assert_eq!(s, c);
443
444     let mut d = t.to_string();
445     d.extend(vec![u]);
446     assert_eq!(s, d);
447 }
448
449 #[test]
450 fn test_drain() {
451     let mut s = String::from("αβγ");
452     assert_eq!(s.drain(2..4).collect::<String>(), "β");
453     assert_eq!(s, "αγ");
454
455     let mut t = String::from("abcd");
456     t.drain(..0);
457     assert_eq!(t, "abcd");
458     t.drain(..1);
459     assert_eq!(t, "bcd");
460     t.drain(3..);
461     assert_eq!(t, "bcd");
462     t.drain(..);
463     assert_eq!(t, "");
464 }
465
466 #[test]
467 fn test_replace_range() {
468     let mut s = "Hello, world!".to_owned();
469     s.replace_range(7..12, "世界");
470     assert_eq!(s, "Hello, 世界!");
471 }
472
473 #[test]
474 #[should_panic]
475 fn test_replace_range_char_boundary() {
476     let mut s = "Hello, 世界!".to_owned();
477     s.replace_range(..8, "");
478 }
479
480 #[test]
481 fn test_replace_range_inclusive_range() {
482     let mut v = String::from("12345");
483     v.replace_range(2..=3, "789");
484     assert_eq!(v, "127895");
485     v.replace_range(1..=2, "A");
486     assert_eq!(v, "1A895");
487 }
488
489 #[test]
490 #[should_panic]
491 fn test_replace_range_out_of_bounds() {
492     let mut s = String::from("12345");
493     s.replace_range(5..6, "789");
494 }
495
496 #[test]
497 #[should_panic]
498 fn test_replace_range_inclusive_out_of_bounds() {
499     let mut s = String::from("12345");
500     s.replace_range(5..=5, "789");
501 }
502
503 #[test]
504 fn test_replace_range_empty() {
505     let mut s = String::from("12345");
506     s.replace_range(1..2, "");
507     assert_eq!(s, "1345");
508 }
509
510 #[test]
511 fn test_replace_range_unbounded() {
512     let mut s = String::from("12345");
513     s.replace_range(.., "");
514     assert_eq!(s, "");
515 }
516
517 #[test]
518 fn test_extend_ref() {
519     let mut a = "foo".to_string();
520     a.extend(&['b', 'a', 'r']);
521
522     assert_eq!(&a, "foobar");
523 }
524
525 #[test]
526 fn test_into_boxed_str() {
527     let xs = String::from("hello my name is bob");
528     let ys = xs.into_boxed_str();
529     assert_eq!(&*ys, "hello my name is bob");
530 }
531
532 #[test]
533 fn test_reserve_exact() {
534     // This is all the same as test_reserve
535
536     let mut s = String::new();
537     assert_eq!(s.capacity(), 0);
538
539     s.reserve_exact(2);
540     assert!(s.capacity() >= 2);
541
542     for _i in 0..16 {
543         s.push('0');
544     }
545
546     assert!(s.capacity() >= 16);
547     s.reserve_exact(16);
548     assert!(s.capacity() >= 32);
549
550     s.push('0');
551
552     s.reserve_exact(16);
553     assert!(s.capacity() >= 33)
554 }
555
556 #[test]
557 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
558 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
559 fn test_try_reserve() {
560     // These are the interesting cases:
561     // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
562     // * > isize::MAX should always fail
563     //    * On 16/32-bit should CapacityOverflow
564     //    * On 64-bit should OOM
565     // * overflow may trigger when adding `len` to `cap` (in number of elements)
566     // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
567
568     const MAX_CAP: usize = isize::MAX as usize;
569     const MAX_USIZE: usize = usize::MAX;
570
571     // On 16/32-bit, we check that allocations don't exceed isize::MAX,
572     // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
573     // Any platform that succeeds for these requests is technically broken with
574     // ptr::offset because LLVM is the worst.
575     let guards_against_isize = size_of::<usize>() < 8;
576
577     {
578         // Note: basic stuff is checked by test_reserve
579         let mut empty_string: String = String::new();
580
581         // Check isize::MAX doesn't count as an overflow
582         if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
583             panic!("isize::MAX shouldn't trigger an overflow!");
584         }
585         // Play it again, frank! (just to be sure)
586         if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
587             panic!("isize::MAX shouldn't trigger an overflow!");
588         }
589
590         if guards_against_isize {
591             // Check isize::MAX + 1 does count as overflow
592             if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
593             } else {
594                 panic!("isize::MAX + 1 should trigger an overflow!")
595             }
596
597             // Check usize::MAX does count as overflow
598             if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
599             } else {
600                 panic!("usize::MAX should trigger an overflow!")
601             }
602         } else {
603             // Check isize::MAX + 1 is an OOM
604             if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
605             } else {
606                 panic!("isize::MAX + 1 should trigger an OOM!")
607             }
608
609             // Check usize::MAX is an OOM
610             if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
611             } else {
612                 panic!("usize::MAX should trigger an OOM!")
613             }
614         }
615     }
616
617     {
618         // Same basic idea, but with non-zero len
619         let mut ten_bytes: String = String::from("0123456789");
620
621         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
622             panic!("isize::MAX shouldn't trigger an overflow!");
623         }
624         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
625             panic!("isize::MAX shouldn't trigger an overflow!");
626         }
627         if guards_against_isize {
628             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
629             } else {
630                 panic!("isize::MAX + 1 should trigger an overflow!");
631             }
632         } else {
633             if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
634             } else {
635                 panic!("isize::MAX + 1 should trigger an OOM!")
636             }
637         }
638         // Should always overflow in the add-to-len
639         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
640         } else {
641             panic!("usize::MAX should trigger an overflow!")
642         }
643     }
644 }
645
646 #[test]
647 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
648 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
649 fn test_try_reserve_exact() {
650     // This is exactly the same as test_try_reserve with the method changed.
651     // See that test for comments.
652
653     const MAX_CAP: usize = isize::MAX as usize;
654     const MAX_USIZE: usize = usize::MAX;
655
656     let guards_against_isize = size_of::<usize>() < 8;
657
658     {
659         let mut empty_string: String = String::new();
660
661         if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
662             panic!("isize::MAX shouldn't trigger an overflow!");
663         }
664         if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
665             panic!("isize::MAX shouldn't trigger an overflow!");
666         }
667
668         if guards_against_isize {
669             if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
670             } else {
671                 panic!("isize::MAX + 1 should trigger an overflow!")
672             }
673
674             if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
675             } else {
676                 panic!("usize::MAX should trigger an overflow!")
677             }
678         } else {
679             if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
680             } else {
681                 panic!("isize::MAX + 1 should trigger an OOM!")
682             }
683
684             if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
685             } else {
686                 panic!("usize::MAX should trigger an OOM!")
687             }
688         }
689     }
690
691     {
692         let mut ten_bytes: String = String::from("0123456789");
693
694         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
695             panic!("isize::MAX shouldn't trigger an overflow!");
696         }
697         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
698             panic!("isize::MAX shouldn't trigger an overflow!");
699         }
700         if guards_against_isize {
701             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
702             } else {
703                 panic!("isize::MAX + 1 should trigger an overflow!");
704             }
705         } else {
706             if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
707             } else {
708                 panic!("isize::MAX + 1 should trigger an OOM!")
709             }
710         }
711         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
712         } else {
713             panic!("usize::MAX should trigger an overflow!")
714         }
715     }
716 }
717
718 #[test]
719 fn test_from_char() {
720     assert_eq!(String::from('a'), 'a'.to_string());
721     let s: String = 'x'.into();
722     assert_eq!(s, 'x'.to_string());
723 }
724
725 #[test]
726 fn test_str_concat() {
727     let a: String = "hello".to_string();
728     let b: String = "world".to_string();
729     let s: String = format!("{}{}", a, b);
730     assert_eq!(s.as_bytes()[9], 'd' as u8);
731 }