2019-08-26 23:38:37 +00:00
|
|
|
//! Tests running SWFs in a headless Ruffle instance.
|
|
|
|
//!
|
2021-01-15 11:47:23 +00:00
|
|
|
//! Trace output can be compared with correct output from the official Flash Player.
|
2019-08-26 23:38:37 +00:00
|
|
|
|
2020-11-11 10:32:23 +00:00
|
|
|
use approx::assert_relative_eq;
|
2019-09-17 03:37:11 +00:00
|
|
|
use ruffle_core::backend::{
|
2021-01-31 00:36:45 +00:00
|
|
|
audio::NullAudioBackend,
|
|
|
|
locale::NullLocaleBackend,
|
|
|
|
log::LogBackend,
|
|
|
|
navigator::{NullExecutor, NullNavigatorBackend},
|
|
|
|
render::NullRenderer,
|
2021-02-05 03:09:51 +00:00
|
|
|
storage::{MemoryStorageBackend, StorageBackend},
|
2021-01-31 00:36:45 +00:00
|
|
|
ui::NullUiBackend,
|
2020-10-15 03:01:48 +00:00
|
|
|
video::NullVideoBackend,
|
2019-09-17 03:37:11 +00:00
|
|
|
};
|
2020-08-31 21:32:12 +00:00
|
|
|
use ruffle_core::context::UpdateContext;
|
2020-08-28 15:24:26 +00:00
|
|
|
use ruffle_core::external::Value as ExternalValue;
|
2020-08-31 21:32:12 +00:00
|
|
|
use ruffle_core::external::{ExternalInterfaceMethod, ExternalInterfaceProvider};
|
2020-05-04 19:37:06 +00:00
|
|
|
use ruffle_core::tag_utils::SwfMovie;
|
2019-08-26 23:38:37 +00:00
|
|
|
use ruffle_core::Player;
|
|
|
|
use std::cell::RefCell;
|
2020-08-28 15:24:26 +00:00
|
|
|
use std::collections::BTreeMap;
|
2020-01-17 00:20:45 +00:00
|
|
|
use std::path::Path;
|
2020-09-05 19:10:46 +00:00
|
|
|
use std::rc::Rc;
|
2020-08-28 10:19:22 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2020-09-15 22:28:41 +00:00
|
|
|
use std::time::Duration;
|
2019-12-18 21:25:54 +00:00
|
|
|
|
2021-02-12 09:57:03 +00:00
|
|
|
fn set_logger() {
|
|
|
|
let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
|
|
|
|
.format_timestamp(None)
|
|
|
|
.is_test(true)
|
|
|
|
.try_init();
|
|
|
|
}
|
|
|
|
|
2019-08-26 23:38:37 +00:00
|
|
|
type Error = Box<dyn std::error::Error>;
|
|
|
|
|
|
|
|
// This macro generates test cases for a given list of SWFs.
|
|
|
|
macro_rules! swf_tests {
|
2019-10-12 20:24:26 +00:00
|
|
|
($($(#[$attr:meta])* ($name:ident, $path:expr, $num_frames:literal),)*) => {
|
|
|
|
$(
|
2019-08-26 23:38:37 +00:00
|
|
|
#[test]
|
2019-10-12 20:24:26 +00:00
|
|
|
$(#[$attr])*
|
2019-08-26 23:38:37 +00:00
|
|
|
fn $name() -> Result<(), Error> {
|
2021-02-12 09:57:03 +00:00
|
|
|
set_logger();
|
2019-08-26 23:38:37 +00:00
|
|
|
test_swf(
|
|
|
|
concat!("tests/swfs/", $path, "/test.swf"),
|
|
|
|
$num_frames,
|
|
|
|
concat!("tests/swfs/", $path, "/output.txt"),
|
|
|
|
)
|
|
|
|
}
|
2019-10-12 20:24:26 +00:00
|
|
|
)*
|
|
|
|
};
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
|
2020-02-17 20:32:25 +00:00
|
|
|
// This macro generates test cases for a given list of SWFs using `test_swf_approx`.
|
|
|
|
macro_rules! swf_tests_approx {
|
2020-11-11 10:32:23 +00:00
|
|
|
($($(#[$attr:meta])* ($name:ident, $path:expr, $num_frames:literal $(, $opt:ident = $val:expr)*),)*) => {
|
2020-02-17 20:32:25 +00:00
|
|
|
$(
|
|
|
|
#[test]
|
|
|
|
$(#[$attr])*
|
|
|
|
fn $name() -> Result<(), Error> {
|
2021-02-12 09:57:03 +00:00
|
|
|
set_logger();
|
2020-02-17 20:32:25 +00:00
|
|
|
test_swf_approx(
|
|
|
|
concat!("tests/swfs/", $path, "/test.swf"),
|
|
|
|
$num_frames,
|
|
|
|
concat!("tests/swfs/", $path, "/output.txt"),
|
2020-11-11 10:32:23 +00:00
|
|
|
|actual, expected| assert_relative_eq!(actual, expected $(, $opt = $val)*),
|
2020-02-17 20:32:25 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-08-26 23:38:37 +00:00
|
|
|
// List of SWFs to test.
|
|
|
|
// Format: (test_name, test_folder, number_of_frames_to_run)
|
|
|
|
// The test folder is a relative to core/tests/swfs
|
|
|
|
// Inside the folder is expected to be "test.swf" and "output.txt" with the correct output.
|
|
|
|
swf_tests! {
|
2019-12-03 23:01:39 +00:00
|
|
|
(add_property, "avm1/add_property", 1),
|
2019-12-15 17:33:58 +00:00
|
|
|
(as_transformed_flag, "avm1/as_transformed_flag", 3),
|
2020-07-28 11:17:27 +00:00
|
|
|
(as_broadcaster, "avm1/as_broadcaster", 1),
|
2020-07-28 20:49:41 +00:00
|
|
|
(as_broadcaster_initialize, "avm1/as_broadcaster_initialize", 1),
|
2019-12-17 11:19:29 +00:00
|
|
|
(attach_movie, "avm1/attach_movie", 1),
|
2021-03-20 21:49:55 +00:00
|
|
|
(as2_bitor, "avm1/bitor", 1),
|
|
|
|
(as2_bitand, "avm1/bitand", 1),
|
|
|
|
(as2_bitxor, "avm1/bitxor", 1),
|
2019-12-19 22:05:56 +00:00
|
|
|
(function_base_clip, "avm1/function_base_clip", 2),
|
2020-01-14 07:38:20 +00:00
|
|
|
(call, "avm1/call", 2),
|
2020-01-04 03:48:39 +00:00
|
|
|
(color, "avm1/color", 1),
|
2019-12-01 20:16:02 +00:00
|
|
|
(clip_events, "avm1/clip_events", 4),
|
2020-11-09 20:25:14 +00:00
|
|
|
(unload_clip_event, "avm1/unload_clip_event", 2),
|
2019-12-17 11:19:29 +00:00
|
|
|
(create_empty_movie_clip, "avm1/create_empty_movie_clip", 2),
|
2020-04-20 09:04:53 +00:00
|
|
|
(empty_movieclip_can_attach_movies, "avm1/empty_movieclip_can_attach_movies", 1),
|
2019-12-17 11:19:29 +00:00
|
|
|
(duplicate_movie_clip, "avm1/duplicate_movie_clip", 1),
|
2019-12-16 21:58:31 +00:00
|
|
|
(mouse_listeners, "avm1/mouse_listeners", 1),
|
2019-10-29 17:49:44 +00:00
|
|
|
(do_init_action, "avm1/do_init_action", 3),
|
2019-10-26 08:42:12 +00:00
|
|
|
(execution_order1, "avm1/execution_order1", 3),
|
2019-10-20 02:17:00 +00:00
|
|
|
(execution_order2, "avm1/execution_order2", 15),
|
|
|
|
(execution_order3, "avm1/execution_order3", 5),
|
2021-01-15 11:47:23 +00:00
|
|
|
(export_assets, "avm1/export_assets", 1),
|
2019-08-26 23:38:37 +00:00
|
|
|
(single_frame, "avm1/single_frame", 2),
|
|
|
|
(looping, "avm1/looping", 6),
|
2020-05-20 15:20:36 +00:00
|
|
|
(matrix, "avm1/matrix", 1),
|
2020-05-20 12:25:15 +00:00
|
|
|
(point, "avm1/point", 1),
|
2020-05-31 11:58:16 +00:00
|
|
|
(rectangle, "avm1/rectangle", 1),
|
2020-07-08 18:26:00 +00:00
|
|
|
(date_is_special, "avm1/date_is_special", 1),
|
2021-01-09 21:27:12 +00:00
|
|
|
(get_bytes_total, "avm1/get_bytes_total", 1),
|
2020-04-25 09:04:37 +00:00
|
|
|
(goto_advance1, "avm1/goto_advance1", 2),
|
|
|
|
(goto_advance2, "avm1/goto_advance2", 2),
|
|
|
|
(goto_both_ways1, "avm1/goto_both_ways1", 2),
|
|
|
|
(goto_both_ways2, "avm1/goto_both_ways2", 3),
|
|
|
|
(goto_frame, "avm1/goto_frame", 3),
|
|
|
|
(goto_frame2, "avm1/goto_frame2", 5),
|
2020-07-29 17:40:55 +00:00
|
|
|
(goto_frame_number, "avm1/goto_frame_number", 4),
|
2020-04-25 09:04:37 +00:00
|
|
|
(goto_label, "avm1/goto_label", 4),
|
2019-12-16 07:56:26 +00:00
|
|
|
(goto_methods, "avm1/goto_methods", 1),
|
2020-04-25 09:04:37 +00:00
|
|
|
(goto_rewind1, "avm1/goto_rewind1", 4),
|
|
|
|
(goto_rewind2, "avm1/goto_rewind2", 5),
|
|
|
|
(goto_rewind3, "avm1/goto_rewind3", 2),
|
2019-10-20 02:17:00 +00:00
|
|
|
(goto_execution_order, "avm1/goto_execution_order", 3),
|
2020-04-25 09:04:37 +00:00
|
|
|
(goto_execution_order2, "avm1/goto_execution_order2", 2),
|
2019-10-08 19:45:39 +00:00
|
|
|
(greaterthan_swf5, "avm1/greaterthan_swf5", 1),
|
|
|
|
(greaterthan_swf8, "avm1/greaterthan_swf8", 1),
|
|
|
|
(strictly_equals, "avm1/strictly_equals", 1),
|
2019-09-17 17:36:25 +00:00
|
|
|
(tell_target, "avm1/tell_target", 3),
|
2019-10-08 08:37:28 +00:00
|
|
|
(typeofs, "avm1/typeof", 1),
|
|
|
|
(typeof_globals, "avm1/typeof_globals", 1),
|
2019-10-08 02:22:50 +00:00
|
|
|
(closure_scope, "avm1/closure_scope", 1),
|
|
|
|
(variable_args, "avm1/variable_args", 1),
|
2019-10-11 23:09:55 +00:00
|
|
|
(custom_clip_methods, "avm1/custom_clip_methods", 3),
|
|
|
|
(delete, "avm1/delete", 3),
|
2020-10-31 22:26:07 +00:00
|
|
|
(selection, "avm1/selection", 1),
|
2020-04-21 12:25:24 +00:00
|
|
|
(default_names, "avm1/default_names", 6),
|
2019-11-27 22:54:19 +00:00
|
|
|
(array_trivial, "avm1/array_trivial", 1),
|
|
|
|
(array_concat, "avm1/array_concat", 1),
|
|
|
|
(array_slice, "avm1/array_slice", 1),
|
2019-12-13 21:35:44 +00:00
|
|
|
(array_splice, "avm1/array_splice", 1),
|
2019-12-11 23:30:04 +00:00
|
|
|
(array_properties, "avm1/array_properties", 1),
|
2019-12-13 14:50:58 +00:00
|
|
|
(array_prototyping, "avm1/array_prototyping", 1),
|
|
|
|
(array_vs_object_length, "avm1/array_vs_object_length", 1),
|
2020-04-01 11:24:46 +00:00
|
|
|
(array_sort, "avm1/array_sort", 1),
|
2020-06-28 02:54:13 +00:00
|
|
|
(array_enumerate, "avm1/array_enumerate", 1),
|
2019-10-11 23:09:55 +00:00
|
|
|
(timeline_function_def, "avm1/timeline_function_def", 3),
|
2019-10-11 23:33:13 +00:00
|
|
|
(root_global_parent, "avm1/root_global_parent", 3),
|
2019-10-13 22:41:07 +00:00
|
|
|
(register_underflow, "avm1/register_underflow", 1),
|
2019-11-26 22:06:26 +00:00
|
|
|
(object_prototypes, "avm1/object_prototypes", 1),
|
2019-11-26 22:20:54 +00:00
|
|
|
(movieclip_prototype_extension, "avm1/movieclip_prototype_extension", 1),
|
2019-12-18 14:46:48 +00:00
|
|
|
(movieclip_hittest, "avm1/movieclip_hittest", 1),
|
2020-08-28 00:41:03 +00:00
|
|
|
(movieclip_hittest_shapeflag, "avm1/movieclip_hittest_shapeflag", 10),
|
2020-12-01 02:50:50 +00:00
|
|
|
(movieclip_lockroot, "avm1/movieclip_lockroot", 10),
|
2019-12-19 09:31:08 +00:00
|
|
|
#[ignore] (textfield_text, "avm1/textfield_text", 1),
|
2020-06-20 21:03:04 +00:00
|
|
|
(recursive_prototypes, "avm1/recursive_prototypes", 2),
|
2019-12-03 08:53:43 +00:00
|
|
|
(stage_object_children, "avm1/stage_object_children", 2),
|
2019-11-27 19:51:40 +00:00
|
|
|
(has_own_property, "avm1/has_own_property", 1),
|
2019-10-29 03:14:59 +00:00
|
|
|
(extends_chain, "avm1/extends_chain", 1),
|
2019-11-27 20:08:41 +00:00
|
|
|
(is_prototype_of, "avm1/is_prototype_of", 1),
|
2019-10-27 00:35:50 +00:00
|
|
|
#[ignore] (string_coercion, "avm1/string_coercion", 1),
|
2019-11-21 21:08:29 +00:00
|
|
|
(lessthan_swf4, "avm1/lessthan_swf4", 1),
|
|
|
|
(lessthan2_swf5, "avm1/lessthan2_swf5", 1),
|
|
|
|
(lessthan2_swf6, "avm1/lessthan2_swf6", 1),
|
|
|
|
(lessthan2_swf7, "avm1/lessthan2_swf7", 1),
|
2019-12-22 06:40:32 +00:00
|
|
|
(logical_ops_swf4, "avm1/logical_ops_swf4", 1),
|
|
|
|
(logical_ops_swf8, "avm1/logical_ops_swf8", 1),
|
2021-02-28 18:23:04 +00:00
|
|
|
(movieclip_get_instance_at_depth, "avm1/movieclip_get_instance_at_depth", 1),
|
2020-01-30 05:58:31 +00:00
|
|
|
(movieclip_depth_methods, "avm1/movieclip_depth_methods", 3),
|
2020-03-10 20:49:07 +00:00
|
|
|
(get_variable_in_scope, "avm1/get_variable_in_scope", 1),
|
2020-05-03 12:01:39 +00:00
|
|
|
(movieclip_init_object, "avm1/movieclip_init_object", 1),
|
2019-11-21 21:08:29 +00:00
|
|
|
(greater_swf6, "avm1/greater_swf6", 1),
|
|
|
|
(greater_swf7, "avm1/greater_swf7", 1),
|
|
|
|
(equals_swf4, "avm1/equals_swf4", 1),
|
|
|
|
(equals2_swf5, "avm1/equals2_swf5", 1),
|
|
|
|
(equals2_swf6, "avm1/equals2_swf6", 1),
|
|
|
|
(equals2_swf7, "avm1/equals2_swf7", 1),
|
2020-12-30 11:50:13 +00:00
|
|
|
(escape, "avm1/escape", 1),
|
2021-01-02 06:52:27 +00:00
|
|
|
(unescape, "avm1/unescape", 1),
|
2020-01-20 21:46:46 +00:00
|
|
|
(register_class, "avm1/register_class", 1),
|
2021-01-12 14:32:56 +00:00
|
|
|
(register_class_return_value, "avm1/register_class_return_value", 1),
|
2021-01-13 20:40:55 +00:00
|
|
|
(register_class_swf6, "avm1/register_class_swf6", 1),
|
2020-04-12 13:36:16 +00:00
|
|
|
(register_and_init_order, "avm1/register_and_init_order", 1),
|
2020-04-20 10:49:41 +00:00
|
|
|
(on_construct, "avm1/on_construct", 1),
|
2020-01-07 03:08:30 +00:00
|
|
|
(set_variable_scope, "avm1/set_variable_scope", 1),
|
2019-12-16 23:33:57 +00:00
|
|
|
(slash_syntax, "avm1/slash_syntax", 2),
|
2019-11-21 21:08:29 +00:00
|
|
|
(strictequals_swf6, "avm1/strictequals_swf6", 1),
|
2020-01-18 22:48:05 +00:00
|
|
|
(string_methods, "avm1/string_methods", 1),
|
2020-09-16 07:51:09 +00:00
|
|
|
(string_ops_swf6, "avm1/string_ops_swf6", 1),
|
2021-03-19 21:32:04 +00:00
|
|
|
(substr_negative, "avm1/substr_negative", 1),
|
2020-08-20 21:48:45 +00:00
|
|
|
(path_string, "avm1/path_string", 1),
|
2019-11-24 17:31:39 +00:00
|
|
|
(global_is_bare, "avm1/global_is_bare", 1),
|
2020-01-20 08:20:27 +00:00
|
|
|
(primitive_type_globals, "avm1/primitive_type_globals", 1),
|
2020-07-01 21:44:01 +00:00
|
|
|
(primitive_instanceof, "avm1/primitive_instanceof", 1),
|
2019-11-29 04:44:37 +00:00
|
|
|
(as2_oop, "avm1/as2_oop", 1),
|
2021-01-21 08:46:35 +00:00
|
|
|
(extends_native_type, "avm1/extends_native_type", 1),
|
2019-12-22 05:21:41 +00:00
|
|
|
(xml, "avm1/xml", 1),
|
2019-12-25 22:42:38 +00:00
|
|
|
(xml_namespaces, "avm1/xml_namespaces", 1),
|
2019-12-31 03:49:18 +00:00
|
|
|
(xml_node_namespaceuri, "avm1/xml_node_namespaceuri", 1),
|
|
|
|
(xml_node_weirdnamespace, "avm1/xml_node_weirdnamespace", 1),
|
2019-12-25 23:01:59 +00:00
|
|
|
(xml_clone_expandos, "avm1/xml_clone_expandos", 1),
|
2019-12-25 23:41:17 +00:00
|
|
|
(xml_has_child_nodes, "avm1/xml_has_child_nodes", 1),
|
2019-12-26 01:31:05 +00:00
|
|
|
(xml_first_last_child, "avm1/xml_first_last_child", 1),
|
2019-12-26 01:42:54 +00:00
|
|
|
(xml_parent_and_child, "avm1/xml_parent_and_child", 1),
|
2019-12-26 01:55:24 +00:00
|
|
|
(xml_siblings, "avm1/xml_siblings", 1),
|
2019-12-26 05:09:43 +00:00
|
|
|
(xml_attributes_read, "avm1/xml_attributes_read", 1),
|
2019-12-26 06:46:25 +00:00
|
|
|
(xml_append_child, "avm1/xml_append_child", 1),
|
2019-12-28 20:41:38 +00:00
|
|
|
(xml_append_child_with_parent, "avm1/xml_append_child_with_parent", 1),
|
2019-12-28 03:56:03 +00:00
|
|
|
(xml_remove_node, "avm1/xml_remove_node", 1),
|
2021-04-11 17:30:29 +00:00
|
|
|
(xml_reparenting, "avm1/xml_reparenting", 1),
|
2019-12-28 20:32:13 +00:00
|
|
|
(xml_insert_before, "avm1/xml_insert_before", 1),
|
2019-12-28 22:15:27 +00:00
|
|
|
(xml_to_string, "avm1/xml_to_string", 1),
|
2019-12-31 21:31:40 +00:00
|
|
|
(xml_to_string_comment, "avm1/xml_to_string_comment", 1),
|
2020-01-01 21:04:58 +00:00
|
|
|
(xml_idmap, "avm1/xml_idmap", 1),
|
2020-11-26 15:29:49 +00:00
|
|
|
(xml_ignore_comments, "avm1/xml_ignore_comments", 1),
|
2020-12-30 00:56:12 +00:00
|
|
|
(xml_ignore_white, "avm1/xml_ignore_white", 1),
|
2019-12-30 04:05:06 +00:00
|
|
|
(xml_inspect_doctype, "avm1/xml_inspect_doctype", 1),
|
2019-12-30 06:09:31 +00:00
|
|
|
#[ignore] (xml_inspect_xmldecl, "avm1/xml_inspect_xmldecl", 1),
|
2019-12-31 01:58:18 +00:00
|
|
|
(xml_inspect_createmethods, "avm1/xml_inspect_createmethods", 1),
|
2020-01-01 00:48:36 +00:00
|
|
|
(xml_inspect_parsexml, "avm1/xml_inspect_parsexml", 1),
|
2019-10-20 23:06:29 +00:00
|
|
|
(funky_function_calls, "avm1/funky_function_calls", 1),
|
2020-02-18 20:12:47 +00:00
|
|
|
(undefined_to_string_swf6, "avm1/undefined_to_string_swf6", 1),
|
2020-02-19 23:15:35 +00:00
|
|
|
(define_function2_preload, "avm1/define_function2_preload", 1),
|
2020-02-20 19:18:09 +00:00
|
|
|
(define_function2_preload_order, "avm1/define_function2_preload_order", 1),
|
2020-01-15 00:58:32 +00:00
|
|
|
(mcl_as_broadcaster, "avm1/mcl_as_broadcaster", 1),
|
2020-06-20 23:02:45 +00:00
|
|
|
(uncaught_exception, "avm1/uncaught_exception", 1),
|
|
|
|
(uncaught_exception_bubbled, "avm1/uncaught_exception_bubbled", 1),
|
2020-07-01 22:50:57 +00:00
|
|
|
(try_catch_finally, "avm1/try_catch_finally", 1),
|
|
|
|
(try_finally_simple, "avm1/try_finally_simple", 1),
|
2020-01-17 00:20:45 +00:00
|
|
|
(loadmovie, "avm1/loadmovie", 2),
|
2020-01-17 00:33:09 +00:00
|
|
|
(loadmovienum, "avm1/loadmovienum", 2),
|
2020-07-24 17:38:53 +00:00
|
|
|
(loadmovie_registerclass, "avm1/loadmovie_registerclass", 2),
|
2021-04-10 19:50:11 +00:00
|
|
|
(loadmovie_replace_root, "avm1/loadmovie_replace_root", 3),
|
2020-01-17 00:37:38 +00:00
|
|
|
(loadmovie_method, "avm1/loadmovie_method", 2),
|
2021-01-06 12:08:15 +00:00
|
|
|
(loadmovie_fail, "avm1/loadmovie_fail", 1),
|
2020-01-18 01:03:53 +00:00
|
|
|
(unloadmovie, "avm1/unloadmovie", 11),
|
Rewrite some of the unload and cliploader tests to be more generous with load timing.
Loads in Flash Player, like all web technologies, are asynchronous tasks of some kind (probably a separate thread). They appear to operate on some kind of a delay. If I `trace` each frame out, like in the previous version of `mcl_loadclip`, you get a series of events that look like this:
1. Parent frame 1
2. Parent frame 2
3. Event: onLoadStart
4. Event: onLoadProgress
5. Event: onLoadComplete
6. Parent frame 3
7. Event: onLoadInit
If I run that version of the test on Ruffle, everything happens after frame 1. This is an artifact of how we're testing asynchronous behavior in Ruffle. In order to guarantee test determinism, we have a dummy implementation of `fetch` that does a blocking load, and we poll all futures every frame of execution. This means that there is a very specific order of execution with these tests, which is good for testing, but probably isn't 100% accurate.
Flash Player appears to delay all loads by at least one frame, even loads that are coming from disk which should load immediately. I don't know if this is intentional or not, so I don't want to implement a load delay just for the sake of making tests pass. Ergo, I'm loosening the tests to just test the ability to load and unload movies, and fire events from a loader.
Specifically:
1. `mcl_loadclip` no longer traces out frames of the parent timeline
2. `unloadmovie` et. all use a target movie that doesn't fail the test until 10 frames have passed.
If someone can find a movie network that breaks with fast loading, then I'll consider implementing explicit frame delays for async tasks. Otherwise, this is how we're testing this.
2020-01-18 00:00:41 +00:00
|
|
|
(unloadmovienum, "avm1/unloadmovienum", 11),
|
|
|
|
(unloadmovie_method, "avm1/unloadmovie_method", 11),
|
2020-01-18 01:20:49 +00:00
|
|
|
(mcl_loadclip, "avm1/mcl_loadclip", 11),
|
2020-01-18 01:29:56 +00:00
|
|
|
(mcl_unloadclip, "avm1/mcl_unloadclip", 11),
|
2020-01-18 01:54:48 +00:00
|
|
|
(mcl_getprogress, "avm1/mcl_getprogress", 6),
|
2020-07-23 01:22:52 +00:00
|
|
|
(load_vars, "avm1/load_vars", 2),
|
2020-01-18 02:04:10 +00:00
|
|
|
(loadvariables, "avm1/loadvariables", 3),
|
|
|
|
(loadvariablesnum, "avm1/loadvariablesnum", 3),
|
|
|
|
(loadvariables_method, "avm1/loadvariables_method", 3),
|
2020-01-18 03:58:48 +00:00
|
|
|
(xml_load, "avm1/xml_load", 1),
|
2020-07-01 22:24:18 +00:00
|
|
|
(with_return, "avm1/with_return", 1),
|
2020-07-02 18:37:27 +00:00
|
|
|
(watch, "avm1/watch", 1),
|
|
|
|
#[ignore] (watch_virtual_property, "avm1/watch_virtual_property", 1),
|
2020-01-30 04:22:31 +00:00
|
|
|
(cross_movie_root, "avm1/cross_movie_root", 5),
|
2020-02-01 19:44:25 +00:00
|
|
|
(roots_and_levels, "avm1/roots_and_levels", 1),
|
2021-01-20 21:44:49 +00:00
|
|
|
(swf5_encoding, "avm1/swf5_encoding", 1),
|
2020-03-27 06:47:50 +00:00
|
|
|
(swf6_case_insensitive, "avm1/swf6_case_insensitive", 1),
|
|
|
|
(swf7_case_sensitive, "avm1/swf7_case_sensitive", 1),
|
2020-03-28 00:13:39 +00:00
|
|
|
(prototype_enumerate, "avm1/prototype_enumerate", 1),
|
|
|
|
(stage_object_enumerate, "avm1/stage_object_enumerate", 1),
|
2020-06-28 01:22:56 +00:00
|
|
|
(new_object_enumerate, "avm1/new_object_enumerate", 1),
|
2020-04-16 03:08:14 +00:00
|
|
|
(as2_super_and_this_v6, "avm1/as2_super_and_this_v6", 1),
|
|
|
|
(as2_super_and_this_v8, "avm1/as2_super_and_this_v8", 1),
|
2020-04-16 05:59:54 +00:00
|
|
|
(as2_super_via_manual_prototype, "avm1/as2_super_via_manual_prototype", 1),
|
2020-04-18 21:16:51 +00:00
|
|
|
(as1_constructor_v6, "avm1/as1_constructor_v6", 1),
|
|
|
|
(as1_constructor_v7, "avm1/as1_constructor_v7", 1),
|
2020-06-13 09:20:46 +00:00
|
|
|
(issue_710, "avm1/issue_710", 1),
|
2020-09-01 23:42:48 +00:00
|
|
|
(issue_1086, "avm1/issue_1086", 1),
|
2020-09-04 00:52:39 +00:00
|
|
|
(issue_1104, "avm1/issue_1104", 3),
|
2021-01-03 00:05:45 +00:00
|
|
|
(issue_1671, "avm1/issue_1671", 1),
|
2020-12-18 01:43:48 +00:00
|
|
|
(issue_1906, "avm1/issue_1906", 2),
|
2020-12-19 09:46:02 +00:00
|
|
|
(issue_2030, "avm1/issue_2030", 1),
|
2021-01-01 03:01:58 +00:00
|
|
|
(issue_2166, "avm1/issue_2166", 1),
|
2021-01-29 00:11:23 +00:00
|
|
|
(issue_2870, "avm1/issue_2870", 10),
|
2021-02-19 11:30:21 +00:00
|
|
|
(issue_3169, "avm1/issue_3169", 1),
|
2021-03-08 08:52:35 +00:00
|
|
|
(issue_3446, "avm1/issue_3446", 1),
|
2020-09-03 21:09:43 +00:00
|
|
|
(function_as_function, "avm1/function_as_function", 1),
|
2020-07-06 19:18:08 +00:00
|
|
|
(infinite_recursion_function, "avm1/infinite_recursion_function", 1),
|
|
|
|
(infinite_recursion_function_in_setter, "avm1/infinite_recursion_function_in_setter", 1),
|
|
|
|
(infinite_recursion_virtual_property, "avm1/infinite_recursion_virtual_property", 1),
|
2020-05-29 03:38:19 +00:00
|
|
|
(edittext_font_size, "avm1/edittext_font_size", 1),
|
2020-06-13 22:45:54 +00:00
|
|
|
(edittext_default_format, "avm1/edittext_default_format", 1),
|
2020-06-04 03:01:26 +00:00
|
|
|
(edittext_leading, "avm1/edittext_leading", 1),
|
2020-06-08 22:40:21 +00:00
|
|
|
#[ignore] (edittext_newlines, "avm1/edittext_newlines", 1),
|
2020-06-19 04:04:15 +00:00
|
|
|
(edittext_html_entity, "avm1/edittext_html_entity", 1),
|
2021-01-31 20:26:58 +00:00
|
|
|
(edittext_password, "avm1/edittext_password", 1),
|
Implement text span raising, sans list items.
During the raising process, we maintain a list of pointers to the lowest-most `textformat`, `p`, `font`, `a`, `b`, `i`, and `u` in the document that we are appending to. When we get a new one of any of those elements, we clear the rest off the stack. This forces us to add HTML in the same order Flash does.
LIs are not yet supported because they require us to process text line-by-line which doesn't mesh with this model.
There's also a test but the XML DOM generates HTML strings with the wrong attribute order, so the test fails spuriously.
2020-06-20 04:29:39 +00:00
|
|
|
#[ignore] (edittext_html_roundtrip, "avm1/edittext_html_roundtrip", 1),
|
2020-11-01 22:24:33 +00:00
|
|
|
(edittext_newline_stripping, "avm1/edittext_newline_stripping", 1),
|
2020-06-28 08:21:44 +00:00
|
|
|
(define_local, "avm1/define_local", 1),
|
2020-11-21 23:13:27 +00:00
|
|
|
(textfield_properties, "avm1/textfield_properties", 1),
|
2020-12-13 17:57:20 +00:00
|
|
|
(textfield_background_color, "avm1/textfield_background_color", 1),
|
2020-12-13 17:43:54 +00:00
|
|
|
(textfield_border_color, "avm1/textfield_border_color", 1),
|
2020-06-23 06:10:53 +00:00
|
|
|
(textfield_variable, "avm1/textfield_variable", 8),
|
2020-07-03 03:18:30 +00:00
|
|
|
(error, "avm1/error", 1),
|
2020-07-04 20:00:12 +00:00
|
|
|
(color_transform, "avm1/color_transform", 1),
|
2020-07-02 21:25:49 +00:00
|
|
|
(with, "avm1/with", 1),
|
2020-07-21 10:34:01 +00:00
|
|
|
(arguments, "avm1/arguments", 1),
|
2020-07-02 22:10:01 +00:00
|
|
|
(prototype_properties, "avm1/prototype_properties", 1),
|
2020-07-02 22:16:11 +00:00
|
|
|
(stage_object_properties_get_var, "avm1/stage_object_properties_get_var", 1),
|
2020-07-08 02:06:03 +00:00
|
|
|
(set_interval, "avm1/set_interval", 20),
|
2020-07-08 17:59:05 +00:00
|
|
|
(context_menu, "avm1/context_menu", 1),
|
|
|
|
(context_menu_item, "avm1/context_menu_item", 1),
|
2020-07-27 16:24:40 +00:00
|
|
|
(constructor_function, "avm1/constructor_function", 1),
|
2020-07-24 18:06:48 +00:00
|
|
|
(global_array, "avm1/global_array", 1),
|
2020-07-27 19:09:12 +00:00
|
|
|
(array_constructor, "avm1/array_constructor", 1),
|
|
|
|
(array_apply, "avm1/array_constructor", 1),
|
2021-01-11 06:25:00 +00:00
|
|
|
(object_constructor, "avm1/object_constructor", 1),
|
2020-07-27 16:20:49 +00:00
|
|
|
(object_function, "avm1/object_function", 1),
|
2020-08-08 22:01:51 +00:00
|
|
|
(parse_int, "avm1/parse_int", 1),
|
2020-08-23 04:10:14 +00:00
|
|
|
(bitmap_filter, "avm1/bitmap_filter", 1),
|
2020-08-23 23:48:50 +00:00
|
|
|
(blur_filter, "avm1/blur_filter", 1),
|
2020-12-20 23:31:09 +00:00
|
|
|
(glow_filter, "avm1/glow_filter", 1),
|
2020-07-08 18:26:00 +00:00
|
|
|
(date_constructor, "avm1/date/constructor", 1),
|
2020-10-24 20:54:38 +00:00
|
|
|
(removed_clip_halts_script, "avm1/removed_clip_halts_script", 13),
|
2020-08-25 22:39:42 +00:00
|
|
|
(date_utc, "avm1/date/UTC", 1),
|
2020-07-08 18:26:00 +00:00
|
|
|
(date_set_date, "avm1/date/setDate", 1),
|
|
|
|
(date_set_full_year, "avm1/date/setFullYear", 1),
|
|
|
|
(date_set_hours, "avm1/date/setHours", 1),
|
|
|
|
(date_set_milliseconds, "avm1/date/setMilliseconds", 1),
|
|
|
|
(date_set_minutes, "avm1/date/setMinutes", 1),
|
|
|
|
(date_set_month, "avm1/date/setMonth", 1),
|
|
|
|
(date_set_seconds, "avm1/date/setSeconds", 1),
|
|
|
|
(date_set_time, "avm1/date/setTime", 1),
|
|
|
|
(date_set_utc_date, "avm1/date/setUTCDate", 1),
|
|
|
|
(date_set_utc_full_year, "avm1/date/setUTCFullYear", 1),
|
|
|
|
(date_set_utc_hours, "avm1/date/setUTCHours", 1),
|
|
|
|
(date_set_utc_milliseconds, "avm1/date/setUTCMilliseconds", 1),
|
|
|
|
(date_set_utc_minutes, "avm1/date/setUTCMinutes", 1),
|
|
|
|
(date_set_utc_month, "avm1/date/setUTCMonth", 1),
|
|
|
|
(date_set_utc_seconds, "avm1/date/setUTCSeconds", 1),
|
|
|
|
(date_set_year, "avm1/date/setYear", 1),
|
2020-09-02 17:17:47 +00:00
|
|
|
(this_scoping, "avm1/this_scoping", 1),
|
2020-09-21 19:57:27 +00:00
|
|
|
(bevel_filter, "avm1/bevel_filter", 1),
|
2020-12-22 22:17:12 +00:00
|
|
|
(drop_shadow_filter, "avm1/drop_shadow_filter", 1),
|
2020-12-29 11:10:46 +00:00
|
|
|
(color_matrix_filter, "avm1/color_matrix_filter", 1),
|
2021-01-02 02:32:53 +00:00
|
|
|
(displacement_map_filter, "avm1/displacement_map_filter", 1),
|
2021-01-05 02:26:11 +00:00
|
|
|
(convolution_filter, "avm1/convolution_filter", 1),
|
2021-01-05 20:02:31 +00:00
|
|
|
(gradient_bevel_filter, "avm1/gradient_bevel_filter", 1),
|
2021-01-06 20:28:31 +00:00
|
|
|
(gradient_glow_filter, "avm1/gradient_glow_filter", 1),
|
2020-10-05 23:53:43 +00:00
|
|
|
(bitmap_data, "avm1/bitmap_data", 1),
|
2021-04-24 22:51:23 +00:00
|
|
|
(bitmap_data_max_size_swf9, "avm1/bitmap_data_max_size_swf9", 1),
|
|
|
|
(bitmap_data_max_size_swf10, "avm1/bitmap_data_max_size_swf10", 1),
|
2021-01-17 00:10:55 +00:00
|
|
|
(bitmap_data_noise, "avm1/bitmap_data_noise", 1),
|
2020-12-30 18:00:19 +00:00
|
|
|
(array_call_method, "avm1/array_call_method", 1),
|
2021-02-03 00:46:58 +00:00
|
|
|
(bad_placeobject_clipaction, "avm1/bad_placeobject_clipaction", 2),
|
2021-01-21 21:02:54 +00:00
|
|
|
(bad_swf_tag_past_eof, "avm1/bad_swf_tag_past_eof", 1),
|
2021-01-26 02:42:51 +00:00
|
|
|
(sound, "avm1/sound", 1),
|
2021-01-30 03:07:15 +00:00
|
|
|
(action_to_integer, "avm1/action_to_integer", 1),
|
2020-02-24 03:28:37 +00:00
|
|
|
(as3_hello_world, "avm2/hello_world", 1),
|
2020-02-24 19:12:51 +00:00
|
|
|
(as3_function_call, "avm2/function_call", 1),
|
2020-03-09 02:29:15 +00:00
|
|
|
(as3_function_call_via_call, "avm2/function_call_via_call", 1),
|
2020-02-24 23:01:57 +00:00
|
|
|
(as3_constructor_call, "avm2/constructor_call", 1),
|
2020-02-26 02:39:37 +00:00
|
|
|
(as3_class_methods, "avm2/class_methods", 1),
|
2020-03-09 02:39:32 +00:00
|
|
|
(as3_es3_inheritance, "avm2/es3_inheritance", 1),
|
|
|
|
(as3_es4_inheritance, "avm2/es4_inheritance", 1),
|
2020-02-29 03:31:47 +00:00
|
|
|
(as3_stored_properties, "avm2/stored_properties", 1),
|
2020-02-29 02:41:19 +00:00
|
|
|
(as3_virtual_properties, "avm2/virtual_properties", 1),
|
2020-03-04 01:06:07 +00:00
|
|
|
(as3_es4_oop_prototypes, "avm2/es4_oop_prototypes", 1),
|
2020-03-04 03:10:46 +00:00
|
|
|
(as3_es4_method_binding, "avm2/es4_method_binding", 1),
|
2020-03-04 19:25:44 +00:00
|
|
|
(as3_control_flow_bool, "avm2/control_flow_bool", 1),
|
|
|
|
(as3_control_flow_stricteq, "avm2/control_flow_stricteq", 1),
|
2020-03-06 02:31:34 +00:00
|
|
|
(as3_object_enumeration, "avm2/object_enumeration", 1),
|
|
|
|
(as3_class_enumeration, "avm2/class_enumeration", 1),
|
2020-03-06 20:33:04 +00:00
|
|
|
(as3_is_prototype_of, "avm2/is_prototype_of", 1),
|
2020-03-07 04:16:10 +00:00
|
|
|
(as3_has_own_property, "avm2/has_own_property", 1),
|
2020-03-08 01:17:07 +00:00
|
|
|
(as3_property_is_enumerable, "avm2/property_is_enumerable", 1),
|
2020-03-08 23:12:40 +00:00
|
|
|
(as3_set_property_is_enumerable, "avm2/set_property_is_enumerable", 1),
|
2020-03-09 00:12:31 +00:00
|
|
|
(as3_object_to_string, "avm2/object_to_string", 1),
|
|
|
|
(as3_function_to_string, "avm2/function_to_string", 1),
|
|
|
|
(as3_class_to_string, "avm2/class_to_string", 1),
|
2020-03-09 02:38:10 +00:00
|
|
|
(as3_object_to_locale_string, "avm2/object_to_locale_string", 1),
|
|
|
|
(as3_function_to_locale_string, "avm2/function_to_locale_string", 1),
|
|
|
|
(as3_class_to_locale_string, "avm2/class_to_locale_string", 1),
|
2020-03-09 02:49:52 +00:00
|
|
|
(as3_object_value_of, "avm2/object_value_of", 1),
|
|
|
|
(as3_function_value_of, "avm2/function_value_of", 1),
|
|
|
|
(as3_class_value_of, "avm2/class_value_of", 1),
|
2020-03-09 03:12:52 +00:00
|
|
|
(as3_if_stricteq, "avm2/if_stricteq", 1),
|
|
|
|
(as3_if_strictne, "avm2/if_strictne", 1),
|
|
|
|
(as3_strict_equality, "avm2/strict_equality", 1),
|
2020-07-08 02:11:00 +00:00
|
|
|
(as3_es4_interfaces, "avm2/es4_interfaces", 1),
|
2020-12-28 05:30:11 +00:00
|
|
|
(as3_is_finite, "avm2/is_finite", 1),
|
2020-12-28 04:40:47 +00:00
|
|
|
(as3_is_nan, "avm2/is_nan", 1),
|
2020-07-09 02:35:20 +00:00
|
|
|
(as3_istype, "avm2/istype", 1),
|
2021-04-12 21:26:48 +00:00
|
|
|
(as3_istypelate, "avm2/istypelate", 1),
|
2020-07-09 02:35:20 +00:00
|
|
|
(as3_instanceof, "avm2/instanceof", 1),
|
2021-04-12 21:04:02 +00:00
|
|
|
(as3_astype, "avm2/astype", 1),
|
2021-04-12 08:53:49 +00:00
|
|
|
(as3_astypelate, "avm2/astypelate", 1),
|
2020-06-23 23:28:33 +00:00
|
|
|
(as3_truthiness, "avm2/truthiness", 1),
|
2020-06-24 01:39:38 +00:00
|
|
|
(as3_falsiness, "avm2/falsiness", 1),
|
2020-06-24 01:47:06 +00:00
|
|
|
(as3_boolean_negation, "avm2/boolean_negation", 1),
|
2020-06-24 01:59:51 +00:00
|
|
|
(as3_convert_boolean, "avm2/convert_boolean", 1),
|
2020-06-24 03:43:43 +00:00
|
|
|
(as3_convert_number, "avm2/convert_number", 1),
|
2020-06-26 04:09:42 +00:00
|
|
|
(as3_convert_integer, "avm2/convert_integer", 1),
|
2020-06-27 01:55:54 +00:00
|
|
|
(as3_convert_uinteger, "avm2/convert_uinteger", 1),
|
2020-06-27 20:37:48 +00:00
|
|
|
(as3_coerce_string, "avm2/coerce_string", 1),
|
2020-07-10 01:09:15 +00:00
|
|
|
(as3_if_eq, "avm2/if_eq", 1),
|
|
|
|
(as3_if_ne, "avm2/if_ne", 1),
|
2020-07-10 01:46:17 +00:00
|
|
|
(as3_equals, "avm2/equals", 1),
|
2020-07-12 00:30:48 +00:00
|
|
|
(as3_if_lt, "avm2/if_lt", 1),
|
|
|
|
(as3_if_lte, "avm2/if_lte", 1),
|
|
|
|
(as3_if_gte, "avm2/if_gte", 1),
|
|
|
|
(as3_if_gt, "avm2/if_gt", 1),
|
2020-07-15 03:05:31 +00:00
|
|
|
(as3_greaterequals, "avm2/greaterequals", 1),
|
|
|
|
(as3_greaterthan, "avm2/greaterthan", 1),
|
|
|
|
(as3_lessequals, "avm2/lessequals", 1),
|
|
|
|
(as3_lessthan, "avm2/lessthan", 1),
|
2020-08-11 23:05:07 +00:00
|
|
|
(nested_textfields_in_buttons, "avm1/nested_textfields_in_buttons", 1),
|
2020-08-17 20:10:23 +00:00
|
|
|
(conflicting_instance_names, "avm1/conflicting_instance_names", 6),
|
2020-08-17 22:02:33 +00:00
|
|
|
(button_children, "avm1/button_children", 1),
|
2020-08-20 11:56:33 +00:00
|
|
|
(transform, "avm1/transform", 1),
|
2021-01-17 15:21:59 +00:00
|
|
|
(target_clip_swf5, "avm1/target_clip_swf5", 2),
|
2021-01-17 16:57:13 +00:00
|
|
|
(target_clip_swf6, "avm1/target_clip_swf6", 2),
|
2020-08-20 21:49:33 +00:00
|
|
|
(target_path, "avm1/target_path", 1),
|
2021-01-10 00:49:59 +00:00
|
|
|
(remove_movie_clip, "avm1/remove_movie_clip", 2),
|
2020-08-23 20:38:38 +00:00
|
|
|
(as3_add, "avm2/add", 1),
|
2021-03-20 21:49:55 +00:00
|
|
|
(as3_bitor, "avm2/bitor", 1),
|
2020-08-23 20:38:38 +00:00
|
|
|
(as3_bitand, "avm2/bitand", 1),
|
|
|
|
(as3_bitnot, "avm2/bitnot", 1),
|
2021-03-20 21:49:55 +00:00
|
|
|
(as3_bitxor, "avm2/bitxor", 1),
|
2020-08-23 20:38:38 +00:00
|
|
|
(as3_declocal, "avm2/declocal", 1),
|
|
|
|
(as3_declocal_i, "avm2/declocal_i", 1),
|
|
|
|
(as3_decrement, "avm2/decrement", 1),
|
|
|
|
(as3_decrement_i, "avm2/decrement_i", 1),
|
|
|
|
(as3_inclocal, "avm2/inclocal", 1),
|
|
|
|
(as3_inclocal_i, "avm2/inclocal_i", 1),
|
|
|
|
(as3_increment, "avm2/increment", 1),
|
|
|
|
(as3_increment_i, "avm2/increment_i", 1),
|
|
|
|
(as3_lshift, "avm2/lshift", 1),
|
|
|
|
(as3_modulo, "avm2/modulo", 1),
|
|
|
|
(as3_multiply, "avm2/multiply", 1),
|
|
|
|
(as3_negate, "avm2/negate", 1),
|
|
|
|
(as3_rshift, "avm2/rshift", 1),
|
|
|
|
(as3_subtract, "avm2/subtract", 1),
|
|
|
|
(as3_urshift, "avm2/urshift", 1),
|
2020-09-04 01:47:26 +00:00
|
|
|
(as3_in, "avm2/in", 1),
|
2021-03-05 23:01:02 +00:00
|
|
|
(as3_bytearray, "avm2/bytearray", 1),
|
2020-08-27 23:32:10 +00:00
|
|
|
(as3_array_constr, "avm2/array_constr", 1),
|
2020-08-28 03:11:34 +00:00
|
|
|
(as3_array_access, "avm2/array_access", 1),
|
2020-08-28 23:06:15 +00:00
|
|
|
(as3_array_storage, "avm2/array_storage", 1),
|
2020-08-29 02:33:45 +00:00
|
|
|
(as3_array_delete, "avm2/array_delete", 1),
|
2020-08-29 02:54:23 +00:00
|
|
|
(as3_array_holes, "avm2/array_holes", 1),
|
2020-08-29 03:20:00 +00:00
|
|
|
(as3_array_literal, "avm2/array_literal", 1),
|
2020-08-29 18:06:41 +00:00
|
|
|
(as3_array_concat, "avm2/array_concat", 1),
|
2020-08-29 19:42:08 +00:00
|
|
|
(as3_array_tostring, "avm2/array_tostring", 1),
|
2020-09-02 23:28:55 +00:00
|
|
|
(as3_array_tolocalestring, "avm2/array_tolocalestring", 1),
|
2020-08-29 19:42:08 +00:00
|
|
|
(as3_array_valueof, "avm2/array_valueof", 1),
|
|
|
|
(as3_array_join, "avm2/array_join", 1),
|
2020-08-29 21:55:09 +00:00
|
|
|
(as3_array_foreach, "avm2/array_foreach", 1),
|
|
|
|
(as3_array_map, "avm2/array_map", 1),
|
|
|
|
(as3_array_filter, "avm2/array_filter", 1),
|
|
|
|
(as3_array_every, "avm2/array_every", 1),
|
|
|
|
(as3_array_some, "avm2/array_some", 1),
|
2020-08-29 23:44:22 +00:00
|
|
|
(as3_array_indexof, "avm2/array_indexof", 1),
|
|
|
|
(as3_array_lastindexof, "avm2/array_lastindexof", 1),
|
2020-08-30 03:39:40 +00:00
|
|
|
(as3_array_push, "avm2/array_push", 1),
|
|
|
|
(as3_array_pop, "avm2/array_pop", 1),
|
2020-09-01 00:46:57 +00:00
|
|
|
(as3_array_reverse, "avm2/array_reverse", 1),
|
2020-09-01 01:49:55 +00:00
|
|
|
(as3_array_shift, "avm2/array_shift", 1),
|
|
|
|
(as3_array_unshift, "avm2/array_unshift", 1),
|
2020-09-01 03:15:03 +00:00
|
|
|
(as3_array_slice, "avm2/array_slice", 1),
|
2020-09-02 03:36:09 +00:00
|
|
|
(as3_array_splice, "avm2/array_splice", 1),
|
2020-09-04 00:22:42 +00:00
|
|
|
(as3_array_sort, "avm2/array_sort", 1),
|
2020-09-05 22:50:43 +00:00
|
|
|
(as3_array_sorton, "avm2/array_sorton", 1),
|
2020-09-14 23:52:36 +00:00
|
|
|
(as3_array_hasownproperty, "avm2/array_hasownproperty", 1),
|
2021-02-07 10:57:30 +00:00
|
|
|
(as3_array_length, "avm2/array_length", 1),
|
2020-09-25 22:50:05 +00:00
|
|
|
(stage_property_representation, "avm1/stage_property_representation", 1),
|
2020-08-18 02:32:03 +00:00
|
|
|
(as3_timeline_scripts, "avm2/timeline_scripts", 3),
|
2020-08-21 02:12:08 +00:00
|
|
|
(as3_movieclip_properties, "avm2/movieclip_properties", 4),
|
2020-09-22 01:26:13 +00:00
|
|
|
(as3_movieclip_gotoandplay, "avm2/movieclip_gotoandplay", 5),
|
|
|
|
(as3_movieclip_gotoandstop, "avm2/movieclip_gotoandstop", 5),
|
2020-08-21 22:44:17 +00:00
|
|
|
(as3_movieclip_stop, "avm2/movieclip_stop", 5),
|
2020-08-22 01:12:27 +00:00
|
|
|
(as3_movieclip_prev_frame, "avm2/movieclip_prev_frame", 5),
|
|
|
|
(as3_movieclip_next_frame, "avm2/movieclip_next_frame", 5),
|
2020-08-22 20:17:17 +00:00
|
|
|
(as3_movieclip_prev_scene, "avm2/movieclip_prev_scene", 5),
|
|
|
|
(as3_movieclip_next_scene, "avm2/movieclip_next_scene", 5),
|
2020-09-17 01:32:00 +00:00
|
|
|
(as3_framelabel_constr, "avm2/framelabel_constr", 5),
|
2020-09-18 00:58:36 +00:00
|
|
|
(as3_movieclip_currentlabels, "avm2/movieclip_currentlabels", 5),
|
2020-09-18 01:56:48 +00:00
|
|
|
(as3_scene_constr, "avm2/scene_constr", 5),
|
2020-09-19 02:05:16 +00:00
|
|
|
(as3_movieclip_currentscene, "avm2/movieclip_currentscene", 5),
|
2020-09-19 03:09:27 +00:00
|
|
|
(as3_movieclip_scenes, "avm2/movieclip_scenes", 5),
|
2020-09-22 00:51:29 +00:00
|
|
|
(as3_movieclip_play, "avm2/movieclip_play", 5),
|
2020-09-23 03:02:31 +00:00
|
|
|
(as3_movieclip_constr, "avm2/movieclip_constr", 1),
|
2020-10-09 02:08:58 +00:00
|
|
|
(as3_lazyinit, "avm2/lazyinit", 1),
|
2020-11-11 00:30:01 +00:00
|
|
|
(as3_trace, "avm2/trace", 1),
|
2020-10-10 01:35:09 +00:00
|
|
|
(as3_displayobjectcontainer_getchildat, "avm2/displayobjectcontainer_getchildat", 1),
|
2020-10-18 04:25:07 +00:00
|
|
|
(as3_displayobjectcontainer_getchildbyname, "avm2/displayobjectcontainer_getchildbyname", 1),
|
2020-10-29 23:33:09 +00:00
|
|
|
(as3_displayobjectcontainer_addchild, "avm2/displayobjectcontainer_addchild", 1),
|
|
|
|
(as3_displayobjectcontainer_addchildat, "avm2/displayobjectcontainer_addchildat", 1),
|
2020-10-29 23:44:01 +00:00
|
|
|
(as3_displayobjectcontainer_removechild, "avm2/displayobjectcontainer_removechild", 1),
|
2020-11-05 02:03:58 +00:00
|
|
|
(as3_displayobjectcontainer_removechild_timelinemanip_remove1, "avm2/displayobjectcontainer_removechild_timelinemanip_remove1", 7),
|
2020-11-03 21:47:18 +00:00
|
|
|
(as3_displayobjectcontainer_addchild_timelinepull0, "avm2/displayobjectcontainer_addchild_timelinepull0", 7),
|
|
|
|
(as3_displayobjectcontainer_addchild_timelinepull1, "avm2/displayobjectcontainer_addchild_timelinepull1", 7),
|
|
|
|
(as3_displayobjectcontainer_addchild_timelinepull2, "avm2/displayobjectcontainer_addchild_timelinepull2", 7),
|
|
|
|
(as3_displayobjectcontainer_addchildat_timelinelock0, "avm2/displayobjectcontainer_addchildat_timelinelock0", 7),
|
|
|
|
(as3_displayobjectcontainer_addchildat_timelinelock1, "avm2/displayobjectcontainer_addchildat_timelinelock1", 7),
|
|
|
|
(as3_displayobjectcontainer_addchildat_timelinelock2, "avm2/displayobjectcontainer_addchildat_timelinelock2", 7),
|
2020-11-05 01:59:00 +00:00
|
|
|
(as3_displayobjectcontainer_contains, "avm2/displayobjectcontainer_contains", 5),
|
2020-11-06 02:37:00 +00:00
|
|
|
(as3_displayobjectcontainer_getchildindex, "avm2/displayobjectcontainer_getchildindex", 5),
|
2020-11-11 03:12:18 +00:00
|
|
|
(as3_displayobjectcontainer_removechildat, "avm2/displayobjectcontainer_removechildat", 1),
|
2020-11-11 03:58:59 +00:00
|
|
|
(as3_displayobjectcontainer_removechildren, "avm2/displayobjectcontainer_removechildren", 5),
|
2020-11-12 00:07:11 +00:00
|
|
|
(as3_displayobjectcontainer_setchildindex, "avm2/displayobjectcontainer_setchildindex", 1),
|
2020-11-12 02:38:01 +00:00
|
|
|
(as3_displayobjectcontainer_swapchildren, "avm2/displayobjectcontainer_swapchildren", 1),
|
|
|
|
(as3_displayobjectcontainer_swapchildrenat, "avm2/displayobjectcontainer_swapchildrenat", 1),
|
2020-11-12 02:49:36 +00:00
|
|
|
(button_order, "avm1/button_order", 1),
|
2020-11-13 03:18:42 +00:00
|
|
|
(as3_displayobjectcontainer_stopallmovieclips, "avm2/displayobjectcontainer_stopallmovieclips", 2),
|
2020-11-14 20:47:33 +00:00
|
|
|
(as3_displayobjectcontainer_timelineinstance, "avm2/displayobjectcontainer_timelineinstance", 6),
|
2020-11-28 00:37:12 +00:00
|
|
|
(as3_displayobject_alpha, "avm2/displayobject_alpha", 1),
|
2020-11-28 00:36:38 +00:00
|
|
|
(as3_displayobject_x, "avm2/displayobject_x", 1),
|
|
|
|
(as3_displayobject_y, "avm2/displayobject_y", 1),
|
2020-11-28 19:18:37 +00:00
|
|
|
(as3_displayobject_name, "avm2/displayobject_name", 4),
|
2020-12-01 02:29:32 +00:00
|
|
|
(as3_displayobject_parent, "avm2/displayobject_parent", 4),
|
2020-12-02 03:27:07 +00:00
|
|
|
(as3_displayobject_root, "avm2/displayobject_root", 4),
|
2020-12-03 03:17:49 +00:00
|
|
|
(as3_displayobject_visible, "avm2/displayobject_visible", 4),
|
2020-12-04 02:24:18 +00:00
|
|
|
(as3_displayobject_hittestpoint, "avm2/displayobject_hittestpoint", 2),
|
2020-12-04 23:34:04 +00:00
|
|
|
(as3_displayobject_hittestobject, "avm2/displayobject_hittestobject", 1),
|
2020-12-08 02:37:43 +00:00
|
|
|
(as3_event_valueof_tostring, "avm2/event_valueof_tostring", 1),
|
2020-12-08 02:54:32 +00:00
|
|
|
(as3_event_bubbles, "avm2/event_bubbles", 1),
|
|
|
|
(as3_event_cancelable, "avm2/event_cancelable", 1),
|
|
|
|
(as3_event_type, "avm2/event_type", 1),
|
2020-12-09 01:48:11 +00:00
|
|
|
(as3_event_clone, "avm2/event_clone", 1),
|
2020-12-09 03:34:36 +00:00
|
|
|
(as3_event_formattostring, "avm2/event_formattostring", 1),
|
2020-12-09 23:09:24 +00:00
|
|
|
(as3_event_isdefaultprevented, "avm2/event_isdefaultprevented", 1),
|
2020-12-11 00:41:56 +00:00
|
|
|
(as3_function_call_via_apply, "avm2/function_call_via_apply", 1),
|
2020-12-11 03:21:36 +00:00
|
|
|
(as3_function_call_arguments, "avm2/function_call_arguments", 1),
|
2020-12-11 03:51:10 +00:00
|
|
|
(as3_function_call_rest, "avm2/function_call_rest", 1),
|
2020-12-18 02:09:33 +00:00
|
|
|
(as3_eventdispatcher_haseventlistener, "avm2/eventdispatcher_haseventlistener", 1),
|
2020-12-18 04:10:30 +00:00
|
|
|
(as3_eventdispatcher_willtrigger, "avm2/eventdispatcher_willtrigger", 1),
|
|
|
|
(as3_movieclip_willtrigger, "avm2/movieclip_willtrigger", 3),
|
2020-12-19 18:50:45 +00:00
|
|
|
(as3_eventdispatcher_dispatchevent, "avm2/eventdispatcher_dispatchevent", 1),
|
|
|
|
(as3_eventdispatcher_dispatchevent_handlerorder, "avm2/eventdispatcher_dispatchevent_handlerorder", 1),
|
|
|
|
(as3_eventdispatcher_dispatchevent_cancel, "avm2/eventdispatcher_dispatchevent_cancel", 1),
|
|
|
|
(as3_eventdispatcher_dispatchevent_this, "avm2/eventdispatcher_dispatchevent_this", 1),
|
|
|
|
(as3_movieclip_dispatchevent, "avm2/movieclip_dispatchevent", 1),
|
|
|
|
(as3_movieclip_dispatchevent_handlerorder, "avm2/movieclip_dispatchevent_handlerorder", 1),
|
|
|
|
(as3_movieclip_dispatchevent_cancel, "avm2/movieclip_dispatchevent_cancel", 1),
|
|
|
|
(as3_movieclip_dispatchevent_target, "avm2/movieclip_dispatchevent_target", 1),
|
|
|
|
(as3_movieclip_dispatchevent_selfadd, "avm2/movieclip_dispatchevent_selfadd", 1),
|
2021-02-06 09:48:28 +00:00
|
|
|
(as3_string_constr, "avm2/string_constr", 1),
|
2021-02-06 09:55:28 +00:00
|
|
|
(as3_string_length, "avm2/string_length", 1),
|
2021-02-06 10:50:08 +00:00
|
|
|
(as3_string_char_at, "avm2/string_char_at", 1),
|
2021-02-06 11:08:15 +00:00
|
|
|
(as3_string_char_code_at, "avm2/string_char_code_at", 1),
|
2021-01-15 22:35:10 +00:00
|
|
|
(as3_typeof, "avm2/typeof", 1),
|
2021-02-17 17:05:58 +00:00
|
|
|
(use_hand_cursor, "avm1/use_hand_cursor", 1),
|
2021-01-15 03:26:15 +00:00
|
|
|
(as3_movieclip_displayevents, "avm2/movieclip_displayevents", 9),
|
2021-01-19 02:43:38 +00:00
|
|
|
(as3_movieclip_displayevents_timeline, "avm2/movieclip_displayevents_timeline", 5),
|
|
|
|
(as3_movieclip_displayevents_looping, "avm2/movieclip_displayevents_looping", 5),
|
2021-02-24 02:49:42 +00:00
|
|
|
(as3_movieclip_displayevents_dblhandler, "avm2/movieclip_displayevents_dblhandler", 4),
|
2021-02-23 08:02:24 +00:00
|
|
|
(as3_regexp_constr, "avm2/regexp_constr", 1),
|
2021-02-23 09:08:48 +00:00
|
|
|
(as3_regexp_test, "avm2/regexp_test", 1),
|
2021-02-23 09:37:31 +00:00
|
|
|
(as3_regexp_exec, "avm2/regexp_exec", 1),
|
2021-03-18 19:03:04 +00:00
|
|
|
(as3_point, "avm2/point", 1),
|
2021-03-04 02:12:42 +00:00
|
|
|
(as3_edittext_default_format, "avm2/edittext_default_format", 1),
|
|
|
|
(as3_edittext_html_entity, "avm2/edittext_html_entity", 1),
|
|
|
|
#[ignore] (as3_edittext_html_roundtrip, "avm2/edittext_html_roundtrip", 1),
|
|
|
|
(as3_edittext_newline_stripping, "avm2/edittext_newline_stripping", 1),
|
2021-03-06 02:20:33 +00:00
|
|
|
(as3_shape_drawrect, "avm2/shape_drawrect", 1),
|
2021-03-06 02:24:26 +00:00
|
|
|
(as3_movieclip_drawrect, "avm2/movieclip_drawrect", 1),
|
2021-03-27 16:59:56 +00:00
|
|
|
(as3_get_timer, "avm2/get_timer", 1),
|
2021-03-30 00:42:36 +00:00
|
|
|
(as3_op_escxattr, "avm2/op_escxattr", 1),
|
2021-03-30 00:47:47 +00:00
|
|
|
(as3_op_escxelem, "avm2/op_escxelem", 1),
|
2021-03-30 16:25:20 +00:00
|
|
|
(as3_op_lookupswitch, "avm2/op_lookupswitch", 1),
|
2021-03-21 02:34:25 +00:00
|
|
|
(as3_loaderinfo_properties, "avm2/loaderinfo_properties", 2),
|
2021-03-22 22:35:43 +00:00
|
|
|
(as3_loaderinfo_quine, "avm2/loaderinfo_quine", 2),
|
2021-04-06 21:59:50 +00:00
|
|
|
(nan_scale, "avm1/nan_scale", 1),
|
2021-04-07 12:33:47 +00:00
|
|
|
(as3_nan_scale, "avm2/nan_scale", 1),
|
2021-04-09 01:22:43 +00:00
|
|
|
(as3_documentclass, "avm2/documentclass", 1),
|
2021-04-15 18:47:18 +00:00
|
|
|
(timer_run_actions, "avm1/timer_run_actions", 1),
|
2021-04-04 18:49:40 +00:00
|
|
|
(as3_op_coerce, "avm2/op_coerce", 1),
|
2021-04-03 19:50:07 +00:00
|
|
|
(as3_domain_memory, "avm2/domain_memory", 1),
|
2021-04-10 02:38:06 +00:00
|
|
|
(as3_movieclip_symbol_constr, "avm2/movieclip_symbol_constr", 1),
|
2021-04-17 21:44:07 +00:00
|
|
|
(as3_stage_access, "avm2/stage_access", 1),
|
2021-04-21 22:33:41 +00:00
|
|
|
(as3_stage_displayobject_properties, "avm2/stage_displayobject_properties", 1),
|
2021-04-18 02:03:12 +00:00
|
|
|
(as3_stage_loaderinfo_properties, "avm2/stage_loaderinfo_properties", 2),
|
2021-04-21 22:33:41 +00:00
|
|
|
(as3_stage_properties, "avm2/stage_properties", 1),
|
2021-04-07 02:32:38 +00:00
|
|
|
(as3_closures, "avm2/closures", 1),
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
|
2020-02-17 20:32:25 +00:00
|
|
|
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.
|
2020-02-21 02:25:26 +00:00
|
|
|
// Eventually we can hopefully make some of these match exactly (see #193).
|
|
|
|
// Some will probably always need to be approx. (if they rely on trig functions, etc.)
|
2020-02-17 20:32:25 +00:00
|
|
|
swf_tests_approx! {
|
2020-11-11 10:32:23 +00:00
|
|
|
(local_to_global, "avm1/local_to_global", 1, epsilon = 0.051),
|
2020-11-21 04:32:07 +00:00
|
|
|
(stage_object_properties, "avm1/stage_object_properties", 6, epsilon = 0.051),
|
2020-11-11 10:32:23 +00:00
|
|
|
(stage_object_properties_swf6, "avm1/stage_object_properties_swf6", 4, epsilon = 0.051),
|
|
|
|
(movieclip_getbounds, "avm1/movieclip_getbounds", 1, epsilon = 0.051),
|
2021-02-12 12:09:04 +00:00
|
|
|
(parse_float, "avm1/parse_float", 1, max_relative = 5.0 * f64::EPSILON),
|
2020-11-11 10:32:23 +00:00
|
|
|
(edittext_letter_spacing, "avm1/edittext_letter_spacing", 1, epsilon = 15.0), // TODO: Discrepancy in wrapping in letterSpacing = 0.1 test.
|
|
|
|
(edittext_align, "avm1/edittext_align", 1, epsilon = 3.0),
|
2021-02-08 18:06:30 +00:00
|
|
|
(edittext_autosize, "avm1/edittext_autosize", 1, epsilon = 4.0), // TODO Flash has _width higher by 4.0, probably padding logic mistake
|
2020-11-11 10:32:23 +00:00
|
|
|
(edittext_margins, "avm1/edittext_margins", 1, epsilon = 5.0), // TODO: Discrepancy in wrapping.
|
|
|
|
(edittext_tab_stops, "avm1/edittext_tab_stops", 1, epsilon = 5.0),
|
|
|
|
(edittext_bullet, "avm1/edittext_bullet", 1, epsilon = 3.0),
|
|
|
|
(edittext_underline, "avm1/edittext_underline", 1, epsilon = 4.0),
|
2021-02-12 12:09:04 +00:00
|
|
|
(as3_coerce_string_precision, "avm2/coerce_string_precision", 1, max_relative = 30.0 * f64::EPSILON),
|
2020-11-11 10:32:23 +00:00
|
|
|
(as3_divide, "avm2/divide", 1, epsilon = 0.0), // TODO: Discrepancy in float formatting.
|
2021-02-12 12:09:04 +00:00
|
|
|
(as3_math, "avm2/math", 1, max_relative = 30.0 * f64::EPSILON),
|
2020-11-27 23:49:47 +00:00
|
|
|
(as3_displayobject_height, "avm2/displayobject_height", 7, epsilon = 0.06), // TODO: height/width appears to be off by 1 twip sometimes
|
|
|
|
(as3_displayobject_width, "avm2/displayobject_width", 7, epsilon = 0.06),
|
2020-11-28 02:15:58 +00:00
|
|
|
(as3_displayobject_rotation, "avm2/displayobject_rotation", 1, epsilon = 0.0000000001),
|
2021-03-04 02:12:42 +00:00
|
|
|
(as3_edittext_align, "avm2/edittext_align", 1, epsilon = 3.0),
|
2021-03-04 23:50:54 +00:00
|
|
|
(as3_edittext_autosize, "avm2/edittext_autosize", 1, epsilon = 5.0), // TODO AS3 has _width higher by 5.0, probably padding logic mistake
|
2021-03-04 02:12:42 +00:00
|
|
|
(as3_edittext_bullet, "avm2/edittext_bullet", 1, epsilon = 3.0),
|
|
|
|
(as3_edittext_letter_spacing, "avm2/edittext_letter_spacing", 1, epsilon = 15.0), // TODO: Discrepancy in wrapping in letterSpacing = 0.1 test.
|
|
|
|
(as3_edittext_margins, "avm2/edittext_margins", 1, epsilon = 5.0), // TODO: Discrepancy in wrapping.
|
|
|
|
(as3_edittext_tab_stops, "avm2/edittext_tab_stops", 1, epsilon = 5.0),
|
|
|
|
(as3_edittext_underline, "avm2/edittext_underline", 1, epsilon = 4.0),
|
2021-03-04 23:50:54 +00:00
|
|
|
(as3_edittext_leading, "avm2/edittext_leading", 1, epsilon = 0.3),
|
|
|
|
(as3_edittext_font_size, "avm2/edittext_font_size", 1, epsilon = 0.1),
|
2020-02-17 20:32:25 +00:00
|
|
|
}
|
|
|
|
|
2020-08-28 10:19:22 +00:00
|
|
|
#[test]
|
|
|
|
fn external_interface_avm1() -> Result<(), Error> {
|
2021-02-12 09:57:03 +00:00
|
|
|
set_logger();
|
2021-03-20 21:50:57 +00:00
|
|
|
test_swf_with_hooks(
|
2020-08-28 10:19:22 +00:00
|
|
|
"tests/swfs/avm1/external_interface/test.swf",
|
|
|
|
1,
|
|
|
|
"tests/swfs/avm1/external_interface/output.txt",
|
|
|
|
|player| {
|
|
|
|
player
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.add_external_interface(Box::new(ExternalInterfaceTestProvider::new()));
|
|
|
|
Ok(())
|
|
|
|
},
|
2020-08-28 10:24:19 +00:00
|
|
|
|player| {
|
2020-08-28 15:24:26 +00:00
|
|
|
let mut player_locked = player.lock().unwrap();
|
|
|
|
|
2020-09-05 19:06:17 +00:00
|
|
|
let parroted =
|
|
|
|
player_locked.call_internal_interface("parrot", vec!["Hello World!".into()]);
|
2020-09-05 19:10:46 +00:00
|
|
|
player_locked.log_backend().avm_trace(&format!(
|
2020-09-05 19:06:17 +00:00
|
|
|
"After calling `parrot` with a string: {:?}",
|
|
|
|
parroted
|
|
|
|
));
|
2020-08-28 15:24:26 +00:00
|
|
|
|
|
|
|
let mut nested = BTreeMap::new();
|
|
|
|
nested.insert(
|
|
|
|
"list".to_string(),
|
|
|
|
vec![
|
|
|
|
"string".into(),
|
|
|
|
100.into(),
|
|
|
|
false.into(),
|
|
|
|
ExternalValue::Object(BTreeMap::new()),
|
|
|
|
]
|
|
|
|
.into(),
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut root = BTreeMap::new();
|
|
|
|
root.insert("number".to_string(), (-500.1).into());
|
|
|
|
root.insert("string".to_string(), "A string!".into());
|
|
|
|
root.insert("true".to_string(), true.into());
|
|
|
|
root.insert("false".to_string(), false.into());
|
|
|
|
root.insert("null".to_string(), ExternalValue::Null);
|
|
|
|
root.insert("nested".to_string(), nested.into());
|
2020-09-05 19:06:17 +00:00
|
|
|
let result = player_locked
|
|
|
|
.call_internal_interface("callWith", vec!["trace".into(), root.into()]);
|
2020-09-05 19:10:46 +00:00
|
|
|
player_locked.log_backend().avm_trace(&format!(
|
2020-09-05 19:06:17 +00:00
|
|
|
"After calling `callWith` with a complex payload: {:?}",
|
|
|
|
result
|
|
|
|
));
|
2020-08-28 10:24:19 +00:00
|
|
|
Ok(())
|
|
|
|
},
|
2020-08-28 10:19:22 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-02-05 03:09:51 +00:00
|
|
|
#[test]
|
|
|
|
fn shared_object_avm1() -> Result<(), Error> {
|
2021-02-12 09:57:03 +00:00
|
|
|
set_logger();
|
2021-02-05 03:09:51 +00:00
|
|
|
// Test SharedObject persistence. Run an SWF that saves data
|
|
|
|
// to a shared object twice and verify that the data is saved.
|
|
|
|
let mut memory_storage_backend: Box<dyn StorageBackend> =
|
|
|
|
Box::new(MemoryStorageBackend::default());
|
|
|
|
|
|
|
|
// Initial run; no shared object data.
|
2021-03-20 21:50:57 +00:00
|
|
|
test_swf_with_hooks(
|
2021-02-05 03:09:51 +00:00
|
|
|
"tests/swfs/avm1/shared_object/test.swf",
|
|
|
|
1,
|
|
|
|
"tests/swfs/avm1/shared_object/output1.txt",
|
|
|
|
|_player| Ok(()),
|
|
|
|
|player| {
|
|
|
|
// Save the storage backend for next run.
|
|
|
|
let mut player = player.lock().unwrap();
|
|
|
|
std::mem::swap(player.storage_mut(), &mut memory_storage_backend);
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
)?;
|
|
|
|
|
|
|
|
// Re-run the SWF, verifying that the shared object persists.
|
2021-03-20 21:50:57 +00:00
|
|
|
test_swf_with_hooks(
|
2021-02-05 03:09:51 +00:00
|
|
|
"tests/swfs/avm1/shared_object/test.swf",
|
|
|
|
1,
|
|
|
|
"tests/swfs/avm1/shared_object/output2.txt",
|
|
|
|
|player| {
|
|
|
|
// Swap in the previous storage backend.
|
|
|
|
let mut player = player.lock().unwrap();
|
|
|
|
std::mem::swap(player.storage_mut(), &mut memory_storage_backend);
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
|_player| Ok(()),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-09-15 22:28:41 +00:00
|
|
|
#[test]
|
|
|
|
fn timeout_avm1() -> Result<(), Error> {
|
2021-02-12 09:57:03 +00:00
|
|
|
set_logger();
|
2021-03-20 21:50:57 +00:00
|
|
|
test_swf_with_hooks(
|
2020-09-15 22:28:41 +00:00
|
|
|
"tests/swfs/avm1/timeout/test.swf",
|
|
|
|
1,
|
|
|
|
"tests/swfs/avm1/timeout/output.txt",
|
|
|
|
|player| {
|
|
|
|
player
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.set_max_execution_duration(Duration::from_secs(5));
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
|_| Ok(()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-04-26 06:39:04 +00:00
|
|
|
#[test]
|
|
|
|
fn stage_scale_mode() -> Result<(), Error> {
|
|
|
|
set_logger();
|
|
|
|
test_swf_with_hooks(
|
|
|
|
"tests/swfs/avm1/stage_scale_mode/test.swf",
|
|
|
|
1,
|
|
|
|
"tests/swfs/avm1/stage_scale_mode/output.txt",
|
|
|
|
|player| {
|
|
|
|
// Simulate a large viewport to test stage size.
|
|
|
|
player
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.set_viewport_dimensions(900, 900, 1.0);
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
|_| Ok(()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-01-17 21:32:16 +00:00
|
|
|
/// Wrapper around string slice that makes debug output `{:?}` to print string same way as `{}`.
|
|
|
|
/// Used in different `assert*!` macros in combination with `pretty_assertions` crate to make
|
|
|
|
/// test failures to show nice diffs.
|
|
|
|
/// Courtesy of https://github.com/colin-kiegel/rust-pretty-assertions/issues/24
|
|
|
|
#[derive(PartialEq, Eq)]
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub struct PrettyString<'a>(pub &'a str);
|
|
|
|
|
|
|
|
/// Make diff to display string as multi-line string
|
|
|
|
impl<'a> std::fmt::Debug for PrettyString<'a> {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
f.write_str(self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! assert_eq {
|
|
|
|
($left:expr, $right:expr) => {
|
|
|
|
pretty_assertions::assert_eq!(PrettyString($left.as_ref()), PrettyString($right.as_ref()));
|
|
|
|
};
|
|
|
|
($left:expr, $right:expr, $message:expr) => {
|
|
|
|
pretty_assertions::assert_eq!(
|
|
|
|
PrettyString($left.as_ref()),
|
|
|
|
PrettyString($right.as_ref()),
|
|
|
|
$message
|
|
|
|
);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-08-26 23:38:37 +00:00
|
|
|
/// Loads an SWF and runs it through the Ruffle core for a number of frames.
|
|
|
|
/// Tests that the trace output matches the given expected output.
|
2021-03-20 21:50:57 +00:00
|
|
|
fn test_swf(swf_path: &str, num_frames: u32, expected_output_path: &str) -> Result<(), Error> {
|
|
|
|
test_swf_with_hooks(
|
|
|
|
swf_path,
|
|
|
|
num_frames,
|
|
|
|
expected_output_path,
|
|
|
|
|_| Ok(()),
|
|
|
|
|_| Ok(()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Loads an SWF and runs it through the Ruffle core for a number of frames.
|
|
|
|
/// Tests that the trace output matches the given expected output.
|
|
|
|
fn test_swf_with_hooks(
|
2020-08-28 10:19:22 +00:00
|
|
|
swf_path: &str,
|
|
|
|
num_frames: u32,
|
|
|
|
expected_output_path: &str,
|
|
|
|
before_start: impl FnOnce(Arc<Mutex<Player>>) -> Result<(), Error>,
|
|
|
|
before_end: impl FnOnce(Arc<Mutex<Player>>) -> Result<(), Error>,
|
|
|
|
) -> Result<(), Error> {
|
2020-09-05 19:06:17 +00:00
|
|
|
let mut expected_output = std::fs::read_to_string(expected_output_path)?.replace("\r\n", "\n");
|
|
|
|
|
|
|
|
// Strip a trailing newline if it has one.
|
2020-09-05 19:10:46 +00:00
|
|
|
if expected_output.ends_with('\n') {
|
2020-09-05 19:06:17 +00:00
|
|
|
expected_output = expected_output[0..expected_output.len() - "\n".len()].to_string();
|
|
|
|
}
|
2019-08-26 23:38:37 +00:00
|
|
|
|
2020-08-28 10:19:22 +00:00
|
|
|
let trace_log = run_swf(swf_path, num_frames, before_start, before_end)?;
|
2020-01-17 21:32:16 +00:00
|
|
|
assert_eq!(
|
|
|
|
trace_log, expected_output,
|
|
|
|
"ruffle output != flash player output"
|
|
|
|
);
|
2019-11-27 20:46:21 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-02-17 20:32:25 +00:00
|
|
|
/// Loads an SWF and runs it through the Ruffle core for a number of frames.
|
|
|
|
/// Tests that the trace output matches the given expected output.
|
|
|
|
/// If a line has a floating point value, it will be compared approxinmately using the given epsilon.
|
|
|
|
fn test_swf_approx(
|
|
|
|
swf_path: &str,
|
|
|
|
num_frames: u32,
|
|
|
|
expected_output_path: &str,
|
2020-11-11 10:32:23 +00:00
|
|
|
approx_assert_fn: impl Fn(f64, f64),
|
2020-02-17 20:32:25 +00:00
|
|
|
) -> Result<(), Error> {
|
2021-03-20 21:50:57 +00:00
|
|
|
let trace_log = run_swf(swf_path, num_frames, |_| Ok(()), |_| Ok(()))?;
|
2020-09-05 19:06:17 +00:00
|
|
|
let mut expected_data = std::fs::read_to_string(expected_output_path)?;
|
|
|
|
|
|
|
|
// Strip a trailing newline if it has one.
|
2020-09-05 19:10:46 +00:00
|
|
|
if expected_data.ends_with('\n') {
|
2020-09-05 19:06:17 +00:00
|
|
|
expected_data = expected_data[0..expected_data.len() - "\n".len()].to_string();
|
|
|
|
}
|
|
|
|
|
2020-02-17 20:32:25 +00:00
|
|
|
std::assert_eq!(
|
|
|
|
trace_log.lines().count(),
|
|
|
|
expected_data.lines().count(),
|
|
|
|
"# of lines of output didn't match"
|
|
|
|
);
|
|
|
|
|
|
|
|
for (actual, expected) in trace_log.lines().zip(expected_data.lines()) {
|
|
|
|
// If these are numbers, compare using approx_eq.
|
|
|
|
if let (Ok(actual), Ok(expected)) = (actual.parse::<f64>(), expected.parse::<f64>()) {
|
2020-08-23 20:38:38 +00:00
|
|
|
// NaNs should be able to pass in an approx test.
|
|
|
|
if actual.is_nan() && expected.is_nan() {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-02-17 20:32:25 +00:00
|
|
|
// TODO: Lower this epsilon as the accuracy of the properties improves.
|
2020-11-11 10:32:23 +00:00
|
|
|
// if let Some(relative_epsilon) = relative_epsilon {
|
|
|
|
// assert_relative_eq!(
|
|
|
|
// actual,
|
|
|
|
// expected,
|
|
|
|
// epsilon = absolute_epsilon,
|
|
|
|
// max_relative = relative_epsilon
|
|
|
|
// );
|
|
|
|
// } else {
|
|
|
|
// assert_abs_diff_eq!(actual, expected, epsilon = absolute_epsilon);
|
|
|
|
// }
|
|
|
|
approx_assert_fn(actual, expected);
|
2020-02-17 20:32:25 +00:00
|
|
|
} else {
|
|
|
|
assert_eq!(actual, expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-11-27 20:46:21 +00:00
|
|
|
/// Loads an SWF and runs it through the Ruffle core for a number of frames.
|
|
|
|
/// Tests that the trace output matches the given expected output.
|
2020-08-28 10:19:22 +00:00
|
|
|
fn run_swf(
|
|
|
|
swf_path: &str,
|
|
|
|
num_frames: u32,
|
|
|
|
before_start: impl FnOnce(Arc<Mutex<Player>>) -> Result<(), Error>,
|
|
|
|
before_end: impl FnOnce(Arc<Mutex<Player>>) -> Result<(), Error>,
|
|
|
|
) -> Result<String, Error> {
|
2020-01-17 00:20:45 +00:00
|
|
|
let base_path = Path::new(swf_path).parent().unwrap();
|
|
|
|
let (mut executor, channel) = NullExecutor::new();
|
2021-03-22 23:41:40 +00:00
|
|
|
let movie = SwfMovie::from_path(swf_path, None)?;
|
2020-07-08 02:06:03 +00:00
|
|
|
let frame_time = 1000.0 / movie.header().frame_rate as f64;
|
2020-09-05 19:10:46 +00:00
|
|
|
let trace_output = Rc::new(RefCell::new(Vec::new()));
|
|
|
|
|
2019-11-08 20:09:57 +00:00
|
|
|
let player = Player::new(
|
|
|
|
Box::new(NullRenderer),
|
|
|
|
Box::new(NullAudioBackend::new()),
|
2020-01-17 00:20:45 +00:00
|
|
|
Box::new(NullNavigatorBackend::with_base_path(base_path, channel)),
|
2020-06-15 16:53:19 +00:00
|
|
|
Box::new(MemoryStorageBackend::default()),
|
2020-07-08 18:26:00 +00:00
|
|
|
Box::new(NullLocaleBackend::new()),
|
2020-10-15 03:01:48 +00:00
|
|
|
Box::new(NullVideoBackend::new()),
|
2020-09-05 19:10:46 +00:00
|
|
|
Box::new(TestLogBackend::new(trace_output.clone())),
|
2020-12-15 16:39:11 +00:00
|
|
|
Box::new(NullUiBackend::new()),
|
2019-09-17 03:37:11 +00:00
|
|
|
)?;
|
2020-07-23 03:18:30 +00:00
|
|
|
player.lock().unwrap().set_root_movie(Arc::new(movie));
|
2020-09-15 22:28:41 +00:00
|
|
|
player
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
2021-04-23 22:52:29 +00:00
|
|
|
.set_max_execution_duration(Duration::from_secs(300));
|
2019-08-26 23:38:37 +00:00
|
|
|
|
2020-08-28 10:19:22 +00:00
|
|
|
before_start(player.clone())?;
|
|
|
|
|
2019-08-26 23:38:37 +00:00
|
|
|
for _ in 0..num_frames {
|
2019-11-08 20:09:57 +00:00
|
|
|
player.lock().unwrap().run_frame();
|
2020-07-08 02:06:03 +00:00
|
|
|
player.lock().unwrap().update_timers(frame_time);
|
2020-01-17 00:20:45 +00:00
|
|
|
executor.poll_all().unwrap();
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
|
2020-08-28 10:19:22 +00:00
|
|
|
before_end(player)?;
|
|
|
|
|
2020-01-17 00:20:45 +00:00
|
|
|
executor.block_all().unwrap();
|
|
|
|
|
2020-09-05 19:10:46 +00:00
|
|
|
let trace = trace_output.borrow().join("\n");
|
|
|
|
Ok(trace)
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
|
2020-09-05 19:10:46 +00:00
|
|
|
struct TestLogBackend {
|
|
|
|
trace_output: Rc<RefCell<Vec<String>>>,
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
|
2020-09-05 19:10:46 +00:00
|
|
|
impl TestLogBackend {
|
|
|
|
pub fn new(trace_output: Rc<RefCell<Vec<String>>>) -> Self {
|
|
|
|
Self { trace_output }
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
2020-09-05 19:10:46 +00:00
|
|
|
}
|
2019-08-26 23:38:37 +00:00
|
|
|
|
2020-09-05 19:10:46 +00:00
|
|
|
impl LogBackend for TestLogBackend {
|
|
|
|
fn avm_trace(&self, message: &str) {
|
|
|
|
self.trace_output.borrow_mut().push(message.to_string());
|
2019-08-26 23:38:37 +00:00
|
|
|
}
|
|
|
|
}
|
2020-08-28 10:19:22 +00:00
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
pub struct ExternalInterfaceTestProvider {}
|
|
|
|
|
|
|
|
impl ExternalInterfaceTestProvider {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:06:17 +00:00
|
|
|
fn do_trace(context: &mut UpdateContext<'_, '_, '_>, args: &[ExternalValue]) -> ExternalValue {
|
|
|
|
context
|
2020-09-05 19:10:46 +00:00
|
|
|
.log
|
2020-09-05 19:06:17 +00:00
|
|
|
.avm_trace(&format!("[ExternalInterface] trace: {:?}", args));
|
2020-08-31 21:32:12 +00:00
|
|
|
"Traced!".into()
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:06:17 +00:00
|
|
|
fn do_ping(context: &mut UpdateContext<'_, '_, '_>, _args: &[ExternalValue]) -> ExternalValue {
|
2020-09-05 19:10:46 +00:00
|
|
|
context.log.avm_trace("[ExternalInterface] ping");
|
2020-08-31 21:32:12 +00:00
|
|
|
"Pong!".into()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_reentry(context: &mut UpdateContext<'_, '_, '_>, _args: &[ExternalValue]) -> ExternalValue {
|
2020-09-05 19:06:17 +00:00
|
|
|
context
|
2020-09-05 19:10:46 +00:00
|
|
|
.log
|
2020-09-05 19:06:17 +00:00
|
|
|
.avm_trace("[ExternalInterface] starting reentry");
|
2020-08-31 21:32:12 +00:00
|
|
|
if let Some(callback) = context.external_interface.get_callback("callWith") {
|
|
|
|
callback.call(
|
|
|
|
context,
|
|
|
|
"callWith",
|
|
|
|
vec!["trace".into(), "successful reentry!".into()],
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
ExternalValue::Null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:43:21 +00:00
|
|
|
impl ExternalInterfaceProvider for ExternalInterfaceTestProvider {
|
2020-08-31 21:32:12 +00:00
|
|
|
fn get_method(&self, name: &str) -> Option<Box<dyn ExternalInterfaceMethod>> {
|
2020-08-28 10:43:21 +00:00
|
|
|
match name {
|
2020-08-31 21:32:12 +00:00
|
|
|
"trace" => Some(Box::new(do_trace)),
|
|
|
|
"ping" => Some(Box::new(do_ping)),
|
|
|
|
"reentry" => Some(Box::new(do_reentry)),
|
2020-08-28 10:43:21 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-09-02 19:02:32 +00:00
|
|
|
|
|
|
|
fn on_callback_available(&self, _name: &str) {}
|
2021-01-28 10:55:26 +00:00
|
|
|
|
|
|
|
fn on_fs_command(&self, _command: &str, _args: &str) -> bool {
|
|
|
|
false
|
|
|
|
}
|
2020-08-28 10:43:21 +00:00
|
|
|
}
|