// Copyright 2013 The Flutter 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 #include #include "flutter/fml/macros.h" #include "flutter/testing/testing.h" #include "impeller/archivist/archive.h" #include "impeller/archivist/archive_location.h" #include "impeller/archivist/archivist_fixture.h" // TODO(zanderso): https://github.com/flutter/flutter/issues/127701 // NOLINTBEGIN(bugprone-unchecked-optional-access) namespace impeller { namespace testing { static int64_t LastSample = 0; class Sample : public Archivable { public: explicit Sample(uint64_t count = 42) : some_data_(count) {} Sample(Sample&&) = default; uint64_t GetSomeData() const { return some_data_; } // |Archivable| PrimaryKey GetPrimaryKey() const override { return name_; } // |Archivable| bool Write(ArchiveLocation& item) const override { return item.Write("some_data", some_data_); }; // |Archivable| bool Read(ArchiveLocation& item) override { name_ = item.GetPrimaryKey(); return item.Read("some_data", some_data_); }; static const ArchiveDef kArchiveDefinition; private: uint64_t some_data_; PrimaryKey name_ = ++LastSample; FML_DISALLOW_COPY_AND_ASSIGN(Sample); }; const ArchiveDef Sample::kArchiveDefinition = { .table_name = "Sample", .members = {"some_data"}, }; class SampleWithVector : public Archivable { public: SampleWithVector() = default; // |Archivable| PrimaryKey GetPrimaryKey() const override { return std::nullopt; } // |Archivable| bool Write(ArchiveLocation& item) const override { std::vector samples; for (size_t i = 0; i < 50u; i++) { samples.emplace_back(Sample{1988 + i}); } return item.Write("hello", "world") && item.Write("samples", samples); }; // |Archivable| bool Read(ArchiveLocation& item) override { std::string str; auto str_result = item.Read("hello", str); std::vector samples; auto vec_result = item.Read("samples", samples); if (!str_result || str != "world" || !vec_result || samples.size() != 50) { return false; } size_t current = 1988; for (const auto& sample : samples) { if (sample.GetSomeData() != current++) { return false; } } return true; }; static const ArchiveDef kArchiveDefinition; private: std::vector samples_; FML_DISALLOW_COPY_AND_ASSIGN(SampleWithVector); }; const ArchiveDef SampleWithVector::kArchiveDefinition = { .table_name = "SampleWithVector", .members = {"hello", "samples"}, }; using ArchiveTest = ArchivistFixture; TEST_F(ArchiveTest, SimpleInitialization) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); } TEST_F(ArchiveTest, AddStorageClass) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); } TEST_F(ArchiveTest, AddData) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); Sample sample; ASSERT_TRUE(archive.Write(sample)); } TEST_F(ArchiveTest, AddDataMultiple) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); for (size_t i = 0; i < 100; i++) { Sample sample(i + 1); ASSERT_TRUE(archive.Write(sample)); } } TEST_F(ArchiveTest, ReadData) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); size_t count = 50; std::vector keys; std::vector values; for (size_t i = 0; i < count; i++) { Sample sample(i + 1); keys.push_back(sample.GetPrimaryKey().value()); values.push_back(sample.GetSomeData()); ASSERT_TRUE(archive.Write(sample)); } for (size_t i = 0; i < count; i++) { Sample sample; ASSERT_TRUE(archive.Read(keys[i], sample)); ASSERT_EQ(values[i], sample.GetSomeData()); } } TEST_F(ArchiveTest, ReadDataWithNames) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); size_t count = 8; std::vector keys; std::vector values; keys.reserve(count); values.reserve(count); for (size_t i = 0; i < count; i++) { Sample sample(i + 1); keys.push_back(sample.GetPrimaryKey().value()); values.push_back(sample.GetSomeData()); ASSERT_TRUE(archive.Write(sample)); } for (size_t i = 0; i < count; i++) { Sample sample; ASSERT_TRUE(archive.Read(keys[i], sample)); ASSERT_EQ(values[i], sample.GetSomeData()); ASSERT_EQ(keys[i], sample.GetPrimaryKey()); } } TEST_F(ArchiveTest, CanReadWriteVectorOfArchivables) { Archive archive(GetArchiveFileName().c_str()); ASSERT_TRUE(archive.IsValid()); SampleWithVector sample_with_vector; ASSERT_TRUE(archive.Write(sample_with_vector)); bool read_success = false; ASSERT_EQ( archive.Read([&](ArchiveLocation& location) -> bool { SampleWithVector other_sample_with_vector; read_success = other_sample_with_vector.Read(location); return true; // Always keep continuing but assert that we only get one. }), 1u); ASSERT_TRUE(read_success); } } // namespace testing } // namespace impeller // NOLINTEND(bugprone-unchecked-optional-access)