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
|
use crate::{Document, TemplateSpec};
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::{Read, Write};
use std::path::Path;
use base64::encode;
use tera::{Context, Tera, Value};
use anyhow::Result;
/// Return the requested template specification.
pub fn template_spec(templates: &Path, doc: &Document) -> Result<TemplateSpec> {
let template = match doc.meta().template_name() {
Some(x) => &x,
None => "python",
};
let mut filename = templates.to_path_buf();
filename.push(Path::new(template));
filename.push(Path::new("template.yaml"));
Ok(TemplateSpec::from_file(&filename)?)
}
/// Generate a test program from a document, using a template spec.
pub fn generate_test_program(
doc: &mut Document,
spec: &TemplateSpec,
filename: &Path,
) -> Result<()> {
let context = context(doc)?;
let tera = tera(&spec)?;
let code = tera.render("template", &context).expect("render");
write(filename, &code)?;
Ok(())
}
fn context(doc: &mut Document) -> Result<Context> {
let mut context = Context::new();
context.insert("scenarios", &doc.matched_scenarios()?);
context.insert("files", doc.files());
let funcs_filenames = doc.meta().functions_filenames();
let mut funcs = String::new();
for filename in funcs_filenames {
funcs.push_str(&cat(filename)?);
}
context.insert("functions", &funcs);
Ok(context)
}
fn tera(tmplspec: &TemplateSpec) -> Result<Tera> {
// Tera insists on a glob, but we want to load a specific template
// only, so we use a glob that doesn't match anything.
let mut tera = Tera::new(&"*notexist").expect("new");
tera.register_filter("base64", base64);
tera.add_template_file(tmplspec.template_filename(), Some("template"))?;
Ok(tera)
}
fn cat<P: AsRef<Path>>(filename: P) -> Result<String> {
let mut f = File::open(filename)?;
let mut buf = String::new();
f.read_to_string(&mut buf)?;
Ok(buf)
}
fn write(filename: &Path, content: &str) -> Result<()> {
let mut f: File = File::create(filename)?;
f.write_all(&content.as_bytes())?;
Ok(())
}
fn base64(v: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> {
match v {
Value::String(s) => Ok(Value::String(encode(s))),
_ => Err(tera::Error::msg(
"can only base64 encode strings".to_string(),
)),
}
}
|