Browse Source

Add `duration.hpp` and associated tests

master
Jessica James 3 years ago
parent
commit
54fb6b9f24
  1. 299
      src/include/duration.hpp
  2. 226
      src/test/duration.cpp

299
src/include/duration.hpp

@ -0,0 +1,299 @@
/**
* Copyright (C) 2021 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#pragma once
#include <chrono>
#include <string>
#include <string_view>
namespace jessilib {
namespace impl {
constexpr const char* suffix_helper(const char* begin, const char* end, const char* ignored_suffix) {
while (begin != end
&& *begin == *ignored_suffix) {
++begin;
++ignored_suffix;
}
return begin;
}
} // namespace impl
// Base 10 only
// y = year (31556952 seconds == 365.2425 day)
// mo = month (2629746 seconds == year/12)
// w = weeks
// d[ay] = days
// h[r] = hours
// m[in] = minutes
// s = seconds
// ms = milliseconds
// us = microseconds
// ns = nanoseconds
// trailing: DurationT
template<typename DurationT = std::chrono::seconds>
struct duration_from_string_result {
const char* itr{};
DurationT duration{};
};
// At time of writing, days, weeks, months, years seem inconsistently available
using days = std::chrono::duration<std::chrono::hours::rep, std::ratio<86400>>;
using weeks = std::chrono::duration<std::chrono::hours::rep, std::ratio<604800>>;
using months = std::chrono::duration<std::chrono::hours::rep, std::ratio<2629746>>;
using years = std::chrono::duration<std::chrono::hours::rep, std::ratio<31556952>>;
template<typename DurationT = std::chrono::seconds>
constexpr duration_from_string_result<DurationT> duration_from_string(const char* begin, const char* end) {
duration_from_string_result<DurationT> result{ begin, {} };
auto& itr = result.itr;
// Sanity check
if (end <= itr) {
return result;
}
while (itr != end) {
// Advance through any whitespace preceding type specifier
while (*itr == ' ') {
++itr;
if (itr == end) {
// no text remains
return result;
}
}
typename DurationT::rep segment{};
// Parse duration segment (i.e: [0-9]+[ms][]
while (*itr >= '0' && *itr <= '9') {
segment *= 10;
segment += *itr - '0';
++itr;
if (itr == end) {
// end of string; always treat ending digits as base unit (DurationT)
result.duration += DurationT{ segment };
return result;
}
}
// Advance past any whitespace preceding type specifier
while (*itr == ' ') {
++itr;
if (itr == end) {
// end of string; always treat ending digits as base unit (DurationT)
result.duration += DurationT{ segment };
return result;
}
}
// after switch, 'itr' shall point to first unparsed character, or end
switch (*itr) {
case 'y': // year
++itr; // 'y'
result.duration += std::chrono::duration_cast<DurationT>(years{ segment });
// "yr"
if (itr != end
&& *itr == 'r') {
// ignore trailing 'r'
++itr;
break;
}
// "year"
itr = impl::suffix_helper(itr, end, "ear");
break;
case 'w': // week
++itr; // 'w'
result.duration += std::chrono::duration_cast<DurationT>(weeks{ segment });
if (itr != end
&& *itr == 'k') {
// "wk"
++itr;
break;
}
// "week"
itr = impl::suffix_helper(itr, end, "eek");
break;
case 'd': // day
++itr; // 'd'
result.duration += std::chrono::duration_cast<DurationT>(days{ segment });
itr = impl::suffix_helper(itr, end, "ay");
break;
case 'h': // hour
++itr; // 'h'
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::hours{ segment });
if (itr != end
&& *itr == 'r') {
// "hr"
++itr;
break;
}
// "hour"
itr = impl::suffix_helper(itr, end, "our");
break;
case 'm': // min/month/milli
++itr; // 'm'
if (itr == end) {
// "m" end of string; treat as minutes
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::minutes{ segment });
return result;
}
if (*itr == 'i') {
// "minutes" or "milliseconds"
++itr;
if (itr != end
&& *itr == 'n') {
// minutes
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::minutes{ segment });
itr = impl::suffix_helper(itr, end, "nutes");
break;
}
// anything not starting with "min", assume milliseconds
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::milliseconds{ segment });
itr = impl::suffix_helper(itr, end, "lliseconds");
break;
}
if (*itr == 's') {
// ms
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::milliseconds{ segment });
++itr;
break;
}
if (*itr == 'o') {
// mo
result.duration += std::chrono::duration_cast<DurationT>(months{ segment });
++itr;
// "month"
itr = impl::suffix_helper(itr, end, "nth");
break;
}
// Valid scenario for "m "; invalid specifier otherwise
break;
case 's':
++itr; // 's'
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::seconds{ segment });
itr = impl::suffix_helper(itr, end, "econd");
break;
case 'u': // micro
++itr; // 'u'
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::microseconds{ segment });
itr = impl::suffix_helper(itr, end, "s");
break;
case 'n': // nano
++itr; // 'n'
result.duration += std::chrono::duration_cast<DurationT>(std::chrono::nanoseconds{ segment });
itr = impl::suffix_helper(itr, end, "s");
break;
default:
// unexpected specifier; assume DurationT and cease parsing
result.duration += DurationT{ segment };
return result;
}
if (itr == end) {
return result;
}
// Remove any trailing 's' at end of unit (i.e: years, months, etc)
if (*itr == 's') {
++itr;
}
}
return result;
}
template<typename DurationT = std::chrono::seconds>
constexpr duration_from_string_result<DurationT> duration_from_string(const std::string_view& in_duration) {
return duration_from_string<DurationT>(in_duration.data(), in_duration.data() + in_duration.size());
}
namespace literals {
constexpr std::chrono::nanoseconds operator ""_duration_ns(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::nanoseconds>(in_str, in_str + in_str_length).duration;
}
constexpr std::chrono::microseconds operator ""_duration_us(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::microseconds>(in_str, in_str + in_str_length).duration;
}
constexpr std::chrono::milliseconds operator ""_duration_ms(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::milliseconds>(in_str, in_str + in_str_length).duration;
}
constexpr std::chrono::seconds operator ""_duration_s(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::seconds>(in_str, in_str + in_str_length).duration;
}
constexpr std::chrono::minutes operator ""_duration_m(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::minutes>(in_str, in_str + in_str_length).duration;
}
constexpr std::chrono::hours operator ""_duration_h(const char* in_str, size_t in_str_length) {
return duration_from_string<std::chrono::hours>(in_str, in_str + in_str_length).duration;
}
constexpr days operator ""_duration_d(const char* in_str, size_t in_str_length) {
return duration_from_string<days>(in_str, in_str + in_str_length).duration;
}
constexpr weeks operator ""_duration_w(const char* in_str, size_t in_str_length) {
return duration_from_string<weeks>(in_str, in_str + in_str_length).duration;
}
constexpr months operator ""_duration_mo(const char* in_str, size_t in_str_length) {
return duration_from_string<months>(in_str, in_str + in_str_length).duration;
}
constexpr years operator ""_duration_y(const char* in_str, size_t in_str_length) {
return duration_from_string<years>(in_str, in_str + in_str_length).duration;
}
} // namespace literals
} // namespace jessilib

226
src/test/duration.cpp

@ -0,0 +1,226 @@
/**
* Copyright (C) 2018 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#include "duration.hpp"
#include "test.hpp"
using namespace jessilib;
using namespace std::literals;
using namespace jessilib::literals;
/*
* ns
* us
* ms
* s
* m
* h
* d
* w
* mo
* y
*/
// Basic compile-time tests
static_assert("1234ns"_duration_ns.count() == 1234, "1234ns Test Failed");
static_assert("1234us"_duration_us.count() == 1234, "1234us Test Failed");
static_assert("1234ms"_duration_ms.count() == 1234, "1234ms Test Failed");
static_assert("1234s"_duration_s.count() == 1234, "1234s Test Failed");
static_assert("1234m"_duration_m.count() == 1234, "1234m Test Failed");
static_assert("1234h"_duration_h.count() == 1234, "1234h Test Failed");
static_assert("1234d"_duration_d.count() == 1234, "1234d Test Failed");
static_assert("1234w"_duration_w.count() == 1234, "1234w Test Failed");
static_assert("1234mo"_duration_mo.count() == 1234, "1234mo Test Failed");
static_assert("1234y"_duration_y.count() == 1234, "1234y Test Failed");
// Ensure string_view variant compiles
static_assert(duration_from_string("1234s"sv).duration.count() == 1234, "1234s string_view test failed");
TEST(duration, as_seconds) {
EXPECT_EQ(duration_from_string("1234"sv).duration.count(), 1234);
EXPECT_EQ(duration_from_string("0s"sv).duration.count(), 0);
EXPECT_EQ(duration_from_string("1s"sv).duration.count(), 1);
EXPECT_EQ(duration_from_string("5000ms"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000us"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000000ns"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("1h"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hr"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hour"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hours"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hrs"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1d"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1day"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1days"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1w"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1week"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1weeks"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1mo"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1mon"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1month"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1months"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1y"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1year"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1years"sv).duration.count(), 31556952);
}
TEST(duration, as_seconds_spaced) {
EXPECT_EQ(duration_from_string("0 s"sv).duration.count(), 0);
EXPECT_EQ(duration_from_string("1 s"sv).duration.count(), 1);
EXPECT_EQ(duration_from_string("5000 ms"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000 us"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000000 ns"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("1 h"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1 hr"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1 hour"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1 hours"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1 hrs"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1 d"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1 day"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1 days"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1 w"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1 week"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1 weeks"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1 mo"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1 mon"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1 month"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1 months"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1 y"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1 year"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1 years"sv).duration.count(), 31556952);
}
TEST(duration, as_seconds_front_spaced) {
EXPECT_EQ(duration_from_string(" 1234"sv).duration.count(), 1234);
EXPECT_EQ(duration_from_string(" 0s"sv).duration.count(), 0);
EXPECT_EQ(duration_from_string(" 1s"sv).duration.count(), 1);
EXPECT_EQ(duration_from_string(" 5000ms"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 5000000us"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 5000000000ns"sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 1h"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1hr"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1hour"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1hours"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1hrs"sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1d"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1day"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1days"sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1w"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1week"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1weeks"sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1mo"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1mon"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1month"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1months"sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1y"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string(" 1year"sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string(" 1years"sv).duration.count(), 31556952);
}
TEST(duration, as_seconds_back_spaced) {
EXPECT_EQ(duration_from_string("1234 "sv).duration.count(), 1234);
EXPECT_EQ(duration_from_string("0s "sv).duration.count(), 0);
EXPECT_EQ(duration_from_string("1s "sv).duration.count(), 1);
EXPECT_EQ(duration_from_string("5000ms "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000us "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("5000000000ns "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string("1h "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hr "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hour "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hours "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1hrs "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string("1d "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1day "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1days "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string("1w "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1week "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1weeks "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string("1mo "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1mon "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1month "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1months "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string("1y "sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1year "sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string("1years "sv).duration.count(), 31556952);
}
TEST(duration, as_seconds_all_spaced) {
EXPECT_EQ(duration_from_string(" 1234 "sv).duration.count(), 1234);
EXPECT_EQ(duration_from_string(" 0 s "sv).duration.count(), 0);
EXPECT_EQ(duration_from_string(" 1 s "sv).duration.count(), 1);
EXPECT_EQ(duration_from_string(" 5000 ms "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 5000000 us "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 5000000000 ns "sv).duration.count(), 5);
EXPECT_EQ(duration_from_string(" 1 h "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1 hr "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1 hour "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1 hours "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1 hrs "sv).duration.count(), 3600);
EXPECT_EQ(duration_from_string(" 1 d "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1 day "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1 days "sv).duration.count(), 86400);
EXPECT_EQ(duration_from_string(" 1 w "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1 week "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1 weeks "sv).duration.count(), 604800);
EXPECT_EQ(duration_from_string(" 1 mo "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1 mon "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1 month "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1 months "sv).duration.count(), 2629746);
EXPECT_EQ(duration_from_string(" 1 y "sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string(" 1 year "sv).duration.count(), 31556952);
EXPECT_EQ(duration_from_string(" 1 years "sv).duration.count(), 31556952);
}
template<typename DurationT>
constexpr std::chrono::seconds to_seconds(DurationT in_duration) {
return std::chrono::duration_cast<std::chrono::seconds>(in_duration);
}
TEST(duration, combinations) {
EXPECT_EQ(duration_from_string("1d 4 weeks"sv).duration.count(),
to_seconds(days{1} + weeks{4}).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1}).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr 5s"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h + 5s).count());
// Consider refactoring such that the expressions are equal without usage of to_seconds for types smaller than seconds
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr 5s 4900ms"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h + 5s + to_seconds(4900ms)).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr 5s 4900ms 6900000us"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h + 5s + to_seconds(4900ms) + to_seconds(6900000us)).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr 5s 4900ms 6900000us 900000000ns"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h + 5s + to_seconds(4900ms) + to_seconds(6900000us) + to_seconds(900000000ns)).count());
EXPECT_EQ(duration_from_string("1d 4 weeks 1 mon 4 min 36 sec 12hr 5s 4900ms 6900000us 900000000ns 7days 6years"sv).duration.count(),
to_seconds(days{1} + weeks{4} + months{1} + 4min + 36s + 12h + 5s + to_seconds(4900ms) + to_seconds(6900000us) + to_seconds(900000000ns) + days{7} + years {6}).count());
}
TEST(duration, invalid) {
EXPECT_EQ(duration_from_string("Jessica was here"sv).duration.count(),0);
EXPECT_EQ(duration_from_string("and here"sv).duration.count(),0);
EXPECT_EQ(duration_from_string("second guessing code"sv).duration.count(),0);
EXPECT_EQ(duration_from_string("year round"sv).duration.count(),0);
EXPECT_EQ(duration_from_string("1yr 3 da 4 mi invalid 77 months"sv).duration.count(),
to_seconds(years{1} + days{3}).count()); // "4 mi" is actually valid, but is rounded down to zero on conversion
}
Loading…
Cancel
Save