File Coverage

blib/lib/RxPerl/Test.pm
Criterion Covered Total %
statement 65 65 100.0
branch 18 20 90.0
condition 2 2 100.0
subroutine 12 12 100.0
pod 0 3 0.0
total 97 102 95.1


line stmt bran cond sub pod time code
1             package RxPerl::Test;
2              
3 4     4   744894 use strict;
  4         20  
  4         90  
4 4     4   18 use warnings;
  4         6  
  4         87  
5              
6 4     4   1218 use RxPerl::SyncTimers ':all';
  4         14  
  4         1725  
7              
8 4     4   25 use Carp 'croak';
  4         6  
  4         171  
9 4     4   21 use Test2::V0;
  4         7  
  4         29  
10              
11 4     4   4096 use Exporter 'import';
  4         8  
  4         2432  
12             our @EXPORT = qw/ obs_is cold /;
13              
14             our $VERSION = "v6.27.1";
15              
16             sub cold {
17 189     189 0 142166 my ($marble, $mapping) = @_;
18              
19 189         447 $marble =~ s/\-\z/\|/;
20 189   100     692 $mapping //= {};
21              
22             # Syntax check
23 189 50       1593 croak 'Invalid syntax in marble diagram of cold' if $marble !~ /^((?:\((?:[a-z0-9|#])+?\))|[a-z0-9|#-])*\z/gx;
24 189         449 pos $marble = 0;
25              
26 189         1064 my @tokens = $marble =~ /[a-z0-9\(\)\-\|\#]/g;
27              
28 189         256 my @components;
29 189         200 my $time = 0;
30 189         194 my $have_waited = 0;
31 189         205 my $in_brackets = 0;
32              
33 189         355 TOKEN: for (my $i = 0; $i < @tokens; $i++) {
34 1483         1897 my $token = $tokens[$i];
35 1483 100       3292 if ($token =~ /^[a-z0-9]\z/) {
    100          
    100          
    100          
    100          
    50          
36 670 100       1141 $token = $mapping->{$token} if exists $mapping->{$token};
37 670         1200 push @components, rx_of($token)->pipe(op_delay($time));
38 670         874 $have_waited = $time;
39 670 100       1540 $time++ unless $in_brackets;
40             } elsif ($token eq '(') {
41 29         55 $in_brackets = 1;
42             } elsif ($token eq ')') {
43 28         37 $in_brackets = 0;
44 28         52 $time++;
45             } elsif ($token eq '-') {
46 693         1047 $time++;
47             } elsif ($token eq '|') {
48 44 100       79 if ($time > $have_waited) {
49 43         111 push @components, rx_timer($time)->pipe(op_ignore_elements);
50             }
51 44         91 last TOKEN;
52             } elsif ($token eq '#') {
53 19         48 push @components, rx_concat(
54             rx_timer($time)->pipe(op_ignore_elements),
55             rx_throw_error,
56             );
57 19         45 last TOKEN;
58             }
59             }
60              
61 189         391 return rx_merge(@components);
62             }
63              
64             sub get_timeline {
65 236     236 0 290 my ($observable) = @_;
66              
67 236         260 my %timeline;
68              
69 236         646 RxPerl::SyncTimers->reset;
70              
71             $observable->subscribe({
72             next => sub {
73 764     764   1059 my ($value) = @_;
74              
75 764         848 my $time = $RxPerl::SyncTimers::time;
76 764         751 push @{$timeline{$time}}, { next => $value };
  764         2271  
77             },
78             error => sub {
79 20     20   30 my ($error) = @_;
80              
81 20         27 my $time = $RxPerl::SyncTimers::time;
82 20         28 push @{$timeline{$time}}, { error => $error };
  20         53  
83             },
84             complete => sub {
85 216     216   277 my $time = $RxPerl::SyncTimers::time;
86 216         212 push @{$timeline{$time}}, {complete => undef};
  216         515  
87             },
88 236         1349 });
89              
90 236         806 RxPerl::SyncTimers->start;
91              
92 236         698 return \%timeline;
93             }
94              
95             sub obs_is {
96 118     118 0 7346 my ($o, $expected, $name) = @_;
97              
98 118         178 my ($marble, $mapping) = @$expected;
99              
100 118         203 return is(get_timeline($o), get_timeline(cold($marble, $mapping)), $name);
101             }
102              
103             1;