File Coverage

blib/lib/JSAN/ServerSide.pm
Criterion Covered Total %
statement 64 65 98.4
branch 4 4 100.0
condition 2 3 66.6
subroutine 15 16 93.7
pod 4 4 100.0
total 89 92 96.7


line stmt bran cond sub pod time code
1             package JSAN::ServerSide;
2              
3 2     2   63181 use strict;
  2         6  
  2         85  
4 2     2   11 use warnings;
  2         4  
  2         94  
5              
6             our $VERSION = '0.06';
7              
8              
9 2     2   2109 use URI::ToDisk;
  2         42761  
  2         98  
10 2     2   2119 use JSAN::Parse::FileDeps;
  2         2131  
  2         72  
11 2     2   1906 use Params::Validate qw( validate SCALAR );
  2         26874  
  2         1658  
12              
13              
14             sub new
15             {
16 4     4 1 1923 my $class = shift;
17 4         282 my %p = validate( @_,
18             { js_dir => { type => SCALAR },
19             uri_prefix => { type => SCALAR },
20             },
21             );
22              
23 4         61 my $location = URI::ToDisk->new( $p{js_dir}, $p{uri_prefix} );
24              
25 4         36006 return bless { location => $location }, $class;
26             }
27              
28             sub add
29             {
30 3     3 1 18 my $self = shift;
31 3         6 my $js_class = shift;
32              
33 3         14 $self->_record_dependencies($js_class);
34              
35 3         6 push @{ $self->{classes} }, $js_class;
  3         11  
36             }
37              
38             sub _record_dependencies
39             {
40 14     14   19 my $self = shift;
41 14         20 my $js_class = shift;
42              
43 14         31 my $js_file = $self->_class_to_file($js_class);
44              
45 14         1109 my $last_mod = _last_mod($js_file);
46              
47 14 100 66     98 return if $self->{last_checked}{$js_class} && $last_mod <= $self->{last_checked}{$js_class};
48              
49 11         38 my @deps = JSAN::Parse::FileDeps->library_deps($js_file);
50              
51 11         89 $self->{dependencies}{$js_class} = [ @deps ];
52 11         32 $self->{last_checked}{$js_class} = time;
53              
54 11         46 $self->_record_dependencies($_) for @deps;
55             }
56              
57             # separate primarily so it can be mocked for tests
58 0     0   0 sub _last_mod { (stat $_[0])[9] }
59              
60             sub _class_to_file
61             {
62 28     28   8703 my $self = shift;
63              
64 28         62 $self->_class_to_path( shift )->path();
65             }
66              
67             sub _class_to_path
68             {
69 42     42   50 my $self = shift;
70 42         129 my $js_class = shift;
71              
72 42         124 my @pieces = split /\./, $js_class;
73 42         61 $pieces[-1] .= '.js';
74              
75 42         159 return $self->{location}->catfile(@pieces);
76             }
77              
78             sub uris
79             {
80 3     3 1 14 my $self = shift;
81              
82 3         11 return map { $self->_class_to_uri($_) } $self->_classes();
  11         582  
83             }
84              
85             sub files
86             {
87 3     3 1 2868 my $self = shift;
88              
89 3         9 return map { $self->_class_to_file($_) } $self->_classes();
  11         544  
90             }
91              
92             sub _classes
93             {
94 6     6   10 my $self = shift;
95              
96 6         9 my %seen;
97             my @classes;
98 6         9 for my $c ( @{ $self->{classes} } )
  6         15  
99             {
100 6         16 $self->_follow_deps( $c, \@classes, \%seen );
101             }
102              
103 6         23 return @classes;
104             }
105              
106             sub _follow_deps
107             {
108 28     28   38 my $self = shift;
109 28         31 my $c = shift;
110 28         32 my $classes = shift;
111 28         31 my $seen = shift;
112              
113 28 100       75 return if $seen->{$c};
114 22         36 $seen->{$c} = 1;
115              
116 22         28 for my $d ( @{ $self->{dependencies}{$c} } )
  22         51  
117             {
118 22         47 $self->_follow_deps( $d, $classes, $seen );
119             }
120              
121 22         79 push @$classes, $c;
122             }
123              
124             sub _class_to_uri
125             {
126 14     14   3890 my $self = shift;
127              
128 14         36 $self->_class_to_path( shift )->uri();
129             }
130              
131              
132             1;
133              
134             __END__