File Coverage

blib/lib/Test/CSS.pm
Criterion Covered Total %
statement 52 54 96.3
branch 10 16 62.5
condition 1 3 33.3
subroutine 10 10 100.0
pod 2 2 100.0
total 75 85 88.2


line stmt bran cond sub pod time code
1             package Test::CSS;
2              
3             $Test::CSS::VERSION = '0.07';
4             $Test::CSS::AUTHOR = 'cpan:MANWAR';
5              
6             =head1 NAME
7              
8             Test::CSS - Interface to test CSS string and file.
9              
10             =head1 VERSION
11              
12             Version 0.07
13              
14             =cut
15              
16 4     4   46191 use strict; use warnings;
  4     4   9  
  4         151  
  4         22  
  4         7  
  4         152  
17 4     4   96 use 5.0006;
  4         26  
18 4     4   3549 use JSON;
  4         75898  
  4         35  
19 4     4   4309 use File::Share ':all';
  4         48264  
  4         1198  
20 4     4   2668 use Test::Builder;
  4         26666  
  4         7831  
21              
22             require Exporter;
23             our @ISA = qw(Exporter);
24             our @EXPORT = qw(ok_css_string ok_css_file);
25              
26             our $TESTER = Test::Builder->new;
27             our $PROPERTIES = JSON->new->utf8(1)->decode(_read_file(dist_file('Test-CSS', 'properties.json')));
28              
29             =head1 DESCRIPTION
30              
31             The one and only feature of the package is to validate the CSS (string / file)
32             structurally. Additionally it checks if the property name is a valid as per the
33             CSS specifications.
34              
35             =head1 METHODS
36              
37             =head2 ok_css_string($css_string, $test_name)
38              
39             =cut
40              
41             sub ok_css_string($;$) {
42 2     2 1 3042 my ($input, $test_name) = @_;
43              
44 2         3 eval { _parse_css($input) };
  2         5  
45 2 100       6 if ($@) {
46 1         10 $TESTER->ok(0, $test_name);
47             }
48             else {
49 1         6 $TESTER->ok(1, $test_name);
50             }
51             }
52              
53             =head2 ok_css_file($css_file, $test_name)
54              
55             =cut
56              
57             sub ok_css_file($;$) {
58 1     1 1 2576 my ($file, $test_name) = @_;
59              
60 1         4 eval { _parse_css(_read_file($file)) };
  1         3  
61 1 50       16 if ($@) {
62 0         0 $TESTER->ok(0, $test_name);
63             }
64             else {
65 1         7 $TESTER->ok(1, $test_name);
66             }
67             }
68              
69             #
70             #
71             # PRIVATE METHODS
72              
73             sub _parse_css {
74 3     3   5 my ($css) = @_;
75              
76 3 50       7 if (defined $css) {
77 3         15 $css =~ s/\r\n|\r|\n/ /gs;
78 3         7 $css =~ s!/\*.*?\*\/!!g;
79              
80             # Split selectors
81 3         17 foreach ( grep { /\S/ } split /(?<=\})/, $css ) {
  3         14  
82 3 50       19 die "Invalid or unexpected selector data '$_'\n"
83             unless (/^\s*([^{]+?)\s*\{(.*)\}\s*$/);
84              
85 3         7 my $selector = $1;
86 3         6 my $properties = $2;
87 3         4 $selector =~ s/\s{2,}/ /g;
88              
89             # Split properties
90 3         6 foreach (grep { /\S/ } split /\;/, $properties) {
  3         9  
91             # skip browser specific properties
92 3 50 33     24 next if ((/^\s*[\*\-\_]/) || (/\\/));
93              
94             # check if properties are valid structurally
95 3 50       13 die "Invalid or unexpected property '$_' in style '$selector'\n"
96             unless (/^\s*([\w._-]+)\s*:\s*(.*?)\s*$/);
97              
98 3         10 my ($name) = split /\:/,$_;
99 3         16 $name =~ s/^\s+|\s+$//g;
100 3 100       21 (exists $PROPERTIES->{lc($name)})
101             || die "Found invalid property [$name] within selector [$selector].\n";
102             }
103             }
104             }
105             else {
106 0         0 die 'No stylesheet data was found in the document';
107             }
108             }
109              
110             sub _read_file {
111 5     5   1529 my ($file) = @_;
112              
113 5 50       279 open my $FILE, "<", $file or die $!;
114 5         45 my $css = do { local( $/ ) ; <$FILE> } ;
  5         27  
  5         168  
115 5         46 close $FILE;
116              
117 5         3460 return $css;
118             }
119              
120             =head1 BUGS
121              
122             None that I am aware of. Of course, if you find a bug, let me know, and I will be
123             sure to fix it. This is still a very early version, so it is always possible that
124             I have just "gotten it wrong" in some places.
125              
126             =head1 AUTHOR
127              
128             Mohammad S Anwar, C<< >>
129              
130             =head1 REPOSITORY
131              
132             L
133              
134             =head1 BUGS
135              
136             Please eport any bugs or feature requests to C, or
137             or through the web interface at L.
138             I will be notified, and then you'll automatically be notified of progress on your
139             bug as I make changes.
140              
141             =head1 SUPPORT
142              
143             You can find documentation for this module with the perldoc command.
144              
145             perldoc Test::CSS
146              
147             You can also look for information at:
148              
149             =over 4
150              
151             =item * RT: CPAN's request tracker (report bugs here)
152              
153             L
154              
155             =item * AnnoCPAN: Annotated CPAN documentation
156              
157             L
158              
159             =item * CPAN Ratings
160              
161             L
162              
163             =item * Search CPAN
164              
165             L
166              
167             =back
168              
169             =head1 LICENSE AND COPYRIGHT
170              
171             Copyright (C) 2014 - 2016 Mohammad S Anwar.
172              
173             This program is free software; you can redistribute it and/or modify it under
174             the terms of the the Artistic License (2.0). You may obtain a copy of the full
175             license at:
176              
177             L
178              
179             Any use, modification, and distribution of the Standard or Modified Versions is
180             governed by this Artistic License.By using, modifying or distributing the Package,
181             you accept this license. Do not use, modify, or distribute the Package, if you do
182             not accept this license.
183              
184             If your Modified Version has been derived from a Modified Version made by someone
185             other than you,you are nevertheless required to ensure that your Modified Version
186             complies with the requirements of this license.
187              
188             This license does not grant you the right to use any trademark, service mark,
189             tradename, or logo of the Copyright Holder.
190              
191             This license includes the non-exclusive, worldwide, free-of-charge patent license
192             to make, have made, use, offer to sell, sell, import and otherwise transfer the
193             Package with respect to any patent claims licensable by the Copyright Holder that
194             are necessarily infringed by the Package. If you institute patent litigation
195             (including a cross-claim or counterclaim) against any party alleging that the
196             Package constitutes direct or contributory patent infringement,then this Artistic
197             License to you shall terminate on the date that such litigation is filed.
198              
199             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND
200             CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
201             WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
202             NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS
203             REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT,
204             INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE
205             OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
206              
207             =cut
208              
209             1; # End of Test-CSS