Skip to content

Commit

Permalink
feat: able to register rust test via macro
Browse files Browse the repository at this point in the history
  • Loading branch information
LeuisKen committed Jan 22, 2025
1 parent e875814 commit cbb6e71
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 44 deletions.
6 changes: 6 additions & 0 deletions bridge/core/api/document.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

#include "plugin_api/document.h"
#include "binding_call_methods.h"
#include "core/api/exception_state.h"
#include "core/dom/comment.h"
#include "core/dom/document.h"
Expand Down Expand Up @@ -246,4 +247,9 @@ WebFValue<Element, HTMLElementPublicMethods> DocumentPublicMethods::Body(webf::D
return WebFValue<Element, HTMLElementPublicMethods>{body, body->htmlElementPublicMethods(), status_block};
}

void DocumentPublicMethods::ClearCookie(webf::Document* document, webf::SharedExceptionState* shared_exception_state) {
document->InvokeBindingMethod(binding_call_methods::k___clear_cookies__, 0, nullptr,
FlushUICommandReason::kDependentsOnElement, shared_exception_state->exception_state);
}

} // namespace webf
4 changes: 2 additions & 2 deletions bridge/core/api/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ WebFValue<Node, NodePublicMethods> NodePublicMethods::RemoveChild(webf::Node* se
webf::Node* target_node,
webf::SharedExceptionState* shared_exception_state) {
MemberMutationScope member_mutation_scope{self_node->GetExecutingContext()};
Node* returned_node = target_node->removeChild(target_node, shared_exception_state->exception_state);
Node* returned_node = self_node->removeChild(target_node, shared_exception_state->exception_state);
if (shared_exception_state->exception_state.HasException()) {
return WebFValue<Node, NodePublicMethods>::Null();
}
Expand All @@ -37,4 +37,4 @@ WebFValue<Node, NodePublicMethods> NodePublicMethods::RemoveChild(webf::Node* se
return WebFValue<Node, NodePublicMethods>(returned_node, returned_node->nodePublicMethods(), status_block);
}

} // namespace webf
} // namespace webf
13 changes: 12 additions & 1 deletion bridge/core/api/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
*/

#include "plugin_api/window.h"
#include "core/api/exception_state.h"
#include "core/dom/events/event_target.h"
#include "core/frame/window.h"

namespace webf {} // namespace webf
namespace webf {

void WindowPublicMethods::ScrollToWithXAndY(Window* window,
double x,
double y,
SharedExceptionState* shared_exception_state) {
window->scrollTo(x, y, shared_exception_state->exception_state);
}

} // namespace webf
3 changes: 3 additions & 0 deletions bridge/include/plugin_api/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ using PublicDocumentElementFromPoint =
using PublicDocumentGetDocumentElement = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentGetDocumentHeader = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentGetDocumentBody = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentClearCookie = void (*)(Document*, SharedExceptionState*);

struct DocumentPublicMethods : public WebFPublicMethods {
static WebFValue<Element, ElementPublicMethods> CreateElement(Document* document,
Expand Down Expand Up @@ -113,6 +114,7 @@ struct DocumentPublicMethods : public WebFPublicMethods {
static WebFValue<Element, HTMLElementPublicMethods> DocumentElement(Document* document);
static WebFValue<Element, HTMLElementPublicMethods> Head(Document* document);
static WebFValue<Element, HTMLElementPublicMethods> Body(Document* document);
static void ClearCookie(Document* document, SharedExceptionState* shared_exception_state);

double version{1.0};
ContainerNodePublicMethods container_node;
Expand All @@ -132,6 +134,7 @@ struct DocumentPublicMethods : public WebFPublicMethods {
PublicDocumentGetDocumentElement document_get_document_element{DocumentElement};
PublicDocumentGetDocumentHeader document_get_document_header{Head};
PublicDocumentGetDocumentBody document_get_document_body{Body};
PublicDocumentClearCookie document_clear_cookie{ClearCookie};
};

} // namespace webf
Expand Down
6 changes: 6 additions & 0 deletions bridge/include/plugin_api/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ class EventTarget;
class SharedExceptionState;
class ExecutingContext;
class Event;
class Window;

using PublicWindowScrollToWithXAndY = void (*)(Window*, double, double, SharedExceptionState*);

struct WindowPublicMethods : WebFPublicMethods {
static void ScrollToWithXAndY(Window* window, double x, double y, SharedExceptionState* shared_exception_state);

double version{1.0};
EventTargetPublicMethods event_target;
PublicWindowScrollToWithXAndY window_scroll_to_with_x_and_y{ScrollToWithXAndY};
};

} // namespace webf
Expand Down
7 changes: 7 additions & 0 deletions bridge/rusty_webf_sys/src/dom/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct DocumentRustMethods {
pub document_element: extern "C" fn(document: *const OpaquePtr) -> RustValue<ElementRustMethods>,
pub head: extern "C" fn(document: *const OpaquePtr) -> RustValue<ElementRustMethods>,
pub body: extern "C" fn(document: *const OpaquePtr) -> RustValue<ElementRustMethods>,
pub ___clear_cookies__: extern "C" fn(*const OpaquePtr, *const OpaquePtr),
}

impl RustMethods for DocumentRustMethods {}
Expand Down Expand Up @@ -263,6 +264,12 @@ impl Document {
};
return HTMLElement::initialize(body_element_value.value, event_target.context(), body_element_value.method_pointer, body_element_value.status);
}

pub fn ___clear_cookies__(&self, exception_state: &ExceptionState) {
unsafe {
((*self.method_pointer).___clear_cookies__)(self.ptr(), exception_state.ptr);
}
}
}

trait DocumentMethods: ContainerNodeMethods {}
Expand Down
14 changes: 10 additions & 4 deletions bridge/rusty_webf_sys/src/frame/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
* Copyright (C) 2022-present The WebF authors. All rights reserved.
*/

use std::ffi::c_double;
use crate::event_target::{EventTargetRustMethods, RustMethods};
use crate::executing_context::ExecutingContext;
use crate::{OpaquePtr, RustValueStatus};
use std::ffi::*;
use crate::*;

#[repr(C)]
pub struct WindowRustMethods {
pub version: c_double,
pub event_target: EventTargetRustMethods,
pub scroll_to_with_x_and_y: extern "C" fn(*const OpaquePtr, c_double, c_double, *const OpaquePtr),
}

impl RustMethods for WindowRustMethods {}
Expand All @@ -30,4 +29,11 @@ impl Window {
status,
}
}

pub fn scroll_to_with_x_and_y(&self, x: f64, y: f64, exception_state: &ExceptionState) {
unsafe {
((*self.method_pointer).scroll_to_with_x_and_y)(self.ptr, x, y, exception_state.ptr)
}
}

}
1 change: 0 additions & 1 deletion bridge/rusty_webf_sys/src/webf_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub struct WebFNativeFunctionContextData {

impl Drop for WebFNativeFunctionContextData {
fn drop(&mut self) {
println!("Drop webf native function context data");
}
}

Expand Down
5 changes: 5 additions & 0 deletions integration_tests/rust_builder/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ crate-type = ["cdylib", "staticlib"]

[dependencies]
webf-sys = "0.16.0"
webf_test_macros = "0.1.0"
webf_test_utils = "0.1.0"
ctor = "0.2.9"

[patch.crates-io]
webf-sys = { path = "../../../bridge/rusty_webf_sys" }
webf_test_macros = { path = "./webf_test_macros" }
webf_test_utils = { path = "./webf_test_utils" }
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use webf_sys::ExecutingContext;
use webf_test_macros::webf_test_async;

#[webf_test_async]
pub async fn test_should_work_with_set_item(context: ExecutingContext) {
let storage = context.async_storage();
let exception_state = context.create_exception_state();
Expand Down
37 changes: 2 additions & 35 deletions integration_tests/rust_builder/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::cell::RefCell;
use std::ffi::c_void;
use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
use webf_sys::executing_context::ExecutingContextRustMethods;
use webf_sys::{initialize_webf_api, ExecutingContext, FutureRuntime, RustValue};
Expand All @@ -10,49 +8,18 @@ pub mod async_storage;
pub mod navigator;
pub mod storage;

fn webf_test_runner(tests: &[&dyn Fn(ExecutingContext)], context: ExecutingContext) {
println!("Running {} tests", tests.len());
for test in tests {
test(context.clone());
println!("Test passed");
}
}

type TestFn = Box<dyn Fn(ExecutingContext) -> Pin<Box<dyn Future<Output = ()>>>>;

async fn webf_test_runner_async(tests: &[TestFn], context: ExecutingContext) {
println!("Running {} tests", tests.len());
for test in tests {
test(context.clone()).await;
println!("Test passed");
}
}

#[no_mangle]
pub extern "C" fn init_webf_test_app(handle: RustValue<ExecutingContextRustMethods>) -> *mut c_void {
let context: ExecutingContext = initialize_webf_api(handle);
let context_async = context.clone();

let tests: &[&dyn Fn(ExecutingContext)] = &[
&navigator::navigator::test_user_agent,
&navigator::navigator::test_hardware_concurrency,
&storage::set::test_local_storage_method_access,
&storage::set::test_session_storage_method_access,
];

webf_test_runner(tests, context);
webf_test_utils::sync_runner::run_tests(context);

let runtime = Rc::new(RefCell::new(FutureRuntime::new()));

let context_async_runtime = context_async.clone();
runtime.borrow_mut().spawn(async move {
let tests: &[TestFn] = &[
Box::new(|context| {
Box::pin(async_storage::async_storage::test_should_work_with_set_item(context))
}),
];

webf_test_runner_async(tests, context_async_runtime).await;
webf_test_utils::async_runner::run_tests(context_async_runtime).await;
});

let runtime_run_task_callback = Box::new(move || {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use webf_sys::ExecutingContext;
use webf_test_macros::webf_test;

#[webf_test]
pub fn test_hardware_concurrency(context: ExecutingContext) {
let navigator = context.navigator();
let exception_state = context.create_exception_state();
Expand All @@ -8,6 +10,7 @@ pub fn test_hardware_concurrency(context: ExecutingContext) {
assert!(hardware_concurrency > 0);
}

#[webf_test]
pub fn test_user_agent(context: ExecutingContext) {
let navigator = context.navigator();
let exception_state = context.create_exception_state();
Expand Down
3 changes: 3 additions & 0 deletions integration_tests/rust_builder/rust/src/storage/set.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use webf_sys::ExecutingContext;
use webf_test_macros::webf_test;

#[webf_test]
pub fn test_local_storage_method_access(context: ExecutingContext) {
let storage = context.local_storage();
let exception_state = context.create_exception_state();
Expand All @@ -19,6 +21,7 @@ pub fn test_local_storage_method_access(context: ExecutingContext) {
assert_eq!(keys.len(), 0);
}

#[webf_test]
pub fn test_session_storage_method_access(context: ExecutingContext) {
let storage = context.session_storage();
let exception_state = context.create_exception_state();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
.idea
Cargo.lock
11 changes: 11 additions & 0 deletions integration_tests/rust_builder/rust/webf_test_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "webf_test_macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
quote = "1.0.38"
syn = { version = "2.0.96", features = ["full"] }
58 changes: 58 additions & 0 deletions integration_tests/rust_builder/rust/webf_test_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use proc_macro::TokenStream;
use syn::spanned::Spanned;
use syn::{parse_macro_input, ItemFn};
use quote::quote;

#[proc_macro_attribute]
pub fn webf_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input_fn = parse_macro_input!(item as ItemFn);

let fn_name = input_fn.sig.ident.to_string();
let fn_ident = input_fn.sig.ident.clone();
let prefixed_fn_name = syn::Ident::new(&format!("register_test_{}", fn_name), fn_name.span());

let expanded = quote! {
#input_fn

#[ctor::ctor]
fn #prefixed_fn_name() {
webf_test_utils::sync_runner::register_test_case(
module_path!().to_string(),
file!().to_string(),
#fn_name.to_string(),
std::sync::Arc::new(#fn_ident)
);
}
};

expanded.into()
}

#[proc_macro_attribute]
pub fn webf_test_async(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input_fn = parse_macro_input!(item as ItemFn);

let fn_name = input_fn.sig.ident.to_string();
let fn_ident = input_fn.sig.ident.clone();
let prefixed_fn_name = syn::Ident::new(&format!("register_test_async_{}", fn_name), fn_name.span());

let expanded = quote! {
#input_fn

#[ctor::ctor]
fn #prefixed_fn_name() {
webf_test_utils::async_runner::register_test_case(
module_path!().to_string(),
file!().to_string(),
#fn_name.to_string(),
std::sync::Arc::new(
Box::new(|context| {
Box::pin(#fn_ident(context))
})
)
);
}
};

expanded.into()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
.idea
Cargo.lock
10 changes: 10 additions & 0 deletions integration_tests/rust_builder/rust/webf_test_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "webf_test_utils"
version = "0.1.0"
edition = "2021"

[dependencies]
webf-sys = "0.16.0"

[patch.crates-io]
webf-sys = { path = "../../../../bridge/rusty_webf_sys" }
Loading

0 comments on commit cbb6e71

Please sign in to comment.