| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- //
- // tape_test.cpp
- // shared_random_generator-test
- //
- // Created by Sam Jaffe on 3/19/23.
- // Copyright © 2023 Sam Jaffe. All rights reserved.
- //
- #include "random/tape.h"
- #include <cstdlib>
- #include <scope_guard/scope_guard.hpp>
- #include "random/distribution.h"
- #include "random/random.h"
- #include "xcode_gtest_helper.h"
- using testing::ElementsAre;
- using testing::FieldsAre;
- template <typename T> class Uniform : public engine::random::Uniform<T> {
- public:
- Uniform(T min, T max) : engine::random::Uniform<T>(min, max) {}
- T operator()(engine::random::Device &) const final { throw; }
- };
- 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.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.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.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.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.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(FieldsAre("iUniform[0,100]", 50),
- FieldsAre("jUniform[0,100]", 50),
- FieldsAre("dUniform[0,100)", BytesAre(50))));
- tape = engine::random::Tape(serial);
- 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.apply(Uniform(0, 100), 50);
- tape.apply(Uniform(0u, 100u), 50u);
- tape.apply(Uniform(0.0, 100.0), 50.0);
- 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(FieldsAre("iUniform[0,100]", 50),
- FieldsAre("jUniform[0,100]", 50),
- FieldsAre("dUniform[0,100)", BytesAre(50))));
- tape = engine::random::Tape(serial);
- 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) {
- engine::random::Random random;
- auto tape = std::make_shared<engine::random::Tape>();
- auto scope = random.record(tape);
- auto result = random(engine::random::Uniform(0, 100));
- EXPECT_EQ(tape->apply(engine::random::Uniform(0, 100)), result);
- }
- TEST(TapeTest, StopsRecordingOnScopeExit) {
- engine::random::Random random;
- auto tape = std::make_shared<engine::random::Tape>();
- {
- auto scope = random.record(tape);
- random(engine::random::Uniform(0, 100));
- }
- random(engine::random::Uniform(0, 100));
- EXPECT_NO_THROW(tape->apply(engine::random::Uniform(0, 100)));
- EXPECT_THROW(tape->apply(engine::random::Uniform(0, 100)), std::out_of_range);
- }
|