core: Clean up test_utils

This commit is contained in:
Mike Welsh 2022-04-26 17:53:52 -07:00
parent f48182ef3d
commit ddc28310f8
3 changed files with 30 additions and 202 deletions

View File

@ -529,106 +529,21 @@ mod tests {
use super::*; use super::*;
use crate::avm1::function::Executable; use crate::avm1::function::Executable;
use crate::avm1::globals::system::SystemProperties; use crate::avm1::function::FunctionObject;
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::{activation::ActivationIdentifier, function::FunctionObject};
use crate::avm1::{Avm1, Timers};
use crate::avm2::Avm2;
use crate::backend::audio::{AudioManager, NullAudioBackend};
use crate::backend::log::NullLogBackend;
use crate::backend::navigator::NullNavigatorBackend;
use crate::backend::render::NullRenderer;
use crate::backend::storage::MemoryStorageBackend;
use crate::backend::ui::NullUiBackend;
use crate::backend::video::NullVideoBackend;
use crate::context::UpdateContext;
use crate::display_object::{MovieClip, Stage};
use crate::focus_tracker::FocusTracker;
use crate::library::Library;
use crate::loader::LoadManager;
use crate::prelude::*;
use crate::tag_utils::SwfMovie;
use crate::vminterface::Instantiator;
use gc_arena::rootless_arena;
use instant::Instant;
use rand::{rngs::SmallRng, SeedableRng};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
fn with_object<F, R>(swf_version: u8, test: F) -> R fn with_object<F>(swf_version: u8, test: F)
where where
F: for<'a, 'gc> FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>) -> R, F: for<'a, 'gc> FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>),
{ {
rootless_arena(|gc_context| { crate::avm1::test_utils::with_avm(swf_version, |activation, _root| {
let mut avm1 = Avm1::new(gc_context, swf_version); let object = ScriptObject::object(
let mut avm2 = Avm2::new(gc_context); activation.context.gc_context,
let swf = Arc::new(SwfMovie::empty(swf_version)); Some(activation.context.avm1.prototypes().object),
let root: DisplayObject<'_> = MovieClip::new(swf.clone(), gc_context).into(); )
root.set_depth(gc_context, 0); .into();
test(activation, object);
let stage = Stage::empty(gc_context, 550, 400); Ok(())
let mut frame_rate = 12.0;
let object = ScriptObject::object(gc_context, Some(avm1.prototypes().object)).into();
let globals = avm1.global_object_cell();
let mut context = UpdateContext {
gc_context,
player_version: 32,
swf: &swf,
stage,
rng: &mut SmallRng::from_seed([0u8; 32]),
action_queue: &mut crate::context::ActionQueue::new(),
audio: &mut NullAudioBackend::new(),
audio_manager: &mut AudioManager::new(),
ui: &mut NullUiBackend::new(),
library: &mut Library::empty(),
navigator: &mut NullNavigatorBackend::new(),
renderer: &mut NullRenderer::new(),
log: &mut NullLogBackend::new(),
video: &mut NullVideoBackend::new(),
mouse_over_object: None,
mouse_down_object: None,
input: &Default::default(),
mouse_position: &(Twips::ZERO, Twips::ZERO),
drag_object: &mut None,
player: None,
load_manager: &mut LoadManager::new(),
system: &mut SystemProperties::default(),
instance_counter: &mut 0,
storage: &mut MemoryStorageBackend::default(),
shared_objects: &mut HashMap::new(),
unbound_text_fields: &mut Vec::new(),
timers: &mut Timers::new(),
current_context_menu: &mut None,
needs_render: &mut false,
avm1: &mut avm1,
avm2: &mut avm2,
external_interface: &mut Default::default(),
start_time: Instant::now(),
update_start: Instant::now(),
max_execution_duration: Duration::from_secs(15),
focus_tracker: FocusTracker::new(gc_context),
times_get_time_called: 0,
time_offset: &mut 0,
frame_rate: &mut frame_rate,
};
context.stage.replace_at_depth(&mut context, root, 0);
root.post_instantiation(&mut context, None, Instantiator::Movie, false);
root.set_name(context.gc_context, "".into());
let swf_version = context.swf.version();
let mut activation = Activation::from_nothing(
context,
ActivationIdentifier::root("[Test]"),
swf_version,
globals,
root,
);
test(&mut activation, object)
}) })
} }

View File

@ -1,108 +1,20 @@
use crate::avm1::activation::{Activation, ActivationIdentifier}; use crate::avm1::{
use crate::avm1::error::Error; activation::{Activation, ActivationIdentifier},
use crate::avm1::globals::system::SystemProperties; error::Error,
use crate::avm1::{Avm1, Object, Timers, UpdateContext}; Object,
use crate::avm2::Avm2; };
use crate::backend::audio::{AudioManager, NullAudioBackend}; use crate::display_object::TDisplayObject;
use crate::backend::log::NullLogBackend;
use crate::backend::navigator::NullNavigatorBackend;
use crate::backend::render::NullRenderer;
use crate::backend::storage::MemoryStorageBackend;
use crate::backend::ui::NullUiBackend;
use crate::backend::video::NullVideoBackend;
use crate::context::ActionQueue;
use crate::display_object::{MovieClip, Stage, TDisplayObject};
use crate::focus_tracker::FocusTracker;
use crate::library::Library;
use crate::loader::LoadManager;
use crate::prelude::*;
use crate::tag_utils::SwfMovie;
use crate::vminterface::Instantiator;
use gc_arena::{rootless_arena, MutationContext};
use instant::Instant;
use rand::{rngs::SmallRng, SeedableRng};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
pub fn with_avm<F>(swf_version: u8, test: F) pub fn with_avm<F>(swf_version: u8, test: F)
where where
F: for<'a, 'gc> FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>, F: for<'a, 'gc> FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>,
{ {
fn in_the_arena<'a, 'gc: 'a, F>(swf_version: u8, test: F, gc_context: MutationContext<'gc, '_>) let player = crate::player::PlayerBuilder::new().build().unwrap();
where let mut player = player.lock().unwrap();
F: FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>, player.mutate_with_update_context(|context| {
{ let context = context.reborrow();
let mut avm1 = Avm1::new(gc_context, swf_version); let globals = context.avm1.globals;
let mut avm2 = Avm2::new(gc_context); let root = context.stage.root_clip();
let swf = Arc::new(SwfMovie::empty(swf_version));
let root: DisplayObject<'gc> = MovieClip::new(swf.clone(), gc_context).into();
root.set_depth(gc_context, 0);
let stage = Stage::empty(gc_context, 550, 400);
let mut frame_rate = 12.0;
let globals = avm1.global_object_cell();
let mut context = UpdateContext {
gc_context,
player_version: 32,
swf: &swf,
stage,
rng: &mut SmallRng::from_seed([0u8; 32]),
audio: &mut NullAudioBackend::new(),
ui: &mut NullUiBackend::new(),
action_queue: &mut ActionQueue::new(),
library: &mut Library::empty(),
navigator: &mut NullNavigatorBackend::new(),
renderer: &mut NullRenderer::new(),
log: &mut NullLogBackend::new(),
video: &mut NullVideoBackend::new(),
mouse_over_object: None,
mouse_down_object: None,
input: &Default::default(),
mouse_position: &(Twips::ZERO, Twips::ZERO),
drag_object: &mut None,
player: None,
load_manager: &mut LoadManager::new(),
system: &mut SystemProperties::default(),
instance_counter: &mut 0,
storage: &mut MemoryStorageBackend::default(),
shared_objects: &mut HashMap::new(),
unbound_text_fields: &mut Vec::new(),
timers: &mut Timers::new(),
current_context_menu: &mut None,
needs_render: &mut false,
avm1: &mut avm1,
avm2: &mut avm2,
external_interface: &mut Default::default(),
start_time: Instant::now(),
update_start: Instant::now(),
max_execution_duration: Duration::from_secs(15),
focus_tracker: FocusTracker::new(gc_context),
times_get_time_called: 0,
time_offset: &mut 0,
audio_manager: &mut AudioManager::new(),
frame_rate: &mut frame_rate,
};
context.stage.replace_at_depth(&mut context, root, 0);
root.post_instantiation(&mut context, None, Instantiator::Movie, false);
root.set_name(context.gc_context, "".into());
fn run_test<'a, 'gc: 'a, F>(
activation: &mut Activation<'_, 'gc, '_>,
root: DisplayObject<'gc>,
test: F,
) where
F: FnOnce(&mut Activation<'_, 'gc, '_>, Object<'gc>) -> Result<(), Error<'gc>>,
{
let this = root.object().coerce_to_object(activation);
let result = test(activation, this);
if let Err(e) = result {
panic!("Encountered exception during test: {}", e);
}
}
let swf_version = context.swf.version();
let mut activation = Activation::from_nothing( let mut activation = Activation::from_nothing(
context, context,
ActivationIdentifier::root("[Test]"), ActivationIdentifier::root("[Test]"),
@ -110,11 +22,12 @@ where
globals, globals,
root, root,
); );
let this = root.object().coerce_to_object(&mut activation);
run_test(&mut activation, root, test) let result = test(&mut activation, this);
} if let Err(e) = result {
panic!("Encountered exception during test: {}", e);
rootless_arena(|gc_context| in_the_arena(swf_version, test, gc_context)) }
})
} }
macro_rules! test_method { macro_rules! test_method {

View File

@ -1453,7 +1453,7 @@ impl Player {
/// Runs the closure `f` with an `UpdateContext`. /// Runs the closure `f` with an `UpdateContext`.
/// This takes cares of populating the `UpdateContext` struct, avoiding borrow issues. /// This takes cares of populating the `UpdateContext` struct, avoiding borrow issues.
fn mutate_with_update_context<F, R>(&mut self, f: F) -> R pub(crate) fn mutate_with_update_context<F, R>(&mut self, f: F) -> R
where where
F: for<'a, 'gc> FnOnce(&mut UpdateContext<'a, 'gc, '_>) -> R, F: for<'a, 'gc> FnOnce(&mut UpdateContext<'a, 'gc, '_>) -> R,
{ {