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