Move embedded typing models to data set file
When data package is reloaded, typing models must be reloaded too.
This CL moves the global instances of typing model to a member of Table
class and implements cache clear method in TableManager.
BUG=
TEST=
REF_BUG=26841123,30236194
REF_CL=127786726,128029339
REF_TIME=2016-07-19T11:08:50+09:00
REF_TIME_RAW=1468894130 +0900
Noriyuki Takahashi
7 years ago
49 | 49 | 'table.cc', |
50 | 50 | ], |
51 | 51 | 'dependencies': [ |
52 | 'embedded_typing_model#host', | |
53 | 52 | '../base/base.gyp:base', |
54 | 53 | '../base/base.gyp:config_file_stream', |
55 | 54 | '../composer/composer.gyp:key_event_util', |
61 | 60 | '../protocol/protocol.gyp:commands_proto', |
62 | 61 | '../transliteration/transliteration.gyp:transliteration', |
63 | 62 | ], |
64 | }, | |
65 | { | |
66 | 'target_name': 'gen_typing_model', | |
67 | 'type': 'none', | |
68 | 'toolsets': ['host'], | |
69 | 'actions': [ | |
70 | { | |
71 | 'action_name': 'gen_qwerty_mobile-hiragana_typing_model', | |
72 | 'variables': { | |
73 | 'input_files': [ | |
74 | '<(mozc_dir)/data/typing/typing_model_qwerty_mobile-hiragana.tsv', | |
75 | ], | |
76 | }, | |
77 | 'inputs': [ | |
78 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
79 | '<@(input_files)', | |
80 | ], | |
81 | 'outputs': [ | |
82 | '<(gen_out_dir)/internal/typing_model_qwerty_mobile-hiragana.h', | |
83 | ], | |
84 | 'action': [ | |
85 | 'python', | |
86 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
87 | '--input_path', | |
88 | '<@(input_files)', | |
89 | '--output_path', | |
90 | '<@(_outputs)', | |
91 | '--variable_name', | |
92 | 'QwertyMobileHiragana' | |
93 | ], | |
94 | }, | |
95 | { | |
96 | 'action_name': 'gen_12keys-hiragana_typing_model', | |
97 | 'variables': { | |
98 | 'input_files': [ | |
99 | '<(mozc_dir)/data/typing/typing_model_12keys-hiragana.tsv', | |
100 | ], | |
101 | }, | |
102 | 'inputs': [ | |
103 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
104 | '<@(input_files)', | |
105 | ], | |
106 | 'outputs': [ | |
107 | '<(gen_out_dir)/internal/typing_model_12keys-hiragana.h', | |
108 | ], | |
109 | 'action': [ | |
110 | 'python', | |
111 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
112 | '--input_path', | |
113 | '<@(input_files)', | |
114 | '--output_path', | |
115 | '<@(_outputs)', | |
116 | '--variable_name', | |
117 | '12keysHiragana' | |
118 | ], | |
119 | }, | |
120 | { | |
121 | 'action_name': 'gen_flick-hiragana_typing_model', | |
122 | 'variables': { | |
123 | 'input_files': [ | |
124 | '<(mozc_dir)/data/typing/typing_model_flick-hiragana.tsv', | |
125 | ], | |
126 | }, | |
127 | 'inputs': [ | |
128 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
129 | '<@(input_files)', | |
130 | ], | |
131 | 'outputs': [ | |
132 | '<(gen_out_dir)/internal/typing_model_flick-hiragana.h', | |
133 | ], | |
134 | 'action': [ | |
135 | 'python', | |
136 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
137 | '--input_path', | |
138 | '<@(input_files)', | |
139 | '--output_path', | |
140 | '<@(_outputs)', | |
141 | '--variable_name', | |
142 | 'FlickHiragana' | |
143 | ], | |
144 | }, | |
145 | { | |
146 | 'action_name': 'gen_godan-hiragana_typing_model', | |
147 | 'variables': { | |
148 | 'input_files': [ | |
149 | '<(mozc_dir)/data/typing/typing_model_godan-hiragana.tsv', | |
150 | ], | |
151 | }, | |
152 | 'inputs': [ | |
153 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
154 | '<@(input_files)', | |
155 | ], | |
156 | 'outputs': [ | |
157 | '<(gen_out_dir)/internal/typing_model_godan-hiragana.h', | |
158 | ], | |
159 | 'action': [ | |
160 | 'python', | |
161 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
162 | '--input_path', | |
163 | '<@(input_files)', | |
164 | '--output_path', | |
165 | '<@(_outputs)', | |
166 | '--variable_name', | |
167 | 'GodanHiragana' | |
168 | ], | |
169 | }, | |
170 | { | |
171 | 'action_name': 'gen_toggle_flick-hiragana_typing_model', | |
172 | 'variables': { | |
173 | 'input_files': [ | |
174 | '<(mozc_dir)/data/typing/typing_model_toggle_flick-hiragana.tsv', | |
175 | ], | |
176 | }, | |
177 | 'inputs': [ | |
178 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
179 | '<@(input_files)', | |
180 | ], | |
181 | 'outputs': [ | |
182 | '<(gen_out_dir)/internal/typing_model_toggle_flick-hiragana.h', | |
183 | ], | |
184 | 'action': [ | |
185 | 'python', | |
186 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
187 | '--input_path', | |
188 | '<@(input_files)', | |
189 | '--output_path', | |
190 | '<@(_outputs)', | |
191 | '--variable_name', | |
192 | 'ToggleFlickHiragana' | |
193 | ], | |
194 | }, | |
195 | ], | |
196 | }, | |
197 | { | |
198 | 'target_name': 'embedded_typing_model', | |
199 | 'type': 'none', | |
200 | 'toolsets': ['host'], | |
201 | 'hard_dependency': 1, | |
202 | 'dependencies': [ | |
203 | 'gen_typing_model#host', | |
204 | ], | |
205 | 'export_dependent_settings': [ | |
206 | 'gen_typing_model#host', | |
207 | ] | |
208 | 63 | }, |
209 | 64 | { |
210 | 65 | 'target_name': 'key_event_util', |
34 | 34 | #include <vector> |
35 | 35 | |
36 | 36 | #include "base/logging.h" |
37 | #include "base/singleton.h" | |
38 | 37 | #include "base/system_util.h" |
39 | 38 | #include "base/util.h" |
40 | 39 | #include "composer/internal/typing_model.h" |
42 | 41 | #include "composer/table.h" |
43 | 42 | #include "config/character_form_manager.h" |
44 | 43 | #include "config/config_handler.h" |
44 | #include "data_manager/testing/mock_data_manager.h" | |
45 | 45 | #include "protocol/commands.pb.h" |
46 | 46 | #include "protocol/config.pb.h" |
47 | 47 | #include "testing/base/public/gunit.h" |
121 | 121 | |
122 | 122 | } // namespace |
123 | 123 | |
124 | class ComposerTest : public testing::Test { | |
124 | class ComposerTest : public ::testing::Test { | |
125 | 125 | protected: |
126 | ComposerTest() {} | |
127 | ||
128 | virtual void SetUp() { | |
126 | ComposerTest() = default; | |
127 | ~ComposerTest() override = default; | |
128 | ||
129 | void SetUp() override { | |
129 | 130 | table_.reset(new Table); |
130 | 131 | config_.reset(new Config); |
131 | 132 | request_.reset(new Request); |
133 | 134 | CharacterFormManager::GetCharacterFormManager()->SetDefaultRule(); |
134 | 135 | } |
135 | 136 | |
136 | virtual void TearDown() { | |
137 | void TearDown() override { | |
137 | 138 | CharacterFormManager::GetCharacterFormManager()->SetDefaultRule(); |
138 | 139 | composer_.reset(); |
139 | 140 | request_.reset(); |
141 | 142 | table_.reset(); |
142 | 143 | } |
143 | 144 | |
145 | const testing::MockDataManager mock_data_manager_; | |
144 | 146 | std::unique_ptr<Composer> composer_; |
145 | 147 | std::unique_ptr<Table> table_; |
146 | 148 | std::unique_ptr<Request> request_; |
1436 | 1438 | |
1437 | 1439 | TEST_F(ComposerTest, ShiftKeyOperationForKatakana) { |
1438 | 1440 | config_->set_shift_key_mode_switch(Config::KATAKANA_INPUT_MODE); |
1439 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
1441 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
1442 | mock_data_manager_); | |
1440 | 1443 | composer_->Reset(); |
1441 | 1444 | composer_->SetInputMode(transliteration::HIRAGANA); |
1442 | 1445 | InsertKey("K", composer_.get()); |
1478 | 1481 | config_->set_preedit_method(Config::ROMAN); |
1479 | 1482 | config_->set_use_auto_ime_turn_off(true); |
1480 | 1483 | |
1481 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
1484 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
1485 | mock_data_manager_); | |
1482 | 1486 | |
1483 | 1487 | commands::KeyEvent key; |
1484 | 1488 | |
1597 | 1601 | config_->set_preedit_method(Config::ROMAN); |
1598 | 1602 | config_->set_use_auto_ime_turn_off(false); |
1599 | 1603 | |
1600 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
1604 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
1605 | mock_data_manager_); | |
1601 | 1606 | |
1602 | 1607 | commands::KeyEvent key; |
1603 | 1608 | |
1634 | 1639 | config_->set_preedit_method(Config::KANA); |
1635 | 1640 | config_->set_use_auto_ime_turn_off(true); |
1636 | 1641 | |
1637 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
1642 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
1643 | mock_data_manager_); | |
1638 | 1644 | |
1639 | 1645 | commands::KeyEvent key; |
1640 | 1646 | |
2610 | 2616 | TEST_F(ComposerTest, CaseSensitiveByConfiguration) { |
2611 | 2617 | { |
2612 | 2618 | config_->set_shift_key_mode_switch(Config::OFF); |
2613 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
2619 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
2620 | mock_data_manager_); | |
2614 | 2621 | |
2615 | 2622 | // i -> "い" |
2616 | 2623 | table_->AddRule("i", "\xe3\x81\x84", ""); |
2629 | 2636 | composer_->Reset(); |
2630 | 2637 | { |
2631 | 2638 | config_->set_shift_key_mode_switch(Config::ASCII_INPUT_MODE); |
2632 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
2639 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
2640 | mock_data_manager_); | |
2633 | 2641 | |
2634 | 2642 | // i -> "い" |
2635 | 2643 | table_->AddRule("i", "\xe3\x81\x84", ""); |
2651 | 2659 | InputUppercaseInAlphanumericModeWithShiftKeyModeSwitchIsKatakana) { |
2652 | 2660 | { |
2653 | 2661 | config_->set_shift_key_mode_switch(Config::KATAKANA_INPUT_MODE); |
2654 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
2662 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
2663 | mock_data_manager_); | |
2655 | 2664 | |
2656 | 2665 | // i -> "い" |
2657 | 2666 | table_->AddRule("i", "\xe3\x81\x84", ""); |
2716 | 2725 | // 2. Type Back-space 6 times ("い") |
2717 | 2726 | // 3. Type "i" (should be "いい") |
2718 | 2727 | |
2719 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
2728 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
2729 | mock_data_manager_); | |
2720 | 2730 | |
2721 | 2731 | // i -> "い" |
2722 | 2732 | table_->AddRule("i", "\xe3\x81\x84", ""); |
2763 | 2773 | TEST_F(ComposerTest, InputModesChangeWhenCursorMoves) { |
2764 | 2774 | // The expectation of this test is the same as MS-IME's |
2765 | 2775 | |
2766 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
2776 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
2777 | mock_data_manager_); | |
2767 | 2778 | |
2768 | 2779 | // i -> "い" |
2769 | 2780 | table_->AddRule("i", "\xe3\x81\x84", ""); |
3137 | 3148 | commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII); |
3138 | 3149 | composer_->SetRequest(&request); |
3139 | 3150 | table_->InitializeWithRequestAndConfig( |
3140 | request, config::ConfigHandler::DefaultConfig()); | |
3151 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
3141 | 3152 | composer_->InsertCharacter("2"); |
3142 | 3153 | EXPECT_EQ("a", GetPreedit(composer_.get())); |
3143 | 3154 | string result; |
3208 | 3219 | |
3209 | 3220 | class MockTypingModel : public TypingModel { |
3210 | 3221 | public: |
3211 | MockTypingModel() : TypingModel(NULL, 0, NULL, 0, NULL) {} | |
3212 | virtual ~MockTypingModel() {} | |
3213 | virtual int GetCost(StringPiece key) const { | |
3222 | MockTypingModel() : TypingModel(nullptr, 0, nullptr, 0, nullptr) {} | |
3223 | ~MockTypingModel() override = default; | |
3224 | int GetCost(StringPiece key) const override { | |
3214 | 3225 | return 10; |
3215 | 3226 | } |
3216 | 3227 | }; |
3219 | 3230 | // corrector inside composer. |
3220 | 3231 | class TypingCorrectionTest : public ::testing::Test { |
3221 | 3232 | protected: |
3222 | virtual void SetUp() { | |
3233 | void SetUp() override { | |
3223 | 3234 | config_.reset(new Config); |
3224 | 3235 | ConfigHandler::GetDefaultConfig(config_.get()); |
3225 | 3236 | config_->set_use_typing_correction(true); |
3232 | 3243 | |
3233 | 3244 | composer_.reset(new Composer(table_.get(), request_.get(), config_.get())); |
3234 | 3245 | |
3235 | table_->typing_model_ = Singleton<MockTypingModel>::get(); | |
3246 | table_->typing_model_.reset(new MockTypingModel()); | |
3236 | 3247 | } |
3237 | 3248 | |
3238 | 3249 | static bool IsTypingCorrectorClearedOrInvalidated(const Composer &composer) { |
44 | 44 | ], |
45 | 45 | 'dependencies': [ |
46 | 46 | '../config/config.gyp:config_handler', |
47 | '../data_manager/testing/mock_data_manager.gyp:mock_data_manager', | |
47 | 48 | '../protocol/protocol.gyp:commands_proto', |
48 | 49 | '../protocol/protocol.gyp:config_proto', |
49 | 50 | '../session/session_base.gyp:request_test_util', |
27 | 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | 28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 | |
30 | """Converts a typing model file to C++ code. | |
30 | """Converts a typing model file to binary image. | |
31 | 31 | |
32 | 32 | Usage: |
33 | 33 | $ gen_typing_model.py model.tsv > output.h |
34 | ||
35 | Output file format: | |
36 | +----------------------------------------------------+ | |
37 | | unique characters array size (4 bytes, uint32) | | |
38 | +----------------------------------------------------+ | |
39 | | unique characters array (variable length, char[]) | | |
40 | +----------------------------------------------------+ | |
41 | | padding (0 - 3 bytes) | | |
42 | +----------------------------------------------------+ | |
43 | | cost array size (4 bytes, uint32) | | |
44 | +----------------------------------------------------+ | |
45 | | cost array (variable length, uint8[]) | | |
46 | +----------------------------------------------------+ | |
47 | | padding (0 - 3 bytes) | | |
48 | +----------------------------------------------------+ | |
49 | | mapping table (variable length, int32[]) | | |
50 | +----------------------------------------------------+ | |
34 | 51 | """ |
35 | 52 | |
36 | 53 | __author__ = "noriyukit" |
52 | 69 | parser.add_option('--input_path', dest='input_path', |
53 | 70 | default='typing_model.tsv', |
54 | 71 | help='Input file path') |
55 | parser.add_option('--variable_name', dest='variable_name', | |
56 | default='typingmodel', | |
57 | help='Suffix of created variable name.') | |
58 | 72 | parser.add_option('--output_path', dest='output_path', |
59 | 73 | default='/tmp/typing_model.h', |
60 | 74 | help='Output file path.') |
144 | 158 | return result |
145 | 159 | |
146 | 160 | |
147 | def WriteResult(romaji_transition_cost, output_path, variable_name): | |
161 | def WriteResult(romaji_transition_cost, output_path): | |
148 | 162 | unique_characters = GetUniqueCharacters(romaji_transition_cost.keys()) |
149 | 163 | mapping_table = GetMappingTable(romaji_transition_cost.values(), |
150 | 164 | MAX_UINT8 + 1) |
151 | 165 | value_list = GetValueTable(unique_characters, mapping_table, |
152 | 166 | romaji_transition_cost) |
153 | quoted_unique_characters = ''.join( | |
154 | [r'\x%X' % ord(c) for c in unique_characters]) | |
155 | with open(output_path, 'w') as out_file: | |
156 | out_file.write('const size_t kKeyCharactersSize_%s = %d;\n' % | |
157 | (variable_name, len(unique_characters))) | |
158 | out_file.write('const char* kKeyCharacters_%s = "%s";\n' % | |
159 | (variable_name, ''.join(quoted_unique_characters))) | |
160 | out_file.write('const size_t kCostTableSize_%s = %d;\n' % | |
161 | (variable_name, len(value_list))) | |
162 | out_file.write('const uint8 kCostTable_%s[] = {\n' % | |
163 | variable_name) | |
164 | for value in value_list: | |
165 | out_file.write('%d,\n' % value) | |
166 | out_file.write('};\n') | |
167 | out_file.write('const int32 kCostMappingTable_%s[] = {\n' % | |
168 | variable_name) | |
169 | for value in mapping_table: | |
170 | out_file.write('%d,\n' % value) | |
171 | out_file.write('};\n') | |
167 | with open(output_path, 'wb') as f: | |
168 | f.write(struct.pack('<I', len(unique_characters))) | |
169 | f.write(''.join(unique_characters)) | |
170 | offset = 4 + len(unique_characters) | |
171 | ||
172 | # Add padding to place value list size at 4-byte boundary. | |
173 | if offset % 4: | |
174 | padding_size = 4 - offset % 4 | |
175 | f.write('\x00' * padding_size) | |
176 | offset += padding_size | |
177 | ||
178 | f.write(struct.pack('<I', len(value_list))) | |
179 | for v in value_list: | |
180 | f.write(struct.pack('<B', v)) | |
181 | offset += 4 + len(value_list) | |
182 | ||
183 | # Add padding to place mapping_table at 4-byte boundary. | |
184 | if offset % 4: | |
185 | padding_size = 4 - offset % 4 | |
186 | f.write('\x00' * padding_size) | |
187 | offset += padding_size | |
188 | ||
189 | for v in mapping_table: | |
190 | f.write(struct.pack('<i', v)) | |
172 | 191 | |
173 | 192 | |
174 | 193 | def main(): |
207 | 226 | # We use unsigned short to store cost value so range check is needed. |
208 | 227 | romaji_transition_cost[ngram] = adjusted_cost |
209 | 228 | |
210 | WriteResult(romaji_transition_cost, options.output_path, | |
211 | options.variable_name) | |
229 | WriteResult(romaji_transition_cost, options.output_path) | |
212 | 230 | |
213 | 231 | |
214 | 232 | if __name__ == '__main__': |
36 | 36 | #include "composer/table.h" |
37 | 37 | #include "composer/type_corrected_query.h" |
38 | 38 | #include "config/config_handler.h" |
39 | #include "data_manager/testing/mock_data_manager.h" | |
39 | 40 | #include "protocol/commands.pb.h" |
40 | 41 | #include "testing/base/public/gunit.h" |
41 | 42 | |
42 | 43 | namespace mozc { |
43 | 44 | namespace composer { |
44 | ||
45 | namespace { | |
46 | #include "composer/internal/typing_model_qwerty_mobile-hiragana.h" | |
47 | } | |
48 | 45 | |
49 | 46 | using mozc::config::Config; |
50 | 47 | using mozc::config::ConfigHandler; |
287 | 284 | |
288 | 285 | class TypingCorrectorTest : public ::testing::Test { |
289 | 286 | protected: |
290 | TypingCorrectorTest() : | |
291 | qwerty_typing_model_( | |
292 | kKeyCharacters_QwertyMobileHiragana, | |
293 | kKeyCharactersSize_QwertyMobileHiragana, | |
294 | kCostTable_QwertyMobileHiragana, | |
295 | kCostTableSize_QwertyMobileHiragana, | |
296 | kCostMappingTable_QwertyMobileHiragana) { | |
297 | } | |
298 | ||
299 | virtual void SetUp() { | |
287 | TypingCorrectorTest() = default; | |
288 | ||
289 | void SetUp() override { | |
300 | 290 | ConfigHandler::GetDefaultConfig(&config_); |
301 | 291 | config_.set_use_typing_correction(true); |
302 | 292 | commands::Request request; |
303 | 293 | request.set_special_romanji_table( |
304 | 294 | commands::Request::QWERTY_MOBILE_TO_HIRAGANA); |
305 | qwerty_table_.InitializeWithRequestAndConfig(request, config_); | |
306 | qwerty_table_.typing_model_ = &qwerty_typing_model_; | |
295 | qwerty_table_.InitializeWithRequestAndConfig(request, config_, | |
296 | mock_data_manager_); | |
297 | qwerty_table_.typing_model_ = TypingModel::CreateTypingModel( | |
298 | commands::Request::QWERTY_MOBILE_TO_HIRAGANA, | |
299 | mock_data_manager_); | |
307 | 300 | } |
308 | 301 | |
309 | 302 | void InsertOneByOne(const char *keys, TypingCorrector *corrector) { |
345 | 338 | } |
346 | 339 | } |
347 | 340 | |
341 | const testing::MockDataManager mock_data_manager_; | |
348 | 342 | Config config_; |
349 | 343 | Table qwerty_table_; |
350 | TypingModel qwerty_typing_model_; | |
351 | 344 | }; |
352 | 345 | |
353 | 346 | TEST_F(TypingCorrectorTest, TypingCorrection) { |
36 | 36 | |
37 | 37 | namespace mozc { |
38 | 38 | namespace composer { |
39 | namespace { | |
40 | ||
41 | // These header files are automatically generated by gen_typing_model.py. | |
42 | #include "composer/internal/typing_model_12keys-hiragana.h" | |
43 | #include "composer/internal/typing_model_flick-hiragana.h" | |
44 | #include "composer/internal/typing_model_godan-hiragana.h" | |
45 | #include "composer/internal/typing_model_qwerty_mobile-hiragana.h" | |
46 | #include "composer/internal/typing_model_toggle_flick-hiragana.h" | |
47 | ||
48 | std::unique_ptr<TypingModel> g_typing_model_12keys_hiragana; | |
49 | std::unique_ptr<TypingModel> g_typing_model_flick_hiragana; | |
50 | std::unique_ptr<TypingModel> g_typing_model_godan_hiragana; | |
51 | std::unique_ptr<TypingModel> g_typing_model_qwerty_mobile_hiragana; | |
52 | std::unique_ptr<TypingModel> g_typing_model_toggle_flick_hiragana; | |
53 | ||
54 | } // namespace | |
55 | 39 | |
56 | 40 | const uint8 TypingModel::kNoData = numeric_limits<uint8>::max(); |
57 | 41 | const int TypingModel::kInfinity = (2 << 20); // approximately equals 1e+6 |
72 | 56 | } |
73 | 57 | } |
74 | 58 | |
59 | TypingModel::~TypingModel() = default; | |
60 | ||
75 | 61 | int TypingModel::GetCost(StringPiece key) const { |
76 | 62 | size_t index = GetIndex(key); |
77 | 63 | if (index >= cost_table_size_) { |
91 | 77 | } |
92 | 78 | |
93 | 79 | // static |
94 | const TypingModel *TypingModel::GetTypingModel( | |
95 | const mozc::commands::Request::SpecialRomanjiTable &special_romanji_table) { | |
80 | std::unique_ptr<const TypingModel> TypingModel::CreateTypingModel( | |
81 | const mozc::commands::Request::SpecialRomanjiTable &special_romanji_table, | |
82 | const DataManagerInterface &data_manager) { | |
83 | const char *key = nullptr; | |
96 | 84 | switch (special_romanji_table) { |
97 | 85 | case mozc::commands::Request::TWELVE_KEYS_TO_HIRAGANA: |
98 | if (!g_typing_model_12keys_hiragana.get()) { | |
99 | g_typing_model_12keys_hiragana.reset(new TypingModel( | |
100 | kKeyCharacters_12keysHiragana, | |
101 | kKeyCharactersSize_12keysHiragana, | |
102 | kCostTable_12keysHiragana, | |
103 | kCostTableSize_12keysHiragana, | |
104 | kCostMappingTable_12keysHiragana)); | |
105 | } | |
106 | return g_typing_model_12keys_hiragana.get(); | |
86 | key = "typing_model_12keys-hiragana.tsv"; | |
87 | break; | |
107 | 88 | case mozc::commands::Request::FLICK_TO_HIRAGANA: |
108 | if (!g_typing_model_flick_hiragana.get()) { | |
109 | g_typing_model_flick_hiragana.reset(new TypingModel( | |
110 | kKeyCharacters_FlickHiragana, | |
111 | kKeyCharactersSize_FlickHiragana, | |
112 | kCostTable_FlickHiragana, | |
113 | kCostTableSize_FlickHiragana, | |
114 | kCostMappingTable_FlickHiragana)); | |
115 | } | |
116 | return g_typing_model_flick_hiragana.get(); | |
89 | key = "typing_model_flick-hiragana.tsv"; | |
90 | break; | |
117 | 91 | case mozc::commands::Request::TOGGLE_FLICK_TO_HIRAGANA: |
118 | if (!g_typing_model_toggle_flick_hiragana.get()) { | |
119 | g_typing_model_toggle_flick_hiragana.reset(new TypingModel( | |
120 | kKeyCharacters_ToggleFlickHiragana, | |
121 | kKeyCharactersSize_ToggleFlickHiragana, | |
122 | kCostTable_ToggleFlickHiragana, | |
123 | kCostTableSize_ToggleFlickHiragana, | |
124 | kCostMappingTable_ToggleFlickHiragana)); | |
125 | } | |
126 | return g_typing_model_toggle_flick_hiragana.get(); | |
92 | key = "typing_model_toggle_flick-hiragana.tsv"; | |
93 | break; | |
127 | 94 | case mozc::commands::Request::QWERTY_MOBILE_TO_HIRAGANA: |
128 | if (!g_typing_model_qwerty_mobile_hiragana.get()) { | |
129 | g_typing_model_qwerty_mobile_hiragana.reset(new TypingModel( | |
130 | kKeyCharacters_QwertyMobileHiragana, | |
131 | kKeyCharactersSize_QwertyMobileHiragana, | |
132 | kCostTable_QwertyMobileHiragana, | |
133 | kCostTableSize_QwertyMobileHiragana, | |
134 | kCostMappingTable_QwertyMobileHiragana)); | |
135 | } | |
136 | return g_typing_model_qwerty_mobile_hiragana.get(); | |
95 | key = "typing_model_qwerty_mobile-hiragana.tsv"; | |
96 | break; | |
137 | 97 | case mozc::commands::Request::GODAN_TO_HIRAGANA: |
138 | if (!g_typing_model_godan_hiragana.get()) { | |
139 | g_typing_model_godan_hiragana.reset(new TypingModel( | |
140 | kKeyCharacters_GodanHiragana, | |
141 | kKeyCharactersSize_GodanHiragana, | |
142 | kCostTable_GodanHiragana, | |
143 | kCostTableSize_GodanHiragana, | |
144 | kCostMappingTable_GodanHiragana)); | |
145 | } | |
146 | return g_typing_model_godan_hiragana.get(); | |
98 | key = "typing_model_godan-hiragana.tsv"; | |
99 | break; | |
147 | 100 | default: |
148 | return NULL; | |
101 | return nullptr; | |
149 | 102 | } |
103 | ||
104 | const StringPiece data = data_manager.GetTypingModel(key); | |
105 | if (data.empty()) { | |
106 | return nullptr; | |
107 | } | |
108 | // Parse the binary image of typing model. See gen_typing_model.py for file | |
109 | // format. | |
110 | const uint32 characters_size = | |
111 | *reinterpret_cast<const uint32*>(data.data()); | |
112 | const char *characters = data.data() + 4; | |
113 | ||
114 | size_t offset = 4 + characters_size; | |
115 | if (offset % 4 != 0) { | |
116 | offset += 4 - offset % 4; | |
117 | } | |
118 | const uint32 cost_table_size = | |
119 | *reinterpret_cast<const uint32*>(data.data() + offset); | |
120 | const uint8 *cost_table = | |
121 | reinterpret_cast<const uint8*>(data.data() + offset + 4); | |
122 | ||
123 | offset += 4 + cost_table_size; | |
124 | if (offset % 4 != 0) { | |
125 | offset += 4 - offset % 4; | |
126 | } | |
127 | const int32 *mapping_table = | |
128 | reinterpret_cast<const int32*>(data.data() + offset); | |
129 | ||
130 | return std::unique_ptr<const TypingModel>( | |
131 | new TypingModel(characters, characters_size, cost_table, cost_table_size, | |
132 | mapping_table)); | |
150 | 133 | } |
151 | 134 | |
152 | 135 | } // namespace composer |
33 | 33 | |
34 | 34 | #include "base/port.h" |
35 | 35 | #include "base/string_piece.h" |
36 | #include "data_manager/data_manager_interface.h" | |
36 | 37 | #include "protocol/commands.pb.h" |
37 | 38 | // for FRIEND_TEST() |
38 | 39 | #include "testing/base/public/gunit_prod.h" |
52 | 53 | const uint8 *cost_table, size_t cost_table_size, |
53 | 54 | const int32 *mapping_table); |
54 | 55 | |
55 | virtual ~TypingModel() {} | |
56 | virtual ~TypingModel(); | |
56 | 57 | |
57 | 58 | // Gets cost value from key. |
58 | 59 | // virtual for mocking. |
59 | 60 | virtual int GetCost(StringPiece key) const; |
60 | 61 | |
61 | // Gets a TypingModel based on SpecialRomanjiTable. | |
62 | // NULL if no corresponding model is available. | |
63 | static const TypingModel *GetTypingModel( | |
64 | const mozc::commands::Request::SpecialRomanjiTable | |
65 | &special_romanji_table); | |
62 | // Creates a TypingModel based on SpecialRomanjiTable. | |
63 | // nullptr if no corresponding model is available. | |
64 | static std::unique_ptr<const TypingModel> CreateTypingModel( | |
65 | const mozc::commands::Request::SpecialRomanjiTable &special_romanji_table, | |
66 | const DataManagerInterface& data_manager); | |
66 | 67 | |
67 | 68 | // No data means its const is infinity. |
68 | 69 | static const int kInfinity; |
35 | 35 | #include <memory> |
36 | 36 | #include <sstream> |
37 | 37 | #include <string> |
38 | #include <utility> | |
38 | 39 | |
39 | 40 | #include "base/config_file_stream.h" |
40 | 41 | #include "base/file_stream.h" |
101 | 102 | // ======================================== |
102 | 103 | Table::Table() |
103 | 104 | : entries_(new EntryTrie), |
104 | case_sensitive_(false), | |
105 | typing_model_(NULL) {} | |
105 | case_sensitive_(false) {} | |
106 | 106 | |
107 | 107 | Table::~Table() { |
108 | 108 | ResetEntrySet(); |
120 | 120 | static const char kSquareClose[] = "]"; |
121 | 121 | static const char kMiddleDot[] = "\xE3\x83\xBB"; // "・" |
122 | 122 | |
123 | bool Table::InitializeWithRequestAndConfig(const commands::Request &request, | |
124 | const config::Config &config) { | |
123 | bool Table::InitializeWithRequestAndConfig( | |
124 | const commands::Request &request, | |
125 | const config::Config &config, | |
126 | const DataManagerInterface& data_manager) { | |
125 | 127 | case_sensitive_ = false; |
126 | 128 | bool result = false; |
127 | typing_model_ = TypingModel::GetTypingModel(request.special_romanji_table()); | |
129 | typing_model_ = TypingModel::CreateTypingModel( | |
130 | request.special_romanji_table(), data_manager); | |
128 | 131 | if (request.special_romanji_table() |
129 | 132 | != mozc::commands::Request::DEFAULT_TABLE) { |
130 | 133 | const char *table_file_name; |
388 | 391 | } |
389 | 392 | |
390 | 393 | const TypingModel* Table::typing_model() const { |
391 | return typing_model_; | |
394 | return typing_model_.get(); | |
392 | 395 | } |
393 | 396 | |
394 | 397 | namespace { |
606 | 609 | : custom_roman_table_fingerprint_(Hash::Fingerprint32("")) { |
607 | 610 | } |
608 | 611 | |
609 | TableManager::~TableManager() { | |
610 | for (map<uint32, const Table*>::iterator iterator = table_map_.begin(); | |
611 | iterator != table_map_.end(); | |
612 | ++iterator) { | |
613 | delete iterator->second; | |
614 | } | |
615 | } | |
616 | ||
617 | const Table *TableManager::GetTable(const mozc::commands::Request &request, | |
618 | const mozc::config::Config &config) { | |
612 | TableManager::~TableManager() = default; | |
613 | ||
614 | const Table *TableManager::GetTable( | |
615 | const mozc::commands::Request &request, | |
616 | const mozc::config::Config &config, | |
617 | const mozc::DataManagerInterface &data_manager) { | |
619 | 618 | // calculate the hash depending on the request and the config |
620 | 619 | uint32 hash = request.special_romanji_table(); |
621 | 620 | hash = hash * (mozc::config::Config_PreeditMethod_PreeditMethod_MAX + 1) |
639 | 638 | } |
640 | 639 | } |
641 | 640 | |
642 | map<uint32, const Table*>::iterator iterator = table_map_.find(hash); | |
641 | const auto iterator = table_map_.find(hash); | |
643 | 642 | if (iterator != table_map_.end()) { |
644 | 643 | if (update_custom_roman_table) { |
645 | 644 | // Delete the previous table to update the table. |
646 | delete iterator->second; | |
647 | 645 | table_map_.erase(iterator); |
648 | 646 | } else { |
649 | return iterator->second; | |
647 | return iterator->second.get(); | |
650 | 648 | } |
651 | 649 | } |
652 | 650 | |
653 | 651 | std::unique_ptr<Table> table(new Table()); |
654 | if (!table->InitializeWithRequestAndConfig(request, config)) { | |
655 | return NULL; | |
656 | } | |
657 | ||
658 | Table* table_to_cache = table.release(); | |
659 | table_map_[hash] = table_to_cache; | |
660 | return table_to_cache; | |
652 | if (!table->InitializeWithRequestAndConfig(request, config, data_manager)) { | |
653 | return nullptr; | |
654 | } | |
655 | ||
656 | const Table* ret = table.get(); | |
657 | table_map_[hash] = std::move(table); | |
658 | return ret; | |
659 | } | |
660 | ||
661 | void TableManager::ClearCaches() { | |
662 | table_map_.clear(); | |
661 | 663 | } |
662 | 664 | |
663 | 665 | } // namespace composer |
39 | 39 | |
40 | 40 | #include "base/port.h" |
41 | 41 | #include "base/trie.h" |
42 | #include "data_manager/data_manager_interface.h" | |
42 | 43 | |
43 | 44 | namespace mozc { |
44 | 45 | |
99 | 100 | virtual ~Table(); |
100 | 101 | |
101 | 102 | bool InitializeWithRequestAndConfig(const commands::Request &request, |
102 | const config::Config &config); | |
103 | const config::Config &config, | |
104 | const DataManagerInterface &data_manager); | |
103 | 105 | |
104 | 106 | |
105 | 107 | // Return true if adding the input-pending pair makes a loop of |
161 | 163 | // characters. The default value is false. |
162 | 164 | bool case_sensitive_; |
163 | 165 | |
164 | // Typing model. NULL if no corresponding model is available. | |
165 | const TypingModel* typing_model_; | |
166 | // Typing model. nullptr if no corresponding model is available. | |
167 | std::unique_ptr<const TypingModel> typing_model_; | |
166 | 168 | |
167 | 169 | DISALLOW_COPY_AND_ASSIGN(Table); |
168 | 170 | }; |
174 | 176 | // Return Table for the request and the config |
175 | 177 | // TableManager has ownership of the return value; |
176 | 178 | const Table *GetTable(const commands::Request &request, |
177 | const config::Config &config); | |
179 | const config::Config &config, | |
180 | const DataManagerInterface &data_manager); | |
181 | ||
182 | void ClearCaches(); | |
178 | 183 | |
179 | 184 | private: |
180 | 185 | // Table caches. |
183 | 188 | // config::Config::PreeditMethod |
184 | 189 | // config::Config::PunctuationMethod |
185 | 190 | // config::Config::SymbolMethod |
186 | map<uint32, const Table*> table_map_; | |
191 | map<uint32, std::unique_ptr<const Table>> table_map_; | |
187 | 192 | // Fingerprint for Config::custom_roman_table; |
188 | 193 | uint32 custom_roman_table_fingerprint_; |
189 | 194 | }; |
33 | 33 | #include "base/system_util.h" |
34 | 34 | #include "composer/internal/composition_input.h" |
35 | 35 | #include "config/config_handler.h" |
36 | #include "data_manager/testing/mock_data_manager.h" | |
36 | 37 | #include "protocol/commands.pb.h" |
37 | 38 | #include "protocol/config.pb.h" |
38 | 39 | #include "testing/base/public/gunit.h" |
88 | 89 | return entry->input(); |
89 | 90 | } |
90 | 91 | |
91 | class TableTest : public testing::Test { | |
92 | class TableTest : public ::testing::Test { | |
92 | 93 | protected: |
93 | TableTest() {} | |
94 | ||
95 | virtual void SetUp() { | |
94 | TableTest() = default; | |
95 | ~TableTest() override = default; | |
96 | ||
97 | void SetUp() override { | |
96 | 98 | config::ConfigHandler::GetDefaultConfig(&config_); |
97 | 99 | } |
98 | 100 | |
101 | const testing::MockDataManager mock_data_manager_; | |
99 | 102 | config::Config config_; |
100 | 103 | |
101 | 104 | private: |
189 | 192 | config::Config config; |
190 | 193 | config.set_punctuation_method(test_cases[i].method); |
191 | 194 | Table table; |
192 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config)); | |
195 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config, | |
196 | mock_data_manager_)); | |
193 | 197 | const Entry *entry = table.LookUp(test_cases[i].input); |
194 | 198 | EXPECT_TRUE(entry != NULL) << "Failed index = " << i; |
195 | 199 | if (entry) { |
232 | 236 | config::Config config; |
233 | 237 | config.set_symbol_method(test_cases[i].method); |
234 | 238 | Table table; |
235 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config)); | |
239 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config, | |
240 | mock_data_manager_)); | |
236 | 241 | const Entry *entry = table.LookUp(test_cases[i].input); |
237 | 242 | EXPECT_TRUE(entry != NULL) << "Failed index = " << i; |
238 | 243 | if (entry) { |
247 | 252 | commands::Request request; |
248 | 253 | |
249 | 254 | Table table; |
250 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config_)); | |
255 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config_, | |
256 | mock_data_manager_)); | |
251 | 257 | |
252 | 258 | const Entry *entry = table.LookUp("a"); |
253 | 259 | ASSERT_TRUE(entry != NULL); |
259 | 265 | TEST_F(TableTest, KanaCombination) { |
260 | 266 | Table table; |
261 | 267 | commands::Request request; |
262 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config_)); | |
268 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config_, | |
269 | mock_data_manager_)); | |
263 | 270 | // "か゛" |
264 | 271 | const Entry *entry = table.LookUp("\xE3\x81\x8B\xE3\x82\x9B"); |
265 | 272 | ASSERT_TRUE(entry != NULL); |
398 | 405 | |
399 | 406 | Table table; |
400 | 407 | commands::Request request; |
401 | table.InitializeWithRequestAndConfig(request, config_); | |
408 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
402 | 409 | |
403 | 410 | const Entry *entry = NULL; |
404 | 411 | entry = table.LookUp("mozc"); |
502 | 509 | commands::Request request; |
503 | 510 | { |
504 | 511 | Table table; |
505 | table.InitializeWithRequestAndConfig(request, config_); | |
512 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
506 | 513 | EXPECT_FALSE(table.case_sensitive()); |
507 | 514 | } |
508 | 515 | { |
509 | 516 | Table table; |
510 | table.InitializeWithRequestAndConfig(request, config_); | |
517 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
511 | 518 | table.AddRule("", "", ""); |
512 | 519 | EXPECT_FALSE(table.case_sensitive()); |
513 | 520 | } |
514 | 521 | { |
515 | 522 | Table table; |
516 | table.InitializeWithRequestAndConfig(request, config_); | |
523 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
517 | 524 | table.AddRule("a", "", ""); |
518 | 525 | EXPECT_FALSE(table.case_sensitive()); |
519 | 526 | } |
520 | 527 | { |
521 | 528 | Table table; |
522 | table.InitializeWithRequestAndConfig(request, config_); | |
529 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
523 | 530 | table.AddRule("A", "", ""); |
524 | 531 | EXPECT_TRUE(table.case_sensitive()); |
525 | 532 | } |
526 | 533 | { |
527 | 534 | Table table; |
528 | table.InitializeWithRequestAndConfig(request, config_); | |
535 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
529 | 536 | table.AddRule("a{A}a", "", ""); |
530 | 537 | EXPECT_FALSE(table.case_sensitive()); |
531 | 538 | } |
532 | 539 | { |
533 | 540 | Table table; |
534 | table.InitializeWithRequestAndConfig(request, config_); | |
541 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
535 | 542 | table.AddRule("A{A}A", "", ""); |
536 | 543 | EXPECT_TRUE(table.case_sensitive()); |
537 | 544 | } |
547 | 554 | // config::Config::OFF |
548 | 555 | { |
549 | 556 | config_.set_shift_key_mode_switch(config::Config::OFF); |
550 | table.InitializeWithRequestAndConfig(request, config_); | |
557 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
551 | 558 | |
552 | 559 | table.AddRule("a", "[a]", ""); |
553 | 560 | table.AddRule("A", "[A]", ""); |
587 | 594 | // config::Config::ASCII_INPUT_MODE |
588 | 595 | { |
589 | 596 | config_.set_shift_key_mode_switch(config::Config::ASCII_INPUT_MODE); |
590 | table.InitializeWithRequestAndConfig(request, config_); | |
597 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
591 | 598 | |
592 | 599 | table.AddRule("a", "[a]", ""); |
593 | 600 | table.AddRule("A", "[A]", ""); |
627 | 634 | // config::Config::KATAKANA_INPUT_MODE |
628 | 635 | { |
629 | 636 | config_.set_shift_key_mode_switch(config::Config::KATAKANA_INPUT_MODE); |
630 | table.InitializeWithRequestAndConfig(request, config_); | |
637 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
631 | 638 | |
632 | 639 | table.AddRule("a", "[a]", ""); |
633 | 640 | table.AddRule("A", "[A]", ""); |
692 | 699 | EXPECT_FALSE(table.case_sensitive()) |
693 | 700 | << "case-sensitive mode should be desabled by default."; |
694 | 701 | // Load a custom config with case-sensitive custom roman table. |
695 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config)); | |
702 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config, | |
703 | mock_data_manager_)); | |
696 | 704 | EXPECT_TRUE(table.case_sensitive()) |
697 | 705 | << "Case sensitive roman table should enable case-sensitive mode."; |
698 | 706 | // Explicitly disable case-sensitive mode. |
705 | 713 | // Load a custom config with case-insensitive custom roman table. |
706 | 714 | config::Config config(config::ConfigHandler::DefaultConfig()); |
707 | 715 | config.set_custom_roman_table(kCaseInsensitiveRomanTable); |
708 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config)); | |
716 | ASSERT_TRUE(table.InitializeWithRequestAndConfig(request, config, | |
717 | mock_data_manager_)); | |
709 | 718 | EXPECT_FALSE(table.case_sensitive()) |
710 | 719 | << "Case insensitive roman table should disable case-sensitive mode."; |
711 | 720 | // Explicitly enable case-sensitive mode. |
724 | 733 | request.set_special_romanji_table( |
725 | 734 | mozc::commands::Request::TWELVE_KEYS_TO_HIRAGANA); |
726 | 735 | mozc::composer::Table table; |
727 | table.InitializeWithRequestAndConfig(request, config_); | |
736 | table.InitializeWithRequestAndConfig(request, config_, | |
737 | mock_data_manager_); | |
728 | 738 | { |
729 | 739 | const mozc::composer::Entry *entry = NULL; |
730 | 740 | size_t key_length = 0; |
759 | 769 | request.set_special_romanji_table( |
760 | 770 | mozc::commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII); |
761 | 771 | Table table; |
762 | table.InitializeWithRequestAndConfig(request, config_); | |
772 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
763 | 773 | const mozc::composer::Entry *entry = NULL; |
764 | 774 | size_t key_length = 0; |
765 | 775 | bool fixed = false; |
772 | 782 | request.set_special_romanji_table( |
773 | 783 | mozc::commands::Request::GODAN_TO_HIRAGANA); |
774 | 784 | Table table; |
775 | table.InitializeWithRequestAndConfig(request, config_); | |
785 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
776 | 786 | { |
777 | 787 | const mozc::composer::Entry *entry = NULL; |
778 | 788 | size_t key_length = 0; |
790 | 800 | request.set_special_romanji_table( |
791 | 801 | mozc::commands::Request::FLICK_TO_HIRAGANA); |
792 | 802 | Table table; |
793 | table.InitializeWithRequestAndConfig(request, config_); | |
803 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
794 | 804 | |
795 | 805 | size_t key_length = 0; |
796 | 806 | bool fixed = false; |
805 | 815 | request.set_special_romanji_table( |
806 | 816 | mozc::commands::Request::NOTOUCH_TO_HIRAGANA); |
807 | 817 | Table table; |
808 | table.InitializeWithRequestAndConfig(request, config_); | |
818 | table.InitializeWithRequestAndConfig(request, config_, mock_data_manager_); | |
809 | 819 | |
810 | 820 | size_t key_length = 0; |
811 | 821 | bool fixed = false; |
1060 | 1070 | config.set_preedit_method(preedit_method[preedit]); |
1061 | 1071 | config.set_punctuation_method(punctuation_method[punctuation]); |
1062 | 1072 | config.set_symbol_method(symbol_method[symbol]); |
1063 | const Table *table = table_manager.GetTable(request, config); | |
1073 | const Table *table = table_manager.GetTable(request, config, | |
1074 | mock_data_manager_); | |
1064 | 1075 | EXPECT_TRUE(table != NULL); |
1065 | EXPECT_TRUE(table_manager.GetTable(request, config) == table); | |
1076 | EXPECT_TRUE(table_manager.GetTable(request, config, | |
1077 | mock_data_manager_) == table); | |
1066 | 1078 | EXPECT_TRUE(table_set.find(table) == table_set.end()); |
1067 | 1079 | table_set.insert(table); |
1068 | 1080 | } |
1082 | 1094 | config.set_punctuation_method(Config::KUTEN_TOUTEN); |
1083 | 1095 | config.set_symbol_method(Config::CORNER_BRACKET_MIDDLE_DOT); |
1084 | 1096 | config.set_custom_roman_table(kRule); |
1085 | const Table *table = table_manager.GetTable(request, config); | |
1097 | const Table *table = table_manager.GetTable(request, config, | |
1098 | mock_data_manager_); | |
1086 | 1099 | EXPECT_TRUE(table != NULL); |
1087 | EXPECT_TRUE(table_manager.GetTable(request, config) == table); | |
1100 | EXPECT_TRUE(table_manager.GetTable(request, config, | |
1101 | mock_data_manager_) == table); | |
1088 | 1102 | EXPECT_TRUE(NULL != table->LookUp("a")); |
1089 | 1103 | EXPECT_TRUE(NULL == table->LookUp("kk")); |
1090 | 1104 | |
1092 | 1106 | "a\t[A]\n" // 2 entry rule |
1093 | 1107 | "kk\t[X]\tk\n"; // 3 entry rule |
1094 | 1108 | config.set_custom_roman_table(kRule2); |
1095 | const Table *table2 = table_manager.GetTable(request, config); | |
1109 | const Table *table2 = table_manager.GetTable(request, config, | |
1110 | mock_data_manager_); | |
1096 | 1111 | EXPECT_TRUE(table2 != NULL); |
1097 | EXPECT_TRUE(table_manager.GetTable(request, config) == table2); | |
1112 | EXPECT_TRUE(table_manager.GetTable(request, config, | |
1113 | mock_data_manager_) == table2); | |
1098 | 1114 | EXPECT_TRUE(NULL != table2->LookUp("a")); |
1099 | 1115 | EXPECT_TRUE(NULL != table2->LookUp("kk")); |
1100 | 1116 | } |
0 | 0 | MAJOR=2 |
1 | 1 | MINOR=18 |
2 | BUILD=2577 | |
2 | BUILD=2578 | |
3 | 3 | REVISION=102 |
4 | 4 | # CAUTION: NACL_DICTIONARY_VERSION is going to be migrated to ENGINE_VERSION. |
5 | 5 | # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be |
34 | 34 | |
35 | 35 | namespace mozc { |
36 | 36 | namespace chromeos { |
37 | namespace { | |
37 | 38 | |
38 | namespace { | |
39 | 39 | #include "data_manager/chromeos/segmenter_inl.h" |
40 | ||
40 | 41 | } // namespace |
41 | 42 | |
42 | 43 | class ChromeOsDataManagerTest : public DataManagerTestBase { |
64 | 65 | "dictionary09.txt"}), |
65 | 66 | mozc::testing::GetSourceFilesInDirOrDie( |
66 | 67 | {"data", "dictionary_chromeos"}, |
67 | {"suggestion_filter.txt"})) {} | |
68 | {"suggestion_filter.txt"}), | |
69 | // ChromeOS doesn't include typing correction models. | |
70 | {}) {} | |
68 | 71 | }; |
69 | 72 | |
70 | 73 | TEST_F(ChromeOsDataManagerTest, AllTests) { |
28 | 28 | |
29 | 29 | #include "data_manager/data_manager.h" |
30 | 30 | |
31 | #include <algorithm> | |
31 | 32 | #include <ostream> |
32 | 33 | |
33 | 34 | #include "base/logging.h" |
34 | 35 | #include "base/serialized_string_array.h" |
36 | #include "base/stl_util.h" | |
35 | 37 | #include "base/util.h" |
36 | 38 | #include "base/version.h" |
37 | 39 | #include "data_manager/dataset_reader.h" |
340 | 342 | } |
341 | 343 | } |
342 | 344 | |
345 | for (const auto &kv : reader.name_to_data_map()) { | |
346 | if (!Util::StartsWith(kv.first, "typing_model")) { | |
347 | continue; | |
348 | } | |
349 | typing_model_data_.push_back(kv); | |
350 | } | |
351 | std::sort(typing_model_data_.begin(), typing_model_data_.end(), | |
352 | OrderBy<FirstKey, Less>()); | |
353 | ||
343 | 354 | if (!reader.Get("version", &data_version_)) { |
344 | 355 | LOG(ERROR) << "Cannot find data version"; |
345 | 356 | return Status::DATA_MISSING; |
538 | 549 | } |
539 | 550 | #endif // NO_USAGE_REWRITER |
540 | 551 | |
552 | StringPiece DataManager::GetTypingModel(const string &name) const { | |
553 | const auto iter = std::lower_bound( | |
554 | typing_model_data_.begin(), typing_model_data_.end(), name, | |
555 | [](const pair<string, StringPiece> &elem, const string &key) { | |
556 | return elem.first < key; | |
557 | }); | |
558 | if (iter == typing_model_data_.end() || iter->first != name) { | |
559 | return StringPiece(); | |
560 | } | |
561 | return iter->second; | |
562 | } | |
563 | ||
541 | 564 | StringPiece DataManager::GetDataVersion() const { |
542 | 565 | return data_version_; |
543 | 566 | } |
121 | 121 | 'gen_separate_single_kanji_rewriter_data_for_<(dataset_tag)#host', |
122 | 122 | 'gen_separate_zero_query_data_for_<(dataset_tag)#host', |
123 | 123 | 'gen_separate_version_data_for_<(dataset_tag)#host', |
124 | 'gen_typing_model_for_<(dataset_tag)#host', | |
124 | 125 | ], |
125 | 126 | 'actions': [ |
126 | 127 | { |
161 | 162 | 'single_kanji_variant_string': '<(gen_out_dir)/single_kanji_variant_string.data', |
162 | 163 | 'single_kanji_noun_prefix_token': '<(gen_out_dir)/single_kanji_noun_prefix_token.data', |
163 | 164 | 'single_kanji_noun_prefix_string': '<(gen_out_dir)/single_kanji_noun_prefix_string.data', |
165 | 'typing_model_qwerty_mobile-hiragana': '<(gen_out_dir)/typing_model_qwerty_mobile-hiragana.data', | |
166 | 'typing_model_12keys-hiragana': '<(gen_out_dir)/typing_model_12keys-hiragana.data', | |
167 | 'typing_model_flick-hiragana': '<(gen_out_dir)/typing_model_flick-hiragana.data', | |
168 | 'typing_model_godan-hiragana': '<(gen_out_dir)/typing_model_godan-hiragana.data', | |
169 | 'typing_model_toggle_flick-hiragana': '<(gen_out_dir)/typing_model_toggle_flick-hiragana.data', | |
164 | 170 | 'zero_query_token_array': '<(gen_out_dir)/zero_query_token.data', |
165 | 171 | 'zero_query_string_array': '<(gen_out_dir)/zero_query_string.data', |
166 | 172 | 'zero_query_number_token_array': '<(gen_out_dir)/zero_query_number_token.data', |
202 | 208 | '<(single_kanji_variant_string)', |
203 | 209 | '<(single_kanji_noun_prefix_token)', |
204 | 210 | '<(single_kanji_noun_prefix_string)', |
211 | '<(typing_model_qwerty_mobile-hiragana)', | |
212 | '<(typing_model_12keys-hiragana)', | |
213 | '<(typing_model_flick-hiragana)', | |
214 | '<(typing_model_godan-hiragana)', | |
215 | '<(typing_model_toggle_flick-hiragana)', | |
205 | 216 | '<(zero_query_token_array)', |
206 | 217 | '<(zero_query_string_array)', |
207 | 218 | '<(zero_query_number_token_array)', |
253 | 264 | 'zero_query_string_array:32:<(gen_out_dir)/zero_query_string.data', |
254 | 265 | 'zero_query_number_token_array:32:<(gen_out_dir)/zero_query_number_token.data', |
255 | 266 | 'zero_query_number_string_array:32:<(gen_out_dir)/zero_query_number_string.data', |
267 | # TODO(noriyukit): These typing models are not necessary for desktop. | |
268 | 'typing_model_qwerty_mobile-hiragana.tsv:32:<(gen_out_dir)/typing_model_qwerty_mobile-hiragana.data', | |
269 | 'typing_model_12keys-hiragana.tsv:32:<(gen_out_dir)/typing_model_12keys-hiragana.data', | |
270 | 'typing_model_flick-hiragana.tsv:32:<(gen_out_dir)/typing_model_flick-hiragana.data', | |
271 | 'typing_model_godan-hiragana.tsv:32:<(gen_out_dir)/typing_model_godan-hiragana.data', | |
272 | 'typing_model_toggle_flick-hiragana.tsv:32:<(gen_out_dir)/typing_model_toggle_flick-hiragana.data', | |
256 | 273 | 'version:32:<(gen_out_dir)/version.data', |
257 | 274 | ], |
258 | 275 | 'conditions': [ |
963 | 980 | ], |
964 | 981 | }, |
965 | 982 | { |
983 | 'target_name': 'gen_typing_model_for_<(dataset_tag)', | |
984 | 'type': 'none', | |
985 | 'toolsets': ['host'], | |
986 | 'actions': [ | |
987 | { | |
988 | 'action_name': 'gen_qwerty_mobile-hiragana_typing_model_<(dataset_tag)', | |
989 | 'variables': { | |
990 | 'input_files': [ | |
991 | '<(mozc_dir)/data/typing/typing_model_qwerty_mobile-hiragana.tsv', | |
992 | ], | |
993 | }, | |
994 | 'inputs': [ | |
995 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
996 | '<@(input_files)', | |
997 | ], | |
998 | 'outputs': [ | |
999 | '<(gen_out_dir)/typing_model_qwerty_mobile-hiragana.data', | |
1000 | ], | |
1001 | 'action': [ | |
1002 | 'python', | |
1003 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1004 | '--input_path', | |
1005 | '<@(input_files)', | |
1006 | '--output_path', | |
1007 | '<@(_outputs)', | |
1008 | ], | |
1009 | }, | |
1010 | { | |
1011 | 'action_name': 'gen_12keys-hiragana_typing_model_<(dataset_tag)', | |
1012 | 'variables': { | |
1013 | 'input_files': [ | |
1014 | '<(mozc_dir)/data/typing/typing_model_12keys-hiragana.tsv', | |
1015 | ], | |
1016 | }, | |
1017 | 'inputs': [ | |
1018 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1019 | '<@(input_files)', | |
1020 | ], | |
1021 | 'outputs': [ | |
1022 | '<(gen_out_dir)/typing_model_12keys-hiragana.data', | |
1023 | ], | |
1024 | 'action': [ | |
1025 | 'python', | |
1026 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1027 | '--input_path', | |
1028 | '<@(input_files)', | |
1029 | '--output_path', | |
1030 | '<@(_outputs)', | |
1031 | ], | |
1032 | }, | |
1033 | { | |
1034 | 'action_name': 'gen_flick-hiragana_typing_model_<(dataset_tag)', | |
1035 | 'variables': { | |
1036 | 'input_files': [ | |
1037 | '<(mozc_dir)/data/typing/typing_model_flick-hiragana.tsv', | |
1038 | ], | |
1039 | }, | |
1040 | 'inputs': [ | |
1041 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1042 | '<@(input_files)', | |
1043 | ], | |
1044 | 'outputs': [ | |
1045 | '<(gen_out_dir)/typing_model_flick-hiragana.data', | |
1046 | ], | |
1047 | 'action': [ | |
1048 | 'python', | |
1049 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1050 | '--input_path', | |
1051 | '<@(input_files)', | |
1052 | '--output_path', | |
1053 | '<@(_outputs)', | |
1054 | ], | |
1055 | }, | |
1056 | { | |
1057 | 'action_name': 'gen_godan-hiragana_typing_model_<(dataset_tag)', | |
1058 | 'variables': { | |
1059 | 'input_files': [ | |
1060 | '<(mozc_dir)/data/typing/typing_model_godan-hiragana.tsv', | |
1061 | ], | |
1062 | }, | |
1063 | 'inputs': [ | |
1064 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1065 | '<@(input_files)', | |
1066 | ], | |
1067 | 'outputs': [ | |
1068 | '<(gen_out_dir)/typing_model_godan-hiragana.data', | |
1069 | ], | |
1070 | 'action': [ | |
1071 | 'python', | |
1072 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1073 | '--input_path', | |
1074 | '<@(input_files)', | |
1075 | '--output_path', | |
1076 | '<@(_outputs)', | |
1077 | ], | |
1078 | }, | |
1079 | { | |
1080 | 'action_name': 'gen_toggle_flick-hiragana_typing_model_<(dataset_tag)', | |
1081 | 'variables': { | |
1082 | 'input_files': [ | |
1083 | '<(mozc_dir)/data/typing/typing_model_toggle_flick-hiragana.tsv', | |
1084 | ], | |
1085 | }, | |
1086 | 'inputs': [ | |
1087 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1088 | '<@(input_files)', | |
1089 | ], | |
1090 | 'outputs': [ | |
1091 | '<(gen_out_dir)/typing_model_toggle_flick-hiragana.data', | |
1092 | ], | |
1093 | 'action': [ | |
1094 | 'python', | |
1095 | '<(mozc_dir)/composer/internal/gen_typing_model.py', | |
1096 | '--input_path', | |
1097 | '<@(input_files)', | |
1098 | '--output_path', | |
1099 | '<@(_outputs)', | |
1100 | ], | |
1101 | }, | |
1102 | ], | |
1103 | }, | |
1104 | { | |
966 | 1105 | 'target_name': 'gen_separate_version_data_for_<(dataset_tag)', |
967 | 1106 | 'type': 'none', |
968 | 1107 | 'toolsets': ['host'], |
31 | 31 | |
32 | 32 | #include <iosfwd> |
33 | 33 | #include <string> |
34 | #include <utility> | |
35 | #include <vector> | |
34 | 36 | |
35 | 37 | #include "base/mmap.h" |
36 | 38 | #include "base/port.h" |
133 | 135 | StringPiece *string_array_data) const override; |
134 | 136 | #endif // NO_USAGE_REWRITER |
135 | 137 | |
138 | StringPiece GetTypingModel(const string &name) const override; | |
136 | 139 | StringPiece GetDataVersion() const override; |
137 | 140 | |
138 | 141 | private: |
183 | 186 | StringPiece usage_conjugation_index_data_; |
184 | 187 | StringPiece usage_items_data_; |
185 | 188 | StringPiece usage_string_array_data_; |
189 | vector<pair<string, StringPiece>> typing_model_data_; | |
186 | 190 | StringPiece data_version_; |
187 | 191 | |
188 | 192 | DISALLOW_COPY_AND_ASSIGN(DataManager); |
28 | 28 | |
29 | 29 | #ifndef MOZC_DATA_MANAGER_DATA_MANAGER_INTERFACE_H_ |
30 | 30 | #define MOZC_DATA_MANAGER_DATA_MANAGER_INTERFACE_H_ |
31 | ||
32 | #include <string> | |
31 | 33 | |
32 | 34 | #include "base/port.h" |
33 | 35 | #include "base/string_piece.h" |
128 | 130 | StringPiece *zero_query_number_token_array_data, |
129 | 131 | StringPiece *zero_query_number_string_array_data) const = 0; |
130 | 132 | |
133 | // Gets the typing model binary data for the specified name. | |
134 | virtual StringPiece GetTypingModel(const string &name) const = 0; | |
135 | ||
131 | 136 | // Gets the data version string. |
132 | 137 | virtual StringPiece GetDataVersion() const = 0; |
133 | 138 |
60 | 60 | const string &connection_txt_file, |
61 | 61 | const int expected_resolution, |
62 | 62 | const vector<string> &dictionary_files, |
63 | const vector<string> &suggestion_filter_files) | |
63 | const vector<string> &suggestion_filter_files, | |
64 | const vector<pair<string, string>> &typing_model_files) | |
64 | 65 | : data_manager_(data_manager), |
65 | 66 | lsize_(lsize), |
66 | 67 | rsize_(rsize), |
68 | 69 | connection_txt_file_(connection_txt_file), |
69 | 70 | expected_resolution_(expected_resolution), |
70 | 71 | dictionary_files_(dictionary_files), |
71 | suggestion_filter_files_(suggestion_filter_files) {} | |
72 | ||
73 | DataManagerTestBase::~DataManagerTestBase() {} | |
72 | suggestion_filter_files_(suggestion_filter_files), | |
73 | typing_model_files_(typing_model_files) {} | |
74 | ||
75 | DataManagerTestBase::~DataManagerTestBase() = default; | |
74 | 76 | |
75 | 77 | void DataManagerTestBase::SegmenterTest_SameAsInternal() { |
76 | 78 | // This test verifies that a segmenter created by MockDataManager provides |
273 | 275 | } |
274 | 276 | } |
275 | 277 | |
278 | void DataManagerTestBase::TypingModelTest() { | |
279 | // Check if typing models are included in the data set. | |
280 | for (const auto &key_and_fname : typing_model_files_) { | |
281 | InputFileStream ifs(key_and_fname.second.c_str(), | |
282 | ios_base::in | ios_base::binary); | |
283 | EXPECT_EQ(ifs.Read(), data_manager_->GetTypingModel(key_and_fname.first)); | |
284 | } | |
285 | } | |
286 | ||
276 | 287 | void DataManagerTestBase::RunAllTests() { |
277 | 288 | ConnectorTest_RandomValueCheck(); |
278 | 289 | SegmenterTest_LNodeTest(); |
282 | 293 | SegmenterTest_SameAsInternal(); |
283 | 294 | SuggestionFilterTest_IsBadSuggestion(); |
284 | 295 | CounterSuffixTest_ValidateTest(); |
296 | TypingModelTest(); | |
285 | 297 | } |
286 | 298 | |
287 | 299 | } // namespace mozc |
31 | 31 | |
32 | 32 | #include <memory> |
33 | 33 | #include <string> |
34 | #include <utility> | |
34 | 35 | #include <vector> |
35 | 36 | |
36 | 37 | #include "base/port.h" |
53 | 54 | // The following two are used in connector test. |
54 | 55 | const string &connection_txt_file, |
55 | 56 | const int expected_resolution, |
56 | // The following two are used in suggestion filter test | |
57 | // The following two are used in suggestion filter test. | |
57 | 58 | const vector<string> &dictionary_files, |
58 | const vector<string> &suggestion_filter_files); | |
59 | virtual ~DataManagerTestBase(); | |
59 | const vector<string> &suggestion_filter_files, | |
60 | // The following is used in typing model test. | |
61 | const vector<pair<string, string>> &typing_model_files); | |
62 | ~DataManagerTestBase() override; | |
60 | 63 | |
61 | 64 | void RunAllTests(); |
62 | 65 | |
69 | 72 | void SegmenterTest_SameAsInternal(); |
70 | 73 | void SuggestionFilterTest_IsBadSuggestion(); |
71 | 74 | void CounterSuffixTest_ValidateTest(); |
75 | void TypingModelTest(); | |
72 | 76 | |
73 | 77 | std::unique_ptr<DataManagerInterface> data_manager_; |
74 | 78 | const uint16 lsize_; |
78 | 82 | const int expected_resolution_; |
79 | 83 | const vector<string> dictionary_files_; |
80 | 84 | const vector<string> suggestion_filter_files_; |
85 | const vector<pair<string, string>> typing_model_files_; | |
81 | 86 | |
82 | 87 | DISALLOW_COPY_AND_ASSIGN(DataManagerTestBase); |
83 | 88 | }; |
55 | 55 | // Verifies the checksum of binary image. |
56 | 56 | static bool VerifyChecksum(StringPiece memblock); |
57 | 57 | |
58 | const map<string, StringPiece> &name_to_data_map() const { | |
59 | return name_to_data_map_; | |
60 | } | |
61 | ||
58 | 62 | private: |
59 | 63 | // The value points to a block of the specified |memblock|. |
60 | 64 | map<string, StringPiece> name_to_data_map_; |
34 | 34 | |
35 | 35 | namespace mozc { |
36 | 36 | namespace oss { |
37 | namespace { | |
37 | 38 | |
38 | namespace { | |
39 | 39 | #include "data_manager/oss/segmenter_inl.h" |
40 | ||
41 | pair<string, string> GetTypingModelEntry(const string &fname) { | |
42 | return pair<string, string>( | |
43 | fname, | |
44 | mozc::testing::GetSourceFileOrDie( | |
45 | {"data_manager", "oss", fname + ".data"})); | |
46 | } | |
47 | ||
40 | 48 | } // namespace |
41 | 49 | |
42 | 50 | class OssDataManagerTest : public DataManagerTestBase { |
63 | 71 | "dictionary08.txt", |
64 | 72 | "dictionary09.txt"}), |
65 | 73 | mozc::testing::GetSourceFilesInDirOrDie( |
66 | {"data", "dictionary_oss"}, {"suggestion_filter.txt"})) {} | |
74 | {"data", "dictionary_oss"}, {"suggestion_filter.txt"}), | |
75 | { | |
76 | GetTypingModelEntry("typing_model_12keys-hiragana.tsv"), | |
77 | GetTypingModelEntry("typing_model_flick-hiragana.tsv"), | |
78 | GetTypingModelEntry("typing_model_godan-hiragana.tsv"), | |
79 | GetTypingModelEntry("typing_model_qwerty_mobile-hiragana.tsv"), | |
80 | GetTypingModelEntry("typing_model_toggle_flick-hiragana.tsv"), | |
81 | }) {} | |
67 | 82 | }; |
68 | 83 | |
69 | 84 | TEST_F(OssDataManagerTest, AllTests) { |
34 | 34 | |
35 | 35 | namespace mozc { |
36 | 36 | namespace testing { |
37 | namespace { | |
37 | 38 | |
38 | namespace { | |
39 | 39 | #include "data_manager/testing/segmenter_inl.h" |
40 | ||
41 | pair<string, string> GetTypingModelEntry(const string &fname) { | |
42 | return pair<string, string>( | |
43 | fname, | |
44 | mozc::testing::GetSourceFileOrDie( | |
45 | {"data_manager", "testing", fname + ".data"})); | |
46 | } | |
47 | ||
40 | 48 | } // namespace |
41 | 49 | |
42 | 50 | class MockDataManagerTest : public DataManagerTestBase { |
55 | 63 | {"dictionary.txt"}), |
56 | 64 | mozc::testing::GetSourceFilesInDirOrDie( |
57 | 65 | {"data", "test", "dictionary"}, |
58 | {"suggestion_filter.txt"})) {} | |
66 | {"suggestion_filter.txt"}), | |
67 | { | |
68 | GetTypingModelEntry("typing_model_12keys-hiragana.tsv"), | |
69 | GetTypingModelEntry("typing_model_flick-hiragana.tsv"), | |
70 | GetTypingModelEntry("typing_model_godan-hiragana.tsv"), | |
71 | GetTypingModelEntry("typing_model_qwerty_mobile-hiragana.tsv"), | |
72 | GetTypingModelEntry("typing_model_toggle_flick-hiragana.tsv"), | |
73 | }) {} | |
59 | 74 | }; |
60 | 75 | |
61 | 76 | TEST_F(MockDataManagerTest, AllTests) { |
106 | 106 | return data_manager_->GetDataVersion(); |
107 | 107 | } |
108 | 108 | |
109 | const DataManagerInterface *GetDataManager() const override { | |
110 | return data_manager_.get(); | |
111 | } | |
112 | ||
109 | 113 | private: |
110 | 114 | // Initializes the object by the given data manager and predictor factory |
111 | 115 | // function. Predictor factory is used to select DefaultPredictor and |
31 | 31 | |
32 | 32 | #include "base/port.h" |
33 | 33 | #include "base/string_piece.h" |
34 | #include "data_manager/data_manager_interface.h" | |
34 | 35 | #include "dictionary/suppression_dictionary.h" |
35 | 36 | |
36 | 37 | namespace mozc { |
45 | 46 | // well as Kana-Kanji converter/predictor, etc. |
46 | 47 | class EngineInterface { |
47 | 48 | public: |
48 | virtual ~EngineInterface() {} | |
49 | virtual ~EngineInterface() = default; | |
49 | 50 | |
50 | 51 | // Returns a reference to a converter. The returned instance is managed by the |
51 | 52 | // engine class and should not be deleted by callers. |
68 | 69 | // Gets the version of underlying data set. |
69 | 70 | virtual StringPiece GetDataVersion() const = 0; |
70 | 71 | |
72 | // Gets the data manager. | |
73 | virtual const DataManagerInterface *GetDataManager() const = 0; | |
74 | ||
71 | 75 | protected: |
72 | 76 | EngineInterface() {} |
73 | 77 |
43 | 43 | bool Reload() override { return true; } |
44 | 44 | UserDataManagerInterface *GetUserDataManager() override { return nullptr; } |
45 | 45 | StringPiece GetDataVersion() const override { return StringPiece(); } |
46 | const DataManagerInterface *GetDataManager() const { return nullptr; } | |
46 | 47 | }; |
47 | 48 | |
48 | 49 | } // namespace mozc |
58 | 58 | return "mock converter engine"; |
59 | 59 | } |
60 | 60 | |
61 | const DataManagerInterface *GetDataManager() const override { | |
62 | return nullptr; | |
63 | } | |
64 | ||
61 | 65 | void SetUserDataManager(UserDataManagerMock *manager); |
62 | 66 | ConverterMock* mutable_converter_mock(); |
63 | 67 |
39 | 39 | #include "base/logging.h" |
40 | 40 | #include "base/port.h" |
41 | 41 | #include "base/serialized_string_array.h" |
42 | #include "base/singleton.h" | |
43 | 42 | #include "base/system_util.h" |
44 | 43 | #include "base/util.h" |
45 | 44 | #include "composer/composer.h" |
370 | 369 | |
371 | 370 | class MockTypingModel : public mozc::composer::TypingModel { |
372 | 371 | public: |
373 | MockTypingModel() : TypingModel(NULL, 0, NULL, 0, NULL) {} | |
374 | ~MockTypingModel() {} | |
375 | int GetCost(StringPiece key) const { | |
372 | MockTypingModel() : TypingModel(nullptr, 0, nullptr, 0, nullptr) {} | |
373 | ~MockTypingModel() override = default; | |
374 | int GetCost(StringPiece key) const override { | |
376 | 375 | return 10; |
377 | 376 | } |
378 | 377 | }; |
821 | 820 | data_and_predictor->dictionary_predictor(); |
822 | 821 | |
823 | 822 | table_->LoadFromFile("system://qwerty_mobile-hiragana.tsv"); |
824 | table_->typing_model_ = Singleton<MockTypingModel>::get(); | |
823 | table_->typing_model_.reset(new MockTypingModel()); | |
825 | 824 | InsertInputSequenceForProbableKeyEvent( |
826 | 825 | key, corrected_key_codes, composer_.get()); |
827 | 826 |
37 | 37 | #include "composer/table.h" |
38 | 38 | #include "config/config_handler.h" |
39 | 39 | #include "converter/segments.h" |
40 | #include "request/conversion_request.h" | |
41 | 40 | #include "data_manager/testing/mock_data_manager.h" |
42 | 41 | #include "dictionary/dictionary_mock.h" |
43 | 42 | #include "dictionary/pos_matcher.h" |
44 | 43 | #include "protocol/commands.pb.h" |
45 | 44 | #include "protocol/config.pb.h" |
45 | #include "request/conversion_request.h" | |
46 | 46 | #include "testing/base/public/gunit.h" |
47 | 47 | #include "testing/base/public/mozctest.h" |
48 | 48 | #include "usage_stats/usage_stats.h" |
88 | 88 | dictionary_mock_.get()); |
89 | 89 | } |
90 | 90 | |
91 | bool RewriteWithLanguageAwareInput(const LanguageAwareRewriter *rewriter, | |
92 | const string &key, string *composition, | |
93 | Segments *segments) { | |
94 | commands::Request client_request; | |
95 | client_request.set_language_aware_input( | |
96 | commands::Request::LANGUAGE_AWARE_SUGGESTION); | |
97 | ||
98 | composer::Table table; | |
99 | config::Config default_config; | |
100 | table.InitializeWithRequestAndConfig(client_request, default_config, | |
101 | data_manager_); | |
102 | ||
103 | composer::Composer composer(&table, &client_request, &default_config); | |
104 | InsertASCIISequence(key, &composer); | |
105 | composer.GetStringForPreedit(composition); | |
106 | ||
107 | // Perform the rewrite command. | |
108 | segments->set_request_type(Segments::SUGGESTION); | |
109 | if (segments->conversion_segments_size() == 0) { | |
110 | segments->add_segment(); | |
111 | } | |
112 | Segment *segment = segments->mutable_conversion_segment(0); | |
113 | segment->set_key(*composition); | |
114 | ConversionRequest request(&composer, &client_request, &default_config); | |
115 | ||
116 | return rewriter->Rewrite(request, segments); | |
117 | } | |
118 | ||
91 | 119 | unique_ptr<DictionaryMock> dictionary_mock_; |
92 | 120 | usage_stats::scoped_usage_stats_enabler usage_stats_enabler_; |
93 | 121 | |
122 | const testing::MockDataManager data_manager_; | |
123 | ||
94 | 124 | private: |
95 | 125 | const testing::ScopedTmpUserProfileDirectory tmp_profile_dir_; |
96 | const testing::MockDataManager data_manager_; | |
97 | 126 | }; |
98 | 127 | |
99 | 128 | namespace { |
100 | bool RewriteWithLanguageAwareInput(const LanguageAwareRewriter *rewriter, | |
101 | const string &key, | |
102 | string *composition, | |
103 | Segments *segments) { | |
104 | commands::Request client_request; | |
105 | client_request.set_language_aware_input( | |
106 | commands::Request::LANGUAGE_AWARE_SUGGESTION); | |
107 | ||
108 | composer::Table table; | |
109 | config::Config default_config; | |
110 | table.InitializeWithRequestAndConfig(client_request, default_config); | |
111 | ||
112 | composer::Composer composer(&table, &client_request, &default_config); | |
113 | InsertASCIISequence(key, &composer); | |
114 | composer.GetStringForPreedit(composition); | |
115 | ||
116 | // Perform the rewrite command. | |
117 | segments->set_request_type(Segments::SUGGESTION); | |
118 | if (segments->conversion_segments_size() == 0) { | |
119 | segments->add_segment(); | |
120 | } | |
121 | Segment *segment = segments->mutable_conversion_segment(0); | |
122 | segment->set_key(*composition); | |
123 | ConversionRequest request(&composer, &client_request, &default_config); | |
124 | ||
125 | return rewriter->Rewrite(request, segments); | |
126 | } | |
127 | 129 | |
128 | 130 | void PushFrontCandidate(const string &data, Segment *segment) { |
129 | 131 | Segment::Candidate *candidate = segment->push_front_candidate(); |
304 | 306 | |
305 | 307 | composer::Table table; |
306 | 308 | config::Config default_config; |
307 | table.InitializeWithRequestAndConfig(client_request, default_config); | |
309 | table.InitializeWithRequestAndConfig(client_request, default_config, | |
310 | data_manager_); | |
308 | 311 | |
309 | 312 | composer::Composer composer(&table, &client_request, &default_config); |
310 | 313 | InsertASCIISequence("python", &composer); |
39 | 39 | #include "composer/table.h" |
40 | 40 | #include "config/config_handler.h" |
41 | 41 | #include "converter/segments.h" |
42 | #include "request/conversion_request.h" | |
43 | 42 | #include "data_manager/testing/mock_data_manager.h" |
44 | 43 | #include "dictionary/pos_matcher.h" |
45 | 44 | #include "protocol/commands.pb.h" |
46 | 45 | #include "protocol/config.pb.h" |
46 | #include "request/conversion_request.h" | |
47 | 47 | #include "testing/base/public/gunit.h" |
48 | 48 | #include "testing/base/public/mozctest.h" |
49 | 49 | #include "transliteration/transliteration.h" |
100 | 100 | |
101 | 101 | usage_stats::scoped_usage_stats_enabler usage_stats_enabler_; |
102 | 102 | |
103 | const testing::MockDataManager mock_data_manager_; | |
104 | ||
103 | 105 | private: |
104 | 106 | const testing::ScopedTmpUserProfileDirectory tmp_profile_dir_; |
105 | const testing::MockDataManager mock_data_manager_; | |
106 | 107 | const commands::Request default_request_; |
107 | 108 | config::Config default_config_; |
108 | 109 | }; |
163 | 164 | CreateTransliterationRewriter()); |
164 | 165 | |
165 | 166 | composer::Table table; |
166 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
167 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
168 | mock_data_manager_); | |
167 | 169 | composer::Composer composer(&table, &default_request(), &default_config()); |
168 | 170 | SetAkann(&composer); |
169 | 171 | |
224 | 226 | CreateTransliterationRewriter()); |
225 | 227 | |
226 | 228 | composer::Table table; |
227 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
229 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
230 | mock_data_manager_); | |
228 | 231 | composer::Composer composer(&table, &default_request(), &default_config()); |
229 | 232 | InsertASCIISequence("ssh", &composer); |
230 | 233 | |
267 | 270 | CreateTransliterationRewriter()); |
268 | 271 | |
269 | 272 | composer::Table table; |
270 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
273 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
274 | mock_data_manager_); | |
271 | 275 | composer::Composer composer(&table, &default_request(), &default_config()); |
272 | 276 | |
273 | 277 | // Set kamabokoinbou to composer. |
320 | 324 | CreateTransliterationRewriter()); |
321 | 325 | |
322 | 326 | composer::Table table; |
323 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
327 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
328 | mock_data_manager_); | |
324 | 329 | composer::Composer composer(&table, &default_request(), &default_config()); |
325 | 330 | |
326 | 331 | // Set kan to composer. |
383 | 388 | CreateTransliterationRewriter()); |
384 | 389 | |
385 | 390 | composer::Table table; |
386 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
391 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
392 | mock_data_manager_); | |
387 | 393 | composer::Composer composer(&table, &default_request(), &default_config()); |
388 | 394 | SetAkann(&composer); |
389 | 395 | |
542 | 548 | CreateTransliterationRewriter()); |
543 | 549 | |
544 | 550 | composer::Table table; |
545 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
551 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
552 | mock_data_manager_); | |
546 | 553 | composer::Composer composer(&table, &default_request(), &default_config()); |
547 | 554 | InsertASCIISequence("a", &composer); |
548 | 555 | |
569 | 576 | CreateTransliterationRewriter()); |
570 | 577 | |
571 | 578 | composer::Table table; |
572 | table.InitializeWithRequestAndConfig(default_request(), default_config()); | |
579 | table.InitializeWithRequestAndConfig(default_request(), default_config(), | |
580 | mock_data_manager_); | |
573 | 581 | |
574 | 582 | Segments segments; |
575 | 583 | Segment *segment = segments.add_segment(); |
609 | 617 | commands::Request::TWELVE_KEYS_TO_HIRAGANA); |
610 | 618 | |
611 | 619 | composer::Table table; |
612 | table.InitializeWithRequestAndConfig(request, default_config()); | |
620 | table.InitializeWithRequestAndConfig(request, default_config(), | |
621 | mock_data_manager_); | |
613 | 622 | composer::Composer composer(&table, &request, &default_config()); |
614 | 623 | |
615 | 624 | { |
679 | 688 | commands::Request::TWELVE_KEYS_TO_HIRAGANA); |
680 | 689 | |
681 | 690 | composer::Table table; |
682 | table.InitializeWithRequestAndConfig(request, default_config()); | |
691 | table.InitializeWithRequestAndConfig(request, default_config(), | |
692 | mock_data_manager_); | |
683 | 693 | composer::Composer composer(&table, &request, &default_config()); |
684 | 694 | |
685 | 695 | { |
750 | 760 | commands::Request::TOGGLE_FLICK_TO_HIRAGANA); |
751 | 761 | |
752 | 762 | composer::Table table; |
753 | table.InitializeWithRequestAndConfig(request, default_config()); | |
763 | table.InitializeWithRequestAndConfig(request, default_config(), | |
764 | mock_data_manager_); | |
754 | 765 | composer::Composer composer(&table, &request, &default_config()); |
755 | 766 | |
756 | 767 | { |
822 | 833 | // "し"; |
823 | 834 | const string kShi = "\xE3\x81\x97"; |
824 | 835 | composer::Table table; |
825 | table.InitializeWithRequestAndConfig(client_request, default_config()); | |
836 | table.InitializeWithRequestAndConfig(client_request, default_config(), | |
837 | mock_data_manager_); | |
826 | 838 | |
827 | 839 | { |
828 | 840 | composer::Composer composer(&table, &client_request, &default_config()); |
871 | 883 | request.set_special_romanji_table(commands::Request::GODAN_TO_HIRAGANA); |
872 | 884 | |
873 | 885 | composer::Table table; |
874 | table.InitializeWithRequestAndConfig(request, default_config()); | |
886 | table.InitializeWithRequestAndConfig(request, default_config(), | |
887 | mock_data_manager_); | |
875 | 888 | composer::Composer composer(&table, &request, &default_config()); |
876 | 889 | { |
877 | 890 | InsertASCIISequence("<'de", &composer); |
939 | 952 | request.set_special_romanji_table(commands::Request::GODAN_TO_HIRAGANA); |
940 | 953 | |
941 | 954 | composer::Table table; |
942 | table.InitializeWithRequestAndConfig(request, default_config()); | |
955 | table.InitializeWithRequestAndConfig(request, default_config(), | |
956 | mock_data_manager_); | |
943 | 957 | |
944 | 958 | // Expected t13n of Godan keyboard. |
945 | 959 | vector<const char *> keycode_to_t13n_map( |
1016 | 1030 | const string kXtsu = "\xE3\x81\xA3"; |
1017 | 1031 | |
1018 | 1032 | composer::Table table; |
1019 | table.InitializeWithRequestAndConfig(client_request, default_config()); | |
1033 | table.InitializeWithRequestAndConfig(client_request, default_config(), | |
1034 | mock_data_manager_); | |
1020 | 1035 | { |
1021 | 1036 | composer::Composer composer(&table, &client_request, &default_config()); |
1022 | 1037 | |
1048 | 1063 | const string kXtsu = "\xE3\x81\xA3"; |
1049 | 1064 | |
1050 | 1065 | composer::Table table; |
1051 | table.InitializeWithRequestAndConfig(client_request, default_config()); | |
1066 | table.InitializeWithRequestAndConfig(client_request, default_config(), | |
1067 | mock_data_manager_); | |
1052 | 1068 | { |
1053 | 1069 | composer::Composer composer(&table, &client_request, &default_config()); |
1054 | 1070 |
48 | 48 | #include "config/config_handler.h" |
49 | 49 | #include "converter/converter_mock.h" |
50 | 50 | #include "converter/segments.h" |
51 | #include "data_manager/testing/mock_data_manager.h" | |
51 | 52 | #include "protocol/candidates.pb.h" |
52 | 53 | #include "protocol/commands.pb.h" |
53 | 54 | #include "protocol/config.pb.h" |
87 | 88 | protected: |
88 | 89 | // Workaround for C2512 error (no default appropriate constructor) on MSVS. |
89 | 90 | SessionConverterTest() {} |
90 | virtual ~SessionConverterTest() {} | |
91 | ||
92 | virtual void SetUp() { | |
91 | ~SessionConverterTest() override {} | |
92 | ||
93 | void SetUp() override { | |
93 | 94 | convertermock_.reset(new ConverterMock()); |
94 | 95 | SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir); |
95 | 96 | mozc::usage_stats::UsageStats::ClearAllStatsForTest(); |
99 | 100 | request_.reset(new Request); |
100 | 101 | |
101 | 102 | table_.reset(new composer::Table); |
102 | table_->InitializeWithRequestAndConfig(*request_, *config_); | |
103 | table_->InitializeWithRequestAndConfig(*request_, *config_, | |
104 | mock_data_manager_); | |
103 | 105 | composer_.reset( |
104 | 106 | new composer::Composer(table_.get(), request_.get(), config_.get())); |
105 | 107 | } |
106 | 108 | |
107 | virtual void TearDown() { | |
109 | void TearDown() override { | |
108 | 110 | table_.reset(); |
109 | 111 | composer_.reset(); |
110 | 112 | |
399 | 401 | std::unique_ptr<Request> request_; |
400 | 402 | std::unique_ptr<Config> config_; |
401 | 403 | mozc::usage_stats::scoped_usage_stats_enabler usage_stats_enabler_; |
404 | ||
405 | private: | |
406 | const testing::MockDataManager mock_data_manager_; | |
402 | 407 | }; |
403 | 408 | |
404 | 409 | #define EXPECT_SELECTED_CANDIDATE_INDICES_EQ(converter, indices) \ |
243 | 243 | |
244 | 244 | void SessionHandler::SetConfig(const config::Config &config) { |
245 | 245 | *config_ = config; |
246 | const composer::Table *table = table_manager_->GetTable(*request_, *config_); | |
246 | const composer::Table *table = table_manager_->GetTable( | |
247 | *request_, *config_, *engine_->GetDataManager()); | |
247 | 248 | for (SessionElement *element = |
248 | 249 | const_cast<SessionElement *>(session_map_->Head()); |
249 | 250 | element != NULL; element = element->next) { |
661 | 662 | engine_.reset(); |
662 | 663 | engine_ = engine_builder_->BuildFromPreparedData(); |
663 | 664 | LOG_IF(FATAL, !engine_) << "Critical failure in engine replace"; |
665 | table_manager_->ClearCaches(); | |
664 | 666 | response->set_status(EngineReloadResponse::RELOADED); |
665 | 667 | } |
666 | 668 | engine_builder_->Clear(); |
41 | 41 | #include "composer/table.h" |
42 | 42 | #include "config/config_handler.h" |
43 | 43 | #include "converter/segments.h" |
44 | #include "data_manager/testing/mock_data_manager.h" | |
44 | 45 | #include "engine/engine_factory.h" |
45 | 46 | #include "protocol/candidates.pb.h" |
46 | 47 | #include "protocol/commands.pb.h" |
147 | 148 | session_.reset(static_cast<session::Session *>(handler_->NewSession())); |
148 | 149 | commands::Request request; |
149 | 150 | table_.reset(new composer::Table()); |
150 | table_->InitializeWithRequestAndConfig(request, config_); | |
151 | table_->InitializeWithRequestAndConfig(request, config_, data_manager_); | |
151 | 152 | session_->SetTable(table_.get()); |
152 | 153 | } |
153 | 154 | |
155 | const testing::MockDataManager data_manager_; | |
154 | 156 | bool orig_use_history_rewriter_; |
155 | 157 | std::unique_ptr<SessionHandler> handler_; |
156 | 158 | std::unique_ptr<session::Session> session_; |
401 | 401 | // since History segments are almost hidden from |
402 | 402 | class ConverterMockForReset : public ConverterMock { |
403 | 403 | public: |
404 | virtual bool ResetConversion(Segments *segments) const { | |
404 | ConverterMockForReset() : reset_conversion_called_(false) {} | |
405 | ||
406 | bool ResetConversion(Segments *segments) const override { | |
405 | 407 | reset_conversion_called_ = true; |
406 | 408 | return true; |
407 | 409 | } |
414 | 416 | reset_conversion_called_ = false; |
415 | 417 | } |
416 | 418 | |
417 | ConverterMockForReset() : reset_conversion_called_(false) {} | |
418 | 419 | private: |
419 | 420 | mutable bool reset_conversion_called_; |
420 | 421 | }; |
444 | 445 | return nullptr; |
445 | 446 | } |
446 | 447 | |
448 | const DataManagerInterface *GetDataManager() const override { | |
449 | return nullptr; | |
450 | } | |
451 | ||
447 | 452 | StringPiece GetDataVersion() const override { return StringPiece(); } |
448 | 453 | |
449 | 454 | const ConverterMockForReset &converter_mock() const { |
460 | 465 | |
461 | 466 | class ConverterMockForRevert : public ConverterMock { |
462 | 467 | public: |
463 | virtual bool RevertConversion(Segments *segments) const { | |
468 | ConverterMockForRevert() : revert_conversion_called_(false) {} | |
469 | ||
470 | bool RevertConversion(Segments *segments) const override { | |
464 | 471 | revert_conversion_called_ = true; |
465 | 472 | return true; |
466 | 473 | } |
473 | 480 | revert_conversion_called_ = false; |
474 | 481 | } |
475 | 482 | |
476 | ConverterMockForRevert() : revert_conversion_called_(false) {} | |
477 | 483 | private: |
478 | 484 | mutable bool revert_conversion_called_; |
479 | 485 | }; |
501 | 507 | } |
502 | 508 | |
503 | 509 | UserDataManagerInterface *GetUserDataManager() override { |
510 | return nullptr; | |
511 | } | |
512 | ||
513 | const DataManagerInterface *GetDataManager() const override { | |
504 | 514 | return nullptr; |
505 | 515 | } |
506 | 516 | |
664 | 674 | session->SetRequest(&request); |
665 | 675 | table_.reset(new composer::Table()); |
666 | 676 | table_->InitializeWithRequestAndConfig( |
667 | request, config::ConfigHandler::DefaultConfig()); | |
677 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
668 | 678 | session->SetTable(table_.get()); |
669 | 679 | } |
670 | 680 | |
834 | 844 | std::unique_ptr<composer::Table> table_; |
835 | 845 | std::unique_ptr<Request> mobile_request_; |
836 | 846 | mozc::usage_stats::scoped_usage_stats_enabler usage_stats_enabler_; |
847 | const testing::MockDataManager mock_data_manager_; | |
837 | 848 | |
838 | 849 | private: |
839 | 850 | const testing::ScopedTmpUserProfileDirectory scoped_profile_dir_; |
840 | const testing::MockDataManager mock_data_manager_; | |
841 | 851 | }; |
842 | 852 | |
843 | 853 | // This test is intentionally defined at this location so that this |
8234 | 8244 | session.SetRequest(&request); |
8235 | 8245 | std::unique_ptr<composer::Table> table(new composer::Table()); |
8236 | 8246 | table->InitializeWithRequestAndConfig( |
8237 | request, config::ConfigHandler::DefaultConfig()); | |
8247 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8238 | 8248 | session.SetTable(table.get()); |
8239 | 8249 | // Type "2*" to produce "A". |
8240 | 8250 | SetSendKeyCommand("2", &command); |
8254 | 8264 | session.SetRequest(&request); |
8255 | 8265 | table.reset(new composer::Table()); |
8256 | 8266 | table->InitializeWithRequestAndConfig( |
8257 | request, config::ConfigHandler::DefaultConfig()); | |
8267 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8258 | 8268 | session.SetTable(table.get()); |
8259 | 8269 | // Type "2" to produce "Aa". |
8260 | 8270 | SetSendKeyCommand("2", &command); |
8310 | 8320 | session.SetRequest(&request); |
8311 | 8321 | composer::Table table; |
8312 | 8322 | table.InitializeWithRequestAndConfig( |
8313 | request, config::ConfigHandler::DefaultConfig()); | |
8323 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8314 | 8324 | session.SetTable(&table); |
8315 | 8325 | |
8316 | 8326 | // Type "2" to produce "a". |
8355 | 8365 | session.SetRequest(&request); |
8356 | 8366 | composer::Table table; |
8357 | 8367 | table.InitializeWithRequestAndConfig( |
8358 | request, config::ConfigHandler::DefaultConfig()); | |
8368 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8359 | 8369 | session.SetTable(&table); |
8360 | 8370 | // Type "33{<}{<}" to produce "さ"->"し"->"さ"->"そ". |
8361 | 8371 | SetSendKeyCommand("3", &command); |
8401 | 8411 | session.SetRequest(&request); |
8402 | 8412 | composer::Table table; |
8403 | 8413 | table.InitializeWithRequestAndConfig( |
8404 | request, config::ConfigHandler::DefaultConfig()); | |
8414 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8405 | 8415 | session.SetTable(&table); |
8406 | 8416 | // Type "3*{<}*{<}", and composition should change |
8407 | 8417 | // "さ"->"ざ"->(No change)->"さ"->(No change). |
8455 | 8465 | session.SetRequest(&request); |
8456 | 8466 | composer::Table table; |
8457 | 8467 | table.InitializeWithRequestAndConfig( |
8458 | request, config::ConfigHandler::DefaultConfig()); | |
8468 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8459 | 8469 | session.SetTable(&table); |
8460 | 8470 | // Type "{<}" and do nothing |
8461 | 8471 | SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command); |
8538 | 8548 | session.SetRequest(&request); |
8539 | 8549 | composer::Table table; |
8540 | 8550 | table.InitializeWithRequestAndConfig( |
8541 | request, config::ConfigHandler::DefaultConfig()); | |
8551 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8542 | 8552 | session.SetTable(&table); |
8543 | 8553 | |
8544 | 8554 | // commit "あ" to push UNDO stack |
8594 | 8604 | |
8595 | 8605 | composer::Table table; |
8596 | 8606 | table.InitializeWithRequestAndConfig( |
8597 | request, config::ConfigHandler::DefaultConfig()); | |
8607 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8598 | 8608 | session.SetTable(&table); |
8599 | 8609 | |
8600 | 8610 | // Type "!" to produce "!". |
8958 | 8968 | |
8959 | 8969 | composer::Table table; |
8960 | 8970 | table.InitializeWithRequestAndConfig( |
8961 | request, config::ConfigHandler::DefaultConfig()); | |
8971 | request, config::ConfigHandler::DefaultConfig(), mock_data_manager_); | |
8962 | 8972 | session->SetTable(&table); |
8963 | 8973 | |
8964 | 8974 | SwitchInputFieldType(commands::Context::PASSWORD, session.get()); |
96 | 96 | 'session_regression_test.cc', |
97 | 97 | ], |
98 | 98 | 'dependencies': [ |
99 | '../data_manager/testing/mock_data_manager.gyp:mock_data_manager', | |
99 | 100 | '../engine/engine.gyp:engine_factory', |
100 | 101 | '../testing/testing.gyp:gtest_main', |
101 | 102 | 'session.gyp:session', |
140 | 141 | ], |
141 | 142 | 'dependencies': [ |
142 | 143 | '../converter/converter_base.gyp:converter_mock', |
144 | '../data_manager/testing/mock_data_manager.gyp:mock_data_manager', | |
143 | 145 | '../testing/testing.gyp:gtest_main', |
144 | 146 | '../testing/testing.gyp:testing_util', |
145 | 147 | '../usage_stats/usage_stats_test.gyp:usage_stats_testing_util', |