mod fixtures; use fixtures::{Fixture, WranglerToml}; use std::collections::HashMap; use std::env; use std::process::Command; use assert_cmd::prelude::*; use predicates::prelude::*; #[test] fn it_can_preview_js_project() { let fixture = Fixture::new(); fixture.create_file( "index.js", r#" addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) /** * Fetch and log a request * @param {Request} request */ async function handleRequest(request) { return new Response('Hello worker!', { status: 200 }) } "#, ); fixture.create_default_package_json(); let wrangler_toml = WranglerToml::javascript("test-preview-javascript"); fixture.create_wrangler_toml(wrangler_toml); preview_succeeds(&fixture); } #[test] fn it_can_preview_webpack_project() { let fixture = Fixture::new(); fixture.scaffold_webpack(); let wrangler_toml = WranglerToml::webpack_build("test-preview-webpack"); fixture.create_wrangler_toml(wrangler_toml); preview_succeeds(&fixture); } #[test] fn it_can_preview_rust_project() { let fixture = Fixture::new(); fixture.create_dir("src"); fixture.create_dir("worker"); fixture.create_file( "src/lib.rs", r#" extern crate cfg_if; extern crate wasm_bindgen; mod utils; use cfg_if::cfg_if; use wasm_bindgen::prelude::*; cfg_if! { // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. if #[cfg(feature = "wee_alloc")] { extern crate wee_alloc; #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; } } #[wasm_bindgen] pub fn greet() -> String { "Hello, wasm-worker!".to_string() } "#, ); fixture.create_file( "src/utils.rs", r#" use cfg_if::cfg_if; cfg_if! { // When the `console_error_panic_hook` feature is enabled, we can call the // `set_panic_hook` function at least once during initialization, and then // we will get better error messages if our code ever panics. // // For more details see // https://github.com/rustwasm/console_error_panic_hook#readme if #[cfg(feature = "console_error_panic_hook")] { extern crate console_error_panic_hook; pub use self::console_error_panic_hook::set_once as set_panic_hook; } else { #[inline] pub fn set_panic_hook() {} } } "#, ); fixture.create_file( "worker/worker.js", r#" addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) /** * Fetch and log a request * @param {Request} request */ async function handleRequest(request) { const { greet } = wasm_bindgen; await wasm_bindgen(wasm) const greeting = greet() return new Response(greeting, {status: 200}) } "#, ); fixture.create_file( "Cargo.toml", r#" [package] name = "worker" version = "0.1.0" authors = ["The Wrangler Team "] edition = "2018" [lib] crate-type = ["cdylib", "rlib"] [features] default = ["console_error_panic_hook"] [dependencies] cfg-if = "0.1.2" wasm-bindgen = "0.2" # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for # code size when deploying. console_error_panic_hook = { version = "0.1.1", optional = true } # `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size # compared to the default allocator's ~10K. It is slower than the default # allocator, however. # # Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. wee_alloc = { version = "0.4.2", optional = true } [dev-dependencies] wasm-bindgen-test = "0.2" [profile.release] # Tell `rustc` to optimize for small code size. opt-level = "s" [package.metadata.wasm-pack.profile.release] wasm-opt = false "#, ); let wrangler_toml = WranglerToml::rust("test-preview-rust"); fixture.create_wrangler_toml(wrangler_toml); preview_succeeds(&fixture); } #[test] fn it_can_preview_using_url_flag() { let fixture = Fixture::new(); fixture.create_file( "index.js", r#" addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { return new Response(request.url, { status: 200 }) } "#, ); fixture.create_default_package_json(); let wrangler_toml = WranglerToml::javascript("test-preview-javascript"); fixture.create_wrangler_toml(wrangler_toml); // URLs should match as expected preview_matches_url(&fixture, "https://example.com/a", "https://example.com/a"); // URLs should not match as expected preview_not_matches_url(&fixture, "https://example.com/a", "https://example.com/b"); } #[test] fn it_previews_with_config_text() { let fixture = Fixture::new(); fixture.create_file( "index.js", r#" addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { return new Response(CONFIG_TEST) } "#, ); fixture.create_default_package_json(); let test_value: &'static str = "sdhftiuyrtdhfjgpoopuyrdfjgkyitudrhf"; let mut wrangler_toml = WranglerToml::javascript("test-preview-with-config"); let mut config: HashMap<&'static str, &'static str> = HashMap::new(); config.insert("CONFIG_TEST", test_value); wrangler_toml.vars = Some(config); fixture.create_wrangler_toml(wrangler_toml); preview_succeeds_with(&fixture, None, test_value); } #[test] fn it_previews_with_text_blob() { let fixture = Fixture::new(); fixture.create_file( "index.js", r#" addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { return new Response(BLOB) } "#, ); fixture.create_default_package_json(); let test_value: &'static str = "sdhftiuyrtdhfjgpoopuyrdfjgkyitudrhf"; fixture.create_file("blob.txt", test_value); let mut wrangler_toml = WranglerToml::javascript("test-preview-with-config"); let mut blobs: HashMap<&'static str, &'static str> = HashMap::new(); blobs.insert("BLOB", "blob.txt"); wrangler_toml.text_blobs = Some(blobs); fixture.create_wrangler_toml(wrangler_toml); preview_succeeds_with(&fixture, None, test_value); } fn preview_succeeds_with(fixture: &Fixture, env: Option<&str>, expected: &str) { env::remove_var("CF_ACCOUNT_ID"); env::remove_var("CF_ZONE_ID"); let mut preview = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); preview.current_dir(fixture.get_path()); preview.arg("preview").arg("--headless"); if let Some(env) = env { preview.arg("--env").arg(env); } preview .assert() .stdout(predicates::str::contains(expected)) .success(); } fn preview_succeeds(fixture: &Fixture) { env::remove_var("CF_ACCOUNT_ID"); env::remove_var("CF_ZONE_ID"); let mut preview = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); preview.current_dir(fixture.get_path()); preview.arg("preview").arg("--headless"); preview.assert().success(); } fn preview_matches_url(fixture: &Fixture, url: &str, expected: &str) { env::remove_var("CF_ACCOUNT_ID"); env::remove_var("CF_ZONE_ID"); let mut preview = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); preview.current_dir(fixture.get_path()); preview.arg("preview").arg("--headless"); preview.arg("--url").arg(url); preview.assert().stdout(predicate::str::contains(expected)); } fn preview_not_matches_url(fixture: &Fixture, url: &str, expected: &str) { env::remove_var("CF_ACCOUNT_ID"); env::remove_var("CF_ZONE_ID"); let mut preview = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); preview.current_dir(fixture.get_path()); preview.arg("preview").arg("--headless"); preview.arg("--url").arg(url); preview .assert() .stdout(predicate::str::contains(expected).not()); }