1# Copyright (C) 2010 Apple Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions 5# are met: 6# 1. Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# 2. Redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution. 11# 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 16# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 23import os 24import unittest 25from StringIO import StringIO 26 27import messages 28import parser 29 30print os.getcwd() 31 32script_directory = os.path.dirname(os.path.realpath(__file__)) 33 34with open(os.path.join(script_directory, 'test-messages.in')) as file: 35 _messages_file_contents = file.read() 36 37with open(os.path.join(script_directory, 'test-legacy-messages.in')) as file: 38 _legacy_messages_file_contents = file.read() 39 40with open(os.path.join(script_directory, 'test-superclass-messages.in')) as file: 41 _superclass_messages_file_contents = file.read() 42 43 44with open(os.path.join(script_directory, 'Messages-expected.h')) as file: 45 _expected_receiver_header = file.read() 46 47with open(os.path.join(script_directory, 'LegacyMessages-expected.h')) as file: 48 _expected_legacy_receiver_header = file.read() 49 50with open(os.path.join(script_directory, 'MessagesSuperclass-expected.h')) as file: 51 _expected_superclass_receiver_header = file.read() 52 53 54with open(os.path.join(script_directory, 'MessageReceiver-expected.cpp')) as file: 55 _expected_receiver_implementation = file.read() 56 57with open(os.path.join(script_directory, 'LegacyMessageReceiver-expected.cpp')) as file: 58 _expected_legacy_receiver_implementation = file.read() 59 60with open(os.path.join(script_directory, 'MessageReceiverSuperclass-expected.cpp')) as file: 61 _expected_superclass_receiver_implementation = file.read() 62 63_expected_results = { 64 'name': 'WebPage', 65 'conditions': ('(ENABLE(WEBKIT2) && (NESTED_MASTER_CONDITION || MASTER_OR && MASTER_AND))'), 66 'messages': ( 67 { 68 'name': 'LoadURL', 69 'parameters': ( 70 ('String', 'url'), 71 ), 72 'conditions': (None), 73 }, 74 { 75 'name': 'LoadSomething', 76 'parameters': ( 77 ('String', 'url'), 78 ), 79 'conditions': ('ENABLE(TOUCH_EVENTS)'), 80 }, 81 { 82 'name': 'TouchEvent', 83 'parameters': ( 84 ('WebKit::WebTouchEvent', 'event'), 85 ), 86 'conditions': ('(ENABLE(TOUCH_EVENTS) && (NESTED_MESSAGE_CONDITION || SOME_OTHER_MESSAGE_CONDITION))'), 87 }, 88 { 89 'name': 'AddEvent', 90 'parameters': ( 91 ('WebKit::WebTouchEvent', 'event'), 92 ), 93 'conditions': ('(ENABLE(TOUCH_EVENTS) && (NESTED_MESSAGE_CONDITION && SOME_OTHER_MESSAGE_CONDITION))'), 94 }, 95 { 96 'name': 'LoadSomethingElse', 97 'parameters': ( 98 ('String', 'url'), 99 ), 100 'conditions': ('ENABLE(TOUCH_EVENTS)'), 101 }, 102 { 103 'name': 'DidReceivePolicyDecision', 104 'parameters': ( 105 ('uint64_t', 'frameID'), 106 ('uint64_t', 'listenerID'), 107 ('uint32_t', 'policyAction'), 108 ), 109 'conditions': (None), 110 }, 111 { 112 'name': 'Close', 113 'parameters': (), 114 'conditions': (None), 115 }, 116 { 117 'name': 'PreferencesDidChange', 118 'parameters': ( 119 ('WebKit::WebPreferencesStore', 'store'), 120 ), 121 'conditions': (None), 122 }, 123 { 124 'name': 'SendDoubleAndFloat', 125 'parameters': ( 126 ('double', 'd'), 127 ('float', 'f'), 128 ), 129 'conditions': (None), 130 }, 131 { 132 'name': 'SendInts', 133 'parameters': ( 134 ('Vector<uint64_t>', 'ints'), 135 ('Vector<Vector<uint64_t>>', 'intVectors') 136 ), 137 'conditions': (None), 138 }, 139 { 140 'name': 'CreatePlugin', 141 'parameters': ( 142 ('uint64_t', 'pluginInstanceID'), 143 ('WebKit::Plugin::Parameters', 'parameters') 144 ), 145 'reply_parameters': ( 146 ('bool', 'result'), 147 ), 148 'conditions': (None), 149 }, 150 { 151 'name': 'RunJavaScriptAlert', 152 'parameters': ( 153 ('uint64_t', 'frameID'), 154 ('String', 'message') 155 ), 156 'reply_parameters': (), 157 'conditions': (None), 158 }, 159 { 160 'name': 'GetPlugins', 161 'parameters': ( 162 ('bool', 'refresh'), 163 ), 164 'reply_parameters': ( 165 ('Vector<WebCore::PluginInfo>', 'plugins'), 166 ), 167 'conditions': (None), 168 }, 169 { 170 'name': 'GetPluginProcessConnection', 171 'parameters': ( 172 ('String', 'pluginPath'), 173 ), 174 'reply_parameters': ( 175 ('IPC::Connection::Handle', 'connectionHandle'), 176 ), 177 'conditions': (None), 178 }, 179 { 180 'name': 'TestMultipleAttributes', 181 'parameters': ( 182 ), 183 'reply_parameters': ( 184 ), 185 'conditions': (None), 186 }, 187 { 188 'name': 'TestParameterAttributes', 189 'parameters': ( 190 ('uint64_t', 'foo', ('AttributeOne', 'AttributeTwo')), 191 ('double', 'bar'), 192 ('double', 'baz', ('AttributeThree',)), 193 ), 194 'conditions': (None), 195 }, 196 { 197 'name': 'TemplateTest', 198 'parameters': ( 199 ('HashMap<String, std::pair<String, uint64_t>>', 'a'), 200 ), 201 'conditions': (None), 202 }, 203 { 204 'name': 'SetVideoLayerID', 205 'parameters': ( 206 ('WebCore::GraphicsLayer::PlatformLayerID', 'videoLayerID'), 207 ), 208 'conditions': (None), 209 }, 210 { 211 'name': 'DidCreateWebProcessConnection', 212 'parameters': ( 213 ('IPC::MachPort', 'connectionIdentifier'), 214 ), 215 'conditions': ('PLATFORM(MAC)'), 216 }, 217 { 218 'name': 'InterpretKeyEvent', 219 'parameters': ( 220 ('uint32_t', 'type'), 221 ), 222 'reply_parameters': ( 223 ('Vector<WebCore::KeypressCommand>', 'commandName'), 224 ), 225 'conditions': ('PLATFORM(MAC)'), 226 }, 227 { 228 'name': 'DeprecatedOperation', 229 'parameters': ( 230 ('IPC::DummyType', 'dummy'), 231 ), 232 'conditions': ('ENABLE(DEPRECATED_FEATURE)'), 233 }, 234 { 235 'name': 'ExperimentalOperation', 236 'parameters': ( 237 ('IPC::DummyType', 'dummy'), 238 ), 239 'conditions': ('ENABLE(EXPERIMENTAL_FEATURE)'), 240 } 241 ), 242} 243 244_expected_superclass_results = { 245 'name': 'WebPage', 246 'superclass' : 'WebPageBase', 247 'conditions': None, 248 'messages': ( 249 { 250 'name': 'LoadURL', 251 'parameters': ( 252 ('String', 'url'), 253 ), 254 'conditions': (None), 255 }, 256 ), 257} 258 259 260class MessagesTest(unittest.TestCase): 261 def setUp(self): 262 self.receiver = parser.parse(StringIO(_messages_file_contents)) 263 self.legacy_receiver = parser.parse(StringIO(_legacy_messages_file_contents)) 264 self.superclass_receiver = parser.parse(StringIO(_superclass_messages_file_contents)) 265 266 267class ParsingTest(MessagesTest): 268 def check_message(self, message, expected_message): 269 self.assertEquals(message.name, expected_message['name']) 270 self.assertEquals(len(message.parameters), len(expected_message['parameters'])) 271 for index, parameter in enumerate(message.parameters): 272 expected_parameter = expected_message['parameters'][index] 273 self.assertEquals(parameter.type, expected_parameter[0]) 274 self.assertEquals(parameter.name, expected_parameter[1]) 275 if len(expected_parameter) > 2: 276 self.assertEquals(parameter.attributes, frozenset(expected_parameter[2])) 277 for attribute in expected_parameter[2]: 278 self.assertTrue(parameter.has_attribute(attribute)) 279 else: 280 self.assertEquals(parameter.attributes, frozenset()) 281 if message.reply_parameters != None: 282 for index, parameter in enumerate(message.reply_parameters): 283 self.assertEquals(parameter.type, expected_message['reply_parameters'][index][0]) 284 self.assertEquals(parameter.name, expected_message['reply_parameters'][index][1]) 285 else: 286 self.assertFalse('reply_parameters' in expected_message) 287 self.assertEquals(message.condition, expected_message['conditions']) 288 289 def test_receiver(self): 290 """Receiver should be parsed as expected""" 291 self.assertEquals(self.receiver.name, _expected_results['name']) 292 self.assertEquals(self.receiver.condition, _expected_results['conditions']) 293 self.assertEquals(len(self.receiver.messages), len(_expected_results['messages'])) 294 for index, message in enumerate(self.receiver.messages): 295 self.check_message(message, _expected_results['messages'][index]) 296 297 self.assertEquals(self.legacy_receiver.name, _expected_results['name']) 298 self.assertEquals(self.legacy_receiver.condition, _expected_results['conditions']) 299 self.assertEquals(len(self.legacy_receiver.messages), len(_expected_results['messages'])) 300 for index, message in enumerate(self.legacy_receiver.messages): 301 self.check_message(message, _expected_results['messages'][index]) 302 303 self.assertEquals(self.superclass_receiver.name, _expected_superclass_results['name']) 304 self.assertEquals(self.superclass_receiver.superclass, _expected_superclass_results['superclass']) 305 self.assertEquals(len(self.superclass_receiver.messages), len(_expected_superclass_results['messages'])) 306 for index, message in enumerate(self.superclass_receiver.messages): 307 self.check_message(message, _expected_superclass_results['messages'][index]) 308 309 310 311class GeneratedFileContentsTest(unittest.TestCase): 312 def assertGeneratedFileContentsEqual(self, first, second): 313 first_list = first.split('\n') 314 second_list = second.split('\n') 315 316 for index, first_line in enumerate(first_list): 317 self.assertEquals(first_line, second_list[index]) 318 319 self.assertEquals(len(first_list), len(second_list)) 320 321 322class HeaderTest(GeneratedFileContentsTest): 323 def test_header(self): 324 file_contents = messages.generate_messages_header(StringIO(_messages_file_contents)) 325 self.assertGeneratedFileContentsEqual(file_contents, _expected_receiver_header) 326 327 legacy_file_contents = messages.generate_messages_header(StringIO(_legacy_messages_file_contents)) 328 self.assertGeneratedFileContentsEqual(legacy_file_contents, _expected_legacy_receiver_header) 329 330 superclass_file_contents = messages.generate_messages_header(StringIO(_superclass_messages_file_contents)) 331 self.assertGeneratedFileContentsEqual(superclass_file_contents, _expected_superclass_receiver_header) 332 333 334class ReceiverImplementationTest(GeneratedFileContentsTest): 335 def test_receiver_implementation(self): 336 file_contents = messages.generate_message_handler(StringIO(_messages_file_contents)) 337 self.assertGeneratedFileContentsEqual(file_contents, _expected_receiver_implementation) 338 339 legacy_file_contents = messages.generate_message_handler(StringIO(_legacy_messages_file_contents)) 340 self.assertGeneratedFileContentsEqual(legacy_file_contents, _expected_legacy_receiver_implementation) 341 342 superclass_file_contents = messages.generate_message_handler(StringIO(_superclass_messages_file_contents)) 343 self.assertGeneratedFileContentsEqual(superclass_file_contents, _expected_superclass_receiver_implementation) 344 345 346class UnsupportedPrecompilerDirectiveTest(unittest.TestCase): 347 def test_error_at_else(self): 348 with self.assertRaisesRegexp(Exception, r"ERROR: '#else.*' is not supported in the \*\.in files"): 349 messages.generate_message_handler(StringIO("asd\n#else bla\nfoo")) 350 351 def test_error_at_elif(self): 352 with self.assertRaisesRegexp(Exception, r"ERROR: '#elif.*' is not supported in the \*\.in files"): 353 messages.generate_message_handler(StringIO("asd\n#elif bla\nfoo")) 354 355 356if __name__ == '__main__': 357 unittest.main() 358