|
|
@@ -12,6 +12,7 @@
|
|
|
|
|
|
#include <scope_guard/scope_guard.hpp>
|
|
|
|
|
|
+#include "random/distribution.h"
|
|
|
#include "random/random.h"
|
|
|
|
|
|
#include "xcode_gtest_helper.h"
|
|
|
@@ -19,69 +20,109 @@
|
|
|
using testing::ElementsAre;
|
|
|
using testing::FieldsAre;
|
|
|
|
|
|
-class StubDistribution : public engine::random::Distribution<int> {
|
|
|
+template <typename T> class Uniform : public engine::random::Uniform<T> {
|
|
|
public:
|
|
|
- StubDistribution(int value) : value_(value) {}
|
|
|
- result_type operator()(engine::random::Device &) const { return value_; }
|
|
|
+ Uniform(T min, T max) : engine::random::Uniform<T>(min, max) {}
|
|
|
|
|
|
-private:
|
|
|
- int value_;
|
|
|
+ T operator()(engine::random::Device &) const final { throw; }
|
|
|
};
|
|
|
|
|
|
-TEST(TapeTest, CanRecord) {
|
|
|
+MATCHER_P(BytesAre, value, "") {
|
|
|
+ *result_listener << "whose bytes are " << std::hex << arg;
|
|
|
+ return reinterpret_cast<double const &>(arg) == value;
|
|
|
+}
|
|
|
+
|
|
|
+TEST(TapeTest, CanRecordIntData) {
|
|
|
engine::random::Tape tape;
|
|
|
|
|
|
- tape(50u);
|
|
|
- EXPECT_EQ(tape(), 50);
|
|
|
+ tape.apply(Uniform(0u, 100u), 50u);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0u, 100u)), 50);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(TapeTest, CanRecordDoubleData) {
|
|
|
+ engine::random::Tape tape;
|
|
|
+
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0.0, 100.0)), 50.0);
|
|
|
+
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0.0, 100.0)), 50.0);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, ThrowsOnOverFetch) {
|
|
|
engine::random::Tape tape;
|
|
|
- tape(50);
|
|
|
- EXPECT_EQ(tape(), 50);
|
|
|
- EXPECT_THROW(tape(), std::out_of_range);
|
|
|
+ tape.apply(Uniform(0, 100), 50);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0, 100)), 50);
|
|
|
+ EXPECT_THROW(tape.apply(Uniform(0, 100)), std::out_of_range);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(TapeTest, BadRequestIsNoOp) {
|
|
|
+ engine::random::Tape tape;
|
|
|
+ tape.apply(Uniform(0, 100), 50);
|
|
|
+ EXPECT_ANY_THROW(tape.apply(Uniform(0, 1)));
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0, 100)), 50);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(TapeTest, ThrowsOnTypeMismatch) {
|
|
|
+ engine::random::Tape tape;
|
|
|
+ tape.apply(Uniform(0u, 100u), 50u);
|
|
|
+ EXPECT_THROW(tape.apply(Uniform(0.0, 100.0)), std::logic_error);
|
|
|
+ EXPECT_THROW(tape.apply(Uniform(0, 100)), std::logic_error);
|
|
|
+ EXPECT_NO_THROW(tape.apply(Uniform(0u, 100u)));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(TapeTest, ThrowsOnBoundsMismatch) {
|
|
|
+ engine::random::Tape tape;
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
+ EXPECT_THROW(tape.apply(Uniform(0.0, 1.0)), std::logic_error);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, IsOrdered) {
|
|
|
engine::random::Tape tape;
|
|
|
- tape(1);
|
|
|
- tape(2);
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
+ tape.apply(Uniform(10.0, 90.0), 50.0);
|
|
|
+
|
|
|
+ EXPECT_THROW(tape.apply(Uniform(10.0, 90.0)), std::logic_error);
|
|
|
|
|
|
- EXPECT_EQ(tape(), 1);
|
|
|
- EXPECT_EQ(tape(), 2);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0.0, 100.0)), 50.0);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(10.0, 90.0)), 50.0);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, IsSerializable) {
|
|
|
engine::random::Tape tape;
|
|
|
- tape(1);
|
|
|
- tape(2);
|
|
|
- tape(3);
|
|
|
+ tape.apply(Uniform(0, 100), 50);
|
|
|
+ tape.apply(Uniform(0u, 100u), 50u);
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
|
|
|
auto serial = engine::random::Tape::serial_type(tape);
|
|
|
- EXPECT_THAT(serial, ElementsAre(1, 2, 3));
|
|
|
+ EXPECT_THAT(serial, ElementsAre(FieldsAre("iUniform[0,100]", 50),
|
|
|
+ FieldsAre("jUniform[0,100]", 50),
|
|
|
+ FieldsAre("dUniform[0,100)", BytesAre(50))));
|
|
|
|
|
|
tape = engine::random::Tape(serial);
|
|
|
- EXPECT_EQ(tape(), 1);
|
|
|
- EXPECT_EQ(tape(), 2);
|
|
|
- EXPECT_EQ(tape(), 3);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0, 100)), 50);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0u, 100u)), 50u);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0.0, 100.0)), 50.0);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, IndexNotIncludedInSerialization) {
|
|
|
engine::random::Tape tape;
|
|
|
- tape(1);
|
|
|
- tape(2);
|
|
|
- tape(3);
|
|
|
+ tape.apply(Uniform(0, 100), 50);
|
|
|
+ tape.apply(Uniform(0u, 100u), 50u);
|
|
|
+ tape.apply(Uniform(0.0, 100.0), 50.0);
|
|
|
|
|
|
- EXPECT_EQ(tape(), 1);
|
|
|
- EXPECT_EQ(tape(), 2);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0, 100)), 50);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0u, 100u)), 50u);
|
|
|
|
|
|
auto serial = engine::random::Tape::serial_type(tape);
|
|
|
- EXPECT_THAT(serial, ElementsAre(1, 2, 3));
|
|
|
+ EXPECT_THAT(serial, ElementsAre(FieldsAre("iUniform[0,100]", 50),
|
|
|
+ FieldsAre("jUniform[0,100]", 50),
|
|
|
+ FieldsAre("dUniform[0,100)", BytesAre(50))));
|
|
|
|
|
|
tape = engine::random::Tape(serial);
|
|
|
- EXPECT_EQ(tape(), 1);
|
|
|
- EXPECT_EQ(tape(), 2);
|
|
|
- EXPECT_EQ(tape(), 3);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0, 100)), 50);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0u, 100u)), 50u);
|
|
|
+ EXPECT_EQ(tape.apply(Uniform(0.0, 100.0)), 50.0);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, CanAttachToRandom) {
|
|
|
@@ -90,9 +131,8 @@ TEST(TapeTest, CanAttachToRandom) {
|
|
|
|
|
|
auto scope = random.record(tape);
|
|
|
|
|
|
- auto result = random(StubDistribution(5));
|
|
|
- EXPECT_EQ(result, 5);
|
|
|
- EXPECT_EQ((*tape)(), 5);
|
|
|
+ auto result = random(engine::random::Uniform(0, 100));
|
|
|
+ EXPECT_EQ(tape->apply(engine::random::Uniform(0, 100)), result);
|
|
|
}
|
|
|
|
|
|
TEST(TapeTest, StopsRecordingOnScopeExit) {
|
|
|
@@ -101,10 +141,10 @@ TEST(TapeTest, StopsRecordingOnScopeExit) {
|
|
|
|
|
|
{
|
|
|
auto scope = random.record(tape);
|
|
|
- random(StubDistribution(2));
|
|
|
+ random(engine::random::Uniform(0, 100));
|
|
|
}
|
|
|
- random(StubDistribution(1));
|
|
|
+ random(engine::random::Uniform(0, 100));
|
|
|
|
|
|
- EXPECT_NO_THROW((*tape)());
|
|
|
- EXPECT_THROW((*tape)(), std::out_of_range);
|
|
|
+ EXPECT_NO_THROW(tape->apply(engine::random::Uniform(0, 100)));
|
|
|
+ EXPECT_THROW(tape->apply(engine::random::Uniform(0, 100)), std::out_of_range);
|
|
|
}
|