finished Time tests and fixed a corner case bug
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index 0a4bf62..e098c0f 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -217,6 +217,7 @@
'<(EXTERNALS):gtest',
'time',
'<(AOS)/build/aos.gyp:logging',
+ '<(AOS)/common/util/util.gyp:death_test_log_implementation',
],
},
{
diff --git a/aos/common/time.cc b/aos/common/time.cc
index aa75eae..1c86811 100644
--- a/aos/common/time.cc
+++ b/aos/common/time.cc
@@ -142,8 +142,8 @@
}
Time &Time::operator%=(int32_t rhs) {
nsec_ = ToNSec() % rhs;
- const int wraps = nsec_ / kNSecInSec;
- sec_ = wraps;
+ const int wraps = nsec_ / ((rhs / kNSecInSec + 1) * kNSecInSec);
+ sec_ = wraps + rhs / kNSecInSec;
nsec_ -= kNSecInSec * wraps;
if (nsec_ < 0) {
nsec_ += kNSecInSec;
diff --git a/aos/common/time.h b/aos/common/time.h
index 0440d91..9c86168 100644
--- a/aos/common/time.h
+++ b/aos/common/time.h
@@ -28,7 +28,8 @@
// not implemented because I can't think of any uses for them and there are
// multiple ways to do it. Division of Times by Times is implemented as the
// ratio of them. Multiplication, division, and modulus of Times by integers are
-// implemented as interpreting the argument as nanoseconds.
+// implemented as interpreting the argument as nanoseconds. Modulus takes the
+// sign from the first operand.
struct Time {
#ifdef SWIG
// All of the uses of constexpr here can safely be simply removed.
diff --git a/aos/common/time_test.cc b/aos/common/time_test.cc
index af6db05..cc19965 100644
--- a/aos/common/time_test.cc
+++ b/aos/common/time_test.cc
@@ -3,6 +3,7 @@
#include "gtest/gtest.h"
#include "aos/common/macros.h"
+#include "aos/common/util/death_test_log_implementation.h"
namespace aos {
namespace time {
@@ -28,6 +29,21 @@
EXPECT_EQ(start.tv_usec, end.tv_usec);
}
+TEST(TimeDeathTest, ConstructorChecking) {
+ EXPECT_DEATH(
+ {
+ logging::AddImplementation(new util::DeathTestLogImplementation());
+ Time(0, -1);
+ },
+ ".*0 <= nsec\\(-1\\) < 10+ .*");
+ EXPECT_DEATH(
+ {
+ logging::AddImplementation(new util::DeathTestLogImplementation());
+ Time(0, Time::kNSecInSec);
+ },
+ ".*0 <= nsec\\(10+\\) < 10+ .*");
+}
+
// It's kind of hard not to test Now and SleepFor at the same time.
TEST(TimeTest, NowAndSleepFor) {
// without this, it tends to fail the first time (ends up sleeping for way
@@ -146,9 +162,10 @@
Time(-50, 0) % (-Time::kNSecInSec / 10 * 3));
EXPECT_EQ(Time(0, Time::kNSecInSec / 10 * 2),
Time(50, 0) % (-Time::kNSecInSec / 10 * 3));
+ EXPECT_EQ(Time(1, Time::kNSecInSec / 10),
+ Time(60, Time::kNSecInSec / 10) % (Time::kNSecInSec / 10 * 12));
}
-// TODO(brians): Finish tests for negatives from here on.
TEST(TimeTest, InSeconds) {
EXPECT_EQ(MACRO_DARG(Time(2, Time::kNSecInSec / 100 * 55 - 1)),
Time::InSeconds(2.55));