AnyEvent-XSPromises
view release on metacpan or search on metacpan
use 5.010;
use strict;
use warnings;
use Test::More;
use AnyEvent;
use AnyEvent::XSPromises qw/deferred resolved rejected collect/;
sub delayed {
my ($seconds, $sub)= @_;
my $timer; $timer= AE::timer $seconds, 0, sub {
undef $timer;
&$sub;
};
}
sub expect_resolve {
$_[0]->then(sub {
1;
}, sub {
fail;
});
}
sub expect_reject {
$_[0]->then(sub {
fail;
}, sub {
1;
});
}
my %tests= (
no_duplicate_invoke_callback => sub {
my $all_good;
resolved->then(sub {
fail if $all_good;
$all_good= 1;
}, sub {
fail;
})->finally(sub {
ok($all_good);
});
},
cannot_resolve_and_reject => sub {
my $d= deferred;
$d->resolve;
eval { $d->reject; fail; };
expect_resolve($d->promise);
},
cannot_reject_and_resolve => sub {
my $d= deferred;
$d->reject;
eval { $d->resolve; fail; };
expect_reject($d->promise);
},
delayed_resolve_and_reject => sub {
my $d= deferred;
delayed(0.1, sub {
$d->resolve;
eval { $d->resolve; fail; };
eval { $d->reject; fail; };
});
expect_resolve($d->promise);
},
rejected_state_must_not_change => sub {
my $d= deferred;
$d->reject;
eval { $d->resolve; fail; };
expect_reject($d->promise);
},
rejected_immediately => sub {
expect_reject(rejected());
},
rejected_delayed => sub {
my $d= deferred;
delayed(0.1, sub {
$d->reject;
});
expect_reject($d->promise);
},
resolved_immediately => sub {
expect_resolve(resolved());
},
resolved_delayed => sub {
my $d= deferred;
delayed(0.1, sub {
$d->resolve;
});
expect_resolve($d->promise);
},
resolve_with_garbage => sub {
expect_reject(resolved->then({}));
},
reject_with_garbage => sub {
expect_reject(rejected->catch(5));
},
reject_with_named_function => sub {
expect_reject(rejected->catch("main::fail"));
},
finally_with_garbage => sub {
expect_resolve(resolved->finally(123));
},
pass_value_to_callback => sub {
expect_resolve(
resolved(1, 2, 3, 4)->then(sub {
is_deeply(\@_, [1,2,3,4]);
})
);
},
callback_sent_later => sub {
my $d= deferred;
my $ok= 0;
delayed(0.1, sub {
$d->resolve;
$ok= 1;
});
expect_resolve(
$d->promise->then(sub {
ok($ok);
})
);
},
never_resolved => sub {
my $d= deferred;
$d->promise->then(sub { fail; });
resolved;
},
called_once => sub {
my $d= deferred;
my $times_called;
my $p= $d->promise->then(sub {
$times_called++;
});
$d->resolve;
eval { $d->resolve; fail; };
$p->then(sub {
is($times_called, 1);
});
},
multiple_thens => sub {
my $d= deferred;
my $d2= deferred;
my ($one, $two, $three);
$d->promise->then(sub { $one++; });
delayed(0.05, sub { $d->promise->then(sub { $two++; }) });
delayed(0.10, sub {
is($one, undef);
is($two, undef);
is($three, undef);
$d->resolve;
});
delayed(0.15, sub { $d->promise->then(sub { $three++; }) });
delayed(0.2, sub {
$d2->resolve;
});
$d2->promise->then(sub {
is($one, 1);
is($two, 1);
is($three, 1);
});
},
call_me_later => sub {
my $not_now= 1;
my $p= resolved->then(sub {
is($not_now, 0);
});
$not_now= 0;
$p
},
call_me_later_2 => sub {
my $d= deferred;
my $not_now= 1;
my $p= $d->promise->then(sub {
is($not_now, 0);
});
$d->resolve;
$not_now= 0;
$p
},
then_in_then_call_me_later => sub {
my $r= resolved;
my $not_now= 1;
my $but_now= 0;
my $p= $r->then(sub {
$r->then(sub {
is($but_now, 1);
is($not_now, 0);
});
$but_now= 1;
is($not_now, 0);
});
$not_now= 0;
$p
},
call_me_later_async => sub {
my $d= deferred;
my $ok;
my $p= $d->promise->then(sub {
is($ok, 1);
});
delayed(0, sub {
$d->resolve;
$ok= 1;
});
$p
},
no_pass_underbar => sub {
$_= 5;
resolved->then(sub {
is($_, undef);
});
},
ordered_thens => sub {
my $r= resolved;
my $last= 0;
collect(
$r->then(sub {
is($last++, 0);
}),
$r->then(sub {
is($last++, 1);
}),
$r->then(sub {
is($last++, 2);
}),
);
},
multiple_thens_with_values => sub {
my $r= resolved(1);
collect(
$r->then(sub {
is($_[0], 1);
resolved(5);
})->then(sub {
is($_[0], 5);
}),
$r->then(sub {
is($_[0], 1);
resolved(6);
})->then(sub {
is($_[0], 6);
}),
$r->then(sub {
is($_[0], 1);
resolved(8, 9);
})->then(sub {
is($_[0], 8);
is($_[1], 9);
}),
$r->then(sub {
rejected(1);
})->catch(sub {
( run in 0.571 second using v1.01-cache-2.11-cpan-39bf76dae61 )