Skip to content

Commit 6e1e1ba

Browse files
committed
Fix coverage
1 parent 8a28184 commit 6e1e1ba

3 files changed

Lines changed: 73 additions & 64 deletions

File tree

libs/extractor/src/extractor/extract_global_style_from_expression.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,8 @@ pub fn extract_global_style_from_expression<'a>(
150150
// Handle @layer property in globalStyle
151151
// Extract the layer name if present in the style object
152152
let mut layer_name: Option<String> = None;
153-
if let Expression::ObjectExpression(style_obj) = &o.value {
154-
for style_prop in style_obj.properties.iter() {
155-
if let ObjectPropertyKind::ObjectProperty(sp) = style_prop
156-
&& let Some(prop_name) = get_string_by_property_key(&sp.key)
157-
&& prop_name == "@layer"
158-
{
159-
layer_name = get_string_by_literal_expression(&sp.value);
160-
break;
161-
}
162-
}
153+
if let Expression::ObjectExpression(style_obj) = &o.value && let Some(ObjectPropertyKind::ObjectProperty(sp)) = style_obj.properties.iter().find(|style_prop| matches!(style_prop, ObjectPropertyKind::ObjectProperty(s) if get_string_by_property_key(&s.key) == Some("@layer".to_string()))) {
154+
layer_name = get_string_by_literal_expression(&sp.value);
163155
}
164156

165157
let extracted = extract_style_from_expression(

libs/extractor/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12203,4 +12203,27 @@ export const card = style({
1220312203
.unwrap()
1220412204
));
1220512205
}
12206+
12207+
#[test]
12208+
#[serial]
12209+
fn test_extract_class_map_from_code_parser_panic() {
12210+
// Test extract_class_map_from_code with invalid code that causes parser panic (covers line 153-154)
12211+
let mut style_names = HashSet::new();
12212+
style_names.insert("test".to_string());
12213+
12214+
let result = extract_class_map_from_code(
12215+
"test.tsx",
12216+
"const {{ invalid syntax {{{{",
12217+
&ExtractOption {
12218+
package: "@devup-ui/react".to_string(),
12219+
css_dir: "@devup-ui/react".to_string(),
12220+
single_css: true,
12221+
import_main_css: false,
12222+
},
12223+
&style_names,
12224+
)
12225+
.unwrap();
12226+
12227+
assert!(result.is_empty());
12228+
}
1220612229
}

libs/extractor/src/vanilla_extract.rs

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,16 @@ fn extract_theme_vars(
240240
let var_name = &contract_str[4..contract_str.len() - 1];
241241

242242
// Get the value
243-
let value_str = if let Some(s) = values.as_string() {
244-
s.to_std_string_escaped()
245-
} else if let Ok(s) = values.to_string(ctx) {
246-
s.to_std_string_escaped()
247-
} else {
248-
String::new()
249-
};
243+
let value_str = values
244+
.as_string()
245+
.map(|s| s.to_std_string_escaped())
246+
.or_else(|| {
247+
values
248+
.to_string(ctx)
249+
.ok()
250+
.map(|s| s.to_std_string_escaped())
251+
})
252+
.unwrap_or_default();
250253

251254
css_vars.push((var_name.to_string(), value_str));
252255
}
@@ -312,13 +315,11 @@ fn transform_theme_to_vars(
312315
*var_counter += 1;
313316

314317
// Get the actual value as string
315-
let value_str = if let Some(s) = value.as_string() {
316-
s.to_std_string_escaped()
317-
} else if let Ok(s) = value.to_string(ctx) {
318-
s.to_std_string_escaped()
319-
} else {
320-
String::new()
321-
};
318+
let value_str = value
319+
.as_string()
320+
.map(|s| s.to_std_string_escaped())
321+
.or_else(|| value.to_string(ctx).ok().map(|s| s.to_std_string_escaped()))
322+
.unwrap_or_default();
322323

323324
css_vars.push((var_name.clone(), value_str));
324325

@@ -344,9 +345,7 @@ fn js_value_to_json(value: &JsValue, context: &mut Context) -> String {
344345

345346
// Fallback: simple conversion using boa_engine 0.21 API
346347
match value.variant() {
347-
boa_engine::value::JsVariant::String(str) => {
348-
format!("\"{}\"", str.to_std_string_escaped())
349-
}
348+
boa_engine::value::JsVariant::String(str) => format!("\"{}\"", str.to_std_string_escaped()),
350349
boa_engine::value::JsVariant::Null => "null".to_string(),
351350
boa_engine::value::JsVariant::Undefined => "undefined".to_string(),
352351
_ => "{}".to_string(),
@@ -840,51 +839,46 @@ fn register_vanilla_extract_apis(
840839
let id = next_style_id(&collector_style);
841840

842841
// Check if argument is an array (composition syntax)
843-
let (json, bases) = if let Some(obj) = style_obj.as_object() {
844-
if let Ok(length_val) = obj.get(js_string!("length"), ctx)
845-
&& let Some(len) = length_val.as_number()
846-
{
847-
// It's an array - handle composition
848-
let len = len as u32;
849-
let mut base_classes = Vec::new();
850-
let mut merged_styles = String::from("{");
851-
let mut first_style = true;
852-
853-
for i in 0..len {
854-
if let Ok(elem) = obj.get(i, ctx) {
855-
if let Some(base_str) = elem.as_string() {
856-
// It's a base class reference (string)
857-
base_classes.push(base_str.to_std_string_escaped());
858-
} else if elem.is_object() {
859-
// It's a style object - merge it
860-
let elem_json = js_value_to_json(&elem, ctx);
861-
// Strip outer braces and merge
862-
let inner = elem_json
863-
.trim()
864-
.trim_start_matches('{')
865-
.trim_end_matches('}')
866-
.trim();
867-
if !inner.is_empty() {
868-
if !first_style {
869-
merged_styles.push(',');
870-
}
871-
merged_styles.push_str(inner);
872-
first_style = false;
842+
let (json, bases) = if let Some(obj) = style_obj.as_object()
843+
&& let Ok(length_val) = obj.get(js_string!("length"), ctx)
844+
&& let Some(len) = length_val.as_number()
845+
{
846+
// It's an array - handle composition
847+
let len = len as u32;
848+
let mut base_classes = Vec::new();
849+
let mut merged_styles = String::from("{");
850+
let mut first_style = true;
851+
852+
for i in 0..len {
853+
if let Ok(elem) = obj.get(i, ctx) {
854+
if let Some(base_str) = elem.as_string() {
855+
// It's a base class reference (string)
856+
base_classes.push(base_str.to_std_string_escaped());
857+
} else if elem.is_object() {
858+
// It's a style object - merge it
859+
let elem_json = js_value_to_json(&elem, ctx);
860+
// Strip outer braces and merge
861+
let inner = elem_json
862+
.trim()
863+
.trim_start_matches('{')
864+
.trim_end_matches('}')
865+
.trim();
866+
if !inner.is_empty() {
867+
if !first_style {
868+
merged_styles.push(',');
873869
}
870+
merged_styles.push_str(inner);
871+
first_style = false;
874872
}
875873
}
876874
}
877-
merged_styles.push('}');
878-
(merged_styles, base_classes)
879-
} else {
880-
// No length property, just a style object
881-
(js_value_to_json(style_obj, ctx), Vec::new())
882875
}
876+
merged_styles.push('}');
877+
(merged_styles, base_classes)
883878
} else {
884-
// Not an object at all
879+
// No length property, just a style object
885880
(js_value_to_json(style_obj, ctx), Vec::new())
886881
};
887-
888882
collector_style.borrow_mut().styles.styles.insert(
889883
id.clone(),
890884
StyleEntry {

0 commit comments

Comments
 (0)