Skip to content

Commit 2cf5c59

Browse files
committed
Switch layout tests styling to parsed CSS
1 parent 52e0ccd commit 2cf5c59

17 files changed

Lines changed: 213 additions & 430 deletions

sbr-log/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub struct RootLogger {
148148
}
149149

150150
impl RootLogger {
151-
pub fn new() -> Self {
151+
pub const fn new() -> Self {
152152
Self {
153153
callback: MessageCallback::Default,
154154
}

sbr-macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ pub fn test_define_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream
1515

1616
#[proc_macro]
1717
pub fn test_apply_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
18-
test::test_apply_style(ts)
18+
test::test_apply_styles(ts)
1919
}

sbr-macros/src/test.rs

Lines changed: 56 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,13 @@ use proc_macro2::{TokenStream as TokenStream2, TokenTree as TokenTree2};
22
use quote::quote;
33
use syn::{parse::ParseStream, Token};
44

5-
use crate::{
6-
common::advance_past_punct,
7-
parse::{wrap_syn_group_macro, AlreadyReported, ParseContext, ReportIn as _},
8-
};
5+
use crate::parse::{AlreadyReported, ParseContext, ReportIn as _};
96

107
#[derive(Debug, Clone)]
118
struct DefineStyleClass {
129
visibility: syn::Visibility,
1310
name: syn::Ident,
14-
properties: Vec<(syn::Ident, syn::Expr)>,
15-
}
16-
17-
impl DefineStyleClass {
18-
fn parse_properties(
19-
buffer: ParseStream,
20-
ctx: &mut ParseContext,
21-
result: &mut Vec<(syn::Ident, syn::Expr)>,
22-
) -> Result<(), AlreadyReported> {
23-
let mut errored = false;
24-
25-
while !buffer.is_empty() {
26-
let Ok(name) = buffer.parse::<syn::Ident>().report_in(ctx) else {
27-
errored = true;
28-
advance_past_punct(buffer, ';');
29-
continue;
30-
};
31-
32-
let Ok(_) = buffer.parse::<Token![:]>().report_in(ctx) else {
33-
errored = true;
34-
advance_past_punct(buffer, ';');
35-
continue;
36-
};
37-
38-
let Ok(value) = buffer.parse::<syn::Expr>().report_in(ctx) else {
39-
errored = true;
40-
advance_past_punct(buffer, ';');
41-
continue;
42-
};
43-
44-
result.push((name, value));
45-
46-
if buffer.is_empty() {
47-
break;
48-
}
49-
50-
errored |= buffer.parse::<Token![,]>().report_in(ctx).is_err();
51-
}
52-
53-
if errored {
54-
Err(AlreadyReported)
55-
} else {
56-
Ok(())
57-
}
58-
}
11+
source: syn::LitStr,
5912
}
6013

6114
#[derive(Debug, Clone)]
@@ -95,24 +48,19 @@ impl DefineStyleInput {
9548
continue;
9649
};
9750

98-
let Ok((inner, _)) =
99-
wrap_syn_group_macro!(syn::braced in buffer).report_in_and_set(ctx, &mut errored)
51+
let Ok(source) = buffer
52+
.parse::<syn::LitStr>()
53+
.report_in_and_set(ctx, &mut errored)
10054
else {
10155
_ = buffer.parse::<TokenTree2>();
10256
continue;
10357
};
10458

105-
let mut group = DefineStyleClass {
59+
result.classes.push(DefineStyleClass {
10660
visibility,
10761
name,
108-
properties: Vec::new(),
109-
};
110-
111-
if let Ok(()) = DefineStyleClass::parse_properties(&inner, ctx, &mut group.properties) {
112-
result.classes.push(group);
113-
} else {
114-
errored = true;
115-
}
62+
source,
63+
});
11664
}
11765

11866
if errored {
@@ -123,8 +71,8 @@ impl DefineStyleInput {
12371
}
12472
}
12573

126-
fn apply_function_for_class_name(class: &syn::Ident) -> syn::Ident {
127-
syn::Ident::new(&format!("apply_style_{class}"), class.span())
74+
fn declarations_name_for_class_name(class: &syn::Ident) -> syn::Ident {
75+
syn::Ident::new(&format!("STYLE_{class}_DECLARATIONS"), class.span())
12876
}
12977

13078
pub fn test_define_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -139,47 +87,57 @@ pub fn test_define_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream
13987
let mut result = TokenStream2::new();
14088

14189
for class in input.classes {
142-
let visibility = &class.visibility;
143-
let apply_name = apply_function_for_class_name(&class.name);
144-
let mut apply_body = TokenStream2::new();
145-
146-
for (name, value) in &class.properties {
147-
let make_mut_name = syn::Ident::new(&format!("make_{name}_mut"), name.span());
148-
149-
apply_body.extend(quote! {
150-
*current.#make_mut_name() = #value;
151-
});
152-
}
90+
let visibility = class.visibility;
91+
let declarations_name = declarations_name_for_class_name(&class.name);
92+
let source = class.source;
15393

15494
result.extend(quote! {
155-
#visibility fn #apply_name(current: &mut crate::style::ComputedStyle) {
156-
#apply_body
157-
}
158-
})
95+
#[allow(non_upper_case_globals)]
96+
#visibility static #declarations_name: std::sync::LazyLock<
97+
&'static [crate::csssyn::algorithms::Declaration<'static>]
98+
> =
99+
std::sync::LazyLock::new(|| {
100+
let buffer = Box::leak(Box::new(crate::csssyn::TokenBuffer::from_source(#source).unwrap()));
101+
let declarations = crate::csssyn::algorithms::parse_declaration_list(buffer.start());
102+
Box::leak(declarations.collect::<Vec<_>>().into_boxed_slice())
103+
});
104+
});
159105
}
160106

161107
result.into()
162108
}
163109

164110
struct ApplyStyleInput {
165-
target: syn::Expr,
166-
name: syn::Ident,
111+
lctx: syn::Expr,
112+
parent: syn::Expr,
113+
classes: Vec<syn::Ident>,
167114
}
168115

169116
impl ApplyStyleInput {
170117
fn parse(buffer: ParseStream, ctx: &mut ParseContext) -> Result<Self, AlreadyReported> {
171118
Ok(Self {
172-
target: {
173-
let target = buffer.parse::<syn::Expr>().report_in(ctx)?;
119+
lctx: {
120+
let lctx = buffer.parse::<syn::Expr>().report_in(ctx)?;
174121
buffer.parse::<Token![,]>().report_in(ctx)?;
175-
target
122+
lctx
123+
},
124+
parent: {
125+
let parent = buffer.parse::<syn::Expr>().report_in(ctx)?;
126+
buffer.parse::<Token![,]>().report_in(ctx)?;
127+
parent
128+
},
129+
classes: {
130+
let mut result = Vec::new();
131+
while !buffer.is_empty() {
132+
result.push(buffer.parse::<syn::Ident>().report_in(ctx)?);
133+
}
134+
result
176135
},
177-
name: buffer.parse::<syn::Ident>().report_in(ctx)?,
178136
})
179137
}
180138
}
181139

182-
pub fn test_apply_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
140+
pub fn test_apply_styles(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
183141
let input = {
184142
let mut parse_ctx = ParseContext::new();
185143
let Ok(input) = parse_ctx.parse2(ApplyStyleInput::parse, ts.into()) else {
@@ -188,8 +146,18 @@ pub fn test_apply_style(ts: proc_macro::TokenStream) -> proc_macro::TokenStream
188146
input
189147
};
190148

191-
let apply_name = apply_function_for_class_name(&input.name);
192-
let target = input.target;
193-
194-
quote! { #apply_name(#target) }.into()
149+
let lctx = input.lctx;
150+
let parent = input.parent;
151+
let class_declarations = input
152+
.classes
153+
.into_iter()
154+
.map(|class| declarations_name_for_class_name(&class));
155+
156+
quote! {{
157+
let mut declarations = [
158+
#(#class_declarations.iter(),)*
159+
].into_iter().flatten().cloned().collect();
160+
crate::style::compute_with_declarations(#lctx, declarations, #parent)
161+
}}
162+
.into()
195163
}

src/style.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static DECLARATION_HANDLER_MAP: LazyLock<HashMap<&'static str, values::ParseAndC
8484
result
8585
});
8686

87-
#[expect(dead_code)]
87+
#[cfg_attr(not(all(test, feature = "_layout_tests")), expect(dead_code))]
8888
pub fn compute_with_declarations(
8989
log: LogContext,
9090
declarations: Vec<Declaration<'_>>,

tests/layout/block.rs

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,32 @@
1-
use rasterize::color::BGRA8;
2-
3-
use crate::{
4-
layout::FixedL,
5-
style::computed::{Color, Direction, HorizontalAlignment, InlineSizing, Length},
6-
};
7-
81
use super::common::*;
92

103
test_define_style! {
11-
.black_on_white {
12-
color: BGRA8::BLACK,
13-
background_color: Color::Srgb(BGRA8::WHITE),
14-
}
15-
.text_centered { text_align: HorizontalAlignment::Center }
16-
.text_right { text_align: HorizontalAlignment::Right }
17-
18-
.vpadding10 {
19-
padding_top: Length::from_pixels(FixedL::new(10)),
20-
padding_bottom: Length::from_pixels(FixedL::new(10)),
21-
}
22-
.hpadding5 {
23-
padding_left: Length::from_pixels(FixedL::new(5)),
24-
padding_right: Length::from_pixels(FixedL::new(5)),
25-
}
26-
.vpadding4 {
27-
padding_top: Length::from_pixels(FixedL::new(4)),
28-
padding_bottom: Length::from_pixels(FixedL::new(4)),
29-
}
30-
.lpadding6 { padding_left: Length::from_pixels(FixedL::new(6)) }
31-
32-
.lmargin_auto { margin_left: None }
33-
.lmargin10 { margin_left: Some(Length::from_pixels(FixedL::new(10))) }
34-
.lmargin48 { margin_left: Some(Length::from_pixels(FixedL::new(48))) }
35-
.rmargin_auto { margin_right: None }
36-
.rmargin16 { margin_right: Some(Length::from_pixels(FixedL::new(16))) }
37-
.rmargin22 { margin_right: Some(Length::from_pixels(FixedL::new(22))) }
38-
.hmargin_auto { margin_left: None, margin_right: None }
39-
.hmargin40 {
40-
margin_left: Some(Length::from_pixels(FixedL::new(40))),
41-
margin_right: Some(Length::from_pixels(FixedL::new(40))),
42-
}
43-
44-
.width32 { width: Some(Length::from_pixels(FixedL::new(32))) }
45-
.width64 { width: Some(Length::from_pixels(FixedL::new(64))) }
46-
47-
.rtl { direction: Direction::Rtl }
48-
49-
.inline_sizing_stretch { inline_sizing: InlineSizing::Stretch }
4+
.black_on_white "
5+
color: black;
6+
background-color: white;
7+
"
8+
.text_centered "text-align: center"
9+
.text_right "text-align: right"
10+
.vpadding10 "padding-top: 10px; padding-bottom: 10px"
11+
.vpadding4 "padding-top: 4px; padding-bottom: 4px"
12+
.hpadding5 "padding-left: 5px; padding-right: 5px"
13+
.lpadding6 "padding-left: 6px"
14+
15+
.lmargin_auto "margin-left: auto"
16+
.lmargin10 "margin-left: 10px"
17+
.lmargin48 "margin-left: 48px"
18+
.rmargin_auto "margin-right: auto"
19+
.rmargin16 "margin-right: 16px"
20+
.rmargin22 "margin-right: 22px"
21+
.hmargin_auto "margin-left: auto; margin-right: auto"
22+
.hmargin40 "margin-left: 40px; margin-right: 40px"
23+
24+
.width32 "width: 32px"
25+
.width64 "width: 64px"
26+
27+
.rtl "direction: rtl"
28+
29+
.inline_sizing_stretch "-sbr-inline-sizing: stretch"
5030
}
5131

5232
check_test! {

0 commit comments

Comments
 (0)