File Coverage

blib/lib/Test/Smart/Question.pm
Criterion Covered Total %
statement 39 39 100.0
branch 13 16 81.2
condition 1 3 33.3
subroutine 10 10 100.0
pod 7 7 100.0
total 70 75 93.3


line stmt bran cond sub pod time code
1             package Test::Smart::Question;
2              
3 5     5   84219 use strict;
  5         10  
  5         170  
4 5     5   23 use warnings;
  5         9  
  5         120  
5 5     5   26 use Carp;
  5         9  
  5         3296  
6              
7             =head1 NAME
8              
9             Test::Smart::Question - Data wrapper for Test::Smart questions
10              
11             =head1 DESCRIPTION
12              
13             This object provides basic semantics and data encapsulation for Test::Smart
14             questions, feel free to subclass it as you need when writing Interfaces.
15              
16             =head1 SYNOPSIS
17              
18             use Test::Smart::Question;
19              
20             $Qobj = Test::Smart::Question->new(question => "I can has cheesburger?",
21             name => "Cheesburger",
22             id => "Uniq123");
23              
24             $Qobj->skip("The person being asked doesn't know how to answer");
25             $Qobj->test;
26              
27             $Qobj->answer('yes','commentary or diagnostics');
28             ($answer,$comment) = $Qobj->answer;
29             $answer = $Qobj->answer;
30              
31             =head1 DETAILS
32              
33             =head2 new(question => $question_text,id => $uniq_id, [name => $test_name,skip => $reason,other_key => $other_value])
34              
35             The constructor takes its params as a hash, requiring question and id and
36             optionally taking name and skip. If skip is set it is equivalent to calling
37             C<< $Qobj->skip("Reason") >> with all of the semantic implications (you can no
38             longer provide an answer unless you explicitly call C<< $Qobj->test >>).
39              
40             Test::Smart::Question also stores any other keys given to it in the blessed
41             hashref for the convinence of any Interface implementer who doesn't need a full
42             subclass. These should probably be treated as private unless documented
43             otherwise in the Interface's documentation.
44              
45             =cut
46              
47             sub new {
48 15     15 1 41 my $class = shift;
49 15         68 my %args = @_;
50            
51 15         32 my $self = {};
52 15         47 $self->{_id} = $args{id};
53 15         51 $self->{_question} = $args{question};
54              
55 15 50 33     133 die "Test::Smart::Question requires a question and an id in the constructor"
56             unless defined $self->{_id} and $self->{_question};
57              
58 15         61 $self->{_name} = $args{name};
59 15         30 $self->{_skip} = $args{skip};
60 15         51 foreach my $key (grep { $_ !~ /question|name|id/ } keys %args) {
  48         252  
61 4         17 $self->{$key} = $args{$key};
62             }
63 15         180 bless $self,$class;
64             }
65              
66             =head2 question
67              
68             This is a read only accessor for the question string provided at object
69             construction. If you try to set question it simply ignores the pass.
70              
71             =cut
72              
73             sub question {
74 3     3 1 781 my $self = shift;
75 3         19 return $self->{_question};
76             }
77              
78             =head2 id
79              
80             Like C but for the constructor set ID.
81              
82             =cut
83              
84             sub id {
85 43     43 1 58 my $self = shift;
86 43         127 return $self->{_id};
87             }
88              
89             =head2 name([$new_name])
90              
91             Mutator for the stored test name. This value is used when answering the
92             question for TAP output in the same way as the second parameter to C
93              
94             =cut
95              
96             sub name {
97 8     8 1 16 my ($self,$name) = @_;
98 8 100       23 $self->{_name} = $name if defined($name);
99 8         29 return $self->{_name};
100             }
101              
102             =head2 skip([$reason])
103              
104             Sets the internal skip value. Once set it cannot be undefed unless you use
105             C<< $Qobj->test >> to indicate you do indeed want to test with this Question.
106             While a skip reason is set the object will silently reject answers submitted to
107             it.
108              
109             =cut
110              
111             sub skip {
112 26     26 1 407 my ($self,$reason) = @_;
113 26 100       87 $self->{_skip} = $reason if defined($reason);
114 26         129 return $self->{_skip};
115             }
116              
117             =head2 test
118              
119             Indicate to the object that you're going to test it, which means it should
120             accept an answer and clear skip.
121              
122             =cut
123              
124             sub test {
125 2     2 1 5 my $self = shift;
126 2         6 $self->{_skip} = undef;
127             }
128              
129             =head2 answer([$answer, $comment])
130              
131             Mutator for the object's stored answer. When setting it the first parameter
132             must match C and should reflect the answer provided by the person.
133             If diagnostics or commentary is required it is provided in the $comment param,
134             though this is optional.
135              
136             If there is currently a reason for skipping set (either through skip or in the
137             constructor) then answer will simply return undef and do nothing. You also
138             cannot retrieve the answer if skip gets set.
139              
140             =cut
141              
142             sub answer {
143 27     27 1 500 my ($self,$answer,$comment) = @_;
144              
145 27 100       155 return undef if defined($self->{_skip});
146 24 100       114 return wantarray ? ($self->{_answer},$self->{_comment}) : $self->{_answer} unless defined($answer);
    100          
147 13 50       96 croak "Answer must be yes or no, not [$answer]" unless $answer =~ /yes|no/i;
148              
149 13         61 ($self->{_answer},$self->{_comment}) = ($answer,$comment);
150 13 50       72 return wantarray ? ($self->{_answer},$self->{_comment}) : $self->{_answer};
151             }
152              
153             =head1 SUBCLASSING
154              
155             If you want to make a custom interface for Test::Smart look at
156             L. If you do find the need to write something so
157             fancy that you must also subclass this, make sure your subclass is a perfect
158             drop-in replacement or else you'll break Test::Smart itsself.
159              
160             =head1 SEE ALSO
161              
162             L, L
163              
164             =head1 AUTHOR
165              
166             Edgar A. Bering, Etrizor@gmail.comE
167              
168             =head1 COPYRIGHT AND LICENSE
169              
170             Copyright (C) 2007 by Edgar A. Bering
171              
172             This library is free software; you can redistribute it and/or modify
173             it under the same terms as Perl itself, either Perl version 5.8.8 or,
174             at your option, any later version of Perl 5 you may have available.
175              
176             =cut
177             1;