Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: content/browser/webui/i18n_source_stream_unittest.cc

Issue 2610063003: [i18n streaming] improve unit tests (Closed)
Patch Set: move padding init Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <utility> 5 #include <utility>
6 6
7 #include "content/browser/webui/i18n_source_stream.h" 7 #include "content/browser/webui/i18n_source_stream.h"
8 #include "net/base/io_buffer.h" 8 #include "net/base/io_buffer.h"
9 #include "net/base/test_completion_callback.h" 9 #include "net/base/test_completion_callback.h"
10 #include "net/filter/mock_source_stream.h" 10 #include "net/filter/mock_source_stream.h"
11 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 namespace { 15 namespace {
16 16
17 // These constants are rather arbitrary, though the offsets and other sizes must 17 // This constant is rather arbitrary, though the offsets and other sizes must
18 // be less than kBufferSize. 18 // be less than kBufferSize.
19 const int kBufferSize = 256; 19 const int kBufferSize = 256;
20 const int kSmallBufferSize = 1;
21 20
22 const int kShortReplacementOffset = 5; 21 const int kMinimumSize = 1;
23 const char kShortReplacementKey[] = "a"; 22 const int kSmallSize = 5; // Arbitrary small value > 1.
24 const char kShortReplacementToken[] = "$i18n{a}"; 23 const int kInOneReadSize = INT_MAX;
25 const char kShortReplacementValue[] = "short";
26 24
27 const int kLongReplacementOffset = 33; 25 const int kPadCount = 1024; // Arbitrary number of pads to add.
28 const char kLongReplacementKey[] = "aLongerReplacementName";
29 const char kLongReplacementToken[] = "$i18n{aLongerReplacementName}";
30 const char kLongReplacementValue[] = "second replacement";
31 26
32 const int kSourceSize = 27 struct I18nTest {
33 50 + arraysize(kShortReplacementToken) + arraysize(kLongReplacementToken); 28 constexpr I18nTest(const char* input, const char* expected_output)
34 const int kResultSize = 29 : input(input), expected_output(expected_output) {}
35 50 + arraysize(kShortReplacementValue) + arraysize(kLongReplacementValue); 30
31 const char* input;
32 const char* expected_output;
33 };
34
35 constexpr I18nTest kTestEmpty = I18nTest("", "");
36
37 constexpr I18nTest kTestNoReplacements =
38 I18nTest("This text has no i18n replacements.",
39 "This text has no i18n replacements.");
40
41 constexpr I18nTest kTestTagAtEndOfLine =
42 I18nTest("test with tag at end of line $",
43 "test with tag at end of line $");
44
45 constexpr I18nTest kTestOneReplacement = I18nTest("$i18n{alpha}", "apple");
46
47 constexpr I18nTest kTestOneReplacementPlus =
48 I18nTest("Extra text $i18n{alpha}.", "Extra text apple.");
49
50 constexpr I18nTest kTestThreeReplacements =
51 I18nTest("$i18n{alpha}^$i18n{beta}_$i18n{gamma}", "apple^banana_carrot");
52
53 constexpr I18nTest kTestExtraBraces =
54 I18nTest("($i18n{alpha})^_^_^_^_$i18n{beta}_beta_$i18n{gamma}}}}}}",
55 "(apple)^_^_^_^_banana_beta_carrot}}}}}");
56
57 // These tests with generic names are sequences that might catch an error in the
58 // future, depending on how the code changes.
59 constexpr I18nTest kTest1 =
60 I18nTest(" } $($i18n{gamma})^_^_^_^_$i18n{alpha}_$i18n{gamma}$",
61 " } $(carrot)^_^_^_^_apple_carrot$");
62
63 constexpr I18nTest kTest2 =
64 I18nTest("$i18n{alpha} gamma}{ ^_^_^_^_$abc{beta}:$i18n{gamma}z",
65 "apple gamma}{ ^_^_^_^_$abc{beta}:carrotz");
36 66
37 struct I18nTestParam { 67 struct I18nTestParam {
38 I18nTestParam(int buf_size, net::MockSourceStream::Mode read_mode) 68 constexpr I18nTestParam(
39 : buffer_size(buf_size), mode(read_mode) {} 69 const I18nTest* test,
70 int buf_size,
71 int read_size,
72 int pad_count = 0,
73 net::MockSourceStream::Mode read_mode = net::MockSourceStream::SYNC)
74 : buffer_size(buf_size),
75 read_size(read_size),
76 pad_count(pad_count),
77 mode(read_mode),
78 test(test) {}
40 79
41 const int buffer_size; 80 const int buffer_size;
81 const int read_size;
82 const int pad_count;
mmenke 2017/01/05 17:25:53 Suggest a bool instead - add_padding, and then add
dschuyler 2017/01/06 22:33:28 Acknowledged.
42 const net::MockSourceStream::Mode mode; 83 const net::MockSourceStream::Mode mode;
84 const I18nTest* test;
43 }; 85 };
44 86
45 } // namespace 87 } // namespace
46 88
47 class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> { 89 class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> {
48 protected: 90 protected:
49 I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {} 91 I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {}
50 92
51 // Helpful function to initialize the test fixture. 93 // Helpful function to initialize the test fixture.
52 void Init() { 94 void Init() {
53 source_data_len_ = kBufferSize;
54 for (size_t i = 0; i < source_data_len_; i++)
55 source_data_[i] = i % 256;
56
57 // Inserts must be done last to first as they appear in the buffer.
58 InsertText(source_data_, source_data_len_, kLongReplacementOffset,
59 kLongReplacementToken);
60 InsertText(source_data_, source_data_len_, kShortReplacementOffset,
61 kShortReplacementToken);
62
63 result_data_len_ = kBufferSize;
64 for (size_t i = 0; i < result_data_len_; i++)
65 result_data_[i] = i % 256;
66
67 // Inserts must be done last to first as they appear in the buffer.
68 InsertText(result_data_, result_data_len_, kLongReplacementOffset,
69 kLongReplacementValue);
70 InsertText(result_data_, result_data_len_, kShortReplacementOffset,
71 kShortReplacementValue);
72
73 output_buffer_ = new net::IOBuffer(output_buffer_size_); 95 output_buffer_ = new net::IOBuffer(output_buffer_size_);
74 std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream()); 96 std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
75 source_ = source.get(); 97 source_ = source.get();
76 98
77 replacements_[kShortReplacementKey] = kShortReplacementValue; 99 replacements_["alpha"] = "apple";
78 replacements_[kLongReplacementKey] = kLongReplacementValue; 100 replacements_["beta"] = "banana";
101 replacements_["gamma"] = "carrot";
79 stream_ = I18nSourceStream::Create( 102 stream_ = I18nSourceStream::Create(
80 std::move(source), net::SourceStream::TYPE_NONE, &replacements_); 103 std::move(source), net::SourceStream::TYPE_NONE, &replacements_);
81 } 104 }
82 105
83 // If MockSourceStream::Mode is ASYNC, completes 1 read from |mock_stream| and 106 // If MockSourceStream::Mode is ASYNC, completes 1 read from |mock_stream| and
84 // wait for |callback| to complete. If Mode is not ASYNC, does nothing and 107 // wait for |callback| to complete. If Mode is not ASYNC, does nothing and
85 // returns |previous_result|. 108 // returns |previous_result|.
86 int CompleteReadIfAsync(int previous_result, 109 int CompleteReadIfAsync(int previous_result,
87 net::TestCompletionCallback* callback, 110 net::TestCompletionCallback* callback,
88 net::MockSourceStream* mock_stream) { 111 net::MockSourceStream* mock_stream) {
89 if (GetParam().mode == net::MockSourceStream::ASYNC) { 112 if (GetParam().mode == net::MockSourceStream::ASYNC) {
90 EXPECT_EQ(net::ERR_IO_PENDING, previous_result); 113 EXPECT_EQ(net::ERR_IO_PENDING, previous_result);
91 mock_stream->CompleteNextRead(); 114 mock_stream->CompleteNextRead();
92 return callback->WaitForResult(); 115 return callback->WaitForResult();
93 } 116 }
94 return previous_result; 117 return previous_result;
95 } 118 }
96 119
97 void InsertText(char* buffer,
98 size_t buffer_length,
99 size_t offset,
100 const char* text) {
101 // Intended to be dead simple so that it can be confirmed
102 // as correct by hand.
103 size_t text_length = strlen(text);
104 memmove(buffer + offset + text_length, buffer + offset,
105 buffer_length - offset - text_length);
106 memcpy(buffer + offset, text, text_length);
107 }
108
109 char* source_data() { return source_data_; }
110 size_t source_data_len() { return source_data_len_; }
111
112 char* result_data() { return result_data_; }
113 size_t result_data_len() { return result_data_len_; }
114
115 net::IOBuffer* output_buffer() { return output_buffer_.get(); } 120 net::IOBuffer* output_buffer() { return output_buffer_.get(); }
116 char* output_data() { return output_buffer_->data(); } 121 char* output_data() { return output_buffer_->data(); }
117 size_t output_buffer_size() { return output_buffer_size_; } 122 size_t output_buffer_size() { return output_buffer_size_; }
118 123
119 net::MockSourceStream* source() { return source_; } 124 net::MockSourceStream* source() { return source_; }
120 I18nSourceStream* stream() { return stream_.get(); } 125 I18nSourceStream* stream() { return stream_.get(); }
121 126
122 // Reads from |stream_| until an error occurs or the EOF is reached. 127 // Reads from |stream_| until an error occurs or the EOF is reached.
123 // When an error occurs, returns the net error code. When an EOF is reached, 128 // When an error occurs, returns the net error code. When an EOF is reached,
124 // returns the number of bytes read and appends data read to |output|. 129 // returns the number of bytes read and appends data read to |output|.
(...skipping 10 matching lines...) Expand all
135 if (rv < net::OK) 140 if (rv < net::OK)
136 return rv; 141 return rv;
137 EXPECT_GT(rv, net::OK); 142 EXPECT_GT(rv, net::OK);
138 bytes_read += rv; 143 bytes_read += rv;
139 output->append(output_data(), rv); 144 output->append(output_data(), rv);
140 } 145 }
141 return bytes_read; 146 return bytes_read;
142 } 147 }
143 148
144 private: 149 private:
145 char source_data_[kBufferSize];
146 size_t source_data_len_;
147
148 char result_data_[kBufferSize];
149 size_t result_data_len_;
150
151 scoped_refptr<net::IOBuffer> output_buffer_; 150 scoped_refptr<net::IOBuffer> output_buffer_;
152 const int output_buffer_size_; 151 const int output_buffer_size_;
153 152
154 net::MockSourceStream* source_; 153 net::MockSourceStream* source_;
155 std::unique_ptr<I18nSourceStream> stream_; 154 std::unique_ptr<I18nSourceStream> stream_;
156 155
157 ui::TemplateReplacements replacements_; 156 ui::TemplateReplacements replacements_;
158 }; 157 };
159 158
160 INSTANTIATE_TEST_CASE_P( 159 INSTANTIATE_TEST_CASE_P(
161 I18nSourceStreamTests, 160 I18nSourceStreamTests,
162 I18nSourceStreamTest, 161 I18nSourceStreamTest,
163 ::testing::Values(I18nTestParam(kBufferSize, net::MockSourceStream::SYNC), 162 ::testing::Values(
164 I18nTestParam(kSmallBufferSize, 163 // kBufferSize, kInOneReadSize
165 net::MockSourceStream::SYNC))); 164 I18nTestParam(&kTestEmpty, kBufferSize, kInOneReadSize),
165 I18nTestParam(&kTestNoReplacements, kBufferSize, kInOneReadSize),
mmenke 2017/01/05 17:25:53 Feel free not to do this, but "by string", I meant
dschuyler 2017/01/06 22:33:29 Done.
166 I18nTestParam(&kTestTagAtEndOfLine, kBufferSize, kInOneReadSize),
167 I18nTestParam(&kTestOneReplacement, kBufferSize, kInOneReadSize),
168 I18nTestParam(&kTestOneReplacementPlus, kBufferSize, kInOneReadSize),
169 I18nTestParam(&kTestThreeReplacements, kBufferSize, kInOneReadSize),
170 I18nTestParam(&kTestExtraBraces, kBufferSize, kInOneReadSize),
171 I18nTestParam(&kTest1, kBufferSize, kInOneReadSize),
172 I18nTestParam(&kTest2, kBufferSize, kInOneReadSize),
173 // kBufferSize, kInOneReadSize, kPadCount
174 I18nTestParam(&kTestEmpty, kBufferSize, kInOneReadSize, kPadCount),
175 I18nTestParam(&kTestNoReplacements,
176 kBufferSize,
177 kInOneReadSize,
178 kPadCount),
179 I18nTestParam(&kTestTagAtEndOfLine,
180 kBufferSize,
181 kInOneReadSize,
182 kPadCount),
183 I18nTestParam(&kTestOneReplacement,
184 kBufferSize,
185 kInOneReadSize,
186 kPadCount),
187 I18nTestParam(&kTestOneReplacementPlus,
188 kBufferSize,
189 kInOneReadSize,
190 kPadCount),
191 I18nTestParam(&kTestThreeReplacements,
192 kBufferSize,
193 kInOneReadSize,
194 kPadCount),
195 I18nTestParam(&kTestExtraBraces,
196 kBufferSize,
197 kInOneReadSize,
198 kPadCount),
199 I18nTestParam(&kTest1, kBufferSize, kInOneReadSize, kPadCount),
200 I18nTestParam(&kTest2, kBufferSize, kInOneReadSize, kPadCount),
201 // kBufferSize, kSmallSize
202 I18nTestParam(&kTestNoReplacements, kBufferSize, kSmallSize),
203 I18nTestParam(&kTestTagAtEndOfLine, kBufferSize, kSmallSize),
204 I18nTestParam(&kTestOneReplacement, kBufferSize, kSmallSize),
205 I18nTestParam(&kTestOneReplacementPlus, kBufferSize, kSmallSize),
206 I18nTestParam(&kTestThreeReplacements, kBufferSize, kSmallSize),
207 I18nTestParam(&kTestExtraBraces, kBufferSize, kSmallSize),
208 I18nTestParam(&kTest1, kBufferSize, kSmallSize),
209 I18nTestParam(&kTest2, kBufferSize, kSmallSize),
210 // kMinimumSize, kSmallSize
211 I18nTestParam(&kTestNoReplacements, kMinimumSize, kSmallSize),
212 I18nTestParam(&kTestTagAtEndOfLine, kMinimumSize, kSmallSize),
213 I18nTestParam(&kTestOneReplacement, kMinimumSize, kSmallSize),
214 I18nTestParam(&kTestOneReplacementPlus, kMinimumSize, kSmallSize),
215 I18nTestParam(&kTestThreeReplacements, kMinimumSize, kSmallSize),
216 I18nTestParam(&kTestExtraBraces, kMinimumSize, kSmallSize),
217 I18nTestParam(&kTest1, kMinimumSize, kSmallSize),
218 I18nTestParam(&kTest2, kMinimumSize, kSmallSize),
219 // kMinimumSize, kMinimumSize
220 I18nTestParam(&kTestNoReplacements, kMinimumSize, kMinimumSize),
221 I18nTestParam(&kTestTagAtEndOfLine, kMinimumSize, kMinimumSize),
222 I18nTestParam(&kTestOneReplacement, kMinimumSize, kMinimumSize),
223 I18nTestParam(&kTestOneReplacementPlus, kMinimumSize, kMinimumSize),
224 I18nTestParam(&kTestThreeReplacements, kMinimumSize, kMinimumSize),
225 I18nTestParam(&kTestExtraBraces, kMinimumSize, kMinimumSize),
226 I18nTestParam(&kTest1, kMinimumSize, kMinimumSize),
227 I18nTestParam(&kTest2, kMinimumSize, kMinimumSize)));
166 228
167 TEST_P(I18nSourceStreamTest, EmptyStream) { 229 TEST_P(I18nSourceStreamTest, I18nLargeAndInMultipleReads) {
mmenke 2017/01/05 17:25:53 I18nLargeAndInMultipleReads -> RunFilterTests? (O
mmenke 2017/01/05 17:25:53 optional: Could remove padding size from I18nTest
dschuyler 2017/01/06 22:33:28 FilterTests and LargeFilterTests?
dschuyler 2017/01/06 22:33:29 Done.
168 Init(); 230 Init();
169 source()->AddReadResult("", 0, net::OK, GetParam().mode); 231 char padding[1024]; // Arbitrary size.
232 for (size_t i = 0; i < sizeof padding; ++i)
233 padding[i] = i % 251; // 251 is prime and avoids power-of-two repetition.
mmenke 2017/01/05 17:25:53 suggest making this an std::string (Or making a pa
dschuyler 2017/01/06 22:33:28 Done.
234
235 // Create the chain of read buffers.
236 for (int i = 0; i < GetParam().pad_count; ++i) {
237 source()->AddReadResult(padding, sizeof padding, net::OK, GetParam().mode);
238 }
239 size_t chunk_size = GetParam().read_size;
240 size_t written = 0;
241 size_t source_size = strlen(GetParam().test->input);
242 while (written != source_size) {
243 size_t write_size = std::min(chunk_size, source_size - written);
244 source()->AddReadResult(GetParam().test->input + written, write_size,
245 net::OK, GetParam().mode);
246 written += write_size;
247 }
248 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
249
250 // Process the buffers.
170 std::string actual_output; 251 std::string actual_output;
171 int result = ReadStream(&actual_output); 252 int rv = ReadStream(&actual_output);
172 EXPECT_EQ(net::OK, result); 253
254 // Check the results.
255 size_t pad_size = GetParam().pad_count * sizeof padding;
256 std::string expected_output(GetParam().test->expected_output);
257 EXPECT_EQ(expected_output.size() + pad_size, static_cast<size_t>(rv));
mmenke 2017/01/05 17:25:53 ASSERT_EQ? If this fails, other EXPECTs may crash
dschuyler 2017/01/06 22:33:29 Done.
258 for (int i = 0; i < GetParam().pad_count; ++i) {
259 EXPECT_TRUE(actual_output.compare(sizeof padding * i, sizeof padding,
260 padding, sizeof padding) == 0);
mmenke 2017/01/05 17:25:53 EXPECT_EQ(padding (or padding_string), a
dschuyler 2017/01/06 22:33:28 Done.
261 }
262 EXPECT_EQ(expected_output, &actual_output[pad_size]);
173 EXPECT_EQ("i18n", stream()->Description()); 263 EXPECT_EQ("i18n", stream()->Description());
174 } 264 }
175 265
176 TEST_P(I18nSourceStreamTest, NoTranslations) {
177 Init();
178 const char kText[] = "This text has no i18n replacements.";
179 size_t kTextLength = strlen(kText);
180 source()->AddReadResult(kText, kTextLength, net::OK, GetParam().mode);
181 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
182 std::string actual_output;
183 int rv = ReadStream(&actual_output);
184 EXPECT_EQ(static_cast<int>(kTextLength), rv);
185 EXPECT_EQ(kText, actual_output);
186 EXPECT_EQ("i18n", stream()->Description());
187 }
188
189 TEST_P(I18nSourceStreamTest, I18nOneRead) {
190 Init();
191 source()->AddReadResult(source_data(), kSourceSize, net::OK, GetParam().mode);
192 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
193 std::string actual_output;
194 int rv = ReadStream(&actual_output);
195 EXPECT_EQ(static_cast<int>(kResultSize), rv);
196 EXPECT_EQ(std::string(result_data(), kResultSize), actual_output);
197 EXPECT_EQ("i18n", stream()->Description());
198 }
199
200 TEST_P(I18nSourceStreamTest, I18nInMultipleReads) {
201 Init();
202 size_t chunk_size = 5;
203 size_t written = 0;
204 while (written + chunk_size < kSourceSize) {
205 source()->AddReadResult(source_data() + written, chunk_size, net::OK,
206 GetParam().mode);
207 written += chunk_size;
208 }
209 source()->AddReadResult(source_data() + written, kSourceSize - written,
210 net::OK, GetParam().mode);
211 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
212 std::string actual_output;
213 int rv = ReadStream(&actual_output);
214 EXPECT_EQ(static_cast<int>(kResultSize), rv);
215 EXPECT_EQ(std::string(result_data(), kResultSize), actual_output);
216 EXPECT_EQ("i18n", stream()->Description());
217 }
218
219 TEST_P(I18nSourceStreamTest, I18nTagAtEndOfLine) {
220 Init();
221 const char kSourceData[] = "test with tag at end of line $";
222 const size_t source_size = strlen(kSourceData);
223 source()->AddReadResult(kSourceData, source_size, net::OK, GetParam().mode);
224 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
225 std::string actual_output;
226 int rv = ReadStream(&actual_output);
227 EXPECT_EQ(static_cast<int>(source_size), rv);
228 EXPECT_EQ(kSourceData, actual_output);
229 EXPECT_EQ("i18n", stream()->Description());
230 }
231
232 } // namespace content 266 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698