Phase 6: IDE-Exportanbindung abschließen und Change archivieren
This commit is contained in:
@@ -283,21 +283,25 @@ fn create(a: &mut App, t: &Temp) -> PathBuf {
|
||||
path
|
||||
}
|
||||
fn exports(a: &mut App, t: &Temp) {
|
||||
a.export_backend = false;
|
||||
let stamp = ProjectStamp::capture(&a.project);
|
||||
for c in [Command::MakeExe, Command::MakeLibrary] {
|
||||
menu(a, c);
|
||||
assert!(draw(a).contains("Erzeugen: Phase 6"));
|
||||
choice(a, 1, "linux");
|
||||
choice(a, 2, "x86_64");
|
||||
field(a, 3, "");
|
||||
let output = if c == Command::MakeLibrary { 1 } else { 3 };
|
||||
if c == Command::MakeExe {
|
||||
choice(a, 1, "linux");
|
||||
choice(a, 2, "x86_64");
|
||||
}
|
||||
field(a, output, "");
|
||||
plain(a, K::Enter);
|
||||
assert!(a.dialog.as_ref().unwrap().error.contains("Ausgabepfad"));
|
||||
field(a, 3, &t.0.join("bad.tbc").display().to_string());
|
||||
field(a, output, &t.0.join("bad.tbc").display().to_string());
|
||||
plain(a, K::Enter);
|
||||
assert!(a.dialog.as_ref().unwrap().error.contains("TBC"));
|
||||
let existing = t.0.join("existing");
|
||||
let existing = t.0.join("existing.tbl");
|
||||
fs::write(&existing, "original").unwrap();
|
||||
field(a, 3, &existing.display().to_string());
|
||||
field(a, output, &existing.display().to_string());
|
||||
plain(a, K::Enter);
|
||||
assert!(a
|
||||
.dialog
|
||||
@@ -309,8 +313,8 @@ fn exports(a: &mut App, t: &Temp) {
|
||||
plain(a, K::Char(' '));
|
||||
plain(a, K::Enter);
|
||||
assert_eq!(fs::read_to_string(existing).unwrap(), "original");
|
||||
let out = t.0.join("native-result");
|
||||
field(a, 3, &out.display().to_string());
|
||||
let out = t.0.join("native-result.tbl");
|
||||
field(a, output, &out.display().to_string());
|
||||
plain(a, K::Enter);
|
||||
let request = a.dialog.as_ref().unwrap().request.clone().unwrap();
|
||||
assert_eq!(request.project, stamp);
|
||||
@@ -805,3 +809,157 @@ fn reference_matrix_is_complete_and_points_to_runnable_tests() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_export(a: &mut App) {
|
||||
let start = std::time::Instant::now();
|
||||
while a.dialog.as_ref().unwrap().export_status == ExportStatus::Running {
|
||||
a.tick_export();
|
||||
assert!(start.elapsed().as_secs() < 15, "Export hängt");
|
||||
std::thread::sleep(std::time::Duration::from_millis(2));
|
||||
}
|
||||
assert_eq!(
|
||||
a.dialog.as_ref().unwrap().export_status,
|
||||
ExportStatus::Success,
|
||||
"{:?}",
|
||||
a.dialog
|
||||
);
|
||||
plain(a, K::Esc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Echter Zielnachweis: TB_IDE_RUNTIME_DIR muss geprüfte Host-tbrt-Vorlage enthalten"]
|
||||
fn real_native_ide_exports_and_source_free_cli_library_consumer() {
|
||||
let runtime_dir =
|
||||
PathBuf::from(std::env::var_os("TB_IDE_RUNTIME_DIR").expect("TB_IDE_RUNTIME_DIR fehlt"));
|
||||
let target = tb_export::Target::host().unwrap();
|
||||
let t = Temp::new();
|
||||
let mut a = App::new(&t.0, t.0.join("options"), (100, 30)).unwrap();
|
||||
a.runtime_dir = runtime_dir;
|
||||
let _project = create(&mut a, &t);
|
||||
a.project.open_document(&t.0.join("work.bi")).unwrap();
|
||||
let disk: Vec<_> = a
|
||||
.project
|
||||
.documents()
|
||||
.map(|(_, d)| {
|
||||
(
|
||||
d.source_path().to_path_buf(),
|
||||
fs::read(d.source_path()).unwrap(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let include = a.project.find_document(&t.0.join("work.bi")).unwrap();
|
||||
a.project.replace_text(include, 6..7, "7").unwrap();
|
||||
let stamp = ProjectStamp::capture(&a.project);
|
||||
// The real project still supports debugging before export.
|
||||
open_code(&mut a, "Form1.frm");
|
||||
plain(&mut a, K::F(8));
|
||||
tick(&mut a, 0);
|
||||
assert_eq!(a.execution, Execution::Paused, "{}", a.message);
|
||||
|
||||
let exe = t.0.join(if cfg!(windows) {
|
||||
"program.exe"
|
||||
} else {
|
||||
"program"
|
||||
});
|
||||
menu(&mut a, Command::MakeExe);
|
||||
let (system, arch) = tb_ide::export::target_parts(target);
|
||||
choice(&mut a, 1, system);
|
||||
choice(&mut a, 2, arch);
|
||||
field(&mut a, 3, &exe.display().to_string());
|
||||
plain(&mut a, K::Enter);
|
||||
finish_export(&mut a);
|
||||
assert_eq!(
|
||||
tb_export::native_target(&fs::read(&exe).unwrap()).unwrap(),
|
||||
target
|
||||
);
|
||||
let library = t.0.join("library.tbl");
|
||||
menu(&mut a, Command::MakeLibrary);
|
||||
field(&mut a, 1, &library.display().to_string());
|
||||
click_hit(&mut a, |h| matches!(h, Hit::DialogSubmit));
|
||||
finish_export(&mut a);
|
||||
let mut compiler = tb_vm::project::ProjectCompiler::default();
|
||||
compiler.debug_symbols = true;
|
||||
let expected = a
|
||||
.project
|
||||
.sources()
|
||||
.unwrap()
|
||||
.compile_library(&mut compiler)
|
||||
.unwrap()
|
||||
.to_tbl()
|
||||
.unwrap();
|
||||
assert_eq!(fs::read(&library).unwrap(), expected);
|
||||
assert_eq!(ProjectStamp::capture(&a.project), stamp);
|
||||
assert!(a.project.document(include).unwrap().is_dirty());
|
||||
for (path, bytes) in disk {
|
||||
assert_eq!(fs::read(&path).unwrap(), bytes);
|
||||
fs::remove_file(path).unwrap();
|
||||
}
|
||||
fs::remove_file(t.0.join("project.mak")).unwrap();
|
||||
let consumer = t.0.join("consumer.bas");
|
||||
fs::write(
|
||||
&consumer,
|
||||
"DIM n AS INTEGER\nn=8\nCALL Bump(n)\nPRINT n\nEND\n",
|
||||
)
|
||||
.unwrap();
|
||||
let tbc = t.0.join("consumer.tbc");
|
||||
// Exactly the tbc link command implementation, with the library sources gone.
|
||||
build(
|
||||
&[
|
||||
consumer.display().to_string(),
|
||||
library.display().to_string(),
|
||||
"-o".into(),
|
||||
tbc.display().to_string(),
|
||||
],
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let cli = tb_vm::project_io::load_program(&tbc).unwrap();
|
||||
fs::write(t.0.join("consumer.mak"), "consumer.bas\nlibrary.tbl\n").unwrap();
|
||||
let mut other = App::new(&t.0, t.0.join("other-options"), (100, 30)).unwrap();
|
||||
other
|
||||
.load_initial_project(t.0.join("consumer.mak"))
|
||||
.unwrap();
|
||||
other.start_execution().unwrap();
|
||||
tick(&mut other, 0);
|
||||
assert_eq!(snapshot::text(other.session.screen()), " 9 \n");
|
||||
let mut cli_vm = new_execution(cli, "", None, None).unwrap();
|
||||
let mut host = tb_runtime::host::CaptureHost::default();
|
||||
assert!(matches!(cli_vm.run(&mut host), RunEvent::Ended));
|
||||
assert_eq!(
|
||||
snapshot::text(&cli_vm.rt.screen),
|
||||
snapshot::text(other.session.screen())
|
||||
);
|
||||
fs::remove_file(&library).unwrap();
|
||||
fs::remove_file(&tbc).unwrap();
|
||||
fs::remove_file(&consumer).unwrap();
|
||||
use std::io::Write;
|
||||
let mut child = std::process::Command::new(&exe)
|
||||
.arg("!")
|
||||
.current_dir(&t.0)
|
||||
.env("PATH", "")
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
child.stdin.take().unwrap().write_all(b"abc\n").unwrap();
|
||||
let start = std::time::Instant::now();
|
||||
while child.try_wait().unwrap().is_none() {
|
||||
if start.elapsed().as_secs() > 10 {
|
||||
let _ = child.kill();
|
||||
panic!("Natives IDE-Programm hängt");
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(5));
|
||||
}
|
||||
let result = child.wait_with_output().unwrap();
|
||||
assert!(
|
||||
result.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&result.stderr)
|
||||
);
|
||||
let output = String::from_utf8_lossy(&result.stdout).replace("\r\n", "\n");
|
||||
assert!(output.contains("8 abc!"), "{output:?}");
|
||||
assert!(fs::read_to_string(t.0.join("result.txt"))
|
||||
.unwrap()
|
||||
.contains('8'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user