Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,181 @@
|
||||
use super::Directory;
|
||||
use dever::compiler::{project::Project, toolchain::BuildTarget};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Output};
|
||||
|
||||
mod packaging;
|
||||
mod skill;
|
||||
|
||||
fn cli(arguments: &[&str]) -> Output {
|
||||
Command::new(env!("CARGO_BIN_EXE_dever"))
|
||||
.args(arguments)
|
||||
.output()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn success(output: Output) -> String {
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_creates_plain_source_and_separate_docs_without_overwriting() {
|
||||
let directory = Directory::new();
|
||||
for name in ["plain", "second"] {
|
||||
let root = directory.0.join(name);
|
||||
let text = root.to_str().unwrap();
|
||||
let arguments = vec!["new", text];
|
||||
success(cli(&arguments));
|
||||
let suffix = "dever";
|
||||
assert!(
|
||||
root.join(format!("module/hello/greeting/app.{suffix}"))
|
||||
.is_file()
|
||||
);
|
||||
assert!(
|
||||
root.join(format!("test/hello/greeting/greet.{suffix}"))
|
||||
.is_file()
|
||||
);
|
||||
assert!(root.join("module/hello/greeting/README.md").is_file());
|
||||
assert!(root.join("module/hello/greeting/doc/greeting.md").is_file());
|
||||
let project = Project::load(&root).unwrap();
|
||||
assert_eq!(project.check().unwrap().commands.len(), 1);
|
||||
success(cli(&["check", text]));
|
||||
success(cli(&["fmt", text, "--check"]));
|
||||
let snapshot = std::fs::read(root.join("README.md")).unwrap();
|
||||
assert!(!cli(&arguments).status.success());
|
||||
assert_eq!(std::fs::read(root.join("README.md")).unwrap(), snapshot);
|
||||
}
|
||||
let path = directory.0.join("invalid");
|
||||
assert!(
|
||||
!cli(&["new", path.to_str().unwrap(), "--markdown"])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert!(!path.exists());
|
||||
let link = directory.0.join("link");
|
||||
std::os::unix::fs::symlink(directory.0.join("plain"), &link).unwrap();
|
||||
let rejected = cli(&["new", link.to_str().unwrap()]);
|
||||
assert!(!rejected.status.success());
|
||||
assert!(String::from_utf8_lossy(&rejected.stderr).contains(link.to_str().unwrap()));
|
||||
assert_eq!(
|
||||
std::fs::read_link(&link).unwrap(),
|
||||
directory.0.join("plain")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_runs_tests_and_builds_a_real_native_executable_for_the_selected_target() {
|
||||
let directory = Directory::new();
|
||||
let root = directory.0.join("app");
|
||||
dever::compiler::project::create(&root).unwrap();
|
||||
let root = root.to_str().unwrap();
|
||||
success(cli(&["test", root]));
|
||||
let result = success(cli(&[
|
||||
"run",
|
||||
root,
|
||||
"--",
|
||||
"hello.greeting.greet",
|
||||
r#"{"name":"Dever"}"#,
|
||||
]));
|
||||
assert_eq!(
|
||||
serde_json::from_str::<serde_json::Value>(&result).unwrap()["data"],
|
||||
"Hello, Dever"
|
||||
);
|
||||
let binary = directory.0.join("hello");
|
||||
success(cli(&[
|
||||
"build",
|
||||
root,
|
||||
"--output",
|
||||
binary.to_str().unwrap(),
|
||||
"--target",
|
||||
BuildTarget::host().unwrap().name(),
|
||||
]));
|
||||
BuildTarget::host()
|
||||
.unwrap()
|
||||
.validate_executable(&std::fs::read(&binary).unwrap())
|
||||
.unwrap();
|
||||
let result = success(
|
||||
Command::new(&binary)
|
||||
.args(["hello.greeting.greet", r#"{"name":"native"}"#])
|
||||
.output()
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<serde_json::Value>(&result).unwrap()["data"],
|
||||
"Hello, native"
|
||||
);
|
||||
let before = std::fs::read(&binary).unwrap();
|
||||
assert!(
|
||||
!cli(&["build", root, "--output", binary.to_str().unwrap()])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert_eq!(std::fs::read(&binary).unwrap(), before);
|
||||
assert!(
|
||||
!cli(&["run", root, "--target", "linux-aarch64"])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
!cli(&[
|
||||
"build",
|
||||
root,
|
||||
"--output",
|
||||
binary.to_str().unwrap(),
|
||||
"--target",
|
||||
"unsupported"
|
||||
])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn elf_validation_checks_architecture_and_executable_type() {
|
||||
let mut header = vec![0_u8; 64];
|
||||
header[..7].copy_from_slice(b"\x7fELF\x02\x01\x01");
|
||||
header[16..18].copy_from_slice(&2_u16.to_le_bytes());
|
||||
header[18..20].copy_from_slice(&183_u16.to_le_bytes());
|
||||
assert!(
|
||||
BuildTarget::LinuxAarch64
|
||||
.validate_executable(&header)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
BuildTarget::LinuxX86_64
|
||||
.validate_executable(&header)
|
||||
.is_err()
|
||||
);
|
||||
header[16..18].copy_from_slice(&1_u16.to_le_bytes());
|
||||
assert!(
|
||||
BuildTarget::LinuxAarch64
|
||||
.validate_executable(&header)
|
||||
.is_err()
|
||||
);
|
||||
assert!(
|
||||
BuildTarget::LinuxAarch64
|
||||
.validate_executable(b"short")
|
||||
.is_err()
|
||||
);
|
||||
assert!(BuildTarget::parse("linux-x86_64").is_ok());
|
||||
assert!(BuildTarget::parse("esp32").is_err());
|
||||
}
|
||||
|
||||
fn copy_tree(source: &Path, destination: &Path) {
|
||||
if source.is_dir() {
|
||||
std::fs::create_dir_all(destination).unwrap();
|
||||
for entry in std::fs::read_dir(source)
|
||||
.unwrap_or_else(|error| panic!("{}: {error}", source.display()))
|
||||
{
|
||||
let entry = entry.unwrap();
|
||||
copy_tree(&entry.path(), &destination.join(entry.file_name()));
|
||||
}
|
||||
} else {
|
||||
std::fs::create_dir_all(destination.parent().unwrap()).unwrap();
|
||||
std::fs::copy(source, destination).unwrap();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user