use assert_cmd::prelude::*; // Add methods on commands use predicates::prelude::*; // Used for writing assertions use std::process::{Command,Stdio}; // Run programs use std::path::Path; use std::fs::File; use std::io::Write; type STDRESULT = Result<(),Box>; #[test] fn parse_simple_file() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; if let Ok(fd) = File::open(Path::new("tests").join("applesoft").join("test.bas")) { cmd.arg("verify") .arg("-t").arg("atxt") .stdin(Stdio::from(fd)) .assert() .success() .stderr(predicate::str::contains("Passing")); } Ok(()) } #[test] fn invalid_file_type() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; if let Ok(fd) = File::open(Path::new("tests").join("applesoft").join("test.bas")) { cmd.arg("verify") .arg("-t").arg("atxt1") .stdin(Stdio::from(fd)) .assert() .failure() .stderr(predicate::str::contains("atxt1")); } Ok(()) } #[test] fn catalog_cpm() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#" A: POLARIS BAK : POLARIS TXT "#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("cpm-smallfiles.dsk")) .assert() .success() .stdout(predicate::str::contains(expected)); Ok(()) } #[test] fn catalog_cpm_wildcard_full() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#"Directory for Drive A: User 0 Name Bytes Recs Attributes Name Bytes Recs Attributes\s* ------------ ------ ------ ------------ ------------ ------ ------ ------------ POLARIS TXT 1k 4 Dir RW\s* Total Bytes = 1k Total Records = 4 Files Found = 1 Total 1k Blocks = 1 Occupied/Tot Entries For Drive A: 2/ 48"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("cpm-smallfiles.dsk")) .arg("-f").arg("*.txt[full]") .assert() .success() .stdout(predicate::str::is_match(expected).expect("regex error")); Ok(()) } #[test] fn catalog_dos32() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#"DISK VOLUME 254 I 004 HELLO T 010 TREE1 T 019 TREE2 B 066 SAPLING"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("dos32-bigfiles.woz")) .assert() .success() .stdout(predicate::str::contains(expected)); Ok(()) } #[test] fn catalog_dos33() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#"DISK VOLUME 254 A 004 HELLO T 010 TREE1 T 019 TREE2 B 066 SAPLING"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("dos33-bigfiles.woz")) .assert() .success() .stdout(predicate::str::contains(expected)); Ok(()) } #[test] fn catalog_prodos() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#".NEW.DISK NAME\s+TYPE\s+BLOCKS\s+MODIFIED\s+CREATED\s+ENDFILE\s+SUBTYPE HELLO\s+BAS\s+3.*753\s+2049 TREE1\s+TXT\s+5.*256018\s+128 TREE2\s+TXT\s+7.*508018\s+127 SAPLING\s+BIN\s+33.*16384\s+16384 BLOCKS FREE: 225\s+BLOCKS USED: 55\s+TOTAL BLOCKS: 280"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("prodos-bigfiles.woz")) .assert() .success() .stdout(predicate::str::is_match(expected).expect("regex err")); Ok(()) } #[test] fn catalog_pascal() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#"BLANK: HELLO.TEXT\s+4.*TEXT TEST2.TEXT\s+4.*TEXT TEST3.TEXT\s+4.*TEXT 3/3 files, 18 blocks used, 262 unused, 262 in largest"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("pascal-smallfiles.do")) .assert() .success() .stdout(predicate::str::is_match(expected).expect("regex err")); Ok(()) } #[test] fn catalog_msdos() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#" Volume in drive A is NEW DISK 1 Directory of A:\\ DSKBLD\s+BAT\s+378.* DSKBLD\s+BAS\s+99.* DIR1\s+.* DIR3\s+.* \s+4 File\(s\)\s+135168 bytes free"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("msdos-ren-del.img")) .assert() .success() .stdout(predicate::str::is_match(expected).expect("regex err")); Ok(()) } #[test] fn catalog_msdos_wildcard() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let expected = r#" Volume in drive A is NEW DISK 1 Directory of A:\\DIR1\\SUB\*\.\* SUBDIR1\s+.* \s+1 File\(s\)\s+135168 bytes free"#; cmd.arg("catalog") .arg("-d").arg(Path::new("tests").join("msdos-ren-del.img")) .arg("-f").arg("/dir1/sub*.*") .assert() .success() .stdout(predicate::str::is_match(expected).expect("regex err")); Ok(()) } // N.b. extensive tokenization tests are in the language modules #[test] fn tokenize_stdin() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let test_prog = r#"10 home 20 print a$ "#; let toks: Vec = vec![7,8,10,0,0x97,0,15,8,0x14,0,0xba,0x41,0x24,0,0,0]; let mut child = cmd.arg("tokenize") .arg("-t").arg("atxt").arg("-a").arg("2049") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("failed to spawn child process"); let mut stdin = child.stdin.take().expect("Failed to open stdin"); std::thread::spawn(move || { stdin.write_all(test_prog.as_bytes()).expect("Failed to write to stdin"); }); let output = child.wait_with_output().expect("Failed to read stdout"); assert_eq!(output.stdout,toks); Ok(()) } #[test] fn detokenize_stdin() -> STDRESULT { let mut cmd = Command::cargo_bin("a2kit")?; let test_prog = r#"10 HOME 20 PRINT A$ "#; let toks: Vec = vec![7,8,10,0,0x97,0,15,8,0x14,0,0xba,0x41,0x24,0,0,0]; let mut child = cmd.arg("detokenize") .arg("-t").arg("atok") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("failed to spawn child process"); let mut stdin = child.stdin.take().expect("Failed to open stdin"); std::thread::spawn(move || { stdin.write_all(&toks).expect("Failed to write to stdin"); }); let output = child.wait_with_output().expect("Failed to read stdout"); assert_eq!(String::from_utf8_lossy(&output.stdout),test_prog); Ok(()) }