From bb81d3c220afd5e828f5d66c858fea25f668fa82 Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 17 Dec 2024 16:32:08 +0800 Subject: [PATCH] generate all data --- .typos.toml | 9 + Cargo.lock | 48 +- Cargo.toml | 10 +- build.cjs | 69 +- data.json | 5702 ++++++++++++++++- src/ctx.rs | 23 + src/feature.rs | 24 +- src/features.rs | 444 +- src/implementation.rs | 836 +-- .../es2016_array_prototype_includes.rs | 6 + .../es2016_exponentiation_operator.rs | 14 + ...erator_functions_can_t_be_used_with_new.rs | 6 + ...nerator_throw_caught_by_inner_generator.rs | 6 + ..._nested_rest_destructuring_declarations.rs | 6 + ...16_nested_rest_destructuring_parameters.rs | 6 + .../es2016_proxy_enumerate_handler_removed.rs | 6 + ...internal_calls_array_prototype_includes.rs | 6 + ...w_non_strict_non_simple_params_is_error.rs | 6 + .../es2017_arguments_caller_removed.rs | 6 + ...lowed_in_for_in_head_in_non_strict_mode.rs | 6 + src/implementation/es2017_async_functions.rs | 6 + ..._object_prototype_getter_setter_methods.rs | 6 + .../es2017_object_static_methods.rs | 6 + ...xy_internal_calls_getter_setter_methods.rs | 6 + .../es2017_reg_exp_u_flag_case_folding.rs | 6 + .../es2017_shared_memory_and_atomics.rs | 6 + src/implementation/es2017_string_padding.rs | 6 + ...2017_trailing_commas_in_function_syntax.rs | 6 + .../es2018_asynchronous_iterators.rs | 6 + .../es2018_object_rest_spread_properties.rs | 6 + .../es2018_promise_prototype_finally.rs | 6 + ...plicate_keys_for_non_extensible_targets.rs | 6 + .../es2018_reg_exp_lookbehind_assertions.rs | 6 + .../es2018_reg_exp_named_capture_groups.rs | 6 + ...es2018_reg_exp_unicode_property_escapes.rs | 6 + ..._s_dot_all_flag_for_regular_expressions.rs | 6 + .../es2018_template_literal_revision.rs | 6 + .../es2019_array_prototype_flat_flat_map.rs | 6 + ...9_function_prototype_to_string_revision.rs | 6 + src/implementation/es2019_json_superset.rs | 6 + .../es2019_object_from_entries.rs | 6 + .../es2019_optional_catch_binding.rs | 6 + src/implementation/es2019_string_trimming.rs | 6 + .../es2019_symbol_prototype_description.rs | 6 + .../es2019_well_formed_json_stringify.rs | 6 + src/implementation/es2020_big_int.rs | 6 + src/implementation/es2020_global_this.rs | 6 + .../es2020_nullish_coalescing_operator.rs | 6 + .../es2020_optional_chaining_operator.rs | 6 + .../es2020_promise_all_settled.rs | 6 + .../es2020_string_prototype_match_all.rs | 6 + .../es2021_logical_assignment.rs | 6 + .../es2021_numeric_separators.rs | 6 + src/implementation/es2021_promise_any.rs | 6 + .../es2021_string_prototype_replace_all.rs | 6 + src/implementation/es2021_weak_references.rs | 6 + ...22_at_method_on_the_built_in_indexables.rs | 6 + ...2022_class_static_initialization_blocks.rs | 6 + ...gonomic_brand_checks_for_private_fields.rs | 6 + .../es2022_error_cause_property.rs | 6 + .../es2022_instance_class_fields.rs | 6 + src/implementation/es2022_object_has_own.rs | 6 + .../es2022_private_class_methods.rs | 6 + ...eg_exp_match_indices_has_indices_d_flag.rs | 6 + .../es2022_static_class_fields.rs | 6 + .../es2023_array_find_from_last.rs | 6 + .../es2023_change_array_by_copy.rs | 6 + src/implementation/es2023_hashbang_grammar.rs | 6 + .../es2024_array_buffer_prototype_transfer.rs | 6 + src/implementation/es2024_array_grouping.rs | 6 + .../es2024_promise_with_resolvers.rs | 6 + src/implementation/es2024_reg_exp_v_flag.rs | 6 + ...es2025_duplicate_named_capturing_groups.rs | 6 + src/implementation/es2025_iterator_helpers.rs | 6 + src/implementation/es2025_promise_try.rs | 6 + .../es2025_reg_exp_pattern_modifiers.rs | 6 + src/implementation/es2025_set_methods.rs | 6 + src/implementation/es5_array_methods.rs | 6 + src/implementation/es5_date_methods.rs | 6 + .../es5_function_prototype_bind.rs | 6 + src/implementation/es5_immutable_globals.rs | 6 + src/implementation/es5_json.rs | 6 + src/implementation/es5_miscellaneous.rs | 6 + src/implementation/es5_number_methods.rs | 6 + .../es5_object_array_literal_extensions.rs | 6 + .../es5_object_static_methods.rs | 6 + src/implementation/es5_strict_mode.rs | 6 + .../es5_string_properties_and_methods.rs | 6 + .../es6_array_is_subclassable.rs | 6 + .../es6_array_prototype_methods.rs | 6 + .../es6_array_static_methods.rs | 6 + src/implementation/es6_arrow_functions.rs | 6 + .../es6_block_level_function_declaration.rs | 6 + src/implementation/es6_class.rs | 6 + src/implementation/es6_const.rs | 6 + .../es6_date_prototype_symbol_to_primitive.rs | 6 + .../es6_default_function_parameters.rs | 6 + .../es6_destructuring_assignment.rs | 6 + .../es6_destructuring_declarations.rs | 6 + .../es6_destructuring_parameters.rs | 6 + src/implementation/es6_for_of_loops.rs | 6 + .../es6_function_is_subclassable.rs | 6 + .../es6_function_name_property.rs | 6 + src/implementation/es6_generators.rs | 6 + src/implementation/es6_html_style_comments.rs | 6 + src/implementation/es6_let.rs | 6 + src/implementation/es6_map.rs | 6 + src/implementation/es6_math_methods.rs | 6 + src/implementation/es6_miscellaneous.rs | 6 + .../es6_miscellaneous_subclassables.rs | 6 + src/implementation/es6_new_target.rs | 6 + .../es6_non_strict_function_semantics.rs | 6 + src/implementation/es6_number_properties.rs | 6 + .../es6_object_literal_extensions.rs | 6 + .../es6_object_prototype_proto.rs | 6 + .../es6_object_static_methods.rs | 6 + ...object_static_methods_accept_primitives.rs | 6 + .../es6_octal_and_binary_literals.rs | 6 + src/implementation/es6_own_property_order.rs | 6 + src/implementation/es6_promise.rs | 6 + .../es6_promise_is_subclassable.rs | 6 + ...roper_tail_calls_tail_call_optimisation.rs | 6 + .../es6_proto_in_object_literals.rs | 6 + .../es6_prototype_of_bound_functions.rs | 6 + src/implementation/es6_proxy.rs | 6 + ...s6_proxy_internal_define_property_calls.rs | 6 + ...s6_proxy_internal_delete_property_calls.rs | 6 + .../es6_proxy_internal_get_calls.rs | 6 + ...ernal_get_own_property_descriptor_calls.rs | 6 + .../es6_proxy_internal_own_keys_calls.rs | 6 + .../es6_proxy_internal_set_calls.rs | 6 + src/implementation/es6_reflect.rs | 6 + .../es6_reg_exp_is_subclassable.rs | 6 + .../es6_reg_exp_prototype_compile.rs | 6 + .../es6_reg_exp_prototype_properties.rs | 6 + .../es6_reg_exp_syntax_extensions.rs | 6 + .../es6_reg_exp_y_and_u_flags.rs | 6 + src/implementation/es6_rest_parameters.rs | 6 + src/implementation/es6_set.rs | 6 + .../es6_spread_syntax_for_iterable_objects.rs | 6 + .../es6_string_prototype_html_methods.rs | 6 + .../es6_string_prototype_methods.rs | 6 + .../es6_string_static_methods.rs | 6 + src/implementation/es6_super.rs | 6 + src/implementation/es6_symbol.rs | 6 + src/implementation/es6_template_literals.rs | 6 + src/implementation/es6_typed_arrays.rs | 6 + .../es6_unicode_code_point_escapes.rs | 6 + .../es6_updated_identifier_syntax.rs | 6 + src/implementation/es6_weak_map.rs | 6 + src/implementation/es6_weak_set.rs | 6 + src/implementation/es6_well_known_symbols.rs | 6 + .../esnext_array_is_template_object.rs | 6 + .../esnext_async_iterator_helpers.rs | 6 + .../esnext_class_and_property_decorators.rs | 6 + ...t_generator_function_sent_meta_property.rs | 6 + ..._legacy_reg_exp_features_in_java_script.rs | 6 + .../esnext_map_prototype_upsert.rs | 6 + src/implementation/esnext_reg_exp_escaping.rs | 6 + src/implementation/esnext_shadow_realm.rs | 6 + .../esnext_throw_expressions.rs | 6 + .../esnext_uint_array_to_from_base_and_hex.rs | 6 + src/lib.rs | 4 + src/main.rs | 18 +- src/meta.rs | 153 + src/meta/es2016_array_prototype_includes.rs | 38 + src/meta/es2016_exponentiation_operator.rs | 35 + ...erator_functions_can_t_be_used_with_new.rs | 28 + ...nerator_throw_caught_by_inner_generator.rs | 28 + ..._nested_rest_destructuring_declarations.rs | 28 + ...16_nested_rest_destructuring_parameters.rs | 28 + .../es2016_proxy_enumerate_handler_removed.rs | 28 + ...internal_calls_array_prototype_includes.rs | 28 + ...w_non_strict_non_simple_params_is_error.rs | 28 + src/meta/es2017_arguments_caller_removed.rs | 28 + ...lowed_in_for_in_head_in_non_strict_mode.rs | 28 + src/meta/es2017_async_functions.rs | 62 + ..._object_prototype_getter_setter_methods.rs | 64 + src/meta/es2017_object_static_methods.rs | 40 + ...xy_internal_calls_getter_setter_methods.rs | 38 + .../es2017_reg_exp_u_flag_case_folding.rs | 28 + src/meta/es2017_shared_memory_and_atomics.rs | 57 + src/meta/es2017_string_padding.rs | 34 + ...2017_trailing_commas_in_function_syntax.rs | 34 + src/meta/es2018_asynchronous_iterators.rs | 34 + .../es2018_object_rest_spread_properties.rs | 34 + src/meta/es2018_promise_prototype_finally.rs | 36 + ...plicate_keys_for_non_extensible_targets.rs | 28 + .../es2018_reg_exp_lookbehind_assertions.rs | 28 + .../es2018_reg_exp_named_capture_groups.rs | 28 + ...es2018_reg_exp_unicode_property_escapes.rs | 48 + ..._s_dot_all_flag_for_regular_expressions.rs | 28 + src/meta/es2018_template_literal_revision.rs | 28 + .../es2019_array_prototype_flat_flat_map.rs | 37 + ...9_function_prototype_to_string_revision.rs | 44 + src/meta/es2019_json_superset.rs | 37 + src/meta/es2019_object_from_entries.rs | 28 + src/meta/es2019_optional_catch_binding.rs | 36 + src/meta/es2019_string_trimming.rs | 45 + .../es2019_symbol_prototype_description.rs | 35 + src/meta/es2019_well_formed_json_stringify.rs | 28 + src/meta/es2020_big_int.rs | 43 + src/meta/es2020_global_this.rs | 35 + .../es2020_nullish_coalescing_operator.rs | 28 + src/meta/es2020_optional_chaining_operator.rs | 40 + src/meta/es2020_promise_all_settled.rs | 28 + src/meta/es2020_string_prototype_match_all.rs | 34 + src/meta/es2021_logical_assignment.rs | 48 + src/meta/es2021_numeric_separators.rs | 28 + src/meta/es2021_promise_any.rs | 34 + .../es2021_string_prototype_replace_all.rs | 28 + src/meta/es2021_weak_references.rs | 34 + ...22_at_method_on_the_built_in_indexables.rs | 36 + ...2022_class_static_initialization_blocks.rs | 28 + ...gonomic_brand_checks_for_private_fields.rs | 28 + src/meta/es2022_error_cause_property.rs | 61 + src/meta/es2022_instance_class_fields.rs | 45 + src/meta/es2022_object_has_own.rs | 34 + src/meta/es2022_private_class_methods.rs | 38 + ...eg_exp_match_indices_has_indices_d_flag.rs | 34 + src/meta/es2022_static_class_fields.rs | 37 + src/meta/es2023_array_find_from_last.rs | 34 + src/meta/es2023_change_array_by_copy.rs | 44 + src/meta/es2023_hashbang_grammar.rs | 28 + .../es2024_array_buffer_prototype_transfer.rs | 36 + src/meta/es2024_array_grouping.rs | 34 + src/meta/es2024_promise_with_resolvers.rs | 28 + src/meta/es2024_reg_exp_v_flag.rs | 40 + ...es2025_duplicate_named_capturing_groups.rs | 28 + src/meta/es2025_iterator_helpers.rs | 61 + src/meta/es2025_promise_try.rs | 28 + src/meta/es2025_reg_exp_pattern_modifiers.rs | 36 + src/meta/es2025_set_methods.rs | 43 + src/meta/es5_array_methods.rs | 58 + src/meta/es5_date_methods.rs | 36 + src/meta/es5_function_prototype_bind.rs | 28 + src/meta/es5_immutable_globals.rs | 36 + src/meta/es5_json.rs | 28 + src/meta/es5_miscellaneous.rs | 47 + src/meta/es5_number_methods.rs | 38 + .../es5_object_array_literal_extensions.rs | 46 + src/meta/es5_object_static_methods.rs | 56 + src/meta/es5_strict_mode.rs | 76 + src/meta/es5_string_properties_and_methods.rs | 38 + src/meta/es6_array_is_subclassable.rs | 51 + src/meta/es6_array_prototype_methods.rs | 52 + src/meta/es6_array_static_methods.rs | 52 + src/meta/es6_arrow_functions.rs | 56 + .../es6_block_level_function_declaration.rs | 28 + src/meta/es6_class.rs | 77 + src/meta/es6_const.rs | 66 + .../es6_date_prototype_symbol_to_primitive.rs | 28 + src/meta/es6_default_function_parameters.rs | 44 + src/meta/es6_destructuring_assignment.rs | 78 + src/meta/es6_destructuring_declarations.rs | 74 + src/meta/es6_destructuring_parameters.rs | 82 + src/meta/es6_for_of_loops.rs | 48 + src/meta/es6_function_is_subclassable.rs | 42 + src/meta/es6_function_name_property.rs | 64 + src/meta/es6_generators.rs | 84 + src/meta/es6_html_style_comments.rs | 28 + src/meta/es6_let.rs | 63 + src/meta/es6_map.rs | 68 + src/meta/es6_math_methods.rs | 54 + src/meta/es6_miscellaneous.rs | 48 + src/meta/es6_miscellaneous_subclassables.rs | 42 + src/meta/es6_new_target.rs | 34 + src/meta/es6_non_strict_function_semantics.rs | 36 + src/meta/es6_number_properties.rs | 45 + src/meta/es6_object_literal_extensions.rs | 42 + src/meta/es6_object_prototype_proto.rs | 42 + src/meta/es6_object_static_methods.rs | 37 + ...object_static_methods_accept_primitives.rs | 46 + src/meta/es6_octal_and_binary_literals.rs | 33 + src/meta/es6_own_property_order.rs | 44 + src/meta/es6_promise.rs | 46 + src/meta/es6_promise_is_subclassable.rs | 38 + ...roper_tail_calls_tail_call_optimisation.rs | 34 + src/meta/es6_proto_in_object_literals.rs | 40 + src/meta/es6_prototype_of_bound_functions.rs | 40 + src/meta/es6_proxy.rs | 97 + ...s6_proxy_internal_define_property_calls.rs | 34 + ...s6_proxy_internal_delete_property_calls.rs | 42 + src/meta/es6_proxy_internal_get_calls.rs | 102 + ...ernal_get_own_property_descriptor_calls.rs | 38 + src/meta/es6_proxy_internal_own_keys_calls.rs | 36 + src/meta/es6_proxy_internal_set_calls.rs | 52 + src/meta/es6_reflect.rs | 71 + src/meta/es6_reg_exp_is_subclassable.rs | 38 + src/meta/es6_reg_exp_prototype_compile.rs | 33 + src/meta/es6_reg_exp_prototype_properties.rs | 42 + src/meta/es6_reg_exp_syntax_extensions.rs | 46 + src/meta/es6_reg_exp_y_and_u_flags.rs | 41 + src/meta/es6_rest_parameters.rs | 40 + src/meta/es6_set.rs | 68 + .../es6_spread_syntax_for_iterable_objects.rs | 59 + src/meta/es6_string_prototype_html_methods.rs | 36 + src/meta/es6_string_prototype_methods.rs | 50 + src/meta/es6_string_static_methods.rs | 34 + src/meta/es6_super.rs | 47 + src/meta/es6_symbol.rs | 54 + src/meta/es6_template_literals.rs | 44 + src/meta/es6_typed_arrays.rs | 122 + src/meta/es6_unicode_code_point_escapes.rs | 42 + src/meta/es6_updated_identifier_syntax.rs | 35 + src/meta/es6_weak_map.rs | 55 + src/meta/es6_weak_set.rs | 52 + src/meta/es6_well_known_symbols.rs | 85 + src/meta/esnext_array_is_template_object.rs | 28 + src/meta/esnext_async_iterator_helpers.rs | 63 + .../esnext_class_and_property_decorators.rs | 32 + ...t_generator_function_sent_meta_property.rs | 28 + ..._legacy_reg_exp_features_in_java_script.rs | 34 + src/meta/esnext_map_prototype_upsert.rs | 34 + src/meta/esnext_reg_exp_escaping.rs | 28 + src/meta/esnext_shadow_realm.rs | 28 + src/meta/esnext_throw_expressions.rs | 38 + .../esnext_uint_array_to_from_base_and_hex.rs | 42 + src/scanner.rs | 37 +- tasks/codegen/Cargo.toml | 15 +- tasks/codegen/src/lib.rs | 60 +- tasks/codegen/src/main.rs | 124 +- 322 files changed, 14088 insertions(+), 962 deletions(-) create mode 100644 .typos.toml create mode 100644 src/ctx.rs create mode 100644 src/implementation/es2016_array_prototype_includes.rs create mode 100644 src/implementation/es2016_exponentiation_operator.rs create mode 100644 src/implementation/es2016_generator_functions_can_t_be_used_with_new.rs create mode 100644 src/implementation/es2016_generator_throw_caught_by_inner_generator.rs create mode 100644 src/implementation/es2016_nested_rest_destructuring_declarations.rs create mode 100644 src/implementation/es2016_nested_rest_destructuring_parameters.rs create mode 100644 src/implementation/es2016_proxy_enumerate_handler_removed.rs create mode 100644 src/implementation/es2016_proxy_internal_calls_array_prototype_includes.rs create mode 100644 src/implementation/es2016_strict_fn_w_non_strict_non_simple_params_is_error.rs create mode 100644 src/implementation/es2017_arguments_caller_removed.rs create mode 100644 src/implementation/es2017_assignments_allowed_in_for_in_head_in_non_strict_mode.rs create mode 100644 src/implementation/es2017_async_functions.rs create mode 100644 src/implementation/es2017_object_prototype_getter_setter_methods.rs create mode 100644 src/implementation/es2017_object_static_methods.rs create mode 100644 src/implementation/es2017_proxy_internal_calls_getter_setter_methods.rs create mode 100644 src/implementation/es2017_reg_exp_u_flag_case_folding.rs create mode 100644 src/implementation/es2017_shared_memory_and_atomics.rs create mode 100644 src/implementation/es2017_string_padding.rs create mode 100644 src/implementation/es2017_trailing_commas_in_function_syntax.rs create mode 100644 src/implementation/es2018_asynchronous_iterators.rs create mode 100644 src/implementation/es2018_object_rest_spread_properties.rs create mode 100644 src/implementation/es2018_promise_prototype_finally.rs create mode 100644 src/implementation/es2018_proxy_own_keys_handler_duplicate_keys_for_non_extensible_targets.rs create mode 100644 src/implementation/es2018_reg_exp_lookbehind_assertions.rs create mode 100644 src/implementation/es2018_reg_exp_named_capture_groups.rs create mode 100644 src/implementation/es2018_reg_exp_unicode_property_escapes.rs create mode 100644 src/implementation/es2018_s_dot_all_flag_for_regular_expressions.rs create mode 100644 src/implementation/es2018_template_literal_revision.rs create mode 100644 src/implementation/es2019_array_prototype_flat_flat_map.rs create mode 100644 src/implementation/es2019_function_prototype_to_string_revision.rs create mode 100644 src/implementation/es2019_json_superset.rs create mode 100644 src/implementation/es2019_object_from_entries.rs create mode 100644 src/implementation/es2019_optional_catch_binding.rs create mode 100644 src/implementation/es2019_string_trimming.rs create mode 100644 src/implementation/es2019_symbol_prototype_description.rs create mode 100644 src/implementation/es2019_well_formed_json_stringify.rs create mode 100644 src/implementation/es2020_big_int.rs create mode 100644 src/implementation/es2020_global_this.rs create mode 100644 src/implementation/es2020_nullish_coalescing_operator.rs create mode 100644 src/implementation/es2020_optional_chaining_operator.rs create mode 100644 src/implementation/es2020_promise_all_settled.rs create mode 100644 src/implementation/es2020_string_prototype_match_all.rs create mode 100644 src/implementation/es2021_logical_assignment.rs create mode 100644 src/implementation/es2021_numeric_separators.rs create mode 100644 src/implementation/es2021_promise_any.rs create mode 100644 src/implementation/es2021_string_prototype_replace_all.rs create mode 100644 src/implementation/es2021_weak_references.rs create mode 100644 src/implementation/es2022_at_method_on_the_built_in_indexables.rs create mode 100644 src/implementation/es2022_class_static_initialization_blocks.rs create mode 100644 src/implementation/es2022_ergonomic_brand_checks_for_private_fields.rs create mode 100644 src/implementation/es2022_error_cause_property.rs create mode 100644 src/implementation/es2022_instance_class_fields.rs create mode 100644 src/implementation/es2022_object_has_own.rs create mode 100644 src/implementation/es2022_private_class_methods.rs create mode 100644 src/implementation/es2022_reg_exp_match_indices_has_indices_d_flag.rs create mode 100644 src/implementation/es2022_static_class_fields.rs create mode 100644 src/implementation/es2023_array_find_from_last.rs create mode 100644 src/implementation/es2023_change_array_by_copy.rs create mode 100644 src/implementation/es2023_hashbang_grammar.rs create mode 100644 src/implementation/es2024_array_buffer_prototype_transfer.rs create mode 100644 src/implementation/es2024_array_grouping.rs create mode 100644 src/implementation/es2024_promise_with_resolvers.rs create mode 100644 src/implementation/es2024_reg_exp_v_flag.rs create mode 100644 src/implementation/es2025_duplicate_named_capturing_groups.rs create mode 100644 src/implementation/es2025_iterator_helpers.rs create mode 100644 src/implementation/es2025_promise_try.rs create mode 100644 src/implementation/es2025_reg_exp_pattern_modifiers.rs create mode 100644 src/implementation/es2025_set_methods.rs create mode 100644 src/implementation/es5_array_methods.rs create mode 100644 src/implementation/es5_date_methods.rs create mode 100644 src/implementation/es5_function_prototype_bind.rs create mode 100644 src/implementation/es5_immutable_globals.rs create mode 100644 src/implementation/es5_json.rs create mode 100644 src/implementation/es5_miscellaneous.rs create mode 100644 src/implementation/es5_number_methods.rs create mode 100644 src/implementation/es5_object_array_literal_extensions.rs create mode 100644 src/implementation/es5_object_static_methods.rs create mode 100644 src/implementation/es5_strict_mode.rs create mode 100644 src/implementation/es5_string_properties_and_methods.rs create mode 100644 src/implementation/es6_array_is_subclassable.rs create mode 100644 src/implementation/es6_array_prototype_methods.rs create mode 100644 src/implementation/es6_array_static_methods.rs create mode 100644 src/implementation/es6_arrow_functions.rs create mode 100644 src/implementation/es6_block_level_function_declaration.rs create mode 100644 src/implementation/es6_class.rs create mode 100644 src/implementation/es6_const.rs create mode 100644 src/implementation/es6_date_prototype_symbol_to_primitive.rs create mode 100644 src/implementation/es6_default_function_parameters.rs create mode 100644 src/implementation/es6_destructuring_assignment.rs create mode 100644 src/implementation/es6_destructuring_declarations.rs create mode 100644 src/implementation/es6_destructuring_parameters.rs create mode 100644 src/implementation/es6_for_of_loops.rs create mode 100644 src/implementation/es6_function_is_subclassable.rs create mode 100644 src/implementation/es6_function_name_property.rs create mode 100644 src/implementation/es6_generators.rs create mode 100644 src/implementation/es6_html_style_comments.rs create mode 100644 src/implementation/es6_let.rs create mode 100644 src/implementation/es6_map.rs create mode 100644 src/implementation/es6_math_methods.rs create mode 100644 src/implementation/es6_miscellaneous.rs create mode 100644 src/implementation/es6_miscellaneous_subclassables.rs create mode 100644 src/implementation/es6_new_target.rs create mode 100644 src/implementation/es6_non_strict_function_semantics.rs create mode 100644 src/implementation/es6_number_properties.rs create mode 100644 src/implementation/es6_object_literal_extensions.rs create mode 100644 src/implementation/es6_object_prototype_proto.rs create mode 100644 src/implementation/es6_object_static_methods.rs create mode 100644 src/implementation/es6_object_static_methods_accept_primitives.rs create mode 100644 src/implementation/es6_octal_and_binary_literals.rs create mode 100644 src/implementation/es6_own_property_order.rs create mode 100644 src/implementation/es6_promise.rs create mode 100644 src/implementation/es6_promise_is_subclassable.rs create mode 100644 src/implementation/es6_proper_tail_calls_tail_call_optimisation.rs create mode 100644 src/implementation/es6_proto_in_object_literals.rs create mode 100644 src/implementation/es6_prototype_of_bound_functions.rs create mode 100644 src/implementation/es6_proxy.rs create mode 100644 src/implementation/es6_proxy_internal_define_property_calls.rs create mode 100644 src/implementation/es6_proxy_internal_delete_property_calls.rs create mode 100644 src/implementation/es6_proxy_internal_get_calls.rs create mode 100644 src/implementation/es6_proxy_internal_get_own_property_descriptor_calls.rs create mode 100644 src/implementation/es6_proxy_internal_own_keys_calls.rs create mode 100644 src/implementation/es6_proxy_internal_set_calls.rs create mode 100644 src/implementation/es6_reflect.rs create mode 100644 src/implementation/es6_reg_exp_is_subclassable.rs create mode 100644 src/implementation/es6_reg_exp_prototype_compile.rs create mode 100644 src/implementation/es6_reg_exp_prototype_properties.rs create mode 100644 src/implementation/es6_reg_exp_syntax_extensions.rs create mode 100644 src/implementation/es6_reg_exp_y_and_u_flags.rs create mode 100644 src/implementation/es6_rest_parameters.rs create mode 100644 src/implementation/es6_set.rs create mode 100644 src/implementation/es6_spread_syntax_for_iterable_objects.rs create mode 100644 src/implementation/es6_string_prototype_html_methods.rs create mode 100644 src/implementation/es6_string_prototype_methods.rs create mode 100644 src/implementation/es6_string_static_methods.rs create mode 100644 src/implementation/es6_super.rs create mode 100644 src/implementation/es6_symbol.rs create mode 100644 src/implementation/es6_template_literals.rs create mode 100644 src/implementation/es6_typed_arrays.rs create mode 100644 src/implementation/es6_unicode_code_point_escapes.rs create mode 100644 src/implementation/es6_updated_identifier_syntax.rs create mode 100644 src/implementation/es6_weak_map.rs create mode 100644 src/implementation/es6_weak_set.rs create mode 100644 src/implementation/es6_well_known_symbols.rs create mode 100644 src/implementation/esnext_array_is_template_object.rs create mode 100644 src/implementation/esnext_async_iterator_helpers.rs create mode 100644 src/implementation/esnext_class_and_property_decorators.rs create mode 100644 src/implementation/esnext_generator_function_sent_meta_property.rs create mode 100644 src/implementation/esnext_legacy_reg_exp_features_in_java_script.rs create mode 100644 src/implementation/esnext_map_prototype_upsert.rs create mode 100644 src/implementation/esnext_reg_exp_escaping.rs create mode 100644 src/implementation/esnext_shadow_realm.rs create mode 100644 src/implementation/esnext_throw_expressions.rs create mode 100644 src/implementation/esnext_uint_array_to_from_base_and_hex.rs create mode 100644 src/meta.rs create mode 100644 src/meta/es2016_array_prototype_includes.rs create mode 100644 src/meta/es2016_exponentiation_operator.rs create mode 100644 src/meta/es2016_generator_functions_can_t_be_used_with_new.rs create mode 100644 src/meta/es2016_generator_throw_caught_by_inner_generator.rs create mode 100644 src/meta/es2016_nested_rest_destructuring_declarations.rs create mode 100644 src/meta/es2016_nested_rest_destructuring_parameters.rs create mode 100644 src/meta/es2016_proxy_enumerate_handler_removed.rs create mode 100644 src/meta/es2016_proxy_internal_calls_array_prototype_includes.rs create mode 100644 src/meta/es2016_strict_fn_w_non_strict_non_simple_params_is_error.rs create mode 100644 src/meta/es2017_arguments_caller_removed.rs create mode 100644 src/meta/es2017_assignments_allowed_in_for_in_head_in_non_strict_mode.rs create mode 100644 src/meta/es2017_async_functions.rs create mode 100644 src/meta/es2017_object_prototype_getter_setter_methods.rs create mode 100644 src/meta/es2017_object_static_methods.rs create mode 100644 src/meta/es2017_proxy_internal_calls_getter_setter_methods.rs create mode 100644 src/meta/es2017_reg_exp_u_flag_case_folding.rs create mode 100644 src/meta/es2017_shared_memory_and_atomics.rs create mode 100644 src/meta/es2017_string_padding.rs create mode 100644 src/meta/es2017_trailing_commas_in_function_syntax.rs create mode 100644 src/meta/es2018_asynchronous_iterators.rs create mode 100644 src/meta/es2018_object_rest_spread_properties.rs create mode 100644 src/meta/es2018_promise_prototype_finally.rs create mode 100644 src/meta/es2018_proxy_own_keys_handler_duplicate_keys_for_non_extensible_targets.rs create mode 100644 src/meta/es2018_reg_exp_lookbehind_assertions.rs create mode 100644 src/meta/es2018_reg_exp_named_capture_groups.rs create mode 100644 src/meta/es2018_reg_exp_unicode_property_escapes.rs create mode 100644 src/meta/es2018_s_dot_all_flag_for_regular_expressions.rs create mode 100644 src/meta/es2018_template_literal_revision.rs create mode 100644 src/meta/es2019_array_prototype_flat_flat_map.rs create mode 100644 src/meta/es2019_function_prototype_to_string_revision.rs create mode 100644 src/meta/es2019_json_superset.rs create mode 100644 src/meta/es2019_object_from_entries.rs create mode 100644 src/meta/es2019_optional_catch_binding.rs create mode 100644 src/meta/es2019_string_trimming.rs create mode 100644 src/meta/es2019_symbol_prototype_description.rs create mode 100644 src/meta/es2019_well_formed_json_stringify.rs create mode 100644 src/meta/es2020_big_int.rs create mode 100644 src/meta/es2020_global_this.rs create mode 100644 src/meta/es2020_nullish_coalescing_operator.rs create mode 100644 src/meta/es2020_optional_chaining_operator.rs create mode 100644 src/meta/es2020_promise_all_settled.rs create mode 100644 src/meta/es2020_string_prototype_match_all.rs create mode 100644 src/meta/es2021_logical_assignment.rs create mode 100644 src/meta/es2021_numeric_separators.rs create mode 100644 src/meta/es2021_promise_any.rs create mode 100644 src/meta/es2021_string_prototype_replace_all.rs create mode 100644 src/meta/es2021_weak_references.rs create mode 100644 src/meta/es2022_at_method_on_the_built_in_indexables.rs create mode 100644 src/meta/es2022_class_static_initialization_blocks.rs create mode 100644 src/meta/es2022_ergonomic_brand_checks_for_private_fields.rs create mode 100644 src/meta/es2022_error_cause_property.rs create mode 100644 src/meta/es2022_instance_class_fields.rs create mode 100644 src/meta/es2022_object_has_own.rs create mode 100644 src/meta/es2022_private_class_methods.rs create mode 100644 src/meta/es2022_reg_exp_match_indices_has_indices_d_flag.rs create mode 100644 src/meta/es2022_static_class_fields.rs create mode 100644 src/meta/es2023_array_find_from_last.rs create mode 100644 src/meta/es2023_change_array_by_copy.rs create mode 100644 src/meta/es2023_hashbang_grammar.rs create mode 100644 src/meta/es2024_array_buffer_prototype_transfer.rs create mode 100644 src/meta/es2024_array_grouping.rs create mode 100644 src/meta/es2024_promise_with_resolvers.rs create mode 100644 src/meta/es2024_reg_exp_v_flag.rs create mode 100644 src/meta/es2025_duplicate_named_capturing_groups.rs create mode 100644 src/meta/es2025_iterator_helpers.rs create mode 100644 src/meta/es2025_promise_try.rs create mode 100644 src/meta/es2025_reg_exp_pattern_modifiers.rs create mode 100644 src/meta/es2025_set_methods.rs create mode 100644 src/meta/es5_array_methods.rs create mode 100644 src/meta/es5_date_methods.rs create mode 100644 src/meta/es5_function_prototype_bind.rs create mode 100644 src/meta/es5_immutable_globals.rs create mode 100644 src/meta/es5_json.rs create mode 100644 src/meta/es5_miscellaneous.rs create mode 100644 src/meta/es5_number_methods.rs create mode 100644 src/meta/es5_object_array_literal_extensions.rs create mode 100644 src/meta/es5_object_static_methods.rs create mode 100644 src/meta/es5_strict_mode.rs create mode 100644 src/meta/es5_string_properties_and_methods.rs create mode 100644 src/meta/es6_array_is_subclassable.rs create mode 100644 src/meta/es6_array_prototype_methods.rs create mode 100644 src/meta/es6_array_static_methods.rs create mode 100644 src/meta/es6_arrow_functions.rs create mode 100644 src/meta/es6_block_level_function_declaration.rs create mode 100644 src/meta/es6_class.rs create mode 100644 src/meta/es6_const.rs create mode 100644 src/meta/es6_date_prototype_symbol_to_primitive.rs create mode 100644 src/meta/es6_default_function_parameters.rs create mode 100644 src/meta/es6_destructuring_assignment.rs create mode 100644 src/meta/es6_destructuring_declarations.rs create mode 100644 src/meta/es6_destructuring_parameters.rs create mode 100644 src/meta/es6_for_of_loops.rs create mode 100644 src/meta/es6_function_is_subclassable.rs create mode 100644 src/meta/es6_function_name_property.rs create mode 100644 src/meta/es6_generators.rs create mode 100644 src/meta/es6_html_style_comments.rs create mode 100644 src/meta/es6_let.rs create mode 100644 src/meta/es6_map.rs create mode 100644 src/meta/es6_math_methods.rs create mode 100644 src/meta/es6_miscellaneous.rs create mode 100644 src/meta/es6_miscellaneous_subclassables.rs create mode 100644 src/meta/es6_new_target.rs create mode 100644 src/meta/es6_non_strict_function_semantics.rs create mode 100644 src/meta/es6_number_properties.rs create mode 100644 src/meta/es6_object_literal_extensions.rs create mode 100644 src/meta/es6_object_prototype_proto.rs create mode 100644 src/meta/es6_object_static_methods.rs create mode 100644 src/meta/es6_object_static_methods_accept_primitives.rs create mode 100644 src/meta/es6_octal_and_binary_literals.rs create mode 100644 src/meta/es6_own_property_order.rs create mode 100644 src/meta/es6_promise.rs create mode 100644 src/meta/es6_promise_is_subclassable.rs create mode 100644 src/meta/es6_proper_tail_calls_tail_call_optimisation.rs create mode 100644 src/meta/es6_proto_in_object_literals.rs create mode 100644 src/meta/es6_prototype_of_bound_functions.rs create mode 100644 src/meta/es6_proxy.rs create mode 100644 src/meta/es6_proxy_internal_define_property_calls.rs create mode 100644 src/meta/es6_proxy_internal_delete_property_calls.rs create mode 100644 src/meta/es6_proxy_internal_get_calls.rs create mode 100644 src/meta/es6_proxy_internal_get_own_property_descriptor_calls.rs create mode 100644 src/meta/es6_proxy_internal_own_keys_calls.rs create mode 100644 src/meta/es6_proxy_internal_set_calls.rs create mode 100644 src/meta/es6_reflect.rs create mode 100644 src/meta/es6_reg_exp_is_subclassable.rs create mode 100644 src/meta/es6_reg_exp_prototype_compile.rs create mode 100644 src/meta/es6_reg_exp_prototype_properties.rs create mode 100644 src/meta/es6_reg_exp_syntax_extensions.rs create mode 100644 src/meta/es6_reg_exp_y_and_u_flags.rs create mode 100644 src/meta/es6_rest_parameters.rs create mode 100644 src/meta/es6_set.rs create mode 100644 src/meta/es6_spread_syntax_for_iterable_objects.rs create mode 100644 src/meta/es6_string_prototype_html_methods.rs create mode 100644 src/meta/es6_string_prototype_methods.rs create mode 100644 src/meta/es6_string_static_methods.rs create mode 100644 src/meta/es6_super.rs create mode 100644 src/meta/es6_symbol.rs create mode 100644 src/meta/es6_template_literals.rs create mode 100644 src/meta/es6_typed_arrays.rs create mode 100644 src/meta/es6_unicode_code_point_escapes.rs create mode 100644 src/meta/es6_updated_identifier_syntax.rs create mode 100644 src/meta/es6_weak_map.rs create mode 100644 src/meta/es6_weak_set.rs create mode 100644 src/meta/es6_well_known_symbols.rs create mode 100644 src/meta/esnext_array_is_template_object.rs create mode 100644 src/meta/esnext_async_iterator_helpers.rs create mode 100644 src/meta/esnext_class_and_property_decorators.rs create mode 100644 src/meta/esnext_generator_function_sent_meta_property.rs create mode 100644 src/meta/esnext_legacy_reg_exp_features_in_java_script.rs create mode 100644 src/meta/esnext_map_prototype_upsert.rs create mode 100644 src/meta/esnext_reg_exp_escaping.rs create mode 100644 src/meta/esnext_shadow_realm.rs create mode 100644 src/meta/esnext_throw_expressions.rs create mode 100644 src/meta/esnext_uint_array_to_from_base_and_hex.rs diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..02a1403 --- /dev/null +++ b/.typos.toml @@ -0,0 +1,9 @@ +# https://github.com/crate-ci/typos +# cargo install typos-cli +# typos + +[files] +extend-exclude = [ + "data.json", + "src/meta/*.rs", +] diff --git a/Cargo.lock b/Cargo.lock index 81138ba..9631942 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,7 @@ version = "0.0.0" dependencies = [ "convert_case", "prettyplease", + "proc-macro2", "project-root", "quote", "serde", @@ -92,6 +93,31 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +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.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "either" version = "1.13.0" @@ -511,6 +537,26 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[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 = "rustc-hash" version = "2.1.0" @@ -540,6 +586,7 @@ name = "scan262" version = "0.0.1" dependencies = [ "oxc", + "rayon", ] [[package]] @@ -574,7 +621,6 @@ version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap", "itoa", "memchr", "ryu", diff --git a/Cargo.toml b/Cargo.toml index e641797..e7fde50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,20 +50,12 @@ unnecessary_safety_comment = "warn" undocumented_unsafe_blocks = "warn" infinite_loop = "warn" -[workspace.dependencies] -convert_case = "0.6.0" -prettyplease = "0.2.20" -project-root = "0.2.2" -quote = "1.0" -serde = "1.0" -serde_json = "1.0" -syn = "2" - [lints] workspace = true [dependencies] oxc = { version = "0.41.0", features = ["semantic"] } +rayon = "1.10.0" [profile.release] # Configurations explicitly listed here for clarity. diff --git a/build.cjs b/build.cjs index 79b17f2..7615d61 100644 --- a/build.cjs +++ b/build.cjs @@ -1,9 +1,70 @@ -const es2016 = require('./compat-table/data-es2016plus.js'); +const es5 = require('./compat-table/data-es5.js').tests.map((t) => ({ + target: 'es5', + ...t, +})); +const es6 = require('./compat-table/data-es6.js').tests.map((t) => ({ + target: 'es6', + ...t, +})); +const es2016Plus = require('./compat-table/data-es2016plus.js').tests.map((t) => ({ + target: 'es2016', + ...t, +})); +const esnext = require('./compat-table/data-esnext.js').tests.map((t) => ({ + target: 'esnext', + ...t, +})); -const data = es2016.tests.map((test) => { +const data = es5.concat(es6, es2016Plus, esnext).map((test) => { + return mapper(test); +}); + +console.log(JSON.stringify(data, null, 2)); + +function mapper(test) { return { name: test.name, + target: test.target, + category: test.category, + significance: test.significance, + spec: test.spec, + mdn: test.mdn, + exec: test.exec && testScript(test.exec).trim(), + subtests: test.subtests && test.subtests.map(mapper), }; -}); +} -console.log(JSON.stringify(data, null, 2)); +function testScript(fn) { + function deindentFunc(fn) { + fn = fn + ''; + var indent = /(?:^|\n)([\t ]+)[^\n]+/.exec(fn); + if (indent) { + fn = fn.replace(new RegExp('\n' + indent[1], 'g'), '\n'); + } + return fn; + } + if (!fn) { + return ''; + } + if (typeof fn === 'function') { + // see if the code is encoded in a comment + var expr = (fn + '').match(/[^]*\/\*([^]*)\*\/\}$/); + // if there wasn't an expression, make the function statement into one + if (!expr) { + expr = deindentFunc(fn); + return expr; + } else { + expr = deindentFunc(expr[1]); + return expr; + } + } else { + // it's an array of objects like the following: + // { type: 'application/javascript;version=1.8', script: function () { ... } } + return fn.reduce(function(text, script) { + var expr = deindentFunc( + (script.script + '').replace(/^function \(\) \{\s*|\s*\}$/g, ''), + ); + return text + '\n' + expr; + }, ''); + } +} diff --git a/data.json b/data.json index 3380ca7..0e94592 100644 --- a/data.json +++ b/data.json @@ -1,206 +1,5772 @@ [ { - "name": "exponentiation (**) operator" + "name": "Object/array literal extensions", + "target": "es5", + "significance": "large", + "subtests": [ + { + "name": "Getter accessors", + "exec": "return ({ get x(){ return 1 } }).x === 1;" + }, + { + "name": "Setter accessors", + "exec": "var value = 0;\n({ set x(v){ value = v; } }).x = 1;\nreturn value === 1;" + }, + { + "name": "Trailing commas in object literals", + "exec": "return { a: true, }.a === true;" + }, + { + "name": "Trailing commas in array literals", + "exec": "return [1,].length === 1;" + }, + { + "name": "Reserved words as property names", + "exec": "return ({ if: 1 }).if === 1;" + } + ] }, { - "name": "Array.prototype.includes" + "name": "Object static methods", + "target": "es5", + "significance": "large", + "subtests": [ + { + "name": "Object.create", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create", + "exec": "function () {\nreturn typeof Object.create === 'function';\n }" + }, + { + "name": "Object.defineProperty", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty", + "exec": "function () {\nreturn typeof Object.defineProperty === 'function';\n }" + }, + { + "name": "Object.defineProperties", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties", + "exec": "function () {\nreturn typeof Object.defineProperties === 'function';\n }" + }, + { + "name": "Object.getPrototypeOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf", + "exec": "function () {\nreturn typeof Object.getPrototypeOf === 'function';\n }" + }, + { + "name": "Object.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys", + "exec": "function () {\nreturn typeof Object.keys === 'function';\n }" + }, + { + "name": "Object.seal", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal", + "exec": "function () {\nreturn typeof Object.seal === 'function';\n }" + }, + { + "name": "Object.freeze", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze", + "exec": "function () {\nreturn typeof Object.freeze === 'function';\n }" + }, + { + "name": "Object.preventExtensions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions", + "exec": "function () {\nreturn typeof Object.preventExtensions === 'function';\n }" + }, + { + "name": "Object.isSealed", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed", + "exec": "function () {\nreturn typeof Object.isSealed === 'function';\n }" + }, + { + "name": "Object.isFrozen", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen", + "exec": "function () {\nreturn typeof Object.isFrozen === 'function';\n }" + }, + { + "name": "Object.isExtensible", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible", + "exec": "function () {\nreturn typeof Object.isExtensible === 'function';\n }" + }, + { + "name": "Object.getOwnPropertyDescriptor", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor", + "exec": "function () {\nreturn typeof Object.getOwnPropertyDescriptor === 'function';\n }" + }, + { + "name": "Object.getOwnPropertyNames", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames", + "exec": "function () {\nreturn typeof Object.getOwnPropertyNames === 'function';\n }" + } + ] }, { - "name": "generator functions can't be used with \"new\"" + "name": "Array methods", + "target": "es5", + "significance": "large", + "subtests": [ + { + "name": "Array.isArray", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray", + "exec": "function () {\nreturn typeof Array.isArray === 'function';\n }" + }, + { + "name": "Array.prototype.indexOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf", + "exec": "function () {\nreturn typeof Array.prototype.indexOf === 'function';\n }" + }, + { + "name": "Array.prototype.lastIndexOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf", + "exec": "function () {\nreturn typeof Array.prototype.lastIndexOf === 'function';\n }" + }, + { + "name": "Array.prototype.every", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every", + "exec": "function () {\nreturn typeof Array.prototype.every === 'function';\n }" + }, + { + "name": "Array.prototype.some", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some", + "exec": "function () {\nreturn typeof Array.prototype.some === 'function';\n }" + }, + { + "name": "Array.prototype.forEach", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach", + "exec": "function () {\nreturn typeof Array.prototype.forEach === 'function';\n }" + }, + { + "name": "Array.prototype.map", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map", + "exec": "function () {\nreturn typeof Array.prototype.map === 'function';\n }" + }, + { + "name": "Array.prototype.filter", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter", + "exec": "function () {\nreturn typeof Array.prototype.filter === 'function';\n }" + }, + { + "name": "Array.prototype.reduce", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce", + "exec": "function () {\nreturn typeof Array.prototype.reduce === 'function';\n }" + }, + { + "name": "Array.prototype.reduceRight", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight", + "exec": "function () {\nreturn typeof Array.prototype.reduceRight === 'function';\n }" + }, + { + "name": "Array.prototype.sort: compareFn must be function or undefined", + "exec": "function () {\ntry {\n [1,2].sort(null);\n return false;\n} catch (enull) {}\ntry {\n [1,2].sort(true);\n return false;\n} catch (etrue) {}\ntry {\n [1,2].sort({});\n return false;\n} catch (eobj) {}\ntry {\n [1,2].sort([]);\n return false;\n} catch (earr) {}\ntry {\n [1,2].sort(/a/g);\n return false;\n} catch (eregex) {}\nreturn true;\n }" + }, + { + "name": "Array.prototype.sort: compareFn may be explicit undefined", + "exec": "function () {\ntry {\n var arr = [2, 1];\n return arr.sort(undefined) === arr && arr[0] === 1 && arr[1] === 2;\n} catch (e) {\n return false;\n}\n }" + }, + { + "name": "Array.prototype.unshift: [].unshift(0) returns the unshifted count", + "exec": "function () {\nreturn [].unshift(0) === 1;\n }" + } + ] }, { - "name": "generator throw() caught by inner generator" + "name": "String properties and methods", + "target": "es5", + "significance": "small", + "subtests": [ + { + "name": "Property access on strings", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Character_access", + "exec": "function () {\nreturn \"foobar\"[3] === \"b\";\n }" + }, + { + "name": "String.prototype.split", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split", + "exec": "function () {\n// all of these tests reflect bugs that es5-shim patches\nreturn typeof String.prototype.split === 'function'\n && ''.split().length === 1 && ''.split()[0] === ''\n && ''.split(undefined).length === 1 && ''.split(undefined)[0] === ''\n && 'ab'.split().length === 1 && 'ab'.split()[0] === 'ab'\n && 'ab'.split(undefined).length === 1 && 'ab'.split(undefined)[0] === 'ab'\n && '0'.split(undefined, 0).length === 0\n && 'ab'.split(/(?:ab)*/).length === 2\n && '.'.split(/(.?)(.?)/).length === 4\n && 'tesst'.split(/(s)*/)[1] !== 't'\n && 'test'.split(/(?:)/, -1).length === 4\n && ''.split(/.?/).length === 0\n && '.'.split(/()()/).length === 1;\n }" + }, + { + "name": "String.prototype.substr", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr", + "exec": "function () {\nreturn '0b'.substr(-1) === 'b';\n }" + }, + { + "name": "String.prototype.trim", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim", + "exec": "function () {\nreturn typeof String.prototype.trim === 'function';\n }" + } + ] }, { - "name": "strict fn w/ non-strict non-simple params is error" + "name": "Date methods", + "target": "es5", + "significance": "small", + "subtests": [ + { + "name": "Date.prototype.toISOString", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString", + "exec": "function () {\nreturn typeof Date.prototype.toISOString === 'function';\n }" + }, + { + "name": "Date.now", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now", + "exec": "function () {\nreturn typeof Date.now === 'function';\n }" + }, + { + "name": "Date.prototype.toJSON", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON", + "exec": "function () {\ntry {\n return Date.prototype.toJSON.call(new Date(NaN)) === null;\n} catch (e) {\n return false;\n}\n }" + } + ] }, { - "name": "nested rest destructuring, declarations" + "name": "Function.prototype.bind", + "target": "es5", + "significance": "medium", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind", + "exec": "function () {\nreturn typeof Function.prototype.bind === 'function';\n }" }, { - "name": "nested rest destructuring, parameters" + "name": "JSON", + "target": "es5", + "significance": "medium", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON", + "exec": "function () {\nreturn typeof JSON === 'object';\n }" }, { - "name": "Proxy, \"enumerate\" handler removed" + "name": "Immutable globals", + "target": "es5", + "significance": "small", + "subtests": [ + { + "name": "undefined", + "exec": "undefined = 12345;\nvar result = typeof undefined === 'undefined';\nundefined = void 0;\nreturn result;" + }, + { + "name": "NaN", + "exec": "NaN = false;\nvar result = typeof NaN === 'number';\nNaN = Math.sqrt(-1);\nreturn result;" + }, + { + "name": "Infinity", + "exec": "Infinity = false;\nvar result = typeof Infinity === 'number';\nInfinity = 1/0;\nreturn result;" + } + ] }, { - "name": "Proxy internal calls, Array.prototype.includes" + "name": "Number methods", + "target": "es5", + "significance": "small", + "subtests": [ + { + "name": "Number.prototype.toExponential rounds properly", + "exec": "function () {\nreturn (-6.9e-11).toExponential(4) === '-6.9000e-11' // Edge <= 17\n && (25).toExponential(0) === '3e+1' // FF <= 86\n && (1.255).toExponential(2) === '1.25e+0'; // IE <= 11 && Edge <= 14\n }" + }, + { + "name": "Number.prototype.toExponential throws on ±Infinity fractionDigits", + "exec": "function () {\ntry {\n (1).toExponential(Infinity);\n (1).toExponential(-Infinity);\n return false;\n} catch (e) {\n return true;\n}\n }" + }, + { + "name": "Number.prototype.toExponential does not throw on edge cases", + "exec": "function () {\ntry {\n NaN.toExponential(Infinity);\n Infinity.toExponential(Infinity);\n return true;\n} catch (e) {\n return false;\n}\n }" + } + ] }, { - "name": "Object static methods" + "name": "Miscellaneous", + "target": "es5", + "significance": "medium", + "subtests": [ + { + "name": "Function.prototype.apply permits array-likes", + "exec": "function () {\ntry {\n return (function(a,b) { return a === 1 && b === 2; }).apply({}, {0:1, 1:2, length:2});\n} catch (e) {\n return false;\n}\n }" + }, + { + "name": "parseInt ignores leading zeros", + "exec": "function () {\nreturn parseInt('010') === 10;\n }" + }, + { + "name": "Function \"prototype\" property is non-enumerable", + "exec": "return !Function().propertyIsEnumerable('prototype');" + }, + { + "name": "Arguments toStringTag is \"Arguments\"", + "exec": "return (function(){ return Object.prototype.toString.call(arguments) === '[object Arguments]'; }());" + }, + { + "name": "Zero-width chars in identifiers", + "exec": "var _\\u200c\\u200d = true;\nreturn _\\u200c\\u200d;" + }, + { + "name": "Unreserved words", + "exec": "var abstract, boolean, byte, char, double, final, float, goto, int, long,\n native, short, synchronized, transient, volatile;\nreturn true;" + }, + { + "name": "Enumerable properties can be shadowed by non-enumerables", + "exec": "var result = true;\nObject.prototype.length = 42;\nfor (var i in Function) {\n if (i === 'length') {\n result = false;\n }\n}\ndelete Object.prototype.length;\nreturn result;" + }, + { + "name": "Thrown functions have proper \"this\" values", + "exec": "try {\n throw function() { return !('a' in this); };\n}\ncatch(e) {\n var a = true;\n return e();\n}" + } + ] }, { - "name": "String padding" + "name": "Strict mode", + "target": "es5", + "significance": "large", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode", + "subtests": [ + { + "name": "reserved words", + "exec": "'use strict';\nvar words = 'implements,interface,let,package,private,protected,public,static,yield'.split(',');\nfor (var i = 0; i < 9; i+=1) {\n try { eval('var ' + words[i]); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\n}\nreturn true;" + }, + { + "name": "\"this\" is undefined in functions", + "exec": "'use strict';\nreturn this === void undefined && (function(){ return this === void undefined; }).call();" + }, + { + "name": "\"this\" is not coerced to object in primitive methods", + "exec": "'use strict';\nreturn (function(){ return typeof this === 'string' }).call('')\n && (function(){ return typeof this === 'number' }).call(1)\n && (function(){ return typeof this === 'boolean' }).call(true);" + }, + { + "name": "\"this\" is not coerced to object in primitive accessors", + "exec": "'use strict';\n\nfunction test(Class, instance) {\n Object.defineProperty(Class.prototype, 'test', {\n get: function () { passed = passed && this === instance; },\n set: function () { passed = passed && this === instance; },\n configurable: true\n });\n\n var passed = true;\n instance.test;\n instance.test = 42;\n return passed;\n}\n\nreturn test(String, '')\n && test(Number, 1)\n && test(Boolean, true);" + }, + { + "name": "legacy octal is a SyntaxError", + "exec": "'use strict';\ntry { eval('010'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('\"\\\\010\"'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\nreturn true;" + }, + { + "name": "assignment to unresolvable identifiers is a ReferenceError", + "exec": "'use strict';\ntry { eval('__i_dont_exist = 1'); } catch (err) { return err instanceof ReferenceError; }" + }, + { + "name": "assignment to eval or arguments is a SyntaxError", + "exec": "'use strict';\ntry { eval('eval = 1'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('arguments = 1'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('eval++'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('arguments++'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\nreturn true;" + }, + { + "name": "assignment to non-writable properties is a TypeError", + "exec": "'use strict';\ntry { Object.defineProperty({},\"x\",{ writable: false }).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\ntry { Object.preventExtensions({}).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\ntry { ({ get x(){ } }).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\ntry { (function f() { f = 123; })(); return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\nreturn true;" + }, + { + "name": "eval or arguments bindings is a SyntaxError", + "exec": "'use strict';\ntry { eval('var eval'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('var arguments'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('(function(eval){})'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('(function(arguments){})'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('try{}catch(eval){}'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\ntry { eval('try{}catch(arguments){}'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }\nreturn true;" + }, + { + "name": "arguments.caller removed or is a TypeError", + "exec": "'use strict';\nif ('caller' in arguments) {\n try { arguments.caller; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\n}\nreturn true;" + }, + { + "name": "arguments.callee is a TypeError", + "exec": "'use strict';\ntry { arguments.callee; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\nreturn true;" + }, + { + "name": "(function(){}).caller and (function(){}).arguments is a TypeError", + "exec": "'use strict';\ntry { (function(){}).caller; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\ntry { (function(){}).arguments; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }\nreturn true;" + }, + { + "name": "arguments is unmapped", + "exec": "'use strict';\nreturn (function(x){\n x = 2;\n return arguments[0] === 1;\n})(1) && (function(x){\n arguments[0] = 2;\n return x === 1;\n})(1);" + }, + { + "name": "eval() can't create bindings", + "exec": "'use strict';\ntry { eval('var __some_unique_variable;'); __some_unique_variable; } catch (err) { return err instanceof ReferenceError; }" + }, + { + "name": "deleting bindings is a SyntaxError", + "exec": "'use strict';\ntry { eval('var x; delete x;'); } catch (err) { return err instanceof SyntaxError; }" + }, + { + "name": "deleting non-configurable properties is a TypeError", + "exec": "'use strict';\ntry { delete Object.prototype; } catch (err) { return err instanceof TypeError; }" + }, + { + "name": "\"with\" is a SyntaxError", + "exec": "'use strict';\ntry { eval('with({}){}'); } catch (err) { return err instanceof SyntaxError; }" + }, + { + "name": "repeated parameter names is a SyntaxError", + "exec": "'use strict';\ntry { eval('function f(x, x) { }'); } catch (err) { return err instanceof SyntaxError; }" + }, + { + "name": "function expressions with matching name and argument are valid", + "exec": "var foo = function bar(bar) {'use strict'};\nreturn typeof foo === 'function';" + } + ] }, { - "name": "trailing commas in function syntax" + "name": "proper tail calls (tail call optimisation)", + "target": "es6", + "category": "optimisation", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-tail-position-calls", + "subtests": [ + { + "name": "direct recursion", + "exec": "\"use strict\";\nreturn (function f(n){\n if (n <= 0) {\n return \"foo\";\n }\n return f(n - 1);\n}(1e6)) === \"foo\";" + }, + { + "name": "mutual recursion", + "exec": "\"use strict\";\nfunction f(n){\n if (n <= 0) {\n return \"foo\";\n }\n return g(n - 1);\n}\nfunction g(n){\n if (n <= 0) {\n return \"bar\";\n }\n return f(n - 1);\n}\nreturn f(1e6) === \"foo\" && f(1e6+1) === \"bar\";" + } + ] }, { - "name": "async functions" + "name": "default function parameters", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters", + "subtests": [ + { + "name": "basic functionality", + "exec": "return (function (a = 1, b = 2) { return a === 3 && b === 2; }(3));" + }, + { + "name": "explicit undefined defers to the default", + "exec": "return (function (a = 1, b = 2) { return a === 1 && b === 3; }(undefined, 3));" + }, + { + "name": "defaults can refer to previous params", + "exec": "return (function (a, b = a) { return b === 5; }(5));" + }, + { + "name": "arguments object interaction", + "exec": "return (function (a = \"baz\", b = \"qux\", c = \"quux\") {\n a = \"corge\";\n // The arguments object is not mapped to the\n // parameters, even outside of strict mode.\n return arguments.length === 2\n && arguments[0] === \"foo\"\n && arguments[1] === \"bar\";\n}(\"foo\", \"bar\"));" + }, + { + "name": "temporal dead zone", + "exec": "return (function(x = 1) {\n try {\n eval(\"(function(a=a){}())\");\n return false;\n } catch(e) {}\n try {\n eval(\"(function(a=b,b){}())\");\n return false;\n } catch(e) {}\n return true;\n}());" + }, + { + "name": "separate scope", + "exec": "return (function(a=function(){\n return typeof b === 'undefined';\n}){\n var b = 1;\n return a();\n}());" + }, + { + "name": "new Function() support", + "exec": "return new Function(\"a = 1\", \"b = 2\",\n \"return a === 3 && b === 2;\"\n)(3);" + } + ] }, { - "name": "shared memory and atomics" + "name": "rest parameters", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters", + "subtests": [ + { + "name": "basic functionality", + "exec": "return (function (foo, ...args) {\n return args instanceof Array && args + \"\" === \"bar,baz\";\n}(\"foo\", \"bar\", \"baz\"));" + }, + { + "name": "function 'length' property", + "exec": "return function(a, ...b){}.length === 1 && function(...c){}.length === 0;" + }, + { + "name": "arguments object interaction", + "exec": "return (function (foo, ...args) {\n foo = \"qux\";\n // The arguments object is not mapped to the\n // parameters, even outside of strict mode.\n return arguments.length === 3\n && arguments[0] === \"foo\"\n && arguments[1] === \"bar\"\n && arguments[2] === \"baz\";\n}(\"foo\", \"bar\", \"baz\"));" + }, + { + "name": "can't be used in setters", + "exec": "return (function (...args) {\n try {\n eval(\"({set e(...args){}})\");\n } catch(e) {\n return true;\n }\n}());" + }, + { + "name": "new Function() support", + "exec": "return new Function(\"a\", \"...b\",\n \"return b instanceof Array && a+b === 'foobar,baz';\"\n)('foo','bar','baz');" + } + ] }, { - "name": "RegExp \"u\" flag, case folding" + "name": "spread syntax for iterable objects", + "target": "es6", + "category": "syntax", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-argument-lists-runtime-semantics-argumentlistevaluation", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator", + "subtests": [ + { + "name": "with arrays, in function calls", + "exec": "return Math.max(...[1, 2, 3]) === 3" + }, + { + "name": "with arrays, in array literals", + "exec": "return [...[1, 2, 3]][2] === 3;" + }, + { + "name": "with sparse arrays, in function calls", + "exec": "var a = Array(...[,,]);\nreturn \"0\" in a && \"1\" in a && '' + a[0] + a[1] === \"undefinedundefined\";" + }, + { + "name": "with sparse arrays, in array literals", + "exec": "var a = [...[,,]];\nreturn \"0\" in a && \"1\" in a && '' + a[0] + a[1] === \"undefinedundefined\";" + }, + { + "name": "with strings, in function calls", + "exec": "return Math.max(...\"1234\") === 4;" + }, + { + "name": "with strings, in array literals", + "exec": "return [\"a\", ...\"bcd\", \"e\"][3] === \"d\";" + }, + { + "name": "with astral plane strings, in function calls", + "exec": "return Array(...\"𠮷𠮶\")[0] === \"𠮷\";" + }, + { + "name": "with astral plane strings, in array literals", + "exec": "return [...\"𠮷𠮶\"][0] === \"𠮷\";" + }, + { + "name": "with generator instances, in calls", + "exec": "var iterable = (function*(){ yield 1; yield 2; yield 3; }());\nreturn Math.max(...iterable) === 3;" + }, + { + "name": "with generator instances, in arrays", + "exec": "var iterable = (function*(){ yield \"b\"; yield \"c\"; yield \"d\"; }());\nreturn [\"a\", ...iterable, \"e\"][3] === \"d\";" + }, + { + "name": "with generic iterables, in calls", + "exec": "var iterable = global.__createIterableObject([1, 2, 3]);\nreturn Math.max(...iterable) === 3;" + }, + { + "name": "with generic iterables, in arrays", + "exec": "var iterable = global.__createIterableObject([\"b\", \"c\", \"d\"]);\nreturn [\"a\", ...iterable, \"e\"][3] === \"d\";" + }, + { + "name": "with instances of iterables, in calls", + "exec": "var iterable = global.__createIterableObject([1, 2, 3]);\nreturn Math.max(...Object.create(iterable)) === 3;" + }, + { + "name": "with instances of iterables, in arrays", + "exec": "var iterable = global.__createIterableObject([\"b\", \"c\", \"d\"]);\nreturn [\"a\", ...Object.create(iterable), \"e\"][3] === \"d\";" + }, + { + "name": "spreading non-iterables is a runtime error", + "exec": "try {\n Math.max(...2);\n} catch(e) {\n return Math.max(...[1, 2, 3]) === 3;\n}" + } + ] }, { - "name": "arguments.caller removed" + "name": "object literal extensions", + "target": "es6", + "category": "syntax", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-object-initialiser", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015", + "subtests": [ + { + "name": "computed properties", + "exec": "var x = 'y';\nreturn ({ [x]: 1 }).y === 1;" + }, + { + "name": "shorthand properties", + "exec": "var a = 7, b = 8, c = {a,b};\nreturn c.a === 7 && c.b === 8;" + }, + { + "name": "shorthand methods", + "exec": "return ({ y() { return 2; } }).y() === 2;" + }, + { + "name": "string-keyed shorthand methods", + "exec": "return ({ \"foo bar\"() { return 4; } })[\"foo bar\"]() === 4;" + }, + { + "name": "computed shorthand methods", + "exec": "var x = 'y';\nreturn ({ [x](){ return 1 } }).y() === 1;" + }, + { + "name": "computed accessors", + "exec": "var x = 'y',\n valueSet,\n obj = {\n get [x] () { return 1 },\n set [x] (value) { valueSet = value }\n };\nobj.y = 'foo';\nreturn obj.y === 1 && valueSet === 'foo';" + } + ] }, { - "name": "Object.prototype getter/setter methods" + "name": "for..of loops", + "target": "es6", + "category": "syntax", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of", + "subtests": [ + { + "name": "with arrays", + "exec": "var arr = [5];\nfor (var item of arr)\n return item === 5;" + }, + { + "name": "with sparse arrays", + "exec": "var arr = [,,];\nvar count = 0;\nfor (var item of arr)\n count += (item === void undefined);\nreturn count === 2;" + }, + { + "name": "with strings", + "exec": "var str = \"\";\nfor (var item of \"foo\")\n str += item;\nreturn str === \"foo\";" + }, + { + "name": "with astral plane strings", + "exec": "var str = \"\";\nfor (var item of \"𠮷𠮶\")\n str += item + \" \";\nreturn str === \"𠮷 𠮶 \";" + }, + { + "name": "with generator instances", + "exec": "var result = \"\";\nvar iterable = (function*(){ yield 1; yield 2; yield 3; }());\nfor (var item of iterable) {\n result += item;\n}\nreturn result === \"123\";" + }, + { + "name": "with generic iterables", + "exec": "var result = \"\";\nvar iterable = global.__createIterableObject([1, 2, 3]);\nfor (var item of iterable) {\n result += item;\n}\nreturn result === \"123\";" + }, + { + "name": "with instances of generic iterables", + "exec": "var result = \"\";\nvar iterable = global.__createIterableObject([1, 2, 3]);\nfor (var item of Object.create(iterable)) {\n result += item;\n}\nreturn result === \"123\";" + }, + { + "name": "iterator closing, break", + "exec": "var closed = false;\nvar iter = __createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\nfor (var it of iter) break;\nreturn closed;" + }, + { + "name": "iterator closing, throw", + "exec": "var closed = false;\nvar iter = __createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\ntry {\n for (var it of iter) throw 0;\n} catch(e){}\nreturn closed;" + } + ] }, { - "name": "Proxy internal calls, getter/setter methods" + "name": "octal and binary literals", + "target": "es6", + "category": "syntax", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-literals-numeric-literals", + "subtests": [ + { + "name": "octal literals", + "exec": "return 0o10 === 8 && 0O10 === 8;" + }, + { + "name": "binary literals", + "exec": "return 0b10 === 2 && 0B10 === 2;" + }, + { + "name": "octal supported by Number()", + "exec": "return Number('0o1') === 1;" + }, + { + "name": "binary supported by Number()", + "exec": "return Number('0b1') === 1;" + } + ] }, { - "name": "assignments allowed in for-in head in non-strict mode" + "name": "template literals", + "target": "es6", + "category": "syntax", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-template-literals", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals", + "subtests": [ + { + "name": "basic functionality", + "exec": "var a = \"ba\", b = \"QUX\";\nreturn `foo bar\n${a + \"z\"} ${b.toLowerCase()}` === \"foo bar\\nbaz qux\";" + }, + { + "name": "toString conversion", + "exec": "var a = {\n toString: function() { return \"foo\"; },\n valueOf: function() { return \"bar\"; }\n};\nreturn `${a}` === \"foo\";" + }, + { + "name": "tagged template literals", + "exec": "var called = false;\nfunction fn(parts, a, b) {\n called = true;\n return parts instanceof Array &&\n parts[0] === \"foo\" &&\n parts[1] === \"bar\\n\" &&\n parts.raw[0] === \"foo\" &&\n parts.raw[1] === \"bar\\\\n\" &&\n a === 123 &&\n b === 456;\n}\nreturn fn `foo${123}bar\\n${456}` && called;" + }, + { + "name": "passed array is frozen", + "exec": "return (function(parts) {\n return Object.isFrozen(parts) && Object.isFrozen(parts.raw);\n}) `foo${0}bar${0}baz`;" + }, + { + "name": "line break normalisation", + "exec": "var cr = eval(\"`x\" + String.fromCharCode(13) + \"y`\");\nvar lf = eval(\"`x\" + String.fromCharCode(10) + \"y`\");\nvar crlf = eval(\"`x\" + String.fromCharCode(13,10) + \"y`\");\n\nreturn cr.length === 3 && lf.length === 3 && crlf.length === 3\n && cr[1] === lf[1] && lf[1] === crlf[1] && crlf[1] === '\\n';" + }, + { + "name": "TemplateStrings call site caching", + "exec": "// TemplateStrings caching was changed from per-contents to\n// per-call-site.\n// https://github.com/tc39/ecma262/pull/890\nfunction strings(array) {\n return array;\n}\nfunction getStrings() {\n return strings`foo`;\n}\nvar original = getStrings();\nvar other = strings`foo`;\nreturn original === getStrings() && original !== other;" + }, + { + "name": "TemplateStrings permanent caching", + "exec": "function strings(array) {\n return array;\n}\nfunction getStrings() {\n return strings`foo`;\n}\nvar original = getStrings();\nvar newed = new getStrings();\nreturn original === getStrings() && original === newed;" + } + ] }, { - "name": "object rest/spread properties" + "name": "RegExp \"y\" and \"u\" flags", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-get-regexp.prototype.sticky", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Parameters", + "subtests": [ + { + "name": "\"y\" flag", + "exec": "var re = new RegExp('\\\\w', 'y');\nre.exec('xy');\nreturn (re.exec('xy')[0] === 'y');" + }, + { + "name": "\"y\" flag, lastIndex", + "exec": "var re = new RegExp('yy', 'y');\nre.lastIndex = 3;\nvar result = re.exec('xxxyyxx')[0];\nreturn result === 'yy' && re.lastIndex === 5;" + }, + { + "name": "\"u\" flag", + "exec": "return \"𠮷\".match(/^.$/u)[0].length === 2;" + }, + { + "name": "\"u\" flag, non-BMP Unicode characters", + "exec": "return \"𠮷x\".match(/^.x$/u)[0].length === 3;" + }, + { + "name": "\"u\" flag, Unicode code point escapes", + "exec": "return \"𝌆\".match(/\\u{1d306}/u)[0].length === 2;" + }, + { + "name": "\"u\" flag, case folding", + "exec": "return \"ſ\".match(/S/iu) && \"S\".match(/ſ/iu);" + } + ] }, { - "name": "Promise.prototype.finally" + "name": "destructuring, declarations", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment", + "subtests": [ + { + "name": "with arrays", + "exec": "var [a, , [b], c] = [5, null, [6]];\nreturn a === 5 && b === 6 && c === void undefined;" + }, + { + "name": "with sparse arrays", + "exec": "var [a, , b] = [,,,];\nreturn a === void undefined && b === void undefined;" + }, + { + "name": "with strings", + "exec": "var [a, b, c] = \"ab\";\nreturn a === \"a\" && b === \"b\" && c === void undefined;" + }, + { + "name": "with astral plane strings", + "exec": "var [c] = \"𠮷𠮶\";\nreturn c === \"𠮷\";" + }, + { + "name": "with generator instances", + "exec": "var [a, b, c] = (function*(){ yield 1; yield 2; }());\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "with generic iterables", + "exec": "var [a, b, c] = global.__createIterableObject([1, 2]);\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "with instances of generic iterables", + "exec": "var [a, b, c] = Object.create(global.__createIterableObject([1, 2]));\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\nvar [a, b] = iter;\nreturn closed;" + }, + { + "name": "trailing commas in iterable patterns", + "exec": "var [a,] = [1];\nreturn a === 1;" + }, + { + "name": "with objects", + "exec": "var {c, x:d, e} = {c:7, x:8};\nreturn c === 7 && d === 8 && e === void undefined;" + }, + { + "name": "object destructuring with primitives", + "exec": "var {toFixed} = 2;\nvar {slice} = '';\nreturn toFixed === Number.prototype.toFixed\n && slice === String.prototype.slice;" + }, + { + "name": "trailing commas in object patterns", + "exec": "var {a,} = {a:1};\nreturn a === 1;" + }, + { + "name": "throws on null and undefined", + "exec": "try {\n var {a} = null;\n return false;\n} catch(e) {\n if (!(e instanceof TypeError))\n return false;\n}\ntry {\n var {b} = void undefined;\n return false;\n} catch(e) {\n if (!(e instanceof TypeError))\n return false;\n}\nreturn true;" + }, + { + "name": "computed properties", + "exec": "var qux = \"corge\";\nvar { [qux]: grault } = { corge: \"garply\" };\nreturn grault === \"garply\";" + }, + { + "name": "multiples in a single var statement", + "exec": "var [a,b] = [5,6], {c,d} = {c:7,d:8};\nreturn a === 5 && b === 6 && c === 7 && d === 8;" + }, + { + "name": "nested", + "exec": "var [e, {x:f, g}] = [9, {x:10}];\nvar {h, x:[i]} = {h:11, x:[12]};\nreturn e === 9 && f === 10 && g === void undefined\n && h === 11 && i === 12;" + }, + { + "name": "in for-in loop heads", + "exec": "for(var [i, j, k] in { qux: 1 }) {\n return i === \"q\" && j === \"u\" && k === \"x\";\n}" + }, + { + "name": "in for-of loop heads", + "exec": "for(var [i, j, k] of [[1,2,3]]) {\n return i === 1 && j === 2 && k === 3;\n}" + }, + { + "name": "in catch heads", + "exec": "try {\n throw [1,2];\n} catch([i,j]) {\n try {\n throw { k: 3, l: 4 };\n } catch({k, l}) {\n return i === 1 && j === 2 && k === 3 && l === 4;\n }\n}" + }, + { + "name": "rest", + "exec": "var [a, ...b] = [3, 4, 5];\nvar [c, ...d] = [6];\nreturn a === 3 && b instanceof Array && (b + \"\") === \"4,5\" &&\n c === 6 && d instanceof Array && d.length === 0;" + }, + { + "name": "defaults", + "exec": "var {a = 1, b = 0, z:c = 3} = {b:2, z:undefined};\nvar [d = 0, e = 5, f = 6] = [4,,undefined];\nreturn a === 1 && b === 2 && c === 3\n && d === 4 && e === 5 && f === 6;" + }, + { + "name": "defaults, let temporal dead zone", + "exec": "var {a, b = 2} = {a:1};\ntry {\n eval(\"let {c = c} = {};\");\n return false;\n} catch(e){}\ntry {\n eval(\"let {c = d, d} = {d:1};\");\n return false;\n} catch(e){}\nreturn a === 1 && b === 2;" + } + ] }, { - "name": "s (dotAll) flag for regular expressions" + "name": "destructuring, assignment", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment", + "subtests": [ + { + "name": "with arrays", + "exec": "var a,b,c;\n[a, , [b], c] = [5, null, [6]];\nreturn a === 5 && b === 6 && c === void undefined;" + }, + { + "name": "with sparse arrays", + "exec": "var a, b;\n[a, , b] = [,,,];\nreturn a === void undefined && b === void undefined;" + }, + { + "name": "with strings", + "exec": "var a,b,c;\n[a, b, c] = \"ab\";\nreturn a === \"a\" && b === \"b\" && c === void undefined;" + }, + { + "name": "with astral plane strings", + "exec": "var c;\n[c] = \"𠮷𠮶\";\nreturn c === \"𠮷\";" + }, + { + "name": "with generator instances", + "exec": "var a,b,c;\n[a, b, c] = (function*(){ yield 1; yield 2; }());\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "with generic iterables", + "exec": "var a,b,c;\n[a, b, c] = global.__createIterableObject([1, 2]);\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "with instances of generic iterables", + "exec": "var a,b,c;\n[a, b, c] = Object.create(global.__createIterableObject([1, 2]));\nreturn a === 1 && b === 2 && c === void undefined;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\nvar a,b;\n[a, b] = iter;\nreturn closed;" + }, + { + "name": "iterable destructuring expression", + "exec": "var a, b, iterable = [1,2];\nreturn ([a, b] = iterable) === iterable;" + }, + { + "name": "chained iterable destructuring", + "exec": "var a,b,c,d;\n[a,b] = [c,d] = [1,2];\nreturn a === 1 && b === 2 && c === 1 && d === 2;" + }, + { + "name": "trailing commas in iterable patterns", + "exec": "var a;\n[a,] = [1];\nreturn a === 1;" + }, + { + "name": "with objects", + "exec": "var c,d,e;\n({c, x:d, e} = {c:7, x:8});\nreturn c === 7 && d === 8 && e === void undefined;" + }, + { + "name": "object destructuring with primitives", + "exec": "var toFixed, slice;\n({toFixed} = 2);\n({slice} = '');\nreturn toFixed === Number.prototype.toFixed\n && slice === String.prototype.slice;" + }, + { + "name": "trailing commas in object patterns", + "exec": "var a;\n({a,} = {a:1});\nreturn a === 1;" + }, + { + "name": "object destructuring expression", + "exec": "var a, b, obj = { a:1, b:2 };\nreturn ({a,b} = obj) === obj;" + }, + { + "name": "parenthesised left-hand-side is a syntax error", + "exec": "var a, b;\n({a,b} = {a:1,b:2});\ntry {\n eval(\"({a,b}) = {a:3,b:4};\");\n}\ncatch(e) {\n return a === 1 && b === 2;\n}" + }, + { + "name": "chained object destructuring", + "exec": "var a,b,c,d;\n({a,b} = {c,d} = {a:1,b:2,c:3,d:4});\nreturn a === 1 && b === 2 && c === 3 && d === 4;" + }, + { + "name": "throws on null and undefined", + "exec": "var a,b;\ntry {\n ({a} = null);\n return false;\n} catch(e) {\n if (!(e instanceof TypeError))\n return false;\n}\ntry {\n ({b} = void undefined);\n return false;\n} catch(e) {\n if (!(e instanceof TypeError))\n return false;\n}\nreturn true;" + }, + { + "name": "computed properties", + "exec": "var grault, qux = \"corge\";\n({ [qux]: grault } = { corge: \"garply\" });\nreturn grault === \"garply\";" + }, + { + "name": "nested", + "exec": "var e,f,g,h,i;\n[e, {x:f, g}] = [9, {x:10}];\n({h, x:[i]} = {h:11, x:[12]});\nreturn e === 9 && f === 10 && g === void undefined\n && h === 11 && i === 12;" + }, + { + "name": "rest", + "exec": "var a,b,c,d;\n[a, ...b] = [3, 4, 5];\n[c, ...d] = [6];\nreturn a === 3 && b instanceof Array && (b + \"\") === \"4,5\" &&\n c === 6 && d instanceof Array && d.length === 0;" + }, + { + "name": "nested rest", + "exec": "var a = [1, 2, 3], first, last;\n[first, ...[a[2], last]] = a;\nreturn first === 1 && last === 3 && (a + \"\") === \"1,2,2\";" + }, + { + "name": "empty patterns", + "exec": "[] = [1,2];\n({} = {a:1,b:2});\nreturn true;" + }, + { + "name": "defaults", + "exec": "var a,b,c,d,e,f;\n({a = 1, b = 0, z:c = 3} = {b:2, z:undefined});\n[d = 0, e = 5, f = 6] = [4,,undefined];\nreturn a === 1 && b === 2 && c === 3\n && d === 4 && e === 5 && f === 6;" + } + ] }, { - "name": "RegExp named capture groups" + "name": "destructuring, parameters", + "target": "es6", + "category": "syntax", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment", + "subtests": [ + { + "name": "with arrays", + "exec": "return function([a, , [b], c]) {\n return a === 5 && b === 6 && c === void undefined;\n}([5, null, [6]]);" + }, + { + "name": "with sparse arrays", + "exec": "return function([a, , b]) {\n return a === void undefined && b === void undefined;\n}([,,,]);" + }, + { + "name": "with strings", + "exec": "return function([a, b, c]) {\n return a === \"a\" && b === \"b\" && c === void undefined;\n}(\"ab\");" + }, + { + "name": "with astral plane strings", + "exec": "return function([c]) {\n return c === \"𠮷\";\n}(\"𠮷𠮶\");" + }, + { + "name": "with generator instances", + "exec": "return function([a, b, c]) {\n return a === 1 && b === 2 && c === void undefined;\n}(function*(){ yield 1; yield 2; }());" + }, + { + "name": "with generic iterables", + "exec": "return function([a, b, c]) {\n return a === 1 && b === 2 && c === void undefined;\n}(global.__createIterableObject([1, 2]));" + }, + { + "name": "with instances of generic iterables", + "exec": "return function([a, b, c]) {\n return a === 1 && b === 2 && c === void undefined;\n}(Object.create(global.__createIterableObject([1, 2])));" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\n(function([a,b]) {}(iter));\nreturn closed;" + }, + { + "name": "trailing commas in iterable patterns", + "exec": "return function([a,]) {\n return a === 1;\n}([1]);" + }, + { + "name": "with objects", + "exec": "return function({c, x:d, e}) {\n return c === 7 && d === 8 && e === void undefined;\n}({c:7, x:8});" + }, + { + "name": "object destructuring with primitives", + "exec": "return function({toFixed}, {slice}) {\n return toFixed === Number.prototype.toFixed\n && slice === String.prototype.slice;\n}(2,'');" + }, + { + "name": "trailing commas in object patterns", + "exec": "return function({a,}) {\n return a === 1;\n}({a:1});" + }, + { + "name": "throws on null and undefined", + "exec": "try {\n (function({a}){}(null));\n return false;\n} catch(e) {}\ntry {\n (function({b}){}(undefined));\n return false;\n} catch(e) {}\nreturn true;" + }, + { + "name": "computed properties", + "exec": "var qux = \"corge\";\nreturn function({ [qux]: grault }) {\n return grault === \"garply\";\n}({ corge: \"garply\" });" + }, + { + "name": "nested", + "exec": "return function([e, {x:f, g}], {h, x:[i]}) {\n return e === 9 && f === 10 && g === void undefined\n && h === 11 && i === 12;\n}([9, {x:10}],{h:11, x:[12]});" + }, + { + "name": "'arguments' interaction", + "exec": "return (function({a, x:b, y:e}, [c, d]) {\n return arguments[0].a === 1 && arguments[0].x === 2\n && !(\"y\" in arguments[0]) && arguments[1] + '' === \"3,4\";\n}({a:1, x:2}, [3, 4]));" + }, + { + "name": "new Function() support", + "exec": "return new Function(\"{a, x:b, y:e}\",\"[c, d]\",\n \"return a === 1 && b === 2 && c === 3 && \"\n + \"d === 4 && e === void undefined;\"\n)({a:1, x:2}, [3, 4]);" + }, + { + "name": "in parameters, function 'length' property", + "exec": "return function({a, b}, [c, d]){}.length === 2;" + }, + { + "name": "rest", + "exec": "return function([a, ...b], [c, ...d]) {\n return a === 3 && b instanceof Array && (b + \"\") === \"4,5\" &&\n c === 6 && d instanceof Array && d.length === 0;\n}([3, 4, 5], [6]);" + }, + { + "name": "empty patterns", + "exec": "return function ([],{}){\n return arguments[0] + '' === \"3,4\" && arguments[1].x === \"foo\";\n}([3,4],{x:\"foo\"});" + }, + { + "name": "defaults", + "exec": "return (function({a = 1, b = 0, c = 3, x:d = 0, y:e = 5},\n [f = 6, g = 0, h = 8]) {\n return a === 1 && b === 2 && c === 3 && d === 4 &&\n e === 5 && f === 6 && g === 7 && h === 8;\n}({b:2, c:undefined, x:4},[, 7, undefined]));" + }, + { + "name": "defaults, separate scope", + "exec": "return (function({a=function(){\n return typeof b === 'undefined';\n}}){\n var b = 1;\n return a();\n}({}));" + }, + { + "name": "defaults, new Function() support", + "exec": "return new Function(\"{a = 1, b = 0, c = 3, x:d = 0, y:e = 5}\",\n \"return a === 1 && b === 2 && c === 3 && d === 4 && e === 5;\"\n)({b:2, c:undefined, x:4});" + }, + { + "name": "aliased defaults, arrow function", + "exec": "return ((a, {b: x = 0, c: y = 3}) => {\n return a === 1 && x === 2 && y === 3;\n})(1, {b: 2});" + }, + { + "name": "shorthand defaults, arrow function", + "exec": "return ((a, {b = 0, c = 3}) => {\n return a === 1 && b === 2 && c === 3;\n})(1, {b: 2});" + }, + { + "name": "duplicate identifier", + "exec": "try {\n eval('var d = function d([d]) { return d };');\n if (d([true]) !== true) return false;\n} catch (e) {\n return !(e instanceof SyntaxError);\n}\n\ntry {\n eval('var f = function f([id, id]) { return id }');\n return false;\n} catch (e) {\n return e instanceof SyntaxError;\n}" + } + ] }, { - "name": "RegExp Lookbehind Assertions" + "name": "Unicode code point escapes", + "target": "es6", + "category": "syntax", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-literals-string-literals", + "subtests": [ + { + "name": "in strings", + "exec": "return '\\u{1d306}' === '\\ud834\\udf06';" + }, + { + "name": "in identifiers", + "exec": "var \\u{102C0} = 2;\nreturn \\u{102C0} === 2;" + }, + { + "name": "in property key definitions", + "exec": "var o = { \\u{102C0} : 2 };\nreturn o['\\ud800\\udec0'] === 2;" + }, + { + "name": "in property key accesses", + "exec": "var o = { '\\ud800\\udec0' : 2 };\nreturn o.\\u{102C0} === 2;" + } + ] }, { - "name": "RegExp Unicode Property Escapes" + "name": "new.target", + "target": "es6", + "category": "syntax", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-built-in-function-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target", + "subtests": [ + { + "name": "in constructors", + "exec": "var passed = false;\nnew function f() {\n passed = (new.target === f);\n}();\n(function() {\n passed &= (new.target === void undefined);\n}());\nreturn passed;" + }, + { + "name": "assignment is an early error", + "exec": "var passed = false;\nnew function f() {\n passed = (new.target === f);\n}();\n\ntry {\n Function(\"new.target = function(){};\");\n} catch(e) {\n return passed;\n}" + } + ] }, { - "name": "Asynchronous Iterators" + "name": "const", + "target": "es6", + "category": "bindings", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const", + "subtests": [ + { + "name": "basic support", + "exec": "const foo = 123;\nreturn (foo === 123);" + }, + { + "name": "is block-scoped", + "exec": "const bar = 123;\n{ const bar = 456; }\nreturn bar === 123;" + }, + { + "name": "scope shadow resolution", + "exec": "try {\n { const bar = 456; }\n const bar = 123;\n return bar === 123;\n} catch(e) {\n return false;\n}" + }, + { + "name": "cannot be in statements", + "exec": "const bar = 1;\ntry {\n Function(\"if(true) const baz = 1;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "redefining a const is an error", + "exec": "const baz = 1;\ntry {\n Function(\"const foo = 1; foo = 2;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "for loop statement scope", + "exec": "const baz = 1;\nfor(const baz = 0; false;) {}\nreturn baz === 1;" + }, + { + "name": "for-in loop iteration scope", + "exec": "var scopes = [];\nfor(const i in { a:1, b:1 }) {\n scopes.push(function(){ return i; });\n}\nreturn (scopes[0]() === \"a\" && scopes[1]() === \"b\");" + }, + { + "name": "for-of loop iteration scope", + "exec": "var scopes = [];\nfor(const i of ['a','b']) {\n scopes.push(function(){ return i; });\n}\nreturn (scopes[0]() === \"a\" && scopes[1]() === \"b\");" + }, + { + "name": "temporal dead zone", + "exec": "var passed = (function(){ try { qux; } catch(e) { return true; }}());\nfunction fn() { passed &= qux === 456; }\nconst qux = 456;\nfn();\nreturn passed;" + }, + { + "name": "basic support (strict mode)", + "exec": "\"use strict\";\nconst foo = 123;\nreturn (foo === 123);" + }, + { + "name": "is block-scoped (strict mode)", + "exec": "'use strict';\nconst bar = 123;\n{ const bar = 456; }\nreturn bar === 123;" + }, + { + "name": "scope shadow resolution (strict mode)", + "exec": "'use strict';\ntry {\n { const bar = 456; }\n const bar = 123;\n return bar === 123;\n} catch(e) {\n return false;\n}" + }, + { + "name": "cannot be in statements (strict mode)", + "exec": "'use strict';\nconst bar = 1;\ntry {\n Function(\"'use strict'; if(true) const baz = 1;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "redefining a const (strict mode)", + "exec": "'use strict';\nconst baz = 1;\ntry {\n Function(\"'use strict'; const foo = 1; foo = 2;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "for loop statement scope (strict mode)", + "exec": "'use strict';\nconst baz = 1;\nfor(const baz = 0; false;) {}\nreturn baz === 1;" + }, + { + "name": "for-in loop iteration scope (strict mode)", + "exec": "'use strict';\nvar scopes = [];\nfor(const i in { a:1, b:1 }) {\n scopes.push(function(){ return i; });\n}\nreturn (scopes[0]() === \"a\" && scopes[1]() === \"b\");" + }, + { + "name": "for-of loop iteration scope (strict mode)", + "exec": "'use strict';\nvar scopes = [];\nfor(const i of ['a','b']) {\n scopes.push(function(){ return i; });\n}\nreturn (scopes[0]() === \"a\" && scopes[1]() === \"b\");" + }, + { + "name": "temporal dead zone (strict mode)", + "exec": "'use strict';\nvar passed = (function(){ try { qux; } catch(e) { return true; }}());\nfunction fn() { passed &= qux === 456; }\nconst qux = 456;\nfn();\nreturn passed;" + } + ] }, { - "name": "Proxy \"ownKeys\" handler, duplicate keys for non-extensible targets" + "name": "let", + "target": "es6", + "category": "bindings", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let", + "subtests": [ + { + "name": "basic support", + "exec": "let foo = 123;\nreturn (foo === 123);" + }, + { + "name": "is block-scoped", + "exec": "let bar = 123;\n{ let bar = 456; }\nreturn bar === 123;" + }, + { + "name": "scope shadow resolution", + "exec": "try {\n { let bar = 456; }\n let bar = 123;\n return bar === 123;\n} catch(e) {\n return false;\n}" + }, + { + "name": "cannot be in statements", + "exec": "let bar = 1;\ntry {\n Function(\"if(true) let baz = 1;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "for loop statement scope", + "exec": "let baz = 1;\nfor(let baz = 0; false;) {}\nreturn baz === 1;" + }, + { + "name": "temporal dead zone", + "exec": "var passed = (function(){ try { qux; } catch(e) { return true; }}());\nfunction fn() { passed &= qux === 456; }\nlet qux = 456;\nfn();\nreturn passed;" + }, + { + "name": "for/for-in loop iteration scope", + "exec": "let scopes = [];\nfor(let i = 0; i < 2; i++) {\n scopes.push(function(){ return i; });\n}\nlet passed = (scopes[0]() === 0 && scopes[1]() === 1);\n\nscopes = [];\nfor(let i in { a:1, b:1 }) {\n scopes.push(function(){ return i; });\n}\npassed &= (scopes[0]() === \"a\" && scopes[1]() === \"b\");\nreturn passed;" + }, + { + "name": "for-in loop binding shadowing parameter", + "exec": "try {\n Function(\"function f(e) { for (let e in {}) e }\");\n return true;\n} catch(e) {\n return false;\n}" + }, + { + "name": "basic support (strict mode)", + "exec": "'use strict';\nlet foo = 123;\nreturn (foo === 123);" + }, + { + "name": "is block-scoped (strict mode)", + "exec": "'use strict';\nlet bar = 123;\n{ let bar = 456; }\nreturn bar === 123;" + }, + { + "name": "scope shadow resolution (strict mode)", + "exec": "'use strict';\ntry {\n { let bar = 456; }\n let bar = 123;\n return bar === 123;\n} catch(e) {\n return false;\n}" + }, + { + "name": "cannot be in statements (strict mode)", + "exec": "'use strict';\nlet bar = 1;\ntry {\n Function(\"'use strict'; if(true) let baz = 1;\")();\n} catch(e) {\n return true;\n}" + }, + { + "name": "for loop statement scope (strict mode)", + "exec": "'use strict';\nlet baz = 1;\nfor(let baz = 0; false;) {}\nreturn baz === 1;" + }, + { + "name": "temporal dead zone (strict mode)", + "exec": "'use strict';\nvar passed = (function(){ try { qux; } catch(e) { return true; }}());\nfunction fn() { passed &= qux === 456; }\nlet qux = 456;\nfn();\nreturn passed;" + }, + { + "name": "for/for-in loop iteration scope (strict mode)", + "exec": "'use strict';\nlet scopes = [];\nfor(let i = 0; i < 2; i++) {\n scopes.push(function(){ return i; });\n}\nlet passed = (scopes[0]() === 0 && scopes[1]() === 1);\n\nscopes = [];\nfor(let i in { a:1, b:1 }) {\n scopes.push(function(){ return i; });\n}\npassed &= (scopes[0]() === \"a\" && scopes[1]() === \"b\");\nreturn passed;" + }, + { + "name": "for-in loop binding shadowing parameter (strict mode)", + "exec": "try {\n Function(\"'use strict'; function f(e) { for (let e in {}) e }\");\n return true;\n} catch(e) {\n return false;\n}" + } + ] }, { - "name": "template literal revision" + "name": "block-level function declaration", + "target": "es6", + "category": "bindings", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation", + "exec": "'use strict';\nif (f() !== 1) return false;\nfunction f() { return 1; }\n{\n if (f() !== 2) return false;\n function f() { return 2; }\n if (f() !== 2) return false;\n}\nif (f() !== 1) return false;\nreturn true;" }, { - "name": "Symbol.prototype.description" + "name": "arrow functions", + "target": "es6", + "category": "functions", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions", + "subtests": [ + { + "name": "0 parameters", + "exec": "return (() => 5)() === 5;" + }, + { + "name": "1 parameter, no brackets", + "exec": "var b = x => x + \"foo\";\nreturn (b(\"fee fie foe \") === \"fee fie foe foo\");" + }, + { + "name": "multiple parameters", + "exec": "var c = (v, w, x, y, z) => \"\" + v + w + x + y + z;\nreturn (c(6, 5, 4, 3, 2) === \"65432\");" + }, + { + "name": "lexical \"this\" binding", + "exec": "var d = { x : \"bar\", y : function() { return z => this.x + z; }}.y();\nvar e = { x : \"baz\", y : d };\nreturn d(\"ley\") === \"barley\" && e.y(\"ley\") === \"barley\";" + }, + { + "name": "\"this\" unchanged by call or apply", + "exec": "var d = { x : \"foo\", y : function() { return () => this.x; }};\nvar e = { x : \"bar\" };\nreturn d.y().call(e) === \"foo\" && d.y().apply(e) === \"foo\";" + }, + { + "name": "can't be bound, can be curried", + "exec": "var d = { x : \"bar\", y : function() { return z => this.x + z; }};\nvar e = { x : \"baz\" };\nreturn d.y().bind(e, \"ley\")() === \"barley\";" + }, + { + "name": "lexical \"arguments\" binding", + "exec": "var f = (function() { return z => arguments[0]; }(5));\nreturn f(6) === 5;" + }, + { + "name": "no line break between params and =>", + "exec": "return (() => {\n try { Function(\"x\\n => 2\")(); } catch(e) { return true; }\n})();" + }, + { + "name": "correct precedence", + "exec": "return (() => {\n try { Function(\"0 || () => 2\")(); } catch(e) { return true; }\n})();" + }, + { + "name": "no \"prototype\" property", + "exec": "var a = () => 5;\nreturn !a.hasOwnProperty(\"prototype\");" + }, + { + "name": "lexical \"super\" binding in constructors", + "exec": "var received;\n\nclass B {\n constructor (arg) {\n received = arg;\n }\n}\nclass C extends B {\n constructor () {\n var callSuper = () => super('foo');\n callSuper();\n }\n}\nreturn new C instanceof C && received === 'foo'" + }, + { + "name": "lexical \"super\" binding in methods", + "exec": "class B {\n qux() {\n return \"quux\";\n }\n}\nclass C extends B {\n baz() {\n return x => super.qux();\n }\n}\nvar arrow = new C().baz();\nreturn arrow() === \"quux\";" + }, + { + "name": "lexical \"new.target\" binding", + "exec": "function C() {\n return x => new.target;\n}\nreturn new C()() === C && C()() === void undefined;" + } + ] }, { - "name": "Object.fromEntries" + "name": "class", + "target": "es6", + "category": "functions", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes", + "subtests": [ + { + "name": "class statement", + "exec": "class C {}\nreturn typeof C === \"function\";" + }, + { + "name": "is block-scoped", + "exec": "class C {}\nvar c1 = C;\n{\n class C {}\n var c2 = C;\n}\nreturn C === c1;" + }, + { + "name": "class expression", + "exec": "return typeof class C {} === \"function\";" + }, + { + "name": "anonymous class", + "exec": "return typeof class {} === \"function\";" + }, + { + "name": "constructor", + "exec": "class C {\n constructor() { this.x = 1; }\n}\nreturn C.prototype.constructor === C\n && new C().x === 1;" + }, + { + "name": "prototype methods", + "exec": "class C {\n method() { return 2; }\n}\nreturn typeof C.prototype.method === \"function\"\n && new C().method() === 2;" + }, + { + "name": "string-keyed methods", + "exec": "class C {\n \"foo bar\"() { return 2; }\n}\nreturn typeof C.prototype[\"foo bar\"] === \"function\"\n && new C()[\"foo bar\"]() === 2;" + }, + { + "name": "computed prototype methods", + "exec": "var foo = \"method\";\nclass C {\n [foo]() { return 2; }\n}\nreturn typeof C.prototype.method === \"function\"\n && new C().method() === 2;" + }, + { + "name": "optional semicolons", + "exec": "class C {\n ;\n method() { return 2; };\n method2() { return 2; }\n method3() { return 2; };\n}\nreturn typeof C.prototype.method === \"function\"\n && typeof C.prototype.method2 === \"function\"\n && typeof C.prototype.method3 === \"function\";" + }, + { + "name": "static methods", + "exec": "class C {\n static method() { return 3; }\n}\nreturn typeof C.method === \"function\"\n && C.method() === 3;" + }, + { + "name": "computed static methods", + "exec": "var foo = \"method\";\nclass C {\n static [foo]() { return 3; }\n}\nreturn typeof C.method === \"function\"\n && C.method() === 3;" + }, + { + "name": "accessor properties", + "exec": "var baz = false;\nclass C {\n get foo() { return \"foo\"; }\n set bar(x) { baz = x; }\n}\nnew C().bar = true;\nreturn new C().foo === \"foo\" && baz;" + }, + { + "name": "computed accessor properties", + "exec": "var garply = \"foo\", grault = \"bar\", baz = false;\nclass C {\n get [garply]() { return \"foo\"; }\n set [grault](x) { baz = x; }\n}\nnew C().bar = true;\nreturn new C().foo === \"foo\" && baz;" + }, + { + "name": "static accessor properties", + "exec": "var baz = false;\nclass C {\n static get foo() { return \"foo\"; }\n static set bar(x) { baz = x; }\n}\nC.bar = true;\nreturn C.foo === \"foo\" && baz;" + }, + { + "name": "computed static accessor properties", + "exec": "var garply = \"foo\", grault = \"bar\", baz = false;\nclass C {\n static get [garply]() { return \"foo\"; }\n static set [grault](x) { baz = x; }\n}\nC.bar = true;\nreturn C.foo === \"foo\" && baz;" + }, + { + "name": "class name is lexically scoped", + "exec": "class C {\n method() { return typeof C === \"function\"; }\n}\nvar M = C.prototype.method;\nC = void undefined;\nreturn C === void undefined && M();" + }, + { + "name": "computed names, temporal dead zone", + "exec": "try {\n var B = class C {\n [C](){}\n }\n} catch(e) {\n return true;\n}" + }, + { + "name": "methods aren't enumerable", + "exec": "class C {\n foo() {}\n static bar() {}\n}\nreturn !C.prototype.propertyIsEnumerable(\"foo\") && !C.propertyIsEnumerable(\"bar\");" + }, + { + "name": "implicit strict mode", + "exec": "class C {\n static method() { return this === void undefined; }\n}\nreturn (0,C.method)();" + }, + { + "name": "constructor requires new", + "exec": "class C {}\ntry {\n C();\n}\ncatch(e) {\n return true;\n}" + }, + { + "name": "extends", + "exec": "class B {}\nclass C extends B {}\nreturn new C() instanceof B\n && B.isPrototypeOf(C);" + }, + { + "name": "extends expressions", + "exec": "var B;\nclass C extends (B = class {}) {}\nreturn new C() instanceof B\n && B.isPrototypeOf(C);" + }, + { + "name": "extends null", + "exec": "class C extends null {\n constructor() { return Object.create(null); }\n}\nreturn Function.prototype.isPrototypeOf(C)\n && Object.getPrototypeOf(C.prototype) === null;" + }, + { + "name": "new.target", + "exec": "var passed = false;\nnew function f() {\n passed = new.target === f;\n}();\n\nclass A {\n constructor() {\n passed &= new.target === B;\n }\n}\nclass B extends A {}\nnew B();\nreturn passed;" + } + ] }, { - "name": "string trimming" + "name": "super", + "target": "es6", + "category": "functions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-super-keyword", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super", + "subtests": [ + { + "name": "statement in constructors", + "exec": "var passed = false;\nclass B {\n constructor(a) { passed = (a === \"barbaz\"); }\n}\nclass C extends B {\n constructor(a) { super(\"bar\" + a); }\n}\nnew C(\"baz\");\nreturn passed;" + }, + { + "name": "expression in constructors", + "exec": "class B {\n constructor(a) { return [\"foo\" + a]; }\n}\nclass C extends B {\n constructor(a) { return super(\"bar\" + a); }\n}\nreturn new C(\"baz\")[0] === \"foobarbaz\";" + }, + { + "name": "in methods, property access", + "exec": "class B {}\nB.prototype.qux = \"foo\";\nB.prototype.corge = \"baz\";\nclass C extends B {\n quux(a) { return super.qux + a + super[\"corge\"]; }\n}\nC.prototype.qux = \"garply\";\nreturn new C().quux(\"bar\") === \"foobarbaz\";" + }, + { + "name": "in methods, method calls", + "exec": "class B {\n qux(a) { return \"foo\" + a; }\n}\nclass C extends B {\n qux(a) { return super.qux(\"bar\" + a); }\n}\nreturn new C().qux(\"baz\") === \"foobarbaz\";" + }, + { + "name": "method calls use correct \"this\" binding", + "exec": "class B {\n qux(a) { return this.foo + a; }\n}\nclass C extends B {\n qux(a) { return super.qux(\"bar\" + a); }\n}\nvar obj = new C();\nobj.foo = \"foo\";\nreturn obj.qux(\"baz\") === \"foobarbaz\";" + }, + { + "name": "constructor calls use correct \"new.target\" binding", + "exec": "var passed;\nclass B {\n constructor() { passed = (new.target === C); }\n}\nclass C extends B {\n constructor() { super(); }\n}\nnew C();\nreturn passed;" + }, + { + "name": "is statically bound", + "exec": "class B {\n qux() { return \"bar\"; }\n}\nclass C extends B {\n qux() { return super.qux() + this.corge; }\n}\nvar obj = {\n qux: C.prototype.qux,\n corge: \"ley\"\n};\nreturn obj.qux() === \"barley\";" + }, + { + "name": "super() invokes the correct constructor", + "exec": "// checks that super() is *not* a synonym of super.constructor()\nvar passed;\nclass B {\n constructor() {\n passed = true;\n }\n};\nB.prototype.constructor = function () {\n passed = false;\n};\nclass C extends B { };\nnew C;\nreturn passed;" + } + ] }, { - "name": "Array.prototype.{flat, flatMap}" + "name": "generators", + "target": "es6", + "category": "functions", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*", + "subtests": [ + { + "name": "basic functionality", + "exec": "function * generator(){\n yield 5; yield 6;\n};\nvar iterator = generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "generator function expressions", + "exec": "var generator = function * (){\n yield 5; yield 6;\n};\nvar iterator = generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "correct \"this\" binding", + "exec": "function * generator(){\n yield this.x; yield this.y;\n};\nvar iterator = { g: generator, x: 5, y: 6 }.g();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "can't use \"this\" with new", + "exec": "function * generator(){\n yield this.x; yield this.y;\n};\ntry {\n (new generator()).next();\n}\ncatch (e) {\n return true;\n}" + }, + { + "name": "sending", + "exec": "var sent;\nfunction * generator(){\n sent = [yield 5, yield 6];\n};\nvar iterator = generator();\niterator.next();\niterator.next(\"foo\");\niterator.next(\"bar\");\nreturn sent[0] === \"foo\" && sent[1] === \"bar\";" + }, + { + "name": "%GeneratorPrototype%", + "exec": "function * generatorFn(){}\nvar ownProto = Object.getPrototypeOf(generatorFn());\nvar passed = ownProto === generatorFn.prototype;\n\nvar sharedProto = Object.getPrototypeOf(ownProto);\npassed &= sharedProto !== Object.prototype &&\n sharedProto === Object.getPrototypeOf(function*(){}.prototype) &&\n sharedProto.hasOwnProperty('next');\n\nreturn passed;" + }, + { + "name": "%GeneratorPrototype% prototype chain", + "exec": "function * generatorFn(){}\nvar g = generatorFn();\nvar ownProto = Object.getPrototypeOf(g);\nvar passed = ownProto === generatorFn.prototype;\n\nvar sharedProto = Object.getPrototypeOf(ownProto);\nvar iterProto = Object.getPrototypeOf(sharedProto);\n\npassed &= iterProto.hasOwnProperty(Symbol.iterator) &&\n !sharedProto .hasOwnProperty(Symbol.iterator) &&\n !ownProto .hasOwnProperty(Symbol.iterator) &&\n g[Symbol.iterator]() === g;\n\nreturn passed;" + }, + { + "name": "%GeneratorPrototype%.constructor", + "exec": "function * g (){}\nvar iterator = new g.constructor(\"a\",\"b\",\"c\",\"yield a; yield b; yield c;\")(5,6,7);\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 7 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\n\npassed &= g.constructor === (function*(){}).constructor;\nreturn passed;" + }, + { + "name": "%GeneratorPrototype%.throw", + "exec": "var passed = false;\nfunction * generator(){\n try {\n yield 5; yield 6;\n } catch(e) {\n passed = (e === \"foo\");\n }\n};\nvar iterator = generator();\niterator.next();\niterator.throw(\"foo\");\nreturn passed;" + }, + { + "name": "%GeneratorPrototype%.return", + "exec": "function * generator(){\n yield 5; yield 6;\n};\nvar iterator = generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.return(\"quxquux\");\npassed &= item.value === \"quxquux\" && item.done === true;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield operator precedence", + "exec": "var passed;\nfunction * generator(){\n passed = yield 0 ? true : false;\n};\nvar iterator = generator();\niterator.next();\niterator.next(true);\nreturn passed;" + }, + { + "name": "yield *, arrays", + "exec": "var iterator = (function * generator() {\n yield * [5, 6];\n}());\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, sparse arrays", + "exec": "var iterator = (function * generator() {\n yield * [,,];\n}());\nvar item = iterator.next();\nvar passed = item.value === void undefined && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, strings", + "exec": "var iterator = (function * generator() {\n yield * \"56\";\n}());\nvar item = iterator.next();\nvar passed = item.value === \"5\" && item.done === false;\nitem = iterator.next();\npassed &= item.value === \"6\" && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, astral plane strings", + "exec": "var iterator = (function * generator() {\n yield * \"𠮷𠮶\";\n}());\nvar item = iterator.next();\nvar passed = item.value === \"𠮷\" && item.done === false;\nitem = iterator.next();\npassed &= item.value === \"𠮶\" && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, generator instances", + "exec": "var iterator = (function * generator() {\n yield * (function*(){ yield 5; yield 6; yield 7; }());\n}());\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 7 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, generic iterables", + "exec": "var iterator = (function * generator() {\n yield * global.__createIterableObject([5, 6, 7]);\n}());\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 7 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield *, instances of iterables", + "exec": "var iterator = (function * generator() {\n yield * Object.create(__createIterableObject([5, 6, 7]));\n}());\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 7 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "yield * on non-iterables is a runtime error", + "exec": "var iterator = (function * generator() {\n yield * [5];\n}());\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\niterator = (function * generator() {\n yield * 5;\n}());\ntry {\n iterator.next();\n} catch (e) {\n return passed;\n}" + }, + { + "name": "yield *, iterator closing", + "exec": "var closed = '';\nvar iter = __createIterableObject([1, 2, 3], {\n 'return': function(){\n closed += 'a';\n return {done: true};\n }\n});\nvar gen = (function* generator(){\n try {\n yield *iter;\n } finally {\n closed += 'b';\n }\n})();\ngen.next();\ngen['return']();\nreturn closed === 'ab';" + }, + { + "name": "yield *, iterator closing via throw()", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'throw': undefined,\n 'return': function() {\n closed = true;\n return {done: true};\n }\n});\nvar gen = (function*(){\n try {\n yield *iter;\n } catch(e){}\n})();\ngen.next();\ngen['throw']();\nreturn closed;" + }, + { + "name": "shorthand generator methods", + "exec": "var o = {\n * generator() {\n yield 5; yield 6;\n }\n};\nvar iterator = o.generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "string-keyed shorthand generator methods", + "exec": "var o = {\n * \"foo bar\"() {\n yield 5; yield 6;\n }\n};\nvar iterator = o[\"foo bar\"]();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "computed shorthand generators", + "exec": "var garply = \"generator\";\nvar o = {\n * [garply] () {\n yield 5; yield 6;\n }\n};\nvar iterator = o.generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "shorthand generator methods, classes", + "exec": "class C {\n * generator() {\n yield 5; yield 6;\n }\n};\nvar iterator = new C().generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "computed shorthand generators, classes", + "exec": "var garply = \"generator\";\nclass C {\n * [garply] () {\n yield 5; yield 6;\n }\n}\nvar iterator = new C().generator();\nvar item = iterator.next();\nvar passed = item.value === 5 && item.done === false;\nitem = iterator.next();\npassed &= item.value === 6 && item.done === false;\nitem = iterator.next();\npassed &= item.value === void undefined && item.done === true;\nreturn passed;" + }, + { + "name": "shorthand generators can't be constructors", + "exec": "class C {\n * generator() {\n yield 5; yield 6;\n }\n};\ntry {\n Function(\"class D { * constructor() { return {}; } }\");\n} catch(e) {\n return true;\n}" + } + ] }, { - "name": "optional catch binding" + "name": "typed arrays", + "target": "es6", + "category": "built-ins", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-typedarray-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", + "subtests": [ + { + "name": "Int8Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Int8Array(buffer); view[0] = 0x80;\nreturn view[0] === -0x80;" + }, + { + "name": "Uint8Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Uint8Array(buffer); view[0] = 0x100;\nreturn view[0] === 0;" + }, + { + "name": "Uint8ClampedArray", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Uint8ClampedArray(buffer); view[0] = 0x100;\nreturn view[0] === 0xFF;" + }, + { + "name": "Int16Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Int16Array(buffer); view[0] = 0x8000;\nreturn view[0] === -0x8000;" + }, + { + "name": "Uint16Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Uint16Array(buffer); view[0] = 0x10000;\nreturn view[0] === 0;" + }, + { + "name": "Int32Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Int32Array(buffer); view[0] = 0x80000000;\nreturn view[0] === -0x80000000;" + }, + { + "name": "Uint32Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Uint32Array(buffer); view[0] = 0x100000000;\nreturn view[0] === 0;" + }, + { + "name": "Float32Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Float32Array(buffer); view[0] = 0.1;\nreturn view[0] === 0.10000000149011612;" + }, + { + "name": "Float64Array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new Float64Array(buffer); view[0] = 0.1;\nreturn view[0] === 0.1;" + }, + { + "name": "DataView (Int8)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setInt8 (0, 0x80);\nreturn view.getInt8(0) === -0x80;" + }, + { + "name": "DataView (Uint8)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setUint8(0, 0x100);\nreturn view.getUint8(0) === 0;" + }, + { + "name": "DataView (Int16)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setInt16(0, 0x8000);\nreturn view.getInt16(0) === -0x8000;" + }, + { + "name": "DataView (Uint16)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setUint16(0, 0x10000);\nreturn view.getUint16(0) === 0;" + }, + { + "name": "DataView (Int32)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setInt32(0, 0x80000000);\nreturn view.getInt32(0) === -0x80000000;" + }, + { + "name": "DataView (Uint32)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setUint32(0, 0x100000000);\nreturn view.getUint32(0) === 0;" + }, + { + "name": "DataView (Float32)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setFloat32(0, 0.1);\nreturn view.getFloat32(0) === 0.10000000149011612;" + }, + { + "name": "DataView (Float64)", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", + "exec": "var buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setFloat64(0, 0.1);\nreturn view.getFloat64(0) === 0.1;" + }, + { + "name": "ArrayBuffer[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species", + "exec": "return typeof ArrayBuffer[Symbol.species] === 'function';" + }, + { + "name": "constructors require new", + "exec": "var buffer = new ArrayBuffer(64);\nvar constructors = [\n 'ArrayBuffer',\n 'DataView',\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array'\n];\nreturn constructors.every(function (constructor) {\n try {\n if (constructor in global) {\n global[constructor](constructor === \"ArrayBuffer\" ? 64 : buffer);\n }\n return false;\n } catch(e) {\n return true;\n }\n});" + }, + { + "name": "constructors accept generic iterables", + "exec": "var constructors = [\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array'\n];\nfor(var i = 0; i < constructors.length; i++){\n var arr = new global[constructors[i]](__createIterableObject([1, 2, 3]));\n if(arr.length !== 3 || arr[0] !== 1 || arr[1] !== 2 || arr[2] !== 3)return false;\n}\nreturn true;" + }, + { + "name": "correct prototype chains", + "exec": "var constructors = [\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array'\n];\nvar constructor = Object.getPrototypeOf(Int8Array);\nvar prototype = Object.getPrototypeOf(Int8Array.prototype);\nif(constructor === Function.prototype || prototype === Object.prototype)return false;\nfor(var i = 0; i < constructors.length; i+=1) {\n if (!(constructors[i] in global\n && Object.getPrototypeOf(global[constructors[i]]) === constructor\n && Object.getPrototypeOf(global[constructors[i]].prototype) === prototype\n && Object.getOwnPropertyNames(global[constructors[i]].prototype).sort() + ''\n === \"BYTES_PER_ELEMENT,constructor\")) {\n return false;\n }\n}\nreturn true;" + }, + { + "name": "%TypedArray%.from", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from", + "exec": "return typeof Int8Array.from === \"function\" &&\ntypeof Uint8Array.from === \"function\" &&\ntypeof Uint8ClampedArray.from === \"function\" &&\ntypeof Int16Array.from === \"function\" &&\ntypeof Uint16Array.from === \"function\" &&\ntypeof Int32Array.from === \"function\" &&\ntypeof Uint32Array.from === \"function\" &&\ntypeof Float32Array.from === \"function\" &&\ntypeof Float64Array.from === \"function\";" + }, + { + "name": "%TypedArray%.of", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of", + "exec": "return typeof Int8Array.of === \"function\" &&\ntypeof Uint8Array.of === \"function\" &&\ntypeof Uint8ClampedArray.of === \"function\" &&\ntypeof Int16Array.of === \"function\" &&\ntypeof Uint16Array.of === \"function\" &&\ntypeof Int32Array.of === \"function\" &&\ntypeof Uint32Array.of === \"function\" &&\ntypeof Float32Array.of === \"function\" &&\ntypeof Float64Array.of === \"function\";" + }, + { + "name": "%TypedArray%.prototype.subarray", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray", + "exec": "return typeof Int8Array.prototype.subarray === \"function\" &&\ntypeof Uint8Array.prototype.subarray === \"function\" &&\ntypeof Uint8ClampedArray.prototype.subarray === \"function\" &&\ntypeof Int16Array.prototype.subarray === \"function\" &&\ntypeof Uint16Array.prototype.subarray === \"function\" &&\ntypeof Int32Array.prototype.subarray === \"function\" &&\ntypeof Uint32Array.prototype.subarray === \"function\" &&\ntypeof Float32Array.prototype.subarray === \"function\" &&\ntypeof Float64Array.prototype.subarray === \"function\";" + }, + { + "name": "%TypedArray%.prototype.join", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/join", + "exec": "return typeof Int8Array.prototype.join === \"function\" &&\ntypeof Uint8Array.prototype.join === \"function\" &&\ntypeof Uint8ClampedArray.prototype.join === \"function\" &&\ntypeof Int16Array.prototype.join === \"function\" &&\ntypeof Uint16Array.prototype.join === \"function\" &&\ntypeof Int32Array.prototype.join === \"function\" &&\ntypeof Uint32Array.prototype.join === \"function\" &&\ntypeof Float32Array.prototype.join === \"function\" &&\ntypeof Float64Array.prototype.join === \"function\";" + }, + { + "name": "%TypedArray%.prototype.indexOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf", + "exec": "return typeof Int8Array.prototype.indexOf === \"function\" &&\ntypeof Uint8Array.prototype.indexOf === \"function\" &&\ntypeof Uint8ClampedArray.prototype.indexOf === \"function\" &&\ntypeof Int16Array.prototype.indexOf === \"function\" &&\ntypeof Uint16Array.prototype.indexOf === \"function\" &&\ntypeof Int32Array.prototype.indexOf === \"function\" &&\ntypeof Uint32Array.prototype.indexOf === \"function\" &&\ntypeof Float32Array.prototype.indexOf === \"function\" &&\ntypeof Float64Array.prototype.indexOf === \"function\";" + }, + { + "name": "%TypedArray%.prototype.lastIndexOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf", + "exec": "return typeof Int8Array.prototype.lastIndexOf === \"function\" &&\ntypeof Uint8Array.prototype.lastIndexOf === \"function\" &&\ntypeof Uint8ClampedArray.prototype.lastIndexOf === \"function\" &&\ntypeof Int16Array.prototype.lastIndexOf === \"function\" &&\ntypeof Uint16Array.prototype.lastIndexOf === \"function\" &&\ntypeof Int32Array.prototype.lastIndexOf === \"function\" &&\ntypeof Uint32Array.prototype.lastIndexOf === \"function\" &&\ntypeof Float32Array.prototype.lastIndexOf === \"function\" &&\ntypeof Float64Array.prototype.lastIndexOf === \"function\";" + }, + { + "name": "%TypedArray%.prototype.slice", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice", + "exec": "return typeof Int8Array.prototype.slice === \"function\" &&\ntypeof Uint8Array.prototype.slice === \"function\" &&\ntypeof Uint8ClampedArray.prototype.slice === \"function\" &&\ntypeof Int16Array.prototype.slice === \"function\" &&\ntypeof Uint16Array.prototype.slice === \"function\" &&\ntypeof Int32Array.prototype.slice === \"function\" &&\ntypeof Uint32Array.prototype.slice === \"function\" &&\ntypeof Float32Array.prototype.slice === \"function\" &&\ntypeof Float64Array.prototype.slice === \"function\";" + }, + { + "name": "%TypedArray%.prototype.every", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/every", + "exec": "return typeof Int8Array.prototype.every === \"function\" &&\ntypeof Uint8Array.prototype.every === \"function\" &&\ntypeof Uint8ClampedArray.prototype.every === \"function\" &&\ntypeof Int16Array.prototype.every === \"function\" &&\ntypeof Uint16Array.prototype.every === \"function\" &&\ntypeof Int32Array.prototype.every === \"function\" &&\ntypeof Uint32Array.prototype.every === \"function\" &&\ntypeof Float32Array.prototype.every === \"function\" &&\ntypeof Float64Array.prototype.every === \"function\";" + }, + { + "name": "%TypedArray%.prototype.filter", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/filter", + "exec": "return typeof Int8Array.prototype.filter === \"function\" &&\ntypeof Uint8Array.prototype.filter === \"function\" &&\ntypeof Uint8ClampedArray.prototype.filter === \"function\" &&\ntypeof Int16Array.prototype.filter === \"function\" &&\ntypeof Uint16Array.prototype.filter === \"function\" &&\ntypeof Int32Array.prototype.filter === \"function\" &&\ntypeof Uint32Array.prototype.filter === \"function\" &&\ntypeof Float32Array.prototype.filter === \"function\" &&\ntypeof Float64Array.prototype.filter === \"function\";" + }, + { + "name": "%TypedArray%.prototype.forEach", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/forEach", + "exec": "return typeof Int8Array.prototype.forEach === \"function\" &&\ntypeof Uint8Array.prototype.forEach === \"function\" &&\ntypeof Uint8ClampedArray.prototype.forEach === \"function\" &&\ntypeof Int16Array.prototype.forEach === \"function\" &&\ntypeof Uint16Array.prototype.forEach === \"function\" &&\ntypeof Int32Array.prototype.forEach === \"function\" &&\ntypeof Uint32Array.prototype.forEach === \"function\" &&\ntypeof Float32Array.prototype.forEach === \"function\" &&\ntypeof Float64Array.prototype.forEach === \"function\";" + }, + { + "name": "%TypedArray%.prototype.map", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/map", + "exec": "return typeof Int8Array.prototype.map === \"function\" &&\ntypeof Uint8Array.prototype.map === \"function\" &&\ntypeof Uint8ClampedArray.prototype.map === \"function\" &&\ntypeof Int16Array.prototype.map === \"function\" &&\ntypeof Uint16Array.prototype.map === \"function\" &&\ntypeof Int32Array.prototype.map === \"function\" &&\ntypeof Uint32Array.prototype.map === \"function\" &&\ntypeof Float32Array.prototype.map === \"function\" &&\ntypeof Float64Array.prototype.map === \"function\";" + }, + { + "name": "%TypedArray%.prototype.reduce", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce", + "exec": "return typeof Int8Array.prototype.reduce === \"function\" &&\ntypeof Uint8Array.prototype.reduce === \"function\" &&\ntypeof Uint8ClampedArray.prototype.reduce === \"function\" &&\ntypeof Int16Array.prototype.reduce === \"function\" &&\ntypeof Uint16Array.prototype.reduce === \"function\" &&\ntypeof Int32Array.prototype.reduce === \"function\" &&\ntypeof Uint32Array.prototype.reduce === \"function\" &&\ntypeof Float32Array.prototype.reduce === \"function\" &&\ntypeof Float64Array.prototype.reduce === \"function\";" + }, + { + "name": "%TypedArray%.prototype.reduceRight", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight", + "exec": "return typeof Int8Array.prototype.reduceRight === \"function\" &&\ntypeof Uint8Array.prototype.reduceRight === \"function\" &&\ntypeof Uint8ClampedArray.prototype.reduceRight === \"function\" &&\ntypeof Int16Array.prototype.reduceRight === \"function\" &&\ntypeof Uint16Array.prototype.reduceRight === \"function\" &&\ntypeof Int32Array.prototype.reduceRight === \"function\" &&\ntypeof Uint32Array.prototype.reduceRight === \"function\" &&\ntypeof Float32Array.prototype.reduceRight === \"function\" &&\ntypeof Float64Array.prototype.reduceRight === \"function\";" + }, + { + "name": "%TypedArray%.prototype.reverse", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reverse", + "exec": "return typeof Int8Array.prototype.reverse === \"function\" &&\ntypeof Uint8Array.prototype.reverse === \"function\" &&\ntypeof Uint8ClampedArray.prototype.reverse === \"function\" &&\ntypeof Int16Array.prototype.reverse === \"function\" &&\ntypeof Uint16Array.prototype.reverse === \"function\" &&\ntypeof Int32Array.prototype.reverse === \"function\" &&\ntypeof Uint32Array.prototype.reverse === \"function\" &&\ntypeof Float32Array.prototype.reverse === \"function\" &&\ntypeof Float64Array.prototype.reverse === \"function\";" + }, + { + "name": "%TypedArray%.prototype.some", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some", + "exec": "return typeof Int8Array.prototype.some === \"function\" &&\ntypeof Uint8Array.prototype.some === \"function\" &&\ntypeof Uint8ClampedArray.prototype.some === \"function\" &&\ntypeof Int16Array.prototype.some === \"function\" &&\ntypeof Uint16Array.prototype.some === \"function\" &&\ntypeof Int32Array.prototype.some === \"function\" &&\ntypeof Uint32Array.prototype.some === \"function\" &&\ntypeof Float32Array.prototype.some === \"function\" &&\ntypeof Float64Array.prototype.some === \"function\";" + }, + { + "name": "%TypedArray%.prototype.sort", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/sort", + "exec": "return typeof Int8Array.prototype.sort === \"function\" &&\ntypeof Uint8Array.prototype.sort === \"function\" &&\ntypeof Uint8ClampedArray.prototype.sort === \"function\" &&\ntypeof Int16Array.prototype.sort === \"function\" &&\ntypeof Uint16Array.prototype.sort === \"function\" &&\ntypeof Int32Array.prototype.sort === \"function\" &&\ntypeof Uint32Array.prototype.sort === \"function\" &&\ntypeof Float32Array.prototype.sort === \"function\" &&\ntypeof Float64Array.prototype.sort === \"function\";" + }, + { + "name": "%TypedArray%.prototype.copyWithin", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin", + "exec": "return typeof Int8Array.prototype.copyWithin === \"function\" &&\ntypeof Uint8Array.prototype.copyWithin === \"function\" &&\ntypeof Uint8ClampedArray.prototype.copyWithin === \"function\" &&\ntypeof Int16Array.prototype.copyWithin === \"function\" &&\ntypeof Uint16Array.prototype.copyWithin === \"function\" &&\ntypeof Int32Array.prototype.copyWithin === \"function\" &&\ntypeof Uint32Array.prototype.copyWithin === \"function\" &&\ntypeof Float32Array.prototype.copyWithin === \"function\" &&\ntypeof Float64Array.prototype.copyWithin === \"function\";" + }, + { + "name": "%TypedArray%.prototype.find", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/find", + "exec": "return typeof Int8Array.prototype.find === \"function\" &&\ntypeof Uint8Array.prototype.find === \"function\" &&\ntypeof Uint8ClampedArray.prototype.find === \"function\" &&\ntypeof Int16Array.prototype.find === \"function\" &&\ntypeof Uint16Array.prototype.find === \"function\" &&\ntypeof Int32Array.prototype.find === \"function\" &&\ntypeof Uint32Array.prototype.find === \"function\" &&\ntypeof Float32Array.prototype.find === \"function\" &&\ntypeof Float64Array.prototype.find === \"function\";" + }, + { + "name": "%TypedArray%.prototype.findIndex", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex", + "exec": "return typeof Int8Array.prototype.findIndex === \"function\" &&\ntypeof Uint8Array.prototype.findIndex === \"function\" &&\ntypeof Uint8ClampedArray.prototype.findIndex === \"function\" &&\ntypeof Int16Array.prototype.findIndex === \"function\" &&\ntypeof Uint16Array.prototype.findIndex === \"function\" &&\ntypeof Int32Array.prototype.findIndex === \"function\" &&\ntypeof Uint32Array.prototype.findIndex === \"function\" &&\ntypeof Float32Array.prototype.findIndex === \"function\" &&\ntypeof Float64Array.prototype.findIndex === \"function\";" + }, + { + "name": "%TypedArray%.prototype.fill", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill", + "exec": "return typeof Int8Array.prototype.fill === \"function\" &&\ntypeof Uint8Array.prototype.fill === \"function\" &&\ntypeof Uint8ClampedArray.prototype.fill === \"function\" &&\ntypeof Int16Array.prototype.fill === \"function\" &&\ntypeof Uint16Array.prototype.fill === \"function\" &&\ntypeof Int32Array.prototype.fill === \"function\" &&\ntypeof Uint32Array.prototype.fill === \"function\" &&\ntypeof Float32Array.prototype.fill === \"function\" &&\ntypeof Float64Array.prototype.fill === \"function\";" + }, + { + "name": "%TypedArray%.prototype.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/keys", + "exec": "return typeof Int8Array.prototype.keys === \"function\" &&\ntypeof Uint8Array.prototype.keys === \"function\" &&\ntypeof Uint8ClampedArray.prototype.keys === \"function\" &&\ntypeof Int16Array.prototype.keys === \"function\" &&\ntypeof Uint16Array.prototype.keys === \"function\" &&\ntypeof Int32Array.prototype.keys === \"function\" &&\ntypeof Uint32Array.prototype.keys === \"function\" &&\ntypeof Float32Array.prototype.keys === \"function\" &&\ntypeof Float64Array.prototype.keys === \"function\";" + }, + { + "name": "%TypedArray%.prototype.values", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/values", + "exec": "return typeof Int8Array.prototype.values === \"function\" &&\ntypeof Uint8Array.prototype.values === \"function\" &&\ntypeof Uint8ClampedArray.prototype.values === \"function\" &&\ntypeof Int16Array.prototype.values === \"function\" &&\ntypeof Uint16Array.prototype.values === \"function\" &&\ntypeof Int32Array.prototype.values === \"function\" &&\ntypeof Uint32Array.prototype.values === \"function\" &&\ntypeof Float32Array.prototype.values === \"function\" &&\ntypeof Float64Array.prototype.values === \"function\";" + }, + { + "name": "%TypedArray%.prototype.entries", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/entries", + "exec": "return typeof Int8Array.prototype.entries === \"function\" &&\ntypeof Uint8Array.prototype.entries === \"function\" &&\ntypeof Uint8ClampedArray.prototype.entries === \"function\" &&\ntypeof Int16Array.prototype.entries === \"function\" &&\ntypeof Uint16Array.prototype.entries === \"function\" &&\ntypeof Int32Array.prototype.entries === \"function\" &&\ntypeof Uint32Array.prototype.entries === \"function\" &&\ntypeof Float32Array.prototype.entries === \"function\" &&\ntypeof Float64Array.prototype.entries === \"function\";" + }, + { + "name": "%TypedArray%.prototype[Symbol.iterator]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator", + "exec": "return typeof Int8Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Uint8Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Uint8ClampedArray.prototype[Symbol.iterator] === \"function\" &&\ntypeof Int16Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Uint16Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Int32Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Uint32Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Float32Array.prototype[Symbol.iterator] === \"function\" &&\ntypeof Float64Array.prototype[Symbol.iterator] === \"function\";" + }, + { + "name": "%TypedArray%[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/@@species", + "exec": "return typeof Int8Array[Symbol.species] === \"function\" &&\ntypeof Uint8Array[Symbol.species] === \"function\" &&\ntypeof Uint8ClampedArray[Symbol.species] === \"function\" &&\ntypeof Int16Array[Symbol.species] === \"function\" &&\ntypeof Uint16Array[Symbol.species] === \"function\" &&\ntypeof Int32Array[Symbol.species] === \"function\" &&\ntypeof Uint32Array[Symbol.species] === \"function\" &&\ntypeof Float32Array[Symbol.species] === \"function\" &&\ntypeof Float64Array[Symbol.species] === \"function\";" + } + ] }, { - "name": "Function.prototype.toString revision" + "name": "Map", + "target": "es6", + "category": "built-ins", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-map-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map", + "subtests": [ + { + "name": "basic functionality", + "exec": "var key = {};\nvar map = new Map();\n\nmap.set(key, 123);\n\nreturn map.has(key) && map.get(key) === 123;" + }, + { + "name": "constructor arguments", + "exec": "var key1 = {};\nvar key2 = {};\nvar map = new Map([[key1, 123], [key2, 456]]);\n\nreturn map.has(key1) && map.get(key1) === 123 &&\n map.has(key2) && map.get(key2) === 456;" + }, + { + "name": "constructor requires new", + "exec": "new Map();\ntry {\n Map();\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "constructor accepts null", + "exec": "new Map(null);\nreturn true;" + }, + { + "name": "constructor invokes set", + "exec": "var passed = false;\nvar _set = Map.prototype.set;\n\nMap.prototype.set = function(k, v) {\n passed = true;\n};\n\nnew Map([ [1, 2] ]);\nMap.prototype.set = _set;\n\nreturn passed;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\ntry {\n new Map(iter);\n} catch(e){}\nreturn closed;" + }, + { + "name": "Map.prototype.set returns this", + "exec": "var map = new Map();\nreturn map.set(0, 0) === map;" + }, + { + "name": "-0 key converts to +0", + "exec": "var map = new Map();\nmap.set(-0, \"foo\");\nvar k;\nmap.forEach(function (value, key) {\n k = 1 / key;\n});\nreturn k === Infinity && map.get(+0) === \"foo\";" + }, + { + "name": "Map.prototype.size", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size", + "exec": "var key = {};\nvar map = new Map();\n\nmap.set(key, 123);\n\nreturn map.size === 1;" + }, + { + "name": "Map.prototype.delete", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete", + "exec": "return typeof Map.prototype.delete === \"function\";" + }, + { + "name": "Map.prototype.clear", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear", + "exec": "return typeof Map.prototype.clear === \"function\";" + }, + { + "name": "Map.prototype.forEach", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach", + "exec": "return typeof Map.prototype.forEach === \"function\";" + }, + { + "name": "Map.prototype.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys", + "exec": "return typeof Map.prototype.keys === \"function\";" + }, + { + "name": "Map.prototype.values", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values", + "exec": "return typeof Map.prototype.values === \"function\";" + }, + { + "name": "Map.prototype.entries", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries", + "exec": "return typeof Map.prototype.entries === \"function\";" + }, + { + "name": "Map.prototype[Symbol.iterator]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator", + "exec": "return typeof Map.prototype[Symbol.iterator] === \"function\";" + }, + { + "name": "Map.prototype isn't an instance", + "exec": "new Map();\nvar obj = {};\ntry {\n Map.prototype.has(obj);\n}\ncatch(e) {\n return true;\n}" + }, + { + "name": "Map iterator prototype chain", + "exec": "// Iterator instance\nvar iterator = new Map()[Symbol.iterator]();\n// %MapIteratorPrototype%\nvar proto1 = Object.getPrototypeOf(iterator);\n// %IteratorPrototype%\nvar proto2 = Object.getPrototypeOf(proto1);\n\nreturn proto2.hasOwnProperty(Symbol.iterator) &&\n !proto1 .hasOwnProperty(Symbol.iterator) &&\n !iterator .hasOwnProperty(Symbol.iterator) &&\n iterator[Symbol.iterator]() === iterator;" + }, + { + "name": "Map[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species", + "exec": "var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);\nreturn 'get' in prop && Map[Symbol.species] === Map;" + } + ] }, { - "name": "JSON superset" + "name": "Set", + "target": "es6", + "category": "built-ins", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-set-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set", + "subtests": [ + { + "name": "basic functionality", + "exec": "var obj = {};\nvar set = new Set();\n\nset.add(123);\nset.add(123);\n\nreturn set.has(123);" + }, + { + "name": "constructor arguments", + "exec": "var obj1 = {};\nvar obj2 = {};\nvar set = new Set([obj1, obj2]);\n\nreturn set.has(obj1) && set.has(obj2);" + }, + { + "name": "constructor requires new", + "exec": "new Set();\ntry {\n Set();\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "constructor accepts null", + "exec": "new Set(null);\nreturn true;" + }, + { + "name": "constructor invokes add", + "exec": "var passed = false;\nvar _add = Set.prototype.add;\n\nSet.prototype.add = function(v) {\n passed = true;\n};\n\nnew Set([1]);\nSet.prototype.add = _add;\n\nreturn passed;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\nvar add = Set.prototype.add;\nSet.prototype.add = function(){ throw 0 };\ntry {\n new Set(iter);\n} catch(e){}\nSet.prototype.add = add;\nreturn closed;" + }, + { + "name": "Set.prototype.add returns this", + "exec": "var set = new Set();\nreturn set.add(0) === set;" + }, + { + "name": "-0 key converts to +0", + "exec": "var set = new Set();\nset.add(-0);\nvar k;\nset.forEach(function (value) {\n k = 1 / value;\n});\nreturn k === Infinity && set.has(+0);" + }, + { + "name": "Set.prototype.size", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size", + "exec": "var obj = {};\nvar set = new Set();\n\nset.add(123);\nset.add(123);\nset.add(456);\n\nreturn set.size === 2;" + }, + { + "name": "Set.prototype.delete", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete", + "exec": "return typeof Set.prototype.delete === \"function\";" + }, + { + "name": "Set.prototype.clear", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear", + "exec": "return typeof Set.prototype.clear === \"function\";" + }, + { + "name": "Set.prototype.forEach", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach", + "exec": "return typeof Set.prototype.forEach === \"function\";" + }, + { + "name": "Set.prototype.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys", + "exec": "return typeof Set.prototype.keys === \"function\";" + }, + { + "name": "Set.prototype.values", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values", + "exec": "return typeof Set.prototype.values === \"function\";" + }, + { + "name": "Set.prototype.entries", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries", + "exec": "return typeof Set.prototype.entries === \"function\";" + }, + { + "name": "Set.prototype[Symbol.iterator]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@iterator", + "exec": "return typeof Set.prototype[Symbol.iterator] === \"function\";" + }, + { + "name": "Set.prototype isn't an instance", + "exec": "new Set();\nvar obj = {};\ntry {\n Set.prototype.has(obj);\n}\ncatch(e) {\n return true;\n}" + }, + { + "name": "Set iterator prototype chain", + "exec": "// Iterator instance\nvar iterator = new Set()[Symbol.iterator]();\n// %SetIteratorPrototype%\nvar proto1 = Object.getPrototypeOf(iterator);\n// %IteratorPrototype%\nvar proto2 = Object.getPrototypeOf(proto1);\n\nreturn proto2.hasOwnProperty(Symbol.iterator) &&\n !proto1 .hasOwnProperty(Symbol.iterator) &&\n !iterator .hasOwnProperty(Symbol.iterator) &&\n iterator[Symbol.iterator]() === iterator;" + }, + { + "name": "Set[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@species", + "exec": "var prop = Object.getOwnPropertyDescriptor(Set, Symbol.species);\nreturn 'get' in prop && Set[Symbol.species] === Set;" + } + ] }, { - "name": "Well-formed JSON.stringify" + "name": "WeakMap", + "target": "es6", + "category": "built-ins", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap", + "subtests": [ + { + "name": "basic functionality", + "exec": "var key = {};\nvar weakmap = new WeakMap();\n\nweakmap.set(key, 123);\n\nreturn weakmap.has(key) && weakmap.get(key) === 123;" + }, + { + "name": "constructor arguments", + "exec": "var key1 = {};\nvar key2 = {};\nvar weakmap = new WeakMap([[key1, 123], [key2, 456]]);\n\nreturn weakmap.has(key1) && weakmap.get(key1) === 123 &&\n weakmap.has(key2) && weakmap.get(key2) === 456;" + }, + { + "name": "constructor requires new", + "exec": "new WeakMap();\ntry {\n WeakMap();\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "constructor accepts null", + "exec": "new WeakMap(null);\nreturn true;" + }, + { + "name": "constructor invokes set", + "exec": "var passed = false;\nvar _set = WeakMap.prototype.set;\n\nWeakMap.prototype.set = function(k, v) {\n passed = true;\n};\n\nnew WeakMap([ [{ }, 42] ]);\nWeakMap.prototype.set = _set;\n\nreturn passed;" + }, + { + "name": "frozen objects as keys", + "exec": "var f = Object.freeze({});\nvar m = new WeakMap;\nm.set(f, 42);\nreturn m.get(f) === 42;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\ntry {\n new WeakMap(iter);\n} catch(e){}\nreturn closed;" + }, + { + "name": "WeakMap.prototype.set returns this", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set#Return_value", + "exec": "var weakmap = new WeakMap();\nvar key = {};\nreturn weakmap.set(key, 0) === weakmap;" + }, + { + "name": "WeakMap.prototype.delete", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete", + "exec": "return typeof WeakMap.prototype.delete === \"function\";" + }, + { + "name": "no WeakMap.prototype.clear method", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/clear", + "exec": "if (!(\"clear\" in WeakMap.prototype)) {\n return true;\n}\nvar m = new WeakMap();\nvar key = {};\nm.set(key, 2);\nm.clear();\nreturn m.has(key);" + }, + { + "name": ".has, .get and .delete methods accept primitives", + "exec": "var m = new WeakMap;\nreturn m.has(1) === false\n && m.get(1) === void undefined\n && m.delete(1) === false;" + }, + { + "name": "WeakMap.prototype isn't an instance", + "exec": "new WeakMap();\nvar obj = {};\ntry {\n WeakMap.prototype.has(obj);\n}\ncatch(e) {\n return true;\n}" + } + ] }, { - "name": "String.prototype.matchAll" + "name": "WeakSet", + "target": "es6", + "category": "built-ins", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-weakset-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet", + "subtests": [ + { + "name": "basic functionality", + "exec": "var obj1 = {};\nvar weakset = new WeakSet();\n\nweakset.add(obj1);\nweakset.add(obj1);\n\nreturn weakset.has(obj1);" + }, + { + "name": "constructor arguments", + "exec": "var obj1 = {}, obj2 = {};\nvar weakset = new WeakSet([obj1, obj2]);\n\nreturn weakset.has(obj1) && weakset.has(obj2);" + }, + { + "name": "constructor requires new", + "exec": "new WeakSet();\ntry {\n WeakSet();\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "constructor accepts null", + "exec": "new WeakSet(null);\nreturn true;" + }, + { + "name": "constructor invokes add", + "exec": "var passed = false;\nvar _add = WeakSet.prototype.add;\n\nWeakSet.prototype.add = function(v) {\n passed = true;\n};\n\nnew WeakSet([ { } ]);\nWeakSet.prototype.add = _add;\n\nreturn passed;" + }, + { + "name": "iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\ntry {\n new WeakSet(iter);\n} catch(e){}\nreturn closed;" + }, + { + "name": "WeakSet.prototype.add returns this", + "exec": "var weakset = new WeakSet();\nvar obj = {};\nreturn weakset.add(obj) === weakset;" + }, + { + "name": "WeakSet.prototype.delete", + "exec": "return typeof WeakSet.prototype.delete === \"function\";" + }, + { + "name": "no WeakSet.prototype.clear method", + "exec": "if (!(\"clear\" in WeakSet.prototype)) {\n return true;\n}\nvar s = new WeakSet();\nvar key = {};\ns.add(key);\ns.clear();\nreturn s.has(key);" + }, + { + "name": ".has and .delete methods accept primitives", + "exec": "var s = new WeakSet;\nreturn s.has(1) === false\n && s.delete(1) === false;" + }, + { + "name": "WeakSet.prototype isn't an instance", + "exec": "new WeakSet();\nvar obj = {};\ntry {\n WeakSet.prototype.has(obj);\n}\ncatch(e) {\n return true;\n}" + } + ] }, { - "name": "BigInt" + "name": "Proxy", + "target": "es6", + "category": "built-ins", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy", + "subtests": [ + { + "name": "constructor requires new", + "exec": "new Proxy({}, {});\ntry {\n Proxy({}, {});\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "no \"prototype\" property", + "exec": "new Proxy({}, {});\nreturn !Proxy.hasOwnProperty('prototype');" + }, + { + "name": "\"get\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get", + "exec": "var proxied = { };\nvar proxy = new Proxy(proxied, {\n get: function (t, k, r) {\n return t === proxied && k === \"foo\" && r === proxy && 5;\n }\n});\nreturn proxy.foo === 5;" + }, + { + "name": "\"get\" handler, instances of proxies", + "exec": "var proxied = { };\nvar proxy = Object.create(new Proxy(proxied, {\n get: function (t, k, r) {\n return t === proxied && k === \"foo\" && r === proxy && 5;\n }\n}));\nreturn proxy.foo === 5;" + }, + { + "name": "\"get\" handler invariants", + "exec": "var passed = false;\nvar proxied = { };\nvar proxy = new Proxy(proxied, {\n get: function () {\n passed = true;\n return 4;\n }\n});\n// The value reported for a property must be the same as the value of the corresponding\n// target object property if the target object property is a non-writable,\n// non-configurable own data property.\nObject.defineProperty(proxied, \"foo\", { value: 5, enumerable: true });\ntry {\n proxy.foo;\n return false;\n}\ncatch(e) {}\n// The value reported for a property must be undefined if the corresponding target\n// object property is a non-configurable own accessor property that has undefined\n// as its [[Get]] attribute.\nObject.defineProperty(proxied, \"bar\",\n { set: function(){}, enumerable: true });\ntry {\n proxy.bar;\n return false;\n}\ncatch(e) {}\nreturn passed;" + }, + { + "name": "\"set\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set", + "exec": "var proxied = { };\nvar passed = false;\nvar proxy = new Proxy(proxied, {\n set: function (t, k, v, r) {\n passed = t === proxied && k + v === \"foobar\" && r === proxy;\n }\n});\nproxy.foo = \"bar\";\nreturn passed;" + }, + { + "name": "\"set\" handler, instances of proxies", + "exec": "var proxied = { };\nvar passed = false;\nvar proxy = Object.create(new Proxy(proxied, {\n set: function (t, k, v, r) {\n passed = t === proxied && k + v === \"foobar\" && r === proxy;\n }\n}));\nproxy.foo = \"bar\";\nreturn passed;" + }, + { + "name": "\"set\" handler invariants", + "exec": "var passed = false;\nnew Proxy({},{});\n// Cannot change the value of a property to be different from the value of\n// the corresponding target object if the corresponding target object\n// property is a non-writable, non-configurable own data property.\nvar proxied = {};\nvar proxy = new Proxy(proxied, {\n set: function () {\n passed = true;\n return true;\n }\n});\nObject.defineProperty(proxied, \"foo\", { value: 2, enumerable: true });\nproxy.foo = 2;\ntry {\n proxy.foo = 4;\n return false;\n} catch(e) {}\n// Cannot set the value of a property if the corresponding target\n// object property is a non-configurable own accessor property\n// that has undefined as its [[Set]] attribute.\nObject.defineProperty(proxied, \"bar\",\n { get: function(){}, enumerable: true });\ntry {\n proxy.bar = 2;\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"has\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has", + "exec": "var proxied = {};\nvar passed = false;\n\"foo\" in new Proxy(proxied, {\n has: function (t, k) {\n passed = t === proxied && k === \"foo\";\n }\n});\nreturn passed;" + }, + { + "name": "\"has\" handler, instances of proxies", + "exec": "var proxied = {};\nvar passed = false;\n\"foo\" in Object.create(new Proxy(proxied, {\n has: function (t, k) {\n passed = t === proxied && k === \"foo\";\n }\n}));\nreturn passed;" + }, + { + "name": "\"has\" handler invariants", + "exec": "var passed = false;\nnew Proxy({},{});\n// A property cannot be reported as non-existent, if it exists as a\n// non-configurable own property of the target object.\nvar proxied = {};\nvar proxy = new Proxy(proxied, {\n has: function () {\n passed = true;\n return false;\n }\n});\nObject.defineProperty(proxied, \"foo\", { value: 2, writable: true, enumerable: true });\ntry {\n 'foo' in proxy;\n return false;\n} catch(e) {}\n// A property cannot be reported as non-existent, if it exists as an\n// own property of the target object and the target object is not extensible.\nproxied.bar = 2;\nObject.preventExtensions(proxied);\ntry {\n 'bar' in proxy;\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"deleteProperty\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty", + "exec": "var proxied = {};\nvar passed = false;\ndelete new Proxy(proxied, {\n deleteProperty: function (t, k) {\n passed = t === proxied && k === \"foo\";\n }\n}).foo;\nreturn passed;" + }, + { + "name": "\"deleteProperty\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\n// A property cannot be reported as deleted, if it exists as a non-configurable\n// own property of the target object.\nvar proxied = {};\nObject.defineProperty(proxied, \"foo\", { value: 2, writable: true, enumerable: true });\ntry {\n delete new Proxy(proxied, {\n deleteProperty: function () {\n passed = true;\n return true;\n }\n }).foo;\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"getOwnPropertyDescriptor\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor", + "exec": "var proxied = {};\nvar fakeDesc = { value: \"foo\", configurable: true };\nvar returnedDesc = Object.getOwnPropertyDescriptor(\n new Proxy(proxied, {\n getOwnPropertyDescriptor: function (t, k) {\n return t === proxied && k === \"foo\" && fakeDesc;\n }\n }),\n \"foo\"\n);\nreturn (returnedDesc.value === fakeDesc.value\n && returnedDesc.configurable === fakeDesc.configurable\n && returnedDesc.writable === false\n && returnedDesc.enumerable === false);" + }, + { + "name": "\"getOwnPropertyDescriptor\" handler invariants", + "exec": "var passed = false;\nnew Proxy({},{});\n// A property cannot be reported as non-existent, if it exists as a non-configurable\n// own property of the target object.\nvar proxied = {};\nvar proxy = new Proxy(proxied, {\n getOwnPropertyDescriptor: function () {\n passed = true;\n return undefined;\n }\n});\nObject.defineProperty(proxied, \"foo\", { value: 2, writable: true, enumerable: true });\ntry {\n Object.getOwnPropertyDescriptor(proxy, \"foo\");\n return false;\n} catch(e) {}\n// A property cannot be reported as non-existent, if it exists as an own property\n// of the target object and the target object is not extensible.\nproxied.bar = 3;\nObject.preventExtensions(proxied);\ntry {\n Object.getOwnPropertyDescriptor(proxy, \"bar\");\n return false;\n} catch(e) {}\n// A property cannot be reported as existent, if it does not exists as an own property\n// of the target object and the target object is not extensible.\ntry {\n Object.getOwnPropertyDescriptor(new Proxy(proxied, {\n getOwnPropertyDescriptor: function() {\n return { value: 2, configurable: true, writable: true, enumerable: true };\n }}), \"baz\");\n return false;\n} catch(e) {}\n// A property cannot be reported as non-configurable, if it does not exists as an own\n// property of the target object or if it exists as a configurable own property of\n// the target object.\ntry {\n Object.getOwnPropertyDescriptor(new Proxy({}, {\n getOwnPropertyDescriptor: function() {\n return { value: 2, configurable: false, writable: true, enumerable: true };\n }}), \"baz\");\n return false;\n} catch(e) {}\ntry {\n Object.getOwnPropertyDescriptor(new Proxy({baz:1}, {\n getOwnPropertyDescriptor: function() {\n return { value: 1, configurable: false, writable: true, enumerable: true };\n }}), \"baz\");\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"defineProperty\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty", + "exec": "var proxied = {};\nvar passed = false;\nObject.defineProperty(\n new Proxy(proxied, {\n defineProperty: function (t, k, d) {\n passed = t === proxied && k === \"foo\" && d.value === 5;\n return true;\n }\n }),\n \"foo\",\n { value: 5, configurable: true }\n);\nreturn passed;" + }, + { + "name": "\"defineProperty\" handler invariants", + "exec": "var passed = false;\nnew Proxy({},{});\n// A property cannot be added, if the target object is not extensible.\nvar proxied = Object.preventExtensions({});\nvar proxy = new Proxy(proxied, {\n defineProperty: function() {\n passed = true;\n return true;\n }\n});\ntry {\n Object.defineProperty(proxy, \"foo\", { value: 2 });\n return false;\n} catch(e) {}\n// A property cannot be non-configurable, unless there exists a corresponding\n// non-configurable own property of the target object.\ntry {\n Object.defineProperty(\n new Proxy({ bar: true }, {\n defineProperty: function () {\n return true;\n }\n }),\n \"bar\",\n { value: 5, configurable: false, writable: true, enumerable: true }\n );\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"getPrototypeOf\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf", + "exec": "var proxied = {};\nvar fakeProto = {};\nvar proxy = new Proxy(proxied, {\n getPrototypeOf: function (t) {\n return t === proxied && fakeProto;\n }\n});\nreturn Object.getPrototypeOf(proxy) === fakeProto;" + }, + { + "name": "\"getPrototypeOf\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\n// If the target object is not extensible, [[GetPrototypeOf]] applied to the proxy object\n// must return the same value as [[GetPrototypeOf]] applied to the proxy object's target object.\ntry {\n Object.getPrototypeOf(new Proxy(Object.preventExtensions({}), {\n getPrototypeOf: function () {\n passed = true;\n return {};\n }\n }));\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"setPrototypeOf\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf", + "exec": "var proxied = {};\nvar newProto = {};\nvar passed = false;\nObject.setPrototypeOf(\n new Proxy(proxied, {\n setPrototypeOf: function (t, p) {\n passed = t === proxied && p === newProto;\n return true;\n }\n }),\n newProto\n);\nreturn passed;" + }, + { + "name": "\"setPrototypeOf\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\nObject.setPrototypeOf({},{});\n// If the target object is not extensible, the argument value must be the\n// same as the result of [[GetPrototypeOf]] applied to target object.\ntry {\n Object.setPrototypeOf(\n new Proxy(Object.preventExtensions({}), {\n setPrototypeOf: function () {\n passed = true;\n return true;\n }\n }),{});\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"isExtensible\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible", + "exec": "var proxied = {};\nvar passed = false;\nObject.isExtensible(\n new Proxy(proxied, {\n isExtensible: function (t) {\n passed = t === proxied; return true;\n }\n })\n);\nreturn passed;" + }, + { + "name": "\"isExtensible\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\n// [[IsExtensible]] applied to the proxy object must return the same value\n// as [[IsExtensible]] applied to the proxy object's target object with the same argument.\ntry {\n Object.isExtensible(new Proxy({}, {\n isExtensible: function (t) {\n passed = true;\n return false;\n }\n }));\n return false;\n} catch(e) {}\ntry {\n Object.isExtensible(new Proxy(Object.preventExtensions({}), {\n isExtensible: function (t) {\n return true;\n }\n }));\n return false;\n} catch(e) {}\nreturn true;" + }, + { + "name": "\"preventExtensions\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions", + "exec": "var proxied = {};\nvar passed = false;\nObject.preventExtensions(\n new Proxy(proxied, {\n preventExtensions: function (t) {\n passed = t === proxied;\n return Object.preventExtensions(proxied);\n }\n })\n);\nreturn passed;" + }, + { + "name": "\"preventExtensions\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\n// [[PreventExtensions]] applied to the proxy object only returns true\n// if [[IsExtensible]] applied to the proxy object's target object is false.\ntry {\n Object.preventExtensions(new Proxy({}, {\n preventExtensions: function () {\n passed = true;\n return true;\n }\n }));\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"ownKeys\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys", + "exec": "var proxied = {};\nvar passed = false;\nObject.keys(\n new Proxy(proxied, {\n ownKeys: function (t) {\n passed = t === proxied; return [];\n }\n })\n);\nreturn passed;" + }, + { + "name": "\"ownKeys\" handler invariant", + "exec": "var passed = false;\nnew Proxy({},{});\n// The Type of each result List element is either String or Symbol.\ntry {\n Object.keys(new Proxy({}, {\n ownKeys: function () {\n passed = true;\n return [2];\n }}));\n return false;\n} catch(e) {}\n// The result List must contain the keys of all non-configurable own properties of the target object.\nvar proxied = {};\nObject.defineProperty(proxied, \"foo\", { value: 2, writable: true, enumerable: true });\ntry {\n Object.keys(new Proxy(proxied, {\n ownKeys: function () {\n return [];\n }}));\n return false;\n} catch(e) {}\n// If the target object is not extensible, then the result List must contain all the keys\n// of the own properties of the target object and no other values.\ntry {\n Object.keys(new Proxy(Object.preventExtensions({b:1}), {\n ownKeys: function () {\n return ['a'];\n }}));\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"apply\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply", + "exec": "var proxied = function(){};\nvar passed = false;\nvar host = {\n method: new Proxy(proxied, {\n apply: function (t, thisArg, args) {\n passed = t === proxied && thisArg === host && args + \"\" === \"foo,bar\";\n }\n })\n};\nhost.method(\"foo\", \"bar\");\nreturn passed;" + }, + { + "name": "\"apply\" handler invariant", + "exec": "var passed = false;\nnew Proxy(function(){}, {\n apply: function () { passed = true; }\n})();\n// A Proxy exotic object only has a [[Call]] internal method if the\n// initial value of its [[ProxyTarget]] internal slot is an object\n// that has a [[Call]] internal method.\ntry {\n new Proxy({}, {\n apply: function () {}\n })();\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "\"construct\" handler", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct", + "exec": "var proxied = function(){};\nvar passed = false;\nnew new Proxy(proxied, {\n construct: function (t, args) {\n passed = t === proxied && args + \"\" === \"foo,bar\";\n return {};\n }\n})(\"foo\",\"bar\");\nreturn passed;" + }, + { + "name": "\"construct\" handler invariants", + "exec": "var passed = false;\nnew Proxy({},{});\n// A Proxy exotic object only has a [[Construct]] internal method if the\n// initial value of its [[ProxyTarget]] internal slot is an object\n// that has a [[Construct]] internal method.\ntry {\n new new Proxy({}, {\n construct: function (t, args) {\n return {};\n }\n })();\n return false;\n} catch(e) {}\n// The result of [[Construct]] must be an Object.\ntry {\n new new Proxy(function(){}, {\n construct: function (t, args) {\n passed = true;\n return 5;\n }\n })();\n return false;\n} catch(e) {}\nreturn passed;" + }, + { + "name": "Proxy.revocable", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/revocable", + "exec": "var obj = Proxy.revocable({}, { get: function() { return 5; } });\nvar passed = (obj.proxy.foo === 5);\nobj.revoke();\ntry {\n obj.proxy.foo;\n} catch(e) {\n passed &= e instanceof TypeError;\n}\nreturn passed;" + }, + { + "name": "Array.isArray support", + "exec": "return Array.isArray(new Proxy([], {}));" + }, + { + "name": "JSON.stringify support", + "exec": "return JSON.stringify(new Proxy(['foo'], {})) === '[\"foo\"]';" + } + ] }, { - "name": "Promise.allSettled" + "name": "Reflect", + "target": "es6", + "category": "built-ins", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-reflection", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect", + "subtests": [ + { + "name": "Reflect.get", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get", + "exec": "return Reflect.get({ qux: 987 }, \"qux\") === 987;" + }, + { + "name": "Reflect.set", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set", + "exec": "var obj = {};\nReflect.set(obj, \"quux\", 654);\nreturn obj.quux === 654;" + }, + { + "name": "Reflect.has", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has", + "exec": "return Reflect.has({ qux: 987 }, \"qux\");" + }, + { + "name": "Reflect.deleteProperty", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty", + "exec": "var obj = { bar: 456 };\nReflect.deleteProperty(obj, \"bar\");\nreturn !(\"bar\" in obj);" + }, + { + "name": "Reflect.getOwnPropertyDescriptor", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor", + "exec": "var obj = { baz: 789 };\nvar desc = Reflect.getOwnPropertyDescriptor(obj, \"baz\");\nreturn desc.value === 789 &&\n desc.configurable && desc.writable && desc.enumerable;" + }, + { + "name": "Reflect.defineProperty", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty", + "exec": "var obj = {};\nReflect.defineProperty(obj, \"foo\", { value: 123 });\nreturn obj.foo === 123 &&\n Reflect.defineProperty(Object.freeze({}), \"foo\", { value: 123 }) === false;" + }, + { + "name": "Reflect.getPrototypeOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf", + "exec": "return Reflect.getPrototypeOf([]) === Array.prototype;" + }, + { + "name": "Reflect.setPrototypeOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf", + "exec": "var obj = {};\nReflect.setPrototypeOf(obj, Array.prototype);\nreturn obj instanceof Array;" + }, + { + "name": "Reflect.isExtensible", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible", + "exec": "return Reflect.isExtensible({}) &&\n !Reflect.isExtensible(Object.preventExtensions({}));" + }, + { + "name": "Reflect.preventExtensions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions", + "exec": "var obj = {};\nReflect.preventExtensions(obj);\nreturn !Object.isExtensible(obj);" + }, + { + "name": "Reflect.ownKeys, string keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys", + "exec": "var obj = Object.create({ C: true });\nobj.A = true;\nObject.defineProperty(obj, 'B', { value: true, enumerable: false });\n\nreturn Reflect.ownKeys(obj).sort() + '' === \"A,B\";" + }, + { + "name": "Reflect.ownKeys, symbol keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys", + "exec": "var s1 = Symbol(), s2 = Symbol(), s3 = Symbol();\nvar proto = {};\nproto[s1] = true;\nvar obj = Object.create(proto);\nobj[s2] = true;\nObject.defineProperty(obj, s3, { value: true, enumerable: false });\n\nvar keys = Reflect.ownKeys(obj);\nreturn keys.indexOf(s2) >-1 && keys.indexOf(s3) >-1 && keys.length === 2;" + }, + { + "name": "Reflect.apply", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply", + "exec": "return Reflect.apply(Array.prototype.push, [1,2], [3,4,5]) === 5;" + }, + { + "name": "Reflect.construct", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct", + "exec": "return Reflect.construct(function(a, b, c) {\n this.qux = a + b + c;\n}, [\"foo\", \"bar\", \"baz\"]).qux === \"foobarbaz\";" + }, + { + "name": "Reflect.construct sets new.target meta-property", + "exec": "return Reflect.construct(function(a, b, c) {\n if (new.target === Object) {\n this.qux = a + b + c;\n }\n}, [\"foo\", \"bar\", \"baz\"], Object).qux === \"foobarbaz\";" + }, + { + "name": "Reflect.construct creates instances from third argument", + "exec": "function F(){}\nvar obj = Reflect.construct(function(){ this.y = 1; }, [], F);\nreturn obj.y === 1 && obj instanceof F;" + }, + { + "name": "Reflect.construct, Array subclassing", + "exec": "function F(){}\nvar obj = Reflect.construct(Array, [], F);\nobj[2] = 'foo';\nreturn obj.length === 3 && obj instanceof F;" + }, + { + "name": "Reflect.construct, RegExp subclassing", + "exec": "function F(){}\nvar obj = Reflect.construct(RegExp, [\"baz\",\"g\"], F);\nreturn RegExp.prototype.exec.call(obj, \"foobarbaz\")[0] === \"baz\"\n && obj.lastIndex === 9 && obj instanceof F;" + }, + { + "name": "Reflect.construct, Function subclassing", + "exec": "function F(){}\nvar obj = Reflect.construct(Function, [\"return 2\"], F);\nreturn obj() === 2 && obj instanceof F;" + }, + { + "name": "Reflect.construct, Promise subclassing", + "exec": "function F(){}\nvar p1 = Reflect.construct(Promise,[function(resolve, reject) { resolve(\"foo\"); }], F);\nvar p2 = Reflect.construct(Promise,[function(resolve, reject) { reject(\"quux\"); }], F);\nvar score = +(p1 instanceof F && p2 instanceof F);\n\nfunction thenFn(result) { score += (result === \"foo\"); check(); }\nfunction catchFn(result) { score += (result === \"quux\"); check(); }\nfunction shouldNotRun(result) { score = -Infinity; }\n\np1.then = p2.then = Promise.prototype.then;\np1.catch = p2.catch = Promise.prototype.catch;\n\np1.then(thenFn, shouldNotRun);\np2.then(shouldNotRun, catchFn);\np1.catch(shouldNotRun);\np2.catch(catchFn);\n\nfunction check() {\n if (score === 4) asyncTestPassed();\n}" + } + ] }, { - "name": "globalThis" + "name": "Promise", + "target": "es6", + "category": "built-ins", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise", + "subtests": [ + { + "name": "basic functionality", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise", + "exec": "var p1 = new Promise(function(resolve, reject) { resolve(\"foo\"); });\nvar p2 = new Promise(function(resolve, reject) { reject(\"quux\"); });\nvar score = 0;\n\nfunction thenFn(result) { score += (result === \"foo\"); check(); }\nfunction catchFn(result) { score += (result === \"quux\"); check(); }\nfunction shouldNotRun(result) { score = -Infinity; }\n\np1.then(thenFn, shouldNotRun);\np2.then(shouldNotRun, catchFn);\np1.catch(shouldNotRun);\np2.catch(catchFn);\n\np1.then(function() {\n // Promise.prototype.then() should return a new Promise\n score += p1.then() !== p1;\n check();\n});\n\nfunction check() {\n if (score === 4) asyncTestPassed();\n}" + }, + { + "name": "constructor requires new", + "exec": "new Promise(function(){});\ntry {\n Promise(function(){});\n return false;\n} catch(e) {\n return true;\n}" + }, + { + "name": "Promise.prototype isn't an instance", + "exec": "new Promise(function(){});\ntry {\n Promise.prototype.then(function(){});\n} catch (e) {\n return true;\n}" + }, + { + "name": "Promise.all", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all", + "exec": "var fulfills = Promise.all([\n new Promise(function(resolve) { setTimeout(resolve,2000,\"foo\"); }),\n new Promise(function(resolve) { setTimeout(resolve,1000,\"bar\"); })\n]);\nvar rejects = Promise.all([\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"baz\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"qux\"); })\n]);\nvar score = 0;\nfulfills.then(function(result) { score += (result + \"\" === \"foo,bar\"); check(); });\nrejects.catch(function(result) { score += (result === \"qux\"); check(); });\n\nfunction check() {\n if (score === 2) asyncTestPassed();\n}" + }, + { + "name": "Promise.all, generic iterables", + "exec": "var fulfills = Promise.all(global.__createIterableObject([\n new Promise(function(resolve) { setTimeout(resolve,2000,\"foo\"); }),\n new Promise(function(resolve) { setTimeout(resolve,1000,\"bar\"); })\n]));\nvar rejects = Promise.all(global.__createIterableObject([\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"baz\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"qux\"); })\n]));\nvar score = 0;\nfulfills.then(function(result) { score += (result + \"\" === \"foo,bar\"); check(); });\nrejects.catch(function(result) { score += (result === \"qux\"); check(); });\n\nfunction check() {\n if (score === 2) asyncTestPassed();\n}" + }, + { + "name": "Promise.race", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race", + "exec": "var fulfills = Promise.race([\n new Promise(function(resolve) { setTimeout(resolve,1000,\"foo\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"bar\"); })\n]);\nvar rejects = Promise.race([\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"baz\"); }),\n new Promise(function(resolve) { setTimeout(resolve,2000,\"qux\"); })\n]);\nvar score = 0;\nfulfills.then(function(result) { score += (result === \"foo\"); check(); });\nrejects.catch(function(result) { score += (result === \"baz\"); check(); });\n\nfunction check() {\n if (score === 2) asyncTestPassed();\n}" + }, + { + "name": "Promise.race, generic iterables", + "exec": "var fulfills = Promise.race(global.__createIterableObject([\n new Promise(function(resolve) { setTimeout(resolve,1000,\"foo\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"bar\"); })\n]));\nvar rejects = Promise.race(global.__createIterableObject([\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"baz\"); }),\n new Promise(function(resolve) { setTimeout(resolve,2000,\"qux\"); })\n]));\nvar score = 0;\nfulfills.then(function(result) { score += (result === \"foo\"); check(); });\nrejects.catch(function(result) { score += (result === \"baz\"); check(); });\n\nfunction check() {\n if (score === 2) asyncTestPassed();\n}" + }, + { + "name": "Promise[Symbol.species]", + "exec": "var prop = Object.getOwnPropertyDescriptor(Promise, Symbol.species);\nreturn 'get' in prop && Promise[Symbol.species] === Promise;" + } + ] }, { - "name": "optional chaining operator (?.)" + "name": "Symbol", + "target": "es6", + "category": "built-ins", + "significance": "large", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-symbol-constructor", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol", + "subtests": [ + { + "name": "basic functionality", + "exec": "var object = {};\nvar symbol = Symbol();\nvar value = {};\nobject[symbol] = value;\nreturn object[symbol] === value;" + }, + { + "name": "typeof support", + "exec": "return typeof Symbol() === \"symbol\";" + }, + { + "name": "symbol keys are hidden to pre-ES6 code", + "exec": "var object = {};\nvar symbol = Symbol();\nobject[symbol] = 1;\n\nfor (var x in object){}\nvar passed = !x;\n\nif (Object.keys && Object.getOwnPropertyNames) {\n passed &= Object.keys(object).length === 0\n && Object.getOwnPropertyNames(object).length === 0;\n}\n\nreturn passed;" + }, + { + "name": "Object.defineProperty support", + "exec": "var object = {};\nvar symbol = Symbol();\nvar value = {};\n\nif (Object.defineProperty) {\n Object.defineProperty(object, symbol, { value: value });\n return object[symbol] === value;\n}\n\nreturn passed;" + }, + { + "name": "symbols inherit from Symbol.prototype", + "exec": "var symbol = Symbol();\nvar passed = symbol.foo === void undefined;\nSymbol.prototype.foo = 2;\npassed &= symbol.foo === 2;\ndelete Symbol.prototype.foo;\nreturn passed;" + }, + { + "name": "cannot coerce to string or number", + "exec": "var symbol = Symbol();\n\ntry {\n symbol + \"\";\n return false;\n}\ncatch(e) {}\n\ntry {\n symbol + 0;\n return false;\n} catch(e) {}\n\nreturn true;" + }, + { + "name": "can convert with String()", + "exec": "return String(Symbol(\"foo\")) === \"Symbol(foo)\";" + }, + { + "name": "new Symbol() throws", + "exec": "var symbol = Symbol();\ntry {\n new Symbol();\n} catch(e) {\n return true;\n}" + }, + { + "name": "Object(symbol)", + "exec": "var symbol = Symbol();\nvar symbolObject = Object(symbol);\n\nreturn typeof symbolObject === \"object\" &&\n symbolObject instanceof Symbol &&\n symbolObject == symbol && // eslint-disable-line eqeqeq\n symbolObject !== symbol &&\n symbolObject.valueOf() === symbol;" + }, + { + "name": "JSON.stringify ignores symbol primitives", + "exec": "var object = { foo: Symbol() };\nobject[Symbol()] = 1;\nvar array = [Symbol()];\nreturn JSON.stringify(object) === '{}' && JSON.stringify(array) === '[null]' && JSON.stringify(Symbol()) === void undefined;" + }, + { + "name": "JSON.stringify ignores symbol objects", + "exec": "var testSymbolObject = function (sym) {\n var object = { foo: sym };\n try {\n // some browsers throw a TypeError when setting symbol object keys.\n // this isn't part of this test, so, ignore it if so.\n object[sym] = 1;\n } catch (e) {} // some browsers throw a TypeError when setting symbol object keys.\n var array = [sym];\n return JSON.stringify(object) === '{\"foo\":{}}' && JSON.stringify(array) === '[{}]' && JSON.stringify(sym) === '{}';\n};\nvar objSym = Object(Symbol());\nvar symNoToJSON = Object(Symbol());\nObject.defineProperty(symNoToJSON, 'toJSON', { enumerable: false, value: null }); // ensure it overrides the prototype, but is not callable\nreturn testSymbolObject(objSym) && testSymbolObject(symNoToJSON);" + }, + { + "name": "global symbol registry", + "exec": "var symbol = Symbol.for('foo');\nreturn Symbol.for('foo') === symbol &&\n Symbol.keyFor(symbol) === 'foo';" + } + ] }, { - "name": "nullish coalescing operator (??)" + "name": "well-known symbols", + "target": "es6", + "category": "built-ins", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols", + "subtests": [ + { + "name": "Symbol.hasInstance", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance", + "exec": "var passed = false;\nvar obj = { foo: true };\nvar C = function(){};\nObject.defineProperty(C, Symbol.hasInstance, {\n value: function(inst) { passed = inst.foo; return false; }\n});\nobj instanceof C;\nreturn passed;" + }, + { + "name": "Symbol.isConcatSpreadable, non-spreadable array", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable", + "exec": "var a = [], b = [];\nb[Symbol.isConcatSpreadable] = false;\na = a.concat(b);\nreturn a[0] === b;" + }, + { + "name": "Symbol.isConcatSpreadable, spreadable object with poisoned getter", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable", + "exec": "if (typeof Symbol !== 'function' || !Symbol.isConcatSpreadable) {\n return null;\n}\nvar spreadableHasPoisonedIndex = { length: Math.pow(2, 53) - 1 };\nspreadableHasPoisonedIndex[Symbol.isConcatSpreadable] = true;\nObject.defineProperty(spreadableHasPoisonedIndex, 0, {\n get: function () { throw new SyntaxError(); }\n});\ntry {\n [].concat(spreadableHasPoisonedIndex);\n return false;\n} catch (e) {\n return !!e && e.name === 'SyntaxError';\n}" + }, + { + "name": "Symbol.iterator, existence", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator", + "exec": "return \"iterator\" in Symbol;" + }, + { + "name": "Symbol.iterator, arguments object", + "exec": "return (function() {\n return typeof arguments[Symbol.iterator] === 'function'\n && Object.hasOwnProperty.call(arguments, Symbol.iterator);\n}());" + }, + { + "name": "Symbol.species, existence", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species", + "exec": "return \"species\" in Symbol;" + }, + { + "name": "Symbol.species, Array.prototype.concat", + "exec": "var obj = [];\nobj.constructor = {};\nobj.constructor[Symbol.species] = function() {\n return { foo: 1 };\n};\nreturn Array.prototype.concat.call(obj, []).foo === 1;" + }, + { + "name": "Symbol.species, Array.prototype.filter", + "exec": "var obj = [];\nobj.constructor = {};\nobj.constructor[Symbol.species] = function() {\n return { foo: 1 };\n};\nreturn Array.prototype.filter.call(obj, Boolean).foo === 1;" + }, + { + "name": "Symbol.species, Array.prototype.map", + "exec": "var obj = [];\nobj.constructor = {};\nobj.constructor[Symbol.species] = function() {\n return { foo: 1 };\n};\nreturn Array.prototype.map.call(obj, Boolean).foo === 1;" + }, + { + "name": "Symbol.species, Array.prototype.slice", + "exec": "var obj = [];\nobj.constructor = {};\nobj.constructor[Symbol.species] = function() {\n return { foo: 1 };\n};\nreturn Array.prototype.slice.call(obj, 0).foo === 1;" + }, + { + "name": "Symbol.species, Array.prototype.splice", + "exec": "var obj = [];\nobj.constructor = {};\nobj.constructor[Symbol.species] = function() {\n return { foo: 1 };\n};\nreturn Array.prototype.splice.call(obj, 0).foo === 1;" + }, + { + "name": "Symbol.species, RegExp.prototype[Symbol.split]", + "exec": "var passed = false;\nvar obj = { constructor: {} };\nobj[Symbol.split] = RegExp.prototype[Symbol.split];\nobj.constructor[Symbol.species] = function() {\n passed = true;\n return /./;\n};\n\"\".split(obj);\nreturn passed;" + }, + { + "name": "Symbol.species, Promise.prototype.then", + "exec": "var promise = new Promise(function(resolve){ resolve(42); });\nvar FakePromise1 = promise.constructor = function(exec){ exec(function(){}, function(){}); };\nvar FakePromise2 = function(exec){ exec(function(){}, function(){}); };\nObject.defineProperty(FakePromise1, Symbol.species, {value: FakePromise2});\nreturn promise.then(function(){}) instanceof FakePromise2;" + }, + { + "name": "Symbol.replace", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace", + "exec": "var O = {};\nO[Symbol.replace] = function(){\n return 42;\n};\nreturn ''.replace(O) === 42;" + }, + { + "name": "Symbol.search", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search", + "exec": "var O = {};\nO[Symbol.search] = function(){\n return 42;\n};\nreturn ''.search(O) === 42;" + }, + { + "name": "Symbol.split", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split", + "exec": "var O = {};\nO[Symbol.split] = function(){\n return 42;\n};\nreturn ''.split(O) === 42;" + }, + { + "name": "Symbol.match", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match", + "exec": "var O = {};\nO[Symbol.match] = function(){\n return 42;\n};\nreturn ''.match(O) === 42;" + }, + { + "name": "Symbol.match, RegExp constructor", + "exec": "var re = /./;\nre[Symbol.match] = false;\nvar foo = {constructor: RegExp};\nfoo[Symbol.match] = true;\nreturn RegExp(re) !== re && RegExp(foo) === foo;" + }, + { + "name": "Symbol.match, String.prototype.startsWith", + "exec": "var re = /./;\ntry {\n '/./'.startsWith(re);\n} catch(e){\n re[Symbol.match] = false;\n return '/./'.startsWith(re);\n}" + }, + { + "name": "Symbol.match, String.prototype.endsWith", + "exec": "var re = /./;\ntry {\n '/./'.endsWith(re);\n} catch(e){\n re[Symbol.match] = false;\n return '/./'.endsWith(re);\n}" + }, + { + "name": "Symbol.match, String.prototype.includes", + "exec": "var re = /./;\ntry {\n '/./'.includes(re);\n} catch(e){\n re[Symbol.match] = false;\n return '/./'.includes(re);\n}" + }, + { + "name": "Symbol.toPrimitive", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive", + "exec": "var a = {}, b = {}, c = {};\nvar passed = 0;\na[Symbol.toPrimitive] = function(hint) { passed += hint === \"number\"; return 0; };\nb[Symbol.toPrimitive] = function(hint) { passed += hint === \"string\"; return 0; };\nc[Symbol.toPrimitive] = function(hint) { passed += hint === \"default\"; return 0; };\n\na >= 0;\nb in {};\nc == 0; // eslint-disable-line eqeqeq\nreturn passed === 3;" + }, + { + "name": "Symbol.toStringTag", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag", + "exec": "var a = {};\na[Symbol.toStringTag] = \"foo\";\nreturn (a + \"\") === \"[object foo]\";" + }, + { + "name": "Symbol.toStringTag affects existing built-ins", + "exec": "var s = Symbol.toStringTag;\nvar passed = true;\n[\n [Array.prototype, []],\n [String.prototype, ''],\n [arguments, arguments],\n [Function.prototype, function(){}],\n [Error.prototype, new Error()],\n [Boolean.prototype, true],\n [Number.prototype, 2],\n [Date.prototype, new Date()],\n [RegExp.prototype, /./]\n].forEach(function(pair){\n pair[0][s] = \"foo\";\n passed &= (Object.prototype.toString.call(pair[1]) === \"[object foo]\");\n delete pair[0][s];\n});\nreturn passed;" + }, + { + "name": "Symbol.toStringTag, new built-ins", + "exec": "var passed = true;\nvar s = Symbol.toStringTag;\n[\n [String, \"String Iterator\"],\n [Array, \"Array Iterator\"],\n [Map, \"Map Iterator\"],\n [Set, \"Set Iterator\"]\n].forEach(function(pair){\n var iterProto = Object.getPrototypeOf(new pair[0]()[Symbol.iterator]());\n passed = passed\n && iterProto.hasOwnProperty(s)\n && iterProto[s] === pair[1];\n});\npassed = passed\n && Object.getPrototypeOf(function*(){})[s] === \"GeneratorFunction\"\n && Object.getPrototypeOf(function*(){}())[s] === \"Generator\"\n && Map.prototype[s] === \"Map\"\n && Set.prototype[s] === \"Set\"\n && ArrayBuffer.prototype[s] === \"ArrayBuffer\"\n && DataView.prototype[s] === \"DataView\"\n && Promise.prototype[s] === \"Promise\"\n && Symbol.prototype[s] === \"Symbol\"\n && typeof Object.getOwnPropertyDescriptor(\n Object.getPrototypeOf(Int8Array).prototype, Symbol.toStringTag).get === \"function\";\n return passed;" + }, + { + "name": "Symbol.toStringTag, misc. built-ins", + "exec": "var s = Symbol.toStringTag;\nreturn Math[s] === \"Math\"\n && JSON[s] === \"JSON\";" + }, + { + "name": "Symbol.unscopables", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables", + "exec": "var a = { foo: 1, bar: 2 };\na[Symbol.unscopables] = { bar: true };\nwith (a) {\n return foo === 1 && typeof bar === \"undefined\";\n}" + } + ] }, { - "name": "String.prototype.replaceAll" + "name": "Object static methods", + "target": "es6", + "category": "built-in extensions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-object-constructor", + "subtests": [ + { + "name": "Object.assign", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign", + "exec": "var o = Object.assign({a:true}, {b:true}, {c:true});\nreturn \"a\" in o && \"b\" in o && \"c\" in o;" + }, + { + "name": "Object.is", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is", + "exec": "return typeof Object.is === 'function' &&\n Object.is(NaN, NaN) &&\n !Object.is(-0, 0);" + }, + { + "name": "Object.getOwnPropertySymbols", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols", + "exec": "var o = {};\nvar sym = Symbol(), sym2 = Symbol(), sym3 = Symbol();\no[sym] = true;\no[sym2] = true;\no[sym3] = true;\nvar result = Object.getOwnPropertySymbols(o);\nreturn result[0] === sym\n && result[1] === sym2\n && result[2] === sym3;" + }, + { + "name": "Object.setPrototypeOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf", + "exec": "return Object.setPrototypeOf({}, Array.prototype) instanceof Array;" + } + ] }, { - "name": "Promise.any" + "name": "function \"name\" property", + "target": "es6", + "category": "built-in extensions", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name", + "subtests": [ + { + "name": "function statements", + "exec": "function foo(){};\nreturn foo.name === 'foo' &&\n (function(){}).name === '';" + }, + { + "name": "function expressions", + "exec": "return (function foo(){}).name === 'foo' &&\n (function(){}).name === '';" + }, + { + "name": "new Function", + "exec": "return (new Function).name === \"anonymous\";" + }, + { + "name": "bound functions", + "exec": "function foo() {};\nreturn foo.bind({}).name === \"bound foo\" &&\n (function(){}).bind({}).name === \"bound \";" + }, + { + "name": "variables (function)", + "exec": "var foo = function() {};\nvar bar = function baz() {};\nreturn foo.name === \"foo\" && bar.name === \"baz\";" + }, + { + "name": "object methods (function)", + "exec": "var o = { foo: function(){}, bar: function baz(){}};\no.qux = function(){};\nreturn o.foo.name === \"foo\" &&\n o.bar.name === \"baz\" &&\n o.qux.name === \"\";" + }, + { + "name": "accessor properties", + "exec": "var o = { get foo(){}, set foo(x){} };\nvar descriptor = Object.getOwnPropertyDescriptor(o, \"foo\");\nreturn descriptor.get.name === \"get foo\" &&\n descriptor.set.name === \"set foo\";" + }, + { + "name": "shorthand methods", + "exec": "var o = { foo(){} };\nreturn o.foo.name === \"foo\";" + }, + { + "name": "shorthand methods (no lexical binding)", + "exec": "var f = \"foo\";\nreturn ({f() { return f; }}).f() === \"foo\";" + }, + { + "name": "symbol-keyed methods", + "exec": "var sym1 = Symbol(\"foo\");\nvar sym2 = Symbol();\nvar o = {\n [sym1]: function(){},\n [sym2]: function(){}\n};\n\nreturn o[sym1].name === \"[foo]\" &&\n o[sym2].name === \"\";" + }, + { + "name": "class statements", + "exec": "class foo {};\nclass bar { static name() {} };\nreturn foo.name === \"foo\" &&\n typeof bar.name === \"function\";" + }, + { + "name": "class expressions", + "exec": "return class foo {}.name === \"foo\" &&\n typeof class bar { static name() {} }.name === \"function\";" + }, + { + "name": "variables (class)", + "exec": "var foo = class {};\nvar bar = class baz {};\nvar qux = class { static name() {} };\nreturn foo.name === \"foo\" &&\n bar.name === \"baz\" &&\n typeof qux.name === \"function\";" + }, + { + "name": "object methods (class)", + "exec": "var o = { foo: class {}, bar: class baz {}};\no.qux = class {};\nreturn o.foo.name === \"foo\" &&\n o.bar.name === \"baz\" &&\n o.qux.name === \"\";" + }, + { + "name": "class prototype methods", + "exec": "class C { foo(){} };\nreturn (new C).foo.name === \"foo\";" + }, + { + "name": "class static methods", + "exec": "class C { static foo(){} };\nreturn C.foo.name === \"foo\";" + }, + { + "name": "isn't writable, is configurable", + "exec": "var descriptor = Object.getOwnPropertyDescriptor(function f(){},\"name\");\nreturn descriptor.enumerable === false &&\n descriptor.writable === false &&\n descriptor.configurable === true;" + } + ] }, { - "name": "WeakReferences" + "name": "String static methods", + "target": "es6", + "category": "built-in extensions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-string-constructor", + "subtests": [ + { + "name": "String.raw", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw", + "exec": "return typeof String.raw === 'function';" + }, + { + "name": "String.fromCodePoint", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint", + "exec": "return typeof String.fromCodePoint === 'function';" + } + ] }, { - "name": "Logical Assignment" + "name": "String.prototype methods", + "target": "es6", + "category": "built-in extensions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-string-prototype-object", + "subtests": [ + { + "name": "String.prototype.codePointAt", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt", + "exec": "return typeof String.prototype.codePointAt === 'function';" + }, + { + "name": "String.prototype.normalize", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize", + "exec": "return typeof String.prototype.normalize === \"function\"\n && \"c\\u0327\\u0301\".normalize(\"NFC\") === \"\\u1e09\"\n && \"\\u1e09\".normalize(\"NFD\") === \"c\\u0327\\u0301\";" + }, + { + "name": "String.prototype.repeat", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat", + "exec": "return typeof String.prototype.repeat === 'function'\n && \"foo\".repeat(3) === \"foofoofoo\";" + }, + { + "name": "String.prototype.startsWith", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith", + "exec": "return typeof String.prototype.startsWith === 'function'\n && \"foobar\".startsWith(\"foo\");" + }, + { + "name": "String.prototype.startsWith throws on RegExp", + "exec": "try {\n \"a\".startsWith(/./);\n} catch(e) {\n return typeof String.prototype.startsWith === 'function';\n}" + }, + { + "name": "String.prototype.endsWith", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith", + "exec": "return typeof String.prototype.endsWith === 'function'\n && \"foobar\".endsWith(\"bar\");" + }, + { + "name": "String.prototype.endsWith throws on RegExp", + "exec": "try {\n \"a\".endsWith(/./);\n} catch(e) {\n return typeof String.prototype.endsWith === 'function';\n}" + }, + { + "name": "String.prototype.includes", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes", + "exec": "return typeof String.prototype.includes === 'function'\n && \"foobar\".includes(\"oba\");" + }, + { + "name": "String.prototype[Symbol.iterator]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator", + "exec": "return typeof String.prototype[Symbol.iterator] === 'function';" + }, + { + "name": "String iterator prototype chain", + "exec": "// Iterator instance\nvar iterator = ''[Symbol.iterator]();\n// %StringIteratorPrototype%\nvar proto1 = Object.getPrototypeOf(iterator);\n// %IteratorPrototype%\nvar proto2 = Object.getPrototypeOf(proto1);\n\nreturn proto2.hasOwnProperty(Symbol.iterator) &&\n !proto1 .hasOwnProperty(Symbol.iterator) &&\n !iterator .hasOwnProperty(Symbol.iterator) &&\n iterator[Symbol.iterator]() === iterator;" + } + ] }, { - "name": "numeric separators" + "name": "RegExp.prototype properties", + "target": "es6", + "category": "built-in extensions", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype", + "subtests": [ + { + "name": "RegExp.prototype.flags", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags", + "exec": "return /./igm.flags === \"gim\" && /./.flags === \"\";" + }, + { + "name": "RegExp.prototype[Symbol.match]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match", + "exec": "return typeof RegExp.prototype[Symbol.match] === 'function';" + }, + { + "name": "RegExp.prototype[Symbol.replace]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@replace", + "exec": "return typeof RegExp.prototype[Symbol.replace] === 'function';" + }, + { + "name": "RegExp.prototype[Symbol.split]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@split", + "exec": "return typeof RegExp.prototype[Symbol.split] === 'function';" + }, + { + "name": "RegExp.prototype[Symbol.search]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@search", + "exec": "return typeof RegExp.prototype[Symbol.search] === 'function';" + }, + { + "name": "RegExp[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@species", + "exec": "var prop = Object.getOwnPropertyDescriptor(RegExp, Symbol.species);\nreturn 'get' in prop && RegExp[Symbol.species] === RegExp;" + } + ] }, { - "name": "instance class fields" + "name": "Array static methods", + "target": "es6", + "category": "built-in extensions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-array-constructor", + "subtests": [ + { + "name": "Array.from, array-like objects", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Array_from_an_Array-like_object_(arguments)", + "exec": "return Array.from({ 0: \"foo\", 1: \"bar\", length: 2 }) + '' === \"foo,bar\";" + }, + { + "name": "Array.from, generator instances", + "exec": "var iterable = (function*(){ yield 1; yield 2; yield 3; }());\nreturn Array.from(iterable) + '' === \"1,2,3\";" + }, + { + "name": "Array.from, generic iterables", + "exec": "var iterable = global.__createIterableObject([1, 2, 3]);\nreturn Array.from(iterable) + '' === \"1,2,3\";" + }, + { + "name": "Array.from, instances of generic iterables", + "exec": "var iterable = global.__createIterableObject([1, 2, 3]);\nreturn Array.from(Object.create(iterable)) + '' === \"1,2,3\";" + }, + { + "name": "Array.from map function, array-like objects", + "exec": "return Array.from({ 0: \"foo\", 1: \"bar\", length: 2 }, function(e, i) {\n return e + this.baz + i;\n}, { baz: \"d\" }) + '' === \"food0,bard1\";" + }, + { + "name": "Array.from map function, generator instances", + "exec": "var iterable = (function*(){ yield \"foo\"; yield \"bar\"; yield \"bal\"; }());\nreturn Array.from(iterable, function(e, i) {\n return e + this.baz + i;\n}, { baz: \"d\" }) + '' === \"food0,bard1,bald2\";" + }, + { + "name": "Array.from map function, generic iterables", + "exec": "var iterable = global.__createIterableObject([\"foo\", \"bar\", \"bal\"]);\nreturn Array.from(iterable, function(e, i) {\n return e + this.baz + i;\n}, { baz: \"d\" }) + '' === \"food0,bard1,bald2\";" + }, + { + "name": "Array.from map function, instances of iterables", + "exec": "var iterable = global.__createIterableObject([\"foo\", \"bar\", \"bal\"]);\nreturn Array.from(Object.create(iterable), function(e, i) {\n return e + this.baz + i;\n}, { baz: \"d\" }) + '' === \"food0,bard1,bald2\";" + }, + { + "name": "Array.from, iterator closing", + "exec": "var closed = false;\nvar iter = global.__createIterableObject([1, 2, 3], {\n 'return': function(){ closed = true; return {}; }\n});\ntry {\n Array.from(iter, function() { throw 42 });\n} catch(e){}\nreturn closed;" + }, + { + "name": "Array.of", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of", + "exec": "return typeof Array.of === 'function' &&\n Array.of(2)[0] === 2;" + }, + { + "name": "Array[Symbol.species]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species", + "exec": "var prop = Object.getOwnPropertyDescriptor(Array, Symbol.species);\nreturn 'get' in prop && Array[Symbol.species] === Array;" + } + ] }, { - "name": "static class fields" + "name": "Array.prototype methods", + "target": "es6", + "category": "built-in extensions", + "significance": "medium", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-array-prototype-object", + "subtests": [ + { + "name": "Array.prototype.copyWithin", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin", + "exec": "return typeof Array.prototype.copyWithin === 'function';" + }, + { + "name": "Array.prototype.find", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find", + "exec": "return typeof Array.prototype.find === 'function';" + }, + { + "name": "Array.prototype.findIndex", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex", + "exec": "return typeof Array.prototype.findIndex === 'function';" + }, + { + "name": "Array.prototype.fill", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill", + "exec": "return typeof Array.prototype.fill === 'function';" + }, + { + "name": "Array.prototype.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys", + "exec": "return typeof Array.prototype.keys === 'function';" + }, + { + "name": "Array.prototype.values", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values", + "exec": "return typeof Array.prototype.values === 'function';" + }, + { + "name": "Array.prototype.entries", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries", + "exec": "return typeof Array.prototype.entries === 'function';" + }, + { + "name": "Array.prototype.splice", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice", + "exec": "if ([0, 1, 2].splice(0).length !== 3) {\n // IE <= 8 and other pre-ES6 engines fail this check\n return false;\n}\n\nvar a = [1, 2];\nvar result = a.splice();\nif (a.length !== 2 || result.length !== 0) {\n // Safari 5.0 has this bug\n return false;\n}\n\nvar obj = {};\nArray.prototype.splice.call(obj, 0, 0, 1);\nif (obj.length !== 1) {\n return false;\n}\n\nvar spliceWorksWithLargeSparseArrays = (function () {\n // Per https://github.com/es-shims/es5-shim/issues/295\n // Safari 7/8 breaks with sparse arrays of size 1e5 or greater\n var arr = new Array(1e5);\n // note: the index MUST be 8 or larger or the test will false pass\n arr[8] = 'x';\n arr.splice(1, 1);\n for (var i = 0; i < arr.length; i += 1) {\n if (arr[i] === 'x') {\n return i === 7;\n }\n }\n return false;\n}());\nvar spliceWorksWithSmallSparseArrays = (function () {\n // Per https://github.com/es-shims/es5-shim/issues/295\n // Opera 12.15 breaks on this, no idea why.\n var n = 256;\n var arr = [];\n arr[n] = 'a';\n arr.splice(n + 1, 0, 'b');\n return arr[n] === 'a';\n}());\n\nreturn spliceWorksWithLargeSparseArrays && spliceWorksWithSmallSparseArrays;" + }, + { + "name": "Array.prototype[Symbol.iterator]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator", + "exec": "return typeof Array.prototype[Symbol.iterator] === 'function';" + }, + { + "name": "Array iterator prototype chain", + "exec": "// Iterator instance\nvar iterator = [][Symbol.iterator]();\n// %ArrayIteratorPrototype%\nvar proto1 = Object.getPrototypeOf(iterator);\n// %IteratorPrototype%\nvar proto2 = Object.getPrototypeOf(proto1);\n\nreturn proto2.hasOwnProperty(Symbol.iterator) &&\n !proto1 .hasOwnProperty(Symbol.iterator) &&\n !iterator .hasOwnProperty(Symbol.iterator) &&\n iterator[Symbol.iterator]() === iterator;" + }, + { + "name": "Array.prototype[Symbol.unscopables]", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables", + "exec": "var unscopables = Array.prototype[Symbol.unscopables];\nif (!unscopables) {\n return false;\n}\nvar ns = \"find,findIndex,fill,copyWithin,entries,keys,values\".split(\",\");\nfor (var i = 0; i < ns.length; i++) {\n if (Array.prototype[ns[i]] && !unscopables[ns[i]]) return false;\n}\nreturn true;" + } + ] }, { - "name": "private class methods" + "name": "Number properties", + "target": "es6", + "category": "built-in extensions", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-isfinite-number", + "subtests": [ + { + "name": "Number.isFinite", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite", + "exec": "return typeof Number.isFinite === 'function';" + }, + { + "name": "Number.isInteger", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger", + "exec": "return typeof Number.isInteger === 'function';" + }, + { + "name": "Number.isSafeInteger", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger", + "exec": "return typeof Number.isSafeInteger === 'function';" + }, + { + "name": "Number.isNaN", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN", + "exec": "return typeof Number.isNaN === 'function';" + }, + { + "name": "Number.parseFloat", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat", + "exec": "var actualGlobal = Function('return this')();\nreturn typeof Number.parseFloat === 'function'\n && Number.parseFloat === actualGlobal.parseFloat;" + }, + { + "name": "Number.parseInt", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseInt", + "exec": "var actualGlobal = Function('return this')();\nreturn typeof Number.parseInt === 'function'\n && Number.parseInt === actualGlobal.parseInt;" + }, + { + "name": "Number.EPSILON", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON", + "exec": "return typeof Number.EPSILON === 'number';" + }, + { + "name": "Number.MIN_SAFE_INTEGER", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER", + "exec": "return typeof Number.MIN_SAFE_INTEGER === 'number';" + }, + { + "name": "Number.MAX_SAFE_INTEGER", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER", + "exec": "return typeof Number.MAX_SAFE_INTEGER === 'number';" + } + ] }, { - "name": "Ergonomic brand checks for private fields" + "name": "Math methods", + "target": "es6", + "category": "built-in extensions", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-math", + "subtests": [ + { + "name": "Math.clz32", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32", + "exec": "return typeof Math.clz32 === \"function\";" + }, + { + "name": "Math.imul", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul", + "exec": "return typeof Math.imul === \"function\";" + }, + { + "name": "Math.sign", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign", + "exec": "return typeof Math.sign === \"function\";" + }, + { + "name": "Math.log10", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10", + "exec": "return typeof Math.log10 === \"function\";" + }, + { + "name": "Math.log2", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2", + "exec": "return typeof Math.log2 === \"function\";" + }, + { + "name": "Math.log1p", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p", + "exec": "return typeof Math.log1p === \"function\";" + }, + { + "name": "Math.expm1", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1", + "exec": "return typeof Math.expm1 === \"function\";" + }, + { + "name": "Math.cosh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh", + "exec": "return typeof Math.cosh === \"function\";" + }, + { + "name": "Math.sinh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh", + "exec": "return typeof Math.sinh === \"function\";" + }, + { + "name": "Math.tanh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh", + "exec": "return typeof Math.tanh === \"function\";" + }, + { + "name": "Math.acosh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh", + "exec": "return typeof Math.acosh === \"function\";" + }, + { + "name": "Math.asinh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh", + "exec": "return typeof Math.asinh === \"function\";" + }, + { + "name": "Math.atanh", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh", + "exec": "return typeof Math.atanh === \"function\";" + }, + { + "name": "Math.trunc", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc", + "exec": "return typeof Math.trunc === \"function\";" + }, + { + "name": "Math.fround", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround", + "exec": "return typeof Math.fround === \"function\";" + }, + { + "name": "Math.cbrt", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt", + "exec": "return typeof Math.cbrt === \"function\";" + }, + { + "name": "Math.hypot", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot", + "exec": "return Math.hypot() === 0 &&\n Math.hypot(1) === 1 &&\n Math.hypot(9, 12, 20) === 25 &&\n Math.hypot(27, 36, 60, 100) === 125;" + } + ] }, { - "name": ".at() method on the built-in indexables" + "name": "Date.prototype[Symbol.toPrimitive]", + "target": "es6", + "category": "built-in extensions", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive", + "exec": "var tp = Date.prototype[Symbol.toPrimitive];\nreturn tp.call(Object(2), \"number\") === 2\n && tp.call(Object(2), \"string\") === \"2\"\n && tp.call(Object(2), \"default\") === \"2\";" }, { - "name": "Object.hasOwn" + "name": "Array is subclassable", + "target": "es6", + "category": "subclassing", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-array-constructor", + "subtests": [ + { + "name": "length property (accessing)", + "exec": "class C extends Array {}\nvar c = new C();\nvar len1 = c.length;\nc[2] = 'foo';\nvar len2 = c.length;\nreturn len1 === 0 && len2 === 3;" + }, + { + "name": "length property (setting)", + "exec": "class C extends Array {}\nvar c = new C();\nc[2] = 'foo';\nc.length = 1;\nreturn c.length === 1 && !(2 in c);" + }, + { + "name": "correct prototype chain", + "exec": "class C extends Array {}\nvar c = new C();\nreturn c instanceof C && c instanceof Array && Object.getPrototypeOf(C) === Array;" + }, + { + "name": "Array.isArray support", + "exec": "class C extends Array {}\nreturn Array.isArray(new C());" + }, + { + "name": "Array.prototype.concat", + "exec": "class C extends Array {}\nvar c = new C();\nreturn c.concat(1) instanceof C;" + }, + { + "name": "Array.prototype.filter", + "exec": "class C extends Array {}\nvar c = new C();\nreturn c.filter(Boolean) instanceof C;" + }, + { + "name": "Array.prototype.map", + "exec": "class C extends Array {}\nvar c = new C();\nreturn c.map(Boolean) instanceof C;" + }, + { + "name": "Array.prototype.slice", + "exec": "class C extends Array {}\nvar c = new C();\nc.push(2,4,6);\nreturn c.slice(1,2) instanceof C;" + }, + { + "name": "Array.prototype.splice", + "exec": "class C extends Array {}\nvar c = new C();\nc.push(2,4,6);\nreturn c.splice(1,2) instanceof C;" + }, + { + "name": "Array.from", + "exec": "class C extends Array {}\nreturn C.from({ length: 0 }) instanceof C;" + }, + { + "name": "Array.of", + "exec": "class C extends Array {}\nreturn C.of(0) instanceof C;" + } + ] }, { - "name": "Class static initialization blocks" + "name": "RegExp is subclassable", + "target": "es6", + "category": "subclassing", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-regexp-constructor", + "subtests": [ + { + "name": "basic functionality", + "exec": "class R extends RegExp {}\nvar r = new R(\"baz\",\"g\");\nreturn r.global && r.source === \"baz\";" + }, + { + "name": "correct prototype chain", + "exec": "class R extends RegExp {}\nvar r = new R(\"baz\",\"g\");\nreturn r instanceof R && r instanceof RegExp && Object.getPrototypeOf(R) === RegExp;" + }, + { + "name": "RegExp.prototype.exec", + "exec": "class R extends RegExp {}\nvar r = new R(\"baz\",\"g\");\nreturn r.exec(\"foobarbaz\")[0] === \"baz\" && r.lastIndex === 9;" + }, + { + "name": "RegExp.prototype.test", + "exec": "class R extends RegExp {}\nvar r = new R(\"baz\");\nreturn r.test(\"foobarbaz\");" + } + ] }, { - "name": "Error.cause property" + "name": "Function is subclassable", + "target": "es6", + "category": "subclassing", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-function-constructor", + "subtests": [ + { + "name": "can be called", + "exec": "class C extends Function {}\nvar c = new C(\"return 'foo';\");\nreturn c() === 'foo';" + }, + { + "name": "correct prototype chain", + "exec": "class C extends Function {}\nvar c = new C(\"return 'foo';\");\nreturn c instanceof C && c instanceof Function && Object.getPrototypeOf(C) === Function;" + }, + { + "name": "can be used with \"new\"", + "exec": "class C extends Function {}\nvar c = new C(\"this.bar = 2;\");\nc.prototype.baz = 3;\nreturn new c().bar === 2 && new c().baz === 3;" + }, + { + "name": "Function.prototype.call", + "exec": "class C extends Function {}\nvar c = new C(\"x\", \"return this.bar + x;\");\nreturn c.call({bar:1}, 2) === 3;" + }, + { + "name": "Function.prototype.apply", + "exec": "class C extends Function {}\nvar c = new C(\"x\", \"return this.bar + x;\");\nreturn c.apply({bar:1}, [2]) === 3;" + }, + { + "name": "Function.prototype.bind", + "exec": "class C extends Function {}\nvar c = new C(\"x\", \"y\", \"return this.bar + x + y;\").bind({bar:1}, 2);\nreturn c(6) === 9 && c instanceof C;" + } + ] }, { - "name": "RegExp Match Indices (`hasIndices` / `d` flag)" + "name": "Promise is subclassable", + "target": "es6", + "category": "subclassing", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-function-constructor", + "subtests": [ + { + "name": "basic functionality", + "exec": "class P extends Promise {}\nvar p1 = new P(function(resolve, reject) { resolve(\"foo\"); });\nvar p2 = new P(function(resolve, reject) { reject(\"quux\"); });\nvar score = +(p1 instanceof P);\n\nfunction thenFn(result) { score += (result === \"foo\"); check(); }\nfunction catchFn(result) { score += (result === \"quux\"); check(); }\nfunction shouldNotRun(result) { score = -Infinity; }\n\np1.then(thenFn, shouldNotRun);\np2.then(shouldNotRun, catchFn);\np1.catch(shouldNotRun);\np2.catch(catchFn);\n\np1.then(function() {\n // P.prototype.then() should return a new P\n score += p1.then() instanceof P && p1.then() !== p1;\n check();\n});\n\nfunction check() {\n if (score === 5) asyncTestPassed();\n}" + }, + { + "name": "correct prototype chain", + "exec": "class C extends Promise {}\nvar c = new C(function(resolve, reject) { resolve(\"foo\"); });\nreturn c instanceof C && c instanceof Promise && Object.getPrototypeOf(C) === Promise;" + }, + { + "name": "Promise.all", + "exec": "class P extends Promise {}\nvar fulfills = P.all([\n new Promise(function(resolve) { setTimeout(resolve,2000,\"foo\"); }),\n new Promise(function(resolve) { setTimeout(resolve,1000,\"bar\"); })\n]);\nvar rejects = P.all([\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"baz\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"qux\"); })\n]);\nvar score = +(fulfills instanceof P);\nfulfills.then(function(result) { score += (result + \"\" === \"foo,bar\"); check(); });\nrejects.catch(function(result) { score += (result === \"qux\"); check(); });\n\nfunction check() {\n if (score === 3) asyncTestPassed();\n}" + }, + { + "name": "Promise.race", + "exec": "class P extends Promise {}\nvar fulfills = P.race([\n new Promise(function(resolve) { setTimeout(resolve,1000,\"foo\"); }),\n new Promise(function(_, reject) { setTimeout(reject, 2000,\"bar\"); })\n]);\nvar rejects = P.race([\n new Promise(function(_, reject) { setTimeout(reject, 1000,\"baz\"); }),\n new Promise(function(resolve) { setTimeout(resolve,2000,\"qux\"); })\n]);\nvar score = +(fulfills instanceof P);\nfulfills.then(function(result) { score += (result === \"foo\"); check(); });\nrejects.catch(function(result) { score += (result === \"baz\"); check(); });\n\nfunction check() {\n if (score === 3) asyncTestPassed();\n}" + } + ] }, { - "name": "Array find from last" + "name": "miscellaneous subclassables", + "target": "es6", + "category": "subclassing", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-boolean-constructor", + "subtests": [ + { + "name": "Boolean is subclassable", + "exec": "class C extends Boolean {}\nvar c = new C(true);\nreturn c instanceof Boolean\n && c instanceof C\n && c == true; // eslint-disable-line eqeqeq" + }, + { + "name": "Number is subclassable", + "exec": "class C extends Number {}\nvar c = new C(6);\nreturn c instanceof Number\n && c instanceof C\n && +c === 6;" + }, + { + "name": "String is subclassable", + "exec": "class C extends String {}\nvar c = new C(\"golly\");\nreturn c instanceof String\n && c instanceof C\n && c + '' === \"golly\"\n && c[0] === \"g\"\n && c.length === 5;" + }, + { + "name": "Error is subclassable", + "exec": "class C extends Error {}\nvar c = new C();\nreturn c instanceof Error\n && c instanceof C\n && Object.prototype.toString.call(c) === \"[object Error]\";" + }, + { + "name": "Map is subclassable", + "exec": "var key = {};\nclass M extends Map {}\nvar map = new M();\n\nmap.set(key, 123);\n\nreturn map instanceof M && map.has(key) && map.get(key) === 123;" + }, + { + "name": "Set is subclassable", + "exec": "var obj = {};\nclass S extends Set {}\nvar set = new S();\n\nset.add(123);\nset.add(123);\n\nreturn set instanceof S && set.has(123);" + } + ] }, { - "name": "Hashbang Grammar" + "name": "prototype of bound functions", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-boundfunctioncreate", + "subtests": [ + { + "name": "basic functions", + "exec": "function correctProtoBound(proto) {\n var f = function(){};\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(f, proto);\n } else {\n f.__proto__ = proto;\n }\n var boundF = Function.prototype.bind.call(f, null);\n return Object.getPrototypeOf(boundF) === proto;\n}\nreturn correctProtoBound(Function.prototype)\n && correctProtoBound({})\n && correctProtoBound(null);" + }, + { + "name": "generator functions", + "exec": "function correctProtoBound(proto) {\n var f = function*(){};\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(f, proto);\n } else {\n f.__proto__ = proto;\n }\n var boundF = Function.prototype.bind.call(f, null);\n return Object.getPrototypeOf(boundF) === proto;\n}\nreturn correctProtoBound(Function.prototype)\n && correctProtoBound({})\n && correctProtoBound(null);" + }, + { + "name": "arrow functions", + "exec": "function correctProtoBound(proto) {\n var f = ()=>5;\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(f, proto);\n } else {\n f.__proto__ = proto;\n }\n var boundF = Function.prototype.bind.call(f, null);\n return Object.getPrototypeOf(boundF) === proto;\n}\nreturn correctProtoBound(Function.prototype)\n && correctProtoBound({})\n && correctProtoBound(null);" + }, + { + "name": "classes", + "exec": "function correctProtoBound(proto) {\n class C {}\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(C, proto);\n } else {\n C.__proto__ = proto;\n }\n var boundF = Function.prototype.bind.call(C, null);\n return Object.getPrototypeOf(boundF) === proto;\n}\nreturn correctProtoBound(Function.prototype)\n && correctProtoBound({})\n && correctProtoBound(null);" + }, + { + "name": "subclasses", + "exec": "function correctProtoBound(superclass) {\n class C extends superclass {\n constructor() {\n return Object.create(null);\n }\n }\n var boundF = Function.prototype.bind.call(C, null);\n return Object.getPrototypeOf(boundF) === Object.getPrototypeOf(C);\n}\nreturn correctProtoBound(function(){})\n && correctProtoBound(Array)\n && correctProtoBound(null);" + } + ] }, { - "name": "Change Array by copy" + "name": "Proxy, internal 'get' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get", + "subtests": [ + { + "name": "ToPrimitive", + "exec": "// ToPrimitive -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({toString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});\np + 3;\nreturn get[0] === Symbol.toPrimitive && get.slice(1) + '' === \"valueOf,toString\";" + }, + { + "name": "CreateListFromArrayLike", + "exec": "// CreateListFromArrayLike -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({length:2, 0:0, 1:0}, { get: function(o, k) { get.push(k); return o[k]; }});\nFunction.prototype.apply({}, p);\nreturn get + '' === \"length,0,1\";" + }, + { + "name": "instanceof operator", + "exec": "// InstanceofOperator -> GetMethod -> GetV -> [[Get]]\n// InstanceofOperator -> OrdinaryHasInstance -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});\n({}) instanceof p;\nreturn get[0] === Symbol.hasInstance && get.slice(1) + '' === \"prototype\";" + }, + { + "name": "HasBinding", + "exec": "// HasBinding -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({foo:1}, { get: function(o, k) { get.push(k); return o[k]; }});\np[Symbol.unscopables] = p;\nwith(p) {\n typeof foo;\n}\nreturn get[0] === Symbol.unscopables && get.slice(1) + '' === \"foo\";" + }, + { + "name": "CreateDynamicFunction", + "exec": "// CreateDynamicFunction -> GetPrototypeFromConstructor -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy(Function, { get: function(o, k) { get.push(k); return o[k]; }});\nnew p;\nreturn get + '' === \"prototype\";" + }, + { + "name": "ClassDefinitionEvaluation", + "exec": "// ClassDefinitionEvaluation -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});\nclass C extends p {}\nreturn get + '' === \"prototype\";" + }, + { + "name": "IteratorComplete, IteratorValue", + "exec": "// IteratorComplete -> Get -> [[Get]]\n// IteratorValue -> Get -> [[Get]]\nvar get = [];\nvar iterable = {};\niterable[Symbol.iterator] = function() {\n return {\n next: function() {\n return new Proxy({ value: 2, done: false }, { get: function(o, k) { get.push(k); return o[k]; }});\n }\n };\n}\nvar i = 0;\nfor(var e of iterable) {\n if (++i >= 2) break;\n}\nreturn get + '' === \"done,value,done,value\";" + }, + { + "name": "ToPropertyDescriptor", + "exec": "// ToPropertyDescriptor -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({\n enumerable: true, configurable: true, value: true,\n writable: true, get: Function(), set: Function()\n }, { get: function(o, k) { get.push(k); return o[k]; }});\ntry {\n // This will throw, since it will have true for both \"get\" and \"value\",\n // but not before performing a Get on every property.\n Object.defineProperty({}, \"foo\", p);\n} catch(e) {\n return get + '' === \"enumerable,configurable,value,writable,get,set\";\n}" + }, + { + "name": "Object.assign", + "exec": "// Object.assign -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({foo:1, bar:2}, { get: function(o, k) { get.push(k); return o[k]; }});\nObject.assign({}, p);\nreturn get + '' === \"foo,bar\";" + }, + { + "name": "Object.defineProperties", + "exec": "// Object.defineProperties -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({foo:{}, bar:{}}, { get: function(o, k) { get.push(k); return o[k]; }});\nObject.defineProperties({}, p);\nreturn get + '' === \"foo,bar\";" + }, + { + "name": "Function.prototype.bind", + "exec": "// Function.prototype.bind -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});\nFunction.prototype.bind.call(p);\nreturn get + '' === \"length,name\";" + }, + { + "name": "Error.prototype.toString", + "exec": "// Error.prototype.toString -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});\nError.prototype.toString.call(p);\nreturn get + '' === \"name,message\";" + }, + { + "name": "String.raw", + "exec": "// String.raw -> Get -> [[Get]]\nvar get = [];\nvar raw = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});\nvar p = new Proxy({raw: raw}, { get: function(o, k) { get.push(k); return o[k]; }});\nString.raw(p);\nreturn get + '' === \"raw,length,0,1\";" + }, + { + "name": "RegExp constructor", + "exec": "// RegExp -> Get -> [[Get]]\nvar get = [];\nvar re = { constructor: null };\nre[Symbol.match] = true;\nvar p = new Proxy(re, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp(p);\nreturn get[0] === Symbol.match && get.slice(1) + '' === \"constructor,source,flags\";" + }, + { + "name": "RegExp.prototype.flags", + "exec": "// RegExp.prototype.flags -> Get -> [[Get]]\nvar expected = [];\n// Sorted alphabetically by shortname – \"gimsuy\".\nif ('hasIndices' in RegExp.prototype) expected.push('hasIndices');\nif ('global' in RegExp.prototype) expected.push('global');\nif ('ignoreCase' in RegExp.prototype) expected.push('ignoreCase');\nif ('multiline' in RegExp.prototype) expected.push('multiline');\nif ('dotAll' in RegExp.prototype) expected.push('dotAll');\nif ('unicode' in RegExp.prototype) expected.push('unicode');\nif ('unicodeSets' in RegExp.prototype) expected.push('unicodeSets');\nif ('sticky' in RegExp.prototype) expected.push('sticky');\n\nvar actual = [];\nvar p = new Proxy({}, { get: function(o, k) { actual.push(k); return o[k]; }});\nObject.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(p);\nif (expected.length !== actual.length) return false;\nfor (var i = 0; i < expected.length; i++) {\n if (expected[i] !== actual[i]) return false;\n}\nreturn true;" + }, + { + "name": "RegExp.prototype.test", + "exec": "// RegExp.prototype.test -> RegExpExec -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype.test.call(p);\nreturn get + '' === \"exec\";" + }, + { + "name": "RegExp.prototype.toString", + "exec": "// RegExp.prototype.toString -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype.toString.call(p);\nreturn get + '' === \"source,flags\";" + }, + { + "name": "RegExp.prototype[Symbol.match]", + "exec": "// RegExp.prototype[Symbol.match] -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype[Symbol.match].call(p);\np.global = true;\nRegExp.prototype[Symbol.match].call(p);\nvar str = get + '';\nreturn str === \"global,exec,global,unicode,exec\" || str === 'flags,exec,flags,exec';" + }, + { + "name": "RegExp.prototype[Symbol.replace]", + "exec": "// RegExp.prototype[Symbol.replace] -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype[Symbol.replace].call(p);\np.global = true;\nRegExp.prototype[Symbol.replace].call(p);\nvar str = get + '';\nreturn str === \"global,exec,global,unicode,exec\" || str === 'flags,exec,flags,exec';" + }, + { + "name": "RegExp.prototype[Symbol.search]", + "exec": "// RegExp.prototype[Symbol.search] -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype[Symbol.search].call(p);\nreturn get + '' === \"lastIndex,exec,lastIndex\";" + }, + { + "name": "RegExp.prototype[Symbol.split]", + "exec": "// RegExp.prototype[Symbol.split] -> Get -> [[Get]]\nvar get = [];\nvar constructor = Function();\nconstructor[Symbol.species] = Object;\nvar p = new Proxy({ constructor: constructor, flags: '', exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});\nRegExp.prototype[Symbol.split].call(p, \"\");\nreturn get + '' === \"constructor,flags,exec\";" + }, + { + "name": "Array.from", + "exec": "// Array.from -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});\nArray.from(p);\nreturn get[0] === Symbol.iterator && get.slice(1) + '' === \"length,0,1\";" + }, + { + "name": "Array.prototype.concat", + "exec": "// Array.prototype.concat -> Get -> [[Get]]\nvar get = [];\nvar arr = [1];\narr.constructor = void undefined;\nvar p = new Proxy(arr, { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.concat.call(p,p);\nreturn get[0] === \"constructor\"\n && get[1] === Symbol.isConcatSpreadable\n && get[2] === \"length\"\n && get[3] === \"0\"\n && get[4] === get[1] && get[5] === get[2] && get[6] === get[3]\n && get.length === 7;" + }, + { + "name": "Array.prototype iteration methods", + "exec": "// Array.prototype methods -> Get -> [[Get]]\nvar methods = ['copyWithin', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach',\n 'indexOf', 'join', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'some'];\nvar get;\nvar p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});\nfor(var i = 0; i < methods.length; i+=1) {\n get = [];\n Array.prototype[methods[i]].call(p, Function());\n if (get + '' !== (\n methods[i] === 'fill' ? \"length\" :\n methods[i] === 'every' ? \"length,0\" :\n methods[i] === 'lastIndexOf' || methods[i] === 'reduceRight' ? \"length,1,0\" :\n \"length,0,1\"\n )) {\n return false;\n }\n}\nreturn true;" + }, + { + "name": "Array.prototype.pop", + "exec": "// Array.prototype.pop -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.pop.call(p);\nreturn get + '' === \"length,3\";" + }, + { + "name": "Array.prototype.reverse", + "exec": "// Array.prototype.reverse -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy([0,,2,,4,,], { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.reverse.call(p);\nreturn get + '' === \"length,0,4,2\";" + }, + { + "name": "Array.prototype.shift", + "exec": "// Array.prototype.shift -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.shift.call(p);\nreturn get + '' === \"length,0,1,2,3\";" + }, + { + "name": "Array.prototype.splice", + "exec": "// Array.prototype.splice -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.splice.call(p,1,1);\nArray.prototype.splice.call(p,1,0,1);\nreturn get + '' === \"length,constructor,1,2,3,length,constructor,2,1\";" + }, + { + "name": "Array.prototype.toString", + "exec": "// Array.prototype.toString -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({ join:Function() }, { get: function(o, k) { get.push(k); return o[k]; }});\nArray.prototype.toString.call(p);\nreturn get + '' === \"join\";" + }, + { + "name": "JSON.stringify", + "exec": "// JSON.stringify -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});\nJSON.stringify(p);\nreturn get + '' === \"toJSON\";" + }, + { + "name": "Promise resolve functions", + "exec": "// Promise resolve functions -> Get -> [[Get]]\nvar get = [];\nvar p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});\nnew Promise(function(resolve){ resolve(p); });\nreturn get + '' === \"then\";" + }, + { + "name": "String.prototype.match", + "exec": "// String.prototype.match -> Get -> [[Get]]\nvar get = [];\nvar proxied = {};\nproxied[Symbol.toPrimitive] = Function();\nvar p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});\n\"\".match(p);\nreturn get[0] === Symbol.match && get[1] === Symbol.toPrimitive && get.length === 2;" + }, + { + "name": "String.prototype.replace", + "exec": "// String.prototype.replace functions -> Get -> [[Get]]\nvar get = [];\nvar proxied = {};\nproxied[Symbol.toPrimitive] = Function();\nvar p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});\n\"\".replace(p);\nreturn get[0] === Symbol.replace && get[1] === Symbol.toPrimitive && get.length === 2;" + }, + { + "name": "String.prototype.search", + "exec": "// String.prototype.search functions -> Get -> [[Get]]\nvar get = [];\nvar proxied = {};\nproxied[Symbol.toPrimitive] = Function();\nvar p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});\n\"\".search(p);\nreturn get[0] === Symbol.search && get[1] === Symbol.toPrimitive && get.length === 2;" + }, + { + "name": "String.prototype.split", + "exec": "// String.prototype.split functions -> Get -> [[Get]]\nvar get = [];\nvar proxied = {};\nproxied[Symbol.toPrimitive] = Function();\nvar p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});\n\"\".split(p);\nreturn get[0] === Symbol.split && get[1] === Symbol.toPrimitive && get.length === 2;" + }, + { + "name": "Date.prototype.toJSON", + "exec": "// Date.prototype.toJSON -> ToPrimitive -> Get -> [[Get]]\n// Date.prototype.toJSON -> Invoke -> GetMethod -> GetV -> [[Get]]\nvar get = [];\nvar p = new Proxy({toString:Function(),toISOString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});\nDate.prototype.toJSON.call(p);\nreturn get[0] === Symbol.toPrimitive && get.slice(1) + '' === \"valueOf,toString,toISOString\";" + } + ] }, { - "name": "RegExp `v` flag" + "name": "Proxy, internal 'set' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set", + "subtests": [ + { + "name": "Object.assign", + "exec": "// Object.assign -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\nObject.assign(p, { foo: 1, bar: 2 });\nreturn set + '' === \"foo,bar\";" + }, + { + "name": "Array.from", + "exec": "// Array.from -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\nArray.from.call(function(){ return p; }, {length:2, 0:1, 1:2});\nreturn set + '' === \"length\";" + }, + { + "name": "Array.of", + "exec": "// Array.from -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\nArray.of.call(function(){ return p; }, 1, 2, 3);\nreturn set + '' === \"length\";" + }, + { + "name": "Array.prototype.copyWithin", + "exec": "// Array.prototype.copyWithin -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.copyWithin(0, 3);\nreturn set + '' === \"0,1,2\";" + }, + { + "name": "Array.prototype.fill", + "exec": "// Array.prototype.fill -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.fill(0, 3);\nreturn set + '' === \"3,4,5\";" + }, + { + "name": "Array.prototype.pop", + "exec": "// Array.prototype.pop -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.pop();\nreturn set + '' === \"length\";" + }, + { + "name": "Array.prototype.push", + "exec": "// Array.prototype.push -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.push(0,0,0);\nreturn set + '' === \"0,1,2,length\";" + }, + { + "name": "Array.prototype.reverse", + "exec": "// Array.prototype.reverse -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([0,0,0,,], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.reverse();\nreturn set + '' === \"3,1,2\";" + }, + { + "name": "Array.prototype.shift", + "exec": "// Array.prototype.shift -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.shift();\nreturn set + '' === \"0,2,length\";" + }, + { + "name": "Array.prototype.splice", + "exec": "// Array.prototype.splice -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([1,2,3], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.splice(1,0,0);\nreturn set + '' === \"3,2,1,length\";" + }, + { + "name": "Array.prototype.unshift", + "exec": "// Array.prototype.unshift -> Set -> [[Set]]\nvar set = [];\nvar p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});\np.unshift(0,1);\nreturn set + '' === \"5,3,2,0,1,length\";" + } + ] }, { - "name": "ArrayBuffer.prototype.transfer" + "name": "Proxy, internal 'defineProperty' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty", + "subtests": [ + { + "name": "[[Set]]", + "exec": "// [[Set]] -> [[DefineOwnProperty]]\nvar def = [];\nvar p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});\np.foo = 2; p.bar = 4;\nreturn def + '' === \"foo,bar\";" + }, + { + "name": "SetIntegrityLevel", + "exec": "// SetIntegrityLevel -> DefinePropertyOrThrow -> [[DefineOwnProperty]]\nvar def = [];\nvar p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});\nObject.freeze(p);\nreturn def + '' === \"foo,bar\";" + } + ] }, { - "name": "Promise.withResolvers" + "name": "Proxy, internal 'deleteProperty' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty", + "subtests": [ + { + "name": "Array.prototype.copyWithin", + "exec": "// Array.prototype.copyWithin -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,0,0,,,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.copyWithin(0,3);\nreturn del + '' === \"0,1,2\";" + }, + { + "name": "Array.prototype.pop", + "exec": "// Array.prototype.pop -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.pop();\nreturn del + '' === \"2\";" + }, + { + "name": "Array.prototype.reverse", + "exec": "// Array.prototype.reverse -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,,2,,4,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.reverse();\nreturn del + '' === \"0,4,2\";" + }, + { + "name": "Array.prototype.shift", + "exec": "// Array.prototype.shift -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,,0,,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.shift();\nreturn del + '' === \"0,2,5\";" + }, + { + "name": "Array.prototype.splice", + "exec": "// Array.prototype.splice -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,0,0,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.splice(2,2,0);\nreturn del + '' === \"3,5\";" + }, + { + "name": "Array.prototype.unshift", + "exec": "// Array.prototype.unshift -> DeletePropertyOrThrow -> [[Delete]]\nvar del = [];\nvar p = new Proxy([0,0,,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});\np.unshift(0);\nreturn del + '' === \"5,3\";" + } + ] }, { - "name": "Array Grouping" + "name": "Proxy, internal 'getOwnPropertyDescriptor' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor", + "subtests": [ + { + "name": "[[Set]]", + "exec": "// [[Set]] -> [[GetOwnProperty]]\nvar gopd = [];\nvar p = new Proxy({},\n { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});\np.foo = 1; p.bar = 1;\nreturn gopd + '' === \"foo,bar\";" + }, + { + "name": "Object.assign", + "exec": "// Object.assign -> [[GetOwnProperty]]\nvar gopd = [];\nvar p = new Proxy({foo:1, bar:2},\n { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});\nObject.assign({}, p);\nreturn gopd + '' === \"foo,bar\";" + }, + { + "name": "Object.prototype.hasOwnProperty", + "exec": "// Object.prototype.hasOwnProperty -> HasOwnProperty -> [[GetOwnProperty]]\nvar gopd = [];\nvar p = new Proxy({foo:1, bar:2},\n { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});\np.hasOwnProperty('garply');\nreturn gopd + '' === \"garply\";" + }, + { + "name": "Function.prototype.bind", + "exec": "// Function.prototype.bind -> HasOwnProperty -> [[GetOwnProperty]]\nvar gopd = [];\nvar p = new Proxy(Function(),\n { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});\np.bind();\nreturn gopd + '' === \"length\";" + } + ] }, { - "name": "Duplicate named capturing groups" + "name": "Proxy, internal 'ownKeys' calls", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys", + "subtests": [ + { + "name": "SetIntegrityLevel", + "exec": "// SetIntegrityLevel -> [[OwnPropertyKeys]]\nvar ownKeysCalled = 0;\nvar p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});\nObject.freeze(p);\nreturn ownKeysCalled === 1;" + }, + { + "name": "TestIntegrityLevel", + "exec": "// TestIntegrityLevel -> [[OwnPropertyKeys]]\nvar ownKeysCalled = 0;\nvar p = new Proxy(Object.preventExtensions({}), { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});\nObject.isFrozen(p);\nreturn ownKeysCalled === 1;" + }, + { + "name": "SerializeJSONObject", + "exec": "// SerializeJSONObject -> EnumerableOwnNames -> [[OwnPropertyKeys]]\nvar ownKeysCalled = 0;\nvar p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});\nJSON.stringify({a:p,b:p});\nreturn ownKeysCalled === 2;" + } + ] }, { - "name": "Set methods" + "name": "Object static methods accept primitives", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-object-constructor", + "subtests": [ + { + "name": "Object.getPrototypeOf", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf", + "exec": "return Object.getPrototypeOf('a').constructor === String;" + }, + { + "name": "Object.getOwnPropertyDescriptor", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor", + "exec": "return Object.getOwnPropertyDescriptor('a', 'foo') === void undefined;" + }, + { + "name": "Object.getOwnPropertyNames", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames", + "exec": "var s = Object.getOwnPropertyNames('a');\nreturn s.length === 2 &&\n ((s[0] === 'length' && s[1] === '0') || (s[0] === '0' && s[1] === 'length'));" + }, + { + "name": "Object.seal", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal", + "exec": "return Object.seal('a') === 'a';" + }, + { + "name": "Object.freeze", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze", + "exec": "return Object.freeze('a') === 'a';" + }, + { + "name": "Object.preventExtensions", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions", + "exec": "return Object.preventExtensions('a') === 'a';" + }, + { + "name": "Object.isSealed", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed", + "exec": "return Object.isSealed('a') === true;" + }, + { + "name": "Object.isFrozen", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen", + "exec": "return Object.isFrozen('a') === true;" + }, + { + "name": "Object.isExtensible", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible", + "exec": "return Object.isExtensible('a') === false;" + }, + { + "name": "Object.keys", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys", + "exec": "var s = Object.keys('a');\nreturn s.length === 1 && s[0] === '0';" + } + ] }, { - "name": "RegExp Pattern Modifiers" + "name": "own property order", + "target": "es6", + "category": "misc", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys", + "subtests": [ + { + "name": "Object.keys", + "exec": "var obj = {\n // Non-negative integer names appear first in value order\n 2: true,\n 0: true,\n 1: true,\n // Other string names appear in source order\n ' ': true,\n // Non-negative integers are sorted above other names\n 9: true,\n D: true,\n B: true,\n // Negative integers are treated as other names\n '-1': true\n};\n// Other string names are added in order of creation\nobj.A = true;\n// Non-negative integer names, conversely, ignore order of creation\nobj[3] = true;\n// Having a total of 20+ properties doesn't affect property order\n\"EFGHIJKLMNOPQRSTUVWXYZ\".split('').forEach(function(key){\n obj[key] = true;\n});\n// Object.defineProperty doesn't affect the above rules\nObject.defineProperty(obj, 'C', { value: true, enumerable: true });\nObject.defineProperty(obj, '4', { value: true, enumerable: true });\n// Deleting and reinserting a property doesn't preserve its position\ndelete obj[2];\nobj[2] = true;\n\nvar forInOrder = '';\nfor(var key in obj)forInOrder += key;\n\nreturn Object.keys(obj).join('') === forInOrder;" + }, + { + "name": "Object.getOwnPropertyNames", + "exec": "var obj = {\n 2: true,\n 0: true,\n 1: true,\n ' ': true,\n 9: true,\n D: true,\n B: true,\n '-1': true\n};\nobj.A = true;\nobj[3] = true;\n\"EFGHIJKLMNOPQRSTUVWXYZ\".split('').forEach(function(key){\n obj[key] = true;\n});\nObject.defineProperty(obj, 'C', { value: true, enumerable: true });\nObject.defineProperty(obj, '4', { value: true, enumerable: true });\ndelete obj[2];\nobj[2] = true;\n\nreturn Object.getOwnPropertyNames(obj).join('') === \"012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC\";" + }, + { + "name": "Object.assign", + "exec": "var result = '';\nvar target = {};\n\n\"012349 DBACEFGHIJKLMNOPQRST\".split('').concat(-1).forEach(function(key){\n Object.defineProperty(target, key, {\n set: function(){\n result += key;\n }\n })\n});\n\nvar obj = {2: 2, 0: 0, 1: 1, ' ': ' ', 9: 9, D: 'D', B: 'B', '-1': '-1'};\nObject.defineProperty(obj, 'A', {value: 'A', enumerable: true});\nObject.defineProperty(obj, '3', {value: '3', enumerable: true});\nObject.defineProperty(obj, 'C', {value: 'C', enumerable: true});\nObject.defineProperty(obj, '4', {value: '4', enumerable: true});\ndelete obj[2];\nobj[2] = true;\n\n\"EFGHIJKLMNOPQRST\".split('').forEach(function(key){\n obj[key] = key;\n});\n\nObject.assign(target, obj);\n\nreturn result === \"012349 DB-1ACEFGHIJKLMNOPQRST\";" + }, + { + "name": "JSON.stringify", + "exec": "var obj = {\n 2: true,\n 0: true,\n 1: true,\n ' ': true,\n 9: true,\n D: true,\n B: true,\n '-1': true\n};\nobj.A = true;\nobj[3] = true;\n\"EFGHIJKLMNOPQRSTUVWXYZ\".split('').forEach(function(key){\n obj[key] = true;\n});\nObject.defineProperty(obj, 'C', { value: true, enumerable: true });\nObject.defineProperty(obj, '4', { value: true, enumerable: true });\ndelete obj[2];\nobj[2] = true;\n\nreturn JSON.stringify(obj) ===\n '{\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"9\":true,\" \":true,\"D\":true,\"B\":true,\"-1\":true,\"A\":true,\"E\":true,\"F\":true,\"G\":true,\"H\":true,\"I\":true,\"J\":true,\"K\":true,\"L\":true,\"M\":true,\"N\":true,\"O\":true,\"P\":true,\"Q\":true,\"R\":true,\"S\":true,\"T\":true,\"U\":true,\"V\":true,\"W\":true,\"X\":true,\"Y\":true,\"Z\":true,\"C\":true}';" + }, + { + "name": "JSON.parse", + "exec": "var result = '';\nJSON.parse(\n '{\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"9\":true,\" \":true,\"D\":true,\"B\":true,\"-1\":true,\"E\":true,\"F\":true,\"G\":true,\"H\":true,\"I\":true,\"J\":true,\"K\":true,\"L\":true,\"A\":true,\"C\":true}',\n function reviver(k,v) {\n result += k;\n return v;\n }\n);\nreturn result === \"012349 DB-1EFGHIJKLAC\";" + }, + { + "name": "Reflect.ownKeys, string key order", + "exec": "var obj = {\n 2: true,\n 0: true,\n 1: true,\n ' ': true,\n 9: true,\n D: true,\n B: true,\n '-1': true\n};\nobj.A = true;\nobj[3] = true;\n\"EFGHIJKLMNOPQRSTUVWXYZ\".split('').forEach(function(key){\n obj[key] = true;\n});\nObject.defineProperty(obj, 'C', { value: true, enumerable: true });\nObject.defineProperty(obj, '4', { value: true, enumerable: true });\ndelete obj[2];\nobj[2] = true;\n\nreturn Reflect.ownKeys(obj).join('') === \"012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC\";" + }, + { + "name": "Reflect.ownKeys, symbol key order", + "exec": "var sym1 = Symbol(), sym2 = Symbol(), sym3 = Symbol();\nvar obj = {\n 1: true,\n A: true\n};\nobj.B = true;\nobj[sym1] = true;\nobj[2] = true;\nobj[sym2] = true;\nObject.defineProperty(obj, 'C', { value: true, enumerable: true });\nObject.defineProperty(obj, sym3,{ value: true, enumerable: true });\nObject.defineProperty(obj, 'D', { value: true, enumerable: true });\n\nvar result = Reflect.ownKeys(obj);\nvar l = result.length;\nreturn result[l-3] === sym1 && result[l-2] === sym2 && result[l-1] === sym3;" + } + ] }, { - "name": "Iterator Helpers" + "name": "Updated identifier syntax", + "target": "es6", + "category": "misc", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords", + "subtests": [ + { + "name": "var ⸯ;", + "exec": "try {\n eval('var ⸯ');\n} catch(e) {\n return true;\n}" + }, + { + "name": "var 𐋀;", + "exec": "var 𐋀;\nreturn true;" + }, + { + "name": "no escaped reserved words as identifiers", + "exec": "var \\u0061;\ntry {\n eval('var v\\\\u0061r');\n} catch(e) {\n return true;\n}" + } + ] }, { - "name": "Promise.try" + "name": "miscellaneous", + "target": "es6", + "category": "misc", + "significance": "small", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-additions-and-changes-that-introduce-incompatibilities-with-prior-editions", + "subtests": [ + { + "name": "duplicate property names in strict mode", + "exec": "'use strict';\nreturn this === void undefined && ({ a:1, a:1 }).a === 1;" + }, + { + "name": "no semicolon needed after do-while", + "exec": "do {} while (false) return true;" + }, + { + "name": "no assignments allowed in for-in head in strict mode", + "exec": "'use strict';\ntry {\n eval('for (var i = 0 in {}) {}');\n}\ncatch(e) {\n return true;\n}" + }, + { + "name": "accessors aren't constructors", + "exec": "var f = (Object.getOwnPropertyDescriptor({get a(){}}, 'a')).get;\ntry {\n new f;\n} catch(e) {\n return true;\n}" + }, + { + "name": "Invalid Date", + "exec": "return new Date(NaN) + \"\" === \"Invalid Date\";" + }, + { + "name": "RegExp constructor can alter flags", + "exec": "return new RegExp(/./im, \"g\").global === true;" + }, + { + "name": "RegExp.prototype.toString generic and uses \"flags\" property", + "exec": "return RegExp.prototype.toString.call({source: 'foo', flags: 'bar'}) === '/foo/bar';" + }, + { + "name": "built-in prototypes are not instances", + "exec": "try {\n RegExp.prototype.exec(); return false;\n} catch(e) {}\ntry {\n Date.prototype.valueOf(); return false;\n} catch(e) {}\n\nif (![Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError].every(function (E) {\n return Object.prototype.toString.call(E.prototype) === '[object Object]';\n})) {\n return false;\n}\n\nreturn true;" + }, + { + "name": "function 'length' is configurable", + "exec": "var fn = function(a, b) {};\n\nvar desc = Object.getOwnPropertyDescriptor(fn, \"length\");\nif (desc.configurable) {\n Object.defineProperty(fn, \"length\", { value: 1 });\n return fn.length === 1;\n}\n\nreturn false;" + } + ] + }, + { + "name": "non-strict function semantics", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-labelled-function-declarations", + "subtests": [ + { + "name": "hoisted block-level function declaration", + "exec": "// Note: only available outside of strict mode.\nif (!this) return false;\nvar passed = f() === 1;\nfunction f() { return 1; }\n\npassed &= typeof g === 'undefined';\n{ function g() { return 1; } }\npassed &= g() === 1;\n\npassed &= h() === 2;\n{ function h() { return 1; } }\nfunction h() { return 2; }\npassed &= h() === 1;\n\nreturn passed;" + }, + { + "name": "labeled function statements", + "exec": "// Note: only available outside of strict mode.\nif (!this) return false;\n\nlabel: function foo() { return 2; }\nreturn foo() === 2;" + }, + { + "name": "function statements in if-statement clauses", + "exec": "// Note: only available outside of strict mode.\nif (!this) return false;\n\nif(true) function foo() { return 2; }\nif(false) {} else function bar() { return 3; }\nif(true) function baz() { return 4; } else {}\nif(false) function qux() { return 5; } else function qux() { return 6; }\nreturn foo() === 2 && bar() === 3 && baz() === 4 && qux() === 6;" + } + ] + }, + { + "name": "__proto__ in object literals", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-__proto__-property-names-in-object-initializers", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto#Specifications", + "subtests": [ + { + "name": "basic support", + "exec": "return { __proto__ : [] } instanceof Array\n && !({ __proto__ : null } instanceof Object);" + }, + { + "name": "multiple __proto__ is an error", + "exec": "try {\n eval(\"({ __proto__ : [], __proto__: {} })\");\n}\ncatch(e) {\n return true;\n}" + }, + { + "name": "not a computed property", + "exec": "if (!({ __proto__ : [] } instanceof Array)) {\n return false;\n}\nvar a = \"__proto__\";\nreturn !({ [a] : [] } instanceof Array);" + }, + { + "name": "not a shorthand property", + "exec": "if (!({ __proto__ : [] } instanceof Array)) {\n return false;\n}\nvar __proto__ = [];\nreturn !({ __proto__ } instanceof Array);" + }, + { + "name": "not a shorthand method", + "exec": "if (!({ __proto__ : [] } instanceof Array)) {\n return false;\n}\nreturn !({ __proto__(){} } instanceof Function);" + } + ] + }, + { + "name": "Object.prototype.__proto__", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-object.prototype.__proto__", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto", + "subtests": [ + { + "name": "get prototype", + "exec": "var A = function(){};\nreturn (new A()).__proto__ === A.prototype;" + }, + { + "name": "set prototype", + "exec": "var o = {};\no.__proto__ = Array.prototype;\nreturn o instanceof Array;" + }, + { + "name": "absent from Object.create(null)", + "exec": "var o = Object.create(null), p = {};\no.__proto__ = p;\nreturn Object.getPrototypeOf(o) !== p;" + }, + { + "name": "present in hasOwnProperty()", + "exec": "return Object.prototype.hasOwnProperty('__proto__');" + }, + { + "name": "correct property descriptor", + "exec": "var desc = Object.getOwnPropertyDescriptor(Object.prototype,\"__proto__\");\nvar A = function(){};\n\nreturn (desc\n && \"get\" in desc\n && \"set\" in desc\n && desc.configurable\n && !desc.enumerable);" + }, + { + "name": "present in Object.getOwnPropertyNames()", + "exec": "return Object.getOwnPropertyNames(Object.prototype).indexOf('__proto__') > -1;" + } + ] + }, + { + "name": "String.prototype HTML methods", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.anchor", + "subtests": [ + { + "name": "existence", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/prototype#HTML_wrapper_methods", + "exec": "var i, names = [\"anchor\", \"big\", \"bold\", \"fixed\", \"fontcolor\", \"fontsize\",\n \"italics\", \"link\", \"small\", \"strike\", \"sub\", \"sup\"];\nfor (i = 0; i < names.length; i++) {\n if (typeof String.prototype[names[i]] !== 'function') {\n return false;\n }\n}\nreturn true;" + }, + { + "name": "tags' names are lowercase", + "exec": "var i, names = [\"anchor\", \"big\", \"bold\", \"fixed\", \"fontcolor\", \"fontsize\",\n \"italics\", \"link\", \"small\", \"strike\", \"sub\", \"sup\"];\nfor (i = 0; i < names.length; i++) {\n if (\"\"[names[i]]().toLowerCase() !== \"\"[names[i]]()) {\n return false;\n }\n}\nreturn true;" + }, + { + "name": "quotes in arguments are escaped", + "exec": "var i, names = [\"anchor\", \"fontcolor\", \"fontsize\", \"link\"];\nfor (i = 0; i < names.length; i++) {\n if (\"\"[names[i]]('\"') !== \"\"[names[i]]('&' + 'quot;')) {\n return false;\n }\n}\nreturn true;" + } + ] + }, + { + "name": "RegExp.prototype.compile", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.compile", + "mdn": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/compile", + "subtests": [ + { + "name": "basic functionality", + "exec": "if (typeof RegExp.prototype.compile !== 'function')\n return false\nvar rx = /a/;\nrx.compile('b');\nreturn rx.test('b');" + }, + { + "name": "returns this", + "exec": "var rx = /a/;\nreturn rx.compile('b') === rx;" + } + ] + }, + { + "name": "RegExp syntax extensions", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns", + "subtests": [ + { + "name": "hyphens in character sets", + "exec": "return /[\\w-_]/.exec(\"-\")[0] === \"-\";" + }, + { + "name": "invalid character escapes", + "exec": "return /\\z/.exec(\"\\\\z\")[0] === \"z\"\n && /[\\z]/.exec(\"[\\\\z]\")[0] === \"z\";" + }, + { + "name": "invalid control-character escapes", + "exec": "return /\\c2/.exec(\"\\\\c2\")[0] === \"\\\\c2\";" + }, + { + "name": "invalid Unicode escapes", + "exec": "return /\\u1/.exec(\"u1\")[0] === \"u1\"\n && /[\\u1]/.exec(\"u\")[0] === \"u\";" + }, + { + "name": "invalid hexadecimal escapes", + "exec": "return /\\x1/.exec(\"x1\")[0] === \"x1\"\n && /[\\x1]/.exec(\"x\")[0] === \"x\";" + }, + { + "name": "incomplete patterns and quantifiers", + "exec": "return /x{1/.exec(\"x{1\")[0] === \"x{1\"\n && /x]1/.exec(\"x]1\")[0] === \"x]1\";" + }, + { + "name": "octal escape sequences", + "exec": "return /\\041/.exec(\"!\")[0] === \"!\"\n && /[\\041]/.exec(\"!\")[0] === \"!\";" + }, + { + "name": "invalid backreferences become octal escapes", + "exec": "return /\\41/.exec(\"!\")[0] === \"!\"\n && /[\\41]/.exec(\"!\")[0] === \"!\";" + } + ] + }, + { + "name": "HTML-style comments", + "target": "es6", + "category": "annex b", + "significance": "tiny", + "spec": "http://www.ecma-international.org/ecma-262/6.0/#sec-html-like-comments", + "exec": "--> A comment\n A comment\n