File Coverage

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