Skip to content

Commit

Permalink
Merge pull request #101 from Rolv-Apneseth/add_tests
Browse files Browse the repository at this point in the history
Additional sorting tests
  • Loading branch information
praveenperera authored Apr 15, 2024
2 parents 3c7c9a6 + ac81242 commit ca0c5ba
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 301 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions rustywind-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ aho-corasick = "1.0"

[dev-dependencies]
pretty_assertions = "1.4"
test-case = "3.3.1"
303 changes: 275 additions & 28 deletions rustywind-core/src/sorter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,32 +162,279 @@ fn sort_variant_classes<'a>(
}

#[cfg(test)]
use pretty_assertions::assert_eq;

#[test]
fn test_sort_classes_vec() {
assert_eq!(
sort_classes_vec(
vec![
"inline",
"inline-block",
"random-class",
"py-2",
"justify-end",
"px-2",
"flex"
]
.into_iter(),
&SORTER
),
vec![
"inline-block",
"inline",
"flex",
"justify-end",
"py-2",
"px-2",
"random-class",
]
)
mod tests {
use super::*;
use pretty_assertions::assert_eq;
use test_case::test_case;

const OPTS_DEFAULT: Options = Options {
regex: FinderRegex::DefaultRegex,
sorter: Sorter::DefaultSorter,
allow_duplicates: false,
};

// HAS_CLASSES --------------------------------------------------------------------------------
#[test_case( r#"<div class="flex-col inline flex"></div>"#, true ; "div tag with class")]
#[test_case( r#"<body class="unknown-class"></body>"#, true ; "body tag with unknown class")]
#[test_case( r#"<p className="unknown-class"></p>"#, true ; "p tag with unknown class")]
#[test_case( r#"<p>not a class</p>"#, false ; "p tag with no class")]
#[test_case( r#"<div><p></p><p></p></div>"#, false ; "nested tags, no class")]
#[test_case( r#"<div><p><span className="inline"></span></p><p></p></div>"#, true ; "nested tags, class in child")]
fn test_has_classes(input: &str, output: bool) {
assert_eq!(has_classes(input, &OPTS_DEFAULT), output);
}

// SORT_CLASSES_VEC ---------------------------------------------------------------------------
#[test_case(
["inline", "inline-block", "random-class", "shadow-sm", "py-2", "justify-end", "px-2", "flex"],
vec!["inline-block", "inline", "flex", "justify-end", "py-2", "px-2", "shadow-sm", "random-class"]
; "classes inline inline-block random-class shadow-sm py-2 justify-end px-2 flex"
)]
#[test_case(
["bg-purple", "text-white", "unknown-class", "flex-col", "gap-4", "flex", "skew-y-0"],
vec!["flex", "flex-col", "gap-4", "text-white", "skew-y-0", "bg-purple", "unknown-class"]
; "classes bg-purple text-white unknown-class flex-col gap-4 flex skew-y-0"
)]
#[test_case(
["translate-x-7", "bg-orange-200", "unknown-class", "static", "top-5", "flex", "items-center"],
vec!["flex", "static", "top-5", "items-center", "bg-orange-200", "translate-x-7", "unknown-class"]
; "classes translate-x-7 bg-orange-200 unknown-class static top-5 flex items-center"
)]
fn test_sort_classes_vec<'a>(input: impl IntoIterator<Item = &'a str>, output: Vec<&str>) {
assert_eq!(sort_classes_vec(input.into_iter(), &SORTER), output)
}

// SORT_FILE_CONTENTS -------------------------------------------------------------------------
// BASIC, SINGLE ELEMENT TESTS
#[test_case(
&OPTS_DEFAULT,
r#"<div class="py-2 inline random-class shadow-sm"></div>"#,
r#"<div class="inline py-2 shadow-sm random-class"></div>"#
; "div tag using class"
)]
#[test_case(
&OPTS_DEFAULT,
r#"<section className="inline lg:inline-block abcd py-2"></section>"#,
r#"<section className="inline py-2 lg:inline-block abcd"></section>"#
; "section tag using className"
)]
#[test_case(
&OPTS_DEFAULT,
r#"<p class="unknown-class bg-blue-300 py-2 object-top">content</p>"#,
r#"<p class="object-top py-2 bg-blue-300 unknown-class">content</p>"#
; "p tag using class"
)]
#[test_case(
&OPTS_DEFAULT,
r#"<p className="py-2 py-2 random-class underline underline underline">text</p>"#,
r#"<p className="py-2 underline random-class">text</p>"#
; "p tag remove duplicates"
)]
#[test_case(
&Options { allow_duplicates: true, ..OPTS_DEFAULT},
r#"<section className="inline py-2 py-2 random-class italic italic italic"></section>"#,
r#"<section className="inline py-2 py-2 italic italic italic random-class"></section>"#
; "section tag keeps duplicates if bool set"
)]
// BASE
#[test_case(
&OPTS_DEFAULT,
r#"
<div>
<div class='mt-4 mb-0.5 flex inline-block inline px-0.5 pt-10 random-class justify-items absolute relative another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#,
r#"
<div>
<div class='inline-block inline flex absolute relative px-0.5 pt-10 mt-4 mb-0.5 random-class justify-items another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#
; "sorts classes"
)]
#[test_case(
&OPTS_DEFAULT,
r#"
<div>
<div class='4xl:inline-block absolute xl:relative relative flex inline-block xl:absolute sm:relative sm:flex inline random-class justify-items another-random-class
sm:absolute 4xl:flex xl:random-class sm:inline-block'>
<ul class='flex items-center md:pr-4 lg:pr-6 xl:flex'>
</div>
</div>
"#,
r#"
<div>
<div class='inline-block inline flex absolute relative sm:inline-block sm:flex sm:absolute sm:relative xl:absolute xl:relative 4xl:inline-block 4xl:flex random-class justify-items another-random-class xl:random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6 xl:flex'>
</div>
</div>
"#
; "sorts responsive classes"
)]
#[test_case(
&OPTS_DEFAULT,
r#"
<div>
<div class='even:inline 4xl:inline-block focus-visible:flex absolute xl:relative relative focus:flex flex active:flex disabled:flex visited:flex inline-block dark:absolute sm:relative sm:flex inline random-class justify-items another-random-class
sm:absolute 4xl:flex xl:random-class sm:inline-block'>
<ul class='flex items-center md:pr-4 lg:pr-6 xl:flex'>
</div>
</div>
"#,
r#"
<div>
<div class='inline-block inline flex absolute relative sm:inline-block sm:flex sm:absolute sm:relative xl:relative 4xl:inline-block 4xl:flex dark:absolute even:inline visited:flex focus:flex focus-visible:flex active:flex disabled:flex random-class justify-items another-random-class xl:random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6 xl:flex'>
</div>
</div>
"#
; "sorts variant classes"
)]
// DUPLICATES
#[test_case(
&OPTS_DEFAULT,
r#"
<div>
<div class='absolute relative flex flex flex flex inline-block inline random-class justify-items another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#,
r#"
<div>
<div class='inline-block inline flex absolute relative random-class justify-items another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#
; "removes duplicates"
)]
#[test_case(
&Options { allow_duplicates: true, ..OPTS_DEFAULT},
r#"
<div>
<div class='absolute relative flex flex flex flex inline-block inline random-class justify-items another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#,
r#"
<div>
<div class='inline-block inline flex flex flex flex absolute relative random-class justify-items another-random-class'>
<ul class='flex items-center md:pr-4 lg:pr-6'>
</ul>
</div>
</div>
"#
; "keeps duplicates if bool set"
)]
// MULTI-LINE AND OTHER SPACING
// Note the intentionally poor spacing. Rustywind isn't concerned so much about formatting, but
// due to how whitespace is handled, it all ends up on one line as a side effect. This makes it
// easier for formatters like Prettier to do their job.
#[test_case(
&OPTS_DEFAULT,
r#"
<div
class="
grid
border
fixed
top-0
right-0
z-20
grid-flow-col
gap-2
justify-start
my-12
mx-8
text-red-800
bg-red-50
rounded
border-red-100
shadow-2xl
"
>
<!-- ... -->
</div>
"#,
r#"
<div
class="grid fixed top-0 right-0 z-20 grid-flow-col gap-2 justify-start my-12 mx-8 text-red-800 bg-red-50 rounded border border-red-100 shadow-2xl"
>
<!-- ... -->
</div>
"#
; "sorts and formats multiline class list"
)]
#[test_case(
&OPTS_DEFAULT,
r#"
<div
class="
grid border fixed
top-0
right-0
z-20
grid-flow-col
gap-2
justify-start
my-12 mx-8 text-red-800
bg-red-50
rounded
border-red-100
shadow-2xl
"
>
<!-- ... -->
</div>
"#,
r#"
<div
class="grid fixed top-0 right-0 z-20 grid-flow-col gap-2 justify-start my-12 mx-8 text-red-800 bg-red-50 rounded border border-red-100 shadow-2xl"
>
<!-- ... -->
</div>
"#
; "sorts and formats multiline and space separated class list"
)]
#[test_case(
&OPTS_DEFAULT,
r#"
<div class="m-2 grid-cols-4
gap-1 foo
border theres-a-tab-here: bar border-red-600
">
</div>
"#,
r#"
<div class="grid-cols-4 gap-1 m-2 border border-red-600 foo theres-a-tab-here: bar">
</div>
"#
; "sorts and formats multiline and space separated class list, with custom classes"
)]
// NO CLASSES
#[test_case(
&OPTS_DEFAULT,
r#"This is to represent any other normal file."#,
r#"This is to represent any other normal file."#
; "makes no change to files without class string"
)]
#[test_case(
&OPTS_DEFAULT,
r#"<div><p><img height="100" width="250" /></p><p></p></div>"#,
r#"<div><p><img height="100" width="250" /></p><p></p></div>"#
; "makes no change to elements without class string"
)]
fn test_sort_file_contents(opts: &Options, input: &str, output: &str) {
assert_eq!(sort_file_contents(input, opts), output);
}
}
Loading

0 comments on commit ca0c5ba

Please sign in to comment.