Skip to main content

stylex_transform/shared/transformers/tests/
stylex_define_consts_test.rs

1#[cfg(test)]
2mod stylex_define_consts {
3  use swc_core::ecma::ast::PropOrSpread;
4
5  use crate::shared::enums::data_structures::evaluate_result_value::EvaluateResultValue;
6  use crate::shared::structures::state_manager::StateManager;
7  use crate::shared::transformers::stylex_define_consts::stylex_define_consts;
8  use crate::shared::utils::ast::convertors::create_string_expr;
9  use crate::shared::utils::common::create_hash;
10  use stylex_ast::ast::factories::{create_key_value_prop, create_object_expression};
11  use stylex_structures::stylex_options::StyleXOptions;
12  use stylex_types::enums::data_structures::injectable_style::InjectableStyleKind;
13
14  fn create_test_state_manager(export_id: &str) -> StateManager {
15    let mut state = StateManager::new(StyleXOptions {
16      class_name_prefix: "x".to_string(),
17      debug: false,
18      enable_debug_class_names: false,
19      ..Default::default()
20    });
21    state.export_id = Some(export_id.to_string());
22    state
23  }
24
25  fn constants_factory(constants: &[(&str, &str)]) -> EvaluateResultValue {
26    let props = constants
27      .iter()
28      .map(|(key, value)| create_key_value_prop(key, create_string_expr(value)))
29      .collect::<Vec<PropOrSpread>>();
30
31    EvaluateResultValue::Expr(create_object_expression(props))
32  }
33
34  fn get_const_hash(export_id: &str, key: &str, class_name_prefix: &str) -> String {
35    format!(
36      "{}{}",
37      class_name_prefix,
38      create_hash(&format!("{}.{}", export_id, key))
39    )
40  }
41
42  #[test]
43  fn returns_correct_structure_for_basic_constants() {
44    let export_id = "TestTheme.stylex.js//buttonTheme";
45    let mut state = create_test_state_manager(export_id);
46
47    let constants =
48      constants_factory(&[("sm", "(min-width: 768px)"), ("md", "(min-width: 1024px)")]);
49
50    let (js_output, injectable_styles) = stylex_define_consts(&constants, &mut state);
51
52    assert_eq!(js_output.len(), 2);
53    assert_eq!(
54      js_output.get("sm").unwrap().as_string().unwrap(),
55      "(min-width: 768px)"
56    );
57    assert_eq!(
58      js_output.get("md").unwrap().as_string().unwrap(),
59      "(min-width: 1024px)"
60    );
61
62    let sm_hash = get_const_hash(export_id, "sm", "x");
63    let md_hash = get_const_hash(export_id, "md", "x");
64
65    assert!(injectable_styles.contains_key(&sm_hash));
66    assert!(injectable_styles.contains_key(&md_hash));
67
68    match injectable_styles.get(&sm_hash).unwrap().as_ref() {
69      InjectableStyleKind::Const(style) => {
70        assert_eq!(style.const_value, "(min-width: 768px)");
71        assert_eq!(style.ltr, "");
72        assert_eq!(style.rtl, None);
73        assert_eq!(style.priority, Some(0.0));
74      },
75      _ => panic!("Expected InjectableStyleKind::Const"),
76    }
77
78    match injectable_styles.get(&md_hash).unwrap().as_ref() {
79      InjectableStyleKind::Const(style) => {
80        assert_eq!(style.const_value, "(min-width: 1024px)");
81        assert_eq!(style.ltr, "");
82        assert_eq!(style.rtl, None);
83        assert_eq!(style.priority, Some(0.0));
84      },
85      _ => panic!("Expected InjectableStyleKind::Const"),
86    }
87
88    assert_ne!(sm_hash, md_hash);
89  }
90
91  #[test]
92  fn handles_special_characters_in_keys() {
93    let export_id = "TestTheme.stylex.js//buttonTheme";
94    let mut state = create_test_state_manager(export_id);
95
96    let constants = constants_factory(&[("max-width", "1200px"), ("font-size*large", "18px")]);
97
98    let (js_output, injectable_styles) = stylex_define_consts(&constants, &mut state);
99
100    assert_eq!(js_output.len(), 2);
101    assert_eq!(
102      js_output.get("max-width").unwrap().as_string().unwrap(),
103      "1200px"
104    );
105    assert_eq!(
106      js_output
107        .get("font-size*large")
108        .unwrap()
109        .as_string()
110        .unwrap(),
111      "18px"
112    );
113
114    let max_width_hash = get_const_hash(export_id, "max-width", "x");
115    let font_size_hash = get_const_hash(export_id, "font-size*large", "x");
116
117    assert!(injectable_styles.contains_key(&max_width_hash));
118    assert!(injectable_styles.contains_key(&font_size_hash));
119
120    assert_ne!(max_width_hash, font_size_hash);
121  }
122
123  #[test]
124  fn handles_numeric_keys() {
125    let export_id = "TestTheme.stylex.js//buttonTheme";
126    let mut state = create_test_state_manager(export_id);
127
128    let constants = constants_factory(&[("1", "one"), ("2", "two")]);
129
130    let (js_output, injectable_styles) = stylex_define_consts(&constants, &mut state);
131
132    assert_eq!(js_output.len(), 2);
133    assert_eq!(js_output.get("1").unwrap().as_string().unwrap(), "one");
134    assert_eq!(js_output.get("2").unwrap().as_string().unwrap(), "two");
135
136    let hash_1 = get_const_hash(export_id, "1", "x");
137    let hash_2 = get_const_hash(export_id, "2", "x");
138
139    assert!(injectable_styles.contains_key(&hash_1));
140    assert!(injectable_styles.contains_key(&hash_2));
141
142    assert_ne!(hash_1, hash_2);
143  }
144
145  #[test]
146  fn generates_consistent_hashes_for_identical_constants() {
147    let export_id = "TestTheme.stylex.js//buttonTheme";
148    let mut state1 = create_test_state_manager(export_id);
149    let mut state2 = create_test_state_manager(export_id);
150
151    let constants = constants_factory(&[("padding", "10px")]);
152
153    let (js_output1, styles1) = stylex_define_consts(&constants, &mut state1);
154    let (js_output2, styles2) = stylex_define_consts(&constants, &mut state2);
155
156    let key_hash = get_const_hash(export_id, "padding", "x");
157
158    assert_eq!(js_output1, js_output2);
159
160    assert!(styles1.contains_key(&key_hash));
161    assert!(styles2.contains_key(&key_hash));
162
163    match (
164      styles1.get(&key_hash).unwrap().as_ref(),
165      styles2.get(&key_hash).unwrap().as_ref(),
166    ) {
167      (InjectableStyleKind::Const(style1), InjectableStyleKind::Const(style2)) => {
168        assert_eq!(style1.const_key, style2.const_key);
169      },
170      _ => panic!("Expected InjectableStyleKind::Const"),
171    }
172  }
173
174  #[test]
175  fn generates_different_hashes_for_different_constants() {
176    let export_id = "TestTheme.stylex.js//buttonTheme";
177    let mut state1 = create_test_state_manager(export_id);
178    let mut state2 = create_test_state_manager(export_id);
179
180    let constants1 = constants_factory(&[("padding", "10px")]);
181    let constants2 = constants_factory(&[("margin", "10px")]);
182
183    let (_, styles1) = stylex_define_consts(&constants1, &mut state1);
184    let (_, styles2) = stylex_define_consts(&constants2, &mut state2);
185
186    let padding_key = get_const_hash(export_id, "padding", "x");
187    let margin_key = get_const_hash(export_id, "margin", "x");
188
189    assert_ne!(padding_key, margin_key);
190
191    assert!(styles1.contains_key(&padding_key));
192    assert!(styles2.contains_key(&margin_key));
193
194    match (
195      styles1.get(&padding_key).unwrap().as_ref(),
196      styles2.get(&margin_key).unwrap().as_ref(),
197    ) {
198      (InjectableStyleKind::Const(style1), InjectableStyleKind::Const(style2)) => {
199        assert_ne!(style1.const_key, style2.const_key);
200      },
201      _ => panic!("Expected InjectableStyleKind::Const"),
202    }
203  }
204
205  #[test]
206  fn preserves_object_keys() {
207    let export_id = "TestTheme.stylex.js//buttonTheme";
208    let mut state = create_test_state_manager(export_id);
209
210    let constants = constants_factory(&[("borderRadius", "8px"), ("colorPrimary", "#ff0000")]);
211
212    let (js_output, _) = stylex_define_consts(&constants, &mut state);
213
214    let keys: Vec<&String> = js_output.keys().collect();
215    assert_eq!(keys.len(), 2);
216    assert!(keys.contains(&&"borderRadius".to_string()));
217    assert!(keys.contains(&&"colorPrimary".to_string()));
218  }
219
220  #[test]
221  fn throws_an_error_for_keys_that_start_with_double_dash() {
222    let export_id = "TestTheme.stylex.js//buttonTheme";
223    let mut state = create_test_state_manager(export_id);
224
225    let constants = constants_factory(&[("--custom-var", "red")]);
226
227    let (js_output, _) = stylex_define_consts(&constants, &mut state);
228
229    assert_eq!(js_output.len(), 1);
230    assert_eq!(
231      js_output.get("--custom-var").unwrap().as_string().unwrap(),
232      "red"
233    );
234  }
235}