fix(css/modules): Allow out-of-order class names for composes (#8218)

**Related issue:**

 - Closes #7910
This commit is contained in:
Donny/강동윤 2023-11-04 10:35:59 +09:00 committed by GitHub
parent cb29fdd1f4
commit aeb9cafd11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 45 deletions

9
Cargo.lock generated
View File

@ -3250,9 +3250,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.188"
version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
dependencies = [
"serde_derive",
]
@ -3280,9 +3280,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.188"
version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
dependencies = [
"proc-macro2",
"quote",
@ -5451,6 +5451,7 @@ dependencies = [
"once_cell",
"pretty_assertions",
"regex",
"serde",
"serde_json",
"swc_common",
"swc_error_reporters",

View File

@ -307,13 +307,23 @@ where
}
}
for class_name in n.value.iter() {
for class_name in n.value.iter_mut() {
if let ComponentValue::Ident(box Ident { span, value, .. }) = class_name {
if let Some(value) = self.data.orig_to_renamed.get(value) {
let orig = value.clone();
rename(
*span,
&mut self.config,
&mut self.result,
&mut self.data.orig_to_renamed,
&mut self.data.renamed_to_orig,
value,
);
if let Some(new_name) = self.data.orig_to_renamed.get(&orig) {
composes_for_current.push(CssClassName::Local {
name: Ident {
span: *span,
value: value.clone(),
value: new_name.clone(),
raw: None,
},
});

View File

@ -32,13 +32,13 @@ fn imports(input: PathBuf) {
return Ok(());
}
let s = serde_json::to_string_pretty(&result).unwrap();
NormalizedOutput::from(s)
.compare_to_file(input.with_file_name(format!(
NormalizedOutput::compare_json_to_file(
&result,
&input.with_file_name(format!(
"{}.imports.json",
input.file_stem().unwrap().to_string_lossy()
)))
.unwrap();
)),
);
Ok(())
})
@ -89,41 +89,39 @@ fn compile(input: PathBuf) {
.unwrap();
if !transform_result.renamed.is_empty() {
let transformed_classes = serde_json::to_string_pretty(
&transform_result
.renamed
.into_iter()
.map(|(k, v)| {
(
k,
v.into_iter()
.map(|v| match v {
CssClassName::Global { name } => {
CssClassNameForTest::Global { name: name.value }
let transformed_classes = &transform_result
.renamed
.into_iter()
.map(|(k, v)| {
(
k,
v.into_iter()
.map(|v| match v {
CssClassName::Global { name } => {
CssClassNameForTest::Global { name: name.value }
}
CssClassName::Local { name } => {
CssClassNameForTest::Local { name: name.value }
}
CssClassName::Import { name, from } => {
CssClassNameForTest::Import {
name: name.value,
from,
}
CssClassName::Local { name } => {
CssClassNameForTest::Local { name: name.value }
}
CssClassName::Import { name, from } => {
CssClassNameForTest::Import {
name: name.value,
from,
}
}
})
.collect::<Vec<_>>(),
)
})
.collect::<FxHashMap<_, _>>(),
)
.unwrap();
}
})
.collect::<Vec<_>>(),
)
})
.collect::<FxHashMap<_, _>>();
NormalizedOutput::from(transformed_classes)
.compare_to_file(input.with_file_name(format!(
NormalizedOutput::compare_json_to_file(
&transformed_classes,
&input.with_file_name(format!(
"{}.transform.json",
input.file_stem().unwrap().to_string_lossy()
)))
.unwrap();
)),
);
}
Ok(())
})

View File

@ -0,0 +1,7 @@
.__local__child-class1 {
color: red;
}
.__local__root-class {}
.__local__child-class2 {
color: green;
}

View File

@ -0,0 +1,10 @@
.child-class1 {
color: red;
}
.root-class {
composes: child-class1;
composes: child-class2;
}
.child-class2 {
color: green;
}

View File

@ -0,0 +1,28 @@
{
"child-class1": [
{
"type": "local",
"name": "__local__child-class1"
}
],
"root-class": [
{
"type": "local",
"name": "__local__root-class"
},
{
"type": "local",
"name": "__local__child-class1"
},
{
"type": "local",
"name": "__local__child-class2"
}
],
"child-class2": [
{
"type": "local",
"name": "__local__child-class2"
}
]
}

View File

@ -18,7 +18,8 @@ difference = "2"
once_cell = "1.18.0"
pretty_assertions = "1.3"
regex = "1"
serde_json = "1.0.71"
serde = "1"
serde_json = "1"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }

View File

@ -1,11 +1,12 @@
use std::{
env, fmt,
fs::{create_dir_all, File},
fs::{self, create_dir_all, File},
io::Read,
ops::Deref,
path::Path,
};
use serde::Serialize;
use tracing::debug;
use crate::paths;
@ -102,6 +103,28 @@ impl NormalizedOutput {
NormalizedOutput(normalize_input(s, true))
}
pub fn compare_json_to_file<T>(actual: &T, path: &Path)
where
T: Serialize,
{
let actual_value =
serde_json::to_value(actual).expect("failed to serialize the actual value to json");
if let Ok(expected) = fs::read_to_string(path) {
let expected_value = serde_json::from_str::<serde_json::Value>(&expected)
.expect("failed to deserialize the expected value from json");
if expected_value == actual_value {
return;
}
}
let actual_json_string = serde_json::to_string_pretty(&actual_value)
.expect("failed to serialize the actual value to json");
let _ = NormalizedOutput::from(actual_json_string).compare_to_file(path);
}
/// If output differs, prints actual stdout/stderr to
/// `CARGO_MANIFEST_DIR/target/swc-test-results/ui/$rel_path` where
/// `$rel_path`: `path.strip_prefix(CARGO_MANIFEST_DIR)`