Branch Coverage

lib/ChordPro/Song.pm
Criterion Covered Total %
branch 459 750 61.2


line true false branch
113 0 170 unless ref $meta eq "HASH"
116 0 170 if $main::options->{'verbose'}
120 0 170 if ($lines->[0] =~ /^##config:\s*json/)
125 0 0 if ($lines->[0] =~ /^# (.*)/) { }
134 0 0 if ($cf)
143 79 0 if (not $main::options->{'nosongconfig'} and $diag->{'file'})
144 0 79 if ($main::options->{'verbose'})
146 0 0 defined $this ? :
149 0 0 $this eq $_ ? :
152 0 79 if ($meta and $meta->{'__config'}) { }
154 0 0 unless -s $cf
155 0 0 if $main::options->{'verbose'}
162 144 14 if $cf eq $diag->{'file'}
163 158 0 unless -s $cf
164 0 0 if $main::options->{'verbose'}
173 0 0 if $main::options->{'verbose'}
176 0 0 if ($tuncheck ne join("|", @{$main::config->{'tuning'};}))
179 0 0 if $res
183 0 0 if ($chords)
185 0 0 if (@$c and $c->[0] eq "append")
192 0 0 if $res
195 0 0 if ($main::options->{'verbose'} > 1)
196 0 0 if $chords
212 0 170 if (%$defs)
219 662 18 unless defined $main::options->{$_}
223 0 170 unless (UNIVERSAL::isa($main::config->{'instrument'}, "HASH"))
234 0 0 if (UNIVERSAL::isa($main::config->{'meta'}{$_}, 'ARRAY')) { }
246 2 168 if ($target) { }
247 2 0 unless ("ChordPro::Chords::Parser"->have_parser($target))
248 2 0 if (my $file = main::rsc_or_file("config/notes/$target.json"))
256 0 2 unless ("ChordPro::Chords::Parser"->have_parser($target))
259 0 2 if $main::options->{'verbose'}
263 0 2 if ($target ne $p->{'system'})
278 170 0 if $meta
286 0 170 if ($main::options->{'meta'})
293 1 169 if ($main::config->{'settings'}{'memorize'}) { }
302 0 1936 if ($skipcnt) { }
327 0 1936 if ($main::config->{'debug'}{'echo'})
331 0 1936 if ($prep->{'all'})
335 0 0 if (/\n/)
343 4 1932 if ($skip_context)
344 2 2 if (/^\s*\{(\w+)\}\s*$/)
346 2 0 if ($dir->{'name'} eq "end_of_$in_context")
354 32 1900 if (/^\s*\{(new_song|ns)\}\s*$/)
355 29 3 if $self->{'body'}
359 55 1845 if (/^#/)
364 1 54 if (/^##(image|asset):\s+(.*)/i)
369 1 54 if ($kw eq "image")
371 0 1 unless ($id)
389 0 1 if ($info->{'error'})
399 0 1 $kv->{'persist'} ? :
402 0 1 if ($main::config->{'debug'}{'images'})
405 0 0 $kv->{'persist'} ? :
411 0 54 if ($kw eq "asset")
414 0 0 unless ($id)
418 0 0 unless ($type)
437 0 0 if ($main::config->{'debug'}{'images'})
444 54 0 if (exists $self->{'title'} or $fragment) { }
453 62 1783 if ($in_context eq "tab")
454 49 13 unless (/^\s*\{(?:end_of_tab|eot)\}\s*$/)
460 0 1796 if (exists $main::config->{'delegates'}{$in_context})
462 0 0 if (/^\s*\{(?:end_of_\Q$in_context\E)\}\s*$/) { }
0 0 elsif ($main::config->{'delegates'}{$in_context}{'omit'}) { }
463 0 0 if ($main::config->{'delegates'}{$in_context}{'omit'}) { }
475 0 0 if ($self->{'body'} and @{$self->{'body'};} and $self->{'body'}[-1]{'context'} eq $in_context and $self->{'body'}[-1]{'open'}) { }
485 0 0 if ($xpose or $main::config->{'settings'}{'transpose'})
503 1004 792 if (/^\s*\{(.*)\}\s*$/)
505 0 1004 if ($prep->{'directive'})
510 1 1003 unless $self->directive($dir)
516 0 495 if (/\S/ and not $fragment and not exists $self->{'title'})
523 0 792 if ($in_context eq "tab")
529 39 753 if ($in_context eq "grid")
534 456 297 if (/\S/) { }
297 0 elsif (exists $self->{'title'} or $fragment) { }
535 0 456 if ($prep->{'songline'})
550 0 170 if $in_context
556 0 170 if $main::options->{'verbose'}
559 0 170 if $main::config->{'debug'}{'song'} > 1
561 1 169 if (@labels)
570 0 0 unless $info
573 0 0 if ($xc)
580 2 428 unless is_true($v->{'diagram'} // 1)
582 2 900 $suppress{$_} ? :
585 5 165 if (exists $self->{'settings'}{'diagrams'}) { }
593 0 170 if ($diagrams =~ /^(user|all)$/ and not "ChordPro::Chords::Parser"->get_parser($target, 1)->has_diagrams)
596 0 0 unless $main::options->{'silent'}
600 0 170 if ($diagrams eq 'user') { }
602 0 0 if ($self->{'define'} and @{$self->{'define'};}) { }
605 0 0 $h{$_->{'name'}} ? :
613 591 309 $h{$_}++ ? :
617 0 170 if ($main::config->{'diagrams'}{'sorted'})
626 114 56 if ($diagrams =~ /^(user|all)$/)
634 0 114 if (%warned_chords)
638 0 0 if (@a > 1) { }
649 0 170 if $main::config->{'debug'}{'song'}
650 0 170 if $main::config->{'debug'}{'songfull'}
657 0 1238 if $skip_context
660 1024 214 $lineinfo ? :
662 108 1130 if ($in_context eq "chorus")
674 0 937 unless length $orig
677 3 934 if ($orig =~ /^\*(.+)/ or $orig =~ /^(\||\s+)$/)
688 927 7 if ($markup eq $c)
694 0 934 if $c =~ s/^\((.*)\)$/$1/
699 0 934 unless (defined $info)
712 7 927 if ($markup) { }
927 0 elsif ((my $m = $orig) =~ s/\Q$c\E/%{formatted}/) { }
713 6 1 if ($markup =~ s/\>\Q$c\E\%{formatted}\(\Q$c\E\)\(%{formatted})
723 5 922 unless $m eq "%{formatted}"
731 922 12 unless ($info->is_nc or $info->is_note)
733 0 922 if ($main::config->{'instrument'}{'type'} eq 'keyboard') { }
766 156 elsif ($info->{'origin'}) { }
156 0 elsif ($main::running_under_test) { }
0 0 elsif (not $info->is_rootless || $info->has_diagram || !$info->parser->has_diagrams) { }
738 766 0 if $info->has_diagram
749 0 0 unless $warned_chords{$c}++
759 579 1 if $orig eq $line
763 237 343 if (@a <= 1)
764 0 237 $orig ? :
770 113 230 if $a[0] eq ""
771 230 113 unless $a[0] =~ /$re_chords/
780 1008 27 if ($chord =~ s/^\[(.*)\]$/$1/ and $chord ne '^') { }
20 7 elsif ($memchords and $in_context) { }
781 230 778 $chord eq '' ? :
782 21 987 if ($memchords and not $dummy)
783 3 18 if ($memcrdinx == 0)
786 20 1 if ($memorizing)
790 0 20 if $main::config->{'debug'}{'chords'}
798 1 19 if ($memcrdinx == 0 and @$memchords == 0) { }
0 19 elsif ($memcrdinx >= @$memchords) { }
810 0 19 if $main::config->{'debug'}{'chords'}
823 1 342 $orig ? :
831 124 0 unless $no_substitute
833 110 14 unless $res{'chords'}
841 0 39 if $line eq ""
845 0 39 if (not $line =~ /\|/) { }
850 0 39 if ($line =~ /(.*\|\S*)\s([^\|]*)$/)
853 0 0 unless $grid_cells->[2]
856 0 39 if ($line =~ /^([^|]+?)\s*(\|.*)/)
859 0 0 unless $grid_cells->[1]
871 0 663 if (/\
875 0 0 if m[\]
882 0 663 if ($_ eq '|:' or $_ eq '{') { }
0 663 elsif (/^\|(\d+)(>?)$/) { }
0 663 elsif ($_ eq ':|' or $_ eq '}') { }
0 663 elsif ($_ eq ':|:' or $_ eq '}{') { }
149 514 elsif ($_ eq '|') { }
2 512 elsif ($_ eq '||') { }
0 512 elsif ($_ eq '|.') { }
0 512 elsif ($_ eq '%') { }
0 512 elsif ($_ eq '%%') { }
0 512 elsif ($_ eq '/') { }
395 117 elsif ($_ eq '.') { }
887 0 0 if $2
920 116 1 if (@a == 1) { }
927 0 2 $_ eq '/' ? :
0 2 $_ eq '.' || $_ eq '' ? :
937 0 39 if ($nbt > $grid_cells->[0])
1032 58 948 unless ($dirpat)
1048 791 215 if ($d =~ /^(.*?)[: ]\s*(.*)/)
1056 11 995 if ($dir =~ /^($dirpat)-(.+)$/) { }
1066 6 5 if $negate
1067 4 7 unless ($sel)
1068 2 2 if ($dir =~ /^start_of_/) { }
1087 2 1002 if $dd->{'omit'} == 1
1090 788 214 if ($arg ne "")
1092 0 788 unless $arg =~ /\S/
1098 77 925 if ($dir =~ /^start_of_(\w+)$/)
1099 0 77 if $in_context
1102 2 75 if ($dd->{'omit'})
1107 27 48 if $in_context eq "chorus"
1109 25 50 if ($in_context eq 'grid') { }
2 48 elsif ($arg and $arg ne '') { }
1110 3 22 if ($arg eq '') { }
22 0 elsif ($arg =~ /^ (?: (\d+) \+)? (\d+) (?: x (\d+) )? (?:\+ (\d+) )? (?:[:\s+] (.*)? )? $/x) { }
0 0 elsif ($arg ne '') { }
1120 0 22 unless $2
1126 0 22 if length($5 || '')
1142 2 0 unless $in_context eq "chorus" and not $main::config->{'settings'}{'choruslabels'}
1145 0 48 if $arg
1151 7 68 if ($main::config->{'settings'}{'memorize'})
1158 75 850 if ($dir =~ /^end_of_(\w+)$/)
1159 0 75 unless $in_context eq $1
1168 30 820 if ($dir =~ /^chorus$/i)
1169 0 30 if ($in_context)
1175 29 1 @chorus ? :
1177 0 29 if (@$chorus and $arg and $arg ne "")
1178 0 0 if ($chorus->[0]{'type'} eq 'set' and $chorus->[0]{'name'} eq 'label') { }
1190 0 0 if $main::config->{'settings'}{'choruslabels'}
1193 17 13 if ($chorus_xpose != (my $xp = $xpose))
1196 16 16 if ($_->{'type'} eq "songline")
1198 15 46 if $_ eq ""
1200 0 46 if $info->is_annotation
1201 46 0 if $xp
1213 29 1 @$chorus ? :
1225 13 807 if ($dir eq "column_break")
1230 16 791 if ($dir eq "new_page" or $dir eq "new_physical_page")
1235 0 791 if ($dir eq "new_song")
1241 124 667 if ($dir =~ /^comment(_italic|_box)?$/)
1245 124 0 unless exists $res{'text'} and $res{'text'} =~ /^[ \t]*$/
1250 3 664 if ($dir eq "image")
1256 1 8 if ($k =~ /^(title)$/i and $v ne '') { }
2 6 elsif ($k =~ /^(border|spread|center)$/i and $v =~ /^(\d+)$/) { }
2 4 elsif ($k =~ /^(width|height)$/i and $v =~ /^(\d+(?:\.\d+)?\%?)$/) { }
0 4 elsif ($k =~ /^(x|y)$/i and $v =~ /^([-+]?\d+(?:\.\d+)?\%?)$/) { }
1 3 elsif ($k =~ /^(scale)$/ and $v =~ /^(\d+(?:\.\d+)?)(%)?$/) { }
0 3 elsif ($k =~ /^(center|border|spread)$/i) { }
0 3 elsif ($k =~ /^(src|uri)$/i and $v ne '') { }
1 2 elsif ($k =~ /^(id)$/i and $v ne '') { }
0 2 elsif ($k =~ /^(anchor)$/i and $v =~ /^(paper|page|column|float|line)$/) { }
0 2 elsif ($uri) { }
1269 0 1 $2 ? :
1297 2 1 if ($uri and not $uri =~ m(^([a-z]:)?[/\\])i)
1300 2 0 if -s "$_/$uri"
1302 0 0 unless $_
1303 0 0 if -s $_
1310 0 3 if ($uri and $id)
1312 0 0 if (%opts)
1318 0 0 unless ($fd)
1325 0 0 if ($info->{'error'})
1337 0 0 if ($main::config->{'debug'}{'images'})
1345 1 2 if $id
1346 0 3 unless ($uri)
1350 0 3 $uri =~ /\.svg$/ ? :
1356 174 490 if ($dir eq "title")
1362 28 462 if ($dir eq "subtitle")
1370 225 237 if (&any(sub { $_ eq $dir; } , @{$$main::config{"metadata"}{"keys"};}))
1376 263 199 if ($dir eq "meta")
1377 263 0 if ($arg =~ /([^ :]+)[ :]+(.*)/) { }
1380 256 7 if ($main::config->{'metadata'}{'autosplit'})
1387 0 263 if ($key eq "user" or $key eq "instrument")
1394 92 171 if ($key eq "key")
1400 0 92 if ($capo)
1402 0 0 if $decapo
1413 16 155 if ($key eq 'capo') { }
9 292 elsif ($key eq 'duration' and $val) { }
1415 1 15 if exists $m->{'capo'}
1418 16 0 if ($capo and $m->{'key'})
1419 4 12 if ($decapo) { }
1443 0 171 if ($main::config->{'metadata'}{'strict'} and not &any(sub { $_ eq $key; } , @{$$main::config{"metadata"}{"keys"};}))
1447 0 0 if $main::config->{'settings'}{'strict'}
1451 171 0 if defined $val
1456 0 0 if $main::config->{'settings'}{'strict'}
1464 22 177 if ($dir eq "titles" and $arg =~ /^(left|right|center|centre)$/i)
1467 1 21 lc $1 eq 'centre' ? :
1471 19 158 if ($dir eq "columns" and $arg =~ /^(\d+)$/)
1475 19 0 unless (ref $main::config->{'settings'}{'columns'} eq "ARRAY" and $arg == @{$main::config->{'settings'}{'columns'};})
1483 2 156 if ($dir eq "pagetype" or $dir eq "pagesize")
1488 2 154 if ($dir eq "diagrams")
1489 1 1 if ($arg ne '') { }
1491 1 0 if $arg =~ /^(right|bottom|top|below)$/i
1499 3 151 if ($dir eq "no_grid")
1504 53 98 if ($dir eq "transpose")
1507 32 21 if ($arg =~ /^([-+]?\d+)\s*$/) { }
1517 22 10 if ($m->{'key'})
1520 2 20 if $capo
1526 0 32 if $no_transpose
1536 21 0 if (@{$propstack{'transpose'};}) { }
1545 15 6 if ($m->{'key'})
1548 0 15 if $capo and $decapo
1552 12 9 unless (@{$propstack{'transpose'};})
1555 0 21 if $no_transpose
1562 0 98 if (not $main::options->{'reference'} and $d =~ /^([-+])([-\w.]+)$/i)
1563 0 0 if ($2 eq "dumpmeta")
1566 0 0 $1 eq '+' ? :
1573 11 87 if (not $main::options->{'reference'} and $dir =~ /^\+([-\w.]+(?:\.[<>])?)$/)
1594 0 11 if (ref $o eq "HASH" and ref $o->{$lk} eq "ARRAY")
1601 0 11 if ($lk =~ /^\d+$/ || $lk eq '>' || $lk eq '<' and ref $o eq 'ARRAY') { }
1603 0 0 unless (ref $$c eq "ARRAY")
1607 0 0 if ($lk eq '>') { }
0 0 elsif ($lk eq '<') { }
1628 28 59 if ($dir =~ / ^( text | chord | chorus | tab | grid | diagrams | title | footer | toc ) ( font | size | colou?r ) $/x)
1638 9 19 if $item eq "text"
1650 58 1 if ($dir eq "define" or $dir eq "chord")
1657 0 1 if $main::config->{'settings'}{'strict'} and not $d =~ /^x_/
1663 12 25 if $prop eq "colour"
1667 2 35 if ($value eq "")
1669 2 0 if (@{$propstack{$name};}) { }
1673 0 2 if ($prop eq "font" and $old =~ /\s(\d+(?:\.\d+)?)$/)
1681 2 0 if (@{$propstack{$name};}) { }
1693 10 25 if ($prop eq "size")
1694 0 10 unless ($value =~ /^\d+(?:\.\d+)?\%?$/)
1699 15 20 if ($prop eq "color")
1701 0 15 unless ($v = get_color($value))
1707 10 25 $prop eq 'font' ? :
1715 0 35 if ($prop eq "font" and $value =~ /\s(\d+(?:\.\d+)?)$/)
1726 942 49 if ($new_id) { }
1727 10 932 if ($new_id eq 1)
1750 2 68 unless @a
1764 11 151 if ($a eq 'copy' or $a eq 'copyall') { }
2 149 elsif ($a eq 'display' and @a) { }
9 140 elsif ($a eq 'format' and @a) { }
46 94 elsif ($a eq 'base-fret') { }
57 37 elsif ($a eq 'frets') { }
16 21 elsif ($a eq 'fingers') { }
8 13 elsif ($a eq 'keys') { }
13 0 elsif ($a eq 'diagram' and @a > 0) { }
1765 11 0 if (my $i = ChordPro::Chords::known_chord($a[0])) { }
1781 0 2 unless $kv{'display'} eq shift @a
1783 0 2 unless defined $kv{'display'}
1793 46 0 if ($a[0] =~ /^\d+$/) { }
1808 57 0 if (@f == $strings) { }
1809 302 40 $_ =~ /^\d+/ ? :
1825 90 6 if (/^[0-9]+$/) { }
0 6 elsif (/^[A-MO-WYZ]$/) { }
6 0 elsif (/^[-xNX]$/) { }
1839 16 0 if (@f == $strings) { }
1856 8 0 if (@f) { }
1867 0 13 if ($show and not is_true($a[0]))
1885 0 70 if $fail
1893 70 0 if ($info) { }
1900 8 62 if ($show)
1911 59 11 unless defined $_
1916 0 11 if ($kv{'copyall'})
1922 11 129 if defined $kv{$_}
1926 13 57 if (defined $kv{'diagram'})
1928 7 6 if (is_true($v)) { }
1929 6 1 if (is_ttrue($v))
1942 282 138 unless defined $kv{$_}
1948 8 62 $show ? :
1952 8 62 if ($show)
1956 2 6 if (defined $self->{'body'} and $self->{'body'}[-1]{'type'} eq 'diagrams') { }
1971 250 246 unless defined $res->{$_}
1976 0 62 if ($ret)
1981 0 62 unless $info
1983 0 62 if $main::config->{'debug'}{'x1'}
1991 9 0 if ($dur =~ /(?:(?:(\d+):)?(\d+):)?(\d+)/)
1992 0 9 $2 ? :
0 9 $1 ? :
2037 0 1112 if $debug
2040 4 1108 if $capo and $decapo
2046 72 1040 if $def
2049 880 232 if ($info) { }
2051 0 880 if $debug > 1
2052 0 880 if $debug > 1
2058 0 232 if $info and $debug > 1
2062 21 1091 if ($def || $xp || $xc and not $info && $info->is_xpxc)
2069 0 0 unless ($info and $info->is_xpxc or $def and not $xc || $xp)
2076 0 0 $xp ? :
0 0 $xc ? :
0 0 if $xp or $xc or $main::config->{'debug'}{'chords'}
2079 156 956 if ($xp and $info)
2084 154 2 unless $i eq $info
2086 0 156 if $debug > 1
2092 1112 0 if ($info)
2094 885 227 if (my $i = ChordPro::Chords::known_chord($info)) { }
0 227 elsif ($main::config->{'instrument'}{'type'} eq 'keyboard' and my $k = ChordPro::Chords::get_keys($info)) { }
2097 0 885 if $debug > 1
2100 90 795 $info->{'xp'} ? :
0 885 $info->{'xc'} ? :
2106 0 0 if $debug > 1
2112 0 227 if $debug
2119 20 1092 if ($xc and $info)
2122 14 6 if $self->{'meta'}{'key'}
2123 0 20 if ($xcmov and not defined $key_ord)
2129 20 0 unless $i eq $info
2133 0 20 if $debug > 1
2135 8 12 if (my $i = ChordPro::Chords::known_chord($info))
2136 0 8 if $debug > 1
2143 0 1112 unless ($info)
2144 0 0 if (my $i = ChordPro::Chords::known_chord($chord))
2148 0 0 if $debug > 1
2153 0 1112 unless ($info or $def)
2154 0 0 if ($main::config->{'debug'}{'chords'} or not $warned_chords{$chord}++)
2155 0 0 if $debug
2156 0 0 unless $chord =~ /^n\.?c\.?$/i
2161 1112 0 if ($info)
2162 0 0 $unk ? :
0 1112 if $debug > 1
2171 0 0 if $debug
2184 0 13 if $self->{'structure'} eq "structured"
2190 56 195 if ($item->{'type'} eq "empty" and $item->{'context'} eq $def_context)
2194 36 159 if ($item->{'type'} eq "songline" and $item->{'context'} eq "")
2197 49 146 if ($context ne $item->{'context'})
2200 135 60 if ($context) { }
2215 0 0 unless ($full)