Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions crates/rspack_core/src/dependency/dependency_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ pub enum DependencyType {
DllEntry,
DelegatedSource,
ExtractCSS,
Rstest,
RstestModulePath,
RstestMockModuleId,
RstestHoistMock,
}

impl DependencyType {
Expand Down Expand Up @@ -191,7 +193,9 @@ impl DependencyType {
DependencyType::ModuleDecorator => "module decorator",
DependencyType::DelegatedSource => "delegated source",
DependencyType::ExtractCSS => "extract css",
DependencyType::Rstest => "rstest",
DependencyType::RstestModulePath => "rstest module path",
DependencyType::RstestMockModuleId => "rstest mock module id",
DependencyType::RstestHoistMock => "rstest hoist mock",
}
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/rspack_core/src/init_fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub enum InitFragmentKey {
ModuleDecorator(String /* module_id */),
ESMFakeNamespaceObjectFragment(String),
Const(String),
// ModuleName(String),
}

impl InitFragmentKey {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,11 @@ async fn compilation(
RuntimeRequirementsDependencyTemplate::template_type(),
Arc::new(RuntimeRequirementsDependencyTemplate::default()),
);
// Rstest
compilation.set_dependency_factory(
DependencyType::RstestMockModuleId,
params.normal_module_factory.clone(),
);
Ok(())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ pub struct JavascriptParser<'parser> {
pub(crate) current_tag_info: Option<TagInfoId>,
pub(crate) local_modules: Vec<LocalModule>,
// ===== scope info =======
pub(crate) in_try: bool,
pub in_try: bool,
pub(crate) in_short_hand: bool,
pub(super) definitions: ScopeInfoId,
pub(crate) top_level_scope: TopLevelScope,
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_plugin_rstest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ version = "0.2.0"

[dependencies]
async-trait = { workspace = true }
regex = { workspace = true }
rspack_cacheable = { workspace = true }
rspack_core = { workspace = true }
rspack_error = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_plugin_rstest/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#![feature(let_chains)]
mod mock_hoist_dependency;
mod mock_module_id_dependency;
mod module_path_name_dependency;
mod parser_plugin;
mod plugin;
Expand Down
93 changes: 93 additions & 0 deletions crates/rspack_plugin_rstest/src/mock_hoist_dependency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use rspack_cacheable::{cacheable, cacheable_dyn, with::Skip};
use rspack_core::{
AsContextDependency, AsModuleDependency, DependencyCodeGeneration, DependencyRange,
DependencyTemplate, DependencyTemplateType, DependencyType, InitFragmentExt, InitFragmentKey,
InitFragmentStage, NormalInitFragment, TemplateContext, TemplateReplaceSource,
};
use swc_core::common::Span;

#[cacheable]
#[derive(Debug, Clone)]
pub struct MockHoistDependency {
#[cacheable(with=Skip)]
call_expr_span: Span,
#[cacheable(with=Skip)]
callee_span: Span,
request: String,
}

impl MockHoistDependency {
pub fn new(call_expr_span: Span, callee_span: Span, request: String) -> Self {
Self {
call_expr_span,
callee_span,
request,
}
}
}

#[cacheable_dyn]
impl DependencyCodeGeneration for MockHoistDependency {
fn dependency_template(&self) -> Option<DependencyTemplateType> {
Some(MockHoistDependencyTemplate::template_type())
}
}

impl AsModuleDependency for MockHoistDependency {}
impl AsContextDependency for MockHoistDependency {}

#[cacheable]
#[derive(Debug, Clone, Default)]
pub struct MockHoistDependencyTemplate;

impl MockHoistDependencyTemplate {
pub fn template_type() -> DependencyTemplateType {
DependencyTemplateType::Dependency(DependencyType::RstestHoistMock)
}
}

impl DependencyTemplate for MockHoistDependencyTemplate {
fn render(
&self,
dep: &dyn DependencyCodeGeneration,
source: &mut TemplateReplaceSource,
code_generatable_context: &mut TemplateContext,
) {
let TemplateContext { init_fragments, .. } = code_generatable_context;

let dep = dep
.as_any()
.downcast_ref::<MockHoistDependency>()
.expect("ModulePathNameDependencyTemplate can only be applied to ModulePathNameDependency");
let request = &dep.request;

// Placeholder of hoist target.
let init = NormalInitFragment::new(
format!("/* RSTEST:MOCK_PLACEHOLDER:{request} */;"),
InitFragmentStage::StageConstants,
0,
InitFragmentKey::Const(format!("retest mock_hoist {request}")),
None,
);

// Start before hoist.
let callee_range: DependencyRange = dep.callee_span.into();
source.replace(
callee_range.start,
callee_range.end,
format!("/* RSTEST:MOCK_HOIST_START:{request} */__webpack_require__.set_mock").as_ref(),
None,
);

// End before hoist.
let range: DependencyRange = dep.call_expr_span.into();
source.replace(
range.end, // count the trailing semicolon
range.end,
format!("/* RSTEST:MOCK_HOIST_END:{request} */").as_ref(),
None,
);

init_fragments.push(init.boxed());
}
}
147 changes: 147 additions & 0 deletions crates/rspack_plugin_rstest/src/mock_module_id_dependency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use rspack_cacheable::{cacheable, cacheable_dyn};
use rspack_core::{
module_id, AsContextDependency, Dependency, DependencyCategory, DependencyCodeGeneration,
DependencyId, DependencyRange, DependencyTemplate, DependencyTemplateType, DependencyType,
ExtendedReferencedExport, FactorizeInfo, ModuleDependency, ModuleGraph, RuntimeSpec,
TemplateContext, TemplateReplaceSource,
};

#[cacheable]
#[derive(Debug, Clone)]
pub struct MockModuleIdDependency {
pub id: DependencyId,
pub request: String,
pub weak: bool,
range: DependencyRange,
optional: bool,
factorize_info: FactorizeInfo,
category: DependencyCategory,
}

impl MockModuleIdDependency {
pub fn new(
request: String,
range: DependencyRange,
weak: bool,
optional: bool,
category: DependencyCategory,
) -> Self {
Self {
range,
request,
weak,
optional,
id: DependencyId::new(),
factorize_info: Default::default(),
category,
}
}
}

#[cacheable_dyn]
impl Dependency for MockModuleIdDependency {
fn id(&self) -> &DependencyId {
&self.id
}

fn category(&self) -> &DependencyCategory {
&self.category
}

fn dependency_type(&self) -> &DependencyType {
&DependencyType::RstestMockModuleId
}

fn range(&self) -> Option<&DependencyRange> {
Some(&self.range)
}

fn get_referenced_exports(
&self,
_module_graph: &ModuleGraph,
_runtime: Option<&RuntimeSpec>,
) -> Vec<ExtendedReferencedExport> {
vec![]
}

fn could_affect_referencing_module(&self) -> rspack_core::AffectType {
rspack_core::AffectType::True
}
}

#[cacheable_dyn]
impl ModuleDependency for MockModuleIdDependency {
fn request(&self) -> &str {
&self.request
}

fn user_request(&self) -> &str {
&self.request
}

fn weak(&self) -> bool {
self.weak
}

fn get_optional(&self) -> bool {
self.optional
}

fn set_request(&mut self, request: String) {
self.request = request;
}

fn factorize_info(&self) -> &FactorizeInfo {
&self.factorize_info
}

fn factorize_info_mut(&mut self) -> &mut FactorizeInfo {
&mut self.factorize_info
}
}

#[cacheable_dyn]
impl DependencyCodeGeneration for MockModuleIdDependency {
fn dependency_template(&self) -> Option<DependencyTemplateType> {
Some(MockModuleIdDependencyTemplate::template_type())
}
}

impl AsContextDependency for MockModuleIdDependency {}

#[cacheable]
#[derive(Debug, Clone, Default)]
pub struct MockModuleIdDependencyTemplate;

impl MockModuleIdDependencyTemplate {
pub fn template_type() -> DependencyTemplateType {
DependencyTemplateType::Dependency(DependencyType::RstestMockModuleId)
}
}

impl DependencyTemplate for MockModuleIdDependencyTemplate {
fn render(
&self,
dep: &dyn DependencyCodeGeneration,
source: &mut TemplateReplaceSource,
code_generatable_context: &mut TemplateContext,
) {
let dep = dep
.as_any()
.downcast_ref::<MockModuleIdDependency>()
.expect("MockModuleIdDependencyTemplate should only be used for MockModuleIdDependency");

source.replace(
dep.range.start,
dep.range.end,
module_id(
code_generatable_context.compilation,
&dep.id,
&dep.request,
dep.weak,
)
.as_str(),
None,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct ModulePathNameDependencyTemplate;

impl ModulePathNameDependencyTemplate {
pub fn template_type() -> DependencyTemplateType {
DependencyTemplateType::Dependency(DependencyType::Rstest)
DependencyTemplateType::Dependency(DependencyType::RstestModulePath)
}
}

Expand Down
Loading
Loading