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

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

Issue 2610063003: [i18n streaming] improve unit tests (Closed)
Patch Set: 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 // These constants are 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; 20 const int kSmallBufferSize = 1;
21 21
22 const int kShortReplacementOffset = 5; 22 struct I18nTest {
23 const char kShortReplacementKey[] = "a"; 23 I18nTest(const char* input, const char* expected_output)
mmenke 2017/01/04 16:12:50 To avoid static initializers, I think this needs t
dschuyler 2017/01/04 23:06:53 Done.
24 const char kShortReplacementToken[] = "$i18n{a}"; 24 : input(input), expected_output(expected_output) {}
25 const char kShortReplacementValue[] = "short";
26 25
27 const int kLongReplacementOffset = 33; 26 const char* input;
28 const char kLongReplacementKey[] = "aLongerReplacementName"; 27 const char* expected_output;
29 const char kLongReplacementToken[] = "$i18n{aLongerReplacementName}"; 28 };
30 const char kLongReplacementValue[] = "second replacement";
31 29
32 const int kSourceSize = 30 const I18nTest kTestNoReplacements =
33 50 + arraysize(kShortReplacementToken) + arraysize(kLongReplacementToken); 31 I18nTest("This text has no i18n replacements.",
34 const int kResultSize = 32 "This text has no i18n replacements.");
35 50 + arraysize(kShortReplacementValue) + arraysize(kLongReplacementValue); 33
34 const I18nTest kTestTagAtEndOfLine = I18nTest("test with tag at end of line $",
35 "test with tag at end of line $");
36
37 const I18nTest kTestOneReplacement = I18nTest("$i18n{alpha}", "apple");
38
39 const I18nTest kTestOneReplacementPlus =
40 I18nTest("Extra text $i18n{alpha}.", "Extra text apple.");
41
42 const I18nTest kTestThreeReplacements =
43 I18nTest("$i18n{alpha}^$i18n{beta}_$i18n{gamma}", "apple^banana_carrot");
44
45 const I18nTest kTestExtraBraces =
46 I18nTest("($i18n{alpha})^_^_^_^_$i18n{beta}_beta_$i18n{gamma}}}}}}",
47 "(apple)^_^_^_^_banana_beta_carrot}}}}}");
48
49 const I18nTest kTest1 =
dschuyler 2017/01/04 01:07:51 I kinda wanted better names than kTest1 and kTest2
mmenke 2017/01/04 16:12:50 Maybe just a comment along those lines?
dschuyler 2017/01/04 23:06:52 Done.
50 I18nTest(" } $($i18n{gamma})^_^_^_^_$i18n{alpha}_$i18n{gamma}$",
51 " } $(carrot)^_^_^_^_apple_carrot$");
52
53 const I18nTest kTest2 =
54 I18nTest("$i18n{alpha} gamma}{ ^_^_^_^_$abc{beta}:$i18n{gamma}z",
55 "apple gamma}{ ^_^_^_^_$abc{beta}:carrotz");
36 56
37 struct I18nTestParam { 57 struct I18nTestParam {
38 I18nTestParam(int buf_size, net::MockSourceStream::Mode read_mode) 58 I18nTestParam(int buf_size,
mmenke 2017/01/04 16:12:49 per above comment, this should be constexpr as wel
dschuyler 2017/01/04 23:06:53 Done.
39 : buffer_size(buf_size), mode(read_mode) {} 59 net::MockSourceStream::Mode read_mode,
60 const I18nTest* test)
61 : buffer_size(buf_size), mode(read_mode), test(test) {}
40 62
41 const int buffer_size; 63 const int buffer_size;
42 const net::MockSourceStream::Mode mode; 64 const net::MockSourceStream::Mode mode;
65 const I18nTest* test;
43 }; 66 };
44 67
45 } // namespace 68 } // namespace
46 69
47 class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> { 70 class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> {
48 protected: 71 protected:
49 I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {} 72 I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {}
50 73
51 // Helpful function to initialize the test fixture. 74 // Helpful function to initialize the test fixture.
52 void Init() { 75 void Init() {
53 source_data_len_ = kBufferSize; 76 std::memset(padding, 'z', 1024);
mmenke 2017/01/04 16:12:50 Maybe make this more interesting? (0x00 to 0xFF r
dschuyler 2017/01/04 23:06:52 I wanted to exclude nulls. I think it's more likel
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 77
73 output_buffer_ = new net::IOBuffer(output_buffer_size_); 78 output_buffer_ = new net::IOBuffer(output_buffer_size_);
74 std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream()); 79 std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
75 source_ = source.get(); 80 source_ = source.get();
76 81
77 replacements_[kShortReplacementKey] = kShortReplacementValue; 82 replacements_["alpha"] = "apple";
78 replacements_[kLongReplacementKey] = kLongReplacementValue; 83 replacements_["beta"] = "banana";
84 replacements_["gamma"] = "carrot";
79 stream_ = I18nSourceStream::Create( 85 stream_ = I18nSourceStream::Create(
80 std::move(source), net::SourceStream::TYPE_NONE, &replacements_); 86 std::move(source), net::SourceStream::TYPE_NONE, &replacements_);
81 } 87 }
82 88
83 // If MockSourceStream::Mode is ASYNC, completes 1 read from |mock_stream| and 89 // 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 90 // wait for |callback| to complete. If Mode is not ASYNC, does nothing and
85 // returns |previous_result|. 91 // returns |previous_result|.
86 int CompleteReadIfAsync(int previous_result, 92 int CompleteReadIfAsync(int previous_result,
87 net::TestCompletionCallback* callback, 93 net::TestCompletionCallback* callback,
88 net::MockSourceStream* mock_stream) { 94 net::MockSourceStream* mock_stream) {
89 if (GetParam().mode == net::MockSourceStream::ASYNC) { 95 if (GetParam().mode == net::MockSourceStream::ASYNC) {
90 EXPECT_EQ(net::ERR_IO_PENDING, previous_result); 96 EXPECT_EQ(net::ERR_IO_PENDING, previous_result);
91 mock_stream->CompleteNextRead(); 97 mock_stream->CompleteNextRead();
92 return callback->WaitForResult(); 98 return callback->WaitForResult();
93 } 99 }
94 return previous_result; 100 return previous_result;
95 } 101 }
96 102
97 void InsertText(char* buffer, 103 char padding[1024];
mmenke 2017/01/04 16:12:49 padding_. Should also be below all methods.
dschuyler 2017/01/04 23:06:53 Done.
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 104
115 net::IOBuffer* output_buffer() { return output_buffer_.get(); } 105 net::IOBuffer* output_buffer() { return output_buffer_.get(); }
116 char* output_data() { return output_buffer_->data(); } 106 char* output_data() { return output_buffer_->data(); }
117 size_t output_buffer_size() { return output_buffer_size_; } 107 size_t output_buffer_size() { return output_buffer_size_; }
118 108
119 net::MockSourceStream* source() { return source_; } 109 net::MockSourceStream* source() { return source_; }
120 I18nSourceStream* stream() { return stream_.get(); } 110 I18nSourceStream* stream() { return stream_.get(); }
121 111
122 // Reads from |stream_| until an error occurs or the EOF is reached. 112 // 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, 113 // When an error occurs, returns the net error code. When an EOF is reached,
(...skipping 11 matching lines...) Expand all
135 if (rv < net::OK) 125 if (rv < net::OK)
136 return rv; 126 return rv;
137 EXPECT_GT(rv, net::OK); 127 EXPECT_GT(rv, net::OK);
138 bytes_read += rv; 128 bytes_read += rv;
139 output->append(output_data(), rv); 129 output->append(output_data(), rv);
140 } 130 }
141 return bytes_read; 131 return bytes_read;
142 } 132 }
143 133
144 private: 134 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_; 135 scoped_refptr<net::IOBuffer> output_buffer_;
152 const int output_buffer_size_; 136 const int output_buffer_size_;
153 137
154 net::MockSourceStream* source_; 138 net::MockSourceStream* source_;
155 std::unique_ptr<I18nSourceStream> stream_; 139 std::unique_ptr<I18nSourceStream> stream_;
156 140
157 ui::TemplateReplacements replacements_; 141 ui::TemplateReplacements replacements_;
158 }; 142 };
159 143
160 INSTANTIATE_TEST_CASE_P( 144 INSTANTIATE_TEST_CASE_P(
161 I18nSourceStreamTests, 145 I18nSourceStreamTests,
162 I18nSourceStreamTest, 146 I18nSourceStreamTest,
163 ::testing::Values(I18nTestParam(kBufferSize, net::MockSourceStream::SYNC), 147 ::testing::Values(
164 I18nTestParam(kSmallBufferSize, 148 I18nTestParam(kBufferSize,
165 net::MockSourceStream::SYNC))); 149 net::MockSourceStream::SYNC,
150 &kTestNoReplacements),
mmenke 2017/01/04 16:12:50 optional: Suggest arranging these by string, rathe
dschuyler 2017/01/04 23:06:53 Done.
151 I18nTestParam(kBufferSize,
152 net::MockSourceStream::SYNC,
153 &kTestTagAtEndOfLine),
154 I18nTestParam(kBufferSize,
155 net::MockSourceStream::SYNC,
156 &kTestOneReplacement),
157 I18nTestParam(kBufferSize,
158 net::MockSourceStream::SYNC,
159 &kTestOneReplacementPlus),
160 I18nTestParam(kBufferSize,
161 net::MockSourceStream::SYNC,
162 &kTestThreeReplacements),
163 I18nTestParam(kBufferSize,
164 net::MockSourceStream::SYNC,
165 &kTestExtraBraces),
166 I18nTestParam(kBufferSize, net::MockSourceStream::SYNC, &kTest1),
167 I18nTestParam(kBufferSize, net::MockSourceStream::SYNC, &kTest2),
168 I18nTestParam(kSmallBufferSize,
169 net::MockSourceStream::SYNC,
170 &kTestNoReplacements),
171 I18nTestParam(kSmallBufferSize,
172 net::MockSourceStream::SYNC,
173 &kTestTagAtEndOfLine),
174 I18nTestParam(kSmallBufferSize,
175 net::MockSourceStream::SYNC,
176 &kTestOneReplacement),
177 I18nTestParam(kSmallBufferSize,
178 net::MockSourceStream::SYNC,
179 &kTestOneReplacementPlus),
180 I18nTestParam(kSmallBufferSize,
181 net::MockSourceStream::SYNC,
182 &kTestThreeReplacements),
183 I18nTestParam(kSmallBufferSize,
184 net::MockSourceStream::SYNC,
185 &kTestExtraBraces),
186 I18nTestParam(kSmallBufferSize, net::MockSourceStream::SYNC, &kTest1),
187 I18nTestParam(kSmallBufferSize, net::MockSourceStream::SYNC, &kTest2)));
mmenke 2017/01/04 16:12:50 No async tests? Looks like that was the case befo
dschuyler 2017/01/04 23:06:53 I make the param optional. So it's semi-removed. I
166 188
167 TEST_P(I18nSourceStreamTest, EmptyStream) { 189 TEST_P(I18nSourceStreamTest, EmptyStream) {
dschuyler 2017/01/04 01:07:51 I wanted to run this as a const I18nTest kTestNoR
mmenke 2017/01/04 16:12:49 Should this just be TEST_F, with a sync and async
mmenke 2017/01/04 16:12:50 The reason for that is that your test would add tw
dschuyler 2017/01/04 23:06:53 Done.
dschuyler 2017/01/04 23:06:53 Acknowledged.
168 Init(); 190 Init();
169 source()->AddReadResult("", 0, net::OK, GetParam().mode); 191 source()->AddReadResult("", 0, net::OK, GetParam().mode);
mmenke 2017/01/04 16:12:49 "" -> nullptr
dschuyler 2017/01/04 23:06:53 Done.
170 std::string actual_output; 192 std::string actual_output;
171 int result = ReadStream(&actual_output); 193 int result = ReadStream(&actual_output);
172 EXPECT_EQ(net::OK, result); 194 EXPECT_EQ(net::OK, result);
173 EXPECT_EQ("i18n", stream()->Description()); 195 EXPECT_EQ("i18n", stream()->Description());
174 } 196 }
175 197
176 TEST_P(I18nSourceStreamTest, NoTranslations) {
dschuyler 2017/01/04 01:07:51 This is replaced by kTestNoReplacements.
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) { 198 TEST_P(I18nSourceStreamTest, I18nOneRead) {
190 Init(); 199 Init();
191 source()->AddReadResult(source_data(), kSourceSize, net::OK, GetParam().mode); 200 size_t source_size = strlen(GetParam().test->input);
201 source()->AddReadResult(GetParam().test->input, source_size, net::OK,
202 GetParam().mode);
192 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode); 203 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
193 std::string actual_output; 204 std::string actual_output;
194 int rv = ReadStream(&actual_output); 205 int rv = ReadStream(&actual_output);
206 size_t kResultSize = strlen(GetParam().test->expected_output);
mmenke 2017/01/04 16:12:50 result_size
dschuyler 2017/01/04 23:06:53 Done.
195 EXPECT_EQ(static_cast<int>(kResultSize), rv); 207 EXPECT_EQ(static_cast<int>(kResultSize), rv);
196 EXPECT_EQ(std::string(result_data(), kResultSize), actual_output); 208 EXPECT_EQ(std::string(GetParam().test->expected_output, kResultSize),
209 actual_output);
197 EXPECT_EQ("i18n", stream()->Description()); 210 EXPECT_EQ("i18n", stream()->Description());
198 } 211 }
199 212
200 TEST_P(I18nSourceStreamTest, I18nInMultipleReads) { 213 TEST_P(I18nSourceStreamTest, I18nInMultipleReads) {
201 Init(); 214 Init();
202 size_t chunk_size = 5; 215 size_t chunk_size = 5;
203 size_t written = 0; 216 size_t written = 0;
217 size_t kSourceSize = strlen(GetParam().test->input);
mmenke 2017/01/04 16:12:50 source_size
dschuyler 2017/01/04 23:06:53 Done.
204 while (written + chunk_size < kSourceSize) { 218 while (written + chunk_size < kSourceSize) {
205 source()->AddReadResult(source_data() + written, chunk_size, net::OK, 219 source()->AddReadResult(GetParam().test->input + written, chunk_size,
206 GetParam().mode); 220 net::OK, GetParam().mode);
207 written += chunk_size; 221 written += chunk_size;
208 } 222 }
209 source()->AddReadResult(source_data() + written, kSourceSize - written, 223 source()->AddReadResult(GetParam().test->input + written,
210 net::OK, GetParam().mode); 224 kSourceSize - written, net::OK, GetParam().mode);
mmenke 2017/01/04 16:12:50 Suggest just rewriting the loop to include this re
dschuyler 2017/01/04 23:06:53 Done.
211 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode); 225 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
212 std::string actual_output; 226 std::string actual_output;
213 int rv = ReadStream(&actual_output); 227 int rv = ReadStream(&actual_output);
228 size_t kResultSize = strlen(GetParam().test->expected_output);
mmenke 2017/01/04 16:12:49 result_size
dschuyler 2017/01/04 23:06:53 Done.
214 EXPECT_EQ(static_cast<int>(kResultSize), rv); 229 EXPECT_EQ(static_cast<int>(kResultSize), rv);
215 EXPECT_EQ(std::string(result_data(), kResultSize), actual_output); 230 EXPECT_EQ(std::string(GetParam().test->expected_output, kResultSize),
231 actual_output);
216 EXPECT_EQ("i18n", stream()->Description()); 232 EXPECT_EQ("i18n", stream()->Description());
217 } 233 }
218 234
219 TEST_P(I18nSourceStreamTest, I18nTagAtEndOfLine) { 235 TEST_P(I18nSourceStreamTest, I18nLargeAndInMultipleReads) {
dschuyler 2017/01/04 01:07:51 This test was replaced with kTestTagAtEndOfLine an
220 Init(); 236 Init();
221 const char kSourceData[] = "test with tag at end of line $"; 237 for (int i = 0; i < 1024; ++i) {
mmenke 2017/01/04 16:12:50 Should probably have two 1024 consts here (One for
dschuyler 2017/01/04 23:06:53 I reworked this. PTAL.
222 const size_t source_size = strlen(kSourceData); 238 source()->AddReadResult(padding, 1024, net::OK, GetParam().mode);
mmenke 2017/01/04 16:12:50 Given that this is the only test that uses padding
dschuyler 2017/01/04 23:06:53 The function is called once per I18nTestParam, so
mmenke 2017/01/04 23:10:09 The test fixture is re-created for each test that'
mmenke 2017/01/04 23:18:38 (Beyond being a different class instance, they're
dschuyler 2017/01/04 23:33:10 You're right of course. I should have realized tha
dschuyler 2017/01/04 23:33:11 Acknowledged.
223 source()->AddReadResult(kSourceData, source_size, net::OK, GetParam().mode); 239 }
240 size_t chunk_size = 5;
241 size_t written = 0;
242 size_t kSourceSize = strlen(GetParam().test->input);
mmenke 2017/01/04 16:12:50 source_size
dschuyler 2017/01/04 23:06:52 Done.
243 while (written + chunk_size < kSourceSize) {
244 source()->AddReadResult(GetParam().test->input + written, chunk_size,
245 net::OK, GetParam().mode);
246 written += chunk_size;
247 }
248 source()->AddReadResult(GetParam().test->input + written,
249 kSourceSize - written, net::OK, GetParam().mode);
mmenke 2017/01/04 16:12:50 Same suggestion as for the previous test here.
dschuyler 2017/01/04 23:06:53 Done.
224 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode); 250 source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
225 std::string actual_output; 251 std::string actual_output;
226 int rv = ReadStream(&actual_output); 252 int rv = ReadStream(&actual_output);
227 EXPECT_EQ(static_cast<int>(source_size), rv); 253 size_t kResultSize = strlen(GetParam().test->expected_output);
mmenke 2017/01/04 16:12:50 result_size
dschuyler 2017/01/04 23:06:53 Done.
228 EXPECT_EQ(kSourceData, actual_output); 254 EXPECT_EQ(static_cast<int>(kResultSize) + 1024 * 1024, rv);
255 EXPECT_EQ(std::string(GetParam().test->expected_output, kResultSize),
256 &actual_output[1024 * 1024]);
mmenke 2017/01/04 16:12:49 Check the padding matches as well?
dschuyler 2017/01/04 23:06:53 Done.
229 EXPECT_EQ("i18n", stream()->Description()); 257 EXPECT_EQ("i18n", stream()->Description());
230 } 258 }
231 259
232 } // namespace content 260 } // 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