[DEV-7081] Add options to tameld

We want to add an option to set the output file to the linker so we do
not need to redirect output to awk any longer.

This also adds integration tests for tameld.
master
Joseph Frazer 2020-03-04 15:31:20 -05:00
parent 777494a602
commit e613bd8a8c
8 changed files with 554 additions and 13 deletions

View File

@ -133,7 +133,7 @@ strip: $(dest_standalone_strip) ui/package.strip.js
%.xmle: %.xmlo $(path_tame)/.rev-xmle
$(TAME_TS)
@echo "WARNING: using WIP proof-of-concept linker!"
set -o pipefail; $(path_tame)/tamer/target/release/tameld $< | awk '/^<package/{p=1};p' > $@
$(path_tame)/tamer/target/release/tameld -o $@ $<
%.js: %.xmle
$(TAME_TS)
$(TAME) standalone $< $@

238
tamer/Cargo.lock generated
View File

@ -1,5 +1,29 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "assert_cmd"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bumpalo"
version = "2.6.0"
@ -10,11 +34,38 @@ name = "byteorder"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "escargot"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "exitcode"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fixedbitset"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "float-cmp"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fxhash"
version = "0.2.1"
@ -23,11 +74,42 @@ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ordermap"
version = "0.3.5"
@ -42,6 +124,40 @@ dependencies = [
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "predicates"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"float-cmp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"normalize-line-endings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "predicates-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "predicates-tree"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-xml"
version = "0.17.0"
@ -50,23 +166,145 @@ dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tamer"
version = "0.0.0"
dependencies = [
"assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"exitcode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-xml 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "treeline"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e63fd144e18ba274ae7095c0197a870a7b9468abc801dd62f190d80817d2ec"
"checksum assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ac5c260f75e4e4ba87b7342be6edcecbcb3eb6741a0507fda7ad115845cc65"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19db1f7e74438642a5018cdf263bb1325b2e792f02dd0a3ca6d6c0f0d7b1d5a5"
"checksum exitcode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum float-cmp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da62c4f1b81918835a8c6a484a397775fff5953fe83529afd51b05f5c6a6617d"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum normalize-line-endings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum predicates 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "347a1b6f0b21e636bc9872fb60b83b8e185f6f5516298b8238699f7f9a531030"
"checksum predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
"checksum predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
"checksum quick-xml 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcdba8c8d71275493d966ef052a88726ac8590c15a09968b32158205c672ef"
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
"checksum regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
"checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"

View File

@ -22,6 +22,10 @@ lto = true
# in a release.
lto = true
[dev-dependencies]
assert_cmd = "0.10"
predicates = "1"
[dependencies]
bumpalo = ">= 2.6.0"
# used by petgraph
@ -29,3 +33,6 @@ fixedbitset = ">= 0.1"
fxhash = ">= 0.2.1"
petgraph = ">= 0.4.13"
quick-xml = ">= 0.17.0"
getopts = "0.2"
exitcode = "1.1.2"

View File

@ -24,9 +24,220 @@
extern crate tamer;
use getopts::{Fail, Options};
use std::env;
use std::error::Error;
use tamer::ld::poc;
pub fn main() -> Result<(), Box<dyn Error>> {
poc::main()
/// Types of commands
enum Command {
Link(String, String),
Usage,
}
/// Entrypoint for the linker
pub fn main() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = env::args().collect();
let program = &args[0];
let opts = get_opts();
let usage = opts.usage(&format!("Usage: {} -o OUTPUT FILE", program));
match parse_options(opts, args) {
Ok(Command::Link(input, output)) => poc::main(&input, &output),
Ok(Command::Usage) => {
println!("{}", usage);
std::process::exit(exitcode::OK);
}
Err(e) => {
eprintln!("{}", e);
println!("{}", usage);
std::process::exit(exitcode::USAGE);
}
}
}
/// Get 'Options'
///
/// ```
/// use getopts::Options;
///
/// let opts = get_opts();
/// ```
fn get_opts() -> Options {
let mut opts = Options::new();
opts.optopt("o", "output", "set output file name", "NAME");
opts.optflag("h", "help", "print this help menu");
opts
}
/// Option parser
fn parse_options(opts: Options, args: Vec<String>) -> Result<Command, Fail> {
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
return Err(f);
}
};
if matches.opt_present("h") {
return Ok(Command::Usage);
}
let input = match matches.free.len() {
0 => return Err(Fail::OptionMissing(String::from("FILE"))),
1 => matches.free[0].clone(),
_ => return Err(Fail::UnrecognizedOption(matches.free[1].clone())),
};
let output = match matches.opt_str("o") {
Some(m) => m,
None => {
return Err(Fail::OptionMissing(String::from("-o OUTPUT")));
}
};
Ok(Command::Link(input, output))
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parse_options_help() {
let opts = get_opts();
let result = parse_options(
opts,
vec![String::from("program"), String::from("-h")],
);
match result {
Ok(Command::Usage) => {}
_ => panic!("Long help option did not parse"),
}
}
#[test]
fn parse_options_help_long() {
let opts = get_opts();
let result = parse_options(
opts,
vec![String::from("program"), String::from("--help")],
);
match result {
Ok(Command::Usage) => {}
_ => panic!("Help option did not parse"),
}
}
#[test]
fn parse_options_invalid() {
let opts = get_opts();
let result = parse_options(
opts,
vec![String::from("program"), String::from("-q")],
);
match result {
Err(Fail::UnrecognizedOption(_)) => {}
_ => panic!("Invalid option not caught"),
}
}
#[test]
fn parse_options_missing_input() {
let opts = get_opts();
let result = parse_options(opts, vec![String::from("program")]);
match result {
Err(Fail::OptionMissing(message)) => {
assert_eq!("FILE", message);
}
_ => panic!("Missing input not caught"),
}
}
#[test]
fn parse_options_missing_output() {
let opts = get_opts();
let result = parse_options(
opts,
vec![String::from("program"), String::from("foo")],
);
match result {
Err(Fail::OptionMissing(message)) => {
assert_eq!("-o OUTPUT", message);
}
_ => panic!("Missing output not caught"),
}
}
#[test]
fn parse_options_too_many_args() {
let opts = get_opts();
let result = parse_options(
opts,
vec![
String::from("program"),
String::from("foo"),
String::from("-o"),
String::from("bar"),
String::from("baz"),
],
);
match result {
Err(Fail::UnrecognizedOption(message)) => {
assert_eq!("baz", message);
}
_ => panic!("Extra option not caught"),
}
}
#[test]
fn parse_options_valid() {
let opts = get_opts();
let result = parse_options(
opts,
vec![
String::from("program"),
String::from("foo"),
String::from("-o"),
String::from("bar"),
],
);
match result {
Ok(Command::Link(infile, outfile)) => {
assert_eq!("foo", infile);
assert_eq!("bar", outfile);
}
_ => panic!("Unexpected result"),
}
}
#[test]
fn parse_options_valid_long() {
let opts = get_opts();
let result = parse_options(
opts,
vec![
String::from("program"),
String::from("foo"),
String::from("--output"),
String::from("bar"),
],
);
match result {
Ok(Command::Link(infile, outfile)) => {
assert_eq!("foo", infile);
assert_eq!("bar", outfile);
}
_ => panic!("Unexpected result"),
}
}
}

View File

@ -30,19 +30,17 @@ use std::convert::TryInto;
use std::error::Error;
use std::fs;
use std::io::BufReader;
use std::io::Cursor;
type LinkerAsg<'i> = DefaultAsg<'i, global::ProgIdentSize>;
type LinkerObjectRef = ObjectRef<global::ProgIdentSize>;
pub fn main() -> Result<(), Box<dyn Error>> {
pub fn main(package_path: &str, output: &str) -> Result<(), Box<dyn Error>> {
let mut pkgs_seen: FxHashSet<String> = Default::default();
let mut fragments: FxHashMap<&str, String> = Default::default();
let mut depgraph = LinkerAsg::with_capacity(65536, 65536);
let mut roots = Vec::new();
let interner = DefaultInterner::new();
let package_path = std::env::args().nth(1).expect("Missing argument");
let abs_path = fs::canonicalize(package_path).unwrap();
println!("WARNING: This is proof-of-concept; do not use!");
@ -84,6 +82,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
&mut sorted,
name.expect("missing root package name"),
relroot.expect("missing root package relroot"),
output,
)?;
Ok(())
@ -305,6 +304,7 @@ fn output_xmle<'a, 'i, I: Interner<'i>>(
sorted: &mut Sections<'a, 'i>,
name: &'i Symbol<'i>,
relroot: String,
output: &str,
) -> Result<(), Box<dyn Error>> {
if !sorted.map.is_empty() {
sorted.map.push_head(get_interner_value(
@ -332,17 +332,12 @@ fn output_xmle<'a, 'i, I: Interner<'i>>(
));
}
let writer = Cursor::new(Vec::new());
let mut xmle_writer = XmleWriter::new(writer);
let file = fs::File::create(output)?;
let mut xmle_writer = XmleWriter::new(file);
xmle_writer
.write(&sorted, name, &relroot)
.expect("Could not write xmle output");
print!(
"{}",
String::from_utf8(xmle_writer.into_inner().into_inner())?
);
Ok(())
}

View File

View File

@ -0,0 +1 @@
This is not valid XML!

View File

@ -0,0 +1,89 @@
// Copyright (C) 2014-2019 Ryan Specialty Group, LLC.
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
use assert_cmd::prelude::*;
use predicates::prelude::*;
use std::process::Command;
#[test]
fn link_invalid_argument() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.arg("-q");
cmd.assert()
.failure()
.code(exitcode::USAGE)
.stderr(predicate::str::contains("Unrecognized option:"));
Ok(())
}
#[test]
fn link_missing_input_file() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.assert()
.failure()
.code(exitcode::USAGE)
.stderr(predicate::str::contains("FILE"));
Ok(())
}
#[test]
fn link_missing_output_file() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.arg("foobar");
cmd.assert()
.failure()
.code(exitcode::USAGE)
.stderr(predicate::str::contains("-o OUTPUT"));
Ok(())
}
#[test]
fn link_input_file_does_not_exist() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.arg("foobar");
cmd.arg("-o").arg("tests/data/test-output.xmle");
cmd.assert()
.failure()
.stderr(predicate::str::contains("No such file or directory"));
Ok(())
}
#[test]
fn link_empty_input_file() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.arg("tests/data/empty.xmlo");
cmd.arg("-o").arg("tests/data/test-output.xmle");
cmd.assert()
.failure()
.stderr(predicate::str::contains("stack overflow")); // uh oh
Ok(())
}
#[test]
fn link_invalid_input_file() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("tameld")?;
cmd.arg("tests/data/invalid.xmlo");
cmd.arg("-o").arg("tests/data/test-output.xmle");
cmd.assert()
.failure()
.stderr(predicate::str::contains("stack overflow")); // uh oh
Ok(())
}