Skip to main content

stylex_transform/shared/structures/tests/
flatten_raw_style_objects_test.rs

1#[cfg(test)]
2mod flatten_style_object_with_legacy_shorthand_expansion {
3  use indexmap::IndexMap;
4  use swc_core::ecma::ast::Expr;
5
6  use crate::shared::structures::functions::FunctionMap;
7  use crate::shared::structures::null_pre_rule::NullPreRule;
8  use crate::shared::structures::pre_rule::{PreRuleValue, PreRules, StylesPreRule};
9  use crate::shared::structures::pre_rule_set::PreRuleSet;
10  use crate::shared::structures::state::EvaluationState;
11  use crate::shared::structures::state_manager::StateManager;
12  use crate::shared::utils::ast::convertors::create_string_expr;
13  use crate::shared::utils::core::flatten_raw_style_object::flatten_raw_style_object;
14  use stylex_ast::ast::factories::{create_array, create_key_value_prop_ident};
15  use stylex_enums::style_resolution::StyleResolution;
16
17  pub(super) fn get_state() -> StateManager {
18    let mut state_manager = StateManager::default();
19
20    state_manager.options.class_name_prefix = "x".to_string();
21    state_manager.options.style_resolution = StyleResolution::LegacyExpandShorthands;
22    state_manager.options.runtime_injection = None;
23    state_manager.options.dev = false;
24    state_manager.options.test = false;
25    state_manager.options.debug = false;
26
27    state_manager
28  }
29
30  pub(super) fn pre_rule_factory(key: &str, value: &str, path_key: &[&str]) -> PreRules {
31    PreRules::StylesPreRule(StylesPreRule::new(
32      key,
33      PreRuleValue::String(value.to_string()),
34      Some(path_key.iter().map(|s| s.to_string()).collect()),
35    ))
36  }
37
38  pub(super) fn pre_rule_set_factory(values: &[PreRules]) -> PreRules {
39    PreRuleSet::create(values.to_vec())
40  }
41
42  pub(super) fn null_rule_factory() -> PreRules {
43    PreRules::NullPreRule(NullPreRule::default())
44  }
45
46  pub(super) fn pre_rule_vec_factory(key: &str, value: &[&str], path_key: &[&str]) -> PreRules {
47    PreRules::StylesPreRule(StylesPreRule::new(
48      key,
49      PreRuleValue::Vec(value.iter().map(|x| x.to_string()).collect()),
50      Some(path_key.iter().map(|s| s.to_string()).collect()),
51    ))
52  }
53
54  #[test]
55  fn should_create_pre_rule_objects_for_simple_style_values() {
56    let result = flatten_raw_style_object(
57      &[
58        create_key_value_prop_ident("color", create_string_expr("red")),
59        create_key_value_prop_ident("marginStart", create_string_expr("10")),
60      ],
61      &mut EvaluationState::new(),
62      &mut get_state(),
63      &FunctionMap::default(),
64    );
65
66    assert_eq!(result.len(), 4);
67
68    let mut expected_result = IndexMap::new();
69
70    expected_result.insert(
71      "color".to_string(),
72      pre_rule_factory("color", "red", &["color"]),
73    );
74    expected_result.insert(
75      "marginInlineStart".to_string(),
76      pre_rule_factory("marginInlineStart", "10", &["marginInlineStart"]),
77    );
78    expected_result.insert("marginLeft".to_string(), null_rule_factory());
79    expected_result.insert("marginRight".to_string(), null_rule_factory());
80
81    assert_eq!(result, expected_result)
82  }
83
84  #[test]
85  fn should_expand_simple_gap_values() {
86    let result = flatten_raw_style_object(
87      &[create_key_value_prop_ident("gap", create_string_expr("10"))],
88      &mut EvaluationState::new(),
89      &mut get_state(),
90      &FunctionMap::default(),
91    );
92
93    assert_eq!(result.len(), 2);
94
95    let mut expected_result = IndexMap::new();
96
97    expected_result.insert(
98      "rowGap".to_string(),
99      pre_rule_factory("rowGap", "10", &["rowGap"]),
100    );
101    expected_result.insert(
102      "columnGap".to_string(),
103      pre_rule_factory("columnGap", "10", &["columnGap"]),
104    );
105
106    assert_eq!(result, expected_result)
107  }
108
109  #[test]
110  fn should_expand_simple_contain_intrinsic_size_values() {
111    let result = flatten_raw_style_object(
112      &[create_key_value_prop_ident(
113        "containIntrinsicSize",
114        create_string_expr("10"),
115      )],
116      &mut EvaluationState::new(),
117      &mut get_state(),
118      &FunctionMap::default(),
119    );
120
121    assert_eq!(result.len(), 2);
122
123    let mut expected_result = IndexMap::new();
124
125    expected_result.insert(
126      "containIntrinsicWidth".to_string(),
127      pre_rule_factory("containIntrinsicWidth", "10", &["containIntrinsicWidth"]),
128    );
129    expected_result.insert(
130      "containIntrinsicHeight".to_string(),
131      pre_rule_factory("containIntrinsicHeight", "10", &["containIntrinsicHeight"]),
132    );
133
134    assert_eq!(result, expected_result)
135  }
136
137  #[test]
138  fn should_expand_simple_gap_with_space_separated_values() {
139    let result = flatten_raw_style_object(
140      &[create_key_value_prop_ident(
141        "gap",
142        create_string_expr("10px 20px"),
143      )],
144      &mut EvaluationState::new(),
145      &mut get_state(),
146      &FunctionMap::default(),
147    );
148
149    assert_eq!(result.len(), 2);
150
151    let mut expected_result = IndexMap::new();
152
153    expected_result.insert(
154      "rowGap".to_string(),
155      pre_rule_factory("rowGap", "10px", &["rowGap"]),
156    );
157    expected_result.insert(
158      "columnGap".to_string(),
159      pre_rule_factory("columnGap", "20px", &["columnGap"]),
160    );
161
162    assert_eq!(result, expected_result)
163  }
164
165  #[test]
166  fn should_expand_simple_contain_intrinsic_size_with_space_separated_values() {
167    let w = "containIntrinsicWidth";
168    let h = "containIntrinsicHeight";
169
170    let result = flatten_raw_style_object(
171      &[create_key_value_prop_ident(
172        "containIntrinsicSize",
173        create_string_expr("10px 20px"),
174      )],
175      &mut EvaluationState::new(),
176      &mut get_state(),
177      &FunctionMap::default(),
178    );
179
180    assert_eq!(result.len(), 2);
181
182    let mut expected_result = IndexMap::new();
183
184    expected_result.insert(w.to_string(), pre_rule_factory(w, "10px", &[w]));
185    expected_result.insert(h.to_string(), pre_rule_factory(h, "20px", &[h]));
186
187    assert_eq!(result, expected_result)
188  }
189
190  #[test]
191  fn should_expand_simple_contain_intrinsic_size_with_space_separated_values_v2() {
192    let w = "containIntrinsicWidth";
193    let h = "containIntrinsicHeight";
194
195    let result = flatten_raw_style_object(
196      &[create_key_value_prop_ident(
197        "containIntrinsicSize",
198        create_string_expr("auto 10px 20px"),
199      )],
200      &mut EvaluationState::new(),
201      &mut get_state(),
202      &FunctionMap::default(),
203    );
204
205    assert_eq!(result.len(), 2);
206
207    let mut expected_result = IndexMap::new();
208
209    expected_result.insert(w.to_string(), pre_rule_factory(w, "auto 10px", &[w]));
210    expected_result.insert(h.to_string(), pre_rule_factory(h, "20px", &[h]));
211
212    assert_eq!(result, expected_result)
213  }
214
215  #[test]
216  fn should_expand_simple_contain_intrinsic_size_with_space_separated_values_v3() {
217    let w = "containIntrinsicWidth";
218    let h = "containIntrinsicHeight";
219
220    let result = flatten_raw_style_object(
221      &[create_key_value_prop_ident(
222        "containIntrinsicSize",
223        create_string_expr("auto 10px auto 20px"),
224      )],
225      &mut EvaluationState::new(),
226      &mut get_state(),
227      &FunctionMap::default(),
228    );
229
230    assert_eq!(result.len(), 2);
231
232    let mut expected_result = IndexMap::new();
233
234    expected_result.insert(w.to_string(), pre_rule_factory(w, "auto 10px", &[w]));
235    expected_result.insert(h.to_string(), pre_rule_factory(h, "auto 20px", &[h]));
236
237    assert_eq!(result, expected_result)
238  }
239
240  #[test]
241  fn should_expand_simple_shorthands() {
242    let result = flatten_raw_style_object(
243      &[create_key_value_prop_ident(
244        "margin",
245        create_string_expr("10"),
246      )],
247      &mut EvaluationState::new(),
248      &mut get_state(),
249      &FunctionMap::default(),
250    );
251
252    assert_eq!(result.len(), 4);
253
254    let mut expected_result = IndexMap::new();
255
256    expected_result.insert(
257      "marginTop".to_string(),
258      pre_rule_factory("marginTop", "10", &["marginTop"]),
259    );
260    expected_result.insert(
261      "marginInlineEnd".to_string(),
262      pre_rule_factory("marginInlineEnd", "10", &["marginInlineEnd"]),
263    );
264    expected_result.insert(
265      "marginBottom".to_string(),
266      pre_rule_factory("marginBottom", "10", &["marginBottom"]),
267    );
268    expected_result.insert(
269      "marginInlineStart".to_string(),
270      pre_rule_factory("marginInlineStart", "10", &["marginInlineStart"]),
271    );
272
273    assert_eq!(result, expected_result)
274  }
275
276  #[test]
277  fn should_expand_simple_shorthands_extended() {
278    let result = flatten_raw_style_object(
279      &[
280        create_key_value_prop_ident("margin", create_string_expr("10")),
281        create_key_value_prop_ident("marginBottom", create_string_expr("20")),
282      ],
283      &mut EvaluationState::new(),
284      &mut get_state(),
285      &FunctionMap::default(),
286    );
287
288    assert_eq!(result.len(), 4);
289
290    let mut expected_result = IndexMap::new();
291
292    expected_result.insert(
293      "marginTop".to_string(),
294      pre_rule_factory("marginTop", "10", &["marginTop"]),
295    );
296    expected_result.insert(
297      "marginInlineEnd".to_string(),
298      pre_rule_factory("marginInlineEnd", "10", &["marginInlineEnd"]),
299    );
300    expected_result.insert(
301      "marginBottom".to_string(),
302      pre_rule_factory("marginBottom", "10", &["marginBottom"]),
303    );
304    expected_result.insert(
305      "marginInlineStart".to_string(),
306      pre_rule_factory("marginInlineStart", "10", &["marginInlineStart"]),
307    );
308
309    expected_result.insert(
310      "marginBottom".to_string(),
311      pre_rule_factory("marginBottom", "20", &["marginBottom"]),
312    );
313
314    assert_eq!(result, expected_result)
315  }
316
317  #[test]
318  fn should_expand_shorthands_with_space_separated_values() {
319    let result = flatten_raw_style_object(
320      &[
321        create_key_value_prop_ident("margin", create_string_expr("10px 20px")),
322        create_key_value_prop_ident("borderColor", create_string_expr("red")),
323      ],
324      &mut EvaluationState::new(),
325      &mut get_state(),
326      &FunctionMap::default(),
327    );
328
329    assert_eq!(result.len(), 8);
330
331    let mut expected_result = IndexMap::new();
332
333    expected_result.insert(
334      "marginTop".to_string(),
335      pre_rule_factory("marginTop", "10px", &["marginTop"]),
336    );
337    expected_result.insert(
338      "marginInlineEnd".to_string(),
339      pre_rule_factory("marginInlineEnd", "20px", &["marginInlineEnd"]),
340    );
341    expected_result.insert(
342      "marginBottom".to_string(),
343      pre_rule_factory("marginBottom", "10px", &["marginBottom"]),
344    );
345    expected_result.insert(
346      "marginInlineStart".to_string(),
347      pre_rule_factory("marginInlineStart", "20px", &["marginInlineStart"]),
348    );
349
350    expected_result.insert(
351      "borderTopColor".to_string(),
352      pre_rule_factory("borderTopColor", "red", &["borderTopColor"]),
353    );
354    expected_result.insert(
355      "borderInlineEndColor".to_string(),
356      pre_rule_factory("borderInlineEndColor", "red", &["borderInlineEndColor"]),
357    );
358    expected_result.insert(
359      "borderBottomColor".to_string(),
360      pre_rule_factory("borderBottomColor", "red", &["borderBottomColor"]),
361    );
362    expected_result.insert(
363      "borderInlineStartColor".to_string(),
364      pre_rule_factory("borderInlineStartColor", "red", &["borderInlineStartColor"]),
365    );
366
367    assert_eq!(result, expected_result)
368  }
369
370  #[test]
371  fn should_expand_shorthands_with_fallbacks() {
372    let result = flatten_raw_style_object(
373      &[create_key_value_prop_ident(
374        "margin",
375        Expr::from(create_array(&[
376          create_string_expr("10vh 20px"),
377          create_string_expr("10dvh 20px"),
378        ])),
379      )],
380      &mut EvaluationState::new(),
381      &mut get_state(),
382      &FunctionMap::default(),
383    );
384
385    assert_eq!(result.len(), 4);
386
387    let mut expected_result = IndexMap::new();
388
389    expected_result.insert(
390      "marginTop".to_string(),
391      pre_rule_vec_factory("marginTop", &["10vh", "10dvh"], &["marginTop"]),
392    );
393    expected_result.insert(
394      "marginInlineEnd".to_string(),
395      pre_rule_factory("marginInlineEnd", "20px", &["marginInlineEnd"]),
396    );
397    expected_result.insert(
398      "marginBottom".to_string(),
399      pre_rule_vec_factory("marginBottom", &["10vh", "10dvh"], &["marginBottom"]),
400    );
401    expected_result.insert(
402      "marginInlineStart".to_string(),
403      pre_rule_factory("marginInlineStart", "20px", &["marginInlineStart"]),
404    );
405
406    assert_eq!(result, expected_result)
407  }
408}
409
410#[cfg(test)]
411mod nested_objects {
412  use indexmap::IndexMap;
413
414  use stylex_ast::ast::factories::{
415    create_key_value_prop_ident,
416    create_object_expression,
417    create_string_key_value_prop,
418  };
419  use crate::shared::structures::functions::FunctionMap;
420  use crate::shared::structures::state::EvaluationState;
421  use crate::shared::structures::tests::flatten_raw_style_objects_test::flatten_style_object_with_legacy_shorthand_expansion::{
422    get_state,
423    null_rule_factory,
424    pre_rule_factory,
425    pre_rule_set_factory,
426  };
427  use crate::shared::utils::ast::convertors::create_string_expr;
428  use crate::shared::utils::core::flatten_raw_style_object::flatten_raw_style_object;
429
430  #[test]
431  fn legacy_pseudo_classes() {
432    let result = flatten_raw_style_object(
433      &[
434        create_key_value_prop_ident("color", create_string_expr("blue")),
435        create_key_value_prop_ident("marginStart", create_string_expr("0")),
436        create_key_value_prop_ident(
437          ":hover",
438          create_object_expression(vec![
439            create_string_key_value_prop("color", "red"),
440            create_string_key_value_prop("marginStart", "10"),
441          ]),
442        ),
443      ],
444      &mut EvaluationState::new(),
445      &mut get_state(),
446      &FunctionMap::default(),
447    );
448
449    assert_eq!(result.len(), 8);
450
451    let mut expected_result = IndexMap::new();
452
453    expected_result.insert(
454      "color".to_string(),
455      pre_rule_factory("color", "blue", &["color"]),
456    );
457    expected_result.insert(
458      "marginInlineStart".to_string(),
459      pre_rule_factory("marginInlineStart", "0", &["marginInlineStart"]),
460    );
461    expected_result.insert("marginLeft".to_string(), null_rule_factory());
462    expected_result.insert("marginRight".to_string(), null_rule_factory());
463    expected_result.insert(
464      ":hover_color".to_string(),
465      pre_rule_factory("color", "red", &[":hover", "color"]),
466    );
467
468    expected_result.insert(
469      ":hover_marginInlineStart".to_string(),
470      pre_rule_factory("marginInlineStart", "10", &[":hover", "marginInlineStart"]),
471    );
472
473    expected_result.insert(":hover_marginLeft".to_string(), null_rule_factory());
474
475    expected_result.insert(":hover_marginRight".to_string(), null_rule_factory());
476
477    assert_eq!(result, expected_result)
478  }
479
480  #[test]
481  fn modern_pseudo_classes() {
482    let result = flatten_raw_style_object(
483      &[
484        create_key_value_prop_ident(
485          "color",
486          create_object_expression(vec![
487            create_string_key_value_prop("default", "blue"),
488            create_string_key_value_prop(":hover", "red"),
489          ]),
490        ),
491        create_key_value_prop_ident(
492          "marginStart",
493          create_object_expression(vec![
494            create_string_key_value_prop("default", "0"),
495            create_string_key_value_prop(":hover", "10"),
496          ]),
497        ),
498      ],
499      &mut EvaluationState::new(),
500      &mut get_state(),
501      &FunctionMap::default(),
502    );
503
504    assert_eq!(result.len(), 4);
505
506    let mut expected_result = IndexMap::new();
507
508    expected_result.insert(
509      "color".to_string(),
510      pre_rule_set_factory(&[
511        pre_rule_factory("color", "blue", &["color", "default"]),
512        pre_rule_factory("color", "red", &["color", ":hover"]),
513      ]),
514    );
515
516    expected_result.insert(
517      "marginInlineStart".to_string(),
518      pre_rule_set_factory(&[
519        pre_rule_factory("marginInlineStart", "0", &["marginInlineStart", "default"]),
520        pre_rule_factory("marginInlineStart", "10", &["marginInlineStart", ":hover"]),
521      ]),
522    );
523
524    expected_result.insert(
525      "marginLeft".to_string(),
526      pre_rule_set_factory(&[null_rule_factory(), null_rule_factory()]),
527    );
528
529    expected_result.insert(
530      "marginRight".to_string(),
531      pre_rule_set_factory(&[null_rule_factory(), null_rule_factory()]),
532    );
533
534    assert_eq!(result, expected_result)
535  }
536
537  #[test]
538  fn modern_pseudo_classes_with_shorthands() {
539    let result = flatten_raw_style_object(
540      &[
541        create_key_value_prop_ident(
542          "color",
543          create_object_expression(vec![
544            create_string_key_value_prop("default", "blue"),
545            create_string_key_value_prop(":hover", "red"),
546          ]),
547        ),
548        create_key_value_prop_ident(
549          "margin",
550          create_object_expression(vec![
551            create_string_key_value_prop("default", "0"),
552            create_string_key_value_prop(":hover", "10"),
553          ]),
554        ),
555      ],
556      &mut EvaluationState::new(),
557      &mut get_state(),
558      &FunctionMap::default(),
559    );
560
561    assert_eq!(result.len(), 5);
562
563    let mut expected_result = IndexMap::new();
564
565    expected_result.insert(
566      "color".to_string(),
567      pre_rule_set_factory(&[
568        pre_rule_factory("color", "blue", &["color", "default"]),
569        pre_rule_factory("color", "red", &["color", ":hover"]),
570      ]),
571    );
572
573    expected_result.insert(
574      "marginTop".to_string(),
575      pre_rule_set_factory(&[
576        pre_rule_factory("marginTop", "0", &["marginTop", "default"]),
577        pre_rule_factory("marginTop", "10", &["marginTop", ":hover"]),
578      ]),
579    );
580
581    expected_result.insert(
582      "marginInlineEnd".to_string(),
583      pre_rule_set_factory(&[
584        pre_rule_factory("marginInlineEnd", "0", &["marginInlineEnd", "default"]),
585        pre_rule_factory("marginInlineEnd", "10", &["marginInlineEnd", ":hover"]),
586      ]),
587    );
588
589    expected_result.insert(
590      "marginBottom".to_string(),
591      pre_rule_set_factory(&[
592        pre_rule_factory("marginBottom", "0", &["marginBottom", "default"]),
593        pre_rule_factory("marginBottom", "10", &["marginBottom", ":hover"]),
594      ]),
595    );
596
597    expected_result.insert(
598      "marginInlineStart".to_string(),
599      pre_rule_set_factory(&[
600        pre_rule_factory("marginInlineStart", "0", &["marginInlineStart", "default"]),
601        pre_rule_factory("marginInlineStart", "10", &["marginInlineStart", ":hover"]),
602      ]),
603    );
604
605    assert_eq!(result, expected_result)
606  }
607
608  #[test]
609  fn modern_pseudo_classes_with_complex_shorthands() {
610    let result = flatten_raw_style_object(
611      &[
612        create_key_value_prop_ident(
613          "color",
614          create_object_expression(vec![
615            create_string_key_value_prop("default", "blue"),
616            create_string_key_value_prop(":hover", "red"),
617          ]),
618        ),
619        create_key_value_prop_ident(
620          "margin",
621          create_object_expression(vec![
622            create_string_key_value_prop("default", "1px 2px 3px 4px"),
623            create_string_key_value_prop(":hover", "10px 20px"),
624          ]),
625        ),
626      ],
627      &mut EvaluationState::new(),
628      &mut get_state(),
629      &FunctionMap::default(),
630    );
631
632    assert_eq!(result.len(), 5);
633
634    let mut expected_result = IndexMap::new();
635
636    expected_result.insert(
637      "color".to_string(),
638      pre_rule_set_factory(&[
639        pre_rule_factory("color", "blue", &["color", "default"]),
640        pre_rule_factory("color", "red", &["color", ":hover"]),
641      ]),
642    );
643
644    expected_result.insert(
645      "marginTop".to_string(),
646      pre_rule_set_factory(&[
647        pre_rule_factory("marginTop", "1px", &["marginTop", "default"]),
648        pre_rule_factory("marginTop", "10px", &["marginTop", ":hover"]),
649      ]),
650    );
651
652    expected_result.insert(
653      "marginInlineEnd".to_string(),
654      pre_rule_set_factory(&[
655        pre_rule_factory("marginInlineEnd", "2px", &["marginInlineEnd", "default"]),
656        pre_rule_factory("marginInlineEnd", "20px", &["marginInlineEnd", ":hover"]),
657      ]),
658    );
659
660    expected_result.insert(
661      "marginBottom".to_string(),
662      pre_rule_set_factory(&[
663        pre_rule_factory("marginBottom", "3px", &["marginBottom", "default"]),
664        pre_rule_factory("marginBottom", "10px", &["marginBottom", ":hover"]),
665      ]),
666    );
667
668    expected_result.insert(
669      "marginInlineStart".to_string(),
670      pre_rule_set_factory(&[
671        pre_rule_factory(
672          "marginInlineStart",
673          "4px",
674          &["marginInlineStart", "default"],
675        ),
676        pre_rule_factory(
677          "marginInlineStart",
678          "20px",
679          &["marginInlineStart", ":hover"],
680        ),
681      ]),
682    );
683
684    assert_eq!(result, expected_result)
685  }
686
687  #[test]
688  fn modern_pseudo_and_at_rules() {
689    let result = flatten_raw_style_object(
690      &[
691        create_key_value_prop_ident(
692          "color",
693          create_object_expression(vec![
694            create_string_key_value_prop("default", "blue"),
695            create_string_key_value_prop(":hover", "red"),
696            create_string_key_value_prop("@media (min-width: 300px)", "green"),
697          ]),
698        ),
699        create_key_value_prop_ident(
700          "marginStart",
701          create_object_expression(vec![
702            create_string_key_value_prop("default", "0"),
703            create_string_key_value_prop(":hover", "10"),
704          ]),
705        ),
706      ],
707      &mut EvaluationState::new(),
708      &mut get_state(),
709      &FunctionMap::default(),
710    );
711
712    assert_eq!(result.len(), 4);
713
714    let mut expected_result = IndexMap::new();
715
716    expected_result.insert(
717      "color".to_string(),
718      pre_rule_set_factory(&[
719        pre_rule_factory("color", "blue", &["color", "default"]),
720        pre_rule_factory("color", "red", &["color", ":hover"]),
721        pre_rule_factory("color", "green", &["color", "@media (min-width: 300px)"]),
722      ]),
723    );
724
725    expected_result.insert(
726      "marginInlineStart".to_string(),
727      pre_rule_set_factory(&[
728        pre_rule_factory("marginInlineStart", "0", &["marginInlineStart", "default"]),
729        pre_rule_factory("marginInlineStart", "10", &["marginInlineStart", ":hover"]),
730      ]),
731    );
732    expected_result.insert(
733      "marginLeft".to_string(),
734      pre_rule_set_factory(&[null_rule_factory(), null_rule_factory()]),
735    );
736
737    expected_result.insert(
738      "marginRight".to_string(),
739      pre_rule_set_factory(&[null_rule_factory(), null_rule_factory()]),
740    );
741
742    assert_eq!(result, expected_result)
743  }
744
745  #[test]
746  fn attribute_selector_conditions() {
747    let result = flatten_raw_style_object(
748      &[create_key_value_prop_ident(
749        "color",
750        create_object_expression(vec![
751          create_string_key_value_prop("default", "blue"),
752          create_string_key_value_prop("[data-panel-state=\"open\"]", "red"),
753        ]),
754      )],
755      &mut EvaluationState::new(),
756      &mut get_state(),
757      &FunctionMap::default(),
758    );
759
760    assert_eq!(result.len(), 1);
761
762    let mut expected_result = IndexMap::new();
763
764    expected_result.insert(
765      "color".to_string(),
766      pre_rule_set_factory(&[
767        pre_rule_factory("color", "blue", &["color", "default"]),
768        pre_rule_factory("color", "red", &["color", "[data-panel-state=\"open\"]"]),
769      ]),
770    );
771
772    assert_eq!(result, expected_result)
773  }
774}
775
776#[cfg(test)]
777mod multiple_levels_of_nesting {
778  use indexmap::IndexMap;
779
780  use stylex_ast::ast::factories::{
781    create_key_value_prop_ident,
782    create_nested_object_prop,
783    create_object_expression,
784    create_string_array_prop,
785    create_string_key_value_prop,
786  };
787  use crate::shared::structures::functions::FunctionMap;
788  use crate::shared::structures::state::EvaluationState;
789  use crate::shared::structures::tests::flatten_raw_style_objects_test::flatten_style_object_with_legacy_shorthand_expansion::{
790    get_state,
791    pre_rule_factory,
792    pre_rule_set_factory,
793    pre_rule_vec_factory,
794  };
795  use crate::shared::utils::core::flatten_raw_style_object::flatten_raw_style_object;
796
797  #[test]
798  fn fallback_styles_within_nested_objects() {
799    let result = flatten_raw_style_object(
800      &[create_key_value_prop_ident(
801        "margin",
802        create_object_expression(vec![
803          create_string_key_value_prop("default", "1px 2px 3px 4px"),
804          create_string_array_prop(":hover", &["10px 20px", "1dvh 2dvh"]),
805        ]),
806      )],
807      &mut EvaluationState::new(),
808      &mut get_state(),
809      &FunctionMap::default(),
810    );
811
812    assert_eq!(result.len(), 4);
813
814    let mut expected_result = IndexMap::new();
815
816    expected_result.insert(
817      "marginTop".to_string(),
818      pre_rule_set_factory(&[
819        pre_rule_factory("marginTop", "1px", &["marginTop", "default"]),
820        pre_rule_vec_factory("marginTop", &["10px", "1dvh"], &["marginTop", ":hover"]),
821      ]),
822    );
823
824    expected_result.insert(
825      "marginInlineEnd".to_string(),
826      pre_rule_set_factory(&[
827        pre_rule_factory("marginInlineEnd", "2px", &["marginInlineEnd", "default"]),
828        pre_rule_vec_factory(
829          "marginInlineEnd",
830          &["20px", "2dvh"],
831          &["marginInlineEnd", ":hover"],
832        ),
833      ]),
834    );
835
836    expected_result.insert(
837      "marginBottom".to_string(),
838      pre_rule_set_factory(&[
839        pre_rule_factory("marginBottom", "3px", &["marginBottom", "default"]),
840        pre_rule_vec_factory(
841          "marginBottom",
842          &["10px", "1dvh"],
843          &["marginBottom", ":hover"],
844        ),
845      ]),
846    );
847
848    expected_result.insert(
849      "marginInlineStart".to_string(),
850      pre_rule_set_factory(&[
851        pre_rule_factory(
852          "marginInlineStart",
853          "4px",
854          &["marginInlineStart", "default"],
855        ),
856        pre_rule_vec_factory(
857          "marginInlineStart",
858          &["20px", "2dvh"],
859          &["marginInlineStart", ":hover"],
860        ),
861      ]),
862    );
863
864    assert_eq!(result, expected_result)
865  }
866
867  #[test]
868  fn pseudo_within_a_media_query_legacy_syntax() {
869    let result = flatten_raw_style_object(
870      &[create_key_value_prop_ident(
871        "@media (min-width: 300px)",
872        create_object_expression(vec![create_nested_object_prop(
873          ":hover",
874          vec![create_string_key_value_prop("color", "red")],
875        )]),
876      )],
877      &mut EvaluationState::new(),
878      &mut get_state(),
879      &FunctionMap::default(),
880    );
881
882    assert_eq!(result.len(), 1);
883
884    let mut expected_result = IndexMap::new();
885
886    expected_result.insert(
887      "@media (min-width: 300px)_:hover_color".to_string(),
888      pre_rule_set_factory(&[pre_rule_factory(
889        "color",
890        "red",
891        &["@media (min-width: 300px)", ":hover", "color"],
892      )]),
893    );
894
895    assert_eq!(result, expected_result)
896  }
897
898  #[test]
899  fn pseudo_with_a_pseudo_within_a_media_query_legacy_syntax() {
900    let result = flatten_raw_style_object(
901      &[create_key_value_prop_ident(
902        "@media (min-width: 300px)",
903        create_object_expression(vec![create_nested_object_prop(
904          ":hover",
905          vec![
906            create_string_key_value_prop("color", "pink"),
907            create_nested_object_prop(
908              ":active",
909              vec![create_string_key_value_prop("color", "red")],
910            ),
911          ],
912        )]),
913      )],
914      &mut EvaluationState::new(),
915      &mut get_state(),
916      &FunctionMap::default(),
917    );
918
919    assert_eq!(result.len(), 2);
920
921    let mut expected_result = IndexMap::new();
922
923    expected_result.insert(
924      "@media (min-width: 300px)_:hover_color".to_string(),
925      pre_rule_set_factory(&[pre_rule_factory(
926        "color",
927        "pink",
928        &["@media (min-width: 300px)", ":hover", "color"],
929      )]),
930    );
931
932    expected_result.insert(
933      "@media (min-width: 300px)_:hover_:active_color".to_string(),
934      pre_rule_set_factory(&[pre_rule_factory(
935        "color",
936        "red",
937        &["@media (min-width: 300px)", ":hover", ":active", "color"],
938      )]),
939    );
940
941    assert_eq!(result, expected_result)
942  }
943
944  #[test]
945  fn pseudo_within_a_media_query_modern_syntax() {
946    let result = flatten_raw_style_object(
947      &[create_key_value_prop_ident(
948        "color",
949        create_object_expression(vec![
950          create_string_key_value_prop("default", "blue"),
951          create_nested_object_prop(
952            "@media (min-width: 300px)",
953            vec![create_string_key_value_prop(":hover", "red")],
954          ),
955        ]),
956      )],
957      &mut EvaluationState::new(),
958      &mut get_state(),
959      &FunctionMap::default(),
960    );
961
962    assert_eq!(result.len(), 1);
963
964    let mut expected_result = IndexMap::new();
965
966    expected_result.insert(
967      "color".to_string(),
968      pre_rule_set_factory(&[
969        pre_rule_factory("color", "blue", &["color", "default"]),
970        pre_rule_factory(
971          "color",
972          "red",
973          &["color", "@media (min-width: 300px)", ":hover"],
974        ),
975      ]),
976    );
977
978    assert_eq!(result, expected_result)
979  }
980
981  #[test]
982  fn extra_deep_pseudo_within_a_media_query_modern_syntax() {
983    let result = flatten_raw_style_object(
984      &[create_key_value_prop_ident(
985        "color",
986        create_object_expression(vec![
987          create_string_key_value_prop("default", "blue"),
988          create_nested_object_prop(
989            "@media (min-width: 300px)",
990            vec![create_nested_object_prop(
991              ":hover",
992              vec![
993                create_string_key_value_prop("default", "red"),
994                create_string_key_value_prop(":active", "maroon"),
995              ],
996            )],
997          ),
998        ]),
999      )],
1000      &mut EvaluationState::new(),
1001      &mut get_state(),
1002      &FunctionMap::default(),
1003    );
1004
1005    assert_eq!(result.len(), 1);
1006
1007    let mut expected_result = IndexMap::new();
1008
1009    expected_result.insert(
1010      "color".to_string(),
1011      pre_rule_set_factory(&[
1012        pre_rule_factory("color", "blue", &["color", "default"]),
1013        pre_rule_factory(
1014          "color",
1015          "red",
1016          &["color", "@media (min-width: 300px)", ":hover", "default"],
1017        ),
1018        pre_rule_factory(
1019          "color",
1020          "maroon",
1021          &["color", "@media (min-width: 300px)", ":hover", ":active"],
1022        ),
1023      ]),
1024    );
1025
1026    assert_eq!(result, expected_result)
1027  }
1028}