File Coverage

blib/lib/Data/TOON/Validator.pm
Criterion Covered Total %
statement 30 32 93.7
branch 14 24 58.3
condition 3 9 33.3
subroutine 6 6 100.0
pod 0 2 0.0
total 53 73 72.6


line stmt bran cond sub pod time code
1             package Data::TOON::Validator;
2 10     10   185 use 5.014;
  10         36  
3 10     10   53 use strict;
  10         19  
  10         262  
4 10     10   58 use warnings;
  10         36  
  10         7222  
5              
6             sub new {
7 3     3 0 4 my ($class) = @_;
8 3         8 return bless {}, $class;
9             }
10              
11             sub validate {
12 3     3 0 5 my ($self, $toon_text) = @_;
13            
14 3 50 33     801 return 1 if !$toon_text || $toon_text =~ /^\s*$/;
15            
16 3         16 my @lines = split /\r?\n/, $toon_text;
17 3 50 33     10 pop @lines if @lines && $lines[-1] eq '';
18            
19             # Find first non-empty line
20 3 50       4 my @non_empty = grep { $_ && $_ !~ /^\s*$/ } @lines;
  6         21  
21            
22             # Empty document is valid
23 3 50       6 return 1 if !@non_empty;
24            
25             # Validate each line
26 3         5 foreach my $line (@lines) {
27 6 50 33     17 next if !$line || $line =~ /^\s*$/;
28            
29             # Check for valid key-value or header
30 6 50       10 if (!$self->_is_valid_line($line)) {
31 0         0 return 0;
32             }
33             }
34            
35 3         13 return 1;
36             }
37              
38             sub _is_valid_line {
39 6     6   7 my ($self, $line) = @_;
40            
41             # Remove leading whitespace to check depth
42 6         8 my $trimmed = $line;
43 6         10 $trimmed =~ s/^ +//;
44            
45             # Empty line is valid
46 6 50       10 return 1 if !$trimmed;
47            
48             # Valid patterns:
49             # 1. key: value
50             # 2. key[N]: ...
51             # 3. key[N]{fields}: ...
52             # 4. - value (list item)
53             # 5. [N]: ... (root array)
54             # 6. CSV row (anything else that looks like values)
55            
56 6 100       17 return 1 if $trimmed =~ /^[\w"]+\s*:/; # key: ...
57 4 100       11 return 1 if $trimmed =~ /^[\w"]+\s*\[\d+\]/; # key[N]...
58 2 50       5 return 1 if $trimmed =~ /^-\s/; # - item
59 2 50       4 return 1 if $trimmed =~ /^\[\d+\]/; # [N]: ... (root array)
60            
61             # If the line has content (looks like a CSV row or data line), it's probably valid
62             # This is a permissive approach - stricter validation would require context
63 2 50       7 return 1 if $trimmed =~ /\S/;
64            
65 0           return 0;
66             }
67              
68             1;