#![cfg(not(target_family = "wasm"))]
use std::process::Output;
const AUTHORING_META_V1_JSON: &str = r#"[{"word":"stack","description":"Copies an existing value from the stack.","operandParserOffset":16}]"#;
fn run(args: &[&str]) -> Output {
std::process::Command::new(env!("CARGO_BIN_EXE_rain-metadata"))
.args(args)
.output()
.expect("failed to spawn rain-metadata binary")
}
fn stdout_utf8(out: &Output) -> String {
String::from_utf8(out.stdout.clone()).expect("stdout not utf8")
}
#[test]
fn test_dispatch_schema_ls() {
let out = run(&["schema", "ls"]);
assert!(out.status.success());
let expected = "\
authoring-meta-v1
";
assert_eq!(stdout_utf8(&out), expected);
}
#[test]
fn test_dispatch_schema_show() {
let out = run(&["schema", "show", "authoring-meta-v1"]);
assert!(out.status.success());
let schema: serde_json::Value =
serde_json::from_str(&stdout_utf8(&out)).expect("schema show did not print JSON");
assert_eq!(
schema["$schema"].as_str(),
Some("http://json-schema.org/draft-07/schema#")
);
let out = run(&["schema", "show", "dotrain-v1"]);
assert!(!out.status.success());
}
#[test]
fn test_dispatch_validate() {
let dir = tempfile::tempdir().unwrap();
let good = dir.path().join("good.json");
std::fs::write(&good, AUTHORING_META_V1_JSON).unwrap();
let out = run(&[
"validate",
"-m",
"authoring-meta-v1",
"-i",
good.to_str().unwrap(),
]);
assert!(out.status.success());
let bad = dir.path().join("bad.json");
std::fs::write(&bad, "this is not authoring meta json").unwrap();
let out = run(&[
"validate",
"-m",
"authoring-meta-v1",
"-i",
bad.to_str().unwrap(),
]);
assert!(!out.status.success());
}
#[test]
fn test_dispatch_magic_ls() {
let out = run(&["magic", "ls"]);
assert!(out.status.success());
let stdout = stdout_utf8(&out);
let lines: Vec<&str> = stdout.lines().collect();
assert_eq!(lines[0], "0xff0a89c674ee7874 rain-meta-document-v1");
assert_eq!(lines.len(), 20);
for line in &lines {
assert!(line.starts_with("0xff"), "not a magic line: {}", line);
}
}
#[test]
fn test_dispatch_build() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("authoring-meta.json");
std::fs::write(&input, AUTHORING_META_V1_JSON).unwrap();
let out = run(&[
"build",
"-i",
input.to_str().unwrap(),
"-m",
"authoring-meta-v1",
"-t",
"json",
"-e",
"identity",
"-l",
"en",
"-E",
"hex",
]);
assert!(out.status.success());
let stdout = stdout_utf8(&out);
assert!(
stdout.starts_with("0xff0a89c674ee7874"),
"missing magic prefix: {}",
stdout
);
assert!(stdout.len() > "0xff0a89c674ee7874".len());
}
#[test]
fn test_dispatch_solc_artifact() {
let dir = tempfile::tempdir().unwrap();
let artifact = dir.path().join("artifact.json");
std::fs::write(
&artifact,
r#"{"abi":[{"type":"fallback"}],"bytecode":"0x60","deployedBytecode":"0x61"}"#,
)
.unwrap();
let out = run(&[
"solc",
"artifact",
"-c",
"abi",
"-i",
artifact.to_str().unwrap(),
]);
assert!(out.status.success());
assert_eq!(stdout_utf8(&out), r#"[{"type":"fallback"}]"#);
let out = run(&[
"solc",
"artifact",
"-c",
"deployed-bytecode",
"-i",
artifact.to_str().unwrap(),
]);
assert!(out.status.success());
assert_eq!(stdout_utf8(&out), r#""0x61""#);
let out = run(&[
"solc",
"artifact",
"-c",
"bytecode",
"-i",
artifact.to_str().unwrap(),
]);
assert!(out.status.success());
assert_eq!(stdout_utf8(&out), r#""0x60""#);
let out_path = dir.path().join("component.json");
let out = run(&[
"solc",
"artifact",
"-c",
"abi",
"-i",
artifact.to_str().unwrap(),
"-o",
out_path.to_str().unwrap(),
]);
assert!(out.status.success());
assert_eq!(stdout_utf8(&out), "");
assert_eq!(
std::fs::read_to_string(&out_path).unwrap(),
r#"[{"type":"fallback"}]"#
);
}
#[test]
fn test_dispatch_solc_artifact_missing_component() {
let dir = tempfile::tempdir().unwrap();
let artifact = dir.path().join("artifact-no-abi.json");
std::fs::write(
&artifact,
r#"{"bytecode":{"object":"0x60"},"deployedBytecode":{"object":"0x60"}}"#,
)
.unwrap();
let out = run(&[
"solc",
"artifact",
"-c",
"abi",
"-i",
artifact.to_str().unwrap(),
]);
assert!(!out.status.success());
assert_eq!(stdout_utf8(&out), "");
let stderr = String::from_utf8(out.stderr.clone()).unwrap();
assert!(
stderr.contains(r#"artifact has no "abi" component"#),
"stderr did not name the missing component: {}",
stderr
);
let out_path = dir.path().join("component.json");
let out = run(&[
"solc",
"artifact",
"-c",
"abi",
"-i",
artifact.to_str().unwrap(),
"-o",
out_path.to_str().unwrap(),
]);
assert!(!out.status.success());
assert!(!out_path.exists());
let null_abi = dir.path().join("artifact-null-abi.json");
std::fs::write(&null_abi, r#"{"abi":null}"#).unwrap();
let out = run(&[
"solc",
"artifact",
"-c",
"abi",
"-i",
null_abi.to_str().unwrap(),
]);
assert!(out.status.success());
assert_eq!(stdout_utf8(&out), "null");
}
#[test]
fn test_dispatch_generate() {
let dir = tempfile::tempdir().unwrap();
let rain = dir.path().join("source.rain");
std::fs::write(&rain, "#calculate-io\n_ _: 1 2;").unwrap();
let out = run(&["generate", "source", "-i", rain.to_str().unwrap()]);
assert!(out.status.success());
let value: serde_json::Value =
serde_json::from_str(&stdout_utf8(&out)).expect("generate did not print JSON");
assert!(value["subject"].as_str().unwrap().starts_with("0x"));
assert!(value["meta_bytes"]
.as_str()
.unwrap()
.starts_with("0xff0a89c674ee7874"));
assert!(value["calldata"].as_str().unwrap().starts_with("0x"));
let empty = dir.path().join("empty.rain");
std::fs::write(&empty, " \n").unwrap();
let out = run(&["generate", "source", "-i", empty.to_str().unwrap()]);
assert!(!out.status.success());
}