@@ -126,3 +126,27 @@ def test_generic_and_unicode_jsx_keep_module_and_literal_classes(tmp_path, tag):
126126 findings = DeadCodeScanner (tmp_path ).scan ().orphaned_css
127127 assert {finding .name for finding in findings } == {"unused" , "unusedGlobal" }
128128 assert all (finding .removable for finding in findings )
129+
130+
131+ @pytest .mark .parametrize ("extension" , ["tsx" , "jsx" ])
132+ @pytest .mark .parametrize ("tag" , ["_Button" , "$Button" , "Button$" , "Élément" ])
133+ def test_all_jsx_identifier_forms_keep_raw_attribute_grammar (tmp_path , monkeypatch , extension , tag ):
134+ view = rf'<{ tag } data-path="C:\" className={{styles.card}} />'
135+ test_raw_jsx_attribute_quotes_preserve_live_module_rules (tmp_path , monkeypatch , extension , view )
136+
137+
138+ @pytest .mark .parametrize ("extension" , ["ts" , "tsx" ])
139+ @pytest .mark .parametrize (
140+ "expression,live" ,
141+ [("a < styles.card > (b)" , False ), ("(a < styles.card) > b" , True ), ("a < styles.card > b" , True )],
142+ )
143+ def test_angle_expression_usage_agrees_with_typescript_emission (tmp_path , extension , expression , live ):
144+ # TypeScript 5.9.3 emits a(b) for the first expression, and preserves the
145+ # two explicitly relational forms. Whitespace does not change that grammar.
146+ (tmp_path / "Card.module.css" ).write_text (".card {}\n " , encoding = "utf-8" )
147+ (tmp_path / f"consumer.{ extension } " ).write_text (
148+ f"import styles from './Card.module.css';\n const value = { expression } ;\n " , encoding = "utf-8"
149+ )
150+ findings = DeadCodeScanner (tmp_path ).scan ().orphaned_css
151+ assert bool (findings ) is not live
152+ assert all (finding .name == "card" and finding .removable for finding in findings )
0 commit comments