test_var_operations.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. """Integration tests for var operations."""
  2. from typing import Generator
  3. import pytest
  4. from selenium.webdriver.common.by import By
  5. from reflex.testing import AppHarness
  6. # pyright: reportOptionalMemberAccess=false, reportGeneralTypeIssues=false, reportUnknownMemberType=false
  7. def VarOperations():
  8. """App with var operations."""
  9. from typing import Dict, List
  10. import reflex_chakra as rc
  11. import reflex as rx
  12. from reflex.ivars.base import LiteralVar
  13. from reflex.ivars.sequence import ArrayVar
  14. class Object(rx.Base):
  15. str: str = "hello"
  16. class VarOperationState(rx.State):
  17. int_var1: int = 10
  18. int_var2: int = 5
  19. int_var3: int = 7
  20. float_var1: float = 10.5
  21. float_var2: float = 5.5
  22. list1: List = [1, 2]
  23. list2: List = [3, 4]
  24. list3: List = ["first", "second", "third"]
  25. list4: List = [Object(name="obj_1"), Object(name="obj_2")]
  26. str_var1: str = "first"
  27. str_var2: str = "second"
  28. str_var3: str = "ThIrD"
  29. str_var4: str = "a long string"
  30. dict1: Dict[int, int] = {1: 2}
  31. dict2: Dict[int, int] = {3: 4}
  32. html_str: str = "<div>hello</div>"
  33. app = rx.App(state=rx.State)
  34. @rx.memo
  35. def memo_comp(list1: List[int], int_var1: int, id: str):
  36. return rx.text(list1, int_var1, id=id)
  37. @rx.memo
  38. def memo_comp_nested(int_var2: int, id: str):
  39. return memo_comp(list1=[3, 4], int_var1=int_var2, id=id)
  40. @app.add_page
  41. def index():
  42. return rx.vstack(
  43. rx.el.input(
  44. id="token",
  45. value=VarOperationState.router.session.client_token,
  46. is_read_only=True,
  47. ),
  48. # INT INT
  49. rx.text(
  50. VarOperationState.int_var1 + VarOperationState.int_var2,
  51. id="int_add_int",
  52. ),
  53. rx.text(
  54. VarOperationState.int_var1 * VarOperationState.int_var2,
  55. id="int_mult_int",
  56. ),
  57. rx.text(
  58. VarOperationState.int_var1 - VarOperationState.int_var2,
  59. id="int_sub_int",
  60. ),
  61. rx.text(
  62. VarOperationState.int_var1**VarOperationState.int_var2,
  63. id="int_exp_int",
  64. ),
  65. rx.text(
  66. VarOperationState.int_var1 / VarOperationState.int_var2,
  67. id="int_div_int",
  68. ),
  69. rx.text(
  70. VarOperationState.int_var1 // VarOperationState.int_var3,
  71. id="int_floor_int",
  72. ),
  73. rx.text(
  74. VarOperationState.int_var1 % VarOperationState.int_var2,
  75. id="int_mod_int",
  76. ),
  77. rx.text(
  78. VarOperationState.int_var1 | VarOperationState.int_var2,
  79. id="int_or_int",
  80. ),
  81. rx.text(
  82. (VarOperationState.int_var1 > VarOperationState.int_var2).to_string(),
  83. id="int_gt_int",
  84. ),
  85. rx.text(
  86. (VarOperationState.int_var1 < VarOperationState.int_var2).to_string(),
  87. id="int_lt_int",
  88. ),
  89. rx.text(
  90. (VarOperationState.int_var1 >= VarOperationState.int_var2).to_string(),
  91. id="int_gte_int",
  92. ),
  93. rx.text(
  94. (VarOperationState.int_var1 <= VarOperationState.int_var2).to_string(),
  95. id="int_lte_int",
  96. ),
  97. rx.text(
  98. VarOperationState.int_var1 & VarOperationState.int_var2,
  99. id="int_and_int",
  100. ),
  101. rx.text(
  102. (VarOperationState.int_var1 | VarOperationState.int_var2).to_string(),
  103. id="int_or_int",
  104. ),
  105. rx.text(
  106. (VarOperationState.int_var1 == VarOperationState.int_var2).to_string(),
  107. id="int_eq_int",
  108. ),
  109. rx.text(
  110. (VarOperationState.int_var1 != VarOperationState.int_var2).to_string(),
  111. id="int_neq_int",
  112. ),
  113. # INT FLOAT OR FLOAT INT
  114. rx.text(
  115. VarOperationState.float_var1 + VarOperationState.int_var2,
  116. id="float_add_int",
  117. ),
  118. rx.text(
  119. VarOperationState.float_var1 * VarOperationState.int_var2,
  120. id="float_mult_int",
  121. ),
  122. rx.text(
  123. VarOperationState.float_var1 - VarOperationState.int_var2,
  124. id="float_sub_int",
  125. ),
  126. rx.text(
  127. VarOperationState.float_var1**VarOperationState.int_var2,
  128. id="float_exp_int",
  129. ),
  130. rx.text(
  131. VarOperationState.float_var1 / VarOperationState.int_var2,
  132. id="float_div_int",
  133. ),
  134. rx.text(
  135. VarOperationState.float_var1 // VarOperationState.int_var3,
  136. id="float_floor_int",
  137. ),
  138. rx.text(
  139. VarOperationState.float_var1 % VarOperationState.int_var2,
  140. id="float_mod_int",
  141. ),
  142. rx.text(
  143. (VarOperationState.float_var1 > VarOperationState.int_var2).to_string(),
  144. id="float_gt_int",
  145. ),
  146. rx.text(
  147. (VarOperationState.float_var1 < VarOperationState.int_var2).to_string(),
  148. id="float_lt_int",
  149. ),
  150. rx.text(
  151. (
  152. VarOperationState.float_var1 >= VarOperationState.int_var2
  153. ).to_string(),
  154. id="float_gte_int",
  155. ),
  156. rx.text(
  157. (
  158. VarOperationState.float_var1 <= VarOperationState.int_var2
  159. ).to_string(),
  160. id="float_lte_int",
  161. ),
  162. rx.text(
  163. (
  164. VarOperationState.float_var1 == VarOperationState.int_var2
  165. ).to_string(),
  166. id="float_eq_int",
  167. ),
  168. rx.text(
  169. (
  170. VarOperationState.float_var1 != VarOperationState.int_var2
  171. ).to_string(),
  172. id="float_neq_int",
  173. ),
  174. rx.text(
  175. (VarOperationState.float_var1 & VarOperationState.int_var2).to_string(),
  176. id="float_and_int",
  177. ),
  178. rx.text(
  179. (VarOperationState.float_var1 | VarOperationState.int_var2).to_string(),
  180. id="float_or_int",
  181. ),
  182. # INT, DICT
  183. rx.text(
  184. (VarOperationState.int_var1 | VarOperationState.dict1).to_string(),
  185. id="int_or_dict",
  186. ),
  187. rx.text(
  188. (VarOperationState.int_var1 & VarOperationState.dict1).to_string(),
  189. id="int_and_dict",
  190. ),
  191. rx.text(
  192. (VarOperationState.int_var1 == VarOperationState.dict1).to_string(),
  193. id="int_eq_dict",
  194. ),
  195. rx.text(
  196. (VarOperationState.int_var1 != VarOperationState.dict1).to_string(),
  197. id="int_neq_dict",
  198. ),
  199. # FLOAT FLOAT
  200. rx.text(
  201. VarOperationState.float_var1 + VarOperationState.float_var2,
  202. id="float_add_float",
  203. ),
  204. rx.text(
  205. VarOperationState.float_var1 * VarOperationState.float_var2,
  206. id="float_mult_float",
  207. ),
  208. rx.text(
  209. VarOperationState.float_var1 - VarOperationState.float_var2,
  210. id="float_sub_float",
  211. ),
  212. rx.text(
  213. VarOperationState.float_var1**VarOperationState.float_var2,
  214. id="float_exp_float",
  215. ),
  216. rx.text(
  217. VarOperationState.float_var1 / VarOperationState.float_var2,
  218. id="float_div_float",
  219. ),
  220. rx.text(
  221. VarOperationState.float_var1 // VarOperationState.float_var2,
  222. id="float_floor_float",
  223. ),
  224. rx.text(
  225. VarOperationState.float_var1 % VarOperationState.float_var2,
  226. id="float_mod_float",
  227. ),
  228. rx.text(
  229. (
  230. VarOperationState.float_var1 > VarOperationState.float_var2
  231. ).to_string(),
  232. id="float_gt_float",
  233. ),
  234. rx.text(
  235. (
  236. VarOperationState.float_var1 < VarOperationState.float_var2
  237. ).to_string(),
  238. id="float_lt_float",
  239. ),
  240. rx.text(
  241. (
  242. VarOperationState.float_var1 >= VarOperationState.float_var2
  243. ).to_string(),
  244. id="float_gte_float",
  245. ),
  246. rx.text(
  247. (
  248. VarOperationState.float_var1 <= VarOperationState.float_var2
  249. ).to_string(),
  250. id="float_lte_float",
  251. ),
  252. rx.text(
  253. (
  254. VarOperationState.float_var1 == VarOperationState.float_var2
  255. ).to_string(),
  256. id="float_eq_float",
  257. ),
  258. rx.text(
  259. (
  260. VarOperationState.float_var1 != VarOperationState.float_var2
  261. ).to_string(),
  262. id="float_neq_float",
  263. ),
  264. rx.text(
  265. (
  266. VarOperationState.float_var1 & VarOperationState.float_var2
  267. ).to_string(),
  268. id="float_and_float",
  269. ),
  270. rx.text(
  271. (
  272. VarOperationState.float_var1 | VarOperationState.float_var2
  273. ).to_string(),
  274. id="float_or_float",
  275. ),
  276. # FLOAT STR
  277. rx.text(
  278. VarOperationState.float_var1 | VarOperationState.str_var1,
  279. id="float_or_str",
  280. ),
  281. rx.text(
  282. VarOperationState.float_var1 & VarOperationState.str_var1,
  283. id="float_and_str",
  284. ),
  285. rx.text(
  286. (
  287. VarOperationState.float_var1 == VarOperationState.str_var1
  288. ).to_string(),
  289. id="float_eq_str",
  290. ),
  291. rx.text(
  292. (
  293. VarOperationState.float_var1 != VarOperationState.str_var1
  294. ).to_string(),
  295. id="float_neq_str",
  296. ),
  297. # FLOAT LIST
  298. rx.text(
  299. (VarOperationState.float_var1 | VarOperationState.list1).to_string(),
  300. id="float_or_list",
  301. ),
  302. rx.text(
  303. (VarOperationState.float_var1 & VarOperationState.list1).to_string(),
  304. id="float_and_list",
  305. ),
  306. rx.text(
  307. (VarOperationState.float_var1 == VarOperationState.list1).to_string(),
  308. id="float_eq_list",
  309. ),
  310. rx.text(
  311. (VarOperationState.float_var1 != VarOperationState.list1).to_string(),
  312. id="float_neq_list",
  313. ),
  314. # FLOAT DICT
  315. rx.text(
  316. (VarOperationState.float_var1 | VarOperationState.dict1).to_string(),
  317. id="float_or_dict",
  318. ),
  319. rx.text(
  320. (VarOperationState.float_var1 & VarOperationState.dict1).to_string(),
  321. id="float_and_dict",
  322. ),
  323. rx.text(
  324. (VarOperationState.float_var1 == VarOperationState.dict1).to_string(),
  325. id="float_eq_dict",
  326. ),
  327. rx.text(
  328. (VarOperationState.float_var1 != VarOperationState.dict1).to_string(),
  329. id="float_neq_dict",
  330. ),
  331. # STR STR
  332. rx.text(
  333. VarOperationState.str_var1 + VarOperationState.str_var2,
  334. id="str_add_str",
  335. ),
  336. rx.text(
  337. (VarOperationState.str_var1 > VarOperationState.str_var2).to_string(),
  338. id="str_gt_str",
  339. ),
  340. rx.text(
  341. (VarOperationState.str_var1 < VarOperationState.str_var2).to_string(),
  342. id="str_lt_str",
  343. ),
  344. rx.text(
  345. (VarOperationState.str_var1 >= VarOperationState.str_var2).to_string(),
  346. id="str_gte_str",
  347. ),
  348. rx.text(
  349. (VarOperationState.str_var1 <= VarOperationState.str_var2).to_string(),
  350. id="str_lte_str",
  351. ),
  352. rx.text(
  353. (
  354. VarOperationState.float_var1 == VarOperationState.float_var2
  355. ).to_string(),
  356. id="str_eq_str",
  357. ),
  358. rx.text(
  359. (
  360. VarOperationState.float_var1 != VarOperationState.float_var2
  361. ).to_string(),
  362. id="str_neq_str",
  363. ),
  364. rx.text(
  365. VarOperationState.str_var1.contains("fir").to_string(),
  366. id="str_contains",
  367. ),
  368. rx.text(
  369. VarOperationState.str_var1 | VarOperationState.str_var1, id="str_or_str"
  370. ),
  371. rx.text(
  372. VarOperationState.str_var1 & VarOperationState.str_var2,
  373. id="str_and_str",
  374. ),
  375. # STR, INT
  376. rx.text(
  377. VarOperationState.str_var1 * VarOperationState.int_var2,
  378. id="str_mult_int",
  379. ),
  380. rx.text(
  381. VarOperationState.str_var1 & VarOperationState.int_var2,
  382. id="str_and_int",
  383. ),
  384. rx.text(
  385. VarOperationState.str_var1 | VarOperationState.int_var2, id="str_or_int"
  386. ),
  387. rx.text(
  388. (VarOperationState.str_var1 == VarOperationState.int_var1).to_string(),
  389. id="str_eq_int",
  390. ),
  391. rx.text(
  392. (VarOperationState.str_var1 != VarOperationState.int_var1).to_string(),
  393. id="str_neq_int",
  394. ),
  395. # STR, LIST
  396. rx.text(
  397. VarOperationState.str_var1 | VarOperationState.list1, id="str_or_list"
  398. ),
  399. rx.text(
  400. (VarOperationState.str_var1 & VarOperationState.list1).to_string(),
  401. id="str_and_list",
  402. ),
  403. rx.text(
  404. (VarOperationState.str_var1 == VarOperationState.list1).to_string(),
  405. id="str_eq_list",
  406. ),
  407. rx.text(
  408. (VarOperationState.str_var1 != VarOperationState.list1).to_string(),
  409. id="str_neq_list",
  410. ),
  411. # STR, DICT
  412. rx.text(
  413. VarOperationState.str_var1 | VarOperationState.dict1, id="str_or_dict"
  414. ),
  415. rx.text(
  416. (VarOperationState.str_var1 & VarOperationState.dict1).to_string(),
  417. id="str_and_dict",
  418. ),
  419. rx.text(
  420. (VarOperationState.str_var1 == VarOperationState.dict1).to_string(),
  421. id="str_eq_dict",
  422. ),
  423. rx.text(
  424. (VarOperationState.str_var1 != VarOperationState.dict1).to_string(),
  425. id="str_neq_dict",
  426. ),
  427. # LIST, LIST
  428. rx.text(
  429. (VarOperationState.list1 + VarOperationState.list2).to_string(),
  430. id="list_add_list",
  431. ),
  432. rx.text(
  433. (VarOperationState.list1 & VarOperationState.list2).to_string(),
  434. id="list_and_list",
  435. ),
  436. rx.text(
  437. (VarOperationState.list1 | VarOperationState.list2).to_string(),
  438. id="list_or_list",
  439. ),
  440. rx.text(
  441. (VarOperationState.list1 > VarOperationState.list2).to_string(),
  442. id="list_gt_list",
  443. ),
  444. rx.text(
  445. (VarOperationState.list1 < VarOperationState.list2).to_string(),
  446. id="list_lt_list",
  447. ),
  448. rx.text(
  449. (VarOperationState.list1 >= VarOperationState.list2).to_string(),
  450. id="list_gte_list",
  451. ),
  452. rx.text(
  453. (VarOperationState.list1 <= VarOperationState.list2).to_string(),
  454. id="list_lte_list",
  455. ),
  456. rx.text(
  457. (VarOperationState.list1 == VarOperationState.list2).to_string(),
  458. id="list_eq_list",
  459. ),
  460. rx.text(
  461. (VarOperationState.list1 != VarOperationState.list2).to_string(),
  462. id="list_neq_list",
  463. ),
  464. rx.text(
  465. VarOperationState.list1.contains(1).to_string(), id="list_contains"
  466. ),
  467. rx.text(VarOperationState.list4.pluck("name").to_string(), id="list_pluck"),
  468. rx.text(VarOperationState.list1.reverse().to_string(), id="list_reverse"),
  469. # LIST, INT
  470. rx.text(
  471. (VarOperationState.list1 * VarOperationState.int_var2).to_string(),
  472. id="list_mult_int",
  473. ),
  474. rx.text(
  475. (VarOperationState.list1 | VarOperationState.int_var1).to_string(),
  476. id="list_or_int",
  477. ),
  478. rx.text(
  479. (VarOperationState.list1 & VarOperationState.int_var1).to_string(),
  480. id="list_and_int",
  481. ),
  482. rx.text(
  483. (VarOperationState.list1 == VarOperationState.int_var1).to_string(),
  484. id="list_eq_int",
  485. ),
  486. rx.text(
  487. (VarOperationState.list1 != VarOperationState.int_var1).to_string(),
  488. id="list_neq_int",
  489. ),
  490. # LIST, DICT
  491. rx.text(
  492. (VarOperationState.list1 | VarOperationState.dict1).to_string(),
  493. id="list_or_dict",
  494. ),
  495. rx.text(
  496. (VarOperationState.list1 & VarOperationState.dict1).to_string(),
  497. id="list_and_dict",
  498. ),
  499. rx.text(
  500. (VarOperationState.list1 == VarOperationState.dict1).to_string(),
  501. id="list_eq_dict",
  502. ),
  503. rx.text(
  504. (VarOperationState.list1 != VarOperationState.dict1).to_string(),
  505. id="list_neq_dict",
  506. ),
  507. # DICT, DICT
  508. rx.text(
  509. (VarOperationState.dict1 | VarOperationState.dict2).to_string(),
  510. id="dict_or_dict",
  511. ),
  512. rx.text(
  513. (VarOperationState.dict1 & VarOperationState.dict2).to_string(),
  514. id="dict_and_dict",
  515. ),
  516. rx.text(
  517. (VarOperationState.dict1 == VarOperationState.dict2).to_string(),
  518. id="dict_eq_dict",
  519. ),
  520. rx.text(
  521. (VarOperationState.dict1 != VarOperationState.dict2).to_string(),
  522. id="dict_neq_dict",
  523. ),
  524. rx.text(
  525. VarOperationState.dict1.contains(1).to_string(), id="dict_contains"
  526. ),
  527. rx.text(VarOperationState.str_var3.lower(), id="str_lower"),
  528. rx.text(VarOperationState.str_var3.upper(), id="str_upper"),
  529. rx.text(VarOperationState.str_var4.split(" ").to_string(), id="str_split"),
  530. rx.text(VarOperationState.list3.join(""), id="list_join"),
  531. rx.text(VarOperationState.list3.join(","), id="list_join_comma"),
  532. # Index from an op var
  533. rx.text(
  534. VarOperationState.list3[VarOperationState.int_var1 % 3],
  535. id="list_index_mod",
  536. ),
  537. rx.html(
  538. VarOperationState.html_str,
  539. id="html_str",
  540. ),
  541. rc.highlight(
  542. "second",
  543. query=[VarOperationState.str_var2],
  544. ),
  545. rx.text(ArrayVar.range(2, 5).join(","), id="list_join_range1"),
  546. rx.text(ArrayVar.range(2, 10, 2).join(","), id="list_join_range2"),
  547. rx.text(ArrayVar.range(5, 0, -1).join(","), id="list_join_range3"),
  548. rx.text(ArrayVar.range(0, 3).join(","), id="list_join_range4"),
  549. rx.box(
  550. rx.foreach(
  551. ArrayVar.range(0, 2),
  552. lambda x: rx.text(VarOperationState.list1[x], as_="p"),
  553. ),
  554. id="foreach_list_arg",
  555. ),
  556. rx.box(
  557. rx.foreach(
  558. ArrayVar.range(0, 2),
  559. lambda x, ix: rx.text(VarOperationState.list1[ix], as_="p"),
  560. ),
  561. id="foreach_list_ix",
  562. ),
  563. rx.box(
  564. rx.foreach(
  565. LiteralVar.create(list(range(0, 3))).to(ArrayVar, List[int]),
  566. lambda x: rx.foreach(
  567. ArrayVar.range(x),
  568. lambda y: rx.text(VarOperationState.list1[y], as_="p"),
  569. ),
  570. ),
  571. id="foreach_list_nested",
  572. ),
  573. memo_comp(
  574. list1=VarOperationState.list1,
  575. int_var1=VarOperationState.int_var1,
  576. id="memo_comp",
  577. ),
  578. memo_comp_nested(
  579. int_var2=VarOperationState.int_var2,
  580. id="memo_comp_nested",
  581. ),
  582. )
  583. @pytest.fixture(scope="module")
  584. def var_operations(tmp_path_factory) -> Generator[AppHarness, None, None]:
  585. """Start VarOperations app at tmp_path via AppHarness.
  586. Args:
  587. tmp_path_factory: pytest tmp_path_factory fixture
  588. Yields:
  589. running AppHarness instance
  590. """
  591. with AppHarness.create(
  592. root=tmp_path_factory.mktemp("var_operations"),
  593. app_source=VarOperations, # type: ignore
  594. ) as harness:
  595. assert harness.app_instance is not None, "app is not running"
  596. yield harness
  597. @pytest.fixture
  598. def driver(var_operations: AppHarness):
  599. """Get an instance of the browser open to the var operations app.
  600. Args:
  601. var_operations: harness for VarOperations app
  602. Yields:
  603. WebDriver instance.
  604. """
  605. driver = var_operations.frontend()
  606. try:
  607. token_input = driver.find_element(By.ID, "token")
  608. assert token_input
  609. # wait for the backend connection to send the token
  610. token = var_operations.poll_for_value(token_input)
  611. assert token is not None
  612. yield driver
  613. finally:
  614. driver.quit()
  615. def test_var_operations(driver, var_operations: AppHarness):
  616. """Test that the var operations produce the right results.
  617. Args:
  618. driver: selenium WebDriver open to the app
  619. var_operations: AppHarness for the var operations app
  620. """
  621. tests = [
  622. # int, int
  623. ("int_add_int", "15"),
  624. ("int_mult_int", "50"),
  625. ("int_sub_int", "5"),
  626. ("int_exp_int", "100000"),
  627. ("int_div_int", "2"),
  628. ("int_floor_int", "1"),
  629. ("int_mod_int", "0"),
  630. ("int_gt_int", "true"),
  631. ("int_lt_int", "false"),
  632. ("int_gte_int", "true"),
  633. ("int_lte_int", "false"),
  634. ("int_and_int", "5"),
  635. ("int_or_int", "10"),
  636. ("int_eq_int", "false"),
  637. ("int_neq_int", "true"),
  638. # int, float
  639. ("float_add_int", "15.5"),
  640. ("float_mult_int", "52.5"),
  641. ("float_sub_int", "5.5"),
  642. ("float_exp_int", "127628.15625"),
  643. ("float_div_int", "2.1"),
  644. ("float_floor_int", "1"),
  645. ("float_mod_int", "0.5"),
  646. ("float_gt_int", "true"),
  647. ("float_lt_int", "false"),
  648. ("float_gte_int", "true"),
  649. ("float_lte_int", "false"),
  650. ("float_eq_int", "false"),
  651. ("float_neq_int", "true"),
  652. ("float_and_int", "5"),
  653. ("float_or_int", "10.5"),
  654. # int, dict
  655. ("int_or_dict", "10"),
  656. ("int_and_dict", '{"1":2}'),
  657. ("int_eq_dict", "false"),
  658. ("int_neq_dict", "true"),
  659. # float, float
  660. ("float_add_float", "16"),
  661. ("float_mult_float", "57.75"),
  662. ("float_sub_float", "5"),
  663. ("float_exp_float", "413562.49323606625"),
  664. ("float_div_float", "1.9090909090909092"),
  665. ("float_floor_float", "1"),
  666. ("float_mod_float", "5"),
  667. ("float_gt_float", "true"),
  668. ("float_lt_float", "false"),
  669. ("float_gte_float", "true"),
  670. ("float_lte_float", "false"),
  671. ("float_eq_float", "false"),
  672. ("float_neq_float", "true"),
  673. ("float_and_float", "5.5"),
  674. ("float_or_float", "10.5"),
  675. # float, str
  676. ("float_or_str", "10.5"),
  677. ("float_and_str", "first"),
  678. ("float_eq_str", "false"),
  679. ("float_neq_str", "true"),
  680. # float, list
  681. ("float_or_list", "10.5"),
  682. ("float_and_list", "[1,2]"),
  683. ("float_eq_list", "false"),
  684. ("float_neq_list", "true"),
  685. # float, dict
  686. ("float_or_dict", "10.5"),
  687. ("float_and_dict", '{"1":2}'),
  688. ("float_eq_dict", "false"),
  689. ("float_neq_dict", "true"),
  690. # str, str
  691. ("str_add_str", "firstsecond"),
  692. ("str_gt_str", "false"),
  693. ("str_lt_str", "true"),
  694. ("str_gte_str", "false"),
  695. ("str_lte_str", "true"),
  696. ("str_eq_str", "false"),
  697. ("str_neq_str", "true"),
  698. ("str_and_str", "second"),
  699. ("str_or_str", "first"),
  700. ("str_contains", "true"),
  701. ("str_lower", "third"),
  702. ("str_upper", "THIRD"),
  703. ("str_split", '["a","long","string"]'),
  704. # str, int
  705. ("str_mult_int", "firstfirstfirstfirstfirst"),
  706. ("str_and_int", "5"),
  707. ("str_or_int", "first"),
  708. ("str_eq_int", "false"),
  709. ("str_neq_int", "true"),
  710. # str, list
  711. ("str_and_list", "[1,2]"),
  712. ("str_or_list", "first"),
  713. ("str_eq_list", "false"),
  714. ("str_neq_list", "true"),
  715. # str, dict
  716. ("str_or_dict", "first"),
  717. ("str_and_dict", '{"1":2}'),
  718. ("str_eq_dict", "false"),
  719. ("str_neq_dict", "true"),
  720. # list, list
  721. ("list_add_list", "[1,2,3,4]"),
  722. ("list_gt_list", "false"),
  723. ("list_lt_list", "true"),
  724. ("list_gte_list", "false"),
  725. ("list_lte_list", "true"),
  726. ("list_eq_list", "false"),
  727. ("list_neq_list", "true"),
  728. ("list_and_list", "[3,4]"),
  729. ("list_or_list", "[1,2]"),
  730. ("list_contains", "true"),
  731. ("list_pluck", '["obj_1","obj_2"]'),
  732. ("list_reverse", "[2,1]"),
  733. ("list_join", "firstsecondthird"),
  734. ("list_join_comma", "first,second,third"),
  735. ("list_join_range1", "2,3,4"),
  736. ("list_join_range2", "2,4,6,8"),
  737. ("list_join_range3", "5,4,3,2,1"),
  738. ("list_join_range4", "0,1,2"),
  739. # list, int
  740. ("list_mult_int", "[1,2,1,2,1,2,1,2,1,2]"),
  741. ("list_or_int", "[1,2]"),
  742. ("list_and_int", "10"),
  743. ("list_eq_int", "false"),
  744. ("list_neq_int", "true"),
  745. # list, dict
  746. ("list_and_dict", '{"1":2}'),
  747. ("list_or_dict", "[1,2]"),
  748. ("list_eq_dict", "false"),
  749. ("list_neq_dict", "true"),
  750. # dict, dict
  751. ("dict_or_dict", '{"1":2}'),
  752. ("dict_and_dict", '{"3":4}'),
  753. ("dict_eq_dict", "false"),
  754. ("dict_neq_dict", "true"),
  755. ("dict_contains", "true"),
  756. # index from an op var
  757. ("list_index_mod", "second"),
  758. # html component with var
  759. ("html_str", "hello"),
  760. # index into list with foreach
  761. ("foreach_list_arg", "1\n2"),
  762. ("foreach_list_ix", "1\n2"),
  763. ("foreach_list_nested", "1\n1\n2"),
  764. # rx.memo component with state
  765. ("memo_comp", "1210"),
  766. ("memo_comp_nested", "345"),
  767. ]
  768. for tag, expected in tests:
  769. print(tag)
  770. assert driver.find_element(By.ID, tag).text == expected
  771. # Highlight component with var query (does not plumb ID)
  772. assert driver.find_element(By.TAG_NAME, "mark").text == "second"