@@ -103,31 +103,74 @@ TEST_CASE("time ago")
103103
104104TEST_CASE (" duration to_string" )
105105{
106+ using namespace std ::chrono_literals;
106107 std::string val;
107108
108- val = humanize::time::duration::from_tv ({ 15 * 60 , 0 } )
109+ val = humanize::time::duration::from (15min )
109110 .with_compact (false )
110111 .to_string ();
111112 CHECK (val == " 15m00s" );
112- val = humanize::time::duration::from_tv ({0 , 100000 })
113- .with_compact (false )
114- .to_string ();
113+ val = humanize::time::duration::from (100ms).with_compact (false ).to_string ();
115114 CHECK (val == " 100ms" );
116- val = humanize::time::duration::from_tv ({ 25 * 60 * 60 , 123000 } ).to_string ();
115+ val = humanize::time::duration::from (25h + 123ms ).to_string ();
117116 CHECK (val == " 1d01h00m00s" );
118- val = humanize::time::duration::from_tv ({25 * 60 * 60 + 25 * 60 , 123000 })
119- .to_string ();
117+ val = humanize::time::duration::from (25h + 25min + 123ms).to_string ();
120118 CHECK (val == " 1d01h25m00s" );
121- val = humanize::time::duration::from_tv ({ 10 , 123000 } ).to_string ();
119+ val = humanize::time::duration::from (10s + 123ms ).to_string ();
122120 CHECK (val == " 10s123" );
123- val = humanize::time::duration::from_tv ({ 10 , 0 } ).to_string ();
121+ val = humanize::time::duration::from (10s ).to_string ();
124122 CHECK (val == " 10s" );
125- val = humanize::time::duration::from_tv ({ 0 , 100000 } ).to_string ();
123+ val = humanize::time::duration::from (100ms ).to_string ();
126124 CHECK (val == " 100" );
127- val = humanize::time::duration::from_tv ({ 0 , 0 } ).to_string ();
125+ val = humanize::time::duration::from (0s ).to_string ();
128126 CHECK (val == " " );
129- val = humanize::time::duration::from_tv ({ 0 , - 10000 } ).to_string ();
127+ val = humanize::time::duration::from (-10ms ).to_string ();
130128 CHECK (val == " -010" );
131- val = humanize::time::duration::from_tv ({- 10 , 0 } ).to_string ();
129+ val = humanize::time::duration::from (-10s ).to_string ();
132130 CHECK (val == " -10s" );
133131}
132+
133+ TEST_CASE (" duration nanosecond input" )
134+ {
135+ using namespace std ::chrono_literals;
136+ std::string val;
137+
138+ // Sub-microsecond → `Nns`, full precision regardless of resolution.
139+ val = humanize::time::duration::from (500ns).to_string ();
140+ CHECK (val == " 500ns" );
141+
142+ // Negative sub-microsecond carries the leading sign.
143+ val = humanize::time::duration::from (-1ns).to_string ();
144+ CHECK (val == " -1ns" );
145+
146+ // `[1us, 1ms)` → `Nus`, sub-microsecond remainder dropped (matches
147+ // pre-nanosecond timeval truncation behavior).
148+ val = humanize::time::duration::from (1234ns).to_string ();
149+ CHECK (val == " 1us" );
150+
151+ val = humanize::time::duration::from (999us + 999ns).to_string ();
152+ CHECK (val == " 999us" );
153+
154+ // `>= 1ms` falls into the segmented path; sub-millisecond
155+ // precision collapses to 1ms (the existing format doesn't carry
156+ // sub-ms segments).
157+ val = humanize::time::duration::from (1ms + 500us).to_string ();
158+ CHECK (val == " 001" );
159+
160+ val = humanize::time::duration::from (10s + 123ms + 456us).to_string ();
161+ CHECK (val == " 10s123" );
162+
163+ // Zero stays empty in compact mode regardless of source duration.
164+ val = humanize::time::duration::from (0ns).to_string ();
165+ CHECK (val == " " );
166+ val = humanize::time::duration::from (0ns).with_compact (false ).to_string ();
167+ CHECK (val == " 0s" );
168+
169+ // with_resolution(ns) doesn't grant sub-ms precision in the
170+ // segmented path — explicitly characterize the floor so a future
171+ // extension shows up as a diff.
172+ val = humanize::time::duration::from (10s + 123ms + 456us)
173+ .with_resolution (1ns)
174+ .to_string ();
175+ CHECK (val == " 10s123" );
176+ }
0 commit comments