Loading image/test/gtest/Common.h +31 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,37 @@ bool RowHasPixels(gfx::SourceSurface* aSurface, int32_t aRow, const std::vector<BGRAColor>& aPixels); // ExpectNoResume is an IResumable implementation for use by tests that expect // Resume() to never get called. class ExpectNoResume final : public IResumable { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ExpectNoResume, override) void Resume() override { FAIL() << "Resume() should not get called"; } private: ~ExpectNoResume() override { } }; // CountResumes is an IResumable implementation for use by tests that expect // Resume() to get called a certain number of times. class CountResumes : public IResumable { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CountResumes, override) CountResumes() : mCount(0) { } void Resume() override { mCount++; } uint32_t Count() const { return mCount; } private: ~CountResumes() override { } uint32_t mCount; }; /////////////////////////////////////////////////////////////////////////////// // SurfacePipe Helpers Loading image/test/gtest/TestStreamingLexer.cpp +325 −45 Original line number Diff line number Diff line Loading @@ -82,26 +82,61 @@ DoLexWithUnbufferedTerminate(TestState aState, const char* aData, size_t aLength } } TEST(ImageStreamingLexer, SingleChunk) class ImageStreamingLexer : public ::testing::Test { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; public: ImageStreamingLexer() : mLexer(Transition::To(TestState::ONE, 3)) , mSourceBuffer(new SourceBuffer) , mIterator(mSourceBuffer->Iterator()) , mExpectNoResume(new ExpectNoResume) , mCountResumes(new CountResumes) { } protected: AutoInitializeImageLib mInit; const char mData[9] { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; StreamingLexer<TestState> mLexer; RefPtr<SourceBuffer> mSourceBuffer; SourceBufferIterator mIterator; RefPtr<ExpectNoResume> mExpectNoResume; RefPtr<CountResumes> mCountResumes; }; TEST_F(ImageStreamingLexer, ZeroLengthData) { // Test delivering a zero-length piece of data. Maybe<TerminalState> result = mLexer.Lex(mData, 0, DoLex); EXPECT_TRUE(result.isNothing()); } TEST_F(ImageStreamingLexer, SingleChunk) { // Test delivering all the data at once. Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), DoLex); Maybe<TerminalState> result = mLexer.Lex(mData, sizeof(mData), DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, SingleChunkWithUnbuffered) TEST_F(ImageStreamingLexer, SingleChunkFromSourceBuffer) { // Test delivering all the data at once. mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, SingleChunkWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering all the data at once. Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -109,14 +144,69 @@ TEST(ImageStreamingLexer, SingleChunkWithUnbuffered) EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, ChunkPerState) TEST_F(ImageStreamingLexer, SingleChunkWithUnbufferedFromSourceBuffer) { Vector<char> unbufferedVector; // Test delivering all the data at once. mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, ChunkPerState) { // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + 3 * i, 3, DoLex); if (i == 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, ChunkPerStateFromSourceBuffer) { // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { mSourceBuffer->Append(mData + 3 * i, 3); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i == 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { Maybe<TerminalState> result = lexer.Lex(data + 3 * i, 3, DoLex); Maybe<TerminalState> result = mLexer.Lex(mData + 3 * i, 3, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); if (i == 2) { EXPECT_TRUE(result.isSome()); Loading @@ -127,16 +217,15 @@ TEST(ImageStreamingLexer, ChunkPerState) } } TEST(ImageStreamingLexer, ChunkPerStateWithUnbuffered) TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbufferedFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { mSourceBuffer->Append(mData + 3 * i, 3); Maybe<TerminalState> result = lexer.Lex(data + 3 * i, 3, mLexer.Lex(mIterator, mCountResumes, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -148,16 +237,32 @@ TEST(ImageStreamingLexer, ChunkPerStateWithUnbuffered) EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST(ImageStreamingLexer, OneByteChunks) TEST_F(ImageStreamingLexer, OneByteChunks) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + i, 1, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, OneByteChunksFromSourceBuffer) { // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = lexer.Lex(data + i, 1, DoLex); mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); Loading @@ -166,18 +271,19 @@ TEST(ImageStreamingLexer, OneByteChunks) EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(8u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST(ImageStreamingLexer, OneByteChunksWithUnbuffered) TEST_F(ImageStreamingLexer, OneByteChunksWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = lexer.Lex(data + i, 1, mLexer.Lex(mData + i, 1, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -191,14 +297,36 @@ TEST(ImageStreamingLexer, OneByteChunksWithUnbuffered) } } TEST(ImageStreamingLexer, TerminateSuccess) TEST_F(ImageStreamingLexer, OneByteChunksWithUnbufferedFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(8u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, TerminateSuccess) { // Test that Terminate is "sticky". Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateSuccess(); Loading @@ -207,7 +335,7 @@ TEST(ImageStreamingLexer, TerminateSuccess) EXPECT_EQ(Some(TerminalState::SUCCESS), result); result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); Loading @@ -216,14 +344,38 @@ TEST(ImageStreamingLexer, TerminateSuccess) EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, TerminateFailure) TEST_F(ImageStreamingLexer, TerminateSuccessFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); // Test that Terminate is "sticky". SourceBufferIterator iterator = mSourceBuffer->Iterator(); Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(iterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateSuccess(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); SourceBufferIterator iterator2 = mSourceBuffer->Iterator(); result = mLexer.Lex(iterator2, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, TerminateFailure) { // Test that Terminate is "sticky". Maybe<TerminalState> result = mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateFailure(); Loading @@ -232,7 +384,7 @@ TEST(ImageStreamingLexer, TerminateFailure) EXPECT_EQ(Some(TerminalState::FAILURE), result); result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); Loading @@ -241,15 +393,56 @@ TEST(ImageStreamingLexer, TerminateFailure) EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST(ImageStreamingLexer, TerminateUnbuffered) TEST_F(ImageStreamingLexer, TerminateFailureFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); // Test that Terminate is "sticky". SourceBufferIterator iterator = mSourceBuffer->Iterator(); Maybe<TerminalState> result = mLexer.Lex(iterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); SourceBufferIterator iterator2 = mSourceBuffer->Iterator(); result = mLexer.Lex(iterator2, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST_F(ImageStreamingLexer, TerminateUnbuffered) { // Test that Terminate works during an unbuffered read. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + i, 1, DoLexWithUnbufferedTerminate); if (i > 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, TerminateUnbufferedFromSourceBuffer) { // Test that Terminate works during an unbuffered read. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = lexer.Lex(data + i, 1, DoLexWithUnbufferedTerminate); mLexer.Lex(mIterator, mCountResumes, DoLexWithUnbufferedTerminate); if (i > 2) { EXPECT_TRUE(result.isSome()); Loading @@ -258,4 +451,91 @@ TEST(ImageStreamingLexer, TerminateUnbuffered) EXPECT_TRUE(result.isNothing()); } } // We expect 3 resumes because TestState::ONE consumes 3 bytes and then // transitions to TestState::UNBUFFERED, which calls TerminateSuccess() as // soon as it receives a single byte. That's four bytes total, which are // delivered one at a time, requiring 3 resumes. EXPECT_EQ(3u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, SourceBufferImmediateComplete) { // Test calling SourceBuffer::Complete() without appending any data. This // causes the SourceBuffer to automatically have a failing completion status, // no matter what you pass, so we expect TerminalState::FAILURE below. mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST_F(ImageStreamingLexer, SourceBufferTruncatedSuccess) { // Test that calling SourceBuffer::Complete() with a successful status results // in an immediate TerminalState::SUCCESS result. for (unsigned i = 0; i < 9; ++i) { if (i < 2) { mSourceBuffer->Append(mData + i, 1); } else if (i == 2) { mSourceBuffer->Complete(NS_OK); } Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i >= 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); } TEST_F(ImageStreamingLexer, SourceBufferTruncatedFailure) { // Test that calling SourceBuffer::Complete() with a failing status results in // an immediate TerminalState::FAILURE result. for (unsigned i = 0; i < 9; ++i) { if (i < 2) { mSourceBuffer->Append(mData + i, 1); } else if (i == 2) { mSourceBuffer->Complete(NS_ERROR_FAILURE); } Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i >= 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); } TEST_F(ImageStreamingLexer, NoSourceBufferResumable) { // Test delivering in one byte chunks with no IResumable. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, nullptr, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } mSourceBuffer->Complete(NS_OK); } Loading
image/test/gtest/Common.h +31 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,37 @@ bool RowHasPixels(gfx::SourceSurface* aSurface, int32_t aRow, const std::vector<BGRAColor>& aPixels); // ExpectNoResume is an IResumable implementation for use by tests that expect // Resume() to never get called. class ExpectNoResume final : public IResumable { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ExpectNoResume, override) void Resume() override { FAIL() << "Resume() should not get called"; } private: ~ExpectNoResume() override { } }; // CountResumes is an IResumable implementation for use by tests that expect // Resume() to get called a certain number of times. class CountResumes : public IResumable { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CountResumes, override) CountResumes() : mCount(0) { } void Resume() override { mCount++; } uint32_t Count() const { return mCount; } private: ~CountResumes() override { } uint32_t mCount; }; /////////////////////////////////////////////////////////////////////////////// // SurfacePipe Helpers Loading
image/test/gtest/TestStreamingLexer.cpp +325 −45 Original line number Diff line number Diff line Loading @@ -82,26 +82,61 @@ DoLexWithUnbufferedTerminate(TestState aState, const char* aData, size_t aLength } } TEST(ImageStreamingLexer, SingleChunk) class ImageStreamingLexer : public ::testing::Test { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; public: ImageStreamingLexer() : mLexer(Transition::To(TestState::ONE, 3)) , mSourceBuffer(new SourceBuffer) , mIterator(mSourceBuffer->Iterator()) , mExpectNoResume(new ExpectNoResume) , mCountResumes(new CountResumes) { } protected: AutoInitializeImageLib mInit; const char mData[9] { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; StreamingLexer<TestState> mLexer; RefPtr<SourceBuffer> mSourceBuffer; SourceBufferIterator mIterator; RefPtr<ExpectNoResume> mExpectNoResume; RefPtr<CountResumes> mCountResumes; }; TEST_F(ImageStreamingLexer, ZeroLengthData) { // Test delivering a zero-length piece of data. Maybe<TerminalState> result = mLexer.Lex(mData, 0, DoLex); EXPECT_TRUE(result.isNothing()); } TEST_F(ImageStreamingLexer, SingleChunk) { // Test delivering all the data at once. Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), DoLex); Maybe<TerminalState> result = mLexer.Lex(mData, sizeof(mData), DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, SingleChunkWithUnbuffered) TEST_F(ImageStreamingLexer, SingleChunkFromSourceBuffer) { // Test delivering all the data at once. mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, SingleChunkWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering all the data at once. Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -109,14 +144,69 @@ TEST(ImageStreamingLexer, SingleChunkWithUnbuffered) EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, ChunkPerState) TEST_F(ImageStreamingLexer, SingleChunkWithUnbufferedFromSourceBuffer) { Vector<char> unbufferedVector; // Test delivering all the data at once. mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, ChunkPerState) { // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + 3 * i, 3, DoLex); if (i == 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, ChunkPerStateFromSourceBuffer) { // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { mSourceBuffer->Append(mData + 3 * i, 3); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i == 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { Maybe<TerminalState> result = lexer.Lex(data + 3 * i, 3, DoLex); Maybe<TerminalState> result = mLexer.Lex(mData + 3 * i, 3, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); if (i == 2) { EXPECT_TRUE(result.isSome()); Loading @@ -127,16 +217,15 @@ TEST(ImageStreamingLexer, ChunkPerState) } } TEST(ImageStreamingLexer, ChunkPerStateWithUnbuffered) TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbufferedFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in perfectly-sized chunks, one per state. for (unsigned i = 0; i < 3; ++i) { mSourceBuffer->Append(mData + 3 * i, 3); Maybe<TerminalState> result = lexer.Lex(data + 3 * i, 3, mLexer.Lex(mIterator, mCountResumes, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -148,16 +237,32 @@ TEST(ImageStreamingLexer, ChunkPerStateWithUnbuffered) EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST(ImageStreamingLexer, OneByteChunks) TEST_F(ImageStreamingLexer, OneByteChunks) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + i, 1, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, OneByteChunksFromSourceBuffer) { // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = lexer.Lex(data + i, 1, DoLex); mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); Loading @@ -166,18 +271,19 @@ TEST(ImageStreamingLexer, OneByteChunks) EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(8u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST(ImageStreamingLexer, OneByteChunksWithUnbuffered) TEST_F(ImageStreamingLexer, OneByteChunksWithUnbuffered) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = lexer.Lex(data + i, 1, mLexer.Lex(mData + i, 1, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); Loading @@ -191,14 +297,36 @@ TEST(ImageStreamingLexer, OneByteChunksWithUnbuffered) } } TEST(ImageStreamingLexer, TerminateSuccess) TEST_F(ImageStreamingLexer, OneByteChunksWithUnbufferedFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; Vector<char> unbufferedVector; // Test delivering in one byte chunks. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, [&](TestState aState, const char* aData, size_t aLength) { return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector); }); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(8u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, TerminateSuccess) { // Test that Terminate is "sticky". Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateSuccess(); Loading @@ -207,7 +335,7 @@ TEST(ImageStreamingLexer, TerminateSuccess) EXPECT_EQ(Some(TerminalState::SUCCESS), result); result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); Loading @@ -216,14 +344,38 @@ TEST(ImageStreamingLexer, TerminateSuccess) EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST(ImageStreamingLexer, TerminateFailure) TEST_F(ImageStreamingLexer, TerminateSuccessFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); // Test that Terminate is "sticky". SourceBufferIterator iterator = mSourceBuffer->Iterator(); Maybe<TerminalState> result = lexer.Lex(data, sizeof(data), mLexer.Lex(iterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateSuccess(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); SourceBufferIterator iterator2 = mSourceBuffer->Iterator(); result = mLexer.Lex(iterator2, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } TEST_F(ImageStreamingLexer, TerminateFailure) { // Test that Terminate is "sticky". Maybe<TerminalState> result = mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateFailure(); Loading @@ -232,7 +384,7 @@ TEST(ImageStreamingLexer, TerminateFailure) EXPECT_EQ(Some(TerminalState::FAILURE), result); result = lexer.Lex(data, sizeof(data), mLexer.Lex(mData, sizeof(mData), [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); Loading @@ -241,15 +393,56 @@ TEST(ImageStreamingLexer, TerminateFailure) EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST(ImageStreamingLexer, TerminateUnbuffered) TEST_F(ImageStreamingLexer, TerminateFailureFromSourceBuffer) { StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3)); char data[9] = { 1, 2, 3, 1, 2, 3, 1, 2, 3 }; mSourceBuffer->Append(mData, sizeof(mData)); mSourceBuffer->Complete(NS_OK); // Test that Terminate is "sticky". SourceBufferIterator iterator = mSourceBuffer->Iterator(); Maybe<TerminalState> result = mLexer.Lex(iterator, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(aState == TestState::ONE); return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); SourceBufferIterator iterator2 = mSourceBuffer->Iterator(); result = mLexer.Lex(iterator2, mExpectNoResume, [&](TestState aState, const char* aData, size_t aLength) { EXPECT_TRUE(false); // Shouldn't get here. return Transition::TerminateFailure(); }); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST_F(ImageStreamingLexer, TerminateUnbuffered) { // Test that Terminate works during an unbuffered read. for (unsigned i = 0; i < 9; ++i) { Maybe<TerminalState> result = mLexer.Lex(mData + i, 1, DoLexWithUnbufferedTerminate); if (i > 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } } TEST_F(ImageStreamingLexer, TerminateUnbufferedFromSourceBuffer) { // Test that Terminate works during an unbuffered read. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = lexer.Lex(data + i, 1, DoLexWithUnbufferedTerminate); mLexer.Lex(mIterator, mCountResumes, DoLexWithUnbufferedTerminate); if (i > 2) { EXPECT_TRUE(result.isSome()); Loading @@ -258,4 +451,91 @@ TEST(ImageStreamingLexer, TerminateUnbuffered) EXPECT_TRUE(result.isNothing()); } } // We expect 3 resumes because TestState::ONE consumes 3 bytes and then // transitions to TestState::UNBUFFERED, which calls TerminateSuccess() as // soon as it receives a single byte. That's four bytes total, which are // delivered one at a time, requiring 3 resumes. EXPECT_EQ(3u, mCountResumes->Count()); mSourceBuffer->Complete(NS_OK); } TEST_F(ImageStreamingLexer, SourceBufferImmediateComplete) { // Test calling SourceBuffer::Complete() without appending any data. This // causes the SourceBuffer to automatically have a failing completion status, // no matter what you pass, so we expect TerminalState::FAILURE below. mSourceBuffer->Complete(NS_OK); Maybe<TerminalState> result = mLexer.Lex(mIterator, mExpectNoResume, DoLex); EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } TEST_F(ImageStreamingLexer, SourceBufferTruncatedSuccess) { // Test that calling SourceBuffer::Complete() with a successful status results // in an immediate TerminalState::SUCCESS result. for (unsigned i = 0; i < 9; ++i) { if (i < 2) { mSourceBuffer->Append(mData + i, 1); } else if (i == 2) { mSourceBuffer->Complete(NS_OK); } Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i >= 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); } TEST_F(ImageStreamingLexer, SourceBufferTruncatedFailure) { // Test that calling SourceBuffer::Complete() with a failing status results in // an immediate TerminalState::FAILURE result. for (unsigned i = 0; i < 9; ++i) { if (i < 2) { mSourceBuffer->Append(mData + i, 1); } else if (i == 2) { mSourceBuffer->Complete(NS_ERROR_FAILURE); } Maybe<TerminalState> result = mLexer.Lex(mIterator, mCountResumes, DoLex); if (i >= 2) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::FAILURE), result); } else { EXPECT_TRUE(result.isNothing()); } } EXPECT_EQ(2u, mCountResumes->Count()); } TEST_F(ImageStreamingLexer, NoSourceBufferResumable) { // Test delivering in one byte chunks with no IResumable. for (unsigned i = 0; i < 9; ++i) { mSourceBuffer->Append(mData + i, 1); Maybe<TerminalState> result = mLexer.Lex(mIterator, nullptr, DoLex); if (i == 8) { EXPECT_TRUE(result.isSome()); EXPECT_EQ(Some(TerminalState::SUCCESS), result); } else { EXPECT_TRUE(result.isNothing()); } } mSourceBuffer->Complete(NS_OK); }