pochoir-extra 0.12.2

Extra utilities for the pochoir template engine
Documentation
//! A collection of extra tools to transform components.
//!
//! - [CSS enhancer](`EnhancedCss`): used to apply various transforms to `<style>` CSS elements, support scoped CSS, CSS nesting, CSS minification, CSS autoprefixer and polyfiller
//! - [Accessibility checker](`AccessibilityChecker`) used to check the accessibility of the page in real time in debug mode
#![doc(html_logo_url = "https://gitlab.com/encre-org/pochoir/raw/main/.assets/logo.png")]
#![forbid(unsafe_code)]
#![warn(
    missing_docs,
    missing_debug_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unused_qualifications,
    rustdoc::private_doc_tests,
    rustdoc::broken_intra_doc_links,
    rustdoc::private_intra_doc_links,
    clippy::unnecessary_wraps,
    clippy::too_many_lines,
    clippy::string_to_string,
    clippy::explicit_iter_loop,
    clippy::unnecessary_cast,
    clippy::missing_errors_doc,
    clippy::pedantic,
    clippy::clone_on_ref_ptr,
    clippy::non_ascii_literal,
    clippy::dbg_macro,
    clippy::map_err_ignore,
    clippy::use_debug,
    clippy::map_err_ignore,
    clippy::use_self,
    clippy::useless_let_if_seq,
    clippy::verbose_file_reads,
    clippy::panic,
    clippy::unimplemented,
    clippy::todo
)]
#![allow(clippy::module_name_repetitions, clippy::must_use_candidate)]
pub mod accessibility_checker;
pub mod enhanced_css;

pub use accessibility_checker::AccessibilityChecker;
pub use enhanced_css::{EnhancedCss, EnhancedCssBundler};

#[cfg(test)]
mod tests {
    use std::path::Path;

    use super::*;
    use enhanced_css::CssBundle;
    use pochoir::{component_not_found, lang::Context, transformers::Transformers, ComponentFile};
    use pretty_assertions::assert_eq;

    const FILES: &[(&str, &str, &str)] = &[
        (
            "index",
            "index.html",
            "
        <h1>Title of the page</h1>
        <main>
            <h3>Section title</h3>
            <p>Page content</p>
            <my-component />
        </main>
        <style enhanced>
        main {
            text-size: 18px;
            font-weight: extrabold;
            padding: 1rem 4rem;

            & p {
                color: green;
            }
        }
        h3 {
            text-size: 22px;
        }
        </style>
        <style>
        html, body {
            width: 100%;
            height: 100%;
        }
        </style>",
        ),
        (
            "my-component",
            "my-component.html",
            "
            <h3>A button</h3>
            <button>My button</button>
            <style enhanced>
            button {
                background-color: red;
            }
            button {
                border-radius: 12px;
            }
            h3 {
                text-size: 24px;
            }
            </style>",
        ),
    ];

    #[test]
    fn enhanced_css() {
        let mut transformers = Transformers::new().with_transformer(EnhancedCss::new());

        let compiled = pochoir::transform_and_compile(
            "index",
            &mut Context::new(),
            |name| {
                if let Some((_, file_path, file_content)) = FILES.iter().find(|f| f.0 == name) {
                    Ok(ComponentFile::new(
                        Path::new(&file_path).to_owned(),
                        *file_content,
                    ))
                } else {
                    Err(component_not_found(name))
                }
            },
            &mut transformers,
        )
        .unwrap();

        assert_eq!(compiled, "
        <h1 data-p-fd1ea890>Title of the page</h1>
        <main data-p-fd1ea890>
            <h3 data-p-fd1ea890>Section title</h3>
            <p data-p-fd1ea890>Page content</p>
            
            <h3 data-p-3e518db5>A button</h3>
            <button data-p-3e518db5>My button</button>
            <style>button:where([data-p-3e518db5]){background-color:red}button:where([data-p-3e518db5]){border-radius:12px}h3:where([data-p-3e518db5]){text-size:24px}</style>
        </main>
        
        <style>
        html, body {
            width: 100%;
            height: 100%;
        }
        </style><style>main:where([data-p-fd1ea890]){text-size:18px;font-weight:extrabold;padding:1rem 4rem}main:where([data-p-fd1ea890]) p:where([data-p-fd1ea890]){color:green}h3:where([data-p-fd1ea890]){text-size:22px}</style>".to_string());
    }

    #[test]
    fn enhanced_css_bundle() {
        let mut css_bundle = CssBundle::new();
        let mut transformers =
            Transformers::new().with_transformer(EnhancedCssBundler::new(&mut css_bundle));

        let compiled = pochoir::transform_and_compile(
            "index",
            &mut Context::new(),
            |name| {
                if let Some((_, file_path, file_content)) = FILES.iter().find(|f| f.0 == name) {
                    Ok(ComponentFile::new(
                        Path::new(&file_path).to_owned(),
                        *file_content,
                    ))
                } else {
                    Err(component_not_found(name))
                }
            },
            &mut transformers,
        )
        .unwrap();

        drop(transformers);
        assert_eq!(
            compiled,
            "
        <h1 data-p-fd1ea890>Title of the page</h1>
        <main data-p-fd1ea890>
            <h3 data-p-fd1ea890>Section title</h3>
            <p data-p-fd1ea890>Page content</p>
            
            <h3 data-p-3e518db5>A button</h3>
            <button data-p-3e518db5>My button</button>
            
        </main>
        
        <style>
        html, body {
            width: 100%;
            height: 100%;
        }
        </style>"
                .to_string()
        );
        assert_eq!(css_bundle.finish().unwrap(), "main:where([data-p-fd1ea890]){text-size:18px;font-weight:extrabold;padding:1rem 4rem}main:where([data-p-fd1ea890]) p:where([data-p-fd1ea890]){color:green}h3:where([data-p-fd1ea890]){text-size:22px}button:where([data-p-3e518db5]){background-color:red}button:where([data-p-3e518db5]){border-radius:12px}h3:where([data-p-3e518db5]){text-size:24px}".to_string());
    }
}