//Copyright (c) 2020 Stefan Thesing // //This file is part of libzettels. // //libzettels is free software: you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation, either version 3 of the License, or //(at your option) any later version. // //libzettels is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with libzettels. If not, see http://www.gnu.org/licenses/. //! Markdown links have several edge cases, especially when parentheses //! (round brackets) and/or square brackets are present in and around //! the hyperlink. //! These tests try to ensure that libzettels indexing is able to handle //! all edge cases that still are valid markdown. // -------------------------------------------------------------------------- extern crate libzettels; extern crate tempfile; use self::tempfile::tempdir; use libzettels::{Config, Error, Index, IndexingMethod}; use libzettels::examples::*; use std::fs::File; use std::io::Write; const FILE_BOILERPLATE: &str = "--- title: 'Edge cases of inline markdown link syntax' keywords: [] followups: [] ... No matter which indexing method the user chooses, the following should not break things: "; fn boilerplate(method: IndexingMethod, file_content: &str) -> Result{ let tmp_dir = tempdir().expect("Failed to setup temp dir"); let dir = tmp_dir.path(); generate_bare_examples(dir).expect("Failed to generate examples"); let rootdir = dir.join("examples/Zettelkasten"); let mut dummy_file = File::create(rootdir.join("f(o)o.md")) .expect("Failed to create dummy file with parentheses in filename."); // write minimal stuff to the dummy file, just to be sure. writeln!(dummy_file, "{}", "foo").expect("Failed to write to file"); let mut parentheses_file = File::create( rootdir.join("test_file.md") ).expect("Failed to create temporary file."); writeln!(parentheses_file, "{}", FILE_BOILERPLATE) .expect("Failed to write to temporary file."); writeln!(parentheses_file, "{}", file_content) .expect("Failed to write to temporary file."); let mut cfg = Config::new(rootdir.to_str().unwrap(), "foo"); cfg.indexingmethod = method; Index::new(&cfg) } // ------------------------------------------------------------------------- // Tests // ------------------------------------------------------------------------- // Links followed by parentheses const PARENTHESES_FOLLOW: &str = "A [normal hyperlink](file1.md) (followed by parentheses) to a file"; #[test] fn test_parentheses_follow_native() { let index = boilerplate(IndexingMethod::Native, PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_parentheses_follow_grep() { let index = boilerplate(IndexingMethod::Grep, PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_parentheses_follow_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, PARENTHESES_FOLLOW); assert!(index.is_ok()); } // Parentheses in link text const PARENTHESES_IN_LINK_TEXT: &str = "A [hyperlink (with parentheses) in the link text](file1.md) to a file"; #[test] fn test_parentheses_in_link_text_native() { let index = boilerplate(IndexingMethod::Native, PARENTHESES_IN_LINK_TEXT); assert!(index.is_ok()); } #[test] fn test_parentheses_in_link_text_grep() { let index = boilerplate(IndexingMethod::Grep, PARENTHESES_IN_LINK_TEXT); assert!(index.is_ok()); } #[test] fn test_parentheses_in_link_text_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, PARENTHESES_IN_LINK_TEXT); assert!(index.is_ok()); } // Parentheses in link text const PARENTHESES_IN_LINK_TEXT_AND_FOLLOW: &str = "A [hyperlink (with parentheses) in the link text](file1.md) (followed by parentheses) to a file"; #[test] fn test_parentheses_in_link_text_and_follow_native() { let index = boilerplate(IndexingMethod::Native, PARENTHESES_IN_LINK_TEXT_AND_FOLLOW); assert!(index.is_ok()); } #[test] fn test_parentheses_in_link_text_and_follow_grep() { let index = boilerplate(IndexingMethod::Grep, PARENTHESES_IN_LINK_TEXT_AND_FOLLOW); assert!(index.is_ok()); } #[test] fn test_parentheses_in_link_text_and_follow_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, PARENTHESES_IN_LINK_TEXT_AND_FOLLOW); assert!(index.is_ok()); } // A hyperlink inside parentheses const HYPERLINK_INSIDE_PARENTHESES: &str = "A (link [inside](file1.md) parentheses) to a file"; #[test] fn test_hyperlink_inside_parentheses_native() { let index = boilerplate(IndexingMethod::Native, HYPERLINK_INSIDE_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_hyperlink_inside_parentheses_grep() { let index = boilerplate(IndexingMethod::Grep, HYPERLINK_INSIDE_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_hyperlink_inside_parentheses_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, HYPERLINK_INSIDE_PARENTHESES); assert!(index.is_ok()); } // A hyperlink directly inside parentheses const HYPERLINK_DIRECTLY_INSIDE_PARENTHESES: &str = "A ([link directly inside parentheses](file1.md)) to a file"; #[test] fn test_hyperlink_directly_inside_parentheses_native() { let index = boilerplate(IndexingMethod::Native, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_hyperlink_directly_inside_parentheses_grep() { let index = boilerplate(IndexingMethod::Grep, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_hyperlink_directly_inside_parentheses_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES); assert!(index.is_ok()); } // A hyperlink inside parentheses followed by parenthese const HYPERLINK_INSIDE_PARENTHESES_FOLLOW: &str = "A (link [inside](file1.md) parentheses) (followed by parentheses) to a file"; #[test] fn test_hyperlink_inside_parentheses_follow_native() { let index = boilerplate(IndexingMethod::Native, HYPERLINK_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_hyperlink_inside_parentheses_follow_grep() { let index = boilerplate(IndexingMethod::Grep, HYPERLINK_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_hyperlink_inside_parentheses_follow_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, HYPERLINK_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } // A hyperlink directly inside parentheses followed by parentheses const HYPERLINK_DIRECTLY_INSIDE_PARENTHESES_FOLLOW: &str = "A ([link directly inside parentheses](file1.md)) (followed by parentheses) to a file"; #[test] fn test_hyperlink_directly_inside_parentheses_follow_native() { let index = boilerplate(IndexingMethod::Native, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_hyperlink_directly_inside_parentheses_follow_grep() { let index = boilerplate(IndexingMethod::Grep, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } #[test] fn test_hyperlink_directly_inside_parentheses_follow_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, HYPERLINK_DIRECTLY_INSIDE_PARENTHESES_FOLLOW); assert!(index.is_ok()); } // Link to a file with parentheses in the filename const TO_FILENAME_PARENTHESES: &str = " A [hyperlink](f(o)o.md) to a file with parentheses in the filename"; #[test] fn test_to_filename_parentheses_native() { let index = boilerplate(IndexingMethod::Native, TO_FILENAME_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_to_filename_parentheses_grep() { let index = boilerplate(IndexingMethod::Grep, TO_FILENAME_PARENTHESES); assert!(index.is_ok()); } #[test] fn test_to_filename_parentheses_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, TO_FILENAME_PARENTHESES); assert!(index.is_ok()); } // Links followed by a single closing parenthesis const PARENTHESES_FOLLOW_CLOSING: &str = "A [normal hyperlink](file1.md)) to a file followed by a single closing parenthesis"; #[test] fn test_parentheses_follow_closing_native() { let index = boilerplate(IndexingMethod::Native, PARENTHESES_FOLLOW_CLOSING); assert!(index.is_ok()); } #[test] fn test_parentheses_follow_closing_grep() { let index = boilerplate(IndexingMethod::Grep, PARENTHESES_FOLLOW_CLOSING); assert!(index.is_ok()); } #[test] fn test_parentheses_follow_closing_ripgrep() { let index = boilerplate(IndexingMethod::RipGrep, PARENTHESES_FOLLOW_CLOSING); assert!(index.is_ok()); }