diff --git a/Cargo.lock b/Cargo.lock index 61f7048fcb..0c18a4e782 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -143,21 +143,21 @@ checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", "event-listener 5.2.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy 0.5.1", "futures-core", "pin-project-lite", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "10b3e585719c2358d2660232671ca8ca4ddb4be4ce8a1842d6c2dc8685303316" dependencies = [ "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-lite 2.3.0", "slab", ] @@ -175,9 +175,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" dependencies = [ "async-lock 3.3.0", "cfg-if", @@ -185,7 +185,7 @@ dependencies = [ "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.5.0", + "polling 3.6.0", "rustix", "slab", "tracing", @@ -225,19 +225,21 @@ dependencies = [ [[package]] name = "async-process" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451e3cf68011bd56771c79db04a9e333095ab6349f7e47592b788e9b98720cc8" +checksum = "d999d925640d51b662b7b4e404224dd81de70f4aa4a199383c2c5e5b86885fa3" dependencies = [ "async-channel 2.2.0", "async-io", "async-lock 3.3.0", "async-signal", + "async-task", "blocking", "cfg-if", "event-listener 5.2.0", "futures-lite 2.3.0", "rustix", + "tracing", "windows-sys 0.52.0", ] @@ -273,15 +275,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -340,7 +342,7 @@ dependencies = [ "async-channel 2.2.0", "async-lock 3.3.0", "async-task", - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-io", "futures-lite 2.3.0", "piper", @@ -580,10 +582,8 @@ dependencies = [ "color-eyre", "colored", "comfy-table", - "once_cell", "phf", "rayon", - "regex", "rustc-hash", "serde", "serde_json", @@ -606,9 +606,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "bus" @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", @@ -671,9 +671,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "calendrical_calculations" @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -731,9 +731,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -816,9 +816,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clipboard-win" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f9a0700e0127ba15d1d52dd742097f821cd9c65939303a44d970465040a297" +checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" dependencies = [ "error-code", ] @@ -1381,9 +1381,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" dependencies = [ "event-listener 5.2.0", "pin-project-lite", @@ -1422,9 +1422,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fd-lock" @@ -1522,7 +1522,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-core", "futures-io", "parking", @@ -2149,7 +2149,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b694dc9f70c3bda874626d2aed13b780f137aab435f4e9814121955cf706122e" dependencies = [ - "memoffset 0.9.0", + "memoffset 0.9.1", ] [[package]] @@ -2210,9 +2210,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jemalloc-sys" @@ -2289,9 +2289,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" dependencies = [ "cc", "libc", @@ -2360,6 +2360,15 @@ dependencies = [ "libc", ] +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + [[package]] name = "matrixmultiply" version = "0.3.8" @@ -2386,9 +2395,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memmap2" @@ -2419,9 +2428,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -2618,9 +2627,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2748,9 +2757,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2765,7 +2774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-io", ] @@ -2821,12 +2830,13 @@ dependencies = [ [[package]] name = "polling" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi", "pin-project-lite", "rustix", "tracing", @@ -3035,7 +3045,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3056,7 +3066,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3067,20 +3077,20 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "region" -version = "3.0.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" dependencies = [ "bitflags 1.3.2", "libc", - "mach", - "winapi", + "mach2", + "windows-sys 0.52.0", ] [[package]] @@ -3169,9 +3179,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ "bitflags 2.5.0", "errno", @@ -3182,9 +3192,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" dependencies = [ "log", "ring", @@ -3196,9 +3206,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" [[package]] name = "rustls-webpki" @@ -3404,9 +3414,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.33" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap 2.2.6", "itoa", @@ -3494,9 +3504,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" dependencies = [ "serde", ] @@ -3618,9 +3628,9 @@ checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -3708,7 +3718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", + "fastrand 2.0.2", "rustix", "windows-sys 0.52.0", ] @@ -3754,7 +3764,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3765,7 +3775,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "test-case-core", ] @@ -3949,7 +3959,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.8", + "toml_edit 0.22.9", ] [[package]] @@ -3974,9 +3984,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.8" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12219811e0c1ba077867254e5ad62ee2c9c190b0d957110750ac0cda1ae96cd" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap 2.2.6", "serde", @@ -4173,9 +4183,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" [[package]] name = "valuable" diff --git a/core/engine/src/lib.rs b/core/engine/src/lib.rs index 448731a5fd..c017bfb4c6 100644 --- a/core/engine/src/lib.rs +++ b/core/engine/src/lib.rs @@ -79,6 +79,11 @@ compile_error!("Boa requires a lock free `AtomicUsize` in order to work properly extern crate self as boa_engine; extern crate static_assertions as sa; +pub use boa_ast as ast; +pub use boa_gc as gc; +pub use boa_interner as interner; +pub use boa_parser as parser; + pub mod bigint; pub mod builtins; pub mod bytecompiler; diff --git a/core/engine/src/module/loader.rs b/core/engine/src/module/loader.rs index 7381e4109b..c7d8855df5 100644 --- a/core/engine/src/module/loader.rs +++ b/core/engine/src/module/loader.rs @@ -308,6 +308,18 @@ impl ModuleLoader for SimpleModuleLoader { finish_load(result, context); } + + fn register_module(&self, specifier: JsString, module: Module) { + let path = PathBuf::from(specifier.to_std_string_escaped()); + + self.insert(path, module); + } + + fn get_module(&self, specifier: JsString) -> Option { + let path = specifier.to_std_string_escaped(); + + self.get(Path::new(&path)) + } } #[cfg(test)] diff --git a/test262_config.toml b/test262_config.toml index 28740c7a32..4512c19913 100644 --- a/test262_config.toml +++ b/test262_config.toml @@ -1,4 +1,4 @@ -commit = "6f7ae1f311a7b01ef2358de7f4f6fd42c3ae3839" +commit = "b73f7d662d51584bfee6d3ed274b676d313b646a" [ignored] # Not implemented yet: diff --git a/tests/tester/Cargo.toml b/tests/tester/Cargo.toml index 155e8a65b7..0d3cd7634d 100644 --- a/tests/tester/Cargo.toml +++ b/tests/tester/Cargo.toml @@ -17,11 +17,9 @@ boa_runtime.workspace = true boa_gc.workspace = true clap = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } -serde_yaml = "0.9.33" +serde_yaml = "0.9.34" # TODO: Track https://github.com/saphyr-rs/saphyr. serde_json.workspace = true bitflags.workspace = true -regex.workspace = true -once_cell.workspace = true colored.workspace = true rustc-hash = { workspace = true, features = ["std"] } rayon = "1.10.0" diff --git a/tests/tester/src/edition.rs b/tests/tester/src/edition.rs index 1df3f8ba68..3be48b570c 100644 --- a/tests/tester/src/edition.rs +++ b/tests/tester/src/edition.rs @@ -73,6 +73,10 @@ static FEATURE_EDITION: phf::Map<&'static str, SpecEdition> = phf::phf_map! { // https://github.com/tc39/proposal-json-parse-with-source "json-parse-with-source" => SpecEdition::ESNext, + // Regular expression modifiers + // https://github.com/tc39/proposal-regexp-modifiers + "regexp-modifiers" => SpecEdition::ESNext, + // Iterator Helpers // https://github.com/tc39/proposal-iterator-helpers "iterator-helpers" => SpecEdition::ESNext, @@ -81,6 +85,14 @@ static FEATURE_EDITION: phf::Map<&'static str, SpecEdition> = phf::phf_map! { // https://github.com/tc39/proposal-set-methods "set-methods" => SpecEdition::ESNext, + // Explicit Resource Management + // https://github.com/tc39/proposal-explicit-resource-management + "explicit-resource-management" => SpecEdition::ESNext, + + // Float16Array + Math.f16round + // https://github.com/tc39/proposal-float16array + "Float16Array" => SpecEdition::ESNext, + // Part of the next ES15 edition "Atomics.waitAsync" => SpecEdition::ESNext, "regexp-v-flag" => SpecEdition::ESNext, diff --git a/tests/tester/src/exec/js262.rs b/tests/tester/src/exec/js262.rs index 350d5b51e4..62cedb9be5 100644 --- a/tests/tester/src/exec/js262.rs +++ b/tests/tester/src/exec/js262.rs @@ -189,7 +189,10 @@ fn sleep(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult JsResult { - Ok(JsValue::from(START.elapsed().as_millis() as f64)) + let clock = START + .get() + .ok_or_else(|| JsNativeError::typ().with_message("could not get the monotonic clock"))?; + Ok(JsValue::from(clock.elapsed().as_millis() as f64)) } /// Initializes the `$262.agent` object in the main agent. diff --git a/tests/tester/src/exec/mod.rs b/tests/tester/src/exec/mod.rs index 859e8a8d72..a8c7f177e3 100644 --- a/tests/tester/src/exec/mod.rs +++ b/tests/tester/src/exec/mod.rs @@ -13,14 +13,15 @@ use boa_engine::{ native_function::NativeFunction, object::FunctionObjectBuilder, optimizer::OptimizerOptions, + parser::source::ReadChar, property::Attribute, script::Script, - Context, JsArgs, JsError, JsNativeErrorKind, JsValue, Source, + Context, JsArgs, JsError, JsNativeErrorKind, JsResult, JsValue, Source, }; use colored::Colorize; use rayon::prelude::*; use rustc_hash::FxHashSet; -use std::{cell::RefCell, eprintln, rc::Rc}; +use std::{cell::RefCell, eprintln, path::Path, rc::Rc}; use self::js262::WorkerHandles; @@ -193,52 +194,77 @@ impl Test { } } + /// Creates the test result from the outcome and message. + fn create_result>>( + &self, + outcome: TestOutcomeResult, + text: S, + strict: bool, + verbosity: u8, + ) -> TestResult { + let result_text = text.into(); + + if verbosity > 1 { + println!( + "`{}`{}: {}", + self.path.display(), + if strict { " (strict)" } else { "" }, + match outcome { + TestOutcomeResult::Passed => "Passed".green(), + TestOutcomeResult::Ignored => "Ignored".yellow(), + TestOutcomeResult::Failed => "Failed".red(), + TestOutcomeResult::Panic => "⚠ Panic ⚠".red(), + } + ); + } else { + let symbol = match outcome { + TestOutcomeResult::Passed => ".".green(), + TestOutcomeResult::Ignored => "-".yellow(), + TestOutcomeResult::Failed | TestOutcomeResult::Panic => "F".red(), + }; + + print!("{symbol}"); + } + + if verbosity > 2 { + println!( + "`{}`{}: result text\n{result_text}\n", + self.path.display(), + if strict { " (strict)" } else { "" }, + ); + } + + TestResult { + name: self.name.clone(), + edition: self.edition, + result_text, + result: outcome, + } + } + /// Runs the test once, in strict or non-strict mode fn run_once( &self, harness: &Harness, strict: bool, - verbose: u8, + verbosity: u8, optimizer_options: OptimizerOptions, console: bool, ) -> TestResult { let Ok(source) = Source::from_filepath(&self.path) else { - if verbose > 1 { - println!( - "`{}`{}: {}", - self.path.display(), - if strict { " (strict mode)" } else { "" }, - "Invalid file".red() - ); - } else { - print!("{}", "F".red()); - } - return TestResult { - name: self.name.clone(), - edition: self.edition, - result: TestOutcomeResult::Failed, - result_text: Box::from("Could not read test file."), - }; + return self.create_result( + TestOutcomeResult::Failed, + "Could not read test file", + strict, + verbosity, + ); }; + if self.ignored { - if verbose > 1 { - println!( - "`{}`{}: {}", - self.path.display(), - if strict { " (strict mode)" } else { "" }, - "Ignored".yellow() - ); - } else { - print!("{}", "-".yellow()); - } - return TestResult { - name: self.name.clone(), - edition: self.edition, - result: TestOutcomeResult::Ignored, - result_text: Box::default(), - }; + return self.create_result(TestOutcomeResult::Ignored, "", strict, verbosity); } - if verbose > 1 { + + if verbosity > 1 { println!( "`{}`{}: starting", self.path.display(), @@ -248,47 +274,19 @@ impl Test { let result = std::panic::catch_unwind(|| match self.expected_outcome { Outcome::Positive => { - let async_result = AsyncResult::default(); - let loader = Rc::new( - SimpleModuleLoader::new( - self.path.parent().expect("test should have a parent dir"), - ) - .expect("test path should be canonicalizable"), - ); - let context = &mut Context::builder() - .module_loader(loader.clone()) - .can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) - .build() - .expect("cannot fail with default global object"); - - let mut handles = WorkerHandles::new(); - - if let Err(e) = self.set_up_env( - harness, - context, - async_result.clone(), - handles.clone(), - console, - ) { - return (false, e); - } - - context.set_optimizer_options(optimizer_options); + let (ref mut context, async_result, mut handles) = + match self.create_context(harness, optimizer_options, console) { + Ok(r) => r, + Err(e) => return (false, e), + }; // TODO: timeout let value = if self.is_module() { - let module = match Module::parse(source, None, context) { + let module = match parse_module_and_register(source, &self.path, context) { Ok(module) => module, Err(err) => return (false, format!("Uncaught {err}")), }; - loader.insert( - self.path - .canonicalize() - .expect("test path should be canonicalizable"), - module.clone(), - ); - let promise = module.load_link_evaluate(context); context.run_jobs(); @@ -337,9 +335,7 @@ impl Test { _ => {} } - let results = handles.join_all(); - - for result in results { + for result in handles.join_all() { match result { js262::WorkerResult::Err(msg) => return (false, msg), js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), @@ -362,8 +358,6 @@ impl Test { let context = &mut Context::default(); - context.set_optimizer_options(OptimizerOptions::OPTIMIZE_ALL); - if self.is_module() { match Module::parse(source, None, context) { Ok(_) => (false, "ModuleItemList parsing should fail".to_owned()), @@ -381,29 +375,17 @@ impl Test { phase: Phase::Resolution, error_type, } => { - let loader = Rc::new( - SimpleModuleLoader::new( - self.path.parent().expect("test should have a parent dir"), - ) - .expect("test path should be canonicalizable"), - ); - let context = &mut Context::builder() - .module_loader(loader.clone()) - .build() - .expect("cannot fail with default global object"); + let context = &mut match self.create_context(harness, optimizer_options, console) { + Ok(r) => r, + Err(e) => return (false, e), + } + .0; - let module = match Module::parse(source, None, context) { + let module = match parse_module_and_register(source, &self.path, context) { Ok(module) => module, Err(err) => return (false, format!("Uncaught {err}")), }; - loader.insert( - self.path - .canonicalize() - .expect("test path should be canonicalizable"), - module.clone(), - ); - let promise = module.load(context); context.run_jobs(); @@ -437,44 +419,18 @@ impl Test { phase: Phase::Runtime, error_type, } => { - let loader = Rc::new( - SimpleModuleLoader::new( - self.path.parent().expect("test should have a parent dir"), - ) - .expect("test path should be canonicalizable"), - ); - let context = &mut Context::builder() - .module_loader(loader.clone()) - .can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) - .build() - .expect("cannot fail with default global object"); - context.strict(strict); - context.set_optimizer_options(optimizer_options); - - let mut handles = WorkerHandles::new(); - - if let Err(e) = self.set_up_env( - harness, - context, - AsyncResult::default(), - handles.clone(), - console, - ) { - return (false, e); - } + let (ref mut context, _async_result, mut handles) = + match self.create_context(harness, optimizer_options, console) { + Ok(r) => r, + Err(e) => return (false, e), + }; + let error = if self.is_module() { - let module = match Module::parse(source, None, context) { + let module = match parse_module_and_register(source, &self.path, context) { Ok(module) => module, - Err(e) => return (false, format!("Uncaught {e}")), + Err(err) => return (false, format!("Uncaught {err}")), }; - loader.insert( - self.path - .canonicalize() - .expect("test path should be canonicalizable"), - module.clone(), - ); - let promise = module.load(context); context.run_jobs(); @@ -517,9 +473,7 @@ impl Test { } }; - let results = handles.join_all(); - - for result in results { + for result in handles.join_all() { match result { js262::WorkerResult::Err(msg) => return (false, msg), js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), @@ -548,65 +502,38 @@ impl Test { }, ); - if verbose > 1 { - println!( - "`{}`{}: {}", - self.path.display(), - if strict { " (strict mode)" } else { "" }, - if result == TestOutcomeResult::Passed { - "Passed".green() - } else if result == TestOutcomeResult::Failed { - "Failed".red() - } else { - "⚠ Panic ⚠".red() - } - ); - } else { - print!( - "{}", - if result == TestOutcomeResult::Passed { - ".".green() - } else { - "F".red() - } - ); - } - - if verbose > 2 { - println!( - "`{}`{}: result text", - self.path.display(), - if strict { " (strict mode)" } else { "" }, - ); - println!("{result_text}"); - println!(); - } - - TestResult { - name: self.name.clone(), - edition: self.edition, - result, - result_text: result_text.into_boxed_str(), - } + self.create_result(result, result_text, strict, verbosity) } - /// Sets the environment up to run the test. - fn set_up_env( + /// Creates the context to run the test. + fn create_context( &self, harness: &Harness, - context: &mut Context, - async_result: AsyncResult, - handles: WorkerHandles, + optimizer_options: OptimizerOptions, console: bool, - ) -> Result<(), String> { + ) -> Result<(Context, AsyncResult, WorkerHandles), String> { + let async_result = AsyncResult::default(); + let handles = WorkerHandles::new(); + let loader = Rc::new( + SimpleModuleLoader::new(self.path.parent().expect("test should have a parent dir")) + .expect("test path should be canonicalizable"), + ); + let mut context = Context::builder() + .module_loader(loader.clone()) + .can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) + .build() + .expect("cannot fail with default global object"); + + context.set_optimizer_options(optimizer_options); + // Register the print() function. - register_print_fn(context, async_result); + register_print_fn(&mut context, async_result.clone()); // add the $262 object. - let _js262 = js262::register_js262(handles, context); + let _js262 = js262::register_js262(handles.clone(), &mut context); if console { - let console = boa_runtime::Console::init(context); + let console = boa_runtime::Console::init(&mut context); context .register_global_property( js_string!(boa_runtime::Console::NAME), @@ -617,7 +544,7 @@ impl Test { } if self.flags.contains(TestFlags::RAW) { - return Ok(()); + return Ok((context, async_result, handles)); } let assert = Source::from_reader( @@ -654,7 +581,7 @@ impl Test { })?; } - Ok(()) + Ok((context, async_result, handles)) } } @@ -727,11 +654,31 @@ fn register_print_fn(context: &mut Context, async_result: AsyncResult) { .expect("shouldn't fail with the default global"); } +/// Parses a module and registers it into the `ModuleLoader` of the context. +fn parse_module_and_register( + source: Source<'_, impl ReadChar>, + path: &Path, + context: &mut Context, +) -> JsResult { + let module = Module::parse(source, None, context)?; + + let path = js_string!(&*path + .canonicalize() + .expect("test path should be canonicalizable") + .to_string_lossy()); + + context + .module_loader() + .register_module(path, module.clone()); + + Ok(module) +} + /// A `Result` value that is possibly uninitialized. /// /// This is mainly used to check if an async test did call `print` to signal the termination of /// a test. Otherwise, all async tests that result in `UninitResult::Uninit` are considered -/// as failed. +/// failures. /// /// The Test262 [interpreting guide][guide] contains more information about how to run async tests. /// diff --git a/tests/tester/src/main.rs b/tests/tester/src/main.rs index dfeac5b5d3..20876a309b 100644 --- a/tests/tester/src/main.rs +++ b/tests/tester/src/main.rs @@ -13,6 +13,7 @@ use std::{ ops::{Add, AddAssign}, path::{Path, PathBuf}, process::Command, + sync::OnceLock, time::Instant, }; @@ -23,7 +24,6 @@ use color_eyre::{ Result, }; use colored::Colorize; -use once_cell::sync::Lazy; use rustc_hash::{FxHashMap, FxHashSet}; use serde::{ de::{Unexpected, Visitor}, @@ -44,7 +44,7 @@ mod exec; mod read; mod results; -static START: Lazy = Lazy::new(Instant::now); +static START: OnceLock = OnceLock::new(); /// Structure that contains the configuration of the tester. #[derive(Debug, Deserialize)] @@ -189,6 +189,8 @@ const DEFAULT_TEST262_DIRECTORY: &str = "test262"; /// Program entry point. fn main() -> Result<()> { + color_eyre::install()?; + // Safety: This is needed because we run tests in multiple threads. // It is safe because tests do not modify the environment. unsafe { @@ -196,8 +198,10 @@ fn main() -> Result<()> { } // initializes the monotonic clock. - Lazy::force(&START); - color_eyre::install()?; + START + .set(Instant::now()) + .map_err(|_| eyre!("could not initialize the monotonic clock"))?; + match Cli::parse() { Cli::Run { verbose, @@ -213,8 +217,11 @@ fn main() -> Result<()> { console, } => { let config: Config = { - let input = std::fs::read_to_string(config_path)?; - toml::from_str(&input).wrap_err("could not decode tester config file")? + let input = std::fs::read_to_string(&config_path).wrap_err_with(|| { + eyre!("could not read config file `{}`", config_path.display()) + })?; + toml::from_str(&input) + .wrap_err_with(|| eyre!("invalid config file `{}`", config_path.display()))? }; let test262_commit = test262_commit diff --git a/tests/tester/src/read.rs b/tests/tester/src/read.rs index 44d4620328..68a9856cf5 100644 --- a/tests/tester/src/read.rs +++ b/tests/tester/src/read.rs @@ -2,12 +2,12 @@ use std::{ ffi::OsStr, - fs, io, + fs, path::{Path, PathBuf}, }; use color_eyre::{ - eyre::{eyre, WrapErr}, + eyre::{OptionExt, WrapErr}, Result, }; use rustc_hash::FxHashMap; @@ -137,9 +137,8 @@ pub(super) fn read_suite( ) -> Result { let name = path .file_name() - .ok_or_else(|| eyre!(format!("test suite with no name found: {}", path.display())))? - .to_str() - .ok_or_else(|| eyre!(format!("non-UTF-8 suite name found: {}", path.display())))?; + .and_then(OsStr::to_str) + .ok_or_eyre("invalid path for test suite")?; ignore_suite |= ignored.contains_test(name); @@ -208,14 +207,8 @@ pub(super) fn read_suite( pub(super) fn read_test(path: &Path) -> Result { let name = path .file_stem() - .ok_or_else(|| eyre!("path for test `{}` has no file name", path.display()))? - .to_str() - .ok_or_else(|| { - eyre!( - "path for test `{}` is not a valid UTF-8 string", - path.display() - ) - })?; + .and_then(OsStr::to_str) + .ok_or_eyre("invalid path for test")?; let metadata = read_metadata(path)?; @@ -223,35 +216,16 @@ pub(super) fn read_test(path: &Path) -> Result { } /// Reads the metadata from the input test code. -fn read_metadata(test: &Path) -> io::Result { - use once_cell::sync::Lazy; - use regex::bytes::Regex; - - /// Regular expression to retrieve the metadata of a test. - static META_REGEX: Lazy = Lazy::new(|| { - Regex::new(r"/\*\-{3}((?:.|\n)*)\-{3}\*/") - .expect("could not compile metadata regular expression") - }); - - let code = fs::read(test)?; - - let yaml = META_REGEX - .captures(&code) - .ok_or_else(|| { - io::Error::new( - io::ErrorKind::InvalidData, - format!("no metadata found for test {}", test.display()), - ) - })? - .get(1) - .map(|m| String::from_utf8_lossy(m.as_bytes())) - .ok_or_else(|| { - io::Error::new( - io::ErrorKind::InvalidData, - format!("no metadata found for test {}", test.display()), - ) - })? - .replace('\r', "\n"); - - serde_yaml::from_str(&yaml).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) +fn read_metadata(test: &Path) -> Result { + let code = fs::read_to_string(test)?; + + let (_, metadata) = code + .split_once("/*---") + .ok_or_eyre("invalid test metadata")?; + let (metadata, _) = metadata + .split_once("---*/") + .ok_or_eyre("invalid test metadata")?; + let metadata = metadata.replace('\r', "\n"); + + serde_yaml::from_str(&metadata).map_err(Into::into) }