encoded_view_unittest.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/zucchini/encoded_view.h"
  5. #include <iterator>
  6. #include <numeric>
  7. #include <vector>
  8. #include "components/zucchini/image_index.h"
  9. #include "components/zucchini/test_disassembler.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace zucchini {
  12. namespace {
  13. constexpr size_t PADDING = kReferencePaddingProjection;
  14. template <class It1, class It2>
  15. void TestInputIterator(It1 first_expected,
  16. It1 last_expected,
  17. It2 first_input,
  18. It2 last_input) {
  19. while (first_expected != last_expected && first_input != last_input) {
  20. EXPECT_EQ(*first_expected, *first_input);
  21. ++first_expected;
  22. ++first_input;
  23. }
  24. EXPECT_EQ(last_input, first_input);
  25. EXPECT_EQ(last_expected, first_expected);
  26. }
  27. template <class It1, class It2>
  28. void TestForwardIterator(It1 first_expected,
  29. It1 last_expected,
  30. It2 first_input,
  31. It2 last_input) {
  32. TestInputIterator(first_expected, last_expected, first_input, last_input);
  33. while (first_expected != last_expected && first_input != last_input) {
  34. EXPECT_EQ(*(first_expected++), *(first_input++));
  35. }
  36. EXPECT_EQ(last_input, first_input);
  37. EXPECT_EQ(last_expected, first_expected);
  38. }
  39. template <class It1, class It2>
  40. void TestBidirectionalIterator(It1 first_expected,
  41. It1 last_expected,
  42. It2 first_input,
  43. It2 last_input) {
  44. TestForwardIterator(first_expected, last_expected, first_input, last_input);
  45. while (first_expected != last_expected && first_input != last_input) {
  46. EXPECT_EQ(*(--last_expected), *(--last_input));
  47. }
  48. EXPECT_EQ(last_input, first_input);
  49. EXPECT_EQ(last_expected, first_expected);
  50. }
  51. template <class It1, class It2>
  52. void TestRandomAccessIterator(It1 first_expected,
  53. It1 last_expected,
  54. It2 first_input,
  55. It2 last_input) {
  56. TestBidirectionalIterator(first_expected, last_expected, first_input,
  57. last_input);
  58. using difference_type = typename std::iterator_traits<It1>::difference_type;
  59. difference_type expected_size = last_expected - first_expected;
  60. difference_type input_size = last_input - first_input;
  61. EXPECT_EQ(expected_size, input_size);
  62. for (difference_type i = 0; i < expected_size; ++i) {
  63. EXPECT_EQ(*(first_expected + i), *(first_input + i));
  64. EXPECT_EQ(first_expected[i], first_input[i]);
  65. EXPECT_EQ(0 < i, first_input < first_input + i);
  66. EXPECT_EQ(0 > i, first_input > first_input + i);
  67. EXPECT_EQ(0 <= i, first_input <= first_input + i);
  68. EXPECT_EQ(0 >= i, first_input >= first_input + i);
  69. EXPECT_EQ(expected_size < i, last_input < first_input + i);
  70. EXPECT_EQ(expected_size > i, last_input > first_input + i);
  71. EXPECT_EQ(expected_size <= i, last_input <= first_input + i);
  72. EXPECT_EQ(expected_size >= i, last_input >= first_input + i);
  73. It2 input = first_input;
  74. input += i;
  75. EXPECT_EQ(*input, first_expected[i]);
  76. input -= i;
  77. EXPECT_EQ(first_input, input);
  78. input += i;
  79. EXPECT_EQ(0 < i, first_input < input);
  80. EXPECT_EQ(0 > i, first_input > input);
  81. EXPECT_EQ(0 <= i, first_input <= input);
  82. EXPECT_EQ(0 >= i, first_input >= input);
  83. EXPECT_EQ(expected_size < i, last_input < input);
  84. EXPECT_EQ(expected_size > i, last_input > input);
  85. EXPECT_EQ(expected_size <= i, last_input <= input);
  86. EXPECT_EQ(expected_size >= i, last_input >= input);
  87. }
  88. }
  89. } // namespace
  90. class EncodedViewTest : public testing::Test {
  91. protected:
  92. EncodedViewTest()
  93. : buffer_(20),
  94. image_index_(ConstBufferView(buffer_.data(), buffer_.size())) {
  95. std::iota(buffer_.begin(), buffer_.end(), 0);
  96. TestDisassembler disasm({2, TypeTag(0), PoolTag(0)},
  97. {{1, 0}, {8, 1}, {10, 2}},
  98. {4, TypeTag(1), PoolTag(0)}, {{3, 3}},
  99. {3, TypeTag(2), PoolTag(1)}, {{12, 4}, {17, 5}});
  100. image_index_.Initialize(&disasm);
  101. }
  102. void CheckView(std::vector<size_t> expected,
  103. const EncodedView& encoded_view) const {
  104. for (offset_t i = 0; i < encoded_view.size(); ++i) {
  105. EXPECT_EQ(expected[i], encoded_view.Projection(i)) << i;
  106. }
  107. TestRandomAccessIterator(expected.begin(), expected.end(),
  108. encoded_view.begin(), encoded_view.end());
  109. }
  110. std::vector<uint8_t> buffer_;
  111. ImageIndex image_index_;
  112. };
  113. TEST_F(EncodedViewTest, Unlabeled) {
  114. EncodedView encoded_view(image_index_);
  115. encoded_view.SetLabels(PoolTag(0), {0, 0, 0, 0}, 1);
  116. encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
  117. std::vector<size_t> expected = {
  118. 0, // raw
  119. kBaseReferenceProjection + 0 + 0 * 3, // ref 0
  120. PADDING,
  121. kBaseReferenceProjection + 1 + 0 * 3, // ref 1
  122. PADDING,
  123. PADDING,
  124. PADDING,
  125. 7, // raw
  126. kBaseReferenceProjection + 0 + 0 * 3, // ref 0
  127. PADDING,
  128. kBaseReferenceProjection + 0 + 0 * 3, // ref 0
  129. PADDING,
  130. kBaseReferenceProjection + 2 + 0 * 3, // ref 2
  131. PADDING,
  132. PADDING,
  133. 15, // raw
  134. 16,
  135. kBaseReferenceProjection + 2 + 0 * 3, // ref 2
  136. PADDING,
  137. PADDING,
  138. };
  139. EXPECT_EQ(kBaseReferenceProjection + 3 * 1, encoded_view.Cardinality());
  140. CheckView(expected, encoded_view);
  141. }
  142. TEST_F(EncodedViewTest, Labeled) {
  143. EncodedView encoded_view(image_index_);
  144. encoded_view.SetLabels(PoolTag(0), {0, 2, 1, 2}, 3);
  145. encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
  146. std::vector<size_t> expected = {
  147. 0, // raw
  148. kBaseReferenceProjection + 0 + 0 * 3, // ref 0
  149. PADDING,
  150. kBaseReferenceProjection + 1 + 2 * 3, // ref 1
  151. PADDING,
  152. PADDING,
  153. PADDING,
  154. 7, // raw
  155. kBaseReferenceProjection + 0 + 2 * 3, // ref 0
  156. PADDING,
  157. kBaseReferenceProjection + 0 + 1 * 3, // ref 0
  158. PADDING,
  159. kBaseReferenceProjection + 2 + 0 * 3, // ref 2
  160. PADDING,
  161. PADDING,
  162. 15, // raw
  163. 16,
  164. kBaseReferenceProjection + 2 + 0 * 3, // ref 2
  165. PADDING,
  166. PADDING,
  167. };
  168. EXPECT_EQ(kBaseReferenceProjection + 3 * 3, encoded_view.Cardinality());
  169. CheckView(expected, encoded_view);
  170. }
  171. } // namespace zucchini