tape_test.cxx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //
  2. // tape_test.cpp
  3. // shared_random_generator-test
  4. //
  5. // Created by Sam Jaffe on 3/19/23.
  6. // Copyright © 2023 Sam Jaffe. All rights reserved.
  7. //
  8. #include "random/tape.h"
  9. #include <cstdlib>
  10. #include <scope_guard/scope_guard.hpp>
  11. #include "random/random.h"
  12. #include "xcode_gtest_helper.h"
  13. using testing::ElementsAre;
  14. using testing::FieldsAre;
  15. MATCHER_P(BytesAre, value, "") {
  16. *result_listener << "whose bytes are " << std::hex << arg;
  17. return reinterpret_cast<double const &>(arg) == value;
  18. }
  19. TEST(TapeTest, CanRecordIntData) {
  20. engine::random::Tape tape;
  21. tape.inclusive(0u, 100u, 50u);
  22. EXPECT_EQ(tape.inclusive(0u, 100u), 50);
  23. }
  24. TEST(TapeTest, CanRecordDoubleData) {
  25. engine::random::Tape tape;
  26. tape.exclusive(0.0, 100.0, 50.0);
  27. EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0);
  28. tape.exclusive(0.0, 100.0, 50.0);
  29. EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0);
  30. }
  31. TEST(TapeTest, ThrowsOnOverFetch) {
  32. engine::random::Tape tape;
  33. tape.inclusive(0, 100, 50);
  34. EXPECT_EQ(tape.inclusive(0, 100), 50);
  35. EXPECT_THROW(tape.inclusive(0, 100), std::out_of_range);
  36. }
  37. TEST(TapeTest, BadRequestIsNoOp) {
  38. engine::random::Tape tape;
  39. tape.inclusive(0, 100, 50);
  40. EXPECT_ANY_THROW(tape.inclusive(0, 1));
  41. EXPECT_EQ(tape.inclusive(0, 100), 50);
  42. }
  43. TEST(TapeTest, ThrowsOnTypeMismatch) {
  44. engine::random::Tape tape;
  45. tape.inclusive(0u, 100u, 50u);
  46. EXPECT_THROW(tape.exclusive(0.0, 100.0), std::domain_error);
  47. EXPECT_THROW(tape.inclusive(0, 100), std::domain_error);
  48. EXPECT_NO_THROW(tape.inclusive(0u, 100u));
  49. }
  50. TEST(TapeTest, ThrowsOnBoundsMismatch) {
  51. engine::random::Tape tape;
  52. tape.exclusive(0.0, 100.0, 50.0);
  53. EXPECT_THROW(tape.exclusive(0.0, 1.0), std::logic_error);
  54. }
  55. TEST(TapeTest, IsOrdered) {
  56. engine::random::Tape tape;
  57. tape.exclusive(0.0, 100.0, 50.0);
  58. tape.exclusive(10.0, 90.0, 50.0);
  59. EXPECT_THROW(tape.exclusive(10.0, 90.0), std::logic_error);
  60. EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0);
  61. EXPECT_EQ(tape.exclusive(10.0, 90.0), 50.0);
  62. }
  63. TEST(TapeTest, IsSerializable) {
  64. engine::random::Tape tape;
  65. tape.inclusive(0, 100, 50);
  66. tape.inclusive(0u, 100u, 50u);
  67. tape.exclusive(0.0, 100.0, 50.0);
  68. auto serial = engine::random::Tape::serial_type(tape);
  69. EXPECT_THAT(
  70. serial,
  71. ElementsAre(FieldsAre("i", 0, 100, 50), FieldsAre("j", 0, 100, 50),
  72. FieldsAre("d", BytesAre(0), BytesAre(100), BytesAre(50))));
  73. tape = engine::random::Tape(serial);
  74. EXPECT_EQ(tape.inclusive(0, 100), 50);
  75. EXPECT_EQ(tape.inclusive(0u, 100u), 50u);
  76. EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0);
  77. }
  78. TEST(TapeTest, IndexNotIncludedInSerialization) {
  79. engine::random::Tape tape;
  80. tape.inclusive(0, 100, 50);
  81. tape.inclusive(0u, 100u, 50u);
  82. tape.exclusive(0.0, 100.0, 50.0);
  83. EXPECT_EQ(tape.inclusive(0, 100), 50);
  84. EXPECT_EQ(tape.inclusive(0u, 100u), 50u);
  85. auto serial = engine::random::Tape::serial_type(tape);
  86. EXPECT_THAT(
  87. serial,
  88. ElementsAre(FieldsAre("i", 0, 100, 50), FieldsAre("j", 0, 100, 50),
  89. FieldsAre("d", BytesAre(0), BytesAre(100), BytesAre(50))));
  90. tape = engine::random::Tape(serial);
  91. EXPECT_EQ(tape.inclusive(0, 100), 50);
  92. EXPECT_EQ(tape.inclusive(0u, 100u), 50u);
  93. EXPECT_EQ(tape.exclusive(0.0, 100.0), 50.0);
  94. }
  95. TEST(TapeTest, CanAttachToRandom) {
  96. engine::random::Random random;
  97. auto tape = std::make_shared<engine::random::Tape>();
  98. auto scope = random.record(tape);
  99. auto result = random.inclusive(0, 100);
  100. EXPECT_EQ(tape->inclusive(0, 100), result);
  101. }
  102. TEST(TapeTest, StopsRecordingOnScopeExit) {
  103. engine::random::Random random;
  104. auto tape = std::make_shared<engine::random::Tape>();
  105. {
  106. auto scope = random.record(tape);
  107. random.inclusive(0, 100);
  108. }
  109. random.inclusive(0, 100);
  110. EXPECT_NO_THROW(tape->inclusive(0, 100));
  111. EXPECT_THROW(tape->inclusive(0, 100), std::out_of_range);
  112. }