| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package My::Module::Test; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 9 |  |  | 9 |  | 133902 | use 5.006002; | 
|  | 9 |  |  |  |  | 38 |  | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 9 |  |  | 9 |  | 48 | use strict; | 
|  | 9 |  |  |  |  | 14 |  | 
|  | 9 |  |  |  |  | 165 |  | 
| 6 | 9 |  |  | 9 |  | 41 | use warnings; | 
|  | 9 |  |  |  |  | 13 |  | 
|  | 9 |  |  |  |  | 414 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | our $VERSION = '0.129_01'; | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 9 |  |  | 9 |  | 48 | use Exporter qw{ import }; | 
|  | 9 |  |  |  |  | 14 |  | 
|  | 9 |  |  |  |  | 400 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 9 |  |  | 9 |  | 8895 | use Astro::Coord::ECI::TLE qw{ :constants }; | 
|  | 9 |  |  |  |  | 43 |  | 
|  | 9 |  |  |  |  | 1910 |  | 
| 13 | 9 |  |  | 9 |  | 66 | use Astro::Coord::ECI::Utils qw{ rad2deg }; | 
|  | 9 |  |  |  |  | 14 |  | 
|  | 9 |  |  |  |  | 502 |  | 
| 14 | 9 |  |  | 9 |  | 4567 | use Test::More 0.88; | 
|  | 9 |  |  |  |  | 466802 |  | 
|  | 9 |  |  |  |  | 89 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 9 |  |  | 9 |  | 2527 | use constant CODE_REF	=> ref sub {}; | 
|  | 9 |  |  |  |  | 21 |  | 
|  | 9 |  |  |  |  | 2400 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | our @EXPORT_OK = qw{ | 
| 19 |  |  |  |  |  |  | format_pass format_time | 
| 20 |  |  |  |  |  |  | magnitude | 
| 21 |  |  |  |  |  |  | tolerance tolerance_frac | 
| 22 |  |  |  |  |  |  | velocity_sanity | 
| 23 |  |  |  |  |  |  | }; | 
| 24 |  |  |  |  |  |  | our %EXPORT_TAGS = ( | 
| 25 |  |  |  |  |  |  | all => \@EXPORT_OK, | 
| 26 |  |  |  |  |  |  | format => [ qw{ format_pass format_time } ], | 
| 27 |  |  |  |  |  |  | tolerance => [ qw{ tolerance tolerance_frac } ], | 
| 28 |  |  |  |  |  |  | ); | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | # Perl::Critic can't find interpolated sub calls | 
| 31 |  |  |  |  |  |  | sub _dor {	## no critic (ProhibitUnusedPrivateSubroutines) | 
| 32 | 0 |  |  | 0 |  | 0 | foreach ( @_ ) { | 
| 33 | 0 | 0 |  |  |  | 0 | defined $_ and return $_; | 
| 34 |  |  |  |  |  |  | } | 
| 35 | 0 |  |  |  |  | 0 | return; | 
| 36 |  |  |  |  |  |  | } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | { | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | my @decoder; | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | # We jump through this hoop in case the constants turn out not to be | 
| 43 |  |  |  |  |  |  | # dualvars. | 
| 44 |  |  |  |  |  |  | BEGIN { | 
| 45 | 9 |  |  | 9 |  | 41 | $decoder[ PASS_EVENT_NONE ]	= ''; | 
| 46 | 9 |  |  |  |  | 31 | $decoder[ PASS_EVENT_SHADOWED ]	= 'shdw'; | 
| 47 | 9 |  |  |  |  | 15 | $decoder[ PASS_EVENT_LIT ]	= 'lit'; | 
| 48 | 9 |  |  |  |  | 18 | $decoder[ PASS_EVENT_DAY ]	= 'day'; | 
| 49 | 9 |  |  |  |  | 38 | $decoder[ PASS_EVENT_RISE ]	= 'rise'; | 
| 50 | 9 |  |  |  |  | 19 | $decoder[ PASS_EVENT_MAX ]	= 'max'; | 
| 51 | 9 |  |  |  |  | 17 | $decoder[ PASS_EVENT_SET ]	= 'set'; | 
| 52 | 9 |  |  |  |  | 16 | $decoder[ PASS_EVENT_APPULSE ]	= 'apls'; | 
| 53 | 9 |  |  |  |  | 18 | $decoder[ PASS_EVENT_START ]	= 'start'; | 
| 54 | 9 |  |  |  |  | 14562 | $decoder[ PASS_EVENT_END ]	= 'end'; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | sub _format_event { | 
| 58 | 304 |  |  | 304 |  | 412 | my ( $event ) = @_; | 
| 59 | 304 | 100 |  |  |  | 417 | defined $event or return ''; | 
| 60 | 297 |  |  |  |  | 701 | return $decoder[ $event + 0 ]; | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | sub format_pass { | 
| 66 | 36 |  |  | 36 | 1 | 8345 | my @passes = @_; | 
| 67 | 36 |  |  |  |  | 73 | my $rslt = ''; | 
| 68 | 36 |  |  |  |  | 72 | foreach my $pass ( @passes ) { | 
| 69 | 36 | 50 |  |  |  | 89 | $pass | 
| 70 |  |  |  |  |  |  | or next; | 
| 71 | 36 |  |  |  |  | 63 | $rslt .= "\n"; | 
| 72 | 36 |  |  |  |  | 46 | foreach my $event ( @{ $pass->{events} } ) { | 
|  | 36 |  |  |  |  | 130 |  | 
| 73 |  |  |  |  |  |  | $rslt .= sprintf '%19s %5s %5s %7s %-5s %-5s', | 
| 74 |  |  |  |  |  |  | format_time( $event->{time} ), | 
| 75 |  |  |  |  |  |  | _format_optional( '%5.1f', $event, 'elevation', \&rad2deg ), | 
| 76 |  |  |  |  |  |  | _format_optional( '%5.1f', $event, 'azimuth', \&rad2deg ), | 
| 77 |  |  |  |  |  |  | _format_optional( '%7.1f', $event, 'range' ), | 
| 78 |  |  |  |  |  |  | _format_event( $event->{illumination} ), | 
| 79 | 152 |  |  |  |  | 332 | _format_event( $event->{event} ), | 
| 80 |  |  |  |  |  |  | ; | 
| 81 | 152 |  |  |  |  | 1205 | $rslt =~ s/ \s+ \z //smx; | 
| 82 | 152 |  |  |  |  | 219 | $rslt .= "\n"; | 
| 83 | 152 | 100 |  |  |  | 328 | if ( $event->{appulse} ) { | 
| 84 | 10 |  |  |  |  | 17 | my $sta = $event->{station}; | 
| 85 |  |  |  |  |  |  | my ( $az, $el ) = $sta->azel( | 
| 86 | 10 |  |  |  |  | 64 | $event->{appulse}{body}->universal( $event->{time} ) ); | 
| 87 |  |  |  |  |  |  | $rslt .= sprintf '%19s %5.1f %5.1f %7.1f %s', '', | 
| 88 |  |  |  |  |  |  | rad2deg( $el ), | 
| 89 |  |  |  |  |  |  | rad2deg( $az ), | 
| 90 |  |  |  |  |  |  | rad2deg( $event->{appulse}{angle} ), | 
| 91 | 10 |  |  |  |  | 40 | $event->{appulse}{body}->get( 'name' ), | 
| 92 |  |  |  |  |  |  | ; | 
| 93 | 10 |  |  |  |  | 84 | $rslt =~ s/ \s+ \z //smx; | 
| 94 | 10 |  |  |  |  | 32 | $rslt .= "\n"; | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  | } | 
| 98 | 36 |  |  |  |  | 130 | $rslt =~ s/ \A \n //smx; | 
| 99 | 36 |  |  |  |  | 192 | $rslt =~ s/ (?<= \s ) - (?= 0 [.] 0+ \s ) / /smxg; | 
| 100 | 36 |  |  |  |  | 206 | return $rslt; | 
| 101 |  |  |  |  |  |  | } | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | sub _format_optional { | 
| 104 | 456 |  |  | 456 |  | 725 | my ( $tplt, $hash, $key, $xfrm ) = @_; | 
| 105 | 456 | 100 |  |  |  | 938 | defined( my $val = $hash->{$key} ) | 
| 106 |  |  |  |  |  |  | or return ''; | 
| 107 | 411 | 100 |  |  |  | 787 | CODE_REF eq ref $xfrm | 
| 108 |  |  |  |  |  |  | and $val = $xfrm->( $val ); | 
| 109 | 411 |  |  |  |  | 1800 | return sprintf $tplt, $val; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | sub format_time { | 
| 113 | 157 |  |  | 157 | 1 | 248 | my ( $time ) = @_; | 
| 114 | 157 |  |  |  |  | 498 | my @parts = gmtime int( $time + 0.5 ); | 
| 115 | 157 |  |  |  |  | 838 | return sprintf '%04d/%02d/%02d %02d:%02d:%02d', $parts[5] + 1900, | 
| 116 |  |  |  |  |  |  | $parts[4] + 1, @parts[ 3, 2, 1, 0 ]; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub magnitude { | 
| 120 | 1 |  |  | 1 | 1 | 5 | my ( $tle, @arg ) = @_; | 
| 121 | 1 |  |  |  |  | 4 | my ( $time, $want, $name ) = splice @arg, -3; | 
| 122 | 1 |  |  |  |  | 2 | my $got; | 
| 123 |  |  |  |  |  |  | eval { | 
| 124 | 1 |  |  |  |  | 5 | $got = $tle->universal( $time )->magnitude( @arg ); | 
| 125 | 1 | 50 |  |  |  | 12 | defined $got | 
| 126 |  |  |  |  |  |  | and $got = sprintf '%.1f', $got; | 
| 127 | 1 |  |  |  |  | 4 | 1; | 
| 128 | 1 | 50 |  |  |  | 2 | } or do { | 
| 129 | 0 |  |  |  |  | 0 | @_ = "$name failed: $@"; | 
| 130 | 0 |  |  |  |  | 0 | goto &fail; | 
| 131 |  |  |  |  |  |  | }; | 
| 132 | 1 | 50 |  |  |  | 4 | if ( defined $want ) { | 
| 133 | 1 |  |  |  |  | 5 | $want = sprintf '%.1f', $want; | 
| 134 | 1 |  |  |  |  | 5 | @_ = ( $got, 'eq', $want, $name ); | 
| 135 | 1 |  |  |  |  | 6 | goto &cmp_ok; | 
| 136 |  |  |  |  |  |  | } else { | 
| 137 | 0 |  |  |  |  | 0 | @_ = ( ! defined $got, $name ); | 
| 138 | 0 |  |  |  |  | 0 | goto &ok; | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | sub tolerance { | 
| 143 | 3430 |  |  | 3430 | 1 | 92617 | my ( $got, $want, $tolerance, $title, $fmtr ) = @_; | 
| 144 | 3430 |  | 100 | 0 |  | 20501 | $fmtr ||= sub { return $_[0] }; | 
|  | 0 |  |  |  |  | 0 |  | 
| 145 | 3430 |  |  |  |  | 19022 | $title =~ s{ (? | 
| 146 | 3430 |  |  |  |  | 10270 | my $delta = $got - $want; | 
| 147 | 3430 |  |  |  |  | 7196 | my $rslt = abs( $delta ) < $tolerance; | 
| 148 | 3430 | 50 |  |  |  | 5677 | $rslt or $title .= <<"EOD"; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 0 |  |  |  |  | 0 | Got: @{[ $fmtr->( $got ) ]} | 
| 151 | 0 |  |  |  |  | 0 | Expected: @{[ $fmtr->( $want ) ]} | 
| 152 |  |  |  |  |  |  | Difference: $delta | 
| 153 |  |  |  |  |  |  | Tolerance: $tolerance | 
| 154 |  |  |  |  |  |  | EOD | 
| 155 | 3430 |  |  |  |  | 4364 | chomp $title; | 
| 156 | 3430 |  |  |  |  | 4725 | local $Test::Builder::Level = $Test::Builder::Level + 1; | 
| 157 | 3430 |  |  |  |  | 8337 | return ok( $rslt, $title ); | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | sub tolerance_frac { | 
| 161 | 50 |  |  | 50 | 1 | 5777 | my ( $got, $want, $tolerance, $title, $fmtr ) = @_; | 
| 162 | 50 |  |  |  |  | 153 | @_ = ( $got, $want, $tolerance * abs $want, $title, $fmtr ); | 
| 163 | 50 |  |  |  |  | 141 | goto &tolerance; | 
| 164 |  |  |  |  |  |  | } | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | { | 
| 167 |  |  |  |  |  |  | my @dim_name = qw{ X Y Z }; | 
| 168 |  |  |  |  |  |  | my %method_dim_name = ( | 
| 169 |  |  |  |  |  |  | azel	=> [ qw{ azimuth elevation range } ], | 
| 170 |  |  |  |  |  |  | equatorial => [ 'right ascension', 'declination', 'range' ], | 
| 171 |  |  |  |  |  |  | ); | 
| 172 |  |  |  |  |  |  | my %tweak = ( | 
| 173 |  |  |  |  |  |  | azel => sub { | 
| 174 |  |  |  |  |  |  | my ( $delta, $current, $previous ) = @_; | 
| 175 |  |  |  |  |  |  | $delta->[0] *= cos( ( $current->[1] + $previous->[1] ) / 2 ); | 
| 176 |  |  |  |  |  |  | return; | 
| 177 |  |  |  |  |  |  | }, | 
| 178 |  |  |  |  |  |  | equatorial => sub { | 
| 179 |  |  |  |  |  |  | my ( $delta, $current, $previous ) = @_; | 
| 180 |  |  |  |  |  |  | $delta->[1] *= cos( ( $current->[0] + $previous->[0] ) / 2 ); | 
| 181 |  |  |  |  |  |  | return; | 
| 182 |  |  |  |  |  |  | }, | 
| 183 |  |  |  |  |  |  | ); | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | sub velocity_sanity { | 
| 186 | 6 |  |  | 6 | 0 | 17 | my ( $method, $body, $sta ) = @_; | 
| 187 | 6 |  |  |  |  | 13 | my $time = $body->universal(); | 
| 188 | 6 |  |  |  |  | 9 | my @rslt; | 
| 189 | 6 |  |  |  |  | 9 | foreach my $delta_t ( 0, 1 ) { | 
| 190 | 12 | 100 |  |  |  | 30 | $delta_t | 
| 191 |  |  |  |  |  |  | and $body->universal( $time + $delta_t ); | 
| 192 | 12 | 100 |  |  |  | 34 | my @coord = $sta ? $sta->$method( $body ) : | 
| 193 |  |  |  |  |  |  | $body->$method(); | 
| 194 |  |  |  |  |  |  | # Accommodate internal methods that return a reference to an | 
| 195 |  |  |  |  |  |  | # array of intermediate results. | 
| 196 | 12 | 50 |  |  |  | 20 | ref @coord and shift @coord; | 
| 197 | 12 |  |  |  |  | 26 | push @rslt, \@coord; | 
| 198 |  |  |  |  |  |  | } | 
| 199 | 6 |  |  |  |  | 11 | my @delta_p = map { $rslt[1][$_] - $rslt[0][$_] } ( 0 .. 2 ); | 
|  | 18 |  |  |  |  | 55 |  | 
| 200 |  |  |  |  |  |  | $tweak{$method} | 
| 201 | 6 | 100 |  |  |  | 20 | and $tweak{$method}->( \@delta_p, @rslt ); | 
| 202 | 6 |  |  |  |  | 18 | my @time_a = gmtime $time; | 
| 203 | 6 |  | 33 |  |  | 15 | my $title = sprintf | 
| 204 |  |  |  |  |  |  | '%s converted to %s at %i/%i/%i %i:%02i:%02i GMT', | 
| 205 |  |  |  |  |  |  | $body->get( 'name' ) || $body->get( 'id' ), $method, | 
| 206 |  |  |  |  |  |  | $time_a[5] + 1900, $time_a[4] + 1, @time_a[ 3, 2, 1, 0 ]; | 
| 207 | 6 |  |  |  |  | 12 | my $grade = \&pass; | 
| 208 | 6 |  |  |  |  | 10 | foreach my $inx ( 0 .. 2 ) { | 
| 209 | 18 |  |  |  |  | 22 | my $v_inx = $inx + 3; | 
| 210 | 18 | 100 | 33 |  |  | 93 | defined $rslt[0][$v_inx] | 
|  |  |  | 66 |  |  |  |  | 
|  |  |  | 66 |  |  |  |  | 
| 211 |  |  |  |  |  |  | and defined $rslt[1][$v_inx] | 
| 212 |  |  |  |  |  |  | and $rslt[0][$v_inx] <= $delta_p[$inx] | 
| 213 |  |  |  |  |  |  | and $delta_p[$inx] <= $rslt[1][$v_inx] | 
| 214 |  |  |  |  |  |  | and next; | 
| 215 | 13 | 50 | 33 |  |  | 72 | defined $rslt[0][$v_inx] | 
|  |  |  | 33 |  |  |  |  | 
|  |  |  | 33 |  |  |  |  | 
| 216 |  |  |  |  |  |  | and defined $rslt[1][$v_inx] | 
| 217 |  |  |  |  |  |  | and $rslt[0][$v_inx] >= $delta_p[$inx] | 
| 218 |  |  |  |  |  |  | and $delta_p[$inx] >= $rslt[1][$v_inx] | 
| 219 |  |  |  |  |  |  | and next; | 
| 220 | 0 |  | 0 |  |  | 0 | my $dim = $method_dim_name{$method}[$inx] || $dim_name[$inx]; | 
| 221 | 0 |  |  |  |  | 0 | $grade = \&fail; | 
| 222 | 0 |  |  |  |  | 0 | $title .= <<"EOD"; | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | $dim( t + 1 ): $rslt[1][$inx] | 
| 225 |  |  |  |  |  |  | $dim( t ): $rslt[0][$inx] | 
| 226 | 0 |  |  |  |  | 0 | $dim dot ( t ): @{[ _dor( $rslt[0][$v_inx], '' ) ]} | 
| 227 |  |  |  |  |  |  | $dim( t + 1 ) - $dim( t ): $delta_p[$inx] | 
| 228 | 0 |  |  |  |  | 0 | $dim dot ( t + 1 ): @{[ _dor( $rslt[1][$v_inx], '' ) ]} | 
| 229 |  |  |  |  |  |  | EOD | 
| 230 | 0 |  |  |  |  | 0 | chomp $title; | 
| 231 |  |  |  |  |  |  | } | 
| 232 | 6 |  |  |  |  | 14 | @_ = ( $title ); | 
| 233 | 6 |  |  |  |  | 30 | goto &$grade; | 
| 234 |  |  |  |  |  |  | } | 
| 235 |  |  |  |  |  |  | } | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | 1; | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | __END__ |