1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
#[cfg(test)]
use wasm_bindgen::prelude::*;
// Must use inline build because the test runner does not import itself in
// the browser with `type=module` which causes `import.meta` calls to fail,
// and `currentScript` does not resolve dynamic imports so the polyfill
// for `import.meta` does not work either.
#[cfg(test)]
#[wasm_bindgen(inline_js = "
export async function worker() {
await import('/dist/pkg/test/perspective.js');
return window.perspective.worker();
}
")]
extern "C" {
fn worker() -> js_sys::Promise;
}
// /// Generate a test `Table`, but only create teh webworker once or the tests
// /// will figuratively literally run forever.
// #[cfg(test)]
// pub async fn get_mock_table() -> JsPerspectiveTable {
// thread_local! {
// static WORKER: RefCell<Option<JsPerspectiveWorker>> =
// RefCell::new(None); }
// let worker: JsPerspectiveWorker = match WORKER.with(|x|
// x.borrow().clone()) { Some(x) => x,
// None => JsFuture::from(worker()).await.unwrap().unchecked_into(),
// };
// WORKER.with(|x| {
// *x.borrow_mut() = Some(worker.clone());
// });
// worker
// .table(
// json!({
// "A": [1, 2, 3]
// })
// .unchecked_into(),
// )
// .await
// .unwrap()
// }
/// A macro which set a property called `weak_link` on the container
/// `Properties` when `cfg(test)`, such that unit tests may send messages to a
/// component. This macro needs to be called in `create()` on any Component
/// which needs to receive messages in a test.
#[macro_export]
macro_rules! enable_weak_link_test {
($props:expr, $link:expr) => {
#[cfg(test)]
{
*$props.weak_link.borrow_mut() = Some($link.clone());
}
};
}
/// A macro which derives a `yew::Component` for an arbitrary HTML snippet and
/// mounts it, for testing.
#[macro_export]
macro_rules! test_html {
($($html:tt)*) => {{
use wasm_bindgen::JsCast;
use yew::prelude::*;
struct TestElement {}
#[derive(Properties, PartialEq)]
struct TestElementProps {
html: Html,
root: NodeRef,
}
impl Component for TestElement {
type Message = ();
type Properties = TestElementProps;
fn create(_ctx: &Context<Self>) -> Self {
TestElement {}
}
fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
false
}
fn changed(&mut self, _ctx: &Context<Self>, _old: &Self::Properties) -> bool {
true
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<>
<style>
{ "#test{position:absolute;top:0;bottom:0;left:0;right:0;}" }
</style>
<div ref={ ctx.props().root.clone() }>
{ ctx.props().html.clone() }
</div>
</>
}
}
}
let document = ::perspective_js::utils::global::document();
let body = document.body().unwrap();
let div = document.create_element("div").unwrap();
body.append_child(&div).unwrap();
let init = web_sys::ShadowRootInit::new(web_sys::ShadowRootMode::Open);
let shadow_root = div
.attach_shadow(&init)
.unwrap()
.unchecked_into::<web_sys::Element>();
let root = NodeRef::default();
let props = TestElementProps {
html: html!{ $($html)* },
root: root.clone(),
};
yew::Renderer::<TestElement>::with_root_and_props(shadow_root, props).render();
request_animation_frame().await;
root.cast::<web_sys::HtmlElement>()
.unwrap()
.children()
.get_with_index(0)
.unwrap()
.unchecked_into::<web_sys::HtmlElement>()
}}
}