#!perl -w use strict; use Test::More; use MozRepl::RemoteObject; my $repl; my $ok = eval { $repl = MozRepl::RemoteObject->install_bridge( #log => ['debug'], use_queue => 1, ); 1; }; if (! $ok) { my $err = $@; plan skip_all => "Couldn't connect to MozRepl: $@"; } else { plan tests => 15; }; sub genObj { my ($repl) = @_; my $rn = $repl->name; my $obj = $repl->expr(<{oncommand} = sub { $called++; push @events, @_; }; ok 1, "Stored callback"; my $cb = $obj->{oncommand}; isa_ok $obj->{oncommand}, 'MozRepl::RemoteObject::Instance', "We can store a subroutine as a callback"; my $setup_roundtrips = $repl->{stats}->{roundtrip}; $cb->('from_perl'); is $called, 1, "We got called back on a direct call from Perl"; my $trigger_command = $repl->declare(<<'JS'); function(o,m) { o.oncommand(m); }; JS $trigger_command->($obj,'from_js'); is $called, 2, "We got called indirectly by a callback in Javascript"; is_deeply \@events, ['from_perl','from_js'], "We received the events in the order we expected"; @events = (); my $trigger_command_multi = $repl->declare(<<'JS'); function(obj,m,n,o,p) { obj.oncommand(m,n,o,p); }; JS $trigger_command_multi->($obj,'param1','param2','param3','param4'); is $called, 3, "We got called indirectly by a callback in Javascript"; is_deeply \@events, ['param1','param2','param3','param4'], "We received the multiple arguments in the order we expected"; @events = (); my $window = $repl->expr(<<'JS'); window JS isa_ok $window, 'MozRepl::RemoteObject::Instance', "We got a handle on window"; # Weirdly enough, .setTimeout cannot be passed around as bare function # Maybe just like object methods in Perl my $timer_id = $window->setTimeout($trigger_command, 2000, $obj, 'from_timer'); is_deeply \@events, [], "Delayed events don't trigger immediately"; sleep 3; $repl->poll; is_deeply \@events, ['from_timer'], "Delayed triggers trigger eventually"; @events = (); $timer_id = $window->setTimeout(sub { push @events, 'in_perl' }, 2000); is_deeply \@events, [], "Delayed events don't trigger immediately (with Perl callback)"; sleep 3; $repl->poll; is_deeply \@events, ['in_perl'], "Delayed triggers trigger eventually (with Perl callback)"; is $repl->{stats}->{callback}, 5, "We triggered 5 callbacks"; # ca. 3 roundtrips per callback: # 1 for the callback itself ( ->poll() ) # 2 for fetching its arguments in the tests # the rest is for ephemeral setup and destructors cmp_ok $repl->{stats}->{roundtrip}-$setup_roundtrips,'<',30, 'We needed less than 30 roundtrips for the callbacks'; use Data::Dumper; diag Dumper $repl->{stats};