Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

155 lines
5.6KB

  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. state.update(message)
  24. if A != B:
  25. error = True
  26. print('-', A)
  27. print('+', B)
  28. print()
  29. elif kind == 'send':
  30. await send_json(websocket, **message)
  31. while 'users' in state:
  32. if min(state['users']) == state['username']:
  33. break
  34. message = await recv_json(websocket)
  35. message.pop('ts')
  36. error = True
  37. print('+', message)
  38. print()
  39. state.update(message)
  40. if error:
  41. print('error')
  42. exit()
  43. async def _test(*clients):
  44. try:
  45. gather = asyncio.gather(
  46. start_server('localhost', 8642, 'TestServer'),
  47. *clients,
  48. )
  49. server, *results = await asyncio.wait_for(gather, timeout=2)
  50. server.close()
  51. except asyncio.TimeoutError:
  52. return
  53. return results
  54. def test_happy_path():
  55. client = _make_client('ws://TestUser@localhost:8642/A', 0.1, Script()
  56. - {'kind': 'update', 'users': ['TestUser'], 'info': 'Welcome to /A', 'username': 'TestUser'}
  57. + {'action': 'post', 'text': 'Hello World!'}
  58. - {'kind': 'post', 'source': 'TestUser', 'text': 'Hello World!'}
  59. )
  60. return _test(client)
  61. def test_name_taken():
  62. client1 = _make_client('ws://A@localhost:8642/', 0.10, Script()
  63. - {'kind': 'update', 'users': ['A'], 'info': 'Welcome to /', 'username': 'A'}
  64. - {'kind': 'update', 'users': ['A', 'B'], 'info': 'B joined'}
  65. )
  66. client2 = _make_client('ws://A@localhost:8642/', 0.11, Script()
  67. - {'kind': 'error', 'info': 'Username taken'}
  68. )
  69. client3 = _make_client('ws://B@localhost:8642/', 0.12, Script()
  70. - {'kind': 'update', 'users': ['A', 'B'], 'info': 'Welcome to /', 'username': 'B'}
  71. - {'kind': 'update', 'users': ['B'], 'info': 'A left'}
  72. )
  73. return _test(client1, client2, client3)
  74. def test_interact():
  75. client1 = _make_client('ws://Alice@localhost:8642/', 0.10, Script()
  76. - {'kind': 'update', 'users': ['Alice'], 'info': 'Welcome to /', 'username': 'Alice'}
  77. - {'kind': 'update', 'users': ['Alice', 'Bob'], 'info': 'Bob joined'}
  78. + {'action': 'post', 'text': 'Hey Bob!'}
  79. - {'kind': 'post', 'source': 'Alice', 'text': 'Hey Bob!'}
  80. - {'kind': 'post', 'source': 'Bob', 'text': 'Howdy!'}
  81. )
  82. client2 = _make_client('ws://Bob@localhost:8642/', 0.11, Script()
  83. - {'kind': 'update', 'users': ['Alice', 'Bob'], 'info': 'Welcome to /', 'username': 'Bob'}
  84. - {'kind': 'post', 'source': 'Alice', 'text': 'Hey Bob!'}
  85. + {'action': 'post', 'text': 'Howdy!'}
  86. - {'kind': 'post', 'source': 'Bob', 'text': 'Howdy!'}
  87. + {'action': 'post', 'text': ''}
  88. - {'kind': 'update', 'users': ['Bob'], 'info': 'Alice left'}
  89. )
  90. return _test(client1, client2)
  91. def test_party():
  92. client1 = _make_client('ws://Norman@localhost:8642/', 0.10, Script()
  93. - {'kind': 'update', 'users': ['Norman'], 'info': 'Welcome to /', 'username': 'Norman'}
  94. - {'kind': 'update', 'users': ['Norman', 'Ray'], 'info': 'Ray joined'}
  95. - {'kind': 'update', 'users': ['Emma', 'Norman', 'Ray'], 'info': 'Emma joined'}
  96. + {'action': 'post', 'text': 'なに?'}
  97. - {'kind': 'post', 'source': 'Norman', 'text': 'なに?'}
  98. - {'kind': 'update', 'users': ['Norman', 'Ray'], 'info': 'Emma left'}
  99. )
  100. client2 = _make_client('ws://Ray@localhost:8642/', 0.11, Script()
  101. - {'kind': 'update', 'users': ['Norman', 'Ray'], 'info': 'Welcome to /', 'username': 'Ray'}
  102. - {'kind': 'update', 'users': ['Emma', 'Norman', 'Ray'], 'info': 'Emma joined'}
  103. - {'kind': 'post', 'source': 'Norman', 'text': 'なに?'}
  104. - {'kind': 'update', 'users': ['Norman', 'Ray'], 'info': 'Emma left'}
  105. - {'kind': 'update', 'users': ['Ray'], 'info': 'Norman left'}
  106. )
  107. client3 = _make_client('ws://Emma@localhost:8642/', 0.12, Script()
  108. - {'kind': 'update', 'users': ['Emma', 'Norman', 'Ray'], 'info': 'Welcome to /', 'username': 'Emma'}
  109. - {'kind': 'post', 'source': 'Norman', 'text': 'なに?'}
  110. )
  111. return _test(client1, client2, client3)
  112. def test_rooms():
  113. client1 = _make_client('ws://Dandy@localhost:8642/A', 0.10, Script()
  114. - {'kind': 'update', 'users': ['Dandy'], 'info': 'Welcome to /A', 'username': 'Dandy'}
  115. + {'action': 'post', 'text': 'Hi'}
  116. - {'kind': 'post', 'source': 'Dandy', 'text': 'Hi'}
  117. )
  118. client2 = _make_client('ws://Dandy@localhost:8642/B', 0.10, Script()
  119. - {'kind': 'update', 'users': ['Dandy'], 'info': 'Welcome to /B', 'username': 'Dandy'}
  120. + {'action': 'post', 'text': 'Howdy'}
  121. - {'kind': 'post', 'source': 'Dandy', 'text': 'Howdy'}
  122. )
  123. return _test(client1, client2)
  124. if __name__ == '__main__':
  125. loop = asyncio.get_event_loop()
  126. for fn_name, fn in list(locals().items()):
  127. if fn_name.startswith('test_'):
  128. loop.run_until_complete(fn())