BEGIN {
require
"t/tools.pl"
};
use
Test2::Util
qw/CAN_FORK CAN_THREAD CAN_REALLY_FORK/
;
{
sub
new {
bless
[],
shift
};
my
$check
= 1;
sub
write
{
my
$self
=
shift
;
my
(
$e
,
$count
) =
@_
;
push
@$self
=>
$e
;
}
}
{
}
tests
basic
=>
sub
{
my
$hub
= Test2::Hub->new(
formatter
=> My::Formatter->new,
);
my
$send_event
=
sub
{
my
(
$msg
) =
@_
;
my
$e
= My::Event->new(
msg
=>
$msg
,
trace
=>
'fake'
);
$hub
->
send
(
$e
);
};
ok(
my
$e1
=
$send_event
->(
'foo'
),
"Created event"
);
ok(
my
$e2
=
$send_event
->(
'bar'
),
"Created event"
);
ok(
my
$e3
=
$send_event
->(
'baz'
),
"Created event"
);
my
$old
=
$hub
->
format
(My::Formatter->new);
ok(
$old
->isa(
'My::Formatter'
),
"old formatter"
);
is_deeply(
$old
,
[
$e1
,
$e2
,
$e3
],
"Formatter got all events"
);
};
tests
follow_ups
=>
sub
{
my
$hub
= Test2::Hub->new;
$hub
->set_count(1);
my
$trace
= Test2::Util::Trace->new(
frame
=> [__PACKAGE__, __FILE__, __LINE__],
);
my
$ran
= 0;
$hub
->follow_up(
sub
{
my
(
$d
,
$h
) =
@_
;
is_deeply(
$d
,
$trace
,
"Got trace"
);
is_deeply(
$h
,
$hub
,
"Got hub"
);
ok(!
$hub
->ended,
"Hub state has not ended yet"
);
$ran
++;
});
like(
exception {
$hub
->follow_up(
'xxx'
) },
qr/follow_up only takes coderefs for arguments, got 'xxx'/
,
"follow_up takes a coderef"
);
$hub
->finalize(
$trace
);
is(
$ran
, 1,
"ran once"
);
is_deeply(
$hub
->ended,
$trace
->frame,
"Ended at the expected place."
);
eval
{
$hub
->finalize(
$trace
) };
is(
$ran
, 1,
"ran once"
);
$hub
=
undef
;
};
tests
IPC
=>
sub
{
my
(
$driver
) = test2_ipc_drivers();
is(
$driver
,
'Test2::IPC::Driver::Files'
,
"Default Driver"
);
my
$ipc
=
$driver
->new;
my
$hub
= Test2::Hub->new(
formatter
=> My::Formatter->new,
ipc
=>
$ipc
,
);
my
$build_event
=
sub
{
my
(
$msg
) =
@_
;
return
My::Event->new(
msg
=>
$msg
,
trace
=>
'fake'
);
};
my
$e1
=
$build_event
->(
'foo'
);
my
$e2
=
$build_event
->(
'bar'
);
my
$e3
=
$build_event
->(
'baz'
);
my
$do_send
=
sub
{
$hub
->
send
(
$e1
);
$hub
->
send
(
$e2
);
$hub
->
send
(
$e3
);
};
my
$do_check
=
sub
{
my
$name
=
shift
;
my
$old
=
$hub
->
format
(My::Formatter->new);
ok(
$old
->isa(
'My::Formatter'
),
"old formatter"
);
is_deeply(
$old
,
[
$e1
,
$e2
,
$e3
],
"Formatter got all events ($name)"
);
};
if
(CAN_REALLY_FORK) {
my
$pid
=
fork
();
die
"Could not fork!"
unless
defined
$pid
;
if
(
$pid
) {
is(
waitpid
(
$pid
, 0),
$pid
,
"waited properly"
);
ok(!$?,
"child exited with success"
);
$hub
->cull();
$do_check
->(
'Fork'
);
}
else
{
$do_send
->();
exit
0;
}
}
if
(CAN_THREAD && $] ge
'5.010'
) {
my
$thr
= threads->new(
sub
{
$do_send
->() });
$thr
->
join
;
$hub
->cull();
$do_check
->(
'Threads'
);
}
$do_send
->();
$hub
->cull();
$do_check
->(
'no IPC'
);
};
tests
listen
=>
sub
{
my
$hub
= Test2::Hub->new();
my
@events
;
my
@counts
;
my
$it
=
$hub
->
listen
(
sub
{
my
(
$h
,
$e
,
$count
) =
@_
;
is_deeply(
$h
,
$hub
,
"got hub"
);
push
@events
=>
$e
;
push
@counts
=>
$count
;
});
my
$second
;
my
$it2
=
$hub
->
listen
(
sub
{
$second
++ });
my
$ok1
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'foo'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok2
= Test2::Event::Ok->new(
pass
=> 0,
name
=>
'bar'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok3
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'baz'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
$hub
->
send
(
$ok1
);
$hub
->
send
(
$ok2
);
$hub
->unlisten(
$it
);
$hub
->
send
(
$ok3
);
is_deeply(\
@counts
, [1, 2],
"Got counts"
);
is_deeply(\
@events
, [
$ok1
,
$ok2
],
"got events"
);
is(
$second
, 3,
"got all events in listener that was not removed"
);
like(
exception {
$hub
->
listen
(
'xxx'
) },
qr/listen only takes coderefs for arguments, got 'xxx'/
,
"listen takes a coderef"
);
};
tests
metadata
=>
sub
{
my
$hub
= Test2::Hub->new();
my
$default
= {
foo
=> 1 };
my
$meta
=
$hub
->meta(
'Foo'
,
$default
);
is_deeply(
$meta
,
$default
,
"Set Meta"
);
$meta
=
$hub
->meta(
'Foo'
, {});
is_deeply(
$meta
,
$default
,
"Same Meta"
);
$hub
->delete_meta(
'Foo'
);
is(
$hub
->meta(
'Foo'
),
undef
,
"No Meta"
);
$hub
->meta(
'Foo'
, {})->{xxx} = 1;
is(
$hub
->meta(
'Foo'
)->{xxx}, 1,
"Vivified meta and set it"
);
like(
exception {
$hub
->meta(
undef
) },
qr/Invalid META key: undef, keys must be true, and may not be references/
,
"Cannot use undef as a meta key"
);
like(
exception {
$hub
->meta(0) },
qr/Invalid META key: '0', keys must be true, and may not be references/
,
"Cannot use 0 as a meta key"
);
like(
exception {
$hub
->delete_meta(
undef
) },
qr/Invalid META key: undef, keys must be true, and may not be references/
,
"Cannot use undef as a meta key"
);
like(
exception {
$hub
->delete_meta(0) },
qr/Invalid META key: '0', keys must be true, and may not be references/
,
"Cannot use 0 as a meta key"
);
};
tests
filter
=>
sub
{
my
$hub
= Test2::Hub->new();
my
@events
;
my
$it
=
$hub
->filter(
sub
{
my
(
$h
,
$e
) =
@_
;
is(
$h
,
$hub
,
"got hub"
);
push
@events
=>
$e
;
return
$e
;
});
my
$count
;
my
$it2
=
$hub
->filter(
sub
{
$count
++;
$_
[1] });
my
$ok1
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'foo'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok2
= Test2::Event::Ok->new(
pass
=> 0,
name
=>
'bar'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok3
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'baz'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
$hub
->
send
(
$ok1
);
$hub
->
send
(
$ok2
);
$hub
->unfilter(
$it
);
$hub
->
send
(
$ok3
);
is_deeply(\
@events
, [
$ok1
,
$ok2
],
"got events"
);
is(
$count
, 3,
"got all events, even after other filter was removed"
);
$hub
= Test2::Hub->new();
@events
= ();
$hub
->filter(
sub
{
undef
});
$hub
->
listen
(
sub
{
my
(
$hub
,
$e
) =
@_
;
push
@events
=>
$e
;
});
$hub
->
send
(
$ok1
);
$hub
->
send
(
$ok2
);
$hub
->
send
(
$ok3
);
ok(!
@events
,
"Blocked events"
);
like(
exception {
$hub
->filter(
'xxx'
) },
qr/filter only takes coderefs for arguments, got 'xxx'/
,
"filter takes a coderef"
);
};
tests
pre_filter
=>
sub
{
my
$hub
= Test2::Hub->new();
my
@events
;
my
$it
=
$hub
->pre_filter(
sub
{
my
(
$h
,
$e
) =
@_
;
is(
$h
,
$hub
,
"got hub"
);
push
@events
=>
$e
;
return
$e
;
});
my
$count
;
my
$it2
=
$hub
->pre_filter(
sub
{
$count
++;
$_
[1] });
my
$ok1
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'foo'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok2
= Test2::Event::Ok->new(
pass
=> 0,
name
=>
'bar'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
my
$ok3
= Test2::Event::Ok->new(
pass
=> 1,
name
=>
'baz'
,
trace
=> Test2::Util::Trace->new(
frame
=> [ __PACKAGE__, __FILE__, __LINE__ ],
),
);
$hub
->
send
(
$ok1
);
$hub
->
send
(
$ok2
);
$hub
->pre_unfilter(
$it
);
$hub
->
send
(
$ok3
);
is_deeply(\
@events
, [
$ok1
,
$ok2
],
"got events"
);
is(
$count
, 3,
"got all events, even after other pre_filter was removed"
);
$hub
= Test2::Hub->new();
@events
= ();
$hub
->pre_filter(
sub
{
undef
});
$hub
->
listen
(
sub
{
my
(
$hub
,
$e
) =
@_
;
push
@events
=>
$e
;
});
$hub
->
send
(
$ok1
);
$hub
->
send
(
$ok2
);
$hub
->
send
(
$ok3
);
ok(!
@events
,
"Blocked events"
);
like(
exception {
$hub
->pre_filter(
'xxx'
) },
qr/pre_filter only takes coderefs for arguments, got 'xxx'/
,
"pre_filter takes a coderef"
);
};
tests
state
=>
sub
{
my
$hub
= Test2::Hub->new;
is(
$hub
->count, 0,
"count starts at 0"
);
is(
$hub
->failed, 0,
"failed starts at 0"
);
is(
$hub
->is_passing, 1,
"start off passing"
);
is(
$hub
->plan,
undef
,
"no plan yet"
);
$hub
->is_passing(0);
is(
$hub
->is_passing, 0,
"Can Fail"
);
$hub
->is_passing(1);
is(
$hub
->is_passing, 1,
"Passes again"
);
$hub
->set_count(1);
is(
$hub
->count, 1,
"Added a passing result"
);
is(
$hub
->failed, 0,
"still no fails"
);
is(
$hub
->is_passing, 1,
"Still passing"
);
$hub
->set_count(2);
$hub
->set_failed(1);
is(
$hub
->count, 2,
"Added a result"
);
is(
$hub
->failed, 1,
"new failure"
);
is(
$hub
->is_passing, 0,
"Not passing"
);
$hub
->is_passing(1);
is(
$hub
->is_passing, 0,
"is_passing always false after a failure"
);
$hub
->set_failed(0);
$hub
->is_passing(1);
is(
$hub
->is_passing, 1,
"Passes again"
);
$hub
->set_failed(1);
is(
$hub
->count, 2,
"No new result"
);
is(
$hub
->failed, 1,
"new failure"
);
is(
$hub
->is_passing, 0,
"Not passing"
);
ok(!
eval
{
$hub
->plan(
'foo'
); 1 },
"Could not set plan to 'foo'"
);
like($@,
qr/'foo' is not a valid plan! Plan must be an integer greater than 0, 'NO PLAN', or 'SKIP'/
,
"Got expected error"
);
ok(
$hub
->plan(5),
"Can set plan to integer"
);
is(
$hub
->plan, 5,
"Set the plan to an integer"
);
$hub
->set__plan(
undef
);
ok(
$hub
->plan(
'NO PLAN'
),
"Can set plan to 'NO PLAN'"
);
is(
$hub
->plan,
'NO PLAN'
,
"Set the plan to 'NO PLAN'"
);
$hub
->set__plan(
undef
);
ok(
$hub
->plan(
'SKIP'
),
"Can set plan to 'SKIP'"
);
is(
$hub
->plan,
'SKIP'
,
"Set the plan to 'SKIP'"
);
ok(!
eval
{
$hub
->plan(5); 1 },
"Cannot change plan"
);
like($@,
qr/You cannot change the plan/
,
"Got error"
);
my
$trace
= Test2::Util::Trace->new(
frame
=> [
'Foo::Bar'
,
'foo.t'
, 42,
'blah'
]);
$hub
->finalize(
$trace
);
my
$ok
=
eval
{
$hub
->finalize(
$trace
) };
my
$err
= $@;
ok(!
$ok
,
"died"
);
is(
$err
,
<<" EOT", "Got expected error");
Test already ended!
First End: foo.t line 42
Second End: foo.t line 42
EOT
$hub
= Test2::Hub->new;
$hub
->plan(5);
$hub
->set_count(5);
$hub
->set_failed(1);
$hub
->set_ended(
$trace
);
$hub
->set_bailed_out(
"foo"
);
$hub
->set_skip_reason(
'xxx'
);
ok(!
$hub
->is_passing,
"not passing"
);
$hub
->reset_state;
ok(!
$hub
->plan,
"no plan"
);
is(
$hub
->count, 0,
"count reset to 0"
);
is(
$hub
->failed, 0,
"reset failures"
);
ok(!
$hub
->ended,
"not ended"
);
ok(!
$hub
->bailed_out,
"did not bail out"
);
ok(!
$hub
->skip_reason,
"no skip reason"
);
};
done_testing;