Skip to content

Commit

Permalink
Move the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Oct 28, 2024
1 parent 1d369f3 commit dc54453
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 154 deletions.
159 changes: 159 additions & 0 deletions crates/uv-trampoline/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,161 @@
pub mod bounce;
mod diagnostics;

#[cfg(test)]
mod test {
use std::io::{Cursor, Write};
use std::path::Path;
use std::process::Command;
use std::{env, io};

use anyhow::Result;
use assert_cmd::prelude::OutputAssertExt;
use assert_fs::prelude::PathChild;
use fs_err::File;
use thiserror::Error;
use which::which;
use zip::write::FileOptions;
use zip::ZipWriter;

use uv_trampoline_builder::windows_script_launcher;

/// Wrapper script template function
///
/// <https://github.com/pypa/pip/blob/7f8a6844037fb7255cfd0d34ff8e8cf44f2598d4/src/pip/_vendor/distlib/scripts.py#L41-L48>
fn get_script_launcher(shebang: &str, is_gui: bool) -> String {
if is_gui {
format!(
r##"{shebang}
# -*- coding: utf-8 -*-
import re
import sys
def make_gui() -> None:
from tkinter import Tk, ttk
root = Tk()
root.title("uv Test App")
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello from uv-trampoline-gui.exe").grid(column=0, row=0)
root.mainloop()
if __name__ == "__main__":
sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0])
sys.exit(make_gui())
"##
)
} else {
format!(
r##"{shebang}
# -*- coding: utf-8 -*-
import re
import sys
def main_console() -> None:
print("Hello from uv-trampoline-console.exe", file=sys.stdout)
print("Hello from uv-trampoline-console.exe", file=sys.stderr)
for arg in sys.argv[1:]:
print(arg, file=sys.stderr)
if __name__ == "__main__":
sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0])
sys.exit(main_console())
"##
)
}
}

/// Format the shebang for a given Python executable.
///
/// Like pip, if a shebang is non-simple (too long or contains spaces), we use `/bin/sh` as the
/// executable.
///
/// See: <https://github.com/pypa/pip/blob/0ad4c94be74cc24874c6feb5bb3c2152c398a18e/src/pip/_vendor/distlib/scripts.py#L136-L165>
fn format_shebang(executable: impl AsRef<Path>) -> String {
// Convert the executable to a simplified path.
let executable = executable.as_ref().display().to_string();
format!("#!{executable}")
}

#[test]
fn generate_console_launcher() -> Result<()> {
// Create Temp Dirs
let temp_dir = assert_fs::TempDir::new()?;
let console_bin_path = temp_dir.child("launcher.console.exe");

// Locate an arbitrary python installation from PATH
let python_executable_path = which("python")?;

// Generate Launcher Script
let launcher_console_script =
get_script_launcher(&format_shebang(&python_executable_path), false);

// Generate Launcher Payload
let console_launcher =
windows_script_launcher(&launcher_console_script, false, &python_executable_path)?;

// Create Launcher
File::create(console_bin_path.path())?.write_all(console_launcher.as_ref())?;

println!(
"Wrote Console Launcher in {}",
console_bin_path.path().display()
);

let stdout_predicate = "Hello from uv-trampoline-console.exe\r\n";
let stderr_predicate = "Hello from uv-trampoline-console.exe\r\n";

// Test Console Launcher
#[cfg(windows)]
Command::new(console_bin_path.path())
.assert()
.success()
.stdout(stdout_predicate)
.stderr(stderr_predicate);

let args_to_test = vec!["foo", "bar", "foo bar", "foo \"bar\"", "foo 'bar'"];
let stderr_predicate = format!("{}{}\r\n", stderr_predicate, args_to_test.join("\r\n"));

// Test Console Launcher (with args)
#[cfg(windows)]
Command::new(console_bin_path.path())
.args(args_to_test)
.assert()
.success()
.stdout(stdout_predicate)
.stderr(stderr_predicate);

Ok(())
}

#[test]
#[ignore]
fn generate_gui_launcher() -> Result<()> {
// Create Temp Dirs
let temp_dir = assert_fs::TempDir::new()?;
let gui_bin_path = temp_dir.child("launcher.gui.exe");

// Locate an arbitrary pythonw installation from PATH
let pythonw_executable_path = which("pythonw")?;

// Generate Launcher Script
let launcher_gui_script =
get_script_launcher(&format_shebang(&pythonw_executable_path), true);

// Generate Launcher Payload
let gui_launcher =
windows_script_launcher(&launcher_gui_script, true, &pythonw_executable_path)?;

// Create Launcher
File::create(gui_bin_path.path())?.write_all(gui_launcher.as_ref())?;

println!("Wrote GUI Launcher in {}", gui_bin_path.path().display());

// Test GUI Launcher
// NOTICE: This will spawn a GUI and will wait until you close the window.
#[cfg(windows)]
Command::new(gui_bin_path.path()).assert().success();

Ok(())
}
}
154 changes: 0 additions & 154 deletions crates/uv-trampoline/tests/harness.rs

This file was deleted.

0 comments on commit dc54453

Please sign in to comment.