/vm/test/test_bytearray.hpp

https://github.com/leocassarani/rubinius · C++ Header · 202 lines · 166 code · 36 blank · 0 comment · 5 complexity · ebe8f869592172ff4c354b194e214e8c MD5 · raw file

  1. #include "vm/test/test.hpp"
  2. #include "vm/object_utils.hpp"
  3. #include "builtin/bytearray.hpp"
  4. #include "builtin/exception.hpp"
  5. #include "builtin/string.hpp"
  6. #include "primitives.hpp"
  7. class TestByteArray : public CxxTest::TestSuite, public VMTest {
  8. public:
  9. void setUp() {
  10. create();
  11. }
  12. void tearDown() {
  13. destroy();
  14. }
  15. ByteArray* new_bytearray(const char* str, int size = 0) {
  16. if(size == 0) size = strlen(str);
  17. ByteArray* b = ByteArray::create(state, size);
  18. memcpy(b->raw_bytes(), str, size);
  19. return b;
  20. }
  21. void test_create() {
  22. size_t mag = sizeof(Object*);
  23. ByteArray* b;
  24. b = ByteArray::create(state, 0);
  25. TS_ASSERT_EQUALS(b->size(state)->to_native(), (native_int)0);
  26. for(size_t i = 1; i <= mag; i++) {
  27. b = ByteArray::create(state, i);
  28. TS_ASSERT_EQUALS(b->size(state)->to_native(), (native_int)mag);
  29. }
  30. for(size_t i = mag + 1; i <= 2 * mag; i++) {
  31. b = ByteArray::create(state, i);
  32. TS_ASSERT_EQUALS(b->size(state)->to_native(), (native_int)(2 * mag));
  33. }
  34. for(size_t i = 5 * mag + 1; i <= 6 * mag; i++) {
  35. b = ByteArray::create(state, i);
  36. TS_ASSERT_EQUALS(b->size(state)->to_native(), (native_int)(6 * mag));
  37. }
  38. }
  39. void test_allocate() {
  40. ByteArray* b = ByteArray::allocate(state, Fixnum::from(5));
  41. TS_ASSERT_EQUALS(b->size(state)->to_native(), 8);
  42. }
  43. void test_size() {
  44. ByteArray* b = ByteArray::create(state, 1);
  45. TS_ASSERT_EQUALS(b->size(state), Fixnum::from(sizeof(Object*)));
  46. }
  47. void test_get_byte() {
  48. ByteArray* b = new_bytearray("xyz");
  49. TS_ASSERT_EQUALS(b->get_byte(state, Fixnum::from(0)), Fixnum::from('x'));
  50. TS_ASSERT_EQUALS(b->get_byte(state, Fixnum::from(2)), Fixnum::from('z'));
  51. }
  52. void test_get_byte_index_out_of_bounds() {
  53. ByteArray* b = new_bytearray("xyz");
  54. native_int sz = b->size(state)->to_native();
  55. TS_ASSERT_THROWS_ASSERT(b->get_byte(state, Fixnum::from(sz)), const RubyException &e,
  56. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  57. TS_ASSERT_THROWS_ASSERT(b->get_byte(state, Fixnum::from(sz+1)), const RubyException &e,
  58. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  59. TS_ASSERT_THROWS_ASSERT(b->get_byte(state, Fixnum::from(-1)), const RubyException &e,
  60. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  61. }
  62. void test_set_byte() {
  63. ByteArray* b = new_bytearray("xyz");
  64. b->set_byte(state, Fixnum::from(0), Fixnum::from('1'));
  65. TS_ASSERT_EQUALS(b->get_byte(state, Fixnum::from(0)), Fixnum::from('1'));
  66. b->set_byte(state, Fixnum::from(2), Fixnum::from('2'));
  67. TS_ASSERT_EQUALS(b->get_byte(state, Fixnum::from(2)), Fixnum::from('2'));
  68. }
  69. void test_set_byte_out_of_bounds() {
  70. ByteArray* b = new_bytearray("xyz");
  71. native_int sz = b->size(state)->to_native();
  72. TS_ASSERT_THROWS_ASSERT(b->set_byte(state, Fixnum::from(sz), Fixnum::from('0')),
  73. const RubyException &e,
  74. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  75. TS_ASSERT_THROWS_ASSERT(b->set_byte(state, Fixnum::from(sz+1), Fixnum::from('0')),
  76. const RubyException &e,
  77. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  78. TS_ASSERT_THROWS_ASSERT(b->set_byte(state, Fixnum::from(-1), Fixnum::from('0')),
  79. const RubyException &e,
  80. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  81. }
  82. void test_move_bytes() {
  83. ByteArray* b = new_bytearray("xyzzy");
  84. b->move_bytes(state, Fixnum::from(0), Fixnum::from(2), Fixnum::from(3));
  85. TS_ASSERT_SAME_DATA(b->raw_bytes(), "xyzxy", 5);
  86. }
  87. void test_move_bytes_out_of_bounds() {
  88. ByteArray* b = new_bytearray("xyzzy");
  89. Fixnum* neg = Fixnum::from(-1);
  90. Fixnum* one = Fixnum::from(1);
  91. Fixnum* zero = Fixnum::from(0);
  92. Fixnum* size = b->size(state);
  93. TS_ASSERT_THROWS_ASSERT(b->move_bytes(state, neg, zero, zero), const RubyException &e,
  94. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  95. TS_ASSERT_THROWS_ASSERT(b->move_bytes(state, zero, neg, zero), const RubyException &e,
  96. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  97. TS_ASSERT_THROWS_ASSERT(b->move_bytes(state, zero, zero, neg), const RubyException &e,
  98. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  99. TS_ASSERT_THROWS_ASSERT(b->move_bytes(state, zero, size, one), const RubyException &e,
  100. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  101. TS_ASSERT_THROWS_ASSERT(b->move_bytes(state, one, size, zero), const RubyException &e,
  102. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  103. }
  104. void test_fetch_bytes() {
  105. ByteArray* b = new_bytearray("xyzzy");
  106. ByteArray* ba = b->fetch_bytes(state, Fixnum::from(1), Fixnum::from(3));
  107. TS_ASSERT_SAME_DATA(ba->raw_bytes(), "yzz", 3);
  108. }
  109. void test_fetch_bytes_out_of_bounds() {
  110. ByteArray* b = new_bytearray("xyzzy");
  111. Fixnum* neg = Fixnum::from(-1);
  112. Fixnum* zero = Fixnum::from(0);
  113. Fixnum* one = Fixnum::from(1);
  114. Fixnum* size = b->size(state);
  115. TS_ASSERT_THROWS_ASSERT(b->fetch_bytes(state, neg, zero), const RubyException &e,
  116. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  117. TS_ASSERT_THROWS_ASSERT(b->fetch_bytes(state, zero, neg), const RubyException &e,
  118. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  119. TS_ASSERT_THROWS_ASSERT(b->fetch_bytes(state, one, size), const RubyException &e,
  120. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  121. }
  122. void test_compare_bytes() {
  123. ByteArray* a = new_bytearray("xyZzyx");
  124. ByteArray* b = new_bytearray("xyzzyx");
  125. Fixnum* two = Fixnum::from(2);
  126. Fixnum* three = Fixnum::from(3);
  127. Fixnum* size = Fixnum::from(8);
  128. Fixnum* size1 = Fixnum::from(9);
  129. TS_ASSERT_EQUALS(a->size(state)->to_native(), 8);
  130. TS_ASSERT_EQUALS(b->size(state)->to_native(), 8);
  131. TS_ASSERT_EQUALS(a->compare_bytes(state, b, two, two), Fixnum::from(0));
  132. TS_ASSERT_EQUALS(a->compare_bytes(state, b, two, three), Fixnum::from(-1));
  133. TS_ASSERT_EQUALS(a->compare_bytes(state, b, three, two), Fixnum::from(1));
  134. TS_ASSERT_EQUALS(a->compare_bytes(state, b, three, three), Fixnum::from(-1));
  135. TS_ASSERT_EQUALS(a->compare_bytes(state, b, size, size), Fixnum::from(-1));
  136. TS_ASSERT_EQUALS(a->compare_bytes(state, b, size1, size1), Fixnum::from(-1));
  137. }
  138. void test_compare_bytes_out_of_bounds() {
  139. ByteArray* a = new_bytearray("xyZzy");
  140. ByteArray* b = new_bytearray("xyzzy");
  141. Fixnum* zero = Fixnum::from(0);
  142. Fixnum* neg = Fixnum::from(-1);
  143. TS_ASSERT_THROWS_ASSERT(a->compare_bytes(state, b, neg, zero), const RubyException &e,
  144. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  145. TS_ASSERT_THROWS_ASSERT(a->compare_bytes(state, b, zero, neg), const RubyException &e,
  146. TS_ASSERT(Exception::object_bounds_exceeded_error_p(state, e.exception)));
  147. }
  148. void test_locate() {
  149. ByteArray* ba = String::create(state, "xyZfoo\nzyx")->data();
  150. Fixnum* size = Fixnum::from(ba->size());
  151. Fixnum* zero = Fixnum::from(0);
  152. Fixnum* three = Fixnum::from(3);
  153. Fixnum* seven = Fixnum::from(7);
  154. Fixnum* four = Fixnum::from(4);
  155. Fixnum* two = Fixnum::from(2);
  156. String* foo_nl = String::create(state, "foo\n");
  157. TS_ASSERT_EQUALS(three, ba->locate(state, String::create(state, ""), three, size));
  158. TS_ASSERT_EQUALS(cNil, ba->locate(state, String::create(state, "\n\n"), zero, size));
  159. TS_ASSERT_EQUALS(seven, ba->locate(state, String::create(state, "\n"), zero, size));
  160. TS_ASSERT_EQUALS(cNil, ba->locate(state, foo_nl, four, size));
  161. TS_ASSERT_EQUALS(seven, ba->locate(state, foo_nl, two, size));
  162. TS_ASSERT_EQUALS(seven, ba->locate(state, foo_nl, three, size));
  163. TS_ASSERT_EQUALS(Fixnum::from(10), ba->locate(state,
  164. String::create(state, "yx"), three, size));
  165. }
  166. };