1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #include "converter/segments.h"
31
32 #include <string>
33 #include <vector>
34
35 #include "base/number_util.h"
36 #include "base/system_util.h"
37 #include "base/util.h"
38 #include "config/config_handler.h"
39 #include "testing/base/public/gunit.h"
40
41 namespace mozc {
42
TEST(SegmentsTest,BasicTest)43 TEST(SegmentsTest, BasicTest) {
44 Segments segments;
45
46 // flags
47 segments.set_request_type(Segments::CONVERSION);
48 EXPECT_EQ(Segments::CONVERSION, segments.request_type());
49
50 segments.set_request_type(Segments::SUGGESTION);
51 EXPECT_EQ(Segments::SUGGESTION, segments.request_type());
52
53 segments.set_user_history_enabled(true);
54 EXPECT_TRUE(segments.user_history_enabled());
55
56 segments.set_user_history_enabled(false);
57 EXPECT_FALSE(segments.user_history_enabled());
58
59 EXPECT_EQ(0, segments.segments_size());
60
61 const int kSegmentsSize = 5;
62 Segment *seg[kSegmentsSize];
63 for (int i = 0; i < kSegmentsSize; ++i) {
64 EXPECT_EQ(i, segments.segments_size());
65 seg[i] = segments.push_back_segment();
66 EXPECT_EQ(i + 1, segments.segments_size());
67 }
68
69 const string output = segments.DebugString();
70 EXPECT_FALSE(output.empty());
71
72 EXPECT_FALSE(segments.resized());
73 segments.set_resized(true);
74 EXPECT_TRUE(segments.resized());
75 segments.set_resized(false);
76 EXPECT_FALSE(segments.resized());
77
78 segments.set_max_history_segments_size(10);
79 EXPECT_EQ(10, segments.max_history_segments_size());
80
81 segments.set_max_history_segments_size(5);
82 EXPECT_EQ(5, segments.max_history_segments_size());
83
84 segments.set_max_prediction_candidates_size(10);
85 EXPECT_EQ(10, segments.max_prediction_candidates_size());
86
87 segments.set_max_prediction_candidates_size(5);
88 EXPECT_EQ(5, segments.max_prediction_candidates_size());
89
90 for (int i = 0; i < kSegmentsSize; ++i) {
91 EXPECT_EQ(seg[i], segments.mutable_segment(i));
92 }
93
94 segments.pop_back_segment();
95 EXPECT_EQ(seg[3], segments.mutable_segment(3));
96
97 segments.pop_front_segment();
98 EXPECT_EQ(seg[1], segments.mutable_segment(0));
99
100 segments.Clear();
101 EXPECT_EQ(0, segments.segments_size());
102
103 for (int i = 0; i < kSegmentsSize; ++i) {
104 seg[i] = segments.push_back_segment();
105 }
106
107 // erase
108 segments.erase_segment(1);
109 EXPECT_EQ(seg[0], segments.mutable_segment(0));
110 EXPECT_EQ(seg[2], segments.mutable_segment(1));
111
112 segments.erase_segments(1, 2);
113 EXPECT_EQ(seg[0], segments.mutable_segment(0));
114 EXPECT_EQ(seg[4], segments.mutable_segment(1));
115
116 EXPECT_EQ(2, segments.segments_size());
117
118 segments.erase_segments(0, 1);
119 EXPECT_EQ(1, segments.segments_size());
120 EXPECT_EQ(seg[4], segments.mutable_segment(0));
121
122 // insert
123 seg[1] = segments.insert_segment(1);
124 EXPECT_EQ(seg[1], segments.mutable_segment(1));
125
126 segments.Clear();
127 for (int i = 0; i < kSegmentsSize; ++i) {
128 seg[i] = segments.push_back_segment();
129 if (i < 2) {
130 seg[i]->set_segment_type(Segment::HISTORY);
131 }
132 }
133
134 // history/conversion
135 for (int i = 0; i < 3; ++i) {
136 EXPECT_EQ(segments.mutable_segment(i + segments.history_segments_size()),
137 segments.mutable_conversion_segment(i));
138 }
139
140 EXPECT_EQ(2, segments.history_segments_size());
141 EXPECT_EQ(3, segments.conversion_segments_size());
142
143 EXPECT_EQ(seg[2], segments.mutable_conversion_segment(0));
144 EXPECT_EQ(seg[0], segments.mutable_history_segment(0));
145
146 segments.clear_history_segments();
147 EXPECT_EQ(3, segments.segments_size());
148
149 segments.clear_conversion_segments();
150 EXPECT_EQ(0, segments.segments_size());
151 }
152
TEST(CandidateTest,BasicTest)153 TEST(CandidateTest, BasicTest) {
154 Segment segment;
155
156 const char str[] = "this is a test";
157 segment.set_key(str);
158 EXPECT_EQ(segment.key(), str);
159
160 segment.set_segment_type(Segment::FIXED_BOUNDARY);
161 EXPECT_EQ(Segment::FIXED_BOUNDARY, segment.segment_type());
162
163 const int kCandidatesSize = 5;
164 Segment::Candidate *cand[kCandidatesSize];
165 for (int i = 0; i < kCandidatesSize; ++i) {
166 EXPECT_EQ(i, segment.candidates_size());
167 cand[i] = segment.push_back_candidate();
168 EXPECT_EQ(i + 1, segment.candidates_size());
169 }
170
171 for (int i = 0; i < kCandidatesSize; ++i) {
172 EXPECT_EQ(cand[i], segment.mutable_candidate(i));
173 }
174
175 for (int i = 0; i < kCandidatesSize; ++i) {
176 EXPECT_EQ(i, segment.indexOf(segment.mutable_candidate(i)));
177 }
178
179 for (int i = -static_cast<int>(segment.meta_candidates_size()) - 1;
180 i >= 0; ++i) {
181 EXPECT_EQ(i, segment.indexOf(segment.mutable_candidate(i)));
182 }
183
184 EXPECT_EQ(segment.candidates_size(),
185 segment.indexOf(NULL));
186
187 segment.pop_back_candidate();
188 EXPECT_EQ(cand[3], segment.mutable_candidate(3));
189
190 segment.pop_front_candidate();
191 EXPECT_EQ(cand[1], segment.mutable_candidate(0));
192
193 segment.Clear();
194 EXPECT_EQ(0, segment.candidates_size());
195
196 for (int i = 0; i < kCandidatesSize; ++i) {
197 cand[i] = segment.push_back_candidate();
198 }
199
200 // erase
201 segment.erase_candidate(1);
202 EXPECT_EQ(cand[0], segment.mutable_candidate(0));
203 EXPECT_EQ(cand[2], segment.mutable_candidate(1));
204
205 segment.erase_candidates(1, 2);
206 EXPECT_EQ(cand[0], segment.mutable_candidate(0));
207 EXPECT_EQ(cand[4], segment.mutable_candidate(1));
208 EXPECT_EQ(2, segment.candidates_size());
209
210 // insert
211 cand[1] = segment.insert_candidate(1);
212 EXPECT_EQ(cand[1], segment.mutable_candidate(1));
213 EXPECT_EQ(cand[4], segment.mutable_candidate(2));
214
215 // move
216 segment.Clear();
217 for (int i = 0; i < kCandidatesSize; ++i) {
218 cand[i] = segment.push_back_candidate();
219 }
220
221 segment.move_candidate(2, 0);
222 EXPECT_EQ(cand[2], segment.mutable_candidate(0));
223 EXPECT_EQ(cand[0], segment.mutable_candidate(1));
224 EXPECT_EQ(cand[1], segment.mutable_candidate(2));
225 }
226
TEST(CandidateTest,CopyFrom)227 TEST(CandidateTest, CopyFrom) {
228 Segment::Candidate src, dest;
229 src.Init();
230
231 src.key = "key";
232 src.value = "value";
233 src.content_key = "content_key";
234 src.content_value = "content_value";
235 src.prefix = "prefix";
236 src.suffix = "suffix";
237 src.description = "description";
238 src.usage_title = "usage_title";
239 src.usage_description = "usage_description";
240 src.cost = 1;
241 src.wcost = 2;
242 src.structure_cost = 3;
243 src.lid = 4;
244 src.rid = 5;
245 src.attributes = 6;
246 src.style = NumberUtil::NumberString::NUMBER_CIRCLED;
247 src.command = Segment::Candidate::DISABLE_PRESENTATION_MODE;
248 src.PushBackInnerSegmentBoundary(1, 3, 5, 7);
249
250 dest.CopyFrom(src);
251
252 EXPECT_EQ(src.key, dest.key);
253 EXPECT_EQ(src.value, dest.value);
254 EXPECT_EQ(src.content_key, dest.content_key);
255 EXPECT_EQ(src.content_value, dest.content_value);
256 EXPECT_EQ(src.prefix, dest.prefix);
257 EXPECT_EQ(src.suffix, dest.suffix);
258 EXPECT_EQ(src.description, dest.description);
259 EXPECT_EQ(src.usage_title, dest.usage_title);
260 EXPECT_EQ(src.usage_description, dest.usage_description);
261 EXPECT_EQ(src.cost, dest.cost);
262 EXPECT_EQ(src.wcost, dest.wcost);
263 EXPECT_EQ(src.structure_cost, dest.structure_cost);
264 EXPECT_EQ(src.lid, dest.lid);
265 EXPECT_EQ(src.rid, dest.rid);
266 EXPECT_EQ(src.attributes, dest.attributes);
267 EXPECT_EQ(src.style, dest.style);
268 EXPECT_EQ(src.command, dest.command);
269 EXPECT_EQ(src.inner_segment_boundary, dest.inner_segment_boundary);
270 }
271
TEST(CandidateTest,IsValid)272 TEST(CandidateTest, IsValid) {
273 Segment::Candidate c;
274 c.Init();
275 EXPECT_TRUE(c.IsValid());
276
277 c.key = "key";
278 c.value = "value";
279 c.content_key = "content_key";
280 c.content_value = "content_value";
281 c.prefix = "prefix";
282 c.suffix = "suffix";
283 c.description = "description";
284 c.usage_title = "usage_title";
285 c.usage_description = "usage_description";
286 c.cost = 1;
287 c.wcost = 2;
288 c.structure_cost = 3;
289 c.lid = 4;
290 c.rid = 5;
291 c.attributes = 6;
292 c.style = NumberUtil::NumberString::NUMBER_CIRCLED;
293 c.command = Segment::Candidate::DISABLE_PRESENTATION_MODE;
294 EXPECT_TRUE(c.IsValid()); // Empty inner_segment_boundary
295
296 // Valid inner_segment_boundary.
297 c.inner_segment_boundary.push_back(
298 Segment::Candidate::EncodeLengths(1, 3, 8, 8));
299 c.inner_segment_boundary.push_back(
300 Segment::Candidate::EncodeLengths(2, 2, 3, 5));
301 EXPECT_TRUE(c.IsValid());
302
303 // Invalid inner_segment_boundary.
304 c.inner_segment_boundary.clear();
305 c.inner_segment_boundary.push_back(
306 Segment::Candidate::EncodeLengths(1, 1, 2, 2));
307 c.inner_segment_boundary.push_back(
308 Segment::Candidate::EncodeLengths(2, 2, 3, 3));
309 c.inner_segment_boundary.push_back(
310 Segment::Candidate::EncodeLengths(3, 3, 4, 4));
311 EXPECT_FALSE(c.IsValid());
312 }
313
TEST(SegmentsTest,RevertEntryTest)314 TEST(SegmentsTest, RevertEntryTest) {
315 Segments segments;
316 EXPECT_EQ(0, segments.revert_entries_size());
317
318 const int kSize = 10;
319 for (int i = 0; i < kSize; ++i) {
320 Segments::RevertEntry *e = segments.push_back_revert_entry();
321 e->key = "test" + std::to_string(i);
322 e->id = i;
323 }
324
325 EXPECT_EQ(kSize, segments.revert_entries_size());
326
327 for (int i = 0; i < kSize; ++i) {
328 {
329 const Segments::RevertEntry &e = segments.revert_entry(i);
330 EXPECT_EQ(string("test") + std::to_string(i), e.key);
331 EXPECT_EQ(i, e.id);
332 }
333 {
334 Segments::RevertEntry *e = segments.mutable_revert_entry(i);
335 EXPECT_EQ(string("test") + std::to_string(i), e->key);
336 EXPECT_EQ(i, e->id);
337 }
338 }
339
340 for (int i = 0; i < kSize; ++i) {
341 Segments::RevertEntry *e = segments.mutable_revert_entry(i);
342 e->id = kSize - i;
343 e->key = "test2" + std::to_string(i);
344 }
345
346 for (int i = 0; i < kSize; ++i) {
347 const Segments::RevertEntry &e = segments.revert_entry(i);
348 EXPECT_EQ(string("test2") + std::to_string(i), e.key);
349 EXPECT_EQ(kSize - i, e.id);
350 }
351
352 {
353 const Segments::RevertEntry &src = segments.revert_entry(0);
354 Segments::RevertEntry dest;
355 dest.CopyFrom(src);
356 EXPECT_EQ(src.revert_entry_type, dest.revert_entry_type);
357 EXPECT_EQ(src.id, dest.id);
358 EXPECT_EQ(src.timestamp, dest.timestamp);
359 EXPECT_EQ(src.key, dest.key);
360 }
361
362 segments.clear_revert_entries();
363 EXPECT_EQ(0, segments.revert_entries_size());
364 }
365
TEST(SegmentsTest,CopyFromTest)366 TEST(SegmentsTest, CopyFromTest) {
367 Segments src;
368
369 src.set_max_history_segments_size(1);
370 src.set_max_prediction_candidates_size(2);
371 src.set_max_conversion_candidates_size(2);
372 src.set_resized(true);
373 src.set_user_history_enabled(true);
374 src.set_request_type(Segments::PREDICTION);
375
376 const int kSegmentsSize = 3;
377 const int kCandidatesSize = 2;
378
379 for (int i = 0; i < kSegmentsSize; ++i) {
380 Segment *segment = src.add_segment();
381 segment->set_key(Util::StringPrintf("segment_%d", i));
382 for (int j = 0; j < kCandidatesSize; ++j) {
383 Segment::Candidate *candidate = segment->add_candidate();
384 candidate->key = Util::StringPrintf("candidate_%d", i);
385 }
386 }
387 EXPECT_EQ(kSegmentsSize, src.segments_size());
388 EXPECT_EQ(kCandidatesSize, src.segment(0).candidates_size());
389
390 Segments dest;
391 dest.CopyFrom(src);
392 EXPECT_EQ(src.max_history_segments_size(), dest.max_history_segments_size());
393 EXPECT_EQ(src.max_prediction_candidates_size(),
394 dest.max_prediction_candidates_size());
395 EXPECT_EQ(src.max_conversion_candidates_size(),
396 dest.max_conversion_candidates_size());
397 EXPECT_EQ(src.resized(), dest.resized());
398 EXPECT_EQ(src.user_history_enabled(), dest.user_history_enabled());
399 EXPECT_EQ(src.request_type(), dest.request_type());
400
401 EXPECT_EQ(kSegmentsSize, dest.segments_size());
402 EXPECT_EQ(kCandidatesSize, dest.segment(0).candidates_size());
403
404 for (int i = 0; i < kSegmentsSize; ++i) {
405 EXPECT_EQ(src.segment(i).key(), dest.segment(i).key());
406 for (int j = 0; j < kCandidatesSize; ++j) {
407 EXPECT_EQ(src.segment(i).candidate(j).key,
408 dest.segment(i).candidate(j).key);
409 }
410 }
411 }
412
TEST(CandidateTest,functional_key)413 TEST(CandidateTest, functional_key) {
414 Segment::Candidate candidate;
415 candidate.Init();
416
417 candidate.key = "testfoobar";
418 candidate.content_key = "test";
419 EXPECT_EQ("foobar", candidate.functional_key());
420
421 candidate.key = "testfoo";
422 candidate.content_key = "test";
423 EXPECT_EQ("foo", candidate.functional_key());
424
425 // This is unexpected key/context_key.
426 // This method doesn't check the prefix part.
427 candidate.key = "abcdefg";
428 candidate.content_key = "test";
429 EXPECT_EQ("efg", candidate.functional_key());
430
431 candidate.key = "test";
432 candidate.content_key = "test";
433 EXPECT_EQ("", candidate.functional_key());
434
435 candidate.key = "test";
436 candidate.content_key = "testfoobar";
437 EXPECT_EQ("", candidate.functional_key());
438
439 candidate.key = "";
440 candidate.content_key = "";
441 EXPECT_EQ("", candidate.functional_key());
442 }
443
TEST(CandidateTest,functional_value)444 TEST(CandidateTest, functional_value) {
445 Segment::Candidate candidate;
446 candidate.Init();
447
448 candidate.value = "testfoobar";
449 candidate.content_value = "test";
450 EXPECT_EQ("foobar", candidate.functional_value());
451
452 candidate.value = "testfoo";
453 candidate.content_value = "test";
454 EXPECT_EQ("foo", candidate.functional_value());
455
456 // This is unexpected value/context_value.
457 // This method doesn't check the prefix part.
458 candidate.value = "abcdefg";
459 candidate.content_value = "test";
460 EXPECT_EQ("efg", candidate.functional_value());
461
462 candidate.value = "test";
463 candidate.content_value = "test";
464 EXPECT_EQ("", candidate.functional_value());
465
466 candidate.value = "test";
467 candidate.content_value = "testfoobar";
468 EXPECT_EQ("", candidate.functional_value());
469
470 candidate.value = "";
471 candidate.content_value = "";
472 EXPECT_EQ("", candidate.functional_value());
473 }
474
TEST(CandidateTest,InnerSegmentIterator)475 TEST(CandidateTest, InnerSegmentIterator) {
476 {
477 // For empty inner_segment_boundary, the initial state is done.
478 Segment::Candidate candidate;
479 candidate.Init();
480 candidate.key = "testfoobar";
481 candidate.value = "redgreenblue";
482 Segment::Candidate::InnerSegmentIterator iter(&candidate);
483 EXPECT_TRUE(iter.Done());
484 }
485 {
486 // key: test | foobar
487 // value: red | greenblue
488 // content key: test | foo
489 // content value: red | green
490 Segment::Candidate candidate;
491 candidate.Init();
492 candidate.key = "testfoobar";
493 candidate.value = "redgreenblue";
494 candidate.PushBackInnerSegmentBoundary(4, 3, 4, 3);
495 candidate.PushBackInnerSegmentBoundary(6, 9, 3, 5);
496 std::vector<StringPiece> keys, values, content_keys, content_values;
497 for (Segment::Candidate::InnerSegmentIterator iter(&candidate);
498 !iter.Done(); iter.Next()) {
499 keys.push_back(iter.GetKey());
500 values.push_back(iter.GetValue());
501 content_keys.push_back(iter.GetContentKey());
502 content_values.push_back(iter.GetContentValue());
503 }
504
505 ASSERT_EQ(2, keys.size());
506 EXPECT_EQ("test", keys[0]);
507 EXPECT_EQ("foobar", keys[1]);
508
509 ASSERT_EQ(2, values.size());
510 EXPECT_EQ("red", values[0]);
511 EXPECT_EQ("greenblue", values[1]);
512
513 ASSERT_EQ(2, content_keys.size());
514 EXPECT_EQ("test", content_keys[0]);
515 EXPECT_EQ("foo", content_keys[1]);
516
517 ASSERT_EQ(2, content_values.size());
518 EXPECT_EQ("red", content_values[0]);
519 EXPECT_EQ("green", content_values[1]);
520 }
521 }
522
TEST(SegmentTest,CopyFrom)523 TEST(SegmentTest, CopyFrom) {
524 Segment src, dest;
525
526 src.set_key("key");
527 src.set_segment_type(Segment::FIXED_VALUE);
528 Segment::Candidate *candidate1 = src.add_candidate();
529 candidate1->key = "candidate1->key";
530 Segment::Candidate *candidate2 = src.add_candidate();
531 candidate2->key = "candidate2->key";
532 Segment::Candidate *meta_candidate = src.add_meta_candidate();
533 meta_candidate->key = "meta_candidate->key";
534
535 dest.CopyFrom(src);
536
537 EXPECT_EQ(src.key(), dest.key());
538 EXPECT_EQ(src.segment_type(), dest.segment_type());
539 EXPECT_EQ(src.candidate(0).key, dest.candidate(0).key);
540 EXPECT_EQ(src.candidate(1).key, dest.candidate(1).key);
541 EXPECT_EQ(src.meta_candidate(0).key, dest.meta_candidate(0).key);
542 }
543
TEST(SegmentTest,MetaCandidateTest)544 TEST(SegmentTest, MetaCandidateTest) {
545 Segment segment;
546
547 EXPECT_EQ(0, segment.meta_candidates_size());
548
549 const int kCandidatesSize = 5;
550 std::vector<string> values;
551 for (size_t i = 0; i < kCandidatesSize; ++i) {
552 values.push_back(string(1, 'a' + i));
553 }
554
555 // add_meta_candidate()
556 for (size_t i = 0; i < kCandidatesSize; ++i) {
557 EXPECT_EQ(i, segment.meta_candidates_size());
558 Segment::Candidate *cand = segment.add_meta_candidate();
559 cand->value = values[i];
560 EXPECT_EQ(i + 1, segment.meta_candidates_size());
561 }
562
563 // mutable_candidate()
564 for (size_t i = 0; i < kCandidatesSize; ++i) {
565 const int meta_idx = -static_cast<int>(i)-1;
566 Segment::Candidate *cand = segment.mutable_candidate(meta_idx);
567 EXPECT_EQ(values[i], cand->value);
568 }
569
570 // mutable_meta_candidate()
571 for (size_t i = 0; i < kCandidatesSize; ++i) {
572 Segment::Candidate *cand = segment.mutable_meta_candidate(i);
573 EXPECT_EQ(values[i], cand->value);
574 }
575
576 // candidate()
577 for (size_t i = 0; i < kCandidatesSize; ++i) {
578 const int meta_idx = -static_cast<int>(i)-1;
579 const Segment::Candidate &cand = segment.candidate(meta_idx);
580 EXPECT_EQ(values[i], cand.value);
581 }
582
583 // meta_candidate()
584 for (size_t i = 0; i < kCandidatesSize; ++i) {
585 const Segment::Candidate &cand = segment.meta_candidate(i);
586 EXPECT_EQ(values[i], cand.value);
587 }
588
589 // indexOf
590 for (size_t i = 0; i < kCandidatesSize; ++i) {
591 const int meta_idx = -static_cast<int>(i)-1;
592 EXPECT_EQ(meta_idx, segment.indexOf(segment.mutable_candidate(meta_idx)));
593 }
594
595 EXPECT_EQ(segment.candidates_size(),
596 segment.indexOf(NULL));
597
598 // mutable_meta_candidates
599 {
600 std::vector<Segment::Candidate> *meta_candidates =
601 segment.mutable_meta_candidates();
602 EXPECT_EQ(kCandidatesSize, meta_candidates->size());
603 Segment::Candidate cand;
604 cand.Init();
605 cand.value = "Test";
606 meta_candidates->push_back(cand);
607 }
608
609 // meta_candidates
610 {
611 const std::vector<Segment::Candidate> &meta_candidates =
612 segment.meta_candidates();
613 EXPECT_EQ(kCandidatesSize + 1, meta_candidates.size());
614 for (size_t i = 0; i < kCandidatesSize; ++i) {
615 EXPECT_EQ(values[i], meta_candidates[i].value);
616 }
617 EXPECT_EQ("Test", meta_candidates[kCandidatesSize].value);
618 }
619 // clear
620 segment.clear_meta_candidates();
621 EXPECT_EQ(0, segment.meta_candidates_size());
622 }
623 } // namespace mozc
624