test_widget_templates.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. "Testing widget layout templates"
  2. from unittest import TestCase
  3. try:
  4. from unittest import mock
  5. except ImportError:
  6. import mock
  7. import pytest
  8. import traitlets
  9. import ipywidgets as widgets
  10. from ipywidgets.widgets.widget_templates import LayoutProperties
  11. class TestTwoByTwoLayout(TestCase):
  12. """test layout templates"""
  13. def test_merge_cells(self): #pylint: disable=no-self-use
  14. """test merging cells with missing widgets"""
  15. button1 = widgets.Button()
  16. button2 = widgets.Button()
  17. button3 = widgets.Button()
  18. button4 = widgets.Button()
  19. box = widgets.TwoByTwoLayout(top_left=button1,
  20. top_right=button2,
  21. bottom_left=button3,
  22. bottom_right=button4)
  23. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  24. '"bottom-left bottom-right"')
  25. assert box.top_left.layout.grid_area == 'top-left'
  26. assert box.top_right.layout.grid_area == 'top-right'
  27. assert box.bottom_left.layout.grid_area == 'bottom-left'
  28. assert box.bottom_right.layout.grid_area == 'bottom-right'
  29. assert len(box.get_state()['children']) == 4
  30. box = widgets.TwoByTwoLayout(top_left=button1,
  31. top_right=button2,
  32. bottom_left=None,
  33. bottom_right=button4)
  34. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  35. '"top-left bottom-right"')
  36. assert box.top_left.layout.grid_area == 'top-left'
  37. assert box.top_right.layout.grid_area == 'top-right'
  38. assert box.bottom_left is None
  39. assert box.bottom_right.layout.grid_area == 'bottom-right'
  40. assert len(box.get_state()['children']) == 3
  41. box = widgets.TwoByTwoLayout(top_left=None,
  42. top_right=button2,
  43. bottom_left=button3,
  44. bottom_right=button4)
  45. assert box.layout.grid_template_areas == ('"bottom-left top-right"\n' +
  46. '"bottom-left bottom-right"')
  47. assert box.top_left is None
  48. assert box.top_right.layout.grid_area == 'top-right'
  49. assert box.bottom_left.layout.grid_area == 'bottom-left'
  50. assert box.bottom_right.layout.grid_area == 'bottom-right'
  51. assert len(box.get_state()['children']) == 3
  52. box = widgets.TwoByTwoLayout(top_left=None,
  53. top_right=button2,
  54. bottom_left=None,
  55. bottom_right=button4)
  56. assert box.layout.grid_template_areas == ('"top-right top-right"\n' +
  57. '"bottom-right bottom-right"')
  58. assert box.top_left is None
  59. assert box.top_right.layout.grid_area == 'top-right'
  60. assert box.bottom_left is None
  61. assert box.bottom_right.layout.grid_area == 'bottom-right'
  62. assert len(box.get_state()['children']) == 2
  63. box = widgets.TwoByTwoLayout(top_left=button1,
  64. top_right=None,
  65. bottom_left=button3,
  66. bottom_right=button4)
  67. assert box.layout.grid_template_areas == ('"top-left bottom-right"\n' +
  68. '"bottom-left bottom-right"')
  69. assert box.top_left.layout.grid_area == 'top-left'
  70. assert box.top_right is None
  71. assert box.bottom_left.layout.grid_area == 'bottom-left'
  72. assert box.bottom_right.layout.grid_area == 'bottom-right'
  73. assert len(box.get_state()['children']) == 3
  74. box = widgets.TwoByTwoLayout(top_left=button1,
  75. top_right=None,
  76. bottom_left=None,
  77. bottom_right=None)
  78. assert box.layout.grid_template_areas == ('"top-left top-left"\n' +
  79. '"top-left top-left"')
  80. assert box.top_left is button1
  81. assert box.top_left.layout.grid_area == 'top-left'
  82. assert box.top_right is None
  83. assert box.bottom_left is None
  84. assert box.bottom_right is None
  85. assert len(box.get_state()['children']) == 1
  86. box = widgets.TwoByTwoLayout(top_left=None,
  87. top_right=button1,
  88. bottom_left=None,
  89. bottom_right=None)
  90. assert box.layout.grid_template_areas == ('"top-right top-right"\n' +
  91. '"top-right top-right"')
  92. assert box.top_right is button1
  93. assert box.top_right.layout.grid_area == 'top-right'
  94. assert box.top_left is None
  95. assert box.bottom_left is None
  96. assert box.bottom_right is None
  97. assert len(box.get_state()['children']) == 1
  98. box = widgets.TwoByTwoLayout(top_left=None,
  99. top_right=None,
  100. bottom_left=None,
  101. bottom_right=None)
  102. assert box.layout.grid_template_areas is None
  103. assert box.top_left is None
  104. assert box.top_right is None
  105. assert box.bottom_left is None
  106. assert box.bottom_right is None
  107. assert not box.get_state()['children']
  108. box = widgets.TwoByTwoLayout(top_left=None,
  109. top_right=button1,
  110. bottom_left=None,
  111. bottom_right=None,
  112. merge=False)
  113. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  114. '"bottom-left bottom-right"')
  115. assert box.top_right is button1
  116. assert box.top_right.layout.grid_area == 'top-right'
  117. assert box.top_left is None
  118. assert box.bottom_left is None
  119. assert box.bottom_right is None
  120. assert len(box.get_state()['children']) == 1
  121. def test_keep_layout_options(self): #pylint: disable=no-self-use
  122. """test whether layout options are passed down to GridBox"""
  123. layout = widgets.Layout(align_items="center")
  124. button1 = widgets.Button()
  125. button2 = widgets.Button()
  126. button3 = widgets.Button()
  127. button4 = widgets.Button()
  128. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button2,
  129. bottom_left=button3, bottom_right=button4,
  130. layout=layout)
  131. assert box.layout.align_items == 'center'
  132. def test_pass_layout_options(self): #pylint: disable=no-self-use
  133. """test whether the extra layout options of the template class are
  134. passed down to Layout object"""
  135. button1 = widgets.Button()
  136. button2 = widgets.Button()
  137. button3 = widgets.Button()
  138. button4 = widgets.Button()
  139. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button2,
  140. bottom_left=button3, bottom_right=button4,
  141. grid_gap="10px", justify_content="center",
  142. align_items="center")
  143. assert box.layout.grid_gap == "10px"
  144. assert box.layout.justify_content == "center"
  145. assert box.layout.align_items == "center"
  146. # we still should be able to pass them through layout
  147. layout = widgets.Layout(grid_gap="10px", justify_content="center",
  148. align_items="center")
  149. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button2,
  150. bottom_left=button3, bottom_right=button4,
  151. layout=layout
  152. )
  153. assert box.layout.grid_gap == "10px"
  154. assert box.layout.justify_content == "center"
  155. assert box.layout.align_items == "center"
  156. # values passed directly in the constructor should overwite layout options
  157. layout = widgets.Layout(grid_gap="10px", justify_content="center",
  158. align_items="center")
  159. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button2,
  160. bottom_left=button3, bottom_right=button4,
  161. layout=layout, grid_gap="30px"
  162. )
  163. assert box.layout.grid_gap == "30px"
  164. assert box.layout.justify_content == "center"
  165. assert box.layout.align_items == "center"
  166. @mock.patch("ipywidgets.Layout.send_state")
  167. def test_update_dynamically(self, send_state): #pylint: disable=no-self-use
  168. """test whether it's possible to add widget outside __init__"""
  169. button1 = widgets.Button()
  170. button2 = widgets.Button()
  171. button3 = widgets.Button()
  172. button4 = widgets.Button()
  173. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button3,
  174. bottom_left=None, bottom_right=button4)
  175. from ipykernel.kernelbase import Kernel
  176. state = box.get_state()
  177. assert len(state['children']) == 3
  178. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  179. '"top-left bottom-right"')
  180. box.layout.comm.kernel = mock.MagicMock(spec=Kernel) #for mocking purposes
  181. send_state.reset_mock()
  182. box.bottom_left = button2
  183. state = box.get_state()
  184. assert len(state['children']) == 4
  185. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  186. '"bottom-left bottom-right"')
  187. # check whether frontend was informed
  188. send_state.assert_called_once_with(key="grid_template_areas")
  189. box = widgets.TwoByTwoLayout(top_left=button1, top_right=button3,
  190. bottom_left=None, bottom_right=button4)
  191. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  192. '"top-left bottom-right"')
  193. box.layout.comm.kernel = mock.MagicMock(spec=Kernel) #for mocking purposes
  194. send_state.reset_mock()
  195. box.merge = False
  196. assert box.layout.grid_template_areas == ('"top-left top-right"\n' +
  197. '"bottom-left bottom-right"')
  198. send_state.assert_called_once_with(key="grid_template_areas")
  199. class TestAppLayout(TestCase):
  200. """test layout templates"""
  201. def test_create_with_defaults(self):
  202. "test creating with default values"
  203. footer = widgets.Button()
  204. header = widgets.Button()
  205. center = widgets.Button()
  206. left_sidebar = widgets.Button()
  207. right_sidebar = widgets.Button()
  208. box = widgets.AppLayout(
  209. footer=footer,
  210. header=header,
  211. center=center,
  212. left_sidebar=left_sidebar,
  213. right_sidebar=right_sidebar
  214. )
  215. assert box.layout.grid_template_areas == ('"header header header"\n' +
  216. '"left-sidebar center right-sidebar"\n' +
  217. '"footer footer footer"')
  218. assert box.footer.layout.grid_area == 'footer'
  219. assert box.header.layout.grid_area == 'header'
  220. assert box.center.layout.grid_area == 'center'
  221. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  222. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  223. assert len(box.get_state()['children']) == 5
  224. # empty layout should produce no effects
  225. box = widgets.AppLayout()
  226. assert box.layout.grid_template_areas is None
  227. assert box.layout.grid_template_columns is None
  228. assert box.layout.grid_template_rows is None
  229. assert len(box.get_state()['children']) == 0
  230. def test_merge_empty_cells(self):
  231. "test if cells are correctly merged"
  232. footer = widgets.Button()
  233. header = widgets.Button()
  234. center = widgets.Button()
  235. left_sidebar = widgets.Button()
  236. right_sidebar = widgets.Button()
  237. # merge all if only one widget
  238. box = widgets.AppLayout(
  239. center=center
  240. )
  241. assert box.layout.grid_template_areas == ('"center center center"\n' +
  242. '"center center center"\n' +
  243. '"center center center"')
  244. assert box.center.layout.grid_area == 'center'
  245. assert len(box.get_state()['children']) == 1
  246. box = widgets.AppLayout(
  247. left_sidebar=left_sidebar
  248. )
  249. assert box.layout.grid_template_areas == ('"left-sidebar left-sidebar left-sidebar"\n' +
  250. '"left-sidebar left-sidebar left-sidebar"\n' +
  251. '"left-sidebar left-sidebar left-sidebar"')
  252. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  253. assert len(box.get_state()['children']) == 1
  254. # merge left and right sidebars with center
  255. box = widgets.AppLayout(
  256. header=header,
  257. footer=footer,
  258. left_sidebar=left_sidebar,
  259. center=center
  260. )
  261. assert box.layout.grid_template_areas == ('"header header header"\n' +
  262. '"left-sidebar center center"\n' +
  263. '"footer footer footer"')
  264. assert box.footer.layout.grid_area == 'footer'
  265. assert box.header.layout.grid_area == 'header'
  266. assert box.center.layout.grid_area == 'center'
  267. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  268. assert len(box.get_state()['children']) == 4
  269. box = widgets.AppLayout(
  270. header=header,
  271. footer=footer,
  272. right_sidebar=right_sidebar,
  273. center=center
  274. )
  275. assert box.layout.grid_template_areas == ('"header header header"\n' +
  276. '"center center right-sidebar"\n' +
  277. '"footer footer footer"')
  278. assert box.footer.layout.grid_area == 'footer'
  279. assert box.header.layout.grid_area == 'header'
  280. assert box.center.layout.grid_area == 'center'
  281. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  282. assert len(box.get_state()['children']) == 4
  283. box = widgets.AppLayout(
  284. header=header,
  285. footer=footer,
  286. center=center
  287. )
  288. assert box.layout.grid_template_areas == ('"header header header"\n' +
  289. '"center center center"\n' +
  290. '"footer footer footer"')
  291. assert box.footer.layout.grid_area == 'footer'
  292. assert box.header.layout.grid_area == 'header'
  293. assert box.center.layout.grid_area == 'center'
  294. assert len(box.get_state()['children']) == 3
  295. # if only center missing, remove it from view
  296. box = widgets.AppLayout(
  297. header=header,
  298. footer=footer,
  299. center=None,
  300. left_sidebar=left_sidebar,
  301. right_sidebar=right_sidebar
  302. )
  303. assert box.layout.grid_template_areas == ('"header header"\n' +
  304. '"left-sidebar right-sidebar"\n' +
  305. '"footer footer"')
  306. assert box.footer.layout.grid_area == 'footer'
  307. assert box.header.layout.grid_area == 'header'
  308. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  309. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  310. assert box.center is None
  311. assert len(box.get_state()['children']) == 4
  312. # center and one sidebar missing -> 3 row arrangement
  313. box = widgets.AppLayout(
  314. header=header,
  315. footer=footer,
  316. center=None,
  317. left_sidebar=None,
  318. right_sidebar=right_sidebar
  319. )
  320. assert box.layout.grid_template_areas == ('"header header"\n' +
  321. '"right-sidebar right-sidebar"\n' +
  322. '"footer footer"')
  323. assert box.footer.layout.grid_area == 'footer'
  324. assert box.header.layout.grid_area == 'header'
  325. assert box.left_sidebar is None
  326. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  327. assert box.center is None
  328. assert len(box.get_state()['children']) == 3
  329. # remove middle row is both sidebars and center missing
  330. box = widgets.AppLayout(
  331. header=header,
  332. footer=footer,
  333. center=None,
  334. left_sidebar=None,
  335. right_sidebar=None
  336. )
  337. assert box.layout.grid_template_areas == ('"header"\n' +
  338. '"footer"')
  339. assert box.footer.layout.grid_area == 'footer'
  340. assert box.header.layout.grid_area == 'header'
  341. assert box.center is None
  342. assert box.left_sidebar is None
  343. assert box.right_sidebar is None
  344. assert len(box.get_state()['children']) == 2
  345. # do not merge if merge=False
  346. box = widgets.AppLayout(
  347. header=header,
  348. footer=footer,
  349. center=center,
  350. merge=False
  351. )
  352. assert box.layout.grid_template_areas == ('"header header header"\n' +
  353. '"left-sidebar center right-sidebar"\n' +
  354. '"footer footer footer"')
  355. assert box.footer.layout.grid_area == 'footer'
  356. assert box.header.layout.grid_area == 'header'
  357. assert box.center.layout.grid_area == 'center'
  358. assert box.left_sidebar is None
  359. assert box.right_sidebar is None
  360. assert len(box.get_state()['children']) == 3
  361. # merge header and footer simply removes it from view
  362. box = widgets.AppLayout(
  363. footer=footer,
  364. center=center,
  365. left_sidebar=left_sidebar,
  366. right_sidebar=right_sidebar
  367. )
  368. assert box.layout.grid_template_areas == ('"left-sidebar center right-sidebar"\n' +
  369. '"footer footer footer"')
  370. assert box.center.layout.grid_area == 'center'
  371. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  372. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  373. assert box.footer.layout.grid_area == 'footer'
  374. assert box.header is None
  375. assert len(box.get_state()['children']) == 4
  376. box = widgets.AppLayout(
  377. header=header,
  378. center=center,
  379. left_sidebar=left_sidebar,
  380. right_sidebar=right_sidebar
  381. )
  382. assert box.layout.grid_template_areas == ('"header header header"\n' +
  383. '"left-sidebar center right-sidebar"')
  384. assert box.center.layout.grid_area == 'center'
  385. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  386. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  387. assert box.header.layout.grid_area == 'header'
  388. assert box.footer is None
  389. assert len(box.get_state()['children']) == 4
  390. box = widgets.AppLayout(
  391. center=center,
  392. left_sidebar=left_sidebar,
  393. right_sidebar=right_sidebar
  394. )
  395. assert box.layout.grid_template_areas == '"left-sidebar center right-sidebar"'
  396. assert box.center.layout.grid_area == 'center'
  397. assert box.left_sidebar.layout.grid_area == 'left-sidebar'
  398. assert box.right_sidebar.layout.grid_area == 'right-sidebar'
  399. assert box.footer is None
  400. assert box.header is None
  401. assert len(box.get_state()['children']) == 3
  402. # merge all if only one widget
  403. box = widgets.AppLayout(
  404. center=center
  405. )
  406. assert box.layout.grid_template_areas == ('"center center center"\n' +
  407. '"center center center"\n' +
  408. '"center center center"')
  409. assert box.center.layout.grid_area == 'center'
  410. assert len(box.get_state()['children']) == 1
  411. def test_size_to_css(self):
  412. box = widgets.AppLayout()
  413. assert box._size_to_css("100px") == '100px'
  414. assert box._size_to_css("1fr") == '1fr'
  415. assert box._size_to_css("2.5fr") == '2.5fr'
  416. assert box._size_to_css('2.5') == '2.5fr'
  417. assert box._size_to_css('25%') == '25%'
  418. with pytest.raises(TypeError):
  419. box._size_to_css('this is not correct size')
  420. def test_set_pane_widths_heights(self):
  421. footer = widgets.Button()
  422. header = widgets.Button()
  423. center = widgets.Button()
  424. left_sidebar = widgets.Button()
  425. right_sidebar = widgets.Button()
  426. box = widgets.AppLayout(
  427. header=header,
  428. footer=footer,
  429. left_sidebar=left_sidebar,
  430. right_sidebar=left_sidebar,
  431. center=center
  432. )
  433. with pytest.raises(traitlets.TraitError):
  434. box.pane_widths = ['1fx', '1fx', '1fx', '1fx']
  435. with pytest.raises(traitlets.TraitError):
  436. box.pane_widths = ['1fx', '1fx']
  437. with pytest.raises(traitlets.TraitError):
  438. box.pane_heights = ['1fx', '1fx', '1fx', '1fx']
  439. with pytest.raises(traitlets.TraitError):
  440. box.pane_heights = ['1fx', '1fx']
  441. assert box.layout.grid_template_rows == "1fr 3fr 1fr"
  442. assert box.layout.grid_template_columns == "1fr 2fr 1fr"
  443. box.pane_heights = ['3fr', '100px', 20]
  444. assert box.layout.grid_template_rows == "3fr 100px 20fr"
  445. assert box.layout.grid_template_columns == "1fr 2fr 1fr"
  446. box.pane_widths = [3, 3, 1]
  447. assert box.layout.grid_template_rows == "3fr 100px 20fr"
  448. assert box.layout.grid_template_columns == "3fr 3fr 1fr"
  449. class TestGridspecLayout(TestCase):
  450. "test GridspecLayout"
  451. def test_init(self):
  452. with pytest.raises(traitlets.TraitError):
  453. box = widgets.GridspecLayout()
  454. with pytest.raises(traitlets.TraitError):
  455. box = widgets.GridspecLayout(n_rows=-1, n_columns=1)
  456. box = widgets.GridspecLayout(n_rows=5, n_columns=3)
  457. assert box.n_rows == 5
  458. assert box.n_columns == 3
  459. assert len(box._grid_template_areas) == 5
  460. assert len(box._grid_template_areas[0]) == 3
  461. box = widgets.GridspecLayout(1, 2)
  462. assert box.n_rows == 1
  463. assert box.n_columns == 2
  464. with pytest.raises(traitlets.TraitError):
  465. box = widgets.GridspecLayout(0, 0)
  466. def test_setitem_index(self):
  467. box = widgets.GridspecLayout(2, 3)
  468. button1 = widgets.Button()
  469. button2 = widgets.Button()
  470. button3 = widgets.Button()
  471. button4 = widgets.Button()
  472. box[0, 0] = button1
  473. button1_label = button1.layout.grid_area
  474. assert button1 in box.children
  475. assert box.layout.grid_template_areas == '''"{} . ."\n". . ."'''.format(button1_label)
  476. box[-1, -1] = button2
  477. button2_label = button2.layout.grid_area
  478. assert button1_label != button2_label
  479. assert button2 in box.children
  480. assert box.layout.grid_template_areas == '''"{} . ."\n". . {}"'''.format(button1_label,
  481. button2_label)
  482. box[1, 0] = button3
  483. button3_label = button3.layout.grid_area
  484. assert button1_label != button3_label
  485. assert button2_label != button3_label
  486. assert button3 in box.children
  487. assert box.layout.grid_template_areas == '''"{b1} . ."\n"{b3} . {b2}"'''.format(b1=button1_label,
  488. b2=button2_label,
  489. b3=button3_label)
  490. #replace widget
  491. box[1, 0] = button4
  492. button4_label = button4.layout.grid_area
  493. assert button1_label != button4_label
  494. assert button2_label != button4_label
  495. assert button4 in box.children
  496. assert button3 not in box.children
  497. assert box.layout.grid_template_areas == '''"{b1} . ."\n"{b4} . {b2}"'''.format(b1=button1_label,
  498. b2=button2_label,
  499. b4=button4_label)
  500. def test_setitem_slices(self):
  501. box = widgets.GridspecLayout(2, 3)
  502. button1 = widgets.Button()
  503. box[:2, 0] = button1
  504. assert len(box.children) == 1
  505. assert button1 in box.children
  506. button1_label = button1.layout.grid_area
  507. assert box.layout.grid_template_areas == '''"{b1} . ."\n"{b1} . ."'''.format(b1=button1_label)
  508. box = widgets.GridspecLayout(2, 3)
  509. button1 = widgets.Button()
  510. button2 = widgets.Button()
  511. box[:2, 1:] = button1
  512. assert len(box.children) == 1
  513. assert button1 in box.children
  514. button1_label = button1.layout.grid_area
  515. assert box.layout.grid_template_areas == '''". {b1} {b1}"\n". {b1} {b1}"'''.format(b1=button1_label)
  516. # replace button
  517. box[:2, 1:] = button2
  518. assert len(box.children) == 1
  519. assert button2 in box.children
  520. button2_label = button2.layout.grid_area
  521. assert box.layout.grid_template_areas == '''". {b1} {b1}"\n". {b1} {b1}"'''.format(b1=button2_label)
  522. def test_getitem_index(self):
  523. "test retrieving widget"
  524. box = widgets.GridspecLayout(2, 3)
  525. button1 = widgets.Button()
  526. box[0, 0] = button1
  527. assert box[0, 0] is button1
  528. def test_getitem_slices(self):
  529. "test retrieving widgets with slices"
  530. box = widgets.GridspecLayout(2, 3)
  531. button1 = widgets.Button()
  532. box[:2, 0] = button1
  533. assert box[:2, 0] is button1
  534. box = widgets.GridspecLayout(2, 3)
  535. button1 = widgets.Button()
  536. button2 = widgets.Button()
  537. box[0, 0] = button1
  538. box[1, 0] = button2
  539. assert box[0, 0] is button1
  540. assert box[1, 0] is button2
  541. with pytest.raises(TypeError, match="The slice spans"):
  542. button = box[:2, 0]
  543. class TestLayoutProperties(TestCase):
  544. """test mixin with layout properties"""
  545. class DummyTemplate(widgets.GridBox, LayoutProperties):
  546. location = traitlets.Instance(widgets.Widget, allow_none=True)
  547. def test_layout_updated_on_trait_change(self):
  548. "test whether respective layout traits are updated when traits change"
  549. template = self.DummyTemplate(width="100%")
  550. assert template.width == '100%'
  551. assert template.layout.width == '100%'
  552. template.width = 'auto'
  553. assert template.width == 'auto'
  554. assert template.layout.width == 'auto'
  555. def test_align_items_extra_options(self):
  556. template = self.DummyTemplate(align_items='top')
  557. assert template.align_items == 'top'
  558. assert template.layout.align_items == 'flex-start'
  559. template.align_items = 'bottom'
  560. assert template.align_items == 'bottom'
  561. assert template.layout.align_items == 'flex-end'
  562. def test_validate_properties(self):
  563. prop_obj = self.DummyTemplate()
  564. for prop in LayoutProperties.align_items.values:
  565. prop_obj.align_items = prop
  566. assert prop_obj.align_items == prop
  567. with pytest.raises(traitlets.TraitError):
  568. prop_obj.align_items = 'any default position'