File: 34utils-repeat-foreach.t

package info (click to toggle)
libfuture-perl 0.51-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 676 kB
  • sloc: perl: 4,625; makefile: 2
file content (152 lines) | stat: -rw-r--r-- 4,026 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/perl

use v5.14;
use warnings;

use Test2::V0;

use Future;
use Future::Utils qw( repeat try_repeat try_repeat_until_success );

# foreach without otherwise
{
   my $trial_f;
   my $arg;
   my $future = repeat {
      $arg = shift;
      return $trial_f = Future->new;
   } foreach => [qw( one two three )];

   is( $arg, "one", '$arg one for first iteration' );
   $trial_f->done;

   ok( !$future->is_ready, '$future not ready' );

   is( $arg, "two", '$arg two for second iteration' );
   $trial_f->done( "another" );

   ok( !$future->is_ready, '$future not ready' );

   is( $arg, "three", '$arg three for third iteration' );
   $trial_f->done( "result" );

   ok( $future->is_ready, '$future now ready' );
   is( scalar $future->result, "result", '$future->result' );
}

# foreach otherwise
{
   my $last_trial_f;
   my $future = repeat {
      Future->done( "ignore me $_[0]" );
   } foreach => [qw( one two three )],
     otherwise => sub {
        $last_trial_f = shift;
        return Future->fail( "Nothing succeeded\n" );
     };

   is( scalar $future->failure, "Nothing succeeded\n", '$future returns otherwise failure' );
   is( scalar $last_trial_f->result, "ignore me three", '$last_trial_f->result' );

   $future = repeat {
      Future->done( "ignore me" );
   } foreach => [],
     otherwise => sub { Future->fail( "Nothing to do\n" ) };

   is( scalar $future->failure, "Nothing to do\n", '$future returns otherwise failure for empty list' );
}

# foreach on empty list
{
   my $future = repeat { die "Not invoked" } foreach => [];

   ok( $future->is_ready, 'repeat {} on empty foreach without otherwise already ready' );
   is( [ $future->result ], [], 'Result of empty future' );

   $future = repeat { die "Not invoked" } foreach => [],
      otherwise => sub { Future->done( 1, 2, 3 ) };

   ok( $future->is_ready, 'repeat {} on empty foreach with otherwise already ready' );
   is( [ $future->result ], [ 1, 2, 3 ], 'Result of otherwise future' );
}

# foreach while
{
   my $future = try_repeat {
      my $arg = shift;
      if( $arg eq "bad" ) {
         return Future->fail( "bad" );
      }
      else {
         return Future->done( $arg );
      }
   } foreach => [qw( bad good not-attempted )],
     while => sub { shift->failure };

   is( scalar $future->result, "good", '$future->result returns correct result for foreach+while' );
}

# foreach until
{
   my $future = try_repeat {
      my $arg = shift;
      if( $arg eq "bad" ) {
         return Future->fail( "bad" );
      }
      else {
         return Future->done( $arg );
      }
   } foreach => [qw( bad good not-attempted )],
     until => sub { !shift->failure };

   is( scalar $future->result, "good", '$future->result returns correct result for foreach+until' );
}

# foreach while + otherwise
{
   my $future = repeat {
      Future->done( $_[0] );
   } foreach => [ 1, 2, 3 ],
     while => sub { $_[0]->result < 2 },
     otherwise => sub { Future->fail( "Failed to find 2" ) };

   is( scalar $future->result, 2, '$future->result returns successful result from while + otherwise' );
}

# try_repeat_until_success foreach
{
   my $future = try_repeat_until_success {
      my $arg = shift;
      if( $arg eq "bad" ) {
         return Future->fail( "bad" );
      }
      else {
         return Future->done( $arg );
      }
   } foreach => [qw( bad good not-attempted )];

   is( scalar $future->result, "good", '$future->result returns correct result for try_repeat_until_success' );
}

# main code dies
{
   my $future = try_repeat {
      $_[1]->failure if @_ > 1; # absorb the previous failure

      die "It failed\n";
   } foreach => [ 1, 2, 3 ];

   is( $future->failure, "It failed\n", 'repeat foreach failure after code exception' );
}

# otherwise code dies
{
   my $future = repeat {
      Future->done;
   } foreach => [],
     otherwise => sub { die "It failed finally\n" };

   is( $future->failure, "It failed finally\n", 'repeat foreach failure after otherwise exception' );
}

done_testing;