summaryrefslogtreecommitdiffstats
path: root/library/core/tests/fmt
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/tests/fmt')
-rw-r--r--library/core/tests/fmt/builders.rs726
-rw-r--r--library/core/tests/fmt/float.rs55
-rw-r--r--library/core/tests/fmt/mod.rs45
-rw-r--r--library/core/tests/fmt/num.rs225
4 files changed, 1051 insertions, 0 deletions
diff --git a/library/core/tests/fmt/builders.rs b/library/core/tests/fmt/builders.rs
new file mode 100644
index 000000000..487ce46be
--- /dev/null
+++ b/library/core/tests/fmt/builders.rs
@@ -0,0 +1,726 @@
+mod debug_struct {
+ use std::fmt;
+
+ #[test]
+ fn test_empty() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo").finish()
+ }
+ }
+
+ assert_eq!("Foo", format!("{Foo:?}"));
+ assert_eq!("Foo", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_single() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo").field("bar", &true).finish()
+ }
+ }
+
+ assert_eq!("Foo { bar: true }", format!("{Foo:?}"));
+ assert_eq!(
+ "Foo {
+ bar: true,
+}",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo")
+ .field("bar", &true)
+ .field("baz", &format_args!("{}/{}", 10, 20))
+ .finish()
+ }
+ }
+
+ assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{Foo:?}"));
+ assert_eq!(
+ "Foo {
+ bar: true,
+ baz: 10/20,
+}",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo")
+ .field("bar", &true)
+ .field("baz", &format_args!("{}/{}", 10, 20))
+ .finish()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Bar").field("foo", &Foo).field("hello", &"world").finish()
+ }
+ }
+
+ assert_eq!(
+ "Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }",
+ format!("{Bar:?}")
+ );
+ assert_eq!(
+ "Bar {
+ foo: Foo {
+ bar: true,
+ baz: 10/20,
+ },
+ hello: \"world\",
+}",
+ format!("{Bar:#?}")
+ );
+ }
+
+ #[test]
+ fn test_only_non_exhaustive() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo").finish_non_exhaustive()
+ }
+ }
+
+ assert_eq!("Foo { .. }", format!("{Foo:?}"));
+ assert_eq!("Foo { .. }", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_multiple_and_non_exhaustive() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo")
+ .field("bar", &true)
+ .field("baz", &format_args!("{}/{}", 10, 20))
+ .finish_non_exhaustive()
+ }
+ }
+
+ assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{Foo:?}"));
+ assert_eq!(
+ "Foo {
+ bar: true,
+ baz: 10/20,
+ ..
+}",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested_non_exhaustive() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Foo")
+ .field("bar", &true)
+ .field("baz", &format_args!("{}/{}", 10, 20))
+ .finish_non_exhaustive()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("Bar")
+ .field("foo", &Foo)
+ .field("hello", &"world")
+ .finish_non_exhaustive()
+ }
+ }
+
+ assert_eq!(
+ "Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }",
+ format!("{Bar:?}")
+ );
+ assert_eq!(
+ "Bar {
+ foo: Foo {
+ bar: true,
+ baz: 10/20,
+ ..
+ },
+ hello: \"world\",
+ ..
+}",
+ format!("{Bar:#?}")
+ );
+ }
+}
+
+mod debug_tuple {
+ use std::fmt;
+
+ #[test]
+ fn test_empty() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_tuple("Foo").finish()
+ }
+ }
+
+ assert_eq!("Foo", format!("{Foo:?}"));
+ assert_eq!("Foo", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_single() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_tuple("Foo").field(&true).finish()
+ }
+ }
+
+ assert_eq!("Foo(true)", format!("{Foo:?}"));
+ assert_eq!(
+ "Foo(
+ true,
+)",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ assert_eq!("Foo(true, 10/20)", format!("{Foo:?}"));
+ assert_eq!(
+ "Foo(
+ true,
+ 10/20,
+)",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish()
+ }
+ }
+
+ assert_eq!("Bar(Foo(true, 10/20), \"world\")", format!("{Bar:?}"));
+ assert_eq!(
+ "Bar(
+ Foo(
+ true,
+ 10/20,
+ ),
+ \"world\",
+)",
+ format!("{Bar:#?}")
+ );
+ }
+}
+
+mod debug_map {
+ use std::fmt;
+
+ #[test]
+ fn test_empty() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().finish()
+ }
+ }
+
+ assert_eq!("{}", format!("{Foo:?}"));
+ assert_eq!("{}", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_single() {
+ struct Entry;
+
+ impl fmt::Debug for Entry {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().entry(&"bar", &true).finish()
+ }
+ }
+
+ struct KeyValue;
+
+ impl fmt::Debug for KeyValue {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().key(&"bar").value(&true).finish()
+ }
+ }
+
+ assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
+ assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
+
+ assert_eq!("{\"bar\": true}", format!("{Entry:?}"));
+ assert_eq!(
+ "{
+ \"bar\": true,
+}",
+ format!("{Entry:#?}")
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ struct Entry;
+
+ impl fmt::Debug for Entry {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map()
+ .entry(&"bar", &true)
+ .entry(&10, &format_args!("{}/{}", 10, 20))
+ .finish()
+ }
+ }
+
+ struct KeyValue;
+
+ impl fmt::Debug for KeyValue {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map()
+ .key(&"bar")
+ .value(&true)
+ .key(&10)
+ .value(&format_args!("{}/{}", 10, 20))
+ .finish()
+ }
+ }
+
+ assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
+ assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
+
+ assert_eq!("{\"bar\": true, 10: 10/20}", format!("{Entry:?}"));
+ assert_eq!(
+ "{
+ \"bar\": true,
+ 10: 10/20,
+}",
+ format!("{Entry:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map()
+ .entry(&"bar", &true)
+ .entry(&10, &format_args!("{}/{}", 10, 20))
+ .finish()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish()
+ }
+ }
+
+ assert_eq!(
+ "{\"foo\": {\"bar\": true, 10: 10/20}, \
+ {\"bar\": true, 10: 10/20}: \"world\"}",
+ format!("{Bar:?}")
+ );
+ assert_eq!(
+ "{
+ \"foo\": {
+ \"bar\": true,
+ 10: 10/20,
+ },
+ {
+ \"bar\": true,
+ 10: 10/20,
+ }: \"world\",
+}",
+ format!("{Bar:#?}")
+ );
+ }
+
+ #[test]
+ fn test_entry_err() {
+ // Ensure errors in a map entry don't trigger panics (#65231)
+ use std::fmt::Write;
+
+ struct ErrorFmt;
+
+ impl fmt::Debug for ErrorFmt {
+ fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Err(fmt::Error)
+ }
+ }
+
+ struct KeyValue<K, V>(usize, K, V);
+
+ impl<K, V> fmt::Debug for KeyValue<K, V>
+ where
+ K: fmt::Debug,
+ V: fmt::Debug,
+ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut map = fmt.debug_map();
+
+ for _ in 0..self.0 {
+ map.entry(&self.1, &self.2);
+ }
+
+ map.finish()
+ }
+ }
+
+ let mut buf = String::new();
+
+ assert!(write!(&mut buf, "{:?}", KeyValue(1, ErrorFmt, "bar")).is_err());
+ assert!(write!(&mut buf, "{:?}", KeyValue(1, "foo", ErrorFmt)).is_err());
+
+ assert!(write!(&mut buf, "{:?}", KeyValue(2, ErrorFmt, "bar")).is_err());
+ assert!(write!(&mut buf, "{:?}", KeyValue(2, "foo", ErrorFmt)).is_err());
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_invalid_key_when_entry_is_incomplete() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().key(&"bar").key(&"invalid").finish()
+ }
+ }
+
+ format!("{Foo:?}");
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_invalid_finish_incomplete_entry() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().key(&"bar").finish()
+ }
+ }
+
+ format!("{Foo:?}");
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_invalid_value_before_key() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().value(&"invalid").key(&"bar").finish()
+ }
+ }
+
+ format!("{Foo:?}");
+ }
+}
+
+mod debug_set {
+ use std::fmt;
+
+ #[test]
+ fn test_empty() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().finish()
+ }
+ }
+
+ assert_eq!("{}", format!("{Foo:?}"));
+ assert_eq!("{}", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_single() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entry(&true).finish()
+ }
+ }
+
+ assert_eq!("{true}", format!("{Foo:?}"));
+ assert_eq!(
+ "{
+ true,
+}",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ assert_eq!("{true, 10/20}", format!("{Foo:?}"));
+ assert_eq!(
+ "{
+ true,
+ 10/20,
+}",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entry(&Foo).entry(&"world").finish()
+ }
+ }
+
+ assert_eq!("{{true, 10/20}, \"world\"}", format!("{Bar:?}"));
+ assert_eq!(
+ "{
+ {
+ true,
+ 10/20,
+ },
+ \"world\",
+}",
+ format!("{Bar:#?}")
+ );
+ }
+}
+
+mod debug_list {
+ use std::fmt;
+
+ #[test]
+ fn test_empty() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_list().finish()
+ }
+ }
+
+ assert_eq!("[]", format!("{Foo:?}"));
+ assert_eq!("[]", format!("{Foo:#?}"));
+ }
+
+ #[test]
+ fn test_single() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_list().entry(&true).finish()
+ }
+ }
+
+ assert_eq!("[true]", format!("{Foo:?}"));
+ assert_eq!(
+ "[
+ true,
+]",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ assert_eq!("[true, 10/20]", format!("{Foo:?}"));
+ assert_eq!(
+ "[
+ true,
+ 10/20,
+]",
+ format!("{Foo:#?}")
+ );
+ }
+
+ #[test]
+ fn test_nested() {
+ struct Foo;
+
+ impl fmt::Debug for Foo {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
+ }
+ }
+
+ struct Bar;
+
+ impl fmt::Debug for Bar {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_list().entry(&Foo).entry(&"world").finish()
+ }
+ }
+
+ assert_eq!("[[true, 10/20], \"world\"]", format!("{Bar:?}"));
+ assert_eq!(
+ "[
+ [
+ true,
+ 10/20,
+ ],
+ \"world\",
+]",
+ format!("{Bar:#?}")
+ );
+ }
+}
+
+#[test]
+fn test_formatting_parameters_are_forwarded() {
+ use std::collections::{BTreeMap, BTreeSet};
+ #[derive(Debug)]
+ #[allow(dead_code)]
+ struct Foo {
+ bar: u32,
+ baz: u32,
+ }
+ let struct_ = Foo { bar: 1024, baz: 7 };
+ let tuple = (1024, 7);
+ let list = [1024, 7];
+ let mut map = BTreeMap::new();
+ map.insert("bar", 1024);
+ map.insert("baz", 7);
+ let mut set = BTreeSet::new();
+ set.insert(1024);
+ set.insert(7);
+
+ assert_eq!(format!("{struct_:03?}"), "Foo { bar: 1024, baz: 007 }");
+ assert_eq!(format!("{tuple:03?}"), "(1024, 007)");
+ assert_eq!(format!("{list:03?}"), "[1024, 007]");
+ assert_eq!(format!("{map:03?}"), r#"{"bar": 1024, "baz": 007}"#);
+ assert_eq!(format!("{set:03?}"), "{007, 1024}");
+ assert_eq!(
+ format!("{struct_:#03?}"),
+ "
+Foo {
+ bar: 1024,
+ baz: 007,
+}
+ "
+ .trim()
+ );
+ assert_eq!(
+ format!("{tuple:#03?}"),
+ "
+(
+ 1024,
+ 007,
+)
+ "
+ .trim()
+ );
+ assert_eq!(
+ format!("{list:#03?}"),
+ "
+[
+ 1024,
+ 007,
+]
+ "
+ .trim()
+ );
+ assert_eq!(
+ format!("{map:#03?}"),
+ r#"
+{
+ "bar": 1024,
+ "baz": 007,
+}
+ "#
+ .trim()
+ );
+ assert_eq!(
+ format!("{set:#03?}"),
+ "
+{
+ 007,
+ 1024,
+}
+ "
+ .trim()
+ );
+}
diff --git a/library/core/tests/fmt/float.rs b/library/core/tests/fmt/float.rs
new file mode 100644
index 000000000..47a7400f7
--- /dev/null
+++ b/library/core/tests/fmt/float.rs
@@ -0,0 +1,55 @@
+#[test]
+fn test_format_f64() {
+ assert_eq!("1", format!("{:.0}", 1.0f64));
+ assert_eq!("9", format!("{:.0}", 9.4f64));
+ assert_eq!("10", format!("{:.0}", 9.9f64));
+ assert_eq!("9.8", format!("{:.1}", 9.849f64));
+ assert_eq!("9.9", format!("{:.1}", 9.851f64));
+ assert_eq!("1", format!("{:.0}", 0.5f64));
+ assert_eq!("1.23456789e6", format!("{:e}", 1234567.89f64));
+ assert_eq!("1.23456789e3", format!("{:e}", 1234.56789f64));
+ assert_eq!("1.23456789E6", format!("{:E}", 1234567.89f64));
+ assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64));
+ assert_eq!("0.0", format!("{:?}", 0.0f64));
+ assert_eq!("1.01", format!("{:?}", 1.01f64));
+
+ let high_cutoff = 1e16_f64;
+ assert_eq!("1e16", format!("{:?}", high_cutoff));
+ assert_eq!("-1e16", format!("{:?}", -high_cutoff));
+ assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f64::EPSILON))));
+ assert_eq!("-3.0", format!("{:?}", -3f64));
+ assert_eq!("0.0001", format!("{:?}", 0.0001f64));
+ assert_eq!("9e-5", format!("{:?}", 0.00009f64));
+ assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f64));
+ assert_eq!("1234.6", format!("{:.1?}", 1234.56789f64));
+}
+
+#[test]
+fn test_format_f32() {
+ assert_eq!("1", format!("{:.0}", 1.0f32));
+ assert_eq!("9", format!("{:.0}", 9.4f32));
+ assert_eq!("10", format!("{:.0}", 9.9f32));
+ assert_eq!("9.8", format!("{:.1}", 9.849f32));
+ assert_eq!("9.9", format!("{:.1}", 9.851f32));
+ assert_eq!("1", format!("{:.0}", 0.5f32));
+ assert_eq!("1.2345679e6", format!("{:e}", 1234567.89f32));
+ assert_eq!("1.2345679e3", format!("{:e}", 1234.56789f32));
+ assert_eq!("1.2345679E6", format!("{:E}", 1234567.89f32));
+ assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32));
+ assert_eq!("0.0", format!("{:?}", 0.0f32));
+ assert_eq!("1.01", format!("{:?}", 1.01f32));
+
+ let high_cutoff = 1e16_f32;
+ assert_eq!("1e16", format!("{:?}", high_cutoff));
+ assert_eq!("-1e16", format!("{:?}", -high_cutoff));
+ assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f32::EPSILON))));
+ assert_eq!("-3.0", format!("{:?}", -3f32));
+ assert_eq!("0.0001", format!("{:?}", 0.0001f32));
+ assert_eq!("9e-5", format!("{:?}", 0.00009f32));
+ assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f32));
+ assert_eq!("1234.6", format!("{:.1?}", 1234.56789f32));
+}
+
+fn is_exponential(s: &str) -> bool {
+ s.contains("e") || s.contains("E")
+}
diff --git a/library/core/tests/fmt/mod.rs b/library/core/tests/fmt/mod.rs
new file mode 100644
index 000000000..618076358
--- /dev/null
+++ b/library/core/tests/fmt/mod.rs
@@ -0,0 +1,45 @@
+mod builders;
+mod float;
+mod num;
+
+#[test]
+fn test_format_flags() {
+ // No residual flags left by pointer formatting
+ let p = "".as_ptr();
+ assert_eq!(format!("{:p} {:x}", p, 16), format!("{p:p} 10"));
+
+ assert_eq!(format!("{: >3}", 'a'), " a");
+}
+
+#[test]
+fn test_pointer_formats_data_pointer() {
+ let b: &[u8] = b"";
+ let s: &str = "";
+ assert_eq!(format!("{s:p}"), format!("{:p}", s.as_ptr()));
+ assert_eq!(format!("{b:p}"), format!("{:p}", b.as_ptr()));
+}
+
+#[test]
+fn test_estimated_capacity() {
+ assert_eq!(format_args!("").estimated_capacity(), 0);
+ assert_eq!(format_args!("{}", "").estimated_capacity(), 0);
+ assert_eq!(format_args!("Hello").estimated_capacity(), 5);
+ assert_eq!(format_args!("Hello, {}!", "").estimated_capacity(), 16);
+ assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0);
+ assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32);
+}
+
+#[test]
+fn pad_integral_resets() {
+ struct Bar;
+
+ impl core::fmt::Display for Bar {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ "1".fmt(f)?;
+ f.pad_integral(true, "", "5")?;
+ "1".fmt(f)
+ }
+ }
+
+ assert_eq!(format!("{Bar:<03}"), "1 0051 ");
+}
diff --git a/library/core/tests/fmt/num.rs b/library/core/tests/fmt/num.rs
new file mode 100644
index 000000000..b9ede65c9
--- /dev/null
+++ b/library/core/tests/fmt/num.rs
@@ -0,0 +1,225 @@
+#[test]
+fn test_format_int() {
+ // Formatting integers should select the right implementation based off
+ // the type of the argument. Also, hex/octal/binary should be defined
+ // for integers, but they shouldn't emit the negative sign.
+ assert_eq!(format!("{}", 1isize), "1");
+ assert_eq!(format!("{}", 1i8), "1");
+ assert_eq!(format!("{}", 1i16), "1");
+ assert_eq!(format!("{}", 1i32), "1");
+ assert_eq!(format!("{}", 1i64), "1");
+ assert_eq!(format!("{}", -1isize), "-1");
+ assert_eq!(format!("{}", -1i8), "-1");
+ assert_eq!(format!("{}", -1i16), "-1");
+ assert_eq!(format!("{}", -1i32), "-1");
+ assert_eq!(format!("{}", -1i64), "-1");
+ assert_eq!(format!("{:?}", 1isize), "1");
+ assert_eq!(format!("{:?}", 1i8), "1");
+ assert_eq!(format!("{:?}", 1i16), "1");
+ assert_eq!(format!("{:?}", 1i32), "1");
+ assert_eq!(format!("{:?}", 1i64), "1");
+ assert_eq!(format!("{:b}", 1isize), "1");
+ assert_eq!(format!("{:b}", 1i8), "1");
+ assert_eq!(format!("{:b}", 1i16), "1");
+ assert_eq!(format!("{:b}", 1i32), "1");
+ assert_eq!(format!("{:b}", 1i64), "1");
+ assert_eq!(format!("{:x}", 1isize), "1");
+ assert_eq!(format!("{:x}", 1i8), "1");
+ assert_eq!(format!("{:x}", 1i16), "1");
+ assert_eq!(format!("{:x}", 1i32), "1");
+ assert_eq!(format!("{:x}", 1i64), "1");
+ assert_eq!(format!("{:X}", 1isize), "1");
+ assert_eq!(format!("{:X}", 1i8), "1");
+ assert_eq!(format!("{:X}", 1i16), "1");
+ assert_eq!(format!("{:X}", 1i32), "1");
+ assert_eq!(format!("{:X}", 1i64), "1");
+ assert_eq!(format!("{:o}", 1isize), "1");
+ assert_eq!(format!("{:o}", 1i8), "1");
+ assert_eq!(format!("{:o}", 1i16), "1");
+ assert_eq!(format!("{:o}", 1i32), "1");
+ assert_eq!(format!("{:o}", 1i64), "1");
+ assert_eq!(format!("{:e}", 1isize), "1e0");
+ assert_eq!(format!("{:e}", 1i8), "1e0");
+ assert_eq!(format!("{:e}", 1i16), "1e0");
+ assert_eq!(format!("{:e}", 1i32), "1e0");
+ assert_eq!(format!("{:e}", 1i64), "1e0");
+ assert_eq!(format!("{:E}", 1isize), "1E0");
+ assert_eq!(format!("{:E}", 1i8), "1E0");
+ assert_eq!(format!("{:E}", 1i16), "1E0");
+ assert_eq!(format!("{:E}", 1i32), "1E0");
+ assert_eq!(format!("{:E}", 1i64), "1E0");
+
+ assert_eq!(format!("{}", 1usize), "1");
+ assert_eq!(format!("{}", 1u8), "1");
+ assert_eq!(format!("{}", 1u16), "1");
+ assert_eq!(format!("{}", 1u32), "1");
+ assert_eq!(format!("{}", 1u64), "1");
+ assert_eq!(format!("{:?}", 1usize), "1");
+ assert_eq!(format!("{:?}", 1u8), "1");
+ assert_eq!(format!("{:?}", 1u16), "1");
+ assert_eq!(format!("{:?}", 1u32), "1");
+ assert_eq!(format!("{:?}", 1u64), "1");
+ assert_eq!(format!("{:b}", 1usize), "1");
+ assert_eq!(format!("{:b}", 1u8), "1");
+ assert_eq!(format!("{:b}", 1u16), "1");
+ assert_eq!(format!("{:b}", 1u32), "1");
+ assert_eq!(format!("{:b}", 1u64), "1");
+ assert_eq!(format!("{:x}", 1usize), "1");
+ assert_eq!(format!("{:x}", 1u8), "1");
+ assert_eq!(format!("{:x}", 1u16), "1");
+ assert_eq!(format!("{:x}", 1u32), "1");
+ assert_eq!(format!("{:x}", 1u64), "1");
+ assert_eq!(format!("{:X}", 1usize), "1");
+ assert_eq!(format!("{:X}", 1u8), "1");
+ assert_eq!(format!("{:X}", 1u16), "1");
+ assert_eq!(format!("{:X}", 1u32), "1");
+ assert_eq!(format!("{:X}", 1u64), "1");
+ assert_eq!(format!("{:o}", 1usize), "1");
+ assert_eq!(format!("{:o}", 1u8), "1");
+ assert_eq!(format!("{:o}", 1u16), "1");
+ assert_eq!(format!("{:o}", 1u32), "1");
+ assert_eq!(format!("{:o}", 1u64), "1");
+ assert_eq!(format!("{:e}", 1u8), "1e0");
+ assert_eq!(format!("{:e}", 1u16), "1e0");
+ assert_eq!(format!("{:e}", 1u32), "1e0");
+ assert_eq!(format!("{:e}", 1u64), "1e0");
+ assert_eq!(format!("{:E}", 1u8), "1E0");
+ assert_eq!(format!("{:E}", 1u16), "1E0");
+ assert_eq!(format!("{:E}", 1u32), "1E0");
+ assert_eq!(format!("{:E}", 1u64), "1E0");
+
+ // Test a larger number
+ assert_eq!(format!("{:b}", 55), "110111");
+ assert_eq!(format!("{:o}", 55), "67");
+ assert_eq!(format!("{}", 55), "55");
+ assert_eq!(format!("{:x}", 55), "37");
+ assert_eq!(format!("{:X}", 55), "37");
+ assert_eq!(format!("{:e}", 55), "5.5e1");
+ assert_eq!(format!("{:E}", 55), "5.5E1");
+ assert_eq!(format!("{:e}", 10000000000u64), "1e10");
+ assert_eq!(format!("{:E}", 10000000000u64), "1E10");
+ assert_eq!(format!("{:e}", 10000000001u64), "1.0000000001e10");
+ assert_eq!(format!("{:E}", 10000000001u64), "1.0000000001E10");
+}
+
+#[test]
+fn test_format_int_exp_limits() {
+ assert_eq!(format!("{:e}", i8::MIN), "-1.28e2");
+ assert_eq!(format!("{:e}", i8::MAX), "1.27e2");
+ assert_eq!(format!("{:e}", i16::MIN), "-3.2768e4");
+ assert_eq!(format!("{:e}", i16::MAX), "3.2767e4");
+ assert_eq!(format!("{:e}", i32::MIN), "-2.147483648e9");
+ assert_eq!(format!("{:e}", i32::MAX), "2.147483647e9");
+ assert_eq!(format!("{:e}", i64::MIN), "-9.223372036854775808e18");
+ assert_eq!(format!("{:e}", i64::MAX), "9.223372036854775807e18");
+ assert_eq!(format!("{:e}", i128::MIN), "-1.70141183460469231731687303715884105728e38");
+ assert_eq!(format!("{:e}", i128::MAX), "1.70141183460469231731687303715884105727e38");
+
+ assert_eq!(format!("{:e}", u8::MAX), "2.55e2");
+ assert_eq!(format!("{:e}", u16::MAX), "6.5535e4");
+ assert_eq!(format!("{:e}", u32::MAX), "4.294967295e9");
+ assert_eq!(format!("{:e}", u64::MAX), "1.8446744073709551615e19");
+ assert_eq!(format!("{:e}", u128::MAX), "3.40282366920938463463374607431768211455e38");
+}
+
+#[test]
+fn test_format_int_exp_precision() {
+ //test that float and integer match
+ let big_int: u32 = 314_159_265;
+ assert_eq!(format!("{big_int:.1e}"), format!("{:.1e}", f64::from(big_int)));
+
+ //test adding precision
+ assert_eq!(format!("{:.10e}", i8::MIN), "-1.2800000000e2");
+ assert_eq!(format!("{:.10e}", i16::MIN), "-3.2768000000e4");
+ assert_eq!(format!("{:.10e}", i32::MIN), "-2.1474836480e9");
+ assert_eq!(format!("{:.20e}", i64::MIN), "-9.22337203685477580800e18");
+ assert_eq!(format!("{:.40e}", i128::MIN), "-1.7014118346046923173168730371588410572800e38");
+
+ //test rounding
+ assert_eq!(format!("{:.1e}", i8::MIN), "-1.3e2");
+ assert_eq!(format!("{:.1e}", i16::MIN), "-3.3e4");
+ assert_eq!(format!("{:.1e}", i32::MIN), "-2.1e9");
+ assert_eq!(format!("{:.1e}", i64::MIN), "-9.2e18");
+ assert_eq!(format!("{:.1e}", i128::MIN), "-1.7e38");
+
+ //test huge precision
+ assert_eq!(format!("{:.1000e}", 1), format!("1.{}e0", "0".repeat(1000)));
+ //test zero precision
+ assert_eq!(format!("{:.0e}", 1), format!("1e0",));
+ assert_eq!(format!("{:.0e}", 35), format!("4e1",));
+
+ //test padding with precision (and sign)
+ assert_eq!(format!("{:+10.3e}", 1), " +1.000e0");
+}
+
+#[test]
+fn test_format_int_zero() {
+ assert_eq!(format!("{}", 0), "0");
+ assert_eq!(format!("{:?}", 0), "0");
+ assert_eq!(format!("{:b}", 0), "0");
+ assert_eq!(format!("{:o}", 0), "0");
+ assert_eq!(format!("{:x}", 0), "0");
+ assert_eq!(format!("{:X}", 0), "0");
+ assert_eq!(format!("{:e}", 0), "0e0");
+ assert_eq!(format!("{:E}", 0), "0E0");
+
+ assert_eq!(format!("{}", 0u32), "0");
+ assert_eq!(format!("{:?}", 0u32), "0");
+ assert_eq!(format!("{:b}", 0u32), "0");
+ assert_eq!(format!("{:o}", 0u32), "0");
+ assert_eq!(format!("{:x}", 0u32), "0");
+ assert_eq!(format!("{:X}", 0u32), "0");
+ assert_eq!(format!("{:e}", 0u32), "0e0");
+ assert_eq!(format!("{:E}", 0u32), "0E0");
+}
+
+#[test]
+fn test_format_int_flags() {
+ assert_eq!(format!("{:3}", 1), " 1");
+ assert_eq!(format!("{:>3}", 1), " 1");
+ assert_eq!(format!("{:>+3}", 1), " +1");
+ assert_eq!(format!("{:<3}", 1), "1 ");
+ assert_eq!(format!("{:#}", 1), "1");
+ assert_eq!(format!("{:#x}", 10), "0xa");
+ assert_eq!(format!("{:#X}", 10), "0xA");
+ assert_eq!(format!("{:#5x}", 10), " 0xa");
+ assert_eq!(format!("{:#o}", 10), "0o12");
+ assert_eq!(format!("{:08x}", 10), "0000000a");
+ assert_eq!(format!("{:8x}", 10), " a");
+ assert_eq!(format!("{:<8x}", 10), "a ");
+ assert_eq!(format!("{:>8x}", 10), " a");
+ assert_eq!(format!("{:#08x}", 10), "0x00000a");
+ assert_eq!(format!("{:08}", -10), "-0000010");
+ assert_eq!(format!("{:x}", !0u8), "ff");
+ assert_eq!(format!("{:X}", !0u8), "FF");
+ assert_eq!(format!("{:b}", !0u8), "11111111");
+ assert_eq!(format!("{:o}", !0u8), "377");
+ assert_eq!(format!("{:#x}", !0u8), "0xff");
+ assert_eq!(format!("{:#X}", !0u8), "0xFF");
+ assert_eq!(format!("{:#b}", !0u8), "0b11111111");
+ assert_eq!(format!("{:#o}", !0u8), "0o377");
+}
+
+#[test]
+fn test_format_int_sign_padding() {
+ assert_eq!(format!("{:+5}", 1), " +1");
+ assert_eq!(format!("{:+5}", -1), " -1");
+ assert_eq!(format!("{:05}", 1), "00001");
+ assert_eq!(format!("{:05}", -1), "-0001");
+ assert_eq!(format!("{:+05}", 1), "+0001");
+ assert_eq!(format!("{:+05}", -1), "-0001");
+}
+
+#[test]
+fn test_format_int_twos_complement() {
+ assert_eq!(format!("{}", i8::MIN), "-128");
+ assert_eq!(format!("{}", i16::MIN), "-32768");
+ assert_eq!(format!("{}", i32::MIN), "-2147483648");
+ assert_eq!(format!("{}", i64::MIN), "-9223372036854775808");
+}
+
+#[test]
+fn test_format_debug_hex() {
+ assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");
+ assert_eq!(format!("{:02X?}", b"Foo\0"), "[46, 6F, 6F, 00]");
+}