@@ -196,8 +196,7 @@ pub const HTMLAnchorElement = struct {
196
196
}
197
197
198
198
pub fn set_href (self : * parser.Anchor , href : []const u8 , page : * const Page ) ! void {
199
- const stitch = @import ("../../url.zig" ).stitch ;
200
- const full = try stitch (page .call_arena , href , page .url .raw , .{});
199
+ const full = try urlStitch (page .call_arena , href , page .url .raw , .{});
201
200
return try parser .anchorSetHref (self , full );
202
201
}
203
202
@@ -695,7 +694,7 @@ pub const HTMLInputElement = struct {
695
694
return try parser .inputGetSrc (self );
696
695
}
697
696
pub fn set_src (self : * parser.Input , src : []const u8 , page : * Page ) ! void {
698
- const new_src = try urlStitch (page .call_arena , src , page .url .raw );
697
+ const new_src = try urlStitch (page .call_arena , src , page .url .raw , .{ . alloc = .if_needed } );
699
698
try parser .inputSetSrc (self , new_src );
700
699
}
701
700
pub fn get_type (self : * parser.Input ) ! []const u8 {
@@ -1266,40 +1265,55 @@ test "Browser.HTML.Element" {
1266
1265
.{ "a.href" , "https://lightpanda.io/opensource-browser/about" },
1267
1266
}, .{});
1268
1267
}
1269
- test "Browser.HTML.Element .propeties" {
1268
+ test "Browser.HTML.HtmlInputElement .propeties" {
1270
1269
var runner = try testing .jsRunner (testing .tracking_allocator , .{ .url = "https://lightpanda.io/noslashattheend" });
1271
1270
defer runner .deinit ();
1272
- const bool_valids = [_ ]Valid {
1273
- .{ .input = "true" , .is_str = false },
1274
- .{ .input = "" , .is_str = true , .expected = "false" },
1275
- .{ .input = "13.5" , .is_str = true , .expected = "true" },
1276
- };
1277
- const str_valids = [_ ]Valid {
1278
- .{ .input = "foo" , .is_str = true },
1279
- .{ .input = "5" , .is_str = false , .expected = "5" },
1280
- .{ .input = "" , .is_str = true },
1281
- .{ .input = "document" , .is_str = false , .expected = "[object HTMLDocument]" },
1282
- };
1283
- // TODO these tests are mostly just data should we store them in Sqlite or so?
1284
- try testCreateElement (& runner , "input" );
1285
- // Valid input.form is tested separately :Browser.HTML.Element.propeties.input.form
1286
- try testProperty (& runner , "input" , "form" , "null" , "null" , &.{}, &.{.{ .input = "foo" , .is_str = true }});
1287
- try testProperty (& runner , "input" , "accept" , "" , "" , & str_valids , &.{});
1288
- try testProperty (& runner , "input" , "alt" , "" , "" , & str_valids , &.{});
1289
- try testProperty (& runner , "input" , "disabled" , "false" , "false" , & bool_valids , &.{});
1290
- try testProperty (& runner , "input" , "maxLength" , "-1" , "0" , &.{.{ .input = "5" , .is_str = false }}, &.{.{ .input = "banana" , .is_str = true }});
1291
- try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.maxLength = -45" , null }}, .{}));
1292
- try testProperty (& runner , "input" , "name" , "" , "" , & str_valids , &.{});
1293
- try testProperty (& runner , "input" , "readOnly" , "false" , "false" , & bool_valids , &.{});
1294
- try testProperty (& runner , "input" , "size" , "20" , "20" , &.{.{ .input = "5" , .is_str = false }}, &.{.{ .input = "-26" , .is_str = false }});
1295
- try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.size = 0" , null }}, .{}));
1296
- try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.size = 'banana'" , null }}, .{}));
1297
- try testProperty (& runner , "input" , "src" , "" , "" , &.{
1298
- .{ .input = "foo" , .is_str = true , .expected = "https://lightpanda.io/foo" }, // TODO stitch should work with spaces -> %20
1299
- .{ .input = "-3" , .is_str = false , .expected = "https://lightpanda.io/-3" },
1300
- .{ .input = "" , .is_str = true , .expected = "https://lightpanda.io/noslashattheend" },
1301
- }, &.{});
1302
- try testProperty (& runner , "input" , "type" , "text" , "text" , &.{.{ .input = "checkbox" , .is_str = true }}, &.{.{ .input = "5" , .is_str = true }});
1271
+ var alloc = std .heap .ArenaAllocator .init (runner .app .allocator );
1272
+ defer alloc .deinit ();
1273
+ const arena = alloc .allocator ();
1274
+
1275
+ try runner .testCases (&.{.{ "let elem_input = document.createElement('input')" , null }}, .{});
1276
+
1277
+ try runner .testCases (&.{.{ "elem_input.form" , "null" }}, .{}); // Initial value
1278
+ // Valid input.form is tested separately :Browser.HTML.HtmlInputElement.propeties.form
1279
+ try testProperty (arena , & runner , "elem_input.form" , "null" , &.{.{ .input = "'foo'" }}); // Invalid
1280
+
1281
+ try runner .testCases (&.{.{ "elem_input.accept" , "" }}, .{}); // Initial value
1282
+ try testProperty (arena , & runner , "elem_input.accept" , null , & str_valids ); // Valid
1283
+
1284
+ try runner .testCases (&.{.{ "elem_input.alt" , "" }}, .{}); // Initial value
1285
+ try testProperty (arena , & runner , "elem_input.alt" , null , & str_valids ); // Valid
1286
+
1287
+ try runner .testCases (&.{.{ "elem_input.disabled" , "false" }}, .{}); // Initial value
1288
+ try testProperty (arena , & runner , "elem_input.disabled" , null , & bool_valids ); // Valid
1289
+
1290
+ try runner .testCases (&.{.{ "elem_input.maxLength" , "-1" }}, .{}); // Initial value
1291
+ try testProperty (arena , & runner , "elem_input.maxLength" , null , &.{.{ .input = "5" }}); // Valid
1292
+ try testProperty (arena , & runner , "elem_input.maxLength" , "0" , &.{.{ .input = "'banana'" }}); // Invalid
1293
+ try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.maxLength = -45" , null }}, .{})); // Error
1294
+
1295
+ try runner .testCases (&.{.{ "elem_input.name" , "" }}, .{}); // Initial value
1296
+ try testProperty (arena , & runner , "elem_input.name" , null , & str_valids ); // Valid
1297
+
1298
+ try runner .testCases (&.{.{ "elem_input.readOnly" , "false" }}, .{}); // Initial value
1299
+ try testProperty (arena , & runner , "elem_input.readOnly" , null , & bool_valids ); // Valid
1300
+
1301
+ try runner .testCases (&.{.{ "elem_input.size" , "20" }}, .{}); // Initial value
1302
+ try testProperty (arena , & runner , "elem_input.size" , null , &.{.{ .input = "5" }}); // Valid
1303
+ try testProperty (arena , & runner , "elem_input.size" , "20" , &.{.{ .input = "-26" }}); // Invalid
1304
+ try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.size = 0" , null }}, .{})); // Error
1305
+ try testing .expectError (error .ExecutionError , runner .testCases (&.{.{ "elem_input.size = 'banana'" , null }}, .{})); // Error
1306
+
1307
+ try runner .testCases (&.{.{ "elem_input.src" , "" }}, .{}); // Initial value
1308
+ try testProperty (arena , & runner , "elem_input.src" , null , &.{
1309
+ .{ .input = "'foo'" , .expected = "https://lightpanda.io/foo" }, // TODO stitch should work with spaces -> %20
1310
+ .{ .input = "-3" , .expected = "https://lightpanda.io/-3" },
1311
+ .{ .input = "''" , .expected = "https://lightpanda.io/noslashattheend" },
1312
+ });
1313
+
1314
+ try runner .testCases (&.{.{ "elem_input.type" , "text" }}, .{}); // Initial value
1315
+ try testProperty (arena , & runner , "elem_input.type" , null , &.{.{ .input = "'checkbox'" , .expected = "checkbox" }}); // Valid
1316
+ try testProperty (arena , & runner , "elem_input.type" , "text" , &.{.{ .input = "'5'" }}); // Invalid
1303
1317
1304
1318
// Properties that are related
1305
1319
try runner .testCases (&.{
@@ -1335,7 +1349,7 @@ test "Browser.HTML.Element.propeties" {
1335
1349
.{ "input_value.value" , "mango" }, // Still mango
1336
1350
}, .{});
1337
1351
}
1338
- test "Browser.HTML.Element .propeties.input .form" {
1352
+ test "Browser.HTML.HtmlInputElement .propeties.form" {
1339
1353
var runner = try testing .jsRunner (testing .tracking_allocator , .{ .html =
1340
1354
\\ <form action="test.php" target="_blank">
1341
1355
\\ <p>
@@ -1348,62 +1362,42 @@ test "Browser.HTML.Element.propeties.input.form" {
1348
1362
try runner .testCases (&.{
1349
1363
.{ "let elem_input = document.querySelector('input')" , null },
1350
1364
}, .{});
1351
- try testProperty (& runner , "input" , "form" , "[object HTMLFormElement]" , "[object HTMLFormElement]" , &.{}, &.{.{ .input = "5" , .is_str = false }});
1365
+ try runner .testCases (&.{.{ "elem_input.form" , "[object HTMLFormElement]" }}, .{}); // Initial value
1366
+ try runner .testCases (&.{
1367
+ .{ "elem_input.form = 'foo'" , null },
1368
+ .{ "elem_input.form" , "[object HTMLFormElement]" }, // Invalid
1369
+ }, .{});
1352
1370
}
1353
1371
1354
- const Valid = struct {
1372
+ const Check = struct {
1355
1373
input : []const u8 ,
1356
- is_str : bool ,
1357
1374
expected : ? []const u8 = null , // Needed when input != expected
1358
1375
};
1359
- const Invalid = struct {
1360
- input : []const u8 ,
1361
- is_str : bool ,
1376
+ const bool_valids = [_ ]Check {
1377
+ .{ .input = "true" },
1378
+ .{ .input = "''" , .expected = "false" },
1379
+ .{ .input = "13.5" , .expected = "true" },
1380
+ };
1381
+ const str_valids = [_ ]Check {
1382
+ .{ .input = "'foo'" , .expected = "foo" },
1383
+ .{ .input = "5" , .expected = "5" },
1384
+ .{ .input = "''" , .expected = "" },
1385
+ .{ .input = "document" , .expected = "[object HTMLDocument]" },
1362
1386
};
1363
1387
1364
- fn testCreateElement (runner : * testing.JsRunner , comptime name : []const u8 ) ! void {
1365
- try runner .testCases (&.{
1366
- .{ "let elem_" ++ name ++ " = document.createElement('" ++ name ++ "')" , null },
1367
- }, .{});
1368
- }
1369
- // TODO reduce comptime
1370
- // Default is the expected value after creation and after setting an invalid value
1371
- // Valid input is expected to return itself or the expected value
1372
- // Invalid input is expected to return the default value
1373
- // .{ "elem.type", "text" }, // default
1374
- // .{ "elem.type = 'checkbox'", "checkbox" }, // valid
1375
- // .{ "elem.type", "checkbox" },
1376
- // .{ "elem.type = '5'", "5" }, // invalid
1388
+ // .{ "elem.type = '5'", "5" },
1377
1389
// .{ "elem.type", "text" },
1378
1390
fn testProperty (
1391
+ arena : std.mem.Allocator ,
1379
1392
runner : * testing.JsRunner ,
1380
- comptime name : []const u8 ,
1381
- comptime property : []const u8 ,
1382
- comptime initial : []const u8 ,
1383
- comptime default : []const u8 ,
1384
- comptime valids : []const Valid ,
1385
- comptime invalids : []const Invalid ,
1393
+ elem_dot_prop : []const u8 ,
1394
+ always : ? []const u8 , // Ignores checks' expected if set
1395
+ checks : []const Check ,
1386
1396
) ! void {
1387
- const elem_dot_prop = "elem_" ++ name ++ "." ++ property ;
1388
-
1389
- try runner .testCases (&.{
1390
- .{ elem_dot_prop , initial },
1391
- }, .{});
1392
-
1393
- inline for (valids ) | valid | {
1394
- const set_input = if (valid .is_str ) "'" ++ valid .input ++ "'" else valid .input ;
1395
- const expected = valid .expected orelse valid .input ;
1396
- try runner .testCases (&.{
1397
- .{ elem_dot_prop ++ " = " ++ set_input , null },
1398
- .{ elem_dot_prop , expected },
1399
- }, .{});
1400
- }
1401
-
1402
- inline for (invalids ) | invalid | {
1403
- const set_input = if (invalid .is_str ) "'" ++ invalid .input ++ "'" else invalid .input ;
1397
+ for (checks ) | check | {
1404
1398
try runner .testCases (&.{
1405
- .{ elem_dot_prop ++ " = " ++ set_input , null },
1406
- .{ elem_dot_prop , default },
1399
+ .{ try std . mem . concat ( arena , u8 , &.{ elem_dot_prop , " = " , check . input }) , null },
1400
+ .{ elem_dot_prop , always orelse check . expected orelse check . input },
1407
1401
}, .{});
1408
1402
}
1409
1403
}
0 commit comments