use assert_cmd::Command;
use predicates::prelude::*;
use serde_json::{Value, json};
use tempfile::tempdir;
fn bin() -> Command {
Command::cargo_bin("gha-expression-proof").unwrap()
}
#[test]
fn eval_reads_eventsmith_github_context() {
let dir = tempdir().unwrap();
let github_context = dir.path().join("github-context.json");
std::fs::write(
&github_context,
serde_json::to_vec_pretty(&json!({
"ref": "refs/heads/main",
"ref_name": "main",
"event_name": "issues",
"event": {
"issue": {
"labels": [
{"name": "bug"},
{"name": "help wanted"}
]
}
}
}))
.unwrap(),
)
.unwrap();
let assert = bin()
.args([
"eval",
"--expr",
"github.ref == 'refs/heads/main' && contains(github.event.issue.labels.*.name, 'BUG')",
"--github-context",
github_context.to_str().unwrap(),
"--format",
"json",
])
.assert()
.success();
let receipt = serde_json::from_slice::<Value>(&assert.get_output().stdout).unwrap();
assert_eq!(receipt["result"], true);
assert_eq!(receipt["summary"]["failed"], 0);
assert!(
receipt["functions"]
.as_array()
.unwrap()
.iter()
.any(|v| v == "contains")
);
}
#[test]
fn eval_supports_from_json_and_context_json() {
let assert = bin()
.args([
"eval",
"--expr",
"fromJSON(env.time) > 2",
"--context-json",
r#"env={"time":"3"}"#,
"--format",
"json",
])
.assert()
.success();
let receipt = serde_json::from_slice::<Value>(&assert.get_output().stdout).unwrap();
assert_eq!(receipt["result"], true);
}
#[test]
fn template_interpolates_expressions() {
let dir = tempdir().unwrap();
let github_context = dir.path().join("github-context.json");
std::fs::write(
&github_context,
serde_json::to_vec(&json!({
"ref_name": "main",
"sha": "2222222222222222222222222222222222222222"
}))
.unwrap(),
)
.unwrap();
let assert = bin()
.args([
"template",
"--template",
"deploy-${{ github.ref_name }}-${{ github.sha }}",
"--github-context",
github_context.to_str().unwrap(),
"--format",
"json",
])
.assert()
.success();
let receipt = serde_json::from_slice::<Value>(&assert.get_output().stdout).unwrap();
assert_eq!(
receipt["rendered"],
"deploy-main-2222222222222222222222222222222222222222"
);
}
#[test]
fn if_condition_applies_implicit_success() {
let assert = bin()
.args([
"eval",
"--expr",
"github.ref == 'refs/heads/main'",
"--context-json",
r#"github={"ref":"refs/heads/main"}"#,
"--if-condition",
"--job-status",
"failure",
"--format",
"json",
])
.assert()
.success();
let receipt = serde_json::from_slice::<Value>(&assert.get_output().stdout).unwrap();
assert_eq!(receipt["result"], false);
}
#[test]
fn hash_files_hashes_workspace_files() {
let dir = tempdir().unwrap();
std::fs::write(dir.path().join("package-lock.json"), "{}\n").unwrap();
let assert = bin()
.args([
"eval",
"--expr",
"hashFiles('package-lock.json') != ''",
"--workspace",
dir.path().to_str().unwrap(),
"--format",
"json",
])
.assert()
.success();
let receipt = serde_json::from_slice::<Value>(&assert.get_output().stdout).unwrap();
assert_eq!(receipt["result"], true);
assert_eq!(receipt["summary"]["failed"], 0);
}
#[test]
fn invalid_expression_fails_with_receipt() {
bin()
.args([
"eval",
"--expr",
r#"github.ref == "main""#,
"--format",
"json",
])
.assert()
.failure()
.stdout(predicate::str::contains("expression.syntax"));
}