aboutsummaryrefslogtreecommitdiff
path: root/tests/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tutorial')
-rw-r--r--tests/tutorial/mod.rs155
1 files changed, 155 insertions, 0 deletions
diff --git a/tests/tutorial/mod.rs b/tests/tutorial/mod.rs
new file mode 100644
index 0000000..576d3af
--- /dev/null
+++ b/tests/tutorial/mod.rs
@@ -0,0 +1,155 @@
+use std::env::set_current_dir;
+use std::fs;
+use std::io::Read;
+use std::path::Path;
+use std::process::Command;
+
+trait ExitStatusExt {
+ fn check(self);
+}
+
+impl ExitStatusExt for std::process::ExitStatus {
+ fn check(self) {
+ assert!(self.success());
+ }
+}
+
+const CARGO: &str = env!("CARGO");
+const PROJECT_DIR: &str = env!("CARGO_MANIFEST_DIR");
+const TOSIN_ADMIN: &str = env!("CARGO_BIN_EXE_tosin-admin");
+
+fn get(url: &'static str) -> (hyper::StatusCode, String) {
+ let get = async {
+ use hyper::{Client, Uri};
+
+ let client = Client::new();
+
+ let res = client.get(Uri::from_static(url)).await.unwrap();
+
+ let status = res.status();
+
+ let body = hyper::body::to_bytes(res).await.unwrap();
+ let body = String::from_utf8_lossy(&body).into_owned();
+
+ (status, body)
+ };
+ tokio::runtime::Builder::new_multi_thread()
+ .enable_all()
+ .build()
+ .unwrap()
+ .block_on(get)
+}
+
+pub fn step1(dest: &str) {
+ // tosin-admin start-project {dest}
+ set_current_dir(PROJECT_DIR).unwrap();
+ set_current_dir("target").unwrap();
+ if fs::metadata(dest).is_ok() {
+ fs::remove_dir_all(dest).unwrap();
+ }
+ Command::new(TOSIN_ADMIN)
+ .args(&["start-project", dest])
+ .status()
+ .unwrap()
+ .check();
+ set_current_dir(dest).unwrap();
+ assert!(fs::metadata("Cargo.toml").is_ok());
+ assert!(fs::read_to_string("Cargo.toml").unwrap().contains("tosin = "));
+ assert!(fs::metadata("src/main.rs").is_ok());
+ assert!(fs::read_to_string("src/main.rs").unwrap().contains("tosin::main!"));
+
+ // cargo run run-server
+ let mut server = Command::new(CARGO)
+ .args(&["run", "run-server", "8069"])
+ .spawn()
+ .unwrap();
+ let server_poke = get("http://127.0.0.1:8069");
+ assert_eq!(server_poke.0, hyper::StatusCode::NOT_FOUND);
+ server.kill().unwrap();
+ let mut server_stdout = String::new();
+ server.stdout.unwrap().read_to_string(&mut server_stdout).unwrap();
+ assert!(server_stdout.contains("http://127.0.0.1:8069"));
+
+ // could `cargo run start-app polls` or `tosin-admin start-app polls` so
+ // flip a coin i guess
+ if rand::random() {
+ let mut cmd = Command::new(CARGO);
+ cmd.arg("run");
+ cmd
+ } else {
+ Command::new(TOSIN_ADMIN)
+ }
+ .args(&["start-app", "polls"])
+ .status().unwrap().check();
+ assert!(fs::metadata("src/polls/mod.rs").is_ok());
+
+ // write views.rs
+ fs::write("src/polls/views.rs", r#"
+use tosin::http::{Reply, Response};
+
+pub fn index() -> Response {
+ "Hello, world. You're at the polls index.".into_response()
+}
+ "#).unwrap();
+
+ // write urls.rs
+ fs::write("src/polls/urls.rs", r#"
+use tosin::urls::{UrlMap, url_map};
+
+use super::views;
+
+pub fn urls() -> UrlMap {
+ url_map! {
+ => views::index, // TODO name: "index"
+ }
+}
+ "#).unwrap();
+
+ // update main.rs
+ fs::write("src/main.rs", r#"
+use tosin::Settings;
+use tosin::contrib::admin;
+use tosin::urls::{UrlMap, url_map};
+
+mod polls;
+
+fn urls() -> UrlMap {
+ url_map! {
+ "polls" / ..polls::urls(),
+ "admin" / ..admin::site::urls(),
+ }
+}
+
+fn settings() -> Settings {
+ Settings {
+ ..Settings::default()
+ }
+}
+
+tosin::main!(urls(), settings());
+ "#).unwrap();
+
+ // poke that new route
+ let mut server = Command::new(CARGO)
+ .args(&["run", "run-server", "8069"])
+ .spawn()
+ .unwrap();
+ let server_poke = get("http://127.0.0.1:8069/polls/");
+ assert_eq!(server_poke.0, hyper::StatusCode::OK);
+ assert_eq!(server_poke.1, "Hello, world. You're at the polls index.");
+ server.kill().unwrap();
+
+ // vibe check
+ let example_tutorial1 = Path::new(PROJECT_DIR).join("examples/tutorial01");
+ for file in &["src/main.rs", "src/polls/mod.rs", "src/polls/urls.rs", "src/polls/views.rs"] {
+ let this_file = fs::read_to_string(file).unwrap();
+ let example_tutorial1_path = example_tutorial1.join(file);
+ let example_tutorial1_file = fs::read_to_string(example_tutorial1_path).unwrap();
+ assert_eq!(this_file.trim(), example_tutorial1_file.trim());
+ }
+}
+
+pub fn step2(dest: &str) {
+ step1(dest);
+ todo!();
+}