// // 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 "random/random.h" #include "xcode_gtest_helper.h" using testing::ElementsAre; using testing::FieldsAre; TEST(TapeTest, CanRecordIntData) { engine::random::Tape tape; tape.exclusive(100u, 50); EXPECT_EQ(tape.exclusive(100), 50); } TEST(TapeTest, CanRecordDoubleData) { engine::random::Tape tape; tape.exclusive(0.0, 100.0, 50.0); EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0); tape.inclusive(0.0, 100.0, 50.0); EXPECT_EQ(tape.inclusive(0.0, 100.0), 50.0); } TEST(TapeTest, ThrowsOnOverFetch) { engine::random::Tape tape; tape.exclusive(100u, 50); EXPECT_EQ(tape.exclusive(100), 50); EXPECT_THROW(tape.exclusive(100), std::out_of_range); } TEST(TapeTest, BadRequestIsNoOp) { engine::random::Tape tape; tape.exclusive(100u, 50); EXPECT_ANY_THROW(tape.exclusive(1)); EXPECT_EQ(tape.exclusive(100), 50); } TEST(TapeTest, ThrowsOnTypeMismatch) { engine::random::Tape tape; tape.exclusive(100u, 50); EXPECT_THROW(tape.exclusive(0.0, 100.0), std::domain_error); } TEST(TapeTest, ThrowsOnInclusiveExclusiveMismatch) { engine::random::Tape tape; tape.exclusive(0.0, 100.0, 50.0); EXPECT_THROW(tape.inclusive(0.0, 100.0), std::domain_error); } TEST(TapeTest, ThrowsOnBoundsMismatch) { engine::random::Tape tape; tape.exclusive(0.0, 100.0, 50.0); EXPECT_THROW(tape.exclusive(0.0, 1.0), std::logic_error); } TEST(TapeTest, IsOrdered) { engine::random::Tape tape; tape.exclusive(0.0, 100.0, 50.0); tape.inclusive(0.0, 100.0, 50.0); EXPECT_THROW(tape.inclusive(0.0, 100.0), std::domain_error); EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0); EXPECT_EQ(tape.inclusive(0.0, 100.0), 50.0); } TEST(TapeTest, IsSerializable) { engine::random::Tape tape; tape.exclusive(100u, 50); tape.exclusive(0.0, 100.0, 50.0); tape.inclusive(0.0, 100.0, 50.0); auto serial = engine::random::Tape::serial_type(tape); EXPECT_THAT(serial, ElementsAre(FieldsAre(true, "j", 0, 100, 50), FieldsAre(true, "d", 0, 100, 50), FieldsAre(false, "d", 0, 100, 50))); tape = engine::random::Tape(serial); EXPECT_EQ(tape.exclusive(100), 50); EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0); EXPECT_EQ(tape.inclusive(0.0, 100.0), 50.0); } TEST(TapeTest, IndexNotIncludedInSerialization) { engine::random::Tape tape; tape.exclusive(100u, 50); tape.exclusive(0.0, 100.0, 50.0); tape.inclusive(0.0, 100.0, 50.0); EXPECT_EQ(tape.exclusive(100), 50); EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0); auto serial = engine::random::Tape::serial_type(tape); EXPECT_THAT(serial, ElementsAre(FieldsAre(true, "j", 0, 100, 50), FieldsAre(true, "d", 0, 100, 50), FieldsAre(false, "d", 0, 100, 50))); tape = engine::random::Tape(serial); EXPECT_EQ(tape.exclusive(100), 50); EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0); EXPECT_EQ(tape.inclusive(0.0, 100.0), 50.0); } TEST(TapeTest, CanAttachToRandom) { engine::random::Random random; auto tape = std::make_shared(); auto scope = random.record(tape); auto result = random.exclusive(100); EXPECT_EQ(tape->exclusive(100), result); } TEST(TapeTest, StopsRecordingOnScopeExit) { engine::random::Random random; auto tape = std::make_shared(); { auto scope = random.record(tape); random.exclusive(100); } random.exclusive(100); EXPECT_NO_THROW(tape->exclusive(100)); EXPECT_THROW(tape->exclusive(100), std::out_of_range); }