blob: 96d9dc4d600197e212a423641aa87658e376ff76 [file] [log] [blame]
Samuel Huang06f1ae92018-03-13 18:19:34 +00001// 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
5#include "components/zucchini/encoded_view.h"
6
7#include <iterator>
8#include <numeric>
9#include <vector>
10
11#include "components/zucchini/image_index.h"
12#include "components/zucchini/test_disassembler.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace zucchini {
16
17namespace {
18
19constexpr size_t PADDING = kReferencePaddingProjection;
20
21template <class It1, class It2>
22void TestInputIterator(It1 first_expected,
23 It1 last_expected,
24 It2 first_input,
25 It2 last_input) {
26 while (first_expected != last_expected && first_input != last_input) {
27 EXPECT_EQ(*first_expected, *first_input);
28 ++first_expected;
29 ++first_input;
30 }
31 EXPECT_EQ(last_input, first_input);
32 EXPECT_EQ(last_expected, first_expected);
33}
34
35template <class It1, class It2>
36void TestForwardIterator(It1 first_expected,
37 It1 last_expected,
38 It2 first_input,
39 It2 last_input) {
40 TestInputIterator(first_expected, last_expected, first_input, last_input);
41
42 while (first_expected != last_expected && first_input != last_input) {
43 EXPECT_EQ(*(first_expected++), *(first_input++));
44 }
45 EXPECT_EQ(last_input, first_input);
46 EXPECT_EQ(last_expected, first_expected);
47}
48
49template <class It1, class It2>
50void TestBidirectionalIterator(It1 first_expected,
51 It1 last_expected,
52 It2 first_input,
53 It2 last_input) {
54 TestForwardIterator(first_expected, last_expected, first_input, last_input);
55
56 while (first_expected != last_expected && first_input != last_input) {
57 EXPECT_EQ(*(--last_expected), *(--last_input));
58 }
59 EXPECT_EQ(last_input, first_input);
60 EXPECT_EQ(last_expected, first_expected);
61}
62
63template <class It1, class It2>
64void TestRandomAccessIterator(It1 first_expected,
65 It1 last_expected,
66 It2 first_input,
67 It2 last_input) {
68 TestBidirectionalIterator(first_expected, last_expected, first_input,
69 last_input);
70
71 using difference_type = typename std::iterator_traits<It1>::difference_type;
72
73 difference_type expected_size = last_expected - first_expected;
74 difference_type input_size = last_input - first_input;
75 EXPECT_EQ(expected_size, input_size);
76
77 for (difference_type i = 0; i < expected_size; ++i) {
78 EXPECT_EQ(*(first_expected + i), *(first_input + i));
79 EXPECT_EQ(first_expected[i], first_input[i]);
80
81 EXPECT_EQ(0 < i, first_input < first_input + i);
82 EXPECT_EQ(0 > i, first_input > first_input + i);
83 EXPECT_EQ(0 <= i, first_input <= first_input + i);
84 EXPECT_EQ(0 >= i, first_input >= first_input + i);
85
86 EXPECT_EQ(expected_size < i, last_input < first_input + i);
87 EXPECT_EQ(expected_size > i, last_input > first_input + i);
88 EXPECT_EQ(expected_size <= i, last_input <= first_input + i);
89 EXPECT_EQ(expected_size >= i, last_input >= first_input + i);
90
91 It2 input = first_input;
92 input += i;
93 EXPECT_EQ(*input, first_expected[i]);
94 input -= i;
95 EXPECT_EQ(first_input, input);
96 input += i;
97
98 EXPECT_EQ(0 < i, first_input < input);
99 EXPECT_EQ(0 > i, first_input > input);
100 EXPECT_EQ(0 <= i, first_input <= input);
101 EXPECT_EQ(0 >= i, first_input >= input);
102
103 EXPECT_EQ(expected_size < i, last_input < input);
104 EXPECT_EQ(expected_size > i, last_input > input);
105 EXPECT_EQ(expected_size <= i, last_input <= input);
106 EXPECT_EQ(expected_size >= i, last_input >= input);
107 }
108}
109
110} // namespace
111
112class EncodedViewTest : public testing::Test {
113 protected:
114 EncodedViewTest()
115 : buffer_(20),
116 image_index_(ConstBufferView(buffer_.data(), buffer_.size())) {
117 std::iota(buffer_.begin(), buffer_.end(), 0);
118 TestDisassembler disasm({2, TypeTag(0), PoolTag(0)},
119 {{1, 0}, {8, 1}, {10, 2}},
120 {4, TypeTag(1), PoolTag(0)}, {{3, 3}},
121 {3, TypeTag(2), PoolTag(1)}, {{12, 4}, {17, 5}});
122 image_index_.Initialize(&disasm);
123 }
124
125 void CheckView(std::vector<size_t> expected,
126 const EncodedView& encoded_view) const {
127 for (offset_t i = 0; i < encoded_view.size(); ++i) {
128 EXPECT_EQ(expected[i], encoded_view.Projection(i)) << i;
129 }
130 TestRandomAccessIterator(expected.begin(), expected.end(),
131 encoded_view.begin(), encoded_view.end());
132 }
133
134 std::vector<uint8_t> buffer_;
135 ImageIndex image_index_;
136};
137
138TEST_F(EncodedViewTest, Unlabeled) {
139 EncodedView encoded_view(image_index_);
140
141 encoded_view.SetLabels(PoolTag(0), {0, 0, 0, 0}, 1);
142 encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
143
144 std::vector<size_t> expected = {
145 0, // raw
146 kBaseReferenceProjection + 0 + 0 * 3, // ref 0
147 PADDING,
148 kBaseReferenceProjection + 1 + 0 * 3, // ref 1
149 PADDING,
150 PADDING,
151 PADDING,
152 7, // raw
153 kBaseReferenceProjection + 0 + 0 * 3, // ref 0
154 PADDING,
155 kBaseReferenceProjection + 0 + 0 * 3, // ref 0
156 PADDING,
157 kBaseReferenceProjection + 2 + 0 * 3, // ref 2
158 PADDING,
159 PADDING,
160 15, // raw
161 16,
162 kBaseReferenceProjection + 2 + 0 * 3, // ref 2
163 PADDING,
164 PADDING,
165 };
166 EXPECT_EQ(kBaseReferenceProjection + 3 * 1, encoded_view.Cardinality());
167 CheckView(expected, encoded_view);
168}
169
170TEST_F(EncodedViewTest, Labeled) {
171 EncodedView encoded_view(image_index_);
172
173 encoded_view.SetLabels(PoolTag(0), {0, 2, 1, 2}, 3);
174 encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
175
176 std::vector<size_t> expected = {
177 0, // raw
178 kBaseReferenceProjection + 0 + 0 * 3, // ref 0
179 PADDING,
180 kBaseReferenceProjection + 1 + 2 * 3, // ref 1
181 PADDING,
182 PADDING,
183 PADDING,
184 7, // raw
185 kBaseReferenceProjection + 0 + 2 * 3, // ref 0
186 PADDING,
187 kBaseReferenceProjection + 0 + 1 * 3, // ref 0
188 PADDING,
189 kBaseReferenceProjection + 2 + 0 * 3, // ref 2
190 PADDING,
191 PADDING,
192 15, // raw
193 16,
194 kBaseReferenceProjection + 2 + 0 * 3, // ref 2
195 PADDING,
196 PADDING,
197 };
198 EXPECT_EQ(kBaseReferenceProjection + 3 * 3, encoded_view.Cardinality());
199 CheckView(expected, encoded_view);
200}
201
202} // namespace zucchini