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   885348 use strict;
  4         25  
  4         110  
4 4     4   33 use warnings;
  4         9  
  4         105  
5              
6 4     4   1562 use RxPerl::SyncTimers ':all';
  4         14  
  4         1983  
7              
8 4     4   31 use Carp 'croak';
  4         8  
  4         229  
9 4     4   29 use Test2::V0;
  4         7  
  4         32  
10              
11 4     4   4648 use Exporter 'import';
  4         9  
  4         3324  
12             our @EXPORT = qw/ obs_is cold /;
13              
14             our $VERSION = "v6.27.0";
15              
16             sub cold {
17 189     189 0 170042 my ($marble, $mapping) = @_;
18              
19 189         503 $marble =~ s/\-\z/\|/;
20 189   100     749 $mapping //= {};
21              
22             # Syntax check
23 189 50       1919 croak 'Invalid syntax in marble diagram of cold' if $marble !~ /^((?:\((?:[a-z0-9|#])+?\))|[a-z0-9|#-])*\z/gx;
24 189         507 pos $marble = 0;
25              
26 189         1330 my @tokens = $marble =~ /[a-z0-9\(\)\-\|\#]/g;
27              
28 189         293 my @components;
29 189         260 my $time = 0;
30 189         238 my $have_waited = 0;
31 189         237 my $in_brackets = 0;
32              
33 189         458 TOKEN: for (my $i = 0; $i < @tokens; $i++) {
34 1483         2323 my $token = $tokens[$i];
35 1483 100       4023 if ($token =~ /^[a-z0-9]\z/) {
    100          
    100          
    100          
    100          
    50          
36 670 100       1374 $token = $mapping->{$token} if exists $mapping->{$token};
37 670         1477 push @components, rx_of($token)->pipe(op_delay($time));
38 670         997 $have_waited = $time;
39 670 100       1908 $time++ unless $in_brackets;
40             } elsif ($token eq '(') {
41 29         71 $in_brackets = 1;
42             } elsif ($token eq ')') {
43 28         36 $in_brackets = 0;
44 28         57 $time++;
45             } elsif ($token eq '-') {
46 693         1648 $time++;
47             } elsif ($token eq '|') {
48 44 100       93 if ($time > $have_waited) {
49 43         103 push @components, rx_timer($time)->pipe(op_ignore_elements);
50             }
51 44         118 last TOKEN;
52             } elsif ($token eq '#') {
53 19         47 push @components, rx_concat(
54             rx_timer($time)->pipe(op_ignore_elements),
55             rx_throw_error,
56             );
57 19         56 last TOKEN;
58             }
59             }
60              
61 189         489 return rx_merge(@components);
62             }
63              
64             sub get_timeline {
65 236     236 0 379 my ($observable) = @_;
66              
67 236         329 my %timeline;
68              
69 236         727 RxPerl::SyncTimers->reset;
70              
71             $observable->subscribe({
72             next => sub {
73 764     764   1336 my ($value) = @_;
74              
75 764         1028 my $time = $RxPerl::SyncTimers::time;
76 764         962 push @{$timeline{$time}}, { next => $value };
  764         2749  
77             },
78             error => sub {
79 20     20   31 my ($error) = @_;
80              
81 20         36 my $time = $RxPerl::SyncTimers::time;
82 20         27 push @{$timeline{$time}}, { error => $error };
  20         65  
83             },
84             complete => sub {
85 216     216   325 my $time = $RxPerl::SyncTimers::time;
86 216         271 push @{$timeline{$time}}, {complete => undef};
  216         614  
87             },
88 236         1654 });
89              
90 236         1045 RxPerl::SyncTimers->start;
91              
92 236         782 return \%timeline;
93             }
94              
95             sub obs_is {
96 118     118 0 9284 my ($o, $expected, $name) = @_;
97              
98 118         213 my ($marble, $mapping) = @$expected;
99              
100 118         219 return is(get_timeline($o), get_timeline(cold($marble, $mapping)), $name);
101             }
102              
103             1;