From 3d4227d374c3f67256d3b7c9fb3c7c7e0eb28a58 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 28 Dec 2010 07:24:54 +0100 Subject: [PATCH] cover offsets, durations and timespans by unit test --- src/lib/time/lumitime.cpp | 33 ++++++++++++ src/lib/time/timevalue.hpp | 28 ++++++++-- tests/lib/time/time-value-test.cpp | 85 +++++++++++++++++++++++++++--- 3 files changed, 134 insertions(+), 12 deletions(-) diff --git a/src/lib/time/lumitime.cpp b/src/lib/time/lumitime.cpp index 5794b445e..8d9bba707 100644 --- a/src/lib/time/lumitime.cpp +++ b/src/lib/time/lumitime.cpp @@ -41,6 +41,39 @@ namespace time { const Time Time::MIN ( TimeValue (-std::numeric_limits::max()) ); + /** convenience constructor to build an + * internal Lumiera Time value from the usual parts + * of an hexagesimal time specification. Arbitrary integral + * values are acceptable and will be summed up accordingly. + * The minute and hour part can be omitted. + * @warning internal Lumiera time values refer to an + * implementation dependent time origin/scale. + * The given value will be used as-is, without + * any further adjustments. + */ + Time::Time ( long millis + , uint secs + , uint mins + , uint hours + ) + : TimeValue(lumiera_build_time (millis,secs,mins,hours)) + { } + + + /** displaying an internal Lumiera Time value + * for diagnostic purposes or internal reporting. + * @warning internal Lumiera time values refer to an + * implementation dependent time origin/scale. + * @return string rendering of the actual, underlying + * implementation value, as \c h:m:s:ms + */ + Time::operator string() const + { + return string (lumiera_tmpbuf_print_time (t_)); + } + + + }} // namespace lib::Time ///////////////////////////////////////////////////////////////////////////TODO leftover of the existing/initial lumitime-Implementation diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index 363fd4d6d..5e0e6f28a 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -93,6 +93,10 @@ namespace time { /** a mutable time value, * behaving like a plain number, * allowing copy and re-accessing + * @note supports scaling by a factor, + * which \em deliberately is chosen + * as int, not gavl_time_t, because the + * multiplying times is meaningless. */ class TimeVar : public TimeValue @@ -139,7 +143,10 @@ namespace time { * It may be used to relate two points in time, * or to create a modification for time-like entities. * Similar to (basic) time values, offsets can be compared, - * but are otherwise opaque and immutable. + * but are otherwise opaque and immutable. Yet they allow + * to build derived values, including + * - the \em absolute (positive) distance for this offset + * - a combined offset by chaining another offset */ class Offset : public TimeValue @@ -160,6 +167,14 @@ namespace time { { return TimeValue(std::llabs (t_)); } + + Offset + operator+ (Offset const& toChain) const + { + TimeVar distance(*this); + distance += toChain; + return Offset(distance); + } }; @@ -200,6 +215,10 @@ namespace time { : TimeValue(val) { } + Time (TimeVar const& calcResult) + : TimeValue(calcResult) + { } + Time ( long millis , uint secs , uint mins =0 @@ -240,8 +259,8 @@ namespace time { * to fully specify the temporal properties of an * object within the model. * - * Similar to Time and Duration, a TimeSpan also may - * receive an (opaque) mutation message + * Similar to Time and Duration, a TimeSpan may + * also receive an (opaque) mutation message. */ class TimeSpan : public Time @@ -253,6 +272,7 @@ namespace time { : Time(start) , dur_(length) { } + ///////////TODO creating timespans needs to be more convenient.... operator Duration() const { @@ -263,7 +283,7 @@ namespace time { getEnd() const { TimeVar startPoint (*this); - return Time(startPoint + dur_); + return (startPoint + dur_); } }; diff --git a/tests/lib/time/time-value-test.cpp b/tests/lib/time/time-value-test.cpp index d939ea525..a56d0cd93 100644 --- a/tests/lib/time/time-value-test.cpp +++ b/tests/lib/time/time-value-test.cpp @@ -26,14 +26,16 @@ #include "lib/util.hpp" #include -//#include +#include //#include +#include using boost::lexical_cast; using util::isnil; //using std::rand; -//using std::cout; -//using std::endl; +using std::cout; +using std::endl; +using std::string; namespace lib { @@ -53,7 +55,7 @@ namespace test{ random_or_get (Arg arg) { if (isnil(arg)) - return (rand() % 10000); + return 1 + (rand() % 10000); else return lexical_cast (arg[1]); } @@ -66,8 +68,9 @@ namespace test{ checkBasicTimeValues (ref); checkMutableTime (ref); - checkComparisons (ref); - checkComponentAccess(); + createOffsets (ref); + buildDuration (ref); + buildTimeSpan (ref); } @@ -106,6 +109,11 @@ namespace test{ } + /** @test time variables can be used for the typical calculations, + * like summing and subtracting values, as well as multiplication + * with a scale factor. Additionally, the raw time value is + * accessible by conversion. + */ void checkMutableTime (TimeValue org) { @@ -138,16 +146,77 @@ namespace test{ void - checkComparisons (TimeValue org) + createOffsets (TimeValue org) { + TimeValue four(4); + TimeValue five(5); + + Offset off5 (five); + CHECK (0 < off5); + + TimeVar point(org); + point += off5; + CHECK (org < point); + + Offset reverse(point,org); + CHECK (reverse < off5); + CHECK (reverse.abs() == off5); + + CHECK (0 == off5 + reverse); + + // chaining and copy construction + Offset off9 (off5 + Offset(four)); + CHECK (9 == off9); } void - checkComponentAccess() + buildDuration (TimeValue org) { + TimeValue zero; + TimeVar point(org); + point += TimeValue(5); + CHECK (org < point); + + Offset backwards(point,org); + CHECK (backwards < zero); + + Duration distance(backwards); + CHECK (distance > zero); + CHECK (distance == backwards.abs()); + + point = backwards; + point *= 2; + CHECK (point < zero); + CHECK (point < backwards); + + CHECK (distance + point < zero); // using the duration as offset + CHECK (distance == backwards.abs()); // while this didn't alter the duration as such } + + void + buildTimeSpan (TimeValue org) + { + TimeValue zero; + TimeValue five(5); + + TimeSpan interval (Time(org), Duration(Offset (org,five))); + + // the time span behaves like a time + CHECK (org == interval); + CHECK (string(Time(org)) == string(interval)); + + // can get the length by direct conversion + Duration theLength(interval); + CHECK (theLength == Offset(org,five).abs()); + + Time endpoint = interval.getEnd(); + CHECK (Offset(interval,endpoint) == Offset(org,five).abs()); + + cout << "Interval: " << string(interval) + << " Endpoint: " << string(endpoint) << endl; + } };