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.09';
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.09
13              
14             =cut
15              
16 4     4   111220 use strict; use warnings;
  4     4   24  
  4         89  
  4         16  
  4         6  
  4         101  
17 4     4   65 use 5.0006;
  4         10  
18 4     4   2146 use JSON;
  4         41504  
  4         17  
19 4     4   1843 use File::Share ':all';
  4         92598  
  4         547  
20 4     4   1185 use Test::Builder;
  4         96648  
  4         2848  
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 2681 my ($input, $test_name) = @_;
43              
44 2         3 eval { _parse_css($input) };
  2         5  
45 2 100       3 if ($@) {
46 1         7 $TESTER->ok(0, $test_name);
47             }
48             else {
49 1         5 $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 2190 my ($file, $test_name) = @_;
59              
60 1         1 eval { _parse_css(_read_file($file)) };
  1         3  
61 1 50       4 if ($@) {
62 0         0 $TESTER->ok(0, $test_name);
63             }
64             else {
65 1         5 $TESTER->ok(1, $test_name);
66             }
67             }
68              
69             #
70             #
71             # PRIVATE METHODS
72              
73             sub _parse_css {
74 3     3   6 my ($css) = @_;
75              
76 3 50       15 if (defined $css) {
77 3         21 $css =~ s/\r\n|\r|\n/ /gs;
78 3         4 $css =~ s!/\*.*?\*\/!!g;
79              
80             # Split selectors
81 3         18 foreach ( grep { /\S/ } split /(?<=\})/, $css ) {
  3         11  
82 3 50       17 die "Invalid or unexpected selector data '$_'\n"
83             unless (/^\s*([^{]+?)\s*\{(.*)\}\s*$/);
84              
85 3         6 my $selector = $1;
86 3         5 my $properties = $2;
87 3         4 $selector =~ s/\s{2,}/ /g;
88              
89             # Split properties
90 3         6 foreach (grep { /\S/ } split /\;/, $properties) {
  3         8  
91             # skip browser specific properties
92 3 50 33     15 next if ((/^\s*[\*\-\_]/) || (/\\/));
93              
94             # check if properties are valid structurally
95 3 50       12 die "Invalid or unexpected property '$_' in style '$selector'\n"
96             unless (/^\s*([\w._-]+)\s*:\s*(.*?)\s*$/);
97              
98 3         7 my ($name) = split /\:/,$_;
99 3         12 $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   703 my ($file) = @_;
112              
113 5 50       216 open my $FILE, "<", $file or die $!;
114 5         20 my $css = do { local( $/ ) ; <$FILE> } ;
  5         22  
  5         217  
115 5         56 close $FILE;
116              
117 5         1609 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 report 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             =head1 LICENSE AND COPYRIGHT
148              
149             Copyright (C) 2014 - 2017 Mohammad S Anwar.
150              
151             This program is free software; you can redistribute it and/or modify it under
152             the terms of the the Artistic License (2.0). You may obtain a copy of the full
153             license at:
154              
155             L
156              
157             Any use, modification, and distribution of the Standard or Modified Versions is
158             governed by this Artistic License.By using, modifying or distributing the Package,
159             you accept this license. Do not use, modify, or distribute the Package, if you do
160             not accept this license.
161              
162             If your Modified Version has been derived from a Modified Version made by someone
163             other than you,you are nevertheless required to ensure that your Modified Version
164             complies with the requirements of this license.
165              
166             This license does not grant you the right to use any trademark, service mark,
167             tradename, or logo of the Copyright Holder.
168              
169             This license includes the non-exclusive, worldwide, free-of-charge patent license
170             to make, have made, use, offer to sell, sell, import and otherwise transfer the
171             Package with respect to any patent claims licensable by the Copyright Holder that
172             are necessarily infringed by the Package. If you institute patent litigation
173             (including a cross-claim or counterclaim) against any party alleging that the
174             Package constitutes direct or contributory patent infringement,then this Artistic
175             License to you shall terminate on the date that such litigation is filed.
176              
177             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND
178             CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
179             WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
180             NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS
181             REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT,
182             INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE
183             OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
184              
185             =cut
186              
187             1; # End of Test-CSS