mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-29 23:23:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			180 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
| const std = @import("std");
 | |
| const builtin = @import("builtin");
 | |
| 
 | |
| const jsruntime = @import("jsruntime");
 | |
| const generate = @import("generate.zig");
 | |
| 
 | |
| const parser = @import("netsurf.zig");
 | |
| const apiweb = @import("apiweb.zig");
 | |
| const Window = @import("html/window.zig").Window;
 | |
| const xhr = @import("xhr/xhr.zig");
 | |
| 
 | |
| const documentTestExecFn = @import("dom/document.zig").testExecFn;
 | |
| const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn;
 | |
| const nodeTestExecFn = @import("dom/node.zig").testExecFn;
 | |
| const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn;
 | |
| const textTestExecFn = @import("dom/text.zig").testExecFn;
 | |
| const elementTestExecFn = @import("dom/element.zig").testExecFn;
 | |
| const HTMLCollectionTestExecFn = @import("dom/html_collection.zig").testExecFn;
 | |
| const DOMExceptionTestExecFn = @import("dom/exceptions.zig").testExecFn;
 | |
| const DOMImplementationExecFn = @import("dom/implementation.zig").testExecFn;
 | |
| const NamedNodeMapExecFn = @import("dom/namednodemap.zig").testExecFn;
 | |
| const DOMTokenListExecFn = @import("dom/token_list.zig").testExecFn;
 | |
| const NodeListTestExecFn = @import("dom/nodelist.zig").testExecFn;
 | |
| const AttrTestExecFn = @import("dom/attribute.zig").testExecFn;
 | |
| const EventTargetTestExecFn = @import("dom/event_target.zig").testExecFn;
 | |
| const EventTestExecFn = @import("events/event.zig").testExecFn;
 | |
| const XHRTestExecFn = xhr.testExecFn;
 | |
| const ProgressEventTestExecFn = @import("xhr/progress_event.zig").testExecFn;
 | |
| 
 | |
| pub const Types = jsruntime.reflect(apiweb.Interfaces);
 | |
| 
 | |
| var doc: *parser.DocumentHTML = undefined;
 | |
| 
 | |
| fn testExecFn(
 | |
|     alloc: std.mem.Allocator,
 | |
|     js_env: *jsruntime.Env,
 | |
|     comptime execFn: jsruntime.ContextExecFn,
 | |
| ) anyerror!void {
 | |
|     // start JS env
 | |
|     try js_env.start(alloc);
 | |
|     defer js_env.stop();
 | |
| 
 | |
|     // document
 | |
|     const file = try std.fs.cwd().openFile("test.html", .{});
 | |
|     defer file.close();
 | |
| 
 | |
|     doc = try parser.documentHTMLParse(file.reader(), "UTF-8");
 | |
|     defer parser.documentHTMLClose(doc) catch |err| {
 | |
|         std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
 | |
|     };
 | |
| 
 | |
|     // alias global as self and window
 | |
|     var window = Window.create(null);
 | |
|     window.replaceDocument(doc);
 | |
|     try js_env.bindGlobal(window);
 | |
| 
 | |
|     // run test
 | |
|     try execFn(alloc, js_env);
 | |
| }
 | |
| 
 | |
| fn testsAllExecFn(
 | |
|     alloc: std.mem.Allocator,
 | |
|     js_env: *jsruntime.Env,
 | |
| ) anyerror!void {
 | |
|     const testFns = [_]jsruntime.ContextExecFn{
 | |
|         documentTestExecFn,
 | |
|         HTMLDocumentTestExecFn,
 | |
|         nodeTestExecFn,
 | |
|         characterDataTestExecFn,
 | |
|         textTestExecFn,
 | |
|         elementTestExecFn,
 | |
|         HTMLCollectionTestExecFn,
 | |
|         DOMExceptionTestExecFn,
 | |
|         DOMImplementationExecFn,
 | |
|         NamedNodeMapExecFn,
 | |
|         DOMTokenListExecFn,
 | |
|         NodeListTestExecFn,
 | |
|         AttrTestExecFn,
 | |
|         EventTargetTestExecFn,
 | |
|         EventTestExecFn,
 | |
|         XHRTestExecFn,
 | |
|         ProgressEventTestExecFn,
 | |
|     };
 | |
| 
 | |
|     inline for (testFns) |testFn| {
 | |
|         try testExecFn(alloc, js_env, testFn);
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub fn main() !void {
 | |
|     try testJSRuntime();
 | |
| 
 | |
|     std.debug.print("\n", .{});
 | |
|     for (builtin.test_functions) |test_fn| {
 | |
|         try test_fn.func();
 | |
|         std.debug.print("{s}\tOK\n", .{test_fn.name});
 | |
|     }
 | |
| }
 | |
| 
 | |
| test {
 | |
|     const AsyncTest = @import("async/test.zig");
 | |
|     std.testing.refAllDecls(AsyncTest);
 | |
| 
 | |
|     const DumpTest = @import("browser/dump.zig");
 | |
|     std.testing.refAllDecls(DumpTest);
 | |
| }
 | |
| 
 | |
| fn testJSRuntime() !void {
 | |
|     // generate tests
 | |
|     try generate.tests();
 | |
| 
 | |
|     // create JS vm
 | |
|     const vm = jsruntime.VM.init();
 | |
|     defer vm.deinit();
 | |
| 
 | |
|     var bench_alloc = jsruntime.bench_allocator(std.testing.allocator);
 | |
|     var arena_alloc = std.heap.ArenaAllocator.init(bench_alloc.allocator());
 | |
|     defer arena_alloc.deinit();
 | |
| 
 | |
|     try jsruntime.loadEnv(&arena_alloc, testsAllExecFn);
 | |
| }
 | |
| 
 | |
| test "DocumentHTMLParseFromStr" {
 | |
|     const file = try std.fs.cwd().openFile("test.html", .{});
 | |
|     defer file.close();
 | |
| 
 | |
|     const str = try file.readToEndAlloc(std.testing.allocator, std.math.maxInt(u32));
 | |
|     defer std.testing.allocator.free(str);
 | |
| 
 | |
|     doc = try parser.documentHTMLParseFromStr(str);
 | |
|     parser.documentHTMLClose(doc) catch {};
 | |
| }
 | |
| 
 | |
| // https://github.com/lightpanda-io/libdom/issues/4
 | |
| test "bug document html parsing #4" {
 | |
|     const file = try std.fs.cwd().openFile("tests/html/bug-html-parsing-4.html", .{});
 | |
|     defer file.close();
 | |
| 
 | |
|     doc = try parser.documentHTMLParse(file.reader(), "UTF-8");
 | |
|     parser.documentHTMLClose(doc) catch {};
 | |
| }
 | |
| 
 | |
| test "Window is a libdom event target" {
 | |
|     var window = Window.create(null);
 | |
| 
 | |
|     const event = try parser.eventCreate();
 | |
|     try parser.eventInit(event, "foo", .{});
 | |
| 
 | |
|     const et = parser.toEventTarget(Window, &window);
 | |
|     _ = try parser.eventTargetDispatchEvent(et, event);
 | |
| }
 | |
| 
 | |
| test "DocumentHTML is a libdom event target" {
 | |
|     doc = try parser.documentHTMLParseFromStr("<body></body>");
 | |
|     parser.documentHTMLClose(doc) catch {};
 | |
| 
 | |
|     const event = try parser.eventCreate();
 | |
|     try parser.eventInit(event, "foo", .{});
 | |
| 
 | |
|     const et = parser.toEventTarget(parser.DocumentHTML, doc);
 | |
|     _ = try parser.eventTargetDispatchEvent(et, event);
 | |
| }
 | |
| 
 | |
| test "XMLHttpRequest.validMethod" {
 | |
|     // valid methods
 | |
|     for ([_][]const u8{ "get", "GET", "head", "HEAD" }) |tc| {
 | |
|         _ = try xhr.XMLHttpRequest.validMethod(tc);
 | |
|     }
 | |
| 
 | |
|     // forbidden
 | |
|     for ([_][]const u8{ "connect", "CONNECT" }) |tc| {
 | |
|         try std.testing.expectError(parser.DOMError.Security, xhr.XMLHttpRequest.validMethod(tc));
 | |
|     }
 | |
| 
 | |
|     // syntax
 | |
|     for ([_][]const u8{ "foo", "BAR" }) |tc| {
 | |
|         try std.testing.expectError(parser.DOMError.Syntax, xhr.XMLHttpRequest.validMethod(tc));
 | |
|     }
 | |
| }
 | 
