Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

200 linhas
7.0KB

  1. import asyncio
  2. import itertools
  3. from pico import start_server, send_json, recv_json
  4. import websockets
  5. class Script:
  6. def __init__(self):
  7. self.events = []
  8. def __add__(self, event):
  9. self.events.append(('send', event))
  10. return self
  11. def __sub__(self, event):
  12. self.events.append(('recv', event))
  13. return self
  14. async def _make_client(path, timeout, script):
  15. state = {}
  16. error = False
  17. await asyncio.sleep(timeout)
  18. async with websockets.connect(path) as websocket:
  19. for kind, message in script.events:
  20. if kind == 'recv':
  21. A, B = message, await recv_json(websocket)
  22. B.pop('ts')
  23. if B['kind'] == 'state':
  24. state.update(B)
  25. if A != B:
  26. error = True
  27. print('-', A)
  28. print('+', B)
  29. print()
  30. elif kind == 'send':
  31. await send_json(websocket, **message)
  32. while 'online' in state:
  33. if state['online'][0] == state['username']:
  34. break
  35. message = await recv_json(websocket)
  36. message.pop('ts')
  37. error = True
  38. print('+', message)
  39. print()
  40. state.update(message)
  41. if error:
  42. print('error')
  43. exit()
  44. async def _test(*clients):
  45. try:
  46. gather = asyncio.gather(
  47. start_server('localhost', 8642, 'TestServer'),
  48. *clients,
  49. )
  50. server, *results = await asyncio.wait_for(gather, timeout=2)
  51. server.close()
  52. except asyncio.TimeoutError:
  53. return
  54. return results
  55. def test_happy_path():
  56. client = _make_client('ws://localhost:8642/x', 0.1, Script()
  57. + {'kind': 'login', 'value': 'TestUser'}
  58. - {'kind': 'state', 'username': 'TestUser'}
  59. - {'kind': 'state', 'online': ['TestUser']}
  60. + {'kind': 'post', 'value': 'Hello World!'}
  61. - {'kind': 'post', 'value': 'Hello World!', 'source': 'TestUser'}
  62. )
  63. return _test(client)
  64. def test_name_taken():
  65. client1 = _make_client('ws://localhost:8642/x', 0.10, Script()
  66. + {'kind': 'login', 'value': 'A'}
  67. - {'kind': 'state', 'username': 'A'}
  68. - {'kind': 'state', 'online': ['A']}
  69. - {'kind': 'state', 'online': ['A', 'B']}
  70. )
  71. client2 = _make_client('ws://localhost:8642/x', 0.11, Script()
  72. + {'kind': 'login', 'value': 'A'}
  73. - {'kind': 'error', 'value': 'Username taken'}
  74. )
  75. client3 = _make_client('ws://localhost:8642/x', 0.12, Script()
  76. + {'kind': 'login', 'value': 'B'}
  77. - {'kind': 'state', 'username': 'B'}
  78. - {'kind': 'state', 'online': ['A', 'B']}
  79. - {'kind': 'state', 'online': ['B']}
  80. )
  81. return _test(client1, client2, client3)
  82. def test_interaction():
  83. client1 = _make_client('ws://localhost:8642/x', 0.10, Script()
  84. + {'kind': 'login', 'value': 'Alice'}
  85. - {'kind': 'state', 'username': 'Alice'}
  86. - {'kind': 'state', 'online': ['Alice']}
  87. - {'kind': 'state', 'online': ['Alice', 'Bob']}
  88. + {'kind': 'post', 'value': 'Hey Bob!'}
  89. - {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
  90. - {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
  91. )
  92. client2 = _make_client('ws://localhost:8642/x', 0.11, Script()
  93. + {'kind': 'login', 'value': 'Bob'}
  94. - {'kind': 'state', 'username': 'Bob'}
  95. - {'kind': 'state', 'online': ['Alice', 'Bob']}
  96. - {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
  97. + {'kind': 'post', 'value': 'Howdy!'}
  98. - {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
  99. - {'kind': 'state', 'online': ['Bob']}
  100. )
  101. return _test(client1, client2)
  102. def test_rooms():
  103. client1 = _make_client('ws://localhost:8642/x', 0.10, Script()
  104. + {'kind': 'login', 'value': 'Dandy'}
  105. - {'kind': 'state', 'username': 'Dandy'}
  106. - {'kind': 'state', 'online': ['Dandy']}
  107. + {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
  108. - {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
  109. )
  110. client2 = _make_client('ws://localhost:8642/y', 0.10, Script()
  111. + {'kind': 'login', 'value': 'Dandy'}
  112. - {'kind': 'state', 'username': 'Dandy'}
  113. - {'kind': 'state', 'online': ['Dandy']}
  114. + {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
  115. - {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
  116. )
  117. return _test(client1, client2)
  118. def test_private_message():
  119. client1 = _make_client('ws://localhost:8642/x', 0.10, Script()
  120. + {'kind': 'login', 'value': 'Norman'}
  121. - {'kind': 'state', 'username': 'Norman'}
  122. - {'kind': 'state', 'online': ['Norman']}
  123. - {'kind': 'state', 'online': ['Norman', 'Ray']}
  124. - {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
  125. + {'kind': 'post', 'value': '1', 'target': 'Ray'}
  126. - {'kind': 'post', 'value': '3', 'source': 'Emma'}
  127. )
  128. client2 = _make_client('ws://localhost:8642/x', 0.11, Script()
  129. + {'kind': 'login', 'value': 'Ray'}
  130. - {'kind': 'state', 'username': 'Ray'}
  131. - {'kind': 'state', 'online': ['Norman', 'Ray']}
  132. - {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
  133. - {'kind': 'post', 'value': '1', 'source': 'Norman'}
  134. + {'kind': 'post', 'value': '2', 'target': 'Emma'}
  135. - {'kind': 'state', 'online': ['Ray', 'Emma']}
  136. )
  137. client3 = _make_client('ws://localhost:8642/x', 0.12, Script()
  138. + {'kind': 'login', 'value': 'Emma'}
  139. - {'kind': 'state', 'username': 'Emma'}
  140. - {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
  141. - {'kind': 'post', 'value': '2', 'source': 'Ray'}
  142. + {'kind': 'post', 'value': '3', 'target': 'Norman'}
  143. - {'kind': 'state', 'online': ['Ray', 'Emma']}
  144. - {'kind': 'state', 'online': ['Emma']}
  145. )
  146. return _test(client1, client2, client3)
  147. def test_query_is_irrelevant():
  148. client1 = _make_client('ws://localhost:8642/x?a=0', 0.10, Script()
  149. + {'kind': 'login', 'value': 'Alice'}
  150. - {'kind': 'state', 'username': 'Alice'}
  151. - {'kind': 'state', 'online': ['Alice']}
  152. - {'kind': 'state', 'online': ['Alice', 'Bob']}
  153. + {'kind': 'post', 'value': 'Hey Bob!'}
  154. - {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
  155. - {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
  156. )
  157. client2 = _make_client('ws://localhost:8642/x?v=0', 0.11, Script()
  158. + {'kind': 'login', 'value': 'Bob'}
  159. - {'kind': 'state', 'username': 'Bob'}
  160. - {'kind': 'state', 'online': ['Alice', 'Bob']}
  161. - {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
  162. + {'kind': 'post', 'value': 'Howdy!'}
  163. - {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
  164. - {'kind': 'state', 'online': ['Bob']}
  165. )
  166. return _test(client1, client2)
  167. if __name__ == '__main__':
  168. loop = asyncio.get_event_loop()
  169. for fn_name, fn in list(locals().items()):
  170. if fn_name.startswith('test_'):
  171. loop.run_until_complete(fn())