diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d0064a93..929ae16ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,4 +26,4 @@ jobs: run: | git config --global user.email "runner@gha.local" git config --global user.name "Github Action" - cargo publish + cargo publish -p temporal_rs diff --git a/.gitignore b/.gitignore index 73fab072c..cbee85c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ # Generated by Cargo # will have compiled files and executables -debug/ -target/ +debug +target # These are backup files generated by rustfmt **/*.rs.bk # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +test262 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 19e7e2a34..3c48e0e31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,42 +2,1188 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "boa_ast" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b6fb81ca0f301f33aff7401e2ffab37dc9e0e4a1cf0ccf6b34f4d9e60aa0682" +dependencies = [ + "bitflags 2.5.0", + "boa_interner", + "boa_macros", + "indexmap", + "num-bigint", + "rustc-hash", +] + +[[package]] +name = "boa_engine" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "600e4e4a65b26efcef08a7b1cf2899d3845a32e82e067ee3b75eaf7e413ff31c" +dependencies = [ + "arrayvec", + "bitflags 2.5.0", + "boa_ast", + "boa_gc", + "boa_interner", + "boa_macros", + "boa_parser", + "boa_profiler", + "bytemuck", + "cfg-if", + "dashmap", + "fast-float", + "hashbrown", + "icu_normalizer", + "indexmap", + "intrusive-collections", + "itertools", + "num-bigint", + "num-integer", + "num-traits", + "num_enum", + "once_cell", + "paste", + "pollster", + "portable-atomic", + "rand", + "regress", + "rustc-hash", + "ryu-js", + "serde", + "serde_json", + "sptr", + "static_assertions", + "tap", + "thin-vec", + "thiserror", + "time", +] + +[[package]] +name = "boa_gc" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c055ef3cd87ea7db014779195bc90c6adfc35de4902e3b2fe587adecbd384578" +dependencies = [ + "boa_macros", + "boa_profiler", + "hashbrown", + "thin-vec", +] + +[[package]] +name = "boa_interner" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cacc9caf022d92195c827a3e5bf83f96089d4bfaff834b359ac7b6be46e9187" +dependencies = [ + "boa_gc", + "boa_macros", + "hashbrown", + "indexmap", + "once_cell", + "phf", + "rustc-hash", + "static_assertions", +] + +[[package]] +name = "boa_macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6be9c93793b60dac381af475b98634d4b451e28336e72218cad9a20176218dbc" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "boa_parser" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8592556849f0619ed142ce2b3a19086769314a8d657f93a5765d06dbce4818" +dependencies = [ + "bitflags 2.5.0", + "boa_ast", + "boa_interner", + "boa_macros", + "boa_profiler", + "fast-float", + "icu_properties", + "num-bigint", + "num-traits", + "regress", + "rustc-hash", +] + +[[package]] +name = "boa_profiler" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0d8372f2d5cbac600a260de87877141b42da1e18d2c7a08ccb493a49cbd55c0" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "calendrical_calculations" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dfe3bc6a50b4667fafdb6d9cf26731c5418c457e317d8166c972014facf9a5d" -dependencies = [ - "core_maths", - "displaydoc", -] +checksum = "8dfe3bc6a50b4667fafdb6d9cf26731c5418c457e317d8166c972014facf9a5d" +dependencies = [ + "core_maths", + "displaydoc", +] + +[[package]] +name = "cc" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "core_maths" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" +dependencies = [ + "libm", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fast-float" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "icu_calendar" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb932a690c92f87955e923106181ee0d5682e688ff37fb5c7b296e1fe806edb" +dependencies = [ + "calendrical_calculations", + "displaydoc", + "icu_calendar_data", + "icu_locid", + "icu_locid_transform", + "icu_provider", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_calendar_data" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22aec7d032735d9acb256eeef72adcac43c3b7572f19b51576a63d664b524ca2" + +[[package]] +name = "icu_collections" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "137d96353afc8544d437e8a99eceb10ab291352699573b0de5b08bda38c78c60" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0aa2536adc14c07e2a521e95512b75ed8ef832f0fdf9299d4a0a45d2be2a9d" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c17d8f6524fdca4471101dd71f0a132eb6382b5d6d7f2970441cb25f6f435a" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c6c3e8bf9580e2dafee8de6f9ec14826aaf359787789c7724f1f85f47d3dc" + +[[package]] +name = "icu_normalizer" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c183e31ed700f1ecd6b032d104c52fe8b15d028956b73727c97ec176b170e187" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22026918a80e6a9a330cb01b60f950e2b4e5284c59528fd0c6150076ef4c8522" + +[[package]] +name = "icu_properties" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976e296217453af983efa25f287a4c1da04b9a63bf1ed63719455068e4453eb5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6a86c0e384532b06b6c104814f9c1b13bcd5b64409001c0d05713a1f3529d99" + +[[package]] +name = "icu_provider" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba58e782287eb6950247abbf11719f83f5d4e4a5c1f2cd490d30a334bc47c2f4" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "intrusive-collections" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b694dc9f70c3bda874626d2aed13b780f137aab435f4e9814121955cf706122e" +dependencies = [ + "memoffset", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "litemap" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d642685b028806386b2b6e75685faadd3eb65a85fff7df711ce18446a422da" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "regress" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eae2a1ebfecc58aff952ef8ccd364329abe627762f5bf09ff42eb9d98522479" +dependencies = [ + "hashbrown", + "memchr", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "ryu-js" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "core_maths" -version = "0.1.0" +name = "syn" +version = "2.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" dependencies = [ - "libm", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "displaydoc" -version = "0.2.4" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", @@ -45,231 +1191,427 @@ dependencies = [ ] [[package]] -name = "icu_calendar" -version = "1.4.0" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb932a690c92f87955e923106181ee0d5682e688ff37fb5c7b296e1fe806edb" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "temporal_rs" +version = "0.0.2" dependencies = [ - "calendrical_calculations", - "displaydoc", - "icu_calendar_data", - "icu_locid", - "icu_locid_transform", - "icu_provider", + "bitflags 2.5.0", + "icu_calendar", + "num-bigint", + "num-traits", + "rustc-hash", "tinystr", - "writeable", - "zerovec", ] [[package]] -name = "icu_calendar_data" -version = "1.4.0" +name = "testgen" +version = "0.0.0" +dependencies = [ + "bitflags 2.5.0", + "boa_engine", + "boa_gc", + "color-eyre", + "env_logger", + "log", + "phf", + "rayon", + "regex", + "rustc-hash", + "serde", + "serde_json", + "serde_repr", + "serde_yaml", +] + +[[package]] +name = "thin-vec" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22aec7d032735d9acb256eeef72adcac43c3b7572f19b51576a63d664b524ca2" +checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] -name = "icu_locid" -version = "1.4.0" +name = "thiserror" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0aa2536adc14c07e2a521e95512b75ed8ef832f0fdf9299d4a0a45d2be2a9d" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "thiserror-impl", ] [[package]] -name = "icu_locid_transform" -version = "1.4.0" +name = "thiserror-impl" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c17d8f6524fdca4471101dd71f0a132eb6382b5d6d7f2970441cb25f6f435a" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "icu_locid_transform_data" -version = "1.4.0" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c6c3e8bf9580e2dafee8de6f9ec14826aaf359787789c7724f1f85f47d3dc" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] [[package]] -name = "icu_provider" -version = "1.4.0" +name = "time" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba58e782287eb6950247abbf11719f83f5d4e4a5c1f2cd490d30a334bc47c2f4" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", + "deranged", + "itoa", + "js-sys", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "icu_provider_macros" -version = "1.4.0" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ - "proc-macro2", - "quote", - "syn", + "num-conv", + "time-core", ] [[package]] -name = "libm" -version = "0.2.8" +name = "tinystr" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +dependencies = [ + "displaydoc", + "zerovec", +] [[package]] -name = "litemap" -version = "0.7.2" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d642685b028806386b2b6e75685faadd3eb65a85fff7df711ce18446a422da" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] -name = "num-bigint" -version = "0.4.4" +name = "toml_edit" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "autocfg", - "num-integer", - "num-traits", - "serde", + "indexmap", + "toml_datetime", + "winnow", ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "tracing" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "autocfg", - "num-traits", + "pin-project-lite", + "tracing-core", ] [[package]] -name = "num-traits" -version = "0.2.18" +name = "tracing-core" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "autocfg", + "once_cell", + "valuable", ] [[package]] -name = "proc-macro2" -version = "1.0.78" +name = "tracing-error" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" dependencies = [ - "unicode-ident", + "tracing", + "tracing-subscriber", ] [[package]] -name = "quote" -version = "1.0.35" +name = "tracing-subscriber" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "proc-macro2", + "sharded-slab", + "thread_local", + "tracing-core", ] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "serde" -version = "1.0.196" +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ - "serde_derive", + "cfg-if", + "wasm-bindgen-macro", ] [[package]] -name = "serde_derive" -version = "1.0.196" +name = "wasm-bindgen-backend" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ + "bumpalo", + "log", + "once_cell", "proc-macro2", "quote", "syn", + "wasm-bindgen-shared", ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "wasm-bindgen-macro" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] [[package]] -name = "syn" -version = "2.0.48" +name = "wasm-bindgen-macro-support" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "synstructure" -version = "0.13.1" +name = "wasm-bindgen-shared" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "windows-targets 0.52.5", ] [[package]] -name = "temporal_rs" -version = "0.0.2" +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "bitflags", - "icu_calendar", - "num-bigint", - "num-traits", - "rustc-hash", - "tinystr", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] -name = "tinystr" -version = "0.7.5" +name = "windows-targets" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "displaydoc", - "zerovec", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" @@ -301,6 +1643,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 732391b48..f1b8ba18f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,6 @@ -[package] -name = "temporal_rs" -keywords = ["date", "time", "calendar", "timezone", "duration"] -categories = ["date-and-time", "internationalization"] -readme = "./README.md" -description = "Temporal in Rust is an implementation of the TC39 Temporal Builtin Proposal in Rust." -version = "0.0.2" -edition = "2021" -authors = ["boa-dev"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/boa-dev/temporal" -rust-version = "1.74" -exclude = [ - "docs/*", - ".github/*", - ".gitignore", - "LICENSE*", +[workspace] +resolver = "2" +members = [ + "temporal_rs", + "testgen" ] - -[dependencies] -tinystr = "0.7.4" -icu_calendar = { version = "~1.4.0", default-features = true } -rustc-hash = { version = "1.1.0", features = ["std"] } -bitflags = "2.5.0" -num-bigint = { version = "0.4.4", features = ["serde"] } -num-traits = "0.2.18" diff --git a/temporal_rs/Cargo.toml b/temporal_rs/Cargo.toml new file mode 100644 index 000000000..732391b48 --- /dev/null +++ b/temporal_rs/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "temporal_rs" +keywords = ["date", "time", "calendar", "timezone", "duration"] +categories = ["date-and-time", "internationalization"] +readme = "./README.md" +description = "Temporal in Rust is an implementation of the TC39 Temporal Builtin Proposal in Rust." +version = "0.0.2" +edition = "2021" +authors = ["boa-dev"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/boa-dev/temporal" +rust-version = "1.74" +exclude = [ + "docs/*", + ".github/*", + ".gitignore", + "LICENSE*", +] + +[dependencies] +tinystr = "0.7.4" +icu_calendar = { version = "~1.4.0", default-features = true } +rustc-hash = { version = "1.1.0", features = ["std"] } +bitflags = "2.5.0" +num-bigint = { version = "0.4.4", features = ["serde"] } +num-traits = "0.2.18" diff --git a/src/components/calendar.rs b/temporal_rs/src/components/calendar.rs similarity index 100% rename from src/components/calendar.rs rename to temporal_rs/src/components/calendar.rs diff --git a/src/components/date.rs b/temporal_rs/src/components/date.rs similarity index 100% rename from src/components/date.rs rename to temporal_rs/src/components/date.rs diff --git a/src/components/datetime.rs b/temporal_rs/src/components/datetime.rs similarity index 100% rename from src/components/datetime.rs rename to temporal_rs/src/components/datetime.rs diff --git a/src/components/duration.rs b/temporal_rs/src/components/duration.rs similarity index 100% rename from src/components/duration.rs rename to temporal_rs/src/components/duration.rs diff --git a/src/components/duration/date.rs b/temporal_rs/src/components/duration/date.rs similarity index 100% rename from src/components/duration/date.rs rename to temporal_rs/src/components/duration/date.rs diff --git a/src/components/duration/normalized.rs b/temporal_rs/src/components/duration/normalized.rs similarity index 100% rename from src/components/duration/normalized.rs rename to temporal_rs/src/components/duration/normalized.rs diff --git a/src/components/duration/tests.rs b/temporal_rs/src/components/duration/tests.rs similarity index 100% rename from src/components/duration/tests.rs rename to temporal_rs/src/components/duration/tests.rs diff --git a/src/components/duration/time.rs b/temporal_rs/src/components/duration/time.rs similarity index 100% rename from src/components/duration/time.rs rename to temporal_rs/src/components/duration/time.rs diff --git a/src/components/instant.rs b/temporal_rs/src/components/instant.rs similarity index 100% rename from src/components/instant.rs rename to temporal_rs/src/components/instant.rs diff --git a/src/components/mod.rs b/temporal_rs/src/components/mod.rs similarity index 100% rename from src/components/mod.rs rename to temporal_rs/src/components/mod.rs diff --git a/src/components/month_day.rs b/temporal_rs/src/components/month_day.rs similarity index 100% rename from src/components/month_day.rs rename to temporal_rs/src/components/month_day.rs diff --git a/src/components/time.rs b/temporal_rs/src/components/time.rs similarity index 100% rename from src/components/time.rs rename to temporal_rs/src/components/time.rs diff --git a/src/components/tz.rs b/temporal_rs/src/components/tz.rs similarity index 100% rename from src/components/tz.rs rename to temporal_rs/src/components/tz.rs diff --git a/src/components/year_month.rs b/temporal_rs/src/components/year_month.rs similarity index 100% rename from src/components/year_month.rs rename to temporal_rs/src/components/year_month.rs diff --git a/src/components/zoneddatetime.rs b/temporal_rs/src/components/zoneddatetime.rs similarity index 100% rename from src/components/zoneddatetime.rs rename to temporal_rs/src/components/zoneddatetime.rs diff --git a/src/error.rs b/temporal_rs/src/error.rs similarity index 100% rename from src/error.rs rename to temporal_rs/src/error.rs diff --git a/src/fields.rs b/temporal_rs/src/fields.rs similarity index 100% rename from src/fields.rs rename to temporal_rs/src/fields.rs diff --git a/src/iso.rs b/temporal_rs/src/iso.rs similarity index 100% rename from src/iso.rs rename to temporal_rs/src/iso.rs diff --git a/src/lib.rs b/temporal_rs/src/lib.rs similarity index 100% rename from src/lib.rs rename to temporal_rs/src/lib.rs diff --git a/src/options.rs b/temporal_rs/src/options.rs similarity index 100% rename from src/options.rs rename to temporal_rs/src/options.rs diff --git a/src/parser/annotations.rs b/temporal_rs/src/parser/annotations.rs similarity index 100% rename from src/parser/annotations.rs rename to temporal_rs/src/parser/annotations.rs diff --git a/src/parser/datetime.rs b/temporal_rs/src/parser/datetime.rs similarity index 100% rename from src/parser/datetime.rs rename to temporal_rs/src/parser/datetime.rs diff --git a/src/parser/duration.rs b/temporal_rs/src/parser/duration.rs similarity index 100% rename from src/parser/duration.rs rename to temporal_rs/src/parser/duration.rs diff --git a/src/parser/grammar.rs b/temporal_rs/src/parser/grammar.rs similarity index 100% rename from src/parser/grammar.rs rename to temporal_rs/src/parser/grammar.rs diff --git a/src/parser/mod.rs b/temporal_rs/src/parser/mod.rs similarity index 100% rename from src/parser/mod.rs rename to temporal_rs/src/parser/mod.rs diff --git a/src/parser/nodes.rs b/temporal_rs/src/parser/nodes.rs similarity index 100% rename from src/parser/nodes.rs rename to temporal_rs/src/parser/nodes.rs diff --git a/src/parser/tests.rs b/temporal_rs/src/parser/tests.rs similarity index 100% rename from src/parser/tests.rs rename to temporal_rs/src/parser/tests.rs diff --git a/src/parser/time.rs b/temporal_rs/src/parser/time.rs similarity index 100% rename from src/parser/time.rs rename to temporal_rs/src/parser/time.rs diff --git a/src/parser/time_zone.rs b/temporal_rs/src/parser/time_zone.rs similarity index 100% rename from src/parser/time_zone.rs rename to temporal_rs/src/parser/time_zone.rs diff --git a/src/utils.rs b/temporal_rs/src/utils.rs similarity index 100% rename from src/utils.rs rename to temporal_rs/src/utils.rs diff --git a/temporal_rs/testdata/Duration/call-builtin.json b/temporal_rs/testdata/Duration/call-builtin.json new file mode 100644 index 000000000..88b30227c --- /dev/null +++ b/temporal_rs/testdata/Duration/call-builtin.json @@ -0,0 +1,34 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/days-undefined.json b/temporal_rs/testdata/Duration/days-undefined.json new file mode 100644 index 000000000..0aa66c249 --- /dev/null +++ b/temporal_rs/testdata/Duration/days-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/argument-duration.json b/temporal_rs/testdata/Duration/from/argument-duration.json new file mode 100644 index 000000000..2f81868db --- /dev/null +++ b/temporal_rs/testdata/Duration/from/argument-duration.json @@ -0,0 +1,34 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 654, + "nanoseconds": 321 + } + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/argument-string-fractional-units-rounding-mode.json b/temporal_rs/testdata/Duration/from/argument-string-fractional-units-rounding-mode.json new file mode 100644 index 000000000..3a546a090 --- /dev/null +++ b/temporal_rs/testdata/Duration/from/argument-string-fractional-units-rounding-mode.json @@ -0,0 +1,80 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "PT1.03125H" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 1, + "minutes": 1, + "seconds": 52, + "milliseconds": 500, + "microseconds": 500, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-PT1.03125H" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": -1, + "minutes": -1, + "seconds": -52, + "milliseconds": -500, + "microseconds": -500, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "PT46H66M71.50040904S" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 46, + "minutes": 66, + "seconds": 71, + "milliseconds": 500, + "microseconds": 500, + "nanoseconds": 409 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-PT46H66M71.50040904S" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": -46, + "minutes": -66, + "seconds": -71, + "milliseconds": -500, + "microseconds": -500, + "nanoseconds": -409 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/argument-string-negative-fractional-units.json b/temporal_rs/testdata/Duration/from/argument-string-negative-fractional-units.json new file mode 100644 index 000000000..e84ab3403 --- /dev/null +++ b/temporal_rs/testdata/Duration/from/argument-string-negative-fractional-units.json @@ -0,0 +1,42 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-PT24.567890123H" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": -24, + "minutes": -34, + "seconds": -4, + "milliseconds": -404, + "microseconds": -404, + "nanoseconds": -442 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-PT1440.567890123M" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": -1440, + "seconds": -34, + "milliseconds": -73, + "microseconds": -73, + "nanoseconds": -407 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/argument-string.json b/temporal_rs/testdata/Duration/from/argument-string.json new file mode 100644 index 000000000..fadeaa622 --- /dev/null +++ b/temporal_rs/testdata/Duration/from/argument-string.json @@ -0,0 +1,365 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1D" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "p1y1m1dt1h1m1s" + } + }, + "years": 1, + "months": 1, + "weeks": 0, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.1S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 100, + "microseconds": 100, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.12S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 120, + "microseconds": 120, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.123S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.1234S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 400 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.12345S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 450 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.123456S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 456 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.1234567S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 456 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.12345678S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 456 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1.123456789S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 456 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y1M1W1DT1H1M1,12S" + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 120, + "microseconds": 120, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1DT0.5M" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 30, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1DT0,5H" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 30, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "+P1D" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-P1D" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": -1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "−P1D" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": -1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "-P1Y1M1W1DT1H1M1.123456789S" + } + }, + "years": -1, + "months": -1, + "weeks": -1, + "days": -1, + "hours": -1, + "minutes": -1, + "seconds": -1, + "milliseconds": -123, + "microseconds": -123, + "nanoseconds": -456 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "PT100M" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 100, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/string-with-skipped-units.json b/temporal_rs/testdata/Duration/from/string-with-skipped-units.json new file mode 100644 index 000000000..8cb40ef6f --- /dev/null +++ b/temporal_rs/testdata/Duration/from/string-with-skipped-units.json @@ -0,0 +1,80 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P3Y4W" + } + }, + "years": 3, + "months": 0, + "weeks": 4, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P3Y4D" + } + }, + "years": 3, + "months": 0, + "weeks": 0, + "days": 4, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P3M4D" + } + }, + "years": 0, + "months": 3, + "weeks": 0, + "days": 4, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "PT3H4.123456789S" + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 3, + "minutes": 0, + "seconds": 4, + "milliseconds": 123, + "microseconds": 123, + "nanoseconds": 456 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/from/subclassing-ignored.json b/temporal_rs/testdata/Duration/from/subclassing-ignored.json new file mode 100644 index 000000000..b0d955d88 --- /dev/null +++ b/temporal_rs/testdata/Duration/from/subclassing-ignored.json @@ -0,0 +1,327 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "String": "P1Y2M3W4DT5H6M7.987654321S" + } + }, + "years": 1, + "months": 2, + "weeks": 3, + "days": 4, + "hours": 5, + "minutes": 6, + "seconds": 7, + "milliseconds": 987, + "microseconds": 987, + "nanoseconds": 654 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/hours-undefined.json b/temporal_rs/testdata/Duration/hours-undefined.json new file mode 100644 index 000000000..3054b8ac5 --- /dev/null +++ b/temporal_rs/testdata/Duration/hours-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/microseconds-undefined.json b/temporal_rs/testdata/Duration/microseconds-undefined.json new file mode 100644 index 000000000..73f408828 --- /dev/null +++ b/temporal_rs/testdata/Duration/microseconds-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/milliseconds-undefined.json b/temporal_rs/testdata/Duration/milliseconds-undefined.json new file mode 100644 index 000000000..7f908f701 --- /dev/null +++ b/temporal_rs/testdata/Duration/milliseconds-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/minutes-undefined.json b/temporal_rs/testdata/Duration/minutes-undefined.json new file mode 100644 index 000000000..e7638efef --- /dev/null +++ b/temporal_rs/testdata/Duration/minutes-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/months-undefined.json b/temporal_rs/testdata/Duration/months-undefined.json new file mode 100644 index 000000000..4bb172fec --- /dev/null +++ b/temporal_rs/testdata/Duration/months-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/nanoseconds-undefined.json b/temporal_rs/testdata/Duration/nanoseconds-undefined.json new file mode 100644 index 000000000..002a436d6 --- /dev/null +++ b/temporal_rs/testdata/Duration/nanoseconds-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 1 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 1, + "milliseconds": 1, + "microseconds": 1, + "nanoseconds": 1 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/prototype/add/argument-string-fractional-units-rounding-mode.json b/temporal_rs/testdata/Duration/prototype/add/argument-string-fractional-units-rounding-mode.json new file mode 100644 index 000000000..10cb253c8 --- /dev/null +++ b/temporal_rs/testdata/Duration/prototype/add/argument-string-fractional-units-rounding-mode.json @@ -0,0 +1,82 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Add": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "other": { + "Plain": { + "String": "PT1.03125H" + } + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 1, + "minutes": 1, + "seconds": 52, + "milliseconds": 500, + "microseconds": 500, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Add": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "other": { + "Plain": { + "String": "-PT1.03125H" + } + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": -1, + "minutes": -1, + "seconds": -52, + "milliseconds": -500, + "microseconds": -500, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/prototype/add/argument-string-negative-fractional-units.json b/temporal_rs/testdata/Duration/prototype/add/argument-string-negative-fractional-units.json new file mode 100644 index 000000000..b87d1ca29 --- /dev/null +++ b/temporal_rs/testdata/Duration/prototype/add/argument-string-negative-fractional-units.json @@ -0,0 +1,82 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Add": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "other": { + "Plain": { + "String": "-PT24.567890123H" + } + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": -24, + "minutes": -34, + "seconds": -4, + "milliseconds": -404, + "microseconds": -404, + "nanoseconds": -442 + } + }, + { + "DurationFullValue": { + "target": { + "Add": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "other": { + "Plain": { + "String": "-PT1440.567890123M" + } + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": -1440, + "seconds": -34, + "milliseconds": -73, + "microseconds": -73, + "nanoseconds": -407 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/seconds-undefined.json b/temporal_rs/testdata/Duration/seconds-undefined.json new file mode 100644 index 000000000..240fe119c --- /dev/null +++ b/temporal_rs/testdata/Duration/seconds-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 1, + "days": 1, + "hours": 1, + "minutes": 1, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/subclass.json b/temporal_rs/testdata/Duration/subclass.json new file mode 100644 index 000000000..96dfa9407 --- /dev/null +++ b/temporal_rs/testdata/Duration/subclass.json @@ -0,0 +1,34 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 0, + "days": 1, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/weeks-undefined.json b/temporal_rs/testdata/Duration/weeks-undefined.json new file mode 100644 index 000000000..674304f34 --- /dev/null +++ b/temporal_rs/testdata/Duration/weeks-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 1, + "months": 1, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/temporal_rs/testdata/Duration/years-undefined.json b/temporal_rs/testdata/Duration/years-undefined.json new file mode 100644 index 000000000..1824cff89 --- /dev/null +++ b/temporal_rs/testdata/Duration/years-undefined.json @@ -0,0 +1,64 @@ +{ + "assertions": [ + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + }, + { + "DurationFullValue": { + "target": { + "Plain": { + "Full": { + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + }, + "years": 0, + "months": 0, + "weeks": 0, + "days": 0, + "hours": 0, + "minutes": 0, + "seconds": 0, + "milliseconds": 0, + "microseconds": 0, + "nanoseconds": 0 + } + } + ] +} \ No newline at end of file diff --git a/test262_config.toml b/test262_config.toml new file mode 100644 index 000000000..3b6d21ae2 --- /dev/null +++ b/test262_config.toml @@ -0,0 +1 @@ +commit = "6f7ae1f311a7b01ef2358de7f4f6fd42c3ae3839" \ No newline at end of file diff --git a/testgen/Cargo.toml b/testgen/Cargo.toml new file mode 100644 index 000000000..f917c5db4 --- /dev/null +++ b/testgen/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "testgen" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +boa_engine = "0.18.0" +boa_gc = "0.18.0" +color-eyre = "0.6.2" +rustc-hash = "1.1.0" +serde = { version = "1.0.197", features = ["derive"] } +serde_repr = "0.1.18" +serde_yaml = "0.9.32" +serde_json = "1.0.116" +bitflags = "2.4.2" +regex = "1.10.3" +phf = "0.11.2" +rayon = "1.9.0" +log = "0.4.21" +env_logger = "0.11.3" \ No newline at end of file diff --git a/testgen/src/edition.rs b/testgen/src/edition.rs new file mode 100644 index 000000000..424cf5fc9 --- /dev/null +++ b/testgen/src/edition.rs @@ -0,0 +1,342 @@ +//! Edition detection utilities. +//! +//! This module contains the [`SpecEdition`] struct, which is used in the tester to +//! classify all tests per minimum required ECMAScript edition. + +use std::fmt::Display; + +use serde_repr::{Deserialize_repr, Serialize_repr}; + +use crate::read::{MetaData, TestFlag}; + +/// Minimum edition required by a specific feature in the `test262` repository. +static FEATURE_EDITION: phf::Map<&'static str, SpecEdition> = phf::phf_map! { + // Proposed language features + + // Intl.Locale Info + // https://github.com/tc39/proposal-intl-locale-info + "Intl.Locale-info" => SpecEdition::ESNext, + + // FinalizationRegistry#cleanupSome + // https://github.com/tc39/proposal-cleanup-some + "FinalizationRegistry.prototype.cleanupSome" => SpecEdition::ESNext, + + // Intl.NumberFormat V3 + // https://github.com/tc39/proposal-intl-numberformat-v3 + "Intl.NumberFormat-v3" => SpecEdition::ESNext, + + // Legacy RegExp features + // https://github.com/tc39/proposal-regexp-legacy-features + "legacy-regexp" => SpecEdition::ESNext, + + // Import Attributes + // https://github.com/tc39/proposal-import-attributes/ + "import-attributes" => SpecEdition::ESNext, + + // Import Assertions + // https://github.com/tc39/proposal-import-assertions/ + "import-assertions" => SpecEdition::ESNext, + + // JSON modules + // https://github.com/tc39/proposal-json-modules + "json-modules" => SpecEdition::ESNext, + + // ArrayBuffer transfer + // https://github.com/tc39/proposal-arraybuffer-transfer + "arraybuffer-transfer" => SpecEdition::ESNext, + + // Temporal + // https://github.com/tc39/proposal-temporal + "Temporal" => SpecEdition::ESNext, + + // ShadowRealm, née Callable Boundary Realms + // https://github.com/tc39/proposal-realms + "ShadowRealm" => SpecEdition::ESNext, + + // Intl.DurationFormat + // https://github.com/tc39/proposal-intl-duration-format + "Intl.DurationFormat" => SpecEdition::ESNext, + + // Decorators + // https://github.com/tc39/proposal-decorators + "decorators" => SpecEdition::ESNext, + + // Duplicate named capturing groups + // https://github.com/tc39/proposal-duplicate-named-capturing-groups + "regexp-duplicate-named-groups" => SpecEdition::ESNext, + + // Array.fromAsync + // https://github.com/tc39/proposal-array-from-async + "Array.fromAsync" => SpecEdition::ESNext, + + // JSON.parse with source + // https://github.com/tc39/proposal-json-parse-with-source + "json-parse-with-source" => SpecEdition::ESNext, + + // Iterator Helpers + // https://github.com/tc39/proposal-iterator-helpers + "iterator-helpers" => SpecEdition::ESNext, + + // Set methods + // https://github.com/tc39/proposal-set-methods + "set-methods" => SpecEdition::ESNext, + + // Part of the next ES15 edition + "Atomics.waitAsync" => SpecEdition::ESNext, + "regexp-v-flag" => SpecEdition::ESNext, + "String.prototype.isWellFormed" => SpecEdition::ESNext, + "String.prototype.toWellFormed" => SpecEdition::ESNext, + "resizable-arraybuffer" => SpecEdition::ESNext, + "promise-with-resolvers" => SpecEdition::ESNext, + "array-grouping" => SpecEdition::ESNext, + + // Standard language features + "AggregateError" => SpecEdition::ES12, + "align-detached-buffer-semantics-with-web-reality" => SpecEdition::ES12, + "arbitrary-module-namespace-names" => SpecEdition::ES13, + "ArrayBuffer" => SpecEdition::ES6, + "array-find-from-last" => SpecEdition::ES14, + "Array.prototype.at" => SpecEdition::ES13, + "Array.prototype.flat" => SpecEdition::ES10, + "Array.prototype.flatMap" => SpecEdition::ES10, + "Array.prototype.includes" => SpecEdition::ES7, + "Array.prototype.values" => SpecEdition::ES6, + "arrow-function" => SpecEdition::ES6, + "async-iteration" => SpecEdition::ES9, + "async-functions" => SpecEdition::ES8, + "Atomics" => SpecEdition::ES8, + "BigInt" => SpecEdition::ES11, + "caller" => SpecEdition::ES5, + "change-array-by-copy" => SpecEdition::ES14, + "class" => SpecEdition::ES6, + "class-fields-private" => SpecEdition::ES13, + "class-fields-private-in" => SpecEdition::ES13, + "class-fields-public" => SpecEdition::ES13, + "class-methods-private" => SpecEdition::ES13, + "class-static-block" => SpecEdition::ES13, + "class-static-fields-private" => SpecEdition::ES13, + "class-static-fields-public" => SpecEdition::ES13, + "class-static-methods-private" => SpecEdition::ES13, + "coalesce-expression" => SpecEdition::ES11, + "computed-property-names" => SpecEdition::ES6, + "const" => SpecEdition::ES6, + "cross-realm" => SpecEdition::ES6, + "DataView" => SpecEdition::ES6, + "DataView.prototype.getFloat32" => SpecEdition::ES6, + "DataView.prototype.getFloat64" => SpecEdition::ES6, + "DataView.prototype.getInt16" => SpecEdition::ES6, + "DataView.prototype.getInt32" => SpecEdition::ES6, + "DataView.prototype.getInt8" => SpecEdition::ES6, + "DataView.prototype.getUint16" => SpecEdition::ES6, + "DataView.prototype.getUint32" => SpecEdition::ES6, + "DataView.prototype.setUint8" => SpecEdition::ES6, + "default-parameters" => SpecEdition::ES6, + "destructuring-assignment" => SpecEdition::ES6, + "destructuring-binding" => SpecEdition::ES6, + "dynamic-import" => SpecEdition::ES11, + "error-cause" => SpecEdition::ES13, + "exponentiation" => SpecEdition::ES7, + "export-star-as-namespace-from-module" => SpecEdition::ES11, + "FinalizationRegistry" => SpecEdition::ES12, + "for-in-order" => SpecEdition::ES11, + "for-of" => SpecEdition::ES6, + "Float32Array" => SpecEdition::ES6, + "Float64Array" => SpecEdition::ES6, + "generators" => SpecEdition::ES6, + "globalThis" => SpecEdition::ES11, + "hashbang" => SpecEdition::ES14, + "import.meta" => SpecEdition::ES11, + "Int8Array" => SpecEdition::ES6, + "Int16Array" => SpecEdition::ES6, + "Int32Array" => SpecEdition::ES6, + "Intl-enumeration" => SpecEdition::ES14, + "intl-normative-optional" => SpecEdition::ES8, + "Intl.DateTimeFormat-datetimestyle" => SpecEdition::ES12, + "Intl.DateTimeFormat-dayPeriod" => SpecEdition::ES8, + "Intl.DateTimeFormat-extend-timezonename" => SpecEdition::ES13, + "Intl.DateTimeFormat-formatRange" => SpecEdition::ES12, + "Intl.DateTimeFormat-fractionalSecondDigits" => SpecEdition::ES12, + "Intl.DisplayNames" => SpecEdition::ES12, + "Intl.DisplayNames-v2" => SpecEdition::ES13, + "Intl.ListFormat" => SpecEdition::ES12, + "Intl.Locale" => SpecEdition::ES12, + "Intl.NumberFormat-unified" => SpecEdition::ES11, + "Intl.RelativeTimeFormat" => SpecEdition::ES11, + "Intl.Segmenter" => SpecEdition::ES13, + "json-superset" => SpecEdition::ES10, + "let" => SpecEdition::ES6, + "logical-assignment-operators" => SpecEdition::ES12, + "Map" => SpecEdition::ES6, + "new.target" => SpecEdition::ES6, + "numeric-separator-literal" => SpecEdition::ES12, + "object-rest" => SpecEdition::ES9, + "object-spread" => SpecEdition::ES9, + "Object.fromEntries" => SpecEdition::ES10, + "Object.hasOwn" => SpecEdition::ES13, + "Object.is" => SpecEdition::ES6, + "optional-catch-binding" => SpecEdition::ES10, + "optional-chaining" => SpecEdition::ES11, + "Promise" => SpecEdition::ES6, + "Promise.allSettled" => SpecEdition::ES11, + "Promise.any" => SpecEdition::ES12, + "Promise.prototype.finally" => SpecEdition::ES9, + "Proxy" => SpecEdition::ES6, + "proxy-missing-checks" => SpecEdition::ES6, + "Reflect" => SpecEdition::ES6, + "Reflect.construct" => SpecEdition::ES6, + "Reflect.set" => SpecEdition::ES6, + "Reflect.setPrototypeOf" => SpecEdition::ES6, + "regexp-dotall" => SpecEdition::ES9, + "regexp-lookbehind" => SpecEdition::ES9, + "regexp-match-indices" => SpecEdition::ES13, + "regexp-named-groups" => SpecEdition::ES9, + "regexp-unicode-property-escapes" => SpecEdition::ES9, + "rest-parameters" => SpecEdition::ES6, + "Set" => SpecEdition::ES6, + "SharedArrayBuffer" => SpecEdition::ES8, + "string-trimming" => SpecEdition::ES10, + "String.fromCodePoint" => SpecEdition::ES6, + "String.prototype.at" => SpecEdition::ES13, + "String.prototype.endsWith" => SpecEdition::ES6, + "String.prototype.includes" => SpecEdition::ES6, + "String.prototype.matchAll" => SpecEdition::ES11, + "String.prototype.replaceAll" => SpecEdition::ES12, + "String.prototype.trimEnd" => SpecEdition::ES10, + "String.prototype.trimStart" => SpecEdition::ES10, + "super" => SpecEdition::ES6, + "Symbol" => SpecEdition::ES6, + "symbols-as-weakmap-keys" => SpecEdition::ES14, + "Symbol.asyncIterator" => SpecEdition::ES9, + "Symbol.hasInstance" => SpecEdition::ES6, + "Symbol.isConcatSpreadable" => SpecEdition::ES6, + "Symbol.iterator" => SpecEdition::ES6, + "Symbol.match" => SpecEdition::ES6, + "Symbol.matchAll" => SpecEdition::ES11, + "Symbol.prototype.description" => SpecEdition::ES10, + "Symbol.replace" => SpecEdition::ES6, + "Symbol.search" => SpecEdition::ES6, + "Symbol.species" => SpecEdition::ES6, + "Symbol.split" => SpecEdition::ES6, + "Symbol.toPrimitive" => SpecEdition::ES6, + "Symbol.toStringTag" => SpecEdition::ES6, + "Symbol.unscopables" => SpecEdition::ES6, + "tail-call-optimization" => SpecEdition::ES6, + "template" => SpecEdition::ES6, + "top-level-await" => SpecEdition::ES13, + "TypedArray" => SpecEdition::ES6, + "TypedArray.prototype.at" => SpecEdition::ES13, + "u180e" => SpecEdition::ES7, + "Uint8Array" => SpecEdition::ES6, + "Uint16Array" => SpecEdition::ES6, + "Uint32Array" => SpecEdition::ES6, + "Uint8ClampedArray" => SpecEdition::ES6, + "WeakMap" => SpecEdition::ES6, + "WeakRef" => SpecEdition::ES12, + "WeakSet" => SpecEdition::ES6, + "well-formed-json-stringify" => SpecEdition::ES10, + "__proto__" => SpecEdition::ES6, + "__getter__" => SpecEdition::ES8, + "__setter__" => SpecEdition::ES8, + + // Test-Harness Features + + "IsHTMLDDA" => SpecEdition::ES9, + "host-gc-required" => SpecEdition::ES5, +}; + +/// List of ECMAScript editions that can be tested in the `test262` repository. +#[derive( + Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize_repr, Deserialize_repr, +)] +#[repr(u8)] +pub(crate) enum SpecEdition { + /// ECMAScript 5.1 Edition + /// + /// + ES5 = 5, + /// ECMAScript 6th Edition + /// + /// + ES6, + /// ECMAScript 7th Edition + /// + /// + ES7, + /// ECMAScript 8th Edition + /// + /// + ES8, + /// ECMAScript 9th Edition + /// + /// + ES9, + /// ECMAScript 10th Edition + /// + /// + ES10, + /// ECMAScript 11th Edition + /// + /// + ES11, + /// ECMAScript 12th Edition + /// + /// + ES12, + /// ECMAScript 13th Edition + /// + /// + ES13, + /// ECMAScript 14th Edition + /// + /// + ES14, + /// The edition being worked on right now. + /// + /// A draft is currently available [here](https://tc39.es/ecma262). + #[default] + ESNext = 255, +} + +impl Display for SpecEdition { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::ESNext => write!(f, "ECMAScript Next"), + Self::ES5 => write!(f, "ECMAScript 5.1"), + v => write!(f, "ECMAScript {}", v as u8), + } + } +} + +impl SpecEdition { + /// Gets the minimum required ECMAScript edition of a test from its metadata. + /// + /// If the function finds unknown features in `metadata`, returns an `Err(Vec<&str>)` containing + /// the list of unknown features. + pub(crate) fn from_test_metadata(metadata: &MetaData) -> Result> { + let mut min_edition = if metadata.flags.contains(&TestFlag::Async) { + Self::ES8 + } else if metadata.flags.contains(&TestFlag::Module) + || metadata.esid.is_some() + || metadata.es6id.is_some() + { + Self::ES6 + } else { + Self::ES5 + }; + + let mut unknowns = Vec::new(); + for feature in &*metadata.features { + let Some(feature_edition) = FEATURE_EDITION.get(feature).copied() else { + unknowns.push(&**feature); + continue; + }; + min_edition = std::cmp::max(min_edition, feature_edition); + } + + if unknowns.is_empty() { + Ok(min_edition) + } else { + Err(unknowns) + } + } +} diff --git a/testgen/src/exec/mod.rs b/testgen/src/exec/mod.rs new file mode 100644 index 000000000..664bccfa7 --- /dev/null +++ b/testgen/src/exec/mod.rs @@ -0,0 +1,212 @@ +//! Execution module for the test runner. + +mod temporal; + +use std::{io::BufWriter, path::PathBuf}; + +use crate::{ + exec::temporal::AssertionsTracker, Harness, Outcome, Phase, SpecEdition, Test, TestFlags, + TestSuite, TESTDATA_DIRECTORY, +}; +use boa_engine::{Context, JsNativeError, JsResult, Source}; +use color_eyre::{ + eyre::{bail, WrapErr}, + Result, +}; +use log::{debug, error, info, warn}; +use rayon::prelude::*; + +impl TestSuite { + /// Runs the test suite. + pub(crate) fn run( + &self, + harness: &Harness, + parallel: bool, + max_edition: SpecEdition, + ) -> Result<()> { + info!(target: "testgen", "Running suite `{}`.", self.path.display()); + + let suites: Result> = if parallel { + self.suites + .par_iter() + .map(|suite| suite.run(harness, parallel, max_edition)) + .collect() + } else { + self.suites + .iter() + .map(|suite| suite.run(harness, parallel, max_edition)) + .collect() + }; + + suites?; + + let tests: Result> = if parallel { + self.tests + .par_iter() + .filter(|test| test.edition <= max_edition) + .map(|test| test.run(harness)) + .collect() + } else { + self.tests + .iter() + .filter(|test| test.edition <= max_edition) + .map(|test| test.run(harness)) + .collect() + }; + + tests?; + + Ok(()) + } +} + +impl Test { + /// Runs the test. + pub(crate) fn run(&self, harness: &Harness) -> Result<()> { + let skip = if self + .flags + .intersects(TestFlags::MODULE | TestFlags::RAW | TestFlags::ASYNC) + || !self + .flags + .contains(TestFlags::STRICT | TestFlags::NO_STRICT) + { + Some("incompatible test flags") + } else if matches!( + self.expected_outcome, + Outcome::Negative { + phase: Phase::Parse | Phase::Resolution, + .. + } + ) { + Some("can only run negative outcomes in the execution phase") + } else { + None + }; + + if let Some(skip) = skip { + debug!(target: "testgen", "Skipping test `{}` ({})", self.path.display(), skip); + return Ok(()); + } + + self.run_once(harness) + } + + /// Runs the test once, in strict or non-strict mode + fn run_once(&self, harness: &Harness) -> Result<()> { + let Ok(source) = Source::from_filepath(&self.path) else { + bail!("could not read file `{}`", self.path.display()); + }; + + debug!(target: "testgen", "starting test `{}`", self.path.display()); + + let result: JsResult<_> = match self.expected_outcome { + Outcome::Positive => (|| { + let context = &mut Context::default(); + self.set_up_env(harness, context)?; + let value = context.eval(source)?; + + let tracker: AssertionsTracker = *context + .realm() + .host_defined_mut() + .remove::() + .ok_or_else(|| { + JsNativeError::typ().with_message("missing tracker on context") + })?; + + Ok((value, tracker)) + })(), + _ => Err(temporal::TemporalUnsupported.into()), + }; + + match result { + Ok((v, tracker)) => { + debug!(target: "testgen", "`{}`: result text", self.path.display()); + debug!(target: "testgen", "{}", v.display()); + if tracker.assertions.is_empty() { + warn!(target: "testgen", "`{}`: generated empty tracker. Skipping.", self.path.display()); + return Ok(()); + } + + let mut new_path = PathBuf::from(TESTDATA_DIRECTORY); + new_path.push(self.path.strip_prefix("test262/test/built-ins/Temporal")?); + new_path.set_extension("json"); + if let Some(parent) = new_path.parent() { + std::fs::create_dir_all(parent).wrap_err_with(|| { + format!("could not create directory `{}`", parent.display()) + })? + } + + let file = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(&new_path) + .wrap_err_with(|| format!("could not write file `{}`", new_path.display()))?; + + let file = &mut BufWriter::new(file); + + serde_json::to_writer_pretty(file, &tracker).wrap_err_with(|| { + format!( + "could not serialize tracker for test `{}`", + self.path.display() + ) + })?; + } + Err(e) => { + if e.to_string() == "Error: TemporalTester:unsupported" { + debug!(target: "testgen", "`{}`: Filtered test", self.path.display()); + return Ok(()); + } + + warn!(target: "testgen", "`{}`: FAILED. Ignoring...", self.path.display()); + warn!(target: "testgen", "`{}`: {e}", self.path.display()); + } + } + + Ok(()) + } + + /// Sets the environment up to run the test. + fn set_up_env(&self, harness: &Harness, context: &mut Context) -> JsResult<()> { + // add the $262 object. + temporal::setup_context(context)?; + + let assert = Source::from_reader( + harness.assert.content.as_bytes(), + Some(&harness.assert.path), + ); + let sta = Source::from_reader(harness.sta.content.as_bytes(), Some(&harness.sta.path)); + + context.eval(assert).map_err(|e| { + JsNativeError::eval() + .with_message("could not run assert.js") + .with_cause(e) + })?; + context.eval(sta).map_err(|e| { + JsNativeError::eval() + .with_message("could not run sta.js") + .with_cause(e) + })?; + + for include_name in &self.includes { + let include = harness.includes.get(include_name).ok_or_else(|| { + JsNativeError::typ() + .with_message(format!("could not find the {include_name} include file.")) + })?; + let source = Source::from_reader(include.content.as_bytes(), Some(&include.path)); + context.eval(source).map_err(|e| { + JsNativeError::eval() + .with_message(format!("could not run the harness `{include_name}`")) + .with_cause(e) + })?; + } + + temporal::patch_harness(context).map_err(|e| { + JsNativeError::typ() + .with_message("could not patch the `Temporal` utils") + .with_cause(e) + })?; + + Ok(()) + } +} diff --git a/testgen/src/exec/temporal.rs b/testgen/src/exec/temporal.rs new file mode 100644 index 000000000..af1542986 --- /dev/null +++ b/testgen/src/exec/temporal.rs @@ -0,0 +1,158 @@ +use boa_engine::{ + js_string, native_function::NativeFunction, object::ObjectInitializer, property::Attribute, + Context, JsArgs, JsData, JsError, JsNativeError, JsResult, JsValue, +}; +use boa_gc::{Finalize, Trace}; +use serde::Serialize; + +use self::duration::Duration; + +mod duration; + +/// Initializes the required properties on the global object for testing. +pub(super) fn setup_context(context: &mut Context) -> JsResult<()> { + let global_obj = context.global_object(); + + let throw_fn = NativeFunction::from_fn_ptr(|_, _, _| Err(TemporalUnsupported.into())); + let throw_fn_obj = throw_fn.clone().to_js_function(context.realm()); + + let js262 = ObjectInitializer::new(context) + .function(throw_fn.clone(), js_string!("createRealm"), 0) + .function(throw_fn.clone(), js_string!("detachArrayBuffer"), 2) + .function(throw_fn.clone(), js_string!("evalScript"), 1) + .function(throw_fn.clone(), js_string!("gc"), 0) + .property( + js_string!("global"), + global_obj, + Attribute::WRITABLE | Attribute::CONFIGURABLE, + ) + .accessor( + js_string!("agent"), + Some(throw_fn_obj), + None, + Attribute::CONFIGURABLE, + ) + .build(); + + context.register_global_property( + js_string!("$262"), + js262, + Attribute::WRITABLE | Attribute::CONFIGURABLE, + )?; + + context.register_global_class::()?; + context + .global_object() + .delete_property_or_throw(js_string!("Duration"), context)?; + let constructor = context + .get_global_class::() + .expect("already registered the class") + .constructor(); + + let temporal = ObjectInitializer::new(context) + .property(js_string!("Duration"), constructor, Attribute::all()) + .build(); + + context.register_global_property(js_string!("Temporal"), temporal, Attribute::all())?; + + context + .realm() + .host_defined_mut() + .insert_default::(); + + Ok(()) +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) struct TemporalUnsupported; + +impl From for JsError { + fn from(_value: TemporalUnsupported) -> Self { + JsNativeError::error() + .with_message("TemporalTester:unsupported") + .into() + } +} + +#[derive(Clone, Trace, Finalize, Serialize)] +pub(crate) enum Assertion { + DurationFullValue { + target: Duration, + years: i32, + months: i32, + weeks: i32, + days: i32, + hours: i32, + minutes: i32, + seconds: i32, + milliseconds: i32, + microseconds: i32, + nanoseconds: i32, + }, + DurationDateValue {}, +} + +#[derive(Default, Clone, Serialize, Trace, Finalize, JsData)] +pub(crate) struct AssertionsTracker { + pub(crate) assertions: Vec, +} + +pub(crate) fn patch_harness(context: &mut Context) -> JsResult<()> { + let helpers = context + .global_object() + .get(js_string!("TemporalHelpers"), context)?; + + let Some(o) = helpers.as_object() else { + return Ok(()); + }; + + o.set( + js_string!("assertDuration"), + NativeFunction::from_fn_ptr(assert_duration).to_js_function(context.realm()), + true, + context, + )?; + + Ok(()) +} + +fn assert_duration(_this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { + let target = args + .get_or_undefined(0) + .as_object() + .and_then(|o| o.downcast_ref::()) + .map(|o| o.clone()) + .ok_or_else(|| JsNativeError::typ().with_message("invalid call to `assertDuration`"))?; + let years: i32 = args.get_or_undefined(1).try_js_into(context)?; + let months: i32 = args.get_or_undefined(2).try_js_into(context)?; + let weeks: i32 = args.get_or_undefined(3).try_js_into(context)?; + let days: i32 = args.get_or_undefined(4).try_js_into(context)?; + let hours: i32 = args.get_or_undefined(5).try_js_into(context)?; + let minutes: i32 = args.get_or_undefined(6).try_js_into(context)?; + let seconds: i32 = args.get_or_undefined(7).try_js_into(context)?; + let milliseconds: i32 = args.get_or_undefined(8).try_js_into(context)?; + let microseconds: i32 = args.get_or_undefined(8).try_js_into(context)?; + let nanoseconds: i32 = args.get_or_undefined(9).try_js_into(context)?; + + context + .realm() + .host_defined_mut() + .get_mut::() + .ok_or_else(|| JsNativeError::typ().with_message("missing assertions tracker on context"))? + .assertions + .push(Assertion::DurationFullValue { + target, + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + }); + + Ok(JsValue::undefined()) +} diff --git a/testgen/src/exec/temporal/duration.rs b/testgen/src/exec/temporal/duration.rs new file mode 100644 index 000000000..8cc940925 --- /dev/null +++ b/testgen/src/exec/temporal/duration.rs @@ -0,0 +1,161 @@ +use boa_engine::prelude::{JsValue, *}; +use boa_engine::{ + class::{Class, ClassBuilder}, + js_string, Context, JsArgs, JsResult, +}; +use boa_gc::{Finalize, Trace}; +use serde::{Deserialize, Serialize}; + +use super::TemporalUnsupported; + +#[derive(Clone, Debug, Trace, Finalize, Serialize, Deserialize)] +pub(crate) enum DurationInitializer { + Full { + years: i32, + months: i32, + weeks: i32, + days: i32, + hours: i32, + minutes: i32, + seconds: i32, + milliseconds: i32, + microseconds: i32, + nanoseconds: i32, + }, + String(String), +} + +#[derive(Clone, Debug, Trace, Finalize, Serialize, Deserialize, JsData)] +pub(crate) enum Duration { + Plain(DurationInitializer), + Add { + target: Box, + other: Box, + // TODO: relativeTo, + }, + Subtract { + target: Box, + other: Box, + // TODO: relativeTo, + }, + Negated(Box), + Abs(Box), + // TODO: round +} + +impl Class for Duration { + const NAME: &'static str = "Duration"; + + fn init(class: &mut ClassBuilder<'_>) -> JsResult<()> { + class + .static_method( + js_string!("from"), + 1, + NativeFunction::from_fn_ptr(Self::from), + ) + .method(js_string!("add"), 1, NativeFunction::from_fn_ptr(Self::add)); + + Ok(()) + } + + fn data_constructor( + _new_target: &JsValue, + args: &[JsValue], + _context: &mut Context, + ) -> boa_engine::JsResult { + let years = to_integer_if_integral(args.get_or_undefined(0))?; + let months = to_integer_if_integral(args.get_or_undefined(1))?; + let weeks = to_integer_if_integral(args.get_or_undefined(2))?; + let days = to_integer_if_integral(args.get_or_undefined(3))?; + let hours = to_integer_if_integral(args.get_or_undefined(4))?; + let minutes = to_integer_if_integral(args.get_or_undefined(5))?; + let seconds = to_integer_if_integral(args.get_or_undefined(6))?; + let milliseconds = to_integer_if_integral(args.get_or_undefined(7))?; + let microseconds = to_integer_if_integral(args.get_or_undefined(8))?; + let nanoseconds = to_integer_if_integral(args.get_or_undefined(9))?; + + Ok(Self::Plain(DurationInitializer::Full { + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + })) + } +} + +impl Duration { + fn from_js_value(duration: &JsValue) -> JsResult { + if let Some(o) = duration.as_object().and_then(|o| o.downcast_ref::()) { + return Ok(o.clone()); + } + + if let JsValue::String(s) = duration { + return Ok(Duration::Plain(DurationInitializer::String( + s.to_std_string_escaped(), + ))); + } + + Err(TemporalUnsupported.into()) + } + fn from(_this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { + let duration = args.get_or_undefined(0); + if args.len() > 1 { + return Err(TemporalUnsupported.into()); + } + + let prototype = context + .get_global_class::() + .ok_or_else(|| JsNativeError::typ().with_message("missing class `Temporal.Duration`"))? + .prototype(); + let duration = Self::from_js_value(duration)?; + + Ok(JsObject::from_proto_and_data(prototype, duration).into()) + } + + fn add(this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { + if args.len() > 1 { + return Err(TemporalUnsupported.into()); + } + let lhs = this + .as_object() + .cloned() + .and_then(|o| o.downcast::().ok()) + .ok_or(TemporalUnsupported)?; + let lhs = lhs.borrow().data().clone(); + let rhs = Self::from_js_value(args.get_or_undefined(0))?; + + let prototype = context + .eval(Source::from_bytes("Temporal.Duration.prototype"))? + .as_object() + .cloned() + .ok_or(TemporalUnsupported)?; + + Ok(JsObject::from_proto_and_data( + prototype, + Duration::Add { + target: Box::new(lhs), + other: Box::new(rhs), + }, + ) + .into()) + } +} + + +fn to_integer_if_integral(value: &JsValue) -> JsResult { + if value.is_undefined() { + Ok(0) + } else if let JsValue::Integer(i) = value { + Ok(*i) + } else { + Err(JsNativeError::error() + .with_message("TemporalTester:unsupported") + .into()) + } +} \ No newline at end of file diff --git a/testgen/src/main.rs b/testgen/src/main.rs new file mode 100644 index 000000000..557b8fa3d --- /dev/null +++ b/testgen/src/main.rs @@ -0,0 +1,437 @@ +//! Test262 test runner +//! +//! This crate will run the full ECMAScript test suite (Test262) and report compliance of the +//! `boa` engine. +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![allow( + clippy::too_many_lines, + clippy::redundant_pub_crate, + clippy::cast_precision_loss +)] + +mod edition; +mod exec; +mod read; + +use self::read::{read_harness, read_suite, MetaData, Negative, TestFlag}; +use bitflags::bitflags; +use color_eyre::{ + eyre::{bail, eyre, Report, WrapErr}, + Result, +}; +use edition::SpecEdition; +use log::{info, warn}; +use read::ErrorType; +use rustc_hash::{FxHashMap, FxHashSet}; +use serde::{ + de::{Unexpected, Visitor}, + Deserialize, Deserializer, +}; +use std::{path::Path, process::Command}; + +const DEFAULT_TEST262_DIRECTORY: &str = "test262"; + +const TESTDATA_DIRECTORY: &str = "temporal_rs/testdata"; + +/// Program entry point. +fn main() -> Result<()> { + const TEST262_COMMIT: &str = "6f7ae1f311a7b01ef2358de7f4f6fd42c3ae3839"; + color_eyre::install()?; + env_logger::init(); + + let threading = true; + + clone_test262(Some(TEST262_COMMIT))?; + let test262_path = Path::new(DEFAULT_TEST262_DIRECTORY); + + run_temporal_suite(threading, test262_path) +} + +/// Returns the commit hash and commit message of the provided branch name. +fn get_last_branch_commit(branch: &str) -> Result<(String, String)> { + info!("Getting last commit on '{branch}' branch"); + + let result = Command::new("git") + .arg("log") + .args(["-n", "1"]) + .arg("--pretty=format:%H %s") + .arg(branch) + .current_dir(DEFAULT_TEST262_DIRECTORY) + .output()?; + + if !result.status.success() { + bail!( + "test262 getting commit hash and message failed with return code {:?}", + result.status.code() + ); + } + + let output = std::str::from_utf8(&result.stdout)?.trim(); + + let (hash, message) = output + .split_once(' ') + .expect("git log output to contain hash and message"); + + Ok((hash.into(), message.into())) +} + +fn reset_test262_commit(commit: &str) -> Result<()> { + info!("Reset test262 to commit: {commit}..."); + + let result = Command::new("git") + .arg("reset") + .arg("--hard") + .arg(commit) + .current_dir(DEFAULT_TEST262_DIRECTORY) + .status()?; + + if !result.success() { + bail!( + "test262 commit {commit} checkout failed with return code: {:?}", + result.code() + ); + } + + Ok(()) +} + +fn clone_test262(commit: Option<&str>) -> Result<()> { + const TEST262_REPOSITORY: &str = "https://github.com/tc39/test262"; + + let update = commit.is_none(); + + if Path::new(DEFAULT_TEST262_DIRECTORY).is_dir() { + let (current_commit_hash, current_commit_message) = get_last_branch_commit("HEAD")?; + + if let Some(commit) = commit { + if current_commit_hash == commit { + return Ok(()); + } + } + + info!("Fetching latest test262 commits..."); + + let result = Command::new("git") + .arg("fetch") + .current_dir(DEFAULT_TEST262_DIRECTORY) + .status()?; + + if !result.success() { + bail!( + "Test262 fetching latest failed with return code {:?}", + result.code() + ); + } + + if let Some(commit) = commit { + println!("Test262 switching to commit {commit}..."); + reset_test262_commit(commit)?; + return Ok(()); + } + + info!("Checking latest Test262 with current HEAD..."); + + let (latest_commit_hash, latest_commit_message) = get_last_branch_commit("origin/main")?; + + if current_commit_hash != latest_commit_hash { + if update { + info!("Updating Test262 repository:"); + } else { + warn!("Test262 repository is not in sync, use '--test262-commit latest' to automatically update it:"); + } + + info!(" Current commit: {current_commit_hash} {current_commit_message}"); + info!(" Latest commit: {latest_commit_hash} {latest_commit_message}"); + + if update { + reset_test262_commit(&latest_commit_hash)?; + } + } + + return Ok(()); + } + + println!("Cloning test262..."); + let result = Command::new("git") + .arg("clone") + .arg(TEST262_REPOSITORY) + .arg(DEFAULT_TEST262_DIRECTORY) + .status()?; + + if !result.success() { + bail!( + "Cloning Test262 repository failed with return code {:?}", + result.code() + ); + } + + if let Some(commit) = commit { + info!("Reset Test262 to commit: {commit}..."); + + reset_test262_commit(commit)?; + } + + Ok(()) +} + +/// Runs the full test suite. +fn run_temporal_suite(parallel: bool, test262_path: &Path) -> Result<()> { + info!("Loading the test suite..."); + let harness = read_harness(test262_path).wrap_err("could not read the harness file")?; + + let suite_path = test262_path.join(Path::new("test/built-ins/Temporal")); + + let suite = read_suite(&suite_path).wrap_err_with(|| { + eyre!( + "could not read the Temporal suite at `{}`", + suite_path.display() + ) + })?; + info!("Test suite loaded, purging old tests..."); + if let Err(e) = std::fs::remove_dir_all(TESTDATA_DIRECTORY) { + if e.kind() != std::io::ErrorKind::NotFound { + return Err(Report::new(e) + .wrap_err(format!("failed to delete directory `{TESTDATA_DIRECTORY}`"))); + } + info!("Creating new directory `{TESTDATA_DIRECTORY}`"); + } + std::fs::create_dir_all(TESTDATA_DIRECTORY) + .wrap_err_with(|| format!("failed to create directory `{TESTDATA_DIRECTORY}`"))?; + + suite.run(&harness, parallel, SpecEdition::ESNext)?; + + Ok(()) +} + +/// All the harness include files. +#[derive(Debug, Clone)] +struct Harness { + assert: HarnessFile, + sta: HarnessFile, + includes: FxHashMap, HarnessFile>, +} + +#[derive(Debug, Clone)] +struct HarnessFile { + content: Box, + path: Box, +} + +/// Represents a test suite. +#[derive(Debug, Clone)] +struct TestSuite { + name: Box, + path: Box, + suites: Box<[TestSuite]>, + tests: Box<[Test]>, +} + +/// Represents a test. +#[derive(Debug, Clone)] +#[allow(dead_code)] +struct Test { + name: Box, + path: Box, + description: Box, + esid: Option>, + edition: SpecEdition, + flags: TestFlags, + information: Box, + expected_outcome: Outcome, + features: FxHashSet>, + includes: FxHashSet>, + locale: Locale, + ignored: bool, +} + +impl Test { + /// Creates a new test. + fn new(name: N, path: C, metadata: MetaData) -> Result + where + N: Into>, + C: Into>, + { + let edition = SpecEdition::from_test_metadata(&metadata) + .map_err(|feats| eyre!("test metadata contained unknown features: {feats:?}"))?; + + Ok(Self { + edition, + name: name.into(), + description: metadata.description, + esid: metadata.esid, + flags: metadata.flags.into(), + information: metadata.info, + features: metadata.features.into_vec().into_iter().collect(), + expected_outcome: Outcome::from(metadata.negative), + includes: metadata.includes.into_vec().into_iter().collect(), + locale: metadata.locale, + path: path.into(), + ignored: false, + }) + } + + /// Sets the test as ignored. + #[inline] + fn set_ignored(&mut self) { + self.ignored = true; + } + + /// Checks if this is a module test. + #[inline] + const fn is_module(&self) -> bool { + self.flags.contains(TestFlags::MODULE) + } +} + +/// An outcome for a test. +#[derive(Debug, Clone)] +enum Outcome { + Positive, + Negative { phase: Phase, error_type: ErrorType }, +} + +impl Default for Outcome { + fn default() -> Self { + Self::Positive + } +} + +impl From> for Outcome { + fn from(neg: Option) -> Self { + neg.map(|neg| Self::Negative { + phase: neg.phase, + error_type: neg.error_type, + }) + .unwrap_or_default() + } +} + +bitflags! { + #[derive(Debug, Clone, Copy)] + struct TestFlags: u16 { + const STRICT = 0b0_0000_0001; + const NO_STRICT = 0b0_0000_0010; + const MODULE = 0b0_0000_0100; + const RAW = 0b0_0000_1000; + const ASYNC = 0b0_0001_0000; + const GENERATED = 0b0_0010_0000; + const CAN_BLOCK_IS_FALSE = 0b0_0100_0000; + const CAN_BLOCK_IS_TRUE = 0b0_1000_0000; + const NON_DETERMINISTIC = 0b1_0000_0000; + } +} + +impl Default for TestFlags { + fn default() -> Self { + Self::STRICT | Self::NO_STRICT + } +} + +impl From for TestFlags { + fn from(flag: TestFlag) -> Self { + match flag { + TestFlag::OnlyStrict => Self::STRICT, + TestFlag::NoStrict => Self::NO_STRICT, + TestFlag::Module => Self::MODULE, + TestFlag::Raw => Self::RAW, + TestFlag::Async => Self::ASYNC, + TestFlag::Generated => Self::GENERATED, + TestFlag::CanBlockIsFalse => Self::CAN_BLOCK_IS_FALSE, + TestFlag::CanBlockIsTrue => Self::CAN_BLOCK_IS_TRUE, + TestFlag::NonDeterministic => Self::NON_DETERMINISTIC, + } + } +} + +impl From for TestFlags +where + T: AsRef<[TestFlag]>, +{ + fn from(flags: T) -> Self { + let flags = flags.as_ref(); + if flags.is_empty() { + Self::default() + } else { + let mut result = Self::empty(); + for flag in flags { + result |= Self::from(*flag); + } + + if !result.intersects(Self::default()) { + result |= Self::default(); + } + + result + } + } +} + +impl<'de> Deserialize<'de> for TestFlags { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FlagsVisitor; + + impl<'de> Visitor<'de> for FlagsVisitor { + type Value = TestFlags; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "a sequence of flags") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + let mut flags = TestFlags::empty(); + while let Some(elem) = seq.next_element::()? { + flags |= elem.into(); + } + Ok(flags) + } + } + + struct RawFlagsVisitor; + + impl Visitor<'_> for RawFlagsVisitor { + type Value = TestFlags; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "a flags number") + } + + fn visit_u16(self, v: u16) -> Result + where + E: serde::de::Error, + { + TestFlags::from_bits(v).ok_or_else(|| { + E::invalid_value(Unexpected::Unsigned(v.into()), &"a valid flag number") + }) + } + } + + if deserializer.is_human_readable() { + deserializer.deserialize_seq(FlagsVisitor) + } else { + deserializer.deserialize_u16(RawFlagsVisitor) + } + } +} + +/// Phase for an error. +#[derive(Debug, Clone, Copy, Deserialize)] +#[serde(rename_all = "lowercase")] +enum Phase { + Parse, + Resolution, + Runtime, +} + +/// Locale information structure. +#[derive(Debug, Default, Clone, Deserialize)] +#[serde(transparent)] +#[allow(dead_code)] +struct Locale { + locale: Box<[Box]>, +} diff --git a/testgen/src/read.rs b/testgen/src/read.rs new file mode 100644 index 000000000..36492ccf6 --- /dev/null +++ b/testgen/src/read.rs @@ -0,0 +1,214 @@ +//! Module to read the list of test suites from disk. + +use crate::HarnessFile; + +use super::{Harness, Locale, Phase, Test, TestSuite}; +use color_eyre::{ + eyre::{eyre, OptionExt, WrapErr}, + Result, +}; +use rustc_hash::FxHashMap; +use serde::Deserialize; +use std::{ + ffi::OsStr, + fs, + path::{Path, PathBuf}, + sync::OnceLock, +}; + +/// Representation of the YAML metadata in Test262 tests. +#[derive(Debug, Clone, Deserialize)] +pub(super) struct MetaData { + pub(super) description: Box, + pub(super) esid: Option>, + #[allow(dead_code)] + pub(super) es5id: Option>, + pub(super) es6id: Option>, + #[serde(default)] + pub(super) info: Box, + #[serde(default)] + pub(super) features: Box<[Box]>, + #[serde(default)] + pub(super) includes: Box<[Box]>, + #[serde(default)] + pub(super) flags: Box<[TestFlag]>, + #[serde(default)] + pub(super) negative: Option, + #[serde(default)] + pub(super) locale: Locale, +} + +/// Negative test information structure. +#[derive(Debug, Clone, Deserialize)] +pub(super) struct Negative { + pub(super) phase: Phase, + #[serde(rename = "type")] + pub(super) error_type: ErrorType, +} + +/// All possible error types +#[derive(Debug, Copy, Clone, Deserialize, PartialEq, Eq)] +#[allow(clippy::enum_variant_names)] // Better than appending `rename` to all variants +pub(super) enum ErrorType { + Test262Error, + SyntaxError, + ReferenceError, + RangeError, + TypeError, +} + +/// Individual test flag. +#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(super) enum TestFlag { + OnlyStrict, + NoStrict, + Module, + Raw, + Async, + Generated, + #[serde(rename = "CanBlockIsFalse")] + CanBlockIsFalse, + #[serde(rename = "CanBlockIsTrue")] + CanBlockIsTrue, + #[serde(rename = "non-deterministic")] + NonDeterministic, +} + +/// Reads the Test262 defined bindings. +pub(super) fn read_harness(test262_path: &Path) -> Result { + fn read_harness_file(path: PathBuf) -> Result { + let content = fs::read_to_string(path.as_path()) + .wrap_err_with(|| format!("error reading the harness file `{}`", path.display()))?; + + Ok(HarnessFile { + content: content.into_boxed_str(), + path: path.into_boxed_path(), + }) + } + let mut includes = FxHashMap::default(); + + for entry in fs::read_dir(test262_path.join("harness")) + .wrap_err("error reading the harness directory")? + { + let entry = entry?; + let file_name = entry.file_name(); + let file_name = file_name.to_string_lossy(); + + if file_name == "assert.js" || file_name == "sta.js" || file_name == "doneprintHandle.js" { + continue; + } + + includes.insert( + file_name.into_owned().into_boxed_str(), + read_harness_file(entry.path())?, + ); + } + let assert = read_harness_file(test262_path.join("harness/assert.js"))?; + let sta = read_harness_file(test262_path.join("harness/sta.js"))?; + + Ok(Harness { + assert, + sta, + includes, + }) +} + +/// Reads a test suite in the given path. +pub(super) fn read_suite(path: &Path) -> 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())))?; + + let mut suites = Vec::new(); + let mut tests = Vec::new(); + + // TODO: iterate in parallel + for entry in path.read_dir().wrap_err("could not retrieve entry")? { + let entry = entry?; + let filetype = entry.file_type().wrap_err("could not retrieve file type")?; + + if filetype.is_dir() { + suites.push(read_suite(entry.path().as_path()).wrap_err_with(|| { + let path = entry.path(); + let suite = path.display(); + format!("error reading sub-suite {suite}") + })?); + continue; + } + + let path = entry.path(); + + if path.extension() != Some(OsStr::new("js")) { + // Ignore files that aren't executable. + continue; + } + + if path + .file_stem() + .is_some_and(|stem| stem.as_encoded_bytes().ends_with(b"FIXTURE")) + { + // Ignore files that are fixtures. + continue; + } + + let test = read_test(&path).wrap_err_with(|| { + let path = entry.path(); + let suite = path.display(); + format!("error reading test {suite}") + })?; + + tests.push(test); + } + + Ok(TestSuite { + name: name.into(), + path: Box::from(path), + suites: suites.into_boxed_slice(), + tests: tests.into_boxed_slice(), + }) +} + +/// Reads information about a given test case. +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() + ) + })?; + + let metadata = read_metadata(path)?; + + Test::new(name, path, metadata) +} + +/// Reads the metadata from the input test code. +fn read_metadata(test: &Path) -> Result { + use regex::bytes::Regex; + + /// Regular expression to retrieve the metadata of a test. + static META_REGEX: OnceLock = OnceLock::new(); + + let code = fs::read_to_string(test)?; + + let yaml = META_REGEX + .get_or_init(|| { + Regex::new(r"/\*\-{3}((?:.|\n)*)\-{3}\*/") + .expect("could not compile metadata regular expression") + }) + .captures(code.as_bytes()) + .ok_or_eyre("missing metadata for test")? + .get(1) + .map(|m| String::from_utf8_lossy(m.as_bytes())) + .ok_or_eyre("invalid metadata for test")? + .replace('\r', "\n"); + + serde_yaml::from_str(&yaml).map_err(Into::into) +}