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