test.rs

 1use std::{
 2    collections::HashMap,
 3    ops::Range,
 4    path::{Path, PathBuf},
 5};
 6use tempdir::TempDir;
 7
 8pub fn temp_tree(tree: serde_json::Value) -> TempDir {
 9    let dir = TempDir::new("").unwrap();
10    write_tree(dir.path(), tree);
11    dir
12}
13
14fn write_tree(path: &Path, tree: serde_json::Value) {
15    use serde_json::Value;
16    use std::fs;
17
18    if let Value::Object(map) = tree {
19        for (name, contents) in map {
20            let mut path = PathBuf::from(path);
21            path.push(name);
22            match contents {
23                Value::Object(_) => {
24                    fs::create_dir(&path).unwrap();
25                    write_tree(&path, contents);
26                }
27                Value::Null => {
28                    fs::create_dir(&path).unwrap();
29                }
30                Value::String(contents) => {
31                    fs::write(&path, contents).unwrap();
32                }
33                _ => {
34                    panic!("JSON object must contain only objects, strings, or null");
35                }
36            }
37        }
38    } else {
39        panic!("You must pass a JSON object to this helper")
40    }
41}
42
43pub fn sample_text(rows: usize, cols: usize, start_char: char) -> String {
44    let mut text = String::new();
45    for row in 0..rows {
46        let c: char = (start_char as u32 + row as u32) as u8 as char;
47        let mut line = c.to_string().repeat(cols);
48        if row < rows - 1 {
49            line.push('\n');
50        }
51        text += &line;
52    }
53    text
54}
55
56pub fn marked_text_by(
57    marked_text: &str,
58    markers: Vec<char>,
59) -> (String, HashMap<char, Vec<usize>>) {
60    let mut extracted_markers: HashMap<char, Vec<usize>> = Default::default();
61    let mut unmarked_text = String::new();
62
63    for char in marked_text.chars() {
64        if markers.contains(&char) {
65            let char_offsets = extracted_markers.entry(char).or_insert(Vec::new());
66            char_offsets.push(unmarked_text.len());
67        } else {
68            unmarked_text.push(char);
69        }
70    }
71
72    (unmarked_text, extracted_markers)
73}
74
75pub fn marked_text(marked_text: &str) -> (String, Vec<usize>) {
76    let (unmarked_text, mut markers) = marked_text_by(marked_text, vec!['|']);
77    (unmarked_text, markers.remove(&'|').unwrap_or_else(Vec::new))
78}
79
80pub fn marked_text_ranges(
81    marked_text: &str,
82    range_markers: Vec<(char, char)>,
83) -> (String, Vec<Range<usize>>) {
84    let mut marker_chars = Vec::new();
85    for (start, end) in range_markers.iter() {
86        marker_chars.push(*start);
87        marker_chars.push(*end);
88    }
89    let (unmarked_text, markers) = marked_text_by(marked_text, marker_chars);
90    let ranges = range_markers
91        .iter()
92        .map(|(start_marker, end_marker)| {
93            let start = markers.get(start_marker).unwrap()[0];
94            let end = markers.get(end_marker).unwrap()[0];
95            start..end
96        })
97        .collect();
98    (unmarked_text, ranges)
99}