Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/tests/gtest/Helpers.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
/* Helper routines for xpcom gtests. */
8
9
#include "Helpers.h"
10
11
#include <algorithm>
12
#include "gtest/gtest.h"
13
#include "nsIOutputStream.h"
14
#include "nsStreamUtils.h"
15
#include "nsTArray.h"
16
#include "nsThreadUtils.h"
17
18
namespace testing {
19
20
// Populate an array with the given number of bytes.  Data is lorem ipsum
21
// random text, but deterministic across multiple calls.
22
void
23
CreateData(uint32_t aNumBytes, nsTArray<char>& aDataOut)
24
0
{
25
0
  static const char data[] =
26
0
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas "
27
0
    "purus eu condimentum iaculis. In accumsan leo eget odio porttitor, non "
28
0
    "rhoncus nulla vestibulum. Etiam lacinia consectetur nisl nec "
29
0
    "sollicitudin. Sed fringilla accumsan diam, pulvinar varius massa. Duis "
30
0
    "mollis dignissim felis, eget tempus nisi tristique ut. Fusce euismod, "
31
0
    "lectus non lacinia tempor, tellus diam suscipit quam, eget hendrerit "
32
0
    "lacus nunc fringilla ante. Sed ultrices massa vitae risus molestie, ut "
33
0
    "finibus quam laoreet nullam.";
34
0
  static const uint32_t dataLength = sizeof(data) - 1;
35
0
36
0
  aDataOut.SetCapacity(aNumBytes);
37
0
38
0
  while (aNumBytes > 0) {
39
0
    uint32_t amount = std::min(dataLength, aNumBytes);
40
0
    aDataOut.AppendElements(data, amount);
41
0
    aNumBytes -= amount;
42
0
  }
43
0
}
44
45
// Write the given number of bytes out to the stream.  Loop until expected
46
// bytes count is reached or an error occurs.
47
void
48
Write(nsIOutputStream* aStream, const nsTArray<char>& aData, uint32_t aOffset,
49
      uint32_t aNumBytes)
50
0
{
51
0
  uint32_t remaining =
52
0
    std::min(aNumBytes, static_cast<uint32_t>(aData.Length() - aOffset));
53
0
54
0
  while (remaining > 0) {
55
0
    uint32_t numWritten;
56
0
    nsresult rv = aStream->Write(aData.Elements() + aOffset, remaining,
57
0
                                 &numWritten);
58
0
    ASSERT_TRUE(NS_SUCCEEDED(rv));
59
0
    if (numWritten < 1) {
60
0
      break;
61
0
    }
62
0
    aOffset += numWritten;
63
0
    remaining -= numWritten;
64
0
  }
65
0
}
66
67
// Write the given number of bytes and then close the stream.
68
void
69
WriteAllAndClose(nsIOutputStream* aStream, const nsTArray<char>& aData)
70
0
{
71
0
  Write(aStream, aData, 0, aData.Length());
72
0
  aStream->Close();
73
0
}
74
75
// Synchronously consume the given input stream and validate the resulting data
76
// against the given array of expected values.
77
void
78
ConsumeAndValidateStream(nsIInputStream* aStream,
79
                         const nsTArray<char>& aExpectedData)
80
0
{
81
0
  nsDependentCSubstring data(aExpectedData.Elements(), aExpectedData.Length());
82
0
  ConsumeAndValidateStream(aStream, data);
83
0
}
84
85
// Synchronously consume the given input stream and validate the resulting data
86
// against the given string of expected values.
87
void
88
ConsumeAndValidateStream(nsIInputStream* aStream,
89
                         const nsACString& aExpectedData)
90
0
{
91
0
  nsAutoCString outputData;
92
0
  nsresult rv = NS_ConsumeStream(aStream, UINT32_MAX, outputData);
93
0
  ASSERT_TRUE(NS_SUCCEEDED(rv));
94
0
  ASSERT_EQ(aExpectedData.Length(), outputData.Length());
95
0
  ASSERT_TRUE(aExpectedData.Equals(outputData));
96
0
}
97
98
NS_IMPL_ISUPPORTS(OutputStreamCallback, nsIOutputStreamCallback);
99
100
OutputStreamCallback::OutputStreamCallback()
101
  : mCalled(false)
102
0
{
103
0
}
104
105
OutputStreamCallback::~OutputStreamCallback()
106
0
{
107
0
}
108
109
NS_IMETHODIMP
110
OutputStreamCallback::OnOutputStreamReady(nsIAsyncOutputStream* aStream)
111
0
{
112
0
  mCalled = true;
113
0
  return NS_OK;
114
0
}
115
116
NS_IMPL_ISUPPORTS(InputStreamCallback, nsIInputStreamCallback);
117
118
InputStreamCallback::InputStreamCallback()
119
  : mCalled(false)
120
0
{
121
0
}
122
123
InputStreamCallback::~InputStreamCallback()
124
0
{
125
0
}
126
127
NS_IMETHODIMP
128
InputStreamCallback::OnInputStreamReady(nsIAsyncInputStream* aStream)
129
0
{
130
0
  mCalled = true;
131
0
  return NS_OK;
132
0
}
133
134
AsyncStringStream::AsyncStringStream(const nsACString& aBuffer)
135
0
{
136
0
  NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
137
0
}
138
139
NS_IMETHODIMP
140
AsyncStringStream::Available(uint64_t* aLength)
141
0
{
142
0
  return mStream->Available(aLength);
143
0
}
144
145
NS_IMETHODIMP
146
AsyncStringStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount)
147
0
{
148
0
  return mStream->Read(aBuffer, aCount, aReadCount);
149
0
}
150
151
NS_IMETHODIMP
152
AsyncStringStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
153
                                uint32_t aCount, uint32_t *aResult)
154
0
{
155
0
  return NS_ERROR_NOT_IMPLEMENTED;
156
0
}
157
158
NS_IMETHODIMP
159
AsyncStringStream::Close()
160
0
{
161
0
  nsresult rv = mStream->Close();
162
0
  if (NS_SUCCEEDED(rv)) {
163
0
    MaybeExecCallback(mCallback, mCallbackEventTarget);
164
0
  }
165
0
  return rv;
166
0
}
167
168
NS_IMETHODIMP
169
AsyncStringStream::IsNonBlocking(bool* aNonBlocking)
170
0
{
171
0
  return mStream->IsNonBlocking(aNonBlocking);
172
0
}
173
174
NS_IMETHODIMP
175
AsyncStringStream::CloseWithStatus(nsresult aStatus)
176
0
{
177
0
  return Close();
178
0
}
179
180
NS_IMETHODIMP
181
AsyncStringStream::AsyncWait(nsIInputStreamCallback* aCallback,
182
                             uint32_t aFlags, uint32_t aRequestedCount,
183
                             nsIEventTarget* aEventTarget)
184
0
{
185
0
  if (aFlags & nsIAsyncInputStream::WAIT_CLOSURE_ONLY) {
186
0
    mCallback = aCallback;
187
0
    mCallbackEventTarget = aEventTarget;
188
0
    return NS_OK;
189
0
  }
190
0
191
0
  MaybeExecCallback(aCallback, aEventTarget);
192
0
  return NS_OK;
193
0
}
194
195
void
196
AsyncStringStream::MaybeExecCallback(nsIInputStreamCallback* aCallback,
197
                                     nsIEventTarget* aEventTarget)
198
0
{
199
0
  if (!aCallback) {
200
0
    return;
201
0
  }
202
0
203
0
  nsCOMPtr<nsIInputStreamCallback> callback = aCallback;
204
0
  nsCOMPtr<nsIAsyncInputStream> self = this;
205
0
206
0
  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
207
0
    "AsyncWait", [callback, self]() { callback->OnInputStreamReady(self); });
208
0
209
0
  if (aEventTarget) {
210
0
    aEventTarget->Dispatch(r.forget());
211
0
  } else {
212
0
    r->Run();
213
0
  }
214
0
}
215
216
NS_IMPL_ISUPPORTS(AsyncStringStream, nsIAsyncInputStream, nsIInputStream)
217
218
NS_IMPL_ADDREF(LengthInputStream);
219
NS_IMPL_RELEASE(LengthInputStream);
220
221
0
NS_INTERFACE_MAP_BEGIN(LengthInputStream)
222
0
  NS_INTERFACE_MAP_ENTRY(nsIInputStream)
223
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamLength, mIsInputStreamLength)
224
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStreamLength, mIsAsyncInputStreamLength)
225
0
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
226
0
NS_INTERFACE_MAP_END
227
228
NS_IMPL_ISUPPORTS(LengthCallback, nsIInputStreamLengthCallback)
229
230
} // namespace testing