ali@5
|
1 |
bookloupe test framework
|
ali@5
|
2 |
========================
|
ali@0
|
3 |
|
ali@0
|
4 |
Running existing testcases
|
ali@0
|
5 |
--------------------------
|
ali@0
|
6 |
|
ali@5
|
7 |
The test harness (the program that runs a test) is called loupe-test. The
|
ali@5
|
8 |
various testcases are stored in multiple text files, typically with a .tst
|
ali@5
|
9 |
extension.
|
ali@0
|
10 |
|
ali@5
|
11 |
To run a testcase when all of bookloupe, loupe-test and the testcase file are
|
ali@0
|
12 |
in the current directory simply do something like:
|
ali@0
|
13 |
|
ali@5
|
14 |
% loupe-test missing-space.tst
|
ali@0
|
15 |
|
ali@0
|
16 |
from a command prompt. Under MS-Windows, this is called a command window and
|
ali@0
|
17 |
the prompt will normally look slightly different, eg.,
|
ali@0
|
18 |
|
ali@5
|
19 |
C:\DP> loupe-test missing-space.tst
|
ali@0
|
20 |
|
ali@0
|
21 |
To run all the tests in the current directory, do something like this:
|
ali@0
|
22 |
|
ali@5
|
23 |
% loupe-test *.tst
|
ali@0
|
24 |
|
ali@5
|
25 |
If bookloupe is not in the current directory or you want to run the testsuite
|
ali@5
|
26 |
against gutcheck (the program that bookloupe is based on), then you can set an
|
ali@5
|
27 |
environment variable (BOOKLOUPE) to point at it. For example, on MS-Windows
|
ali@5
|
28 |
you might do:
|
ali@0
|
29 |
|
ali@5
|
30 |
C:\DP> set BOOKLOUPE=C:\GUTCHECK\GUTCHECK.EXE
|
ali@5
|
31 |
C:\DP> loupe-test *.tst
|
ali@0
|
32 |
|
ali@0
|
33 |
Writing your own testcases
|
ali@0
|
34 |
--------------------------
|
ali@0
|
35 |
|
ali@0
|
36 |
Writing a new testcase is pretty painless. Most testcases follow this simple
|
ali@0
|
37 |
pattern:
|
ali@0
|
38 |
|
ali@0
|
39 |
┌──────────────────────────────────────────┐
|
ali@0
|
40 |
│**************** INPUT **************** │
|
ali@0
|
41 |
│"Look!John, over there!" │
|
ali@0
|
42 |
│**************** EXPECTED ****************│
|
ali@0
|
43 |
│ │
|
ali@0
|
44 |
│"Look!John, over there!" │
|
ali@0
|
45 |
│ Line 1 column 6 - Missing space? │
|
ali@0
|
46 |
└──────────────────────────────────────────┘
|
ali@0
|
47 |
|
ali@0
|
48 |
The sixteen asterisks in this example form what is known as the "flag". This
|
ali@0
|
49 |
flag must come before and after all tags (eg., INPUT and EXPECTED). In the
|
ali@5
|
50 |
unlikely event that you need sixteen asterisks at the start of a line of text,
|
ali@0
|
51 |
then simply choose a different flag and use it throughout the file (flags
|
ali@0
|
52 |
can be any sequence of ASCII characters except control codes and space).
|
ali@0
|
53 |
|
ali@5
|
54 |
Note that the header that bookloupe and gutcheck normally output is not
|
ali@5
|
55 |
included in the expected output. This avoids problems with not knowing
|
ali@5
|
56 |
beforehand the name of the file that bookloupe/gutcheck will be asked to
|
ali@5
|
57 |
look at (and saves typing!). bookloupe (and gutcheck) prints a blank line
|
ali@5
|
58 |
before each warning. These are not part of the header and so do need to
|
ali@5
|
59 |
be included.
|
ali@0
|
60 |
|
ali@5
|
61 |
To test that bookloupe produces no output, you still need to include
|
ali@0
|
62 |
an EXPECTED tag, just with no text following it. If there is no EXPECTED
|
ali@5
|
63 |
tag, then loupe-test will consider that no expectation exists and won't
|
ali@5
|
64 |
check the output at all.
|
ali@0
|
65 |
|
ali@10
|
66 |
Non-ASCII testcases
|
ali@10
|
67 |
-------------------
|
ali@10
|
68 |
|
ali@10
|
69 |
The testcase definitions (the .tst files) are always written in UTF-8
|
ali@10
|
70 |
which is a superset of ASCII. Since gutcheck does not understand UTF-8
|
ali@10
|
71 |
this causes a problem when it is desired to include characters that
|
ali@10
|
72 |
are not in ASCII in a testcase. To solve this problem it is possible
|
ali@10
|
73 |
to specify an encoding to use for the test. It is very important to
|
ali@10
|
74 |
undertand that this specifies the encoding that loupe-test will use to
|
ali@10
|
75 |
talk to bookloupe/gutcheck and _not_ the encoding of the .tst file
|
ali@10
|
76 |
(which remains UTF-8). gutcheck understands Latin-1 (at least to a
|
ali@10
|
77 |
limited extent), the canonical name for which is ISO-8859-1:
|
ali@10
|
78 |
|
ali@10
|
79 |
┌─────────────────────────────────────────────────────────────────┐
|
ali@10
|
80 |
│**************** ENCODING **************** │
|
ali@10
|
81 |
│ISO-8859-1 │
|
ali@10
|
82 |
│**************** INPUT **************** │
|
ali@10
|
83 |
│"Hello," he said, "I wanted to bave a tête-à-tête with you." │
|
ali@10
|
84 |
│**************** EXPECTED **************** │
|
ali@10
|
85 |
│ │
|
ali@10
|
86 |
│"Hello," he said, "I wanted to bave a tête-à-tête with you." │
|
ali@10
|
87 |
│ Line 1 column 31 - Query word bave - not reporting duplicates│
|
ali@10
|
88 |
└─────────────────────────────────────────────────────────────────┘
|
ali@10
|
89 |
|
ali@10
|
90 |
Embedded linefeeds
|
ali@10
|
91 |
------------------
|
ali@10
|
92 |
|
ali@10
|
93 |
One of the tests that bookloupe/gutcheck need to do is check that all
|
ali@101
|
94 |
lines are ended with CR LF (as required by PG) rather than the UNIX
|
ali@101
|
95 |
standard LF. loupe-test deliberately ignores the line endings in testcase
|
ali@101
|
96 |
definition files and uses the expected CR LF. Thus there is needed a means
|
ali@10
|
97 |
to embed a linefeed (aka newline) character into the input to be sent
|
ali@10
|
98 |
to bookloupe/gutcheck to test that it correctly identified the problem.
|
ali@10
|
99 |
loupe-test recognises the unicode symbol for linefeed (U+240A): ␊ which
|
ali@10
|
100 |
can be used for this purpose instead of a normal newline.
|
ali@10
|
101 |
|
ali@101
|
102 |
UNIX-style newlines
|
ali@101
|
103 |
-------------------
|
ali@101
|
104 |
|
ali@101
|
105 |
To make life easier for users on UNIX and similar platforms, bookloupe
|
ali@101
|
106 |
recognises the case of all lines terminated with UNIX-style newlines.
|
ali@101
|
107 |
It notes this in the summary but does not issue any warnings. We thus
|
ali@101
|
108 |
need some way to test this case which we do by the NEWLINES tag:
|
ali@101
|
109 |
|
ali@101
|
110 |
┌──────────────────────────────────────────────────────────────────────────┐
|
ali@101
|
111 |
│**************** NEWLINES **************** │
|
ali@101
|
112 |
│LF │
|
ali@101
|
113 |
│**************** INPUT **************** │
|
ali@101
|
114 |
│Katherine was assailed by a sudden doubt. Had she mailed that letter? Yes,│
|
ali@101
|
115 |
│she was certain of that. She had run out to the mail box at ten o'clock │
|
ali@101
|
116 |
│at night especially to mail it. What had gone wrong? Why wasn't there │
|
ali@101
|
117 |
│someone to meet her? │
|
ali@101
|
118 |
└──────────────────────────────────────────────────────────────────────────┘
|
ali@101
|
119 |
|
ali@101
|
120 |
The possible options are CRLF for DOS-style newlines (the default) and
|
ali@101
|
121 |
LF for UNIX-style newlines.
|
ali@101
|
122 |
|
ali@10
|
123 |
Passing command line options
|
ali@10
|
124 |
----------------------------
|
ali@10
|
125 |
|
ali@10
|
126 |
Some of bookloupe's functionality is only available using command line
|
ali@10
|
127 |
options. loupe-test provides a means of specifying these with the
|
ali@10
|
128 |
OPTIONS tag:
|
ali@10
|
129 |
|
ali@10
|
130 |
┌──────────────────────────────────────────┐
|
ali@10
|
131 |
│**************** OPTIONS **************** │
|
ali@10
|
132 |
│-m │
|
ali@10
|
133 |
│-d │
|
ali@10
|
134 |
│**************** INPUT **************** │
|
ali@10
|
135 |
│“He went <i>thataway!</i>” │
|
ali@10
|
136 |
│**************** EXPECTED ****************│
|
ali@10
|
137 |
└──────────────────────────────────────────┘
|
ali@10
|
138 |
|
ali@10
|
139 |
Extra input files
|
ali@10
|
140 |
-----------------
|
ali@10
|
141 |
|
ali@10
|
142 |
Under certain circumstances, bookloupe reads other input files than just
|
ali@10
|
143 |
the ebook. These can be specified in the testcase definition file by
|
ali@10
|
144 |
adding the name of the file to the INPUT tag:
|
ali@10
|
145 |
|
ali@10
|
146 |
┌───────────────────────────────────────────────────────────────┐
|
ali@10
|
147 |
│**************** OPTIONS **************** │
|
ali@10
|
148 |
│-u │
|
ali@10
|
149 |
│**************** INPUT(gutcheck.typ) **************** │
|
ali@10
|
150 |
│arid │
|
ali@10
|
151 |
│**************** INPUT **************** │
|
ali@10
|
152 |
│I am the very model of a modern Major-General, │
|
ali@10
|
153 |
│I've information vegetable, animal, and mineral, │
|
ali@10
|
154 |
│I know the kings of England, arid I quote the fights historical│
|
ali@10
|
155 |
│From Marathon to Waterloo, in order categorical; │
|
ali@10
|
156 |
│I'm very well acquainted, too, with matters mathematical, │
|
ali@10
|
157 |
│I understand equations, both the simple and quadratical, │
|
ali@10
|
158 |
│About binomial theorem I'm teeming with a lot o' news-- │
|
ali@10
|
159 |
│With many cheerful facts about the square of the hypotenuse. │
|
ali@10
|
160 |
│**************** EXPECTED **************** │
|
ali@10
|
161 |
│ │
|
ali@10
|
162 |
│I know the kings of England, arid I quote the fights historical│
|
ali@10
|
163 |
│ Line 3 column 29 - Query possible scanno arid │
|
ali@10
|
164 |
└───────────────────────────────────────────────────────────────┘
|
ali@10
|
165 |
|
ali@19
|
166 |
False-positives
|
ali@19
|
167 |
---------------
|
ali@10
|
168 |
|
ali@19
|
169 |
Most of the time, the input can be tweaked so that all warnings bookloupe
|
ali@19
|
170 |
reports represent real errors in the text. Sometimes, however, this either
|
ali@19
|
171 |
cannot be done and still test what we need to. In these cases we need a
|
ali@19
|
172 |
means to describe these false-positives (warnings that do not describe
|
ali@19
|
173 |
a real error). This is important so that a later version of bookloupe can
|
ali@19
|
174 |
be improved to not issue the false-positive warning and still pass the
|
ali@19
|
175 |
test. In order to do this, we need to describe the warnings in a more
|
ali@19
|
176 |
structures manner, like this:
|
ali@19
|
177 |
|
ali@19
|
178 |
┌───────────────────────────────────────────────────────────────┐
|
ali@19
|
179 |
│**************** OPTIONS **************** │
|
ali@19
|
180 |
│-s │
|
ali@19
|
181 |
│**************** INPUT **************** │
|
ali@19
|
182 |
│'In a moment,' Peter replied,' I'm just coming.' │
|
ali@19
|
183 |
│ │
|
ali@19
|
184 |
│'Underneath the girls' scarves. │
|
ali@19
|
185 |
│ │
|
ali@19
|
186 |
│**************** WARNINGS **************** │
|
ali@19
|
187 |
│<expected> │
|
ali@19
|
188 |
│ <error> │
|
ali@19
|
189 |
│ <at line="1" column="30"/> │
|
ali@19
|
190 |
│ <text>Wrongspaced singlequotes?</text> │
|
ali@19
|
191 |
│ </error> │
|
ali@19
|
192 |
│ <false-positive> │
|
ali@19
|
193 |
│ <at line="2"/> │
|
ali@19
|
194 |
│ <text>Mismatched singlequotes?</text> │
|
ali@19
|
195 |
│ </false-positive> │
|
ali@19
|
196 |
│ <false-negative> │
|
ali@19
|
197 |
│ <at line="3" column="1"/> │
|
ali@19
|
198 |
│ <at line="4"/> │
|
ali@19
|
199 |
│ <text>Mismatched singlequotes?</text> │
|
ali@19
|
200 |
│ </false-negative> │
|
ali@19
|
201 |
│</expected> │
|
ali@19
|
202 |
└───────────────────────────────────────────────────────────────┘
|
ali@19
|
203 |
|
ali@19
|
204 |
Here, we use the "WARNINGS" tag instead of "EXPECTED" to denote that we
|
ali@19
|
205 |
wish to use structured warnings and the list of warnings is enclosed in
|
ali@19
|
206 |
an <expected> ... </expected> node.
|
ali@19
|
207 |
|
ali@19
|
208 |
Each warning, or potential warnings is then described using either an
|
ali@19
|
209 |
"error" node (for warnings that represent real errors in the text), a
|
ali@19
|
210 |
"false-positive" node (for warnings that do not represent real errors),
|
ali@19
|
211 |
or a "false-negative" node (for warnings that should be issued, but that
|
ali@19
|
212 |
are not yet detected by bookloupe).
|
ali@19
|
213 |
|
ali@19
|
214 |
Within each warning node, there are then one or more "at" nodes which
|
ali@19
|
215 |
list the acceptable locations for the warning to be reported at (the
|
ali@19
|
216 |
first listed should be the preferred location) and exactly one "text"
|
ali@19
|
217 |
node which must match the text of the warning issued.
|
ali@19
|
218 |
|
ali@19
|
219 |
A testcase will pass if all the warnings marked as errors were issued and
|
ali@19
|
220 |
if no warnings were issued that are not listed in one form or another.
|
ali@19
|
221 |
If the testcase passes with an expected failure (ie., issues a warning
|
ali@19
|
222 |
for a false positive or does not issue a warning for a false negative),
|
ali@19
|
223 |
then the test is counted as passed, but a note will be printed describing
|
ali@19
|
224 |
this, eg.:
|
ali@19
|
225 |
|
ali@19
|
226 |
sample: PASS (with 1 of 1 false positives and 1 of 1 false negatives)
|
ali@101
|
227 |
|
ali@101
|
228 |
The summary
|
ali@101
|
229 |
-----------
|
ali@101
|
230 |
|
ali@101
|
231 |
As part of the header (the first section of output), bookloupe may display
|
ali@101
|
232 |
a number of summary lines. These are characterized by a leading ASCII
|
ali@101
|
233 |
long arrow (-->) and generally say something about the ebook as a whole
|
ali@101
|
234 |
rather than individual lines. Where it is desired to test for the presence
|
ali@101
|
235 |
of a summary line, a "summary" node can be included within the "expected"
|
ali@101
|
236 |
node of a testcase using structured warnings. The "summary" node can contain
|
ali@101
|
237 |
one or more "text" nodes which indicate the text of lines that must be
|
ali@101
|
238 |
present in the summary section in order for the test to pass. No account is
|
ali@101
|
239 |
taken of the order of such lines and other summary lines may also be present.
|