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
84
85
86
87
88
89
90
// SPDX-License-Identifier: BUSL-1.1
// Copyright (c) 2026 vertexclique
// Licensed under the Business Source License 1.1.
// Change Date: 10 years after this version's release. Change License: Apache-2.0.
#![cfg(feature = "bin")]
//! Ruby -> self-contained wasm compile+run integration, driving the real burn CLI.
//!
//! Heavy: the compile path fetches `wasi-vfs` and the stock `ruby.wasm` (network on
//! first use, then cached in `~/.burn`). `#[ignore]`d so CI stays fast and offline;
//! run locally with `cargo test -p afterburner --features bin -- --ignored ruby`.
//!
//! Dogfoods the CLI end to end: `burn new` scaffolds the package, then `burn compile`
//! and `burn run`. The environment is scrubbed (no `WASI_VFS` / `BURN_RUBY_*`) so it
//! exercises the zero-configuration path a real user hits.
use std::process::Command;
const BURN: &str = env!("CARGO_BIN_EXE_burn");
/// A `burn` command with every runtime/override env var removed, so the test proves
/// the zero-configuration path (auto-fetch, nothing set).
fn burn() -> Command {
let mut c = Command::new(BURN);
for v in [
"WASI_VFS",
"BURN_RUBY_RUNTIME",
"BURN_RUBY_USR",
"BURN_PYTHON_RUNTIME",
"BURN_PYTHON_STDLIB_ZIP",
"BURN_PYTHON_STDLIB_VER",
"BURN_WHEELS",
] {
c.env_remove(v);
}
c
}
#[test]
#[ignore = "fetches wasi-vfs + ruby.wasm; run locally with --ignored"]
fn ruby_compiles_to_standalone_wasm_blob() {
let work = std::env::temp_dir().join(format!("burn-ruby-compile-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&work);
std::fs::create_dir_all(&work).expect("mkdir work");
// Dogfood: scaffold through the real `burn new`, not a hand-written fixture.
let new = burn()
.current_dir(&work)
.args(["new", "test/rbc", "--lang", "ruby"])
.output()
.expect("spawn burn new");
assert!(
new.status.success(),
"burn new failed:\n{}",
String::from_utf8_lossy(&new.stderr)
);
let pkg = work.join("rbc");
std::fs::write(pkg.join("source/main.rb"), "puts 'ruby-wasm-blob-ok'\n")
.expect("write main.rb");
let afb = work.join("out.afb");
let compile = burn()
.args([
"compile",
pkg.to_str().unwrap(),
"-o",
afb.to_str().unwrap(),
])
.output()
.expect("spawn burn compile");
assert!(
compile.status.success(),
"compile failed:\n{}",
String::from_utf8_lossy(&compile.stderr)
);
assert!(afb.exists(), "no .afb produced");
let run = burn()
.args(["run", afb.to_str().unwrap()])
.output()
.expect("spawn burn run");
let stdout = String::from_utf8_lossy(&run.stdout);
let stderr = String::from_utf8_lossy(&run.stderr);
let _ = std::fs::remove_dir_all(&work);
assert!(
stdout.contains("ruby-wasm-blob-ok"),
"blob did not run standalone:\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
}