fhttp_core/request_sources/
file_includes.rs

1use std::path::Path;
2
3use anyhow::Result;
4
5pub fn load_file_recursively<P: AsRef<Path>>(path: P) -> Result<String> {
6    recursive_file_loader::load_file_recursively(path).map_err(anyhow::Error::new)
7}
8
9#[cfg(test)]
10mod test {
11    use std::str::FromStr;
12
13    use indoc::indoc;
14
15    use crate::test_utils::root;
16
17    use super::*;
18
19    #[test]
20    fn should_load_files_recursively() {
21        let result =
22            load_file_recursively(root().join("resources/nested_file_includes/normal/start.txt"));
23
24        let expectation = String::from_str(indoc! {r##"
25                START
26                LEVEL-1
27                LEVEL-2
28                LEVEL-3
29                LEVEL-3
30            "##})
31        .unwrap();
32
33        assert_ok!(result, expectation);
34    }
35
36    #[test]
37    fn should_detect_cyclic_dependencies() {
38        let one = root().join("resources/nested_file_includes/cyclic_dependency/level-1.txt");
39        let three = root().join("resources/nested_file_includes/cyclic_dependency/level-3.txt");
40        let result = load_file_recursively(
41            root().join("resources/nested_file_includes/cyclic_dependency/start.txt"),
42        );
43
44        assert_err!(
45            result,
46            format!(
47                "cyclic dependency detected between '{}' and '{}'",
48                three.to_str(),
49                one.to_str(),
50            )
51        );
52    }
53
54    #[test]
55    fn should_respect_escapes() {
56        let result =
57            load_file_recursively(root().join("resources/nested_file_includes/escaped/start.txt"));
58
59        let expectation = String::from_str(indoc! {r##"
60                START
61                LEVEL 1
62                ${include("level-1.txt")}
63                \LEVEL 1
64                \${include("level-1.txt")}
65                \\LEVEL 1
66                \\${include("level-1.txt")}
67                \\\LEVEL 1
68            "##})
69        .unwrap();
70
71        assert_ok!(result, expectation);
72    }
73
74    #[test]
75    fn should_include_files_preserving_indentation() -> Result<()> {
76        let location = root().join("resources/file_includes_indent/request.yaml");
77        let text = load_file_recursively(location)?;
78
79        assert_eq!(
80            text,
81            indoc! {r#"
82                method: POST
83                url: http://localhost/foo
84                body: |
85                  before_include
86                  include1
87                  	include2
88                  	    include3
89                  \include3
90                  after_include
91            "#}
92        );
93
94        Ok(())
95    }
96}