summaryrefslogtreecommitdiffstats
path: root/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/tests/gtest/TestInputStreamLengthHelper.cpp')
-rw-r--r--xpcom/tests/gtest/TestInputStreamLengthHelper.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp b/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp
new file mode 100644
index 0000000000..2a58816209
--- /dev/null
+++ b/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp
@@ -0,0 +1,159 @@
+#include "gtest/gtest.h"
+
+#include "mozilla/InputStreamLengthHelper.h"
+#include "mozilla/SpinEventLoopUntil.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "nsStringStream.h"
+#include "nsThreadUtils.h"
+#include "nsXPCOM.h"
+#include "Helpers.h"
+
+using namespace mozilla;
+
+TEST(TestInputStreamLengthHelper, NonLengthStream)
+{
+ nsCString buf;
+ buf.AssignLiteral("Hello world");
+
+ nsCOMPtr<nsIInputStream> stream;
+ NS_NewCStringInputStream(getter_AddRefs(stream), buf);
+
+ bool called = false;
+ InputStreamLengthHelper::GetAsyncLength(stream, [&](int64_t aLength) {
+ ASSERT_EQ(int64_t(buf.Length()), aLength);
+ called = true;
+ });
+
+ MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+ "xpcom:TEST(TestInputStreamLengthHelper, NonLengthStream)"_ns,
+ [&]() { return called; }));
+}
+
+class LengthStream final : public nsIInputStreamLength,
+ public nsIAsyncInputStreamLength,
+ public nsIInputStream {
+ public:
+ NS_DECL_ISUPPORTS
+
+ LengthStream(int64_t aLength, nsresult aLengthRv, uint64_t aAvailable,
+ bool aIsAsyncLength)
+ : mLength(aLength),
+ mLengthRv(aLengthRv),
+ mAvailable(aAvailable),
+ mIsAsyncLength(aIsAsyncLength) {}
+
+ NS_IMETHOD Close(void) override { MOZ_CRASH("Invalid call!"); }
+ NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* _retval) override {
+ MOZ_CRASH("Invalid call!");
+ }
+ NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) override {
+ MOZ_CRASH("Invalid call!");
+ }
+ NS_IMETHOD IsNonBlocking(bool* _retval) override {
+ MOZ_CRASH("Invalid call!");
+ }
+
+ NS_IMETHOD Length(int64_t* aLength) override {
+ *aLength = mLength;
+ return mLengthRv;
+ }
+
+ NS_IMETHOD AsyncLengthWait(nsIInputStreamLengthCallback* aCallback,
+ nsIEventTarget* aEventTarget) override {
+ if (aCallback) {
+ aCallback->OnInputStreamLengthReady(this, mLength);
+ }
+ return NS_OK;
+ }
+
+ NS_IMETHOD Available(uint64_t* aAvailable) override {
+ *aAvailable = mAvailable;
+ return NS_OK;
+ }
+
+ private:
+ ~LengthStream() = default;
+
+ int64_t mLength;
+ nsresult mLengthRv;
+ uint64_t mAvailable;
+
+ bool mIsAsyncLength;
+};
+
+NS_IMPL_ADDREF(LengthStream);
+NS_IMPL_RELEASE(LengthStream);
+
+NS_INTERFACE_MAP_BEGIN(LengthStream)
+ NS_INTERFACE_MAP_ENTRY(nsIInputStream)
+ NS_INTERFACE_MAP_ENTRY(nsIInputStreamLength)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStreamLength, mIsAsyncLength)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
+NS_INTERFACE_MAP_END
+
+TEST(TestInputStreamLengthHelper, LengthStream)
+{
+ nsCOMPtr<nsIInputStream> stream = new LengthStream(42, NS_OK, 0, false);
+
+ bool called = false;
+ InputStreamLengthHelper::GetAsyncLength(stream, [&](int64_t aLength) {
+ ASSERT_EQ(42, aLength);
+ called = true;
+ });
+
+ MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+ "xpcom:TEST(TestInputStreamLengthHelper, LengthStream)"_ns,
+ [&]() { return called; }));
+}
+
+TEST(TestInputStreamLengthHelper, InvalidLengthStream)
+{
+ nsCOMPtr<nsIInputStream> stream =
+ new LengthStream(42, NS_ERROR_NOT_AVAILABLE, 0, false);
+
+ bool called = false;
+ InputStreamLengthHelper::GetAsyncLength(stream, [&](int64_t aLength) {
+ ASSERT_EQ(-1, aLength);
+ called = true;
+ });
+
+ MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+ "xpcom:TEST(TestInputStreamLengthHelper, InvalidLengthStream)"_ns,
+ [&]() { return called; }));
+}
+
+TEST(TestInputStreamLengthHelper, AsyncLengthStream)
+{
+ nsCOMPtr<nsIInputStream> stream =
+ new LengthStream(22, NS_BASE_STREAM_WOULD_BLOCK, 123, true);
+
+ bool called = false;
+ InputStreamLengthHelper::GetAsyncLength(stream, [&](int64_t aLength) {
+ ASSERT_EQ(22, aLength);
+ called = true;
+ });
+
+ MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+ "xpcom:TEST(TestInputStreamLengthHelper, AsyncLengthStream)"_ns,
+ [&]() { return called; }));
+}
+
+TEST(TestInputStreamLengthHelper, FallbackLengthStream)
+{
+ nsCOMPtr<nsIInputStream> stream =
+ new LengthStream(-1, NS_BASE_STREAM_WOULD_BLOCK, 123, false);
+
+ bool called = false;
+ InputStreamLengthHelper::GetAsyncLength(stream, [&](int64_t aLength) {
+ ASSERT_EQ(123, aLength);
+ called = true;
+ });
+
+ MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+ "xpcom:TEST(TestInputStreamLengthHelper, FallbackLengthStream)"_ns,
+ [&]() { return called; }));
+}