// // 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 #include #include "random/random.h" #include "xcode_gtest_helper.h" using testing::ElementsAre; using testing::FieldsAre; class StubDistribution : public engine::random::Distribution { public: StubDistribution(int value) : value_(value) {} result_type operator()(engine::random::Device &) const { return value_; } private: int value_; }; TEST(TapeTest, CanRecord) { engine::random::Tape tape; tape(50u); EXPECT_EQ(tape(), 50); } TEST(TapeTest, ThrowsOnOverFetch) { engine::random::Tape tape; tape(50); EXPECT_EQ(tape(), 50); EXPECT_THROW(tape(), std::out_of_range); } TEST(TapeTest, IsOrdered) { engine::random::Tape tape; tape(1); tape(2); EXPECT_EQ(tape(), 1); EXPECT_EQ(tape(), 2); } TEST(TapeTest, IsSerializable) { engine::random::Tape tape; tape(1); tape(2); tape(3); auto serial = engine::random::Tape::serial_type(tape); EXPECT_THAT(serial, ElementsAre(1, 2, 3)); tape = engine::random::Tape(serial); EXPECT_EQ(tape(), 1); EXPECT_EQ(tape(), 2); EXPECT_EQ(tape(), 3); } TEST(TapeTest, IndexNotIncludedInSerialization) { engine::random::Tape tape; tape(1); tape(2); tape(3); EXPECT_EQ(tape(), 1); EXPECT_EQ(tape(), 2); auto serial = engine::random::Tape::serial_type(tape); EXPECT_THAT(serial, ElementsAre(1, 2, 3)); tape = engine::random::Tape(serial); EXPECT_EQ(tape(), 1); EXPECT_EQ(tape(), 2); EXPECT_EQ(tape(), 3); } TEST(TapeTest, CanAttachToRandom) { engine::random::Random random; auto tape = std::make_shared(); auto scope = random.record(tape); auto result = random(StubDistribution(5)); EXPECT_EQ(result, 5); EXPECT_EQ((*tape)(), 5); } TEST(TapeTest, StopsRecordingOnScopeExit) { engine::random::Random random; auto tape = std::make_shared(); { auto scope = random.record(tape); random(StubDistribution(2)); } random(StubDistribution(1)); EXPECT_NO_THROW((*tape)()); EXPECT_THROW((*tape)(), std::out_of_range); }