fml 0.6.5

Friendly Markup Language
Documentation
use proc_macros::{make_delimits_tests, make_headings_tests};

use crate::ast::{
    Content,
    FmlValue::{self, *},
    Section,
};

#[test]
fn nonesc_backslash() {
    let txt = r"sample \x text";
    let fml = crate::parse(txt).expect("failed to parse");

    assert_eq!(
        fml,
        Content(vec![Section(vec![Text(r"sample \x text".into())].into())])
    )
}

make_delimits_tests! {
    mod @{Name} {
        use crate::ast::{
            Content,
            FmlValue::{self, *},
            Section,
        };

        #[test]
        fn normal() {
            let txt = "@{Delim}sample text@{Delim}";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                fml,
                Content(vec![Section(
                    vec![@{CS}Text("sample text".into())@{CE}].into()
                )])
            )
        }

        #[test]
        fn whitespace() {
            let txt = "@{Delim}	sample text @{Delim}";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                fml,
                Content(vec![Section(
                    vec![@{CS}Text("	sample text ".into())@{CE}].into()
                )])
            )
        }

        #[test]
        fn multiline() {
            let txt = r"@{Delim}
sample text
@{Delim}";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                fml,
                Content(vec![Section(
                    vec![@{CS}Linebreak, Text("sample text".into()), Linebreak@{CE}].into()
                )])
            )
        }

        #[test]
        fn uses_nearest() {
            let txt = r"@{Delim}@{Delim}sample text@{Delim}@{Delim}";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                fml,
                Content(vec![Section(
                    vec![Text("@{Delim}".into()), @{CS}Text("sample text".into())@{CE}, Text("@{Delim}".into())].into()
                )])
            )
        }

        mod esc {
            use super::*;

            #[test]
            fn start() {
                let txt = r"\@{Delim}sample text@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text("@{Delim}sample text@{Delim}".into())].into()
                    )])
                )
            }

            #[test]
            fn end() {
                let txt = r"@{Delim}sample text\@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text("@{Delim}sample text@{Delim}".into())].into()
                    )])
                )
            }

            #[test]
            fn double_start() {
                let txt = r"\\@{Delim}sample text@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text(r"\".into()), @{CS}Text("sample text".into())@{CE}].into()
                    )])
                )
            }

            #[test]
            fn double_end() {
                let txt = r"@{Delim}sample text\\@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![@{CS}Text(r"sample text\".into())@{CE}].into()
                    )])
                )
            }
        }

        mod empty {
            use super::*;

            #[test]
            fn touching() {
                let txt = r"@{Delim}@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text(r"@{Delim}@{Delim}".into())].into()
                    )])
                )
            }

            #[test]
            fn whitespace() {
                let txt = r"@{Delim}	 @{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text(r"@{Delim}	 @{Delim}".into())].into()
                    )])
                )
            }

            #[test]
            fn multiline() {
                let txt = r"@{Delim}
@{Delim}";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                    fml,
                    Content(vec![Section(
                        vec![Text(r"@{Delim}".into()), Linebreak, Text("@{Delim}".into())].into()
                    )])
                )
            }
        }
    }
}

make_headings_tests! {
    mod @{Name} {
        use crate::ast::{
            Content,
            FmlValue::{self, *},
            Section,
        };

        #[test]
        fn normal() {
            let txt = r"@{Pat} Lorem ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        @{CS}Text("Lorem ipsum".into())@{CE}
                    ].into())])
                )
        }

        #[test]
        fn normal_alt() {
            let txt = r"Lorem
@{Pat} ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        Text("Lorem".into()),
                        @{CS}Text("ipsum".into())@{CE}
                    ].into())])
                )
        }

        #[test]
        fn alternative_whitespace() {
            let txt = r"@{Pat}	  	Lorem ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        @{CS}Text("Lorem ipsum".into())@{CE}
                    ].into())])
                )
        }

        #[test]
        // #[ignore] // FIXME:
        fn explicit_multiline() {
            let txt = r"@{Pat} Lorem\
ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        @{CS}Text("Lorem".into()), Linebreak, Text("ipsum".into())@{CE},
                    ].into())])
                )
        }

        #[test]
        fn esc() {
            let txt = r"\@{Pat} Lorem ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        Text("@{Pat} Lorem ipsum".into()),
                    ].into())])
                )
        }

        #[test]
        fn double_esc_no_sol() {
            let txt = r"\\@{Pat} Lorem ipsum";
            let fml = crate::parse(txt).expect("failed to parse");

            assert_eq!(
                    fml,
                    Content(vec![Section(vec![
                        Text(r"\@{Pat} Lorem ipsum".into()),
                    ].into())])
                )
        }

        mod fails {
            use super::*;

            #[test]
            fn no_start_of_line() {
                let txt = r"Lorem@{Pat} ipsum";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                        fml,
                        Content(vec![Section(vec![
                            Text("Lorem@{Pat} ipsum".into())
                        ].into())])
                    )
            }

            #[test]
            fn no_start_of_line_alt() {
                // Please mind the space after the newline
                let txt = r"Lorem
 @{Pat} ipsum";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                        fml,
                        Content(vec![Section(vec![
                            Text("Lorem".into()),
                            Linebreak,
                            Text(" @{Pat} ipsum".into())
                        ].into())])
                    )
            }

            #[test]
            fn no_whitespace() {
                let txt = r"@{Pat}Lorem ipsum";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                        fml,
                        Content(vec![Section(vec![
                            Text("@{Pat}Lorem ipsum".into())
                        ].into())])
                    )
            }

            #[test]
            fn multiline() {
                let txt = r"@{Pat} Lorem
ipsum";
                let fml = crate::parse(txt).expect("failed to parse");

                assert_eq!(
                        fml,
                        Content(vec![Section(vec![
                            @{CS}Text("Lorem".into())@{CE},
                            Text("ipsum".into())
                        ].into())])
                    )
            }
        }
    }
}