Skip to content

Commit

Permalink
enh(#45): add defineProps tests and refine logic (#57)
Browse files Browse the repository at this point in the history
* enh(#45): add `defineProps` tests and refine logic

* chore: add exceptions to cspell list

* test: fix tests by removing unnecessary quotes

* test: move code around to try and work around hash collision on apple x64

* fix: fix unknown test cases
  • Loading branch information
phoenix-ru authored Nov 28, 2024
1 parent eade663 commit 93aaafd
Show file tree
Hide file tree
Showing 30 changed files with 2,267 additions and 193 deletions.
11 changes: 10 additions & 1 deletion crates/fervid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
//! let mut transform_errors = Vec::new();
//! let transform_options = fervid_transform::TransformSfcOptions {
//! is_prod: true,
//! is_ce: false,
//! props_destructure: fervid_transform::PropsDestructureConfig::default(),
//! scope_id: "filehash",
//! filename: "input.vue"
//! };
Expand Down Expand Up @@ -58,7 +60,7 @@ use fervid_codegen::CodegenContext;
pub use fervid_core::*;
use fervid_parser::SfcParser;
use fervid_transform::{
style::should_transform_style_block, transform_sfc, SetupBinding, TransformSfcOptions,
style::should_transform_style_block, transform_sfc, PropsDestructureConfig, SetupBinding, TransformSfcOptions
};
use fxhash::FxHasher32;
use std::{
Expand All @@ -78,7 +80,9 @@ pub struct CompileOptions<'o> {
// pub scoped: Option<bool>,
// pub slotted: Option<bool>,
pub is_prod: Option<bool>,
pub is_custom_element: Option<bool>,
pub ssr: Option<bool>,
pub props_destructure: Option<PropsDestructureConfig>,
// pub ssrCssVars?: string[],
// pub inMap?: RawSourceMap,
// pub compiler?: TemplateCompiler,
Expand Down Expand Up @@ -131,6 +135,7 @@ pub fn compile(source: &str, options: CompileOptions) -> Result<CompileResult, C

// Options
let is_prod = options.is_prod.unwrap_or_default();
let is_custom_element = options.is_custom_element.unwrap_or_default();

// Parse
let mut sfc_parsing_errors = Vec::new();
Expand All @@ -151,6 +156,8 @@ pub fn compile(source: &str, options: CompileOptions) -> Result<CompileResult, C
let mut transform_errors = Vec::new();
let transform_options = TransformSfcOptions {
is_prod,
is_ce: is_custom_element,
props_destructure: options.props_destructure.unwrap_or_default(),
scope_id: &file_hash,
filename: &options.filename,
};
Expand Down Expand Up @@ -246,6 +253,8 @@ pub fn compile_sync_naive(source: &str, is_prod: bool) -> Result<String, String>
let mut transform_errors = Vec::new();
let transform_options = TransformSfcOptions {
is_prod,
is_ce: false,
props_destructure: PropsDestructureConfig::default(),
scope_id: &file_hash,
filename: "anonymous.vue".into(),
};
Expand Down
6 changes: 3 additions & 3 deletions crates/fervid_codegen/src/attributes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use fervid_core::{
fervid_atom, AttributeOrBinding, FervidAtom, IntoIdent, StrOrExpr, VBindDirective,
VOnDirective, VueImports,
fervid_atom, str_to_propname, AttributeOrBinding, FervidAtom, IntoIdent, StrOrExpr,
VBindDirective, VOnDirective, VueImports,
};
use regex::Regex;
use swc_core::{
Expand All @@ -12,7 +12,7 @@ use swc_core::{
},
};

use crate::{context::CodegenContext, utils::str_to_propname};
use crate::context::CodegenContext;

lazy_static! {
static ref CSS_RE: Regex =
Expand Down
4 changes: 2 additions & 2 deletions crates/fervid_codegen/src/builtins/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"(_openBlock(),_createBlock(_resolveDynamicComponent("div"),null,{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
r#"(_openBlock(),_createBlock(_resolveDynamicComponent("div"),null,{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
)
}

Expand Down Expand Up @@ -300,7 +300,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"(_openBlock(),_createBlock(_resolveDynamicComponent("div"),{foo:"bar",baz:qux},{named:_withCtx(()=>[_createTextVNode("bazqux")]),"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
r#"(_openBlock(),_createBlock(_resolveDynamicComponent("div"),{foo:"bar",baz:qux},{named:_withCtx(()=>[_createTextVNode("bazqux")]),default:_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/fervid_codegen/src/builtins/suspense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"(_openBlock(),_createBlock(_Suspense,null,{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
r#"(_openBlock(),_createBlock(_Suspense,null,{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
)
}

Expand All @@ -123,7 +123,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"(_openBlock(),_createBlock(_Suspense,{foo:"bar",baz:qux},{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
r#"(_openBlock(),_createBlock(_Suspense,{foo:"bar",baz:qux},{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1}))"#,
)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/fervid_codegen/src/builtins/transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_Transition,null,{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
r#"_createVNode(_Transition,null,{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
)
}

Expand All @@ -122,7 +122,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_Transition,{foo:"bar",baz:qux},{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
r#"_createVNode(_Transition,{foo:"bar",baz:qux},{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/fervid_codegen/src/builtins/transition_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_TransitionGroup,null,{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
r#"_createVNode(_TransitionGroup,null,{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
)
}

Expand All @@ -122,7 +122,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_TransitionGroup,{foo:"bar",baz:qux},{"default":_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
r#"_createVNode(_TransitionGroup,{foo:"bar",baz:qux},{default:_withCtx(()=>[_createTextVNode("foobar")]),_:1})"#,
)
}

Expand Down
20 changes: 9 additions & 11 deletions crates/fervid_codegen/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use fervid_core::{
fervid_atom, ComponentBinding, ElementNode, FervidAtom, Node, PatchHints, StartingTag,
StrOrExpr, VSlotDirective, VueDirectives, VueImports,
fervid_atom, str_or_expr_to_propname, ComponentBinding, ElementNode, FervidAtom, Node,
PatchHints, StartingTag, StrOrExpr, VSlotDirective, VueDirectives, VueImports,
};
use swc_core::{
common::{Span, DUMMY_SP},
Expand All @@ -11,9 +11,7 @@ use swc_core::{
},
};

use crate::{
context::CodegenContext, control_flow::SlottedIterator, utils::str_or_expr_to_propname,
};
use crate::{context::CodegenContext, control_flow::SlottedIterator};

impl CodegenContext {
pub fn generate_component_vnode(
Expand Down Expand Up @@ -741,7 +739,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"default":_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
r#"_createVNode(_component_test_component,null,{default:_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
false,
);

Expand Down Expand Up @@ -792,7 +790,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"default":_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
r#"_createVNode(_component_test_component,null,{default:_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
false,
);
}
Expand Down Expand Up @@ -985,7 +983,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),"default":_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),default:_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
false,
);

Expand Down Expand Up @@ -1057,7 +1055,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"default":_withCtx(()=>[_createTextVNode("hello from default"),_createElementVNode("div",null,"hello from div")]),"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")])})"#,
r#"_createVNode(_component_test_component,null,{default:_withCtx(()=>[_createTextVNode("hello from default"),_createElementVNode("div",null,"hello from div")]),"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")])})"#,
false,
);

Expand Down Expand Up @@ -1110,7 +1108,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),"default":_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),default:_withCtx(()=>[_createTextVNode("hello from component"),_createElementVNode("div",null,"hello from div")])})"#,
false,
);
}
Expand Down Expand Up @@ -1204,7 +1202,7 @@ mod tests {
patch_hints: Default::default(),
span: DUMMY_SP,
},
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),"default":_withCtx(()=>[_createTextVNode("hello from default"),_createElementVNode("div",null,"hello from div")]),baz:_withCtx(()=>[_createTextVNode("hello from baz")])})"#,
r#"_createVNode(_component_test_component,null,{"foo-bar":_withCtx(()=>[_createTextVNode("hello from slot")]),default:_withCtx(()=>[_createTextVNode("hello from default"),_createElementVNode("div",null,"hello from div")]),baz:_withCtx(()=>[_createTextVNode("hello from baz")])})"#,
false,
);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/fervid_codegen/src/directives/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use fervid_core::{CustomDirectiveBinding, FervidAtom, StrOrExpr, VueDirectives, VueImports};
use fervid_core::{str_to_propname, CustomDirectiveBinding, FervidAtom, StrOrExpr, VueDirectives, VueImports};
use swc_core::{
common::{Span, DUMMY_SP},
ecma::ast::{
Expand All @@ -7,7 +7,7 @@ use swc_core::{
},
};

use crate::{utils::str_to_propname, CodegenContext};
use crate::CodegenContext;

mod v_for;
mod v_html;
Expand Down
27 changes: 18 additions & 9 deletions crates/fervid_codegen/src/directives/v_model.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use fervid_core::{FervidAtom, StrOrExpr, VModelDirective};
use fervid_core::{
str_or_expr_to_propname, str_to_propname, FervidAtom, StrOrExpr, VModelDirective,
};
use swc_core::{
common::Span,
ecma::ast::{
Expand All @@ -7,10 +9,7 @@ use swc_core::{
},
};

use crate::{
context::CodegenContext,
utils::{str_or_expr_to_propname, str_to_propname, to_camelcase},
};
use crate::{context::CodegenContext, utils::to_camelcase};

impl CodegenContext {
/// Generates the `v-model` parts for a component:
Expand Down Expand Up @@ -40,7 +39,8 @@ impl CodegenContext {
}))));

// 3. Generate event handler propname
let event_handler_propname = generate_v_model_handler_propname(&bound_attribute, &mut buf, span);
let event_handler_propname =
generate_v_model_handler_propname(&bound_attribute, &mut buf, span);

// 4. Push the update code,
// e.g. `v-model="smth"` -> `"onUpdate:modelValue": $event => ((_ctx.smth) = $event)`
Expand Down Expand Up @@ -109,7 +109,11 @@ impl CodegenContext {

/// Generates the `v-model` for an element.
/// This generates the update handler
pub fn generate_v_model_for_element(&self, v_model: &VModelDirective, out: &mut Vec<PropOrSpread>) {
pub fn generate_v_model_for_element(
&self,
v_model: &VModelDirective,
out: &mut Vec<PropOrSpread>,
) {
let span = v_model.span;
let mut buf = String::new();

Expand All @@ -121,7 +125,8 @@ impl CodegenContext {
.unwrap_or_else(|| "modelValue".into());

// 2. Generate event handler propname
let event_handler_propname = generate_v_model_handler_propname(&bound_attribute, &mut buf, span);
let event_handler_propname =
generate_v_model_handler_propname(&bound_attribute, &mut buf, span);

// 3. Push the update handler code,
// e.g. `v-model="smth"` -> `"onUpdate:modelValue": $event => ((_ctx.smth) = $event)`
Expand All @@ -141,7 +146,11 @@ impl CodegenContext {
/// ## Examples
/// - `v-model="smth"` -> `"onUpdate:modelValue"`;
/// - `v-model:users-argument="smth"` -> `"onUpdate:usersArgument"`.
fn generate_v_model_handler_propname(bound_attribute: &StrOrExpr, buf: &mut String, span: Span) -> PropName {
fn generate_v_model_handler_propname(
bound_attribute: &StrOrExpr,
buf: &mut String,
span: Span,
) -> PropName {
match bound_attribute {
StrOrExpr::Str(ref s) => {
buf.reserve(9 + s.len());
Expand Down
59 changes: 1 addition & 58 deletions crates/fervid_codegen/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,4 @@
// to_ident_or_str

use std::fmt::{Write, Error};

use fervid_core::{FervidAtom, StrOrExpr};
use swc_core::{common::Span, ecma::ast::{ComputedPropName, Ident, EsReserved, IdentName, PropName, Str}};

/// Adapted from SWC Ident::verify_symbol
#[inline]
pub fn is_valid_ident(s: &str) -> bool {
if s.is_reserved() || s.is_reserved_in_strict_mode(true) || s.is_reserved_in_strict_bind() {
return false;
}

let mut chars = s.chars();

if let Some(first) = chars.next() {
if Ident::is_valid_start(first) && chars.all(Ident::is_valid_continue) {
return true;
}
}

false
}

pub fn str_to_propname(s: &str, span: Span) -> PropName {
if is_valid_ident(s) {
PropName::Ident(IdentName { span, sym: s.into() })
} else {
PropName::Str(Str {
span,
value: s.into(),
raw: None,
})
}
}

pub fn atom_to_propname(sym: FervidAtom, span: Span) -> PropName {
if is_valid_ident(&sym) {
PropName::Ident(IdentName { span, sym })
} else {
PropName::Str(Str {
span,
value: sym,
raw: None,
})
}
}

pub fn str_or_expr_to_propname(str_or_expr: StrOrExpr, span: Span) -> PropName {
match str_or_expr {
StrOrExpr::Str(sym) => atom_to_propname(sym, span),
StrOrExpr::Expr(expr) => PropName::Computed(ComputedPropName {
span,
expr,
}),
}
}
use std::fmt::{Error, Write};

pub fn to_camelcase(s: &str, buf: &mut impl Write) -> Result<(), Error> {
for (idx, word) in s.split('-').enumerate() {
Expand Down
Loading

0 comments on commit 93aaafd

Please sign in to comment.