1
0

test_timer.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import asyncio
  2. import gc
  3. import pytest
  4. from nicegui import app, ui
  5. from nicegui.testing import Screen, User
  6. class Counter:
  7. value = 0
  8. def increment(self):
  9. self.value += 1
  10. def test_timer(screen: Screen):
  11. counter = Counter()
  12. t = ui.timer(0.1, counter.increment)
  13. assert counter.value == 0, 'count is initially zero'
  14. screen.wait(0.5)
  15. assert counter.value == 0, 'timer is not running'
  16. screen.start_server()
  17. screen.wait(0.5)
  18. assert counter.value > 0, 'timer is running after starting the server'
  19. t.deactivate()
  20. screen.wait(0.5)
  21. c = counter.value
  22. screen.wait(0.5)
  23. assert counter.value == c, 'timer is not running anymore after deactivating it'
  24. t.activate()
  25. screen.wait(0.5)
  26. assert counter.value > c, 'timer is running again after activating it'
  27. t.cancel()
  28. screen.wait(0.5)
  29. c = counter.value
  30. screen.wait(0.5)
  31. assert counter.value == c, 'timer is not running anymore after canceling it'
  32. def test_timer_on_private_page(screen: Screen):
  33. counter = Counter()
  34. @ui.page('/', reconnect_timeout=0)
  35. def page():
  36. ui.timer(0.1, counter.increment)
  37. assert counter.value == 0, 'count is initially zero'
  38. screen.start_server()
  39. screen.wait(0.5)
  40. assert counter.value == 0, 'timer is not running even after starting the server'
  41. screen.open('/')
  42. screen.wait(0.5)
  43. assert counter.value > 0, 'timer is running after opening the page'
  44. screen.close()
  45. count = counter.value
  46. screen.wait(0.5)
  47. assert counter.value == count, 'timer is not running anymore after closing the page'
  48. @pytest.mark.parametrize('once', [True, False])
  49. def test_setting_visibility(screen: Screen, once: bool):
  50. """reproduction of https://github.com/zauberzeug/nicegui/issues/206"""
  51. @ui.page('/')
  52. def page():
  53. label = ui.label('Some Label')
  54. ui.timer(0.1, lambda: label.set_visibility(False), once=once)
  55. screen.open('/')
  56. screen.wait(0.5)
  57. screen.should_not_contain('Some Label')
  58. def test_awaiting_coroutine(screen: Screen):
  59. user = {'name': 'Alice'}
  60. async def update_user():
  61. await asyncio.sleep(0.1)
  62. user['name'] = 'Bob'
  63. ui.timer(0.5, update_user)
  64. screen.open('/')
  65. screen.wait(1)
  66. assert user['name'] == 'Bob'
  67. def test_timer_on_deleted_container(screen: Screen):
  68. state = {'count': 0}
  69. with ui.row() as outer_container:
  70. with ui.row():
  71. ui.timer(0.1, lambda: state.update(count=state['count'] + 1))
  72. ui.button('delete', on_click=outer_container.clear)
  73. screen.open('/')
  74. screen.click('delete')
  75. screen.wait(0.5)
  76. count = state['count']
  77. screen.wait(0.5)
  78. assert state['count'] == count, 'timer is not running anymore after deleting the container'
  79. def test_different_callbacks(screen: Screen):
  80. def sync_function():
  81. ui.label('a synchronous function')
  82. async def async_function():
  83. await asyncio.sleep(0.1)
  84. ui.label('an asynchronous function')
  85. async def async_lambda(msg: str):
  86. await asyncio.sleep(0.1)
  87. ui.label(f'an asynchronous lambda: {msg}')
  88. ui.timer(0.1, sync_function, once=True)
  89. ui.timer(0.1, async_function, once=True)
  90. ui.timer(0.1, lambda: ui.label('a synchronous lambda'), once=True)
  91. ui.timer(0.1, lambda: async_lambda('Hi!'), once=True)
  92. screen.open('/')
  93. screen.should_contain('a synchronous function')
  94. screen.should_contain('an asynchronous function')
  95. screen.should_contain('a synchronous lambda')
  96. screen.should_contain('an asynchronous lambda: Hi!')
  97. async def test_cleanup(user: User):
  98. def update():
  99. ui.timer(0.01, update, once=True)
  100. ui.timer(0, update, once=True)
  101. def count():
  102. return sum(1 for obj in gc.get_objects() if isinstance(obj, ui.timer))
  103. await user.open('/')
  104. assert count() > 0, 'there are timer objects in memory'
  105. await asyncio.sleep(0.1)
  106. gc.collect()
  107. assert count() == 1, 'only current timer object is in memory'
  108. def test_app_timer(screen: Screen):
  109. counter = Counter()
  110. timer = app.timer(0.1, counter.increment)
  111. @ui.page('/')
  112. def page():
  113. ui.button('Activate', on_click=timer.activate)
  114. ui.button('Deactivate', on_click=timer.deactivate)
  115. screen.open('/')
  116. screen.wait(0.5)
  117. assert counter.value > 0, 'timer is running after starting the server'
  118. screen.click('Deactivate')
  119. value = counter.value
  120. screen.wait(0.5)
  121. assert counter.value == value, 'timer is not running anymore after deactivating it'
  122. screen.click('Activate')
  123. screen.wait(0.5)
  124. assert counter.value > value, 'timer is running again after activating it'
  125. value = counter.value
  126. screen.open('/')
  127. screen.wait(0.5)
  128. assert counter.value > value, 'timer is also incrementing when opening another page'