1 #include "gtest/gtest.h"
4 #include "mozilla/SpinEventLoopUntil.h"
5 #include "nsComponentManagerUtils.h"
7 #include "nsStreamUtils.h"
9 #include "nsStringStream.h"
10 #include "nsIMIMEInputStream.h"
11 #include "nsISeekableStream.h"
13 using mozilla::GetCurrentSerialEventTarget
;
14 using mozilla::SpinEventLoopUntil
;
18 class SeekableLengthInputStream final
: public testing::LengthInputStream
,
19 public nsISeekableStream
{
21 SeekableLengthInputStream(const nsACString
& aBuffer
,
22 bool aIsInputStreamLength
,
23 bool aIsAsyncInputStreamLength
,
24 nsresult aLengthRv
= NS_OK
,
25 bool aNegativeValue
= false)
26 : testing::LengthInputStream(aBuffer
, aIsInputStreamLength
,
27 aIsAsyncInputStreamLength
, aLengthRv
,
30 NS_DECL_ISUPPORTS_INHERITED
33 Seek(int32_t aWhence
, int64_t aOffset
) override
{
34 MOZ_CRASH("This method should not be called.");
35 return NS_ERROR_FAILURE
;
39 Tell(int64_t* aResult
) override
{
40 MOZ_CRASH("This method should not be called.");
41 return NS_ERROR_FAILURE
;
46 MOZ_CRASH("This method should not be called.");
47 return NS_ERROR_FAILURE
;
51 ~SeekableLengthInputStream() = default;
54 NS_IMPL_ISUPPORTS_INHERITED(SeekableLengthInputStream
,
55 testing::LengthInputStream
, nsISeekableStream
)
59 // nsIInputStreamLength && nsIAsyncInputStreamLength
61 TEST(TestNsMIMEInputStream
, QIInputStreamLength
)
64 buf
.AssignLiteral("Hello world");
66 for (int i
= 0; i
< 4; i
++) {
67 nsCOMPtr
<nsIInputStream
> mis
;
69 RefPtr
<SeekableLengthInputStream
> stream
=
70 new SeekableLengthInputStream(buf
, i
% 2, i
> 1);
73 nsCOMPtr
<nsIMIMEInputStream
> m(
74 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
77 rv
= m
->SetData(stream
);
85 nsCOMPtr
<nsIInputStreamLength
> qi
= do_QueryInterface(mis
);
86 ASSERT_EQ(!!(i
% 2), !!qi
);
90 nsCOMPtr
<nsIAsyncInputStreamLength
> qi
= do_QueryInterface(mis
);
91 ASSERT_EQ(i
> 1, !!qi
);
96 TEST(TestNsMIMEInputStream
, InputStreamLength
)
99 buf
.AssignLiteral("Hello world");
101 nsCOMPtr
<nsIInputStream
> mis
;
103 RefPtr
<SeekableLengthInputStream
> stream
=
104 new SeekableLengthInputStream(buf
, true, false);
107 nsCOMPtr
<nsIMIMEInputStream
> m(
108 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
109 ASSERT_EQ(NS_OK
, rv
);
111 rv
= m
->SetData(stream
);
112 ASSERT_EQ(NS_OK
, rv
);
118 nsCOMPtr
<nsIInputStreamLength
> qi
= do_QueryInterface(mis
);
122 nsresult rv
= qi
->Length(&size
);
123 ASSERT_EQ(NS_OK
, rv
);
124 ASSERT_EQ(int64_t(buf
.Length()), size
);
127 TEST(TestNsMIMEInputStream
, NegativeInputStreamLength
)
130 buf
.AssignLiteral("Hello world");
132 nsCOMPtr
<nsIInputStream
> mis
;
134 RefPtr
<SeekableLengthInputStream
> stream
=
135 new SeekableLengthInputStream(buf
, true, false, NS_OK
, true);
138 nsCOMPtr
<nsIMIMEInputStream
> m(
139 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
140 ASSERT_EQ(NS_OK
, rv
);
142 rv
= m
->SetData(stream
);
143 ASSERT_EQ(NS_OK
, rv
);
149 nsCOMPtr
<nsIInputStreamLength
> qi
= do_QueryInterface(mis
);
153 nsresult rv
= qi
->Length(&size
);
154 ASSERT_EQ(NS_OK
, rv
);
158 TEST(TestNsMIMEInputStream
, AsyncInputStreamLength
)
161 buf
.AssignLiteral("Hello world");
163 nsCOMPtr
<nsIInputStream
> mis
;
165 RefPtr
<SeekableLengthInputStream
> stream
=
166 new SeekableLengthInputStream(buf
, false, true);
169 nsCOMPtr
<nsIMIMEInputStream
> m(
170 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
171 ASSERT_EQ(NS_OK
, rv
);
173 rv
= m
->SetData(stream
);
174 ASSERT_EQ(NS_OK
, rv
);
180 nsCOMPtr
<nsIAsyncInputStreamLength
> qi
= do_QueryInterface(mis
);
183 RefPtr
<testing::LengthCallback
> callback
= new testing::LengthCallback();
185 nsresult rv
= qi
->AsyncLengthWait(callback
, GetCurrentSerialEventTarget());
186 ASSERT_EQ(NS_OK
, rv
);
188 MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
189 "TEST(TestNsMIMEInputStream, AsyncInputStreamLength)"_ns
,
190 [&]() { return callback
->Called(); }));
191 ASSERT_EQ(int64_t(buf
.Length()), callback
->Size());
194 TEST(TestNsMIMEInputStream
, NegativeAsyncInputStreamLength
)
197 buf
.AssignLiteral("Hello world");
199 nsCOMPtr
<nsIInputStream
> mis
;
201 RefPtr
<SeekableLengthInputStream
> stream
=
202 new SeekableLengthInputStream(buf
, false, true, NS_OK
, true);
205 nsCOMPtr
<nsIMIMEInputStream
> m(
206 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
207 ASSERT_EQ(NS_OK
, rv
);
209 rv
= m
->SetData(stream
);
210 ASSERT_EQ(NS_OK
, rv
);
216 nsCOMPtr
<nsIAsyncInputStreamLength
> qi
= do_QueryInterface(mis
);
219 RefPtr
<testing::LengthCallback
> callback
= new testing::LengthCallback();
221 nsresult rv
= qi
->AsyncLengthWait(callback
, GetCurrentSerialEventTarget());
222 ASSERT_EQ(NS_OK
, rv
);
224 MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
225 "TEST(TestNsMIMEInputStream, NegativeAsyncInputStreamLength)"_ns
,
226 [&]() { return callback
->Called(); }));
227 ASSERT_EQ(-1, callback
->Size());
230 TEST(TestNsMIMEInputStream
, AbortLengthCallback
)
233 buf
.AssignLiteral("Hello world");
235 nsCOMPtr
<nsIInputStream
> mis
;
237 RefPtr
<SeekableLengthInputStream
> stream
=
238 new SeekableLengthInputStream(buf
, false, true, NS_OK
, true);
241 nsCOMPtr
<nsIMIMEInputStream
> m(
242 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv
));
243 ASSERT_EQ(NS_OK
, rv
);
245 rv
= m
->SetData(stream
);
246 ASSERT_EQ(NS_OK
, rv
);
252 nsCOMPtr
<nsIAsyncInputStreamLength
> qi
= do_QueryInterface(mis
);
255 RefPtr
<testing::LengthCallback
> callback1
= new testing::LengthCallback();
256 nsresult rv
= qi
->AsyncLengthWait(callback1
, GetCurrentSerialEventTarget());
257 ASSERT_EQ(NS_OK
, rv
);
259 RefPtr
<testing::LengthCallback
> callback2
= new testing::LengthCallback();
260 rv
= qi
->AsyncLengthWait(callback2
, GetCurrentSerialEventTarget());
261 ASSERT_EQ(NS_OK
, rv
);
264 SpinEventLoopUntil("TEST(TestNsMIMEInputStream, AbortLengthCallback)"_ns
,
265 [&]() { return callback2
->Called(); }));
266 ASSERT_TRUE(!callback1
->Called());
267 ASSERT_EQ(-1, callback2
->Size());