File Coverage

blib/lib/Rex/Test/Spec.pm
Criterion Covered Total %
statement 41 50 82.0
branch 4 10 40.0
condition 1 3 33.3
subroutine 15 17 88.2
pod 0 2 0.0
total 61 82 74.3


line stmt bran cond sub pod time code
1             package Rex::Test::Spec;
2              
3 4     4   24570 use 5.006;
  4         11  
  4         144  
4 4     4   17 use strict;
  4         6  
  4         130  
5 4     4   14 use warnings FATAL => 'all';
  4         15  
  4         360  
6             my @EXPORT = qw(describe context its it);
7             my @testFuncs = qw(ok is isnt like unlike is_deeply);
8             my @typeFuncs = qw(cron file gateway group iptables
9             pkg port process routes run service sysctl user);
10             push @EXPORT, @testFuncs, @typeFuncs, 'done_testing';
11              
12             our ($obj, $msg);
13              
14 4     4   1172 use Test::More;
  4         28278  
  4         40  
15              
16             =head1 NAME
17              
18             Rex::Test::Spec - Write Rex::Test like RSpec!
19              
20             =head1 VERSION
21              
22             Version 0.06
23              
24             =cut
25              
26             our $VERSION = '0.06';
27              
28              
29             =head1 SYNOPSIS
30              
31             use Rex::Test::Spec;
32             describe "Nginx Test", sub {
33             context run("nginx -t"), "nginx.conf testing", sub {
34             like its('stdout'), qr/ok/;
35             };
36             context file("~/.ssh/id_rsa"), sub {
37             is its('ensure'), 'file';
38             is its('mode'), '0600';
39             like its('content'), qr/name\@email\.com/;
40             };
41             context file("/data"), sub {
42             is its('ensure'), 'directory';
43             is its('owner'), 'www';
44             is its('mounted_on'), '/dev/sdb1';
45             isnt its('writable');
46             };
47             context service("nginx"), sub {
48             is its('ensure'), 'running';
49             };
50             context pkg("nginx"), sub {
51             is its('ensure'), 'present';
52             is its('version'), '1.5.8';
53             };
54             context cron, sub {
55             like its('www'), 'logrotate';
56             };
57             context gateway, sub {
58             is it, '192.168.0.1';
59             };
60             context group('www'), sub {
61             ok its('ensure');
62             };
63             context iptables, sub {
64             };
65             context port(80), sub {
66             is its('bind'), '0.0.0.0';
67             is its('proto'), 'tcp';
68             is its('command'), 'nginx';
69             };
70             context process('nginx'), sub {
71             like its('command'), qr(nginx -c /etc/nginx.conf);
72             ok its('mem') > 1024;
73             };
74             context routes, sub {
75             is_deeply its(1), {
76             destination => $dest,
77             gateway => $gw,
78             genmask => $genmask,
79             flags => $flags,
80             mss => $mss,
81             irtt => $irtt,
82             iface => $iface,
83             };
84             };
85             context sysctl, sub {
86             is its('vm.swapiness'), 1;
87             };
88             context user('www'), sub {
89             ok its('ensure');
90             is its('home'), '/var/www/html';
91             is its('shell'), '/sbin/nologin';
92             is_deeply its('belong_to'), ['www', 'nogroup'];
93             };
94             };
95             done_testing;
96              
97             =head1 EXPORT FUNCTIONS
98              
99             =head2 Spec definition functions
100              
101             These are the functions you will use to define behaviors and run your specs:
102             I (and alias to I), I (alias to I).
103              
104             Normally suggest C<< describe "strings" >> and C<< context resource type object >>,
105             use C<< its(key) >> return value, C<< it >> return objects by default.
106              
107             =cut
108              
109             sub describe {
110 1     1 0 10 my $code = pop;
111 1         2 local $msg = '';
112 1         2 local $obj;
113 1 50 33     7 if ( defined $_[0] and ref($_[0]) =~ m/^Rex::Test::Spec::(\w+)$/ ) {
114 0         0 $msg .= sprintf "%s(%s)", $1, $_[0]->{name};
115 0         0 $obj = shift;
116             };
117 1 50       6 $msg .= join(' ', @_) if scalar @_;
118 1         3 $code->();
119             }
120              
121 4     4   1810 BEGIN { *context = \&describe }
122              
123             sub its {
124 0     0 0 0 return $obj->getvalue(@_);
125             }
126              
127 4     4   101 BEGIN { *it = \&its }
128              
129             =head2 Test::More export functions
130              
131             This now include I, I, I, I, I, I, I.
132             You'll use these to assert correct behavior.
133              
134             The resource type name will be automatic passed as testing message.
135              
136             =cut
137              
138             for my $func (@testFuncs) {
139 4     4   23 no strict 'refs';
  4         6  
  4         112  
140 4     4   16 no warnings;
  4         4  
  4         275  
141             *$func = sub {
142 0     0   0 Test::More->can($func)->(@_, $msg);
143             };
144             };
145              
146 4     4   2409 BEGIN { *done_testing = \&Test::More::done_testing }
147              
148             =head2 Rex resource type generation functions
149              
150             Now support I, I, I, I, I, I,
151             I, I, I, I, I, I, I.
152              
153             See L for more details.
154              
155             =cut
156              
157             sub AUTOLOAD {
158 1     1   13 my ($method) = our $AUTOLOAD =~ /^[\w:]+::(\w+)$/;
159 1 50       4 return if $method eq 'DESTROY';
160              
161 1     1   68 eval "use $AUTOLOAD";
  1         382  
  0            
  0            
162 1 50       77 die "Error loading $AUTOLOAD." if $@;
163 0         0 my @args = @_;
164 0 0       0 unshift @args, 'name' if scalar @args == 1;
165 0         0 return $AUTOLOAD->new(@args);
166             }
167              
168             sub import {
169 4     4   22 no strict 'refs';
  4         6  
  4         107  
170 4     4   14 no warnings;
  4         5  
  4         328  
171 3     3   20 for ( @EXPORT ) {
172 72         119 *{"main::$_"} = \&$_;
  72         1505  
173             }
174             }
175              
176             =head1 AUTHOR
177              
178             Rao Chenlin(chenryn), C<< >>
179              
180             =head1 SEE ALSO
181            
182             =over 4
183              
184             =item 1. Rspec
185              
186             L
187              
188             =item 2. Serverspec
189              
190             L
191              
192             =item 3. TDD (Test Driven Development)
193              
194             L
195              
196             =item 4. BDD (Behavior Driven Development)
197              
198             L
199              
200             =item 5. L
201              
202             =item 6. L
203              
204             =back
205              
206             =head1 BUGS
207              
208             Please report any bugs or feature requests to C, or through
209             the web interface at L. I will be notified, and then you'll
210             automatically be notified of progress on your bug as I make changes.
211              
212             Also accept pull requests and issue at L.
213              
214             =head1 LICENSE AND COPYRIGHT
215              
216             Copyright 2014 Rao Chenlin(chenryn).
217              
218             Licensed under the Apache License, Version 2.0 (the "License");
219             you may not use this file except in compliance with the License.
220             You may obtain a copy of the License at
221              
222             L
223              
224             Unless required by applicable law or agreed to in writing, software
225             distributed under the License is distributed on an "AS IS" BASIS,
226             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
227             See the License for the specific language governing permissions and
228             limitations under the License.
229              
230             =cut
231              
232             1; # End of Rex::Test::Spec