203 lines
6.5 KiB
C++
203 lines
6.5 KiB
C++
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "components/zucchini/encoded_view.h"
|
|
|
|
#include <iterator>
|
|
#include <numeric>
|
|
#include <vector>
|
|
|
|
#include "components/zucchini/image_index.h"
|
|
#include "components/zucchini/test_disassembler.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace zucchini {
|
|
|
|
namespace {
|
|
|
|
constexpr size_t PADDING = kReferencePaddingProjection;
|
|
|
|
template <class It1, class It2>
|
|
void TestInputIterator(It1 first_expected,
|
|
It1 last_expected,
|
|
It2 first_input,
|
|
It2 last_input) {
|
|
while (first_expected != last_expected && first_input != last_input) {
|
|
EXPECT_EQ(*first_expected, *first_input);
|
|
++first_expected;
|
|
++first_input;
|
|
}
|
|
EXPECT_EQ(last_input, first_input);
|
|
EXPECT_EQ(last_expected, first_expected);
|
|
}
|
|
|
|
template <class It1, class It2>
|
|
void TestForwardIterator(It1 first_expected,
|
|
It1 last_expected,
|
|
It2 first_input,
|
|
It2 last_input) {
|
|
TestInputIterator(first_expected, last_expected, first_input, last_input);
|
|
|
|
while (first_expected != last_expected && first_input != last_input) {
|
|
EXPECT_EQ(*(first_expected++), *(first_input++));
|
|
}
|
|
EXPECT_EQ(last_input, first_input);
|
|
EXPECT_EQ(last_expected, first_expected);
|
|
}
|
|
|
|
template <class It1, class It2>
|
|
void TestBidirectionalIterator(It1 first_expected,
|
|
It1 last_expected,
|
|
It2 first_input,
|
|
It2 last_input) {
|
|
TestForwardIterator(first_expected, last_expected, first_input, last_input);
|
|
|
|
while (first_expected != last_expected && first_input != last_input) {
|
|
EXPECT_EQ(*(--last_expected), *(--last_input));
|
|
}
|
|
EXPECT_EQ(last_input, first_input);
|
|
EXPECT_EQ(last_expected, first_expected);
|
|
}
|
|
|
|
template <class It1, class It2>
|
|
void TestRandomAccessIterator(It1 first_expected,
|
|
It1 last_expected,
|
|
It2 first_input,
|
|
It2 last_input) {
|
|
TestBidirectionalIterator(first_expected, last_expected, first_input,
|
|
last_input);
|
|
|
|
using difference_type = typename std::iterator_traits<It1>::difference_type;
|
|
|
|
difference_type expected_size = last_expected - first_expected;
|
|
difference_type input_size = last_input - first_input;
|
|
EXPECT_EQ(expected_size, input_size);
|
|
|
|
for (difference_type i = 0; i < expected_size; ++i) {
|
|
EXPECT_EQ(*(first_expected + i), *(first_input + i));
|
|
EXPECT_EQ(first_expected[i], first_input[i]);
|
|
|
|
EXPECT_EQ(0 < i, first_input < first_input + i);
|
|
EXPECT_EQ(0 > i, first_input > first_input + i);
|
|
EXPECT_EQ(0 <= i, first_input <= first_input + i);
|
|
EXPECT_EQ(0 >= i, first_input >= first_input + i);
|
|
|
|
EXPECT_EQ(expected_size < i, last_input < first_input + i);
|
|
EXPECT_EQ(expected_size > i, last_input > first_input + i);
|
|
EXPECT_EQ(expected_size <= i, last_input <= first_input + i);
|
|
EXPECT_EQ(expected_size >= i, last_input >= first_input + i);
|
|
|
|
It2 input = first_input;
|
|
input += i;
|
|
EXPECT_EQ(*input, first_expected[i]);
|
|
input -= i;
|
|
EXPECT_EQ(first_input, input);
|
|
input += i;
|
|
|
|
EXPECT_EQ(0 < i, first_input < input);
|
|
EXPECT_EQ(0 > i, first_input > input);
|
|
EXPECT_EQ(0 <= i, first_input <= input);
|
|
EXPECT_EQ(0 >= i, first_input >= input);
|
|
|
|
EXPECT_EQ(expected_size < i, last_input < input);
|
|
EXPECT_EQ(expected_size > i, last_input > input);
|
|
EXPECT_EQ(expected_size <= i, last_input <= input);
|
|
EXPECT_EQ(expected_size >= i, last_input >= input);
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
class EncodedViewTest : public testing::Test {
|
|
protected:
|
|
EncodedViewTest()
|
|
: buffer_(20),
|
|
image_index_(ConstBufferView(buffer_.data(), buffer_.size())) {
|
|
std::iota(buffer_.begin(), buffer_.end(), 0);
|
|
TestDisassembler disasm({2, TypeTag(0), PoolTag(0)},
|
|
{{1, 0}, {8, 1}, {10, 2}},
|
|
{4, TypeTag(1), PoolTag(0)}, {{3, 3}},
|
|
{3, TypeTag(2), PoolTag(1)}, {{12, 4}, {17, 5}});
|
|
image_index_.Initialize(&disasm);
|
|
}
|
|
|
|
void CheckView(std::vector<size_t> expected,
|
|
const EncodedView& encoded_view) const {
|
|
for (offset_t i = 0; i < encoded_view.size(); ++i) {
|
|
EXPECT_EQ(expected[i], encoded_view.Projection(i)) << i;
|
|
}
|
|
TestRandomAccessIterator(expected.begin(), expected.end(),
|
|
encoded_view.begin(), encoded_view.end());
|
|
}
|
|
|
|
std::vector<uint8_t> buffer_;
|
|
ImageIndex image_index_;
|
|
};
|
|
|
|
TEST_F(EncodedViewTest, Unlabeled) {
|
|
EncodedView encoded_view(image_index_);
|
|
|
|
encoded_view.SetLabels(PoolTag(0), {0, 0, 0, 0}, 1);
|
|
encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
|
|
|
|
std::vector<size_t> expected = {
|
|
0, // raw
|
|
kBaseReferenceProjection + 0 + 0 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 1 + 0 * 3, // ref 1
|
|
PADDING,
|
|
PADDING,
|
|
PADDING,
|
|
7, // raw
|
|
kBaseReferenceProjection + 0 + 0 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 0 + 0 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 2 + 0 * 3, // ref 2
|
|
PADDING,
|
|
PADDING,
|
|
15, // raw
|
|
16,
|
|
kBaseReferenceProjection + 2 + 0 * 3, // ref 2
|
|
PADDING,
|
|
PADDING,
|
|
};
|
|
EXPECT_EQ(kBaseReferenceProjection + 3 * 1, encoded_view.Cardinality());
|
|
CheckView(expected, encoded_view);
|
|
}
|
|
|
|
TEST_F(EncodedViewTest, Labeled) {
|
|
EncodedView encoded_view(image_index_);
|
|
|
|
encoded_view.SetLabels(PoolTag(0), {0, 2, 1, 2}, 3);
|
|
encoded_view.SetLabels(PoolTag(1), {0, 0}, 1);
|
|
|
|
std::vector<size_t> expected = {
|
|
0, // raw
|
|
kBaseReferenceProjection + 0 + 0 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 1 + 2 * 3, // ref 1
|
|
PADDING,
|
|
PADDING,
|
|
PADDING,
|
|
7, // raw
|
|
kBaseReferenceProjection + 0 + 2 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 0 + 1 * 3, // ref 0
|
|
PADDING,
|
|
kBaseReferenceProjection + 2 + 0 * 3, // ref 2
|
|
PADDING,
|
|
PADDING,
|
|
15, // raw
|
|
16,
|
|
kBaseReferenceProjection + 2 + 0 * 3, // ref 2
|
|
PADDING,
|
|
PADDING,
|
|
};
|
|
EXPECT_EQ(kBaseReferenceProjection + 3 * 3, encoded_view.Cardinality());
|
|
CheckView(expected, encoded_view);
|
|
}
|
|
|
|
} // namespace zucchini
|