TEST(pqrs_xml_compiler, reload) { pqrs::xml_compiler xml_compiler("data/system_xml", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ(0, xml_compiler.get_error_count()); EXPECT_EQ(boost::optional<uint32_t>(123), xml_compiler.get_symbol_map_value("KeyCode::MY_LANG_KEY")); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("ConsumerKeyCode::BRIGHTNESS_UP")); EXPECT_EQ(boost::optional<uint32_t>(5), xml_compiler.get_symbol_map_value("ApplicationType::VI")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::VI"), xml_compiler.get_appid("org.vim.MacVim")); // com.apple.Terminal is overwritten by private.xml. EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::TERMINAL_APPLE"), xml_compiler.get_appid("com.apple.Terminal")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::TERMINAL"), xml_compiler.get_appid("com.googlecode.iterm2")); // org.gnu.Emacs is overwritten by private.xml. EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::EMACS"), xml_compiler.get_appid("org.gnu.Emacs")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::EMACS"), xml_compiler.get_appid("org.gnu.AquamacsEmacs")); EXPECT_EQ(boost::optional<uint32_t>(0x03f0), xml_compiler.get_symbol_map_value("DeviceVendor::HEWLETT_PACKARD")); EXPECT_EQ(boost::optional<uint32_t>(0x0224), xml_compiler.get_symbol_map_value("DeviceProduct::MY_HP_KEYBOARD")); }
TEST(pqrs_xml_compiler, reload) { pqrs::xml_compiler xml_compiler("data/system_xml", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ(0, xml_compiler.get_error_information().get_count()); EXPECT_EQ("", xml_compiler.get_error_information().get_message()); EXPECT_EQ(boost::optional<uint32_t>(0), xml_compiler.get_symbol_map_value("ConfigIndex::notsave_private_sample")); EXPECT_EQ(boost::optional<uint32_t>(1), xml_compiler.get_symbol_map_value("ConfigIndex::notsave_passthrough")); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("ConfigIndex::notsave_remap_sample")); EXPECT_EQ(boost::optional<uint32_t>(3), xml_compiler.get_symbol_map_value("ConfigIndex::private_include_test")); EXPECT_EQ(boost::optional<uint32_t>(4), xml_compiler.get_symbol_map_value("ConfigIndex::private_replacement")); EXPECT_EQ(boost::optional<uint32_t>(5), xml_compiler.get_symbol_map_value("ConfigIndex::private_space_is_ignored")); { std::string expected = "private.space_ is_ ignored"; EXPECT_EQ(boost::optional<const std::string&>(expected), xml_compiler.get_identifier(5)); } EXPECT_EQ(boost::optional<uint32_t>(123), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_123")); EXPECT_EQ(boost::optional<uint32_t>(456), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_456")); EXPECT_EQ(boost::optional<uint32_t>(654), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_654")); EXPECT_EQ(boost::optional<uint32_t>(1), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_PARENT1")); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_PARENT2")); EXPECT_EQ(boost::optional<uint32_t>(3), xml_compiler.get_symbol_map_value("KeyCode::MY_INCLUDE_TEST_PARENT3")); EXPECT_EQ(boost::optional<uint32_t>(123), xml_compiler.get_symbol_map_value("KeyCode::MY_LANG_KEY")); EXPECT_EQ(boost::optional<uint32_t>(999), xml_compiler.get_symbol_map_value("KeyCode::SPACE_IS_IGNORED")); EXPECT_EQ(boost::optional<uint32_t>(1191), xml_compiler.get_symbol_map_value("KeyCode::VK_CONFIG_TOGGLE_notsave_passthrough")); EXPECT_EQ(boost::optional<uint32_t>(1192), xml_compiler.get_symbol_map_value("KeyCode::VK_CONFIG_FORCE_ON_notsave_passthrough")); EXPECT_EQ(boost::optional<uint32_t>(1193), xml_compiler.get_symbol_map_value("KeyCode::VK_CONFIG_FORCE_OFF_notsave_passthrough")); EXPECT_EQ(boost::optional<uint32_t>(1194), xml_compiler.get_symbol_map_value("KeyCode::VK_CONFIG_SYNC_KEYDOWNUP_notsave_passthrough")); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("ConsumerKeyCode::BRIGHTNESS_UP")); EXPECT_EQ(boost::optional<uint32_t>(5), xml_compiler.get_symbol_map_value("ApplicationType::VI")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::VI"), xml_compiler.get_appid("org.vim.MacVim")); EXPECT_EQ(boost::optional<uint32_t>(7), xml_compiler.get_symbol_map_value("ApplicationType::SPACE_IS_IGNORED")); // com.apple.Terminal is overwritten by private.xml. EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::TERMINAL_APPLE"), xml_compiler.get_appid("com.apple.Terminal")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::TERMINAL"), xml_compiler.get_appid("com.googlecode.iterm2")); // org.gnu.Emacs is overwritten by private.xml. EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::EMACS"), xml_compiler.get_appid("org.gnu.Emacs")); EXPECT_EQ(xml_compiler.get_symbol_map_value("ApplicationType::EMACS"), xml_compiler.get_appid("org.gnu.AquamacsEmacs")); EXPECT_EQ(boost::optional<uint32_t>(0x03f0), xml_compiler.get_symbol_map_value("DeviceVendor::HEWLETT_PACKARD")); EXPECT_EQ(boost::optional<uint32_t>(0x9999), xml_compiler.get_symbol_map_value("DeviceVendor::SPACE_IS_IGNORED")); EXPECT_EQ(boost::optional<uint32_t>(0x0224), xml_compiler.get_symbol_map_value("DeviceProduct::MY_HP_KEYBOARD")); EXPECT_EQ(boost::optional<uint32_t>(0x9999), xml_compiler.get_symbol_map_value("DeviceProduct::SPACE_IS_IGNORED")); auto node_tree = xml_compiler.get_preferences_checkbox_node_tree(); EXPECT_TRUE(node_tree.get_children()); auto node_ptr = (*(node_tree.get_children()))[0]; EXPECT_EQ("Swap Space and Tab\n appendix1\n appendix123\n appendix123_2", node_ptr->get_node().get_name()); { std::vector<uint32_t> actual; EXPECT_TRUE(xml_compiler.debug_get_initialize_vector(actual, "remap.showstatusmessage")); std::vector<uint32_t> expected; // <autogen>--ShowStatusMessage-- A B C D E F G </autogen> expected.push_back(14); // count expected.push_back(47); // BRIDGE_STATUSMESSAGE expected.push_back(65); // A expected.push_back(32); // space expected.push_back(66); // B expected.push_back(32); // space expected.push_back(67); // C expected.push_back(32); // space expected.push_back(68); // D expected.push_back(32); // space expected.push_back(69); // E expected.push_back(32); // space expected.push_back(70); // F expected.push_back(32); // space expected.push_back(71); // G EXPECT_EQ(expected, actual); } }
TEST(pqrs_xml_compiler_filter_vector, filter_vector) { pqrs::xml_compiler::symbol_map s; s.add("ApplicationType", "APP1", 1); s.add("ApplicationType", "APP2", 2); s.add("ApplicationType", "APP3", 3); s.add("DeviceVendor", "VENDOR1", 10); s.add("DeviceVendor", "VENDOR2", 20); s.add("DeviceVendor", "VENDOR3", 30); s.add("DeviceProduct", "PRODUCT1", 100); s.add("DeviceProduct", "PRODUCT2", 200); s.add("DeviceProduct", "PRODUCT3", 300); s.add("ConfigIndex", "config1", 1000); s.add("ConfigIndex", "config2", 2000); s.add("ConfigIndex", "config3", 3000); s.add("ModifierFlag", "MOD1", 0x1000); s.add("ModifierFlag", "MOD2", 0x2000); s.add("ModifierFlag", "MOD3", 0x4000); std::string xml("<?xml version=\"1.0\"?>" "<item>" " <only>APP1,APP3</only>" " <only><!-- empty --></only>" " <only>,,</only>" " <not><!-- XXX --->APP2</not>" " <identifier>sample</identifier>" " <device_only>DeviceVendor::VENDOR1, DeviceProduct::PRODUCT1, </device_only>" " <device_not>" " DeviceVendor::VENDOR3,,,," " DeviceProduct::PRODUCT3," " </device_not>" " <config_only>config1,config2</config_only>" " <config_not>config3</config_not>" " <modifier_only>ModifierFlag::MOD1 ||| ModifierFlag::MOD3</modifier_only>" " <modifier_not> ModifierFlag::MOD2 </modifier_not>" "</item>"); std::stringstream istream(xml, std::stringstream::in); pqrs::xml_compiler xml_compiler("data/system_xml", "data/private_xml"); int flags = boost::property_tree::xml_parser::no_comments; boost::property_tree::ptree pt; boost::property_tree::read_xml(istream, pt, flags); pqrs::string::replacement replacement; for (auto& it : pt) { pqrs::xml_compiler::filter_vector fv(s); fv.traverse(pqrs::xml_compiler::extracted_ptree(xml_compiler, replacement, it.second, "")); std::vector<uint32_t> expected; // <only>APP1,APP3</only> expected.push_back(3); // count expected.push_back(BRIDGE_FILTERTYPE_APPLICATION_ONLY); expected.push_back(1); // APP1 expected.push_back(3); // APP3 // <only><!-- empty --></only>" // <only>,,</only>" // ***IGNORED*** // <not>APP2</not> expected.push_back(2); // count expected.push_back(BRIDGE_FILTERTYPE_APPLICATION_NOT); expected.push_back(2); // APP2 // <device_only>DeviceVendor::VENDOR1, DeviceProduct::PRODUCT1, </device_only> expected.push_back(3); // count expected.push_back(BRIDGE_FILTERTYPE_DEVICE_ONLY); expected.push_back(10); expected.push_back(100); // <device_not>DeviceVendor::VENDOR3, DeviceProduct::PRODUCT3, </device_not> expected.push_back(3); // count expected.push_back(BRIDGE_FILTERTYPE_DEVICE_NOT); expected.push_back(30); expected.push_back(300); // <config_only>config1,config2</config_only> expected.push_back(3); // count expected.push_back(BRIDGE_FILTERTYPE_CONFIG_ONLY); expected.push_back(1000); expected.push_back(2000); // <config_not>config3</config_not> expected.push_back(2); // count expected.push_back(BRIDGE_FILTERTYPE_CONFIG_NOT); expected.push_back(3000); // <modifier_only>ModifierFlag::MOD1 ||| ModifierFlag::MOD3</modifier_only> expected.push_back(2); expected.push_back(BRIDGE_FILTERTYPE_MODIFIER_ONLY); expected.push_back(0x1000 | 0x4000); // <modifier_not> ModifierFlag::MOD2 </modifier_not> expected.push_back(2); expected.push_back(BRIDGE_FILTERTYPE_MODIFIER_NOT); expected.push_back(0x2000); EXPECT_EQ(expected, fv.get()); } }
TEST(pqrs_xml_compiler, reload_invalid_xml) { // ------------------------------------------------------------ // invalid XML format { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/broken_xml"); xml_compiler.reload(); EXPECT_EQ("<data/invalid_xml/broken_xml/private.xml>(4): expected element name", xml_compiler.get_error_information().get_message()); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("ConsumerKeyCode::BRIGHTNESS_UP")); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/broken_include"); xml_compiler.reload(); EXPECT_EQ("<data/invalid_xml/broken_include/include.xml>(4): expected element name", xml_compiler.get_error_information().get_message()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/missing_include"); xml_compiler.reload(); EXPECT_EQ("data/invalid_xml/missing_include/include.xml is not found.", xml_compiler.get_error_information().get_message()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/infinite_include_loop"); xml_compiler.reload(); EXPECT_EQ("An infinite include loop is detected:\n" "data/invalid_xml/infinite_include_loop/private.xml", xml_compiler.get_error_information().get_message()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/infinite_include_loop2"); xml_compiler.reload(); EXPECT_EQ("An infinite include loop is detected:\n" "data/invalid_xml/infinite_include_loop2/include.xml", xml_compiler.get_error_information().get_message()); } // ------------------------------------------------------------ // identifier { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/dup_identifier"); xml_compiler.reload(); const char* message = "Duplicated identifier:\n" "\n" "<identifier>private.swap_space_and_tab</identifier>"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/empty_identifier"); xml_compiler.reload(); EXPECT_EQ("Empty <identifier>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(2, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/empty_identifier2"); xml_compiler.reload(); EXPECT_EQ("Empty <identifier>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(2, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/invalid_identifier_place"); xml_compiler.reload(); const char* message = "<identifier> must be placed directly under <item>:\n" "\n" "<identifier>private.swap_space_and_tab</identifier>"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/invalid_identifier_place2"); xml_compiler.reload(); const char* message = "<identifier> must be placed directly under <item>:\n" "\n" "<identifier>private.swap_space_and_tab</identifier>"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // autogen { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_autogen"); xml_compiler.reload(); const char* message = "Invalid <autogen>:\n" "\n" "<autogen>--KeyToKey2-- KeyCode::SPACE, VK_SHIFT, KeyCode::TAB</autogen>"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); { std::vector<uint32_t> actual; EXPECT_TRUE(xml_compiler.debug_get_initialize_vector(actual, "private.swap_space_and_tab")); // empty if error std::vector<uint32_t> expected; EXPECT_EQ(expected, actual); } { std::vector<uint32_t> actual; EXPECT_TRUE(xml_compiler.debug_get_initialize_vector(actual, "private.swap_space_and_tab2")); std::vector<uint32_t> expected; // ------------------------------------------------------------ // <autogen>--KeyToKey-- KeyCode::SPACE, VK_SHIFT, KeyCode::TAB</autogen> expected.push_back(7); // count expected.push_back(12); // BRIDGE_REMAPTYPE_KEYTOKEY expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(49); // KeyCode::SPACE expected.push_back(3); // BRIDGE_DATATYPE_FLAGS expected.push_back(131074); // ModifierFlag::SHIFT_L expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(48); // KeyCode::TAB expected.push_back(2); // count expected.push_back(36); // BRIDGE_FILTERTYPE_CONFIG_NOT expected.push_back(0); // ConfigIndex::notsave_passthrough expected.push_back(7); // count expected.push_back(12); // BRIDGE_REMAPTYPE_KEYTOKEY expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(49); // KeyCode::SPACE expected.push_back(3); // BRIDGE_DATATYPE_FLAGS expected.push_back(131076); // ModifierFlag::SHIFT_R expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(48); // KeyCode::TAB expected.push_back(2); // count expected.push_back(36); // BRIDGE_FILTERTYPE_CONFIG_NOT expected.push_back(0); // ConfigIndex::notsave_passthrough // ------------------------------------------------------------ // <autogen>--KeyToKey-- KeyCode::TAB, VK_SHIFT, KeyCode::SPACE</autogen> expected.push_back(7); // count expected.push_back(12); // BRIDGE_REMAPTYPE_KEYTOKEY expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(48); // KeyCode::TAB expected.push_back(3); // BRIDGE_DATATYPE_FLAGS expected.push_back(131074); // ModifierFlag::SHIFT_L expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(49); // KeyCode::SPACE expected.push_back(2); // count expected.push_back(36); // BRIDGE_FILTERTYPE_CONFIG_NOT expected.push_back(0); // ConfigIndex::notsave_passthrough expected.push_back(7); // count expected.push_back(12); // BRIDGE_REMAPTYPE_KEYTOKEY expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(48); // KeyCode::TAB expected.push_back(3); // BRIDGE_DATATYPE_FLAGS expected.push_back(131076); // ModifierFlag::SHIFT_R expected.push_back(1); // BRIDGE_DATATYPE_KEYCODE expected.push_back(49); // KeyCode::SPACE expected.push_back(2); // count expected.push_back(36); // BRIDGE_FILTERTYPE_CONFIG_NOT expected.push_back(0); // ConfigIndex::notsave_passthrough EXPECT_EQ(expected, actual); } } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/autogen_invalid_pipe_type"); xml_compiler.reload(); const char* message = "Cannot connect(|) except ModifierFlag and PointingButton:\n" "\n" "KeyCode::SPACE|KeyCode::TAB"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/autogen_invalid_pipe_different_type"); xml_compiler.reload(); const char* message = "Cannot connect(|) between different types:\n" "\n" "ModifierFlag::SHIFT_L|PointingButton::LEFT"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // Unknown symbol_map { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_symbol_map"); xml_compiler.reload(); EXPECT_EQ("Unknown symbol:\n\nKeyCode::MY_UNKNOWN_KEY", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // Unknown data_type { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_data_type"); xml_compiler.reload(); EXPECT_EQ("Unknown symbol:\n\nKeyCode2::SPACE", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // replacementdef.xml { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_no_name", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("No <replacementname> within <replacementdef>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_empty_name", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Empty <replacementname> within <replacementdef>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_invalid_name1", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Do not use '{{' and '}}' within <replacementname>:\n\nVI{{_J", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_invalid_name2", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Do not use '{{' and '}}' within <replacementname>:\n\nVI_}}J", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_no_value", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("No <replacementvalue> within <replacementdef>:\n\nVI_J", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // symbol_map.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_type"); xml_compiler.reload(); EXPECT_EQ("No 'type' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_type"); xml_compiler.reload(); EXPECT_EQ("Empty 'type' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_name"); xml_compiler.reload(); EXPECT_EQ("No 'name' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty 'name' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_value"); xml_compiler.reload(); EXPECT_EQ("No 'value' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty 'value' Attribute within <symbol_map>.", xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_invalid_value"); xml_compiler.reload(); const char* message = "Invalid 'value' Attribute within <symbol_map>:\n" "\n" "<symbol_map type=\"ConsumerKeyCode\" name=\"BRIGHTNESS_UP\" value=\"XXX\" />"; EXPECT_EQ(message, xml_compiler.get_error_information().get_message()); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // appdef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/appdef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <appname> within <appdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/appdef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <appname> within <appdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // devicevendordef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <vendorname> within <devicevendordef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <vendorname> within <devicevendordef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_no_value"); xml_compiler.reload(); EXPECT_EQ("No <vendorid> within <devicevendordef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty <vendorid> within <devicevendordef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_invalid_value"); xml_compiler.reload(); const char* message = "Invalid <vendorid> within <devicevendordef>:\n" "\n" "<vendorid>XXX</vendorid>"; EXPECT_EQ(message, std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } // ------------------------------------------------------------ // deviceproductdef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <productname> within <deviceproductdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <productname> within <deviceproductdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_no_value"); xml_compiler.reload(); EXPECT_EQ("No <productid> within <deviceproductdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty <productid> within <deviceproductdef>.", std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_invalid_value"); xml_compiler.reload(); const char* message = "Invalid <productid> within <deviceproductdef>:\n" "\n" "<productid>XXX</productid>"; EXPECT_EQ(message, std::string(xml_compiler.get_error_information().get_message())); EXPECT_EQ(1, xml_compiler.get_error_information().get_count()); } }
int main(int argc, const char* argv[]) { if (argc != 4) { std::cerr << "Usage: " << argv[0] << " system_xml_directory private_xml_directory command" << std::endl << std::endl << "Example: " << argv[0] << " /Applications/Karabiner.app/Contents/Resources" << " ~/Library/Application\\ Support/Karabiner" << " dump_data" << std::endl; exit(1); } pqrs::xml_compiler xml_compiler(argv[1], argv[2]); xml_compiler.reload(); if (xml_compiler.get_error_information().get_count() > 0) { std::cerr << xml_compiler.get_error_information().get_message() << std::endl; exit(1); } std::string command(argv[3]); if (command == "dump_data") { auto v = xml_compiler.get_remapclasses_initialize_vector().get(); for (auto& it : v) { std::cout << it << std::endl; } } else if (command == "dump_tree") { dump_tree(xml_compiler.get_preferences_checkbox_node_tree(), false); std::cout << std::endl; std::cout << std::endl; std::cout << "Total items: " << total_identifier_count_ << std::endl; } else if (command == "dump_tree_all") { dump_tree(xml_compiler.get_preferences_checkbox_node_tree(), true); std::cout << std::endl; std::cout << std::endl; std::cout << "Total items: " << total_identifier_count_ << std::endl; } else if (command == "dump_number") { dump_number(xml_compiler.get_preferences_number_node_tree()); } else if (command == "dump_identifier_except_essential") { for (int i = 0;; ++i) { auto identifier = xml_compiler.get_identifier(i); if (!identifier) break; std::cout << *identifier << std::endl; } } else if (command == "dump_symbol_map") { xml_compiler.get_symbol_map().dump(); } else if (command == "output_bridge_essential_configuration_enum_h") { std::cout << "enum {" << std::endl; for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { std::cout << "BRIDGE_ESSENTIAL_CONFIG_INDEX__END__ = " << i << std::endl; break; } std::cout << "BRIDGE_ESSENTIAL_CONFIG_INDEX_" << essential_configuration->get_identifier() << " = " << i << "," << std::endl; } std::cout << "};" << std::endl; } else if (command == "output_bridge_essential_configuration_default_values_c") { for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { break; } std::cout << essential_configuration->get_default_value() << "," << std::endl; } } else if (command == "output_bridge_essential_configuration_identifiers_m") { for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { std::cout << "nil" << std::endl; break; } std::cout << "@\"" << essential_configuration->get_raw_identifier() << "\"" << "," << std::endl; } } return 0; }
TEST(pqrs_xml_compiler, reload_invalid_xml) { // ------------------------------------------------------------ // invalid XML format { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/broken_xml"); xml_compiler.reload(); EXPECT_EQ("<private.xml>(4): expected element name", xml_compiler.get_error_message()); EXPECT_EQ(boost::optional<uint32_t>(2), xml_compiler.get_symbol_map_value("ConsumerKeyCode::BRIGHTNESS_UP")); } // ------------------------------------------------------------ // identifier { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/dup_identifier"); xml_compiler.reload(); const char* message = "Duplicated identifier:\n" "\n" "<identifier>private.swap_space_and_tab</identifier>"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/empty_identifier"); xml_compiler.reload(); EXPECT_EQ("Empty <identifier>.", xml_compiler.get_error_message()); EXPECT_EQ(3, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/invalid_identifier_place"); xml_compiler.reload(); const char* message = "<identifier> must be placed directly under <item>:\n" "\n" "<identifier>private.swap_space_and_tab</identifier>"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(3, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // autogen { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_autogen"); xml_compiler.reload(); const char* message = "Invalid <autogen>:\n" "\n" "<autogen>--KeyToKey2-- KeyCode::SPACE, VK_SHIFT, KeyCode::TAB</autogen>"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(2, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/autogen_invalid_pipe_type"); xml_compiler.reload(); const char* message = "Cannot connect(|) except ModifierFlag and PointingButton:\n" "\n" "KeyCode::SPACE|KeyCode::TAB"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(2, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/autogen_invalid_pipe_different_type"); xml_compiler.reload(); const char* message = "Cannot connect(|) between different types:\n" "\n" "ModifierFlag::SHIFT_L|PointingButton::LEFT"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(2, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // Unknown symbol_map { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_symbol_map"); xml_compiler.reload(); EXPECT_EQ("Unknown symbol:\n\nKeyCode::MY_UNKNOWN_KEY", xml_compiler.get_error_message()); EXPECT_EQ(2, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // Unknown data_type { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/unknown_data_type"); xml_compiler.reload(); EXPECT_EQ("Unknown symbol:\n\nKeyCode2::SPACE", xml_compiler.get_error_message()); EXPECT_EQ(2, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // replacementdef.xml { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_no_name", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("No <replacementname> within <replacementdef>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_empty_name", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Empty <replacementname> within <replacementdef>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_invalid_name1", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Do not use '{{' and '}}' within <replacementname>:\n\nVI{{_J", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_invalid_name2", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("Do not use '{{' and '}}' within <replacementname>:\n\nVI_}}J", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/invalid_xml/replacementdef_no_value", "data/private_xml"); xml_compiler.reload(); EXPECT_EQ("No <replacementvalue> within <replacementdef>:\n\nVI_J", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // symbol_map.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_type"); xml_compiler.reload(); EXPECT_EQ("No 'type' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_type"); xml_compiler.reload(); EXPECT_EQ("Empty 'type' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_name"); xml_compiler.reload(); EXPECT_EQ("No 'name' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty 'name' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_no_value"); xml_compiler.reload(); EXPECT_EQ("No 'value' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty 'value' Attribute within <symbol_map>.", xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/symbol_map_xml_invalid_value"); xml_compiler.reload(); const char* message = "Invalid 'value' Attribute within <symbol_map>:\n" "\n" "<symbol_map type=\"ConsumerKeyCode\" name=\"BRIGHTNESS_UP\" value=\"XXX\" />"; EXPECT_EQ(message, xml_compiler.get_error_message()); EXPECT_EQ(1, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // appdef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/appdef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <appname> within <appdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/appdef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <appname> within <appdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // devicevendordef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <vendorname> within <devicevendordef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <vendorname> within <devicevendordef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_no_value"); xml_compiler.reload(); EXPECT_EQ("No <vendorid> within <devicevendordef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty <vendorid> within <devicevendordef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/devicevendordef_invalid_value"); xml_compiler.reload(); const char* message = "Invalid <vendorid> within <devicevendordef>:\n" "\n" "<vendorid>XXX</vendorid>"; EXPECT_EQ(message, std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } // ------------------------------------------------------------ // deviceproductdef.xml { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_no_name"); xml_compiler.reload(); EXPECT_EQ("No <productname> within <deviceproductdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_empty_name"); xml_compiler.reload(); EXPECT_EQ("Empty <productname> within <deviceproductdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_no_value"); xml_compiler.reload(); EXPECT_EQ("No <productid> within <deviceproductdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_empty_value"); xml_compiler.reload(); EXPECT_EQ("Empty <productid> within <deviceproductdef>.", std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } { pqrs::xml_compiler xml_compiler("data/system_xml", "data/invalid_xml/deviceproductdef_invalid_value"); xml_compiler.reload(); const char* message = "Invalid <productid> within <deviceproductdef>:\n" "\n" "<productid>XXX</productid>"; EXPECT_EQ(message, std::string(xml_compiler.get_error_message())); EXPECT_EQ(1, xml_compiler.get_error_count()); } }