AnyEvent-XSPromises

 view release on metacpan or  search on metacpan

t/aplus.t  view on Meta::CPAN

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 )