1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::fmt;
use std::fs:: { OpenOptions, File as OutputFile };
use std::convert::{ AsRef };
use std::io:: { Result as IOResult };
use std::io::prelude::*;
use std::path::Path;
use report::summary:: { Summary };
use report::file:: { File, Files };
use record:: { RecordWrite };
pub mod attribute;
pub mod summary;
pub mod file;
pub mod branch;
pub mod line;
pub mod function;
pub mod test;
pub mod counter;
#[derive(Debug)]
pub struct Report {
files: Files
}
impl Report {
pub fn new(files: Files) -> Self {
Report {
files: files
}
}
pub fn get(&self, key: &str) -> Option<&File> {
self.files.get(&key.to_string())
}
pub fn files(&self) -> &Files {
&self.files
}
pub fn len(&self) -> usize {
self.files.len()
}
pub fn save_as<T: AsRef<Path>>(&self, path: T) -> IOResult<()> {
let mut output = OpenOptions::new().create(true).write(true).open(path)?;
self.write_records::<OutputFile>(&mut output)
}
}
impl RecordWrite for Report {
fn write_records<T: Write>(&self, output: &mut T) -> IOResult<()> {
writeln!(output, "{}", self)
}
}
impl fmt::Display for Report {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (source_name, file) in self.files.iter() {
for (test_name, test) in file.tests().iter() {
writeln!(f, "TN:{}", test_name)?;
writeln!(f, "SF:{}", source_name)?;
write!(f, "{}", test.functions())?;
write!(f, "{}", test.branches())?;
write!(f, "{}", test.lines())?;
writeln!(f, "end_of_record")?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
extern crate tempdir;
use self::tempdir::TempDir;
use record::{ LineData, FunctionData, BranchData };
use report::test::{ Tests };
use report::file;
use report::{ Report };
use merger::ops:: { TryMerge };
use std::fs::File;
use std::io::*;
fn build_report() -> Report {
let mut tests = Tests::new();
let line_data = &LineData { line: 1, count: 1, checksum: None };
let function_data = &FunctionData { name: "main".to_string(), count: 1 };
let branch_data = &BranchData { line: 1, block: 1, branch: 1, taken: 1 };
let test_name = "test1".to_string();
tests.try_merge((&test_name, line_data)).unwrap();
tests.try_merge((&test_name, function_data)).unwrap();
tests.try_merge((&test_name, branch_data)).unwrap();
let file = file::File::new(tests);
let mut files = file::Files::new();
files.try_merge((&"a.c".to_string(), &file)).unwrap();
Report::new(files)
}
#[test]
fn save_as() {
let report = build_report();
let tmp_dir = TempDir::new("report").expect("create temp dir");
let file_path = tmp_dir.path().join("report.lcov");
let _ = report.save_as(file_path.clone()).unwrap();
assert_eq!(file_path.as_path().exists(), true);
}
#[test]
fn display() {
let report = build_report();
let report_path = "tests/fixtures/report/report.info";
let readed_file_content = {
let mut output = String::new();
let mut f = File::open(report_path).unwrap();
let _ = f.read_to_string(&mut output);
output
};
assert_eq!(report.to_string(), readed_file_content);
}
}