// Copyright 2019 The Amber Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or parseried. // See the License for the specific language governing permissions and // limitations under the License. #include "gtest/gtest.h" #include "src/amberscript/parser.h" namespace amber { namespace amberscript { using AmberScriptParserTest = testing::Test; class DummyDelegate : public amber::Delegate { public: DummyDelegate() = default; ~DummyDelegate() override = default; void Log(const std::string&) override {} bool LogGraphicsCalls() const override { return false; } void SetLogGraphicsCalls(bool) {} bool LogExecuteCalls() const override { return false; } void SetLogExecuteCalls(bool) {} bool LogGraphicsCallsTime() const override { return false; } void SetLogGraphicsCallsTime(bool) {} uint64_t GetTimestampNs() const override { return 0; } void SetScriptPath(std::string) {} amber::Result LoadBufferData(const std::string, amber::BufferDataFileType type, amber::BufferInfo* buffer) const override { amber::Value v; v.SetIntValue(static_cast(type)); buffer->values.push_back(v); buffer->width = 1; buffer->height = 1; return {}; } }; TEST_F(AmberScriptParserTest, BufferData) { std::string in = R"( BUFFER my_buffer DATA_TYPE uint32 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(7U, buffer->ValueCount()); EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4, 55, 99, 1234}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataStd140) { std::string in = R"( BUFFER my_buffer DATA_TYPE uint32 STD140 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(7U, buffer->ValueCount()); EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4, 55, 99, 1234}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataMatrixStd430) { std::string in = R"( BUFFER my_buffer DATA_TYPE mat2x2 STD430 DATA 1 2 3 4 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsFloat32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(4U * sizeof(float), buffer->GetSizeInBytes()); std::vector results = {1.f, 2.f, 3.f, 4.f}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_FLOAT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataMatrixStd140) { std::string in = R"( BUFFER my_buffer DATA_TYPE mat2x2 STD140 DATA 1 2 3 4 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsFloat32()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(8U * sizeof(float), buffer->GetSizeInBytes()); std::vector results = {1.f, 2.f, 0.f, 0.f, 3.f, 4.f, 0.f, 0.f}; const auto* data = buffer->GetValues(); for (size_t i = 0; i < results.size(); ++i) { EXPECT_FLOAT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataStd430) { std::string in = R"( BUFFER my_buffer DATA_TYPE uint32 STD430 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(7U, buffer->ValueCount()); EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4, 55, 99, 1234}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataArrayStd140) { std::string in = R"( BUFFER my_buffer DATA_TYPE uint32[] STD140 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(28U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 55, 0, 0, 0, 99, 0, 0, 0, 1234, 0, 0, 0}; const auto* data = buffer->GetValues(); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataArrayStd430) { std::string in = R"( BUFFER my_buffer DATA_TYPE uint32[] STD430 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(7U, buffer->ValueCount()); EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4, 55, 99, 1234}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataOneLine) { std::string in = "BUFFER my_buffer DATA_TYPE uint32 DATA 1 2 3 4 END"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(4U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferDataFloat) { std::string in = "BUFFER my_buffer DATA_TYPE float DATA 1 2 3 4 END"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->IsFloat32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(4U * sizeof(float), buffer->GetSizeInBytes()); std::vector results = {1, 2, 3, 4}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_FLOAT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferFill) { std::string in = "BUFFER my_buffer DATA_TYPE uint8 SIZE 5 FILL 5"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsUint8()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(5U, buffer->ValueCount()); EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector results = {5, 5, 5, 5, 5}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferFillFloat) { std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 5 FILL 5.2"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsFloat32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(5U, buffer->ValueCount()); EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes()); std::vector results = {5.2f, 5.2f, 5.2f, 5.2f, 5.2f}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_FLOAT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferSeries) { std::string in = "BUFFER my_buffer DATA_TYPE uint8 SIZE 5 SERIES_FROM 2 INC_BY 1"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsUint8()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(5U, buffer->ValueCount()); EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector results = {2, 3, 4, 5, 6}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferSeriesFloat) { std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 5 SERIES_FROM 2.2 INC_BY " "1.1"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsFloat32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(5U, buffer->ValueCount()); EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes()); std::vector results = {2.2f, 3.3f, 4.4f, 5.5f, 6.6f}; const auto* data = buffer->GetValues(); ASSERT_EQ(results.size(), buffer->ValueCount()); for (size_t i = 0; i < results.size(); ++i) { EXPECT_FLOAT_EQ(results[i], data[i]); } } TEST_F(AmberScriptParserTest, BufferMultipleBuffers) { std::string in = R"( BUFFER color_buffer DATA_TYPE uint8 SIZE 5 FILL 5 BUFFER storage_buffer DATA_TYPE uint32 DATA 1 2 3 4 55 99 1234 END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(2U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("color_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsUint8()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(5U, buffer->ValueCount()); EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector results0 = {5, 5, 5, 5, 5}; const auto* data0 = buffer->GetValues(); ASSERT_EQ(results0.size(), buffer->ValueCount()); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); } ASSERT_TRUE(buffers[1] != nullptr); buffer = buffers[1].get(); EXPECT_EQ("storage_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(7U, buffer->ElementCount()); EXPECT_EQ(7U, buffer->ValueCount()); EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results1 = {1, 2, 3, 4, 55, 99, 1234}; const auto* data1 = buffer->GetValues(); ASSERT_EQ(results1.size(), buffer->ValueCount()); for (size_t i = 0; i < results1.size(); ++i) { EXPECT_EQ(results1[i], data1[i]); } } TEST_F(AmberScriptParserTest, BufferFillMultiRow) { std::string in = R"( BUFFER my_index_buffer DATA_TYPE vec2 SIZE 5 FILL 2)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_index_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsInt32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(5U, buffer->ElementCount()); EXPECT_EQ(10U, buffer->ValueCount()); EXPECT_EQ(10U * sizeof(int32_t), buffer->GetSizeInBytes()); std::vector results0 = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; const auto* data0 = buffer->GetValues(); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); } } TEST_F(AmberScriptParserTest, BufferDataMultiRowStd430) { std::string in = R"( BUFFER my_index_buffer DATA_TYPE vec2 DATA 2 3 4 5 6 7 8 9 END )"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_index_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsInt32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(8U, buffer->ValueCount()); EXPECT_EQ(8U * sizeof(int32_t), buffer->GetSizeInBytes()); std::vector results0 = {2, 3, 4, 5, 6, 7, 8, 9}; const auto* data0 = buffer->GetValues(); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); } } TEST_F(AmberScriptParserTest, BufferDataMultiRowStd140) { std::string in = R"( BUFFER my_index_buffer DATA_TYPE vec2 STD140 DATA 2 3 4 5 6 7 8 9 END )"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_index_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsInt32()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(8U, buffer->ValueCount()); EXPECT_EQ(8U * sizeof(int32_t), buffer->GetSizeInBytes()); std::vector results0 = {2, 3, 4, 5, 6, 7, 8, 9}; const auto* data0 = buffer->GetValues(); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); } } TEST_F(AmberScriptParserTest, BufferDataHex) { std::string in = R"( BUFFER my_index_buffer DATA_TYPE uint32 DATA 0xff000000 0x00ff0000 0x0000ff00 0x000000ff END )"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_index_buffer", buffer->GetName()); EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(4U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector results0 = {4278190080, 16711680, 65280, 255}; const auto* data0 = buffer->GetValues(); ASSERT_EQ(results0.size(), buffer->ValueCount()); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); } } TEST_F(AmberScriptParserTest, BufferFormat) { std::string in = "BUFFER my_buf FORMAT R32G32B32A32_SINT"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buf", buffer->GetName()); auto fmt = buffer->GetFormat(); EXPECT_EQ(FormatType::kR32G32B32A32_SINT, fmt->GetFormatType()); auto& segs = fmt->GetSegments(); ASSERT_EQ(4U, segs.size()); for (size_t i = 0; i < 4; ++i) { EXPECT_EQ(segs[i].GetNumBits(), 32u); EXPECT_EQ(segs[i].GetFormatMode(), FormatMode::kSInt); EXPECT_EQ(segs[i].GetName(), static_cast(i)); } } TEST_F(AmberScriptParserTest, BufferSamples) { std::string in = "BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES 2"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buf", buffer->GetName()); EXPECT_EQ(2u, buffer->GetSamples()); } struct BufferParseError { const char* in; const char* err; }; using AmberScriptParserBufferParseErrorTest = testing::TestWithParam; TEST_P(AmberScriptParserBufferParseErrorTest, Test) { auto test_data = GetParam(); Parser parser; Result r = parser.Parse(test_data.in); ASSERT_FALSE(r.IsSuccess()) << test_data.in; EXPECT_EQ(std::string(test_data.err), r.Error()) << test_data.in; } INSTANTIATE_TEST_SUITE_P( AmberScriptParserBufferParseErrorTest, AmberScriptParserBufferParseErrorTest, testing::Values( BufferParseError{"BUFFER my_buf FORMAT 123", "1: BUFFER FORMAT must be an identifier"}, BufferParseError{"BUFFER my_buf FORMAT A23A32", "1: invalid BUFFER FORMAT"}, BufferParseError{"BUFFER my_buf FORMAT", "1: BUFFER FORMAT must be an identifier"}, BufferParseError{"BUFFER my_buffer FORMAT R32G32B32A32_SFLOAT EXTRA", "1: unknown token: EXTRA"}, BufferParseError{"BUFFER 1234 DATA_TYPE uint8 SIZE 5 FILL 5", "1: invalid BUFFER name provided"}, BufferParseError{"BUFFER DATA_TYPE uint8 SIZE 5 FILL 5", "1: missing BUFFER name"}, BufferParseError{"BUFFER my_buf 1234", "1: invalid BUFFER command provided"}, BufferParseError{"BUFFER my_buf INVALID", "1: unknown BUFFER command provided: INVALID"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE INVALID FILL 5", "1: BUFFER size invalid"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE FILL 5", "1: BUFFER size invalid"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL", "1: missing BUFFER fill value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL INVALID", "1: invalid BUFFER fill value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 INVALID 5", "1: invalid BUFFER initializer provided"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL INVALID", "1: invalid BUFFER fill value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL", "1: missing BUFFER fill value"}, BufferParseError{ "BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM INC_BY 2", "1: invalid BUFFER series_from value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM 2", "1: missing BUFFER series_from inc_by"}, BufferParseError{ "BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM 2 INC_BY", "1: missing BUFFER series_from inc_by value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 " "SERIES_FROM INVALID INC_BY 2", "1: invalid BUFFER series_from value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 " "SERIES_FROM 1 INC_BY INVALID", "1: invalid BUFFER series_from inc_by value"}, BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 " "SERIES_FROM 1 INVALID 2", "1: BUFFER series_from invalid command"}, BufferParseError{ "BUFFER my_index_buffer DATA_TYPE int32 DATA\n1.234\nEND", "2: invalid BUFFER data value: 1.234"}, BufferParseError{ "BUFFER my_index_buffer DATA_TYPE int32 DATA\nINVALID\nEND", "2: invalid BUFFER data value: INVALID"}, BufferParseError{ "BUFFER my_index_buffer DATA_TYPE int32 DATA INVALID\n123\nEND", "1: invalid BUFFER data value: INVALID"}, BufferParseError{ "BUFFER my_index_buffer DATA_TYPE int32 SIZE 256 FILL " "5 INVALID\n123\nEND", "1: extra parameters after BUFFER fill command: INVALID"}, BufferParseError{ "BUFFER my_buffer DATA_TYPE int32 SIZE 256 SERIES_FROM 2 " "INC_BY 5 " "INVALID", "1: extra parameters after BUFFER series_from command: INVALID"}, BufferParseError{"BUFFER my_buf DATA_TYPE int32 SIZE 5 FILL 5\nBUFFER " "my_buf DATA_TYPE int16 SIZE 5 FILL 2", // NOLINTNEXTLINE(whitespace/parens) "2: duplicate buffer name provided"}, BufferParseError{"BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES 9", "1: invalid sample count: 9"}, BufferParseError{"BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES foo", "1: expected integer value for SAMPLES"})); struct BufferData { const char* name; FormatMode type; size_t num_bits; size_t row_count; size_t column_count; bool is_array; }; using AmberScriptParserBufferDataTypeTest = testing::TestWithParam; TEST_P(AmberScriptParserBufferDataTypeTest, BufferTypes) { auto test_data = GetParam(); std::string in = std::string("BUFFER my_buf DATA_TYPE ") + test_data.name + " SIZE 2 FILL 5"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << test_data.name << " :" << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); auto* buffer = buffers[0].get(); auto fmt = buffer->GetFormat(); EXPECT_EQ(test_data.row_count, fmt->GetType()->RowCount()); EXPECT_EQ(test_data.column_count, fmt->GetType()->ColumnCount()); auto& seg = fmt->GetSegments()[0]; EXPECT_EQ(test_data.type, seg.GetFormatMode()); EXPECT_EQ(test_data.num_bits, seg.GetNumBits()); EXPECT_EQ(test_data.is_array, fmt->GetType()->IsArray()); } INSTANTIATE_TEST_SUITE_P( AmberScriptParserTestsDataType, AmberScriptParserBufferDataTypeTest, testing::Values( BufferData{"int8", FormatMode::kSInt, 8, 1, 1, false}, BufferData{"int16", FormatMode::kSInt, 16, 1, 1, false}, BufferData{"int32", FormatMode::kSInt, 32, 1, 1, false}, BufferData{"int64", FormatMode::kSInt, 64, 1, 1, false}, BufferData{"uint8", FormatMode::kUInt, 8, 1, 1, false}, BufferData{"uint16", FormatMode::kUInt, 16, 1, 1, false}, BufferData{"uint32", FormatMode::kUInt, 32, 1, 1, false}, BufferData{"uint64", FormatMode::kUInt, 64, 1, 1, false}, BufferData{"float", FormatMode::kSFloat, 32, 1, 1, false}, BufferData{"double", FormatMode::kSFloat, 64, 1, 1, false}, BufferData{"vec2", FormatMode::kSInt, 8, 2, 1, false}, BufferData{"vec3", FormatMode::kSFloat, 32, 3, 1, false}, BufferData{"vec4", FormatMode::kUInt, 32, 4, 1, false}, BufferData{"mat2x4", FormatMode::kSInt, 32, 4, 2, false}, BufferData{"mat3x3", FormatMode::kSFloat, 32, 3, 3, false}, BufferData{"mat4x2", FormatMode::kUInt, 16, 2, 4, false}, BufferData{"B8G8R8_UNORM", FormatMode::kUNorm, 8, 3, 1, false})); // NOLINT(whitespace/parens) INSTANTIATE_TEST_SUITE_P( AmberScriptParserTestsDataType2, AmberScriptParserBufferDataTypeTest, testing::Values( BufferData{"int8[]", FormatMode::kSInt, 8, 1, 1, true}, BufferData{"int16[]", FormatMode::kSInt, 16, 1, 1, true}, BufferData{"int32[]", FormatMode::kSInt, 32, 1, 1, true}, BufferData{"int64[]", FormatMode::kSInt, 64, 1, 1, true}, BufferData{"uint8[]", FormatMode::kUInt, 8, 1, 1, true}, BufferData{"uint16[]", FormatMode::kUInt, 16, 1, 1, true}, BufferData{"uint32[]", FormatMode::kUInt, 32, 1, 1, true}, BufferData{"uint64[]", FormatMode::kUInt, 64, 1, 1, true}, BufferData{"float[]", FormatMode::kSFloat, 32, 1, 1, true}, BufferData{"double[]", FormatMode::kSFloat, 64, 1, 1, true}, BufferData{"vec2[]", FormatMode::kSInt, 8, 2, 1, true}, BufferData{"vec3[]", FormatMode::kSFloat, 32, 3, 1, true}, BufferData{"vec4[]", FormatMode::kUInt, 32, 4, 1, true}, BufferData{"mat2x4[]", FormatMode::kSInt, 32, 4, 2, true}, BufferData{"mat3x3[]", FormatMode::kSFloat, 32, 3, 3, true}, BufferData{"mat4x2[]", FormatMode::kUInt, 16, 2, 4, true})); // NOLINT(whitespace/parens) struct NameData { const char* name; }; using AmberScriptParserBufferDataTypeInvalidTest = testing::TestWithParam; TEST_P(AmberScriptParserBufferDataTypeInvalidTest, BufferTypes) { auto test_data = GetParam(); std::string in = std::string("BUFFER my_buf DATA_TYPE ") + test_data.name + " SIZE 4 FILL 5"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << test_data.name; EXPECT_EQ( std::string("1: invalid data type '") + test_data.name + "' provided", r.Error()) << test_data.name; } INSTANTIATE_TEST_SUITE_P( AmberScriptParserBufferDataTypeInvalidTestSamples, AmberScriptParserBufferDataTypeInvalidTest, testing::Values(NameData{"int17"}, NameData{"int["}, NameData{"int]"}, NameData{"B8G8R8_UNORM[]"}, NameData{"uintt0"}, NameData{"vec7"}, NameData{"vec27"}, NameData{"vec2>"}, NameData{"vec2>"}, NameData{"vec2float>"}, NameData{"vec2"}, NameData{"vec2<>"}, NameData{"vec2"}, NameData{"mat1x1"}, NameData{"mat5x2"}, NameData{"mat2x5"}, NameData{"mat22x22"}, NameData{"matx5"}, NameData{"mat2"}, NameData{"mat2x"}, NameData{"mat2x2>"}, NameData{"mat2x2>"}, NameData{"mat2x2"}, NameData{"mat2x2"}, NameData{"mat2x2<>"})); // NOLINT(whitespace/parens) TEST_F(AmberScriptParserTest, BufferWithStructStd140) { std::string in = R"( STRUCT s uint32 d uint32 e END STRUCT my_data float a uint32 b s c END BUFFER my_buffer DATA_TYPE my_data STD140 DATA 1 # a 64 # b 128 # c.d 220 # c.e END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(32U, buffer->GetSizeInBytes()); const auto* data = buffer->GetValues(); EXPECT_FLOAT_EQ(1.f, *reinterpret_cast(data + 0)); EXPECT_EQ(64u, *reinterpret_cast(data + 4 /* sizeof(float) */)); EXPECT_EQ(128u, *reinterpret_cast(data + 16 /* 8 round -> 16 */)); EXPECT_EQ(220u, *reinterpret_cast( data + 20 /* 8 round -> 16 + 4 */)); } TEST_F(AmberScriptParserTest, BufferWithStructStd430) { std::string in = R"( STRUCT s uint32 d uint32 e END STRUCT my_data float a uint32 b s c END BUFFER my_buffer DATA_TYPE my_data STD430 DATA 1 # a 64 # b 128 # c.d 220 # c.e END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(16U, buffer->GetSizeInBytes()); const auto* data = buffer->GetValues(); EXPECT_FLOAT_EQ(1.f, *reinterpret_cast(data + 0)); EXPECT_EQ(64u, *reinterpret_cast(data + 4)); EXPECT_EQ(128u, *reinterpret_cast(data + 8)); EXPECT_EQ(220u, *reinterpret_cast(data + 12)); } TEST_F(AmberScriptParserTest, BufferWithStructAndPaddingStd430) { std::string in = R"( STRUCT s uint32 d OFFSET 8 uint32 e OFFSET 16 END STRUCT my_data float a OFFSET 8 uint32 b OFFSET 16 s c; END BUFFER my_buffer DATA_TYPE my_data STD430 DATA 1 # a 64 # b 128 # c.d 220 # c.e END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct()); EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(40U, buffer->GetSizeInBytes()); const auto* data = buffer->GetValues(); EXPECT_FLOAT_EQ(1.f, *reinterpret_cast(data + 8)); EXPECT_EQ(64u, *reinterpret_cast(data + 16)); EXPECT_EQ(128u, *reinterpret_cast(data + 28)); EXPECT_EQ(220u, *reinterpret_cast(data + 36)); } TEST_F(AmberScriptParserTest, BufferWithStructPartialInitialization) { std::string in = R"( STRUCT my_data uint32 a float b uint32 c uint32 d END BUFFER my_buffer DATA_TYPE my_data STD430 DATA 1 # a 64 # b END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("12: Mismatched number of items in buffer", r.Error()); } TEST_F(AmberScriptParserTest, BufferWithStruct_vec_Std140) { std::string in = R"( STRUCT my_data float a vec3 b END BUFFER my_buffer DATA_TYPE my_data STD140 DATA 1 # a 64 128 220 # b END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct()); EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout()); EXPECT_EQ(1U, buffer->ElementCount()); EXPECT_EQ(32U, buffer->GetSizeInBytes()); const auto* data = buffer->GetValues(); EXPECT_FLOAT_EQ(1.f, *reinterpret_cast(data + 0)); EXPECT_FLOAT_EQ(64u, *reinterpret_cast(data + 16)); EXPECT_FLOAT_EQ(128u, *reinterpret_cast(data + 20)); EXPECT_FLOAT_EQ(220u, *reinterpret_cast(data + 24)); } TEST_F(AmberScriptParserTest, InvalidBufferWidth) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH a )"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("2: expected an integer for WIDTH", r.Error()); } TEST_F(AmberScriptParserTest, ZeroBufferWidth) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH 0 )"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("2: expected WIDTH to be positive", r.Error()); } TEST_F(AmberScriptParserTest, MissingBufferHeight) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH 1 )"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("3: BUFFER HEIGHT missing", r.Error()); } TEST_F(AmberScriptParserTest, InvalidBufferHeight) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH 1 HEIGHT 1.0 )"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("2: expected an integer for HEIGHT", r.Error()); } TEST_F(AmberScriptParserTest, ZeroBufferHeight) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH 1 HEIGHT 0 )"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("2: expected HEIGHT to be positive", r.Error()); } TEST_F(AmberScriptParserTest, BufferWidthAndHeight) { std::string in = R"( BUFFER buf DATA_TYPE vec4 WIDTH 2 HEIGHT 3 )"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("buf", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_EQ(2u, buffer->GetWidth()); EXPECT_EQ(3u, buffer->GetHeight()); EXPECT_EQ(6u, buffer->ElementCount()); } TEST_F(AmberScriptParserTest, BufferMipLevels) { std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM MIP_LEVELS 3"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); auto* buffer = buffers[0].get(); EXPECT_EQ(3U, buffer->GetMipLevels()); } TEST_F(AmberScriptParserTest, BufferMissingMipLevels) { std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM MIP_LEVELS"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("1: invalid value for MIP_LEVELS", r.Error()); } TEST_F(AmberScriptParserTest, BufferMissingDataFile) { std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("1: invalid value for FILE", r.Error()); } TEST_F(AmberScriptParserTest, BufferMissingDataFilePng) { std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE PNG"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("1: missing file name for FILE", r.Error()); } TEST_F(AmberScriptParserTest, BufferDataFilePng) { std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE PNG foo.png"; DummyDelegate delegate; Parser parser(&delegate); Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); ASSERT_EQ(static_cast(amber::BufferDataFileType::kPng), buffers[0]->GetValues()[0]); } TEST_F(AmberScriptParserTest, BufferMissingDataFileBinary) { std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 10 FILE BINARY"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("1: missing file name for FILE", r.Error()); } TEST_F(AmberScriptParserTest, BufferDataFileBinary) { std::string in = "BUFFER my_buffer DATA_TYPE int32 SIZE 10 FILE BINARY data.bin"; DummyDelegate delegate; Parser parser(&delegate); Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); ASSERT_EQ(static_cast(amber::BufferDataFileType::kBinary), buffers[0]->GetValues()[0]); } TEST_F(AmberScriptParserTest, BufferMissingDataFileText) { std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 10 FILE TEXT"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("1: missing file name for FILE", r.Error()); } TEST_F(AmberScriptParserTest, BufferDataFileText) { std::string in = "BUFFER my_buffer DATA_TYPE int32 SIZE 10 FILE TEXT data.txt"; DummyDelegate delegate; Parser parser(&delegate); Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()); auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); ASSERT_EQ(static_cast(amber::BufferDataFileType::kText), buffers[0]->GetValues()[0]); } } // namespace amberscript } // namespace amber