Skip to content

Commit ef6c36b

Browse files
Add tests for Event
Signed-off-by: Francis Bouvier <francis@lightpanda.io>
1 parent b50f5fd commit ef6c36b

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

src/dom/event_target.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub fn testExecFn(
6060
var common = [_]Case{
6161
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
6262
.{ .src = "let para = document.getElementById('para')", .ex = "undefined" },
63+
// NOTE: as some event properties will change during the event dispatching phases
64+
// we need to copy thoses values in order to check them afterwards
6365
.{ .src =
6466
\\var nb = 0; var evt; var phase; var cur;
6567
\\function cbk(event) {
@@ -121,6 +123,7 @@ pub fn testExecFn(
121123
.{ .src = "nb", .ex = "1" },
122124
.{ .src = "evt instanceof Event", .ex = "true" },
123125
.{ .src = "evt.type", .ex = "bubbles" },
126+
.{ .src = "evt.bubbles", .ex = "true" },
124127
.{ .src = "phase", .ex = "2" },
125128
.{ .src = "cur.getAttribute('id')", .ex = "content" },
126129
};

src/events/event.zig

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ const std = @import("std");
22

33
const generate = @import("../generate.zig");
44

5+
const jsruntime = @import("jsruntime");
6+
const Callback = jsruntime.Callback;
7+
const Case = jsruntime.test_utils.Case;
8+
const checkCases = jsruntime.test_utils.checkCases;
9+
510
const parser = @import("../netsurf.zig");
611

712
const DOMException = @import("../dom/exceptions.zig").DOMException;
@@ -73,15 +78,15 @@ pub const Event = struct {
7378

7479
// Methods
7580

76-
pub fn get_stopPropagation(self: *parser.Event) !void {
81+
pub fn _stopPropagation(self: *parser.Event) !void {
7782
return try parser.eventStopPropagation(self);
7883
}
7984

80-
pub fn get_stopImmediatePropagation(self: *parser.Event) !void {
85+
pub fn _stopImmediatePropagation(self: *parser.Event) !void {
8186
return try parser.eventStopImmediatePropagation(self);
8287
}
8388

84-
pub fn get_preventDefault(self: *parser.Event) !void {
89+
pub fn _preventDefault(self: *parser.Event) !void {
8590
return try parser.eventPreventDefault(self);
8691
}
8792
};
@@ -92,3 +97,77 @@ pub const Interfaces = generate.Tuple(.{
9297
});
9398
const Generated = generate.Union.compile(Interfaces);
9499
pub const Union = Generated._union;
100+
101+
pub fn testExecFn(
102+
_: std.mem.Allocator,
103+
js_env: *jsruntime.Env,
104+
) anyerror!void {
105+
var common = [_]Case{
106+
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
107+
.{ .src = "let para = document.getElementById('para')", .ex = "undefined" },
108+
.{ .src = "var nb = 0; var evt", .ex = "undefined" },
109+
};
110+
try checkCases(js_env, &common);
111+
112+
var basic = [_]Case{
113+
.{ .src =
114+
\\content.addEventListener('target',
115+
\\function(e) {
116+
\\evt = e; nb = nb + 1;
117+
\\e.preventDefault();
118+
\\})
119+
, .ex = "undefined" },
120+
.{ .src = "content.dispatchEvent(new Event('target', {bubbles: true, cancelable: true}))", .ex = "false" },
121+
.{ .src = "nb", .ex = "1" },
122+
.{ .src = "evt.target === content", .ex = "true" },
123+
.{ .src = "evt.bubbles", .ex = "true" },
124+
.{ .src = "evt.cancelable", .ex = "true" },
125+
.{ .src = "evt.defaultPrevented", .ex = "true" },
126+
.{ .src = "evt.isTrusted", .ex = "true" },
127+
.{ .src = "evt.timestamp > 1704063600", .ex = "true" }, // 2024/01/01 00:00
128+
// event.type, event.currentTarget, event.phase checked in EventTarget
129+
};
130+
try checkCases(js_env, &basic);
131+
132+
var stop = [_]Case{
133+
.{ .src = "nb = 0", .ex = "0" },
134+
.{ .src =
135+
\\content.addEventListener('stop',
136+
\\function(e) {
137+
\\e.stopPropagation();
138+
\\nb = nb + 1;
139+
\\}, true)
140+
, .ex = "undefined" },
141+
// the following event listener will not be invoked
142+
.{ .src =
143+
\\para.addEventListener('stop',
144+
\\function(e) {
145+
\\nb = nb + 1;
146+
\\})
147+
, .ex = "undefined" },
148+
.{ .src = "para.dispatchEvent(new Event('stop'))", .ex = "true" },
149+
.{ .src = "nb", .ex = "1" }, // will be 2 if event was not stopped at content event listener
150+
};
151+
try checkCases(js_env, &stop);
152+
153+
var stop_immediate = [_]Case{
154+
.{ .src = "nb = 0", .ex = "0" },
155+
.{ .src =
156+
\\content.addEventListener('immediate',
157+
\\function(e) {
158+
\\e.stopImmediatePropagation();
159+
\\nb = nb + 1;
160+
\\})
161+
, .ex = "undefined" },
162+
// the following event listener will not be invoked
163+
.{ .src =
164+
\\content.addEventListener('immediate',
165+
\\function(e) {
166+
\\nb = nb + 1;
167+
\\})
168+
, .ex = "undefined" },
169+
.{ .src = "content.dispatchEvent(new Event('immediate'))", .ex = "true" },
170+
.{ .src = "nb", .ex = "1" }, // will be 2 if event was not stopped at first content event listener
171+
};
172+
try checkCases(js_env, &stop_immediate);
173+
}

src/run_tests.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const DOMTokenListExecFn = @import("dom/token_list.zig").testExecFn;
2121
const NodeListTestExecFn = @import("dom/nodelist.zig").testExecFn;
2222
const AttrTestExecFn = @import("dom/attribute.zig").testExecFn;
2323
const EventTargetTestExecFn = @import("dom/event_target.zig").testExecFn;
24+
const EventTestExecFn = @import("events/event.zig").testExecFn;
2425

2526
pub const Types = jsruntime.reflect(apiweb.Interfaces);
2627

@@ -75,6 +76,7 @@ fn testsAllExecFn(
7576
NodeListTestExecFn,
7677
AttrTestExecFn,
7778
EventTargetTestExecFn,
79+
EventTestExecFn,
7880
};
7981

8082
inline for (testFns) |testFn| {

0 commit comments

Comments
 (0)