123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- from __future__ import annotations
- from typing import Any
- import pytest
- import reflex as rx
- from reflex import style
- from reflex.vars import Var
- test_style = [
- ({"a": 1}, {"a": 1}),
- ({"a": Var.create("abc")}, {"a": "abc"}),
- ({"test_case": 1}, {"testCase": 1}),
- ({"test_case": {"a": 1}}, {"testCase": {"a": 1}}),
- ({":test_case": {"a": 1}}, {":testCase": {"a": 1}}),
- ({"::test_case": {"a": 1}}, {"::testCase": {"a": 1}}),
- (
- {"::-webkit-scrollbar": {"display": "none"}},
- {"::-webkit-scrollbar": {"display": "none"}},
- ),
- ]
- @pytest.mark.parametrize(
- "style_dict,expected",
- test_style,
- )
- def test_convert(style_dict, expected):
- """Test Format a style dictionary.
- Args:
- style_dict: The style to check.
- expected: The expected formatted style.
- """
- converted_dict, _var_data = style.convert(style_dict)
- assert converted_dict == expected
- @pytest.mark.parametrize(
- "style_dict,expected",
- test_style,
- )
- def test_create_style(style_dict, expected):
- """Test style dictionary.
- Args:
- style_dict: The style to check.
- expected: The expected formatted style.
- """
- assert style.Style(style_dict) == expected
- def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
- """Compare two dictionaries of Var objects.
- Args:
- d1: The first dictionary.
- d2: The second dictionary.
- """
- assert len(d1) == len(d2)
- for key, value in d1.items():
- assert key in d2
- if isinstance(value, dict):
- compare_dict_of_var(value, d2[key])
- elif isinstance(value, Var):
- assert value.equals(d2[key])
- else:
- assert value == d2[key]
- @pytest.mark.parametrize(
- ("kwargs", "style_dict", "expected_get_style"),
- [
- ({}, {}, {"css": None}),
- ({"color": "hotpink"}, {}, {"css": Var.create({"color": "hotpink"})}),
- ({}, {"color": "red"}, {"css": Var.create({"color": "red"})}),
- (
- {"color": "hotpink"},
- {"color": "red"},
- {"css": Var.create({"color": "hotpink"})},
- ),
- (
- {"_hover": {"color": "hotpink"}},
- {},
- {"css": Var.create({"&:hover": {"color": "hotpink"}})},
- ),
- (
- {},
- {"_hover": {"color": "red"}},
- {"css": Var.create({"&:hover": {"color": "red"}})},
- ),
- (
- {},
- {":hover": {"color": "red"}},
- {"css": Var.create({"&:hover": {"color": "red"}})},
- ),
- (
- {},
- {"::-webkit-scrollbar": {"display": "none"}},
- {"css": Var.create({"&::-webkit-scrollbar": {"display": "none"}})},
- ),
- (
- {},
- {"::-moz-progress-bar": {"background_color": "red"}},
- {"css": Var.create({"&::-moz-progress-bar": {"backgroundColor": "red"}})},
- ),
- (
- {"color": ["#111", "#222", "#333", "#444", "#555"]},
- {},
- {
- "css": Var.create(
- {
- "@media screen and (min-width: 0)": {"color": "#111"},
- "@media screen and (min-width: 30em)": {"color": "#222"},
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- }
- )
- },
- ),
- (
- {
- "color": ["#111", "#222", "#333", "#444", "#555"],
- "background_color": "#FFF",
- },
- {},
- {
- "css": Var.create(
- {
- "@media screen and (min-width: 0)": {"color": "#111"},
- "@media screen and (min-width: 30em)": {"color": "#222"},
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- "backgroundColor": "#FFF",
- }
- )
- },
- ),
- (
- {
- "color": ["#111", "#222", "#333", "#444", "#555"],
- "background_color": ["#FFF", "#EEE", "#DDD", "#CCC", "#BBB"],
- },
- {},
- {
- "css": Var.create(
- {
- "@media screen and (min-width: 0)": {
- "color": "#111",
- "backgroundColor": "#FFF",
- },
- "@media screen and (min-width: 30em)": {
- "color": "#222",
- "backgroundColor": "#EEE",
- },
- "@media screen and (min-width: 48em)": {
- "color": "#333",
- "backgroundColor": "#DDD",
- },
- "@media screen and (min-width: 62em)": {
- "color": "#444",
- "backgroundColor": "#CCC",
- },
- "@media screen and (min-width: 80em)": {
- "color": "#555",
- "backgroundColor": "#BBB",
- },
- }
- )
- },
- ),
- (
- {
- "_hover": [
- {"color": "#111"},
- {"color": "#222"},
- {"color": "#333"},
- {"color": "#444"},
- {"color": "#555"},
- ]
- },
- {},
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {"color": "#111"},
- "@media screen and (min-width: 30em)": {"color": "#222"},
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- }
- }
- )
- },
- ),
- (
- {"_hover": {"color": ["#111", "#222", "#333", "#444", "#555"]}},
- {},
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {"color": "#111"},
- "@media screen and (min-width: 30em)": {"color": "#222"},
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- }
- }
- )
- },
- ),
- (
- {
- "_hover": {
- "color": ["#111", "#222", "#333", "#444", "#555"],
- "background_color": ["#FFF", "#EEE", "#DDD", "#CCC", "#BBB"],
- }
- },
- {},
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {
- "color": "#111",
- "backgroundColor": "#FFF",
- },
- "@media screen and (min-width: 30em)": {
- "color": "#222",
- "backgroundColor": "#EEE",
- },
- "@media screen and (min-width: 48em)": {
- "color": "#333",
- "backgroundColor": "#DDD",
- },
- "@media screen and (min-width: 62em)": {
- "color": "#444",
- "backgroundColor": "#CCC",
- },
- "@media screen and (min-width: 80em)": {
- "color": "#555",
- "backgroundColor": "#BBB",
- },
- }
- }
- )
- },
- ),
- (
- {
- "_hover": {
- "color": ["#111", "#222", "#333", "#444", "#555"],
- "background_color": "#FFF",
- }
- },
- {},
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {"color": "#111"},
- "@media screen and (min-width: 30em)": {"color": "#222"},
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- "backgroundColor": "#FFF",
- }
- }
- )
- },
- ),
- ],
- )
- def test_style_via_component(
- kwargs: dict[str, Any],
- style_dict: dict[str, Any],
- expected_get_style: dict[str, Any],
- ):
- """Pass kwargs and style_dict to a component and assert the final, combined style dict.
- Args:
- kwargs: The kwargs to pass to the component.
- style_dict: The style_dict to pass to the component.
- expected_get_style: The expected style dict.
- """
- comp = rx.el.div(style=style_dict, **kwargs) # type: ignore
- compare_dict_of_var(comp._get_style(), expected_get_style)
- class StyleState(rx.State):
- """Style vars in a substate."""
- color: str = "hotpink"
- color2: str = "red"
- @pytest.mark.parametrize(
- ("kwargs", "expected_get_style"),
- [
- (
- {"color": StyleState.color},
- {"css": Var.create({"color": StyleState.color})},
- ),
- (
- {"color": f"dark{StyleState.color}"},
- {"css": Var.create_safe(f'{{"color": `dark{StyleState.color}`}}').to(dict)},
- ),
- (
- {"color": StyleState.color, "_hover": {"color": StyleState.color2}},
- {
- "css": Var.create(
- {
- "color": StyleState.color,
- "&:hover": {"color": StyleState.color2},
- }
- )
- },
- ),
- (
- {"color": [StyleState.color, "gray", StyleState.color2, "yellow", "blue"]},
- {
- "css": Var.create(
- {
- "@media screen and (min-width: 0)": {"color": StyleState.color},
- "@media screen and (min-width: 30em)": {"color": "gray"},
- "@media screen and (min-width: 48em)": {
- "color": StyleState.color2
- },
- "@media screen and (min-width: 62em)": {"color": "yellow"},
- "@media screen and (min-width: 80em)": {"color": "blue"},
- }
- )
- },
- ),
- (
- {
- "_hover": [
- {"color": StyleState.color},
- {"color": StyleState.color2},
- {"color": "#333"},
- {"color": "#444"},
- {"color": "#555"},
- ]
- },
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {
- "color": StyleState.color
- },
- "@media screen and (min-width: 30em)": {
- "color": StyleState.color2
- },
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- }
- }
- )
- },
- ),
- (
- {
- "_hover": {
- "color": [
- StyleState.color,
- StyleState.color2,
- "#333",
- "#444",
- "#555",
- ]
- }
- },
- {
- "css": Var.create(
- {
- "&:hover": {
- "@media screen and (min-width: 0)": {
- "color": StyleState.color
- },
- "@media screen and (min-width: 30em)": {
- "color": StyleState.color2
- },
- "@media screen and (min-width: 48em)": {"color": "#333"},
- "@media screen and (min-width: 62em)": {"color": "#444"},
- "@media screen and (min-width: 80em)": {"color": "#555"},
- }
- }
- )
- },
- ),
- ],
- )
- def test_style_via_component_with_state(
- kwargs: dict[str, Any],
- expected_get_style: dict[str, Any],
- ):
- """Pass kwargs to a component with state vars and assert the final, combined style dict.
- Args:
- kwargs: The kwargs to pass to the component.
- expected_get_style: The expected style dict.
- """
- comp = rx.el.div(**kwargs)
- assert comp.style._var_data == expected_get_style["css"]._var_data
- # Remove the _var_data from the expected style, since the emotion-formatted
- # style dict won't actually have it.
- expected_get_style["css"]._var_data = None
- # Assert that style values are equal.
- compare_dict_of_var(comp._get_style(), expected_get_style)
|