2 # Copyright (C) 2006, The Perl Foundation.
7 t/op/sprintf.t -- sprintf tests
11 These tests are based on sprintf tests from perl 5.9.4.
13 Tests sprintf, excluding handling of 64-bit integers or long
14 doubles (if supported), of machine-specific short and long
15 integers, machine-specific floating point exceptions (infinity,
16 not-a-number ...), of the effects of locale, and of features
17 specific to multi-byte characters (under the utf8 pragma and such).
19 Individual tests are stored in the C<sprintf_tests> file in the same
20 directory; There is one test per line. In each test, there are three
27 =item data to be formatted (as a parrot expression)
29 =item expected result of formatting
33 Optional fields contain
41 Each field is separated by one or more tabs. If formatting requires more than
42 one data item (for example, if variable field widths are used), the Parrot
43 data expression should return a reference to an array having the requisite
44 number of elements. Even so, subterfuge is sometimes required:
45 see tests for %n and %p.
48 Tests that are expected to fail on a certain OS can be marked as such
49 by trailing the comment with a skip: section. Skips are tags separated
50 by space consisting of a $^O optionally trailed with :osvers. In the
51 latter case, all os-levels below that are expected to fail. A special
52 tag 'all' is allowed for todo tests that should fail on any system
54 >%GE<gt> >1234567e96< >1.23457E+102< >exponent too big skip: os390<
55 >%.0g< >-0.0< >-0< >No minus skip: MSWin32 VMS hpux:10.20<
56 >%d< >4< >1< >4 != 1 skip: all<
60 % prove t/op/sprintf.t
65 .const int TESTS = 308
68 load_bytecode 'Test/Builder.pir'
69 load_bytecode 'PGE.pbc'
70 load_bytecode 'PGE/Dumper.pbc'
71 .include "iglobals.pasm"
73 # Variable declarations, initializations
74 .local pmc test # the test harness object.
75 test = new 'Test::Builder'
77 .local pmc todo_tests # keys indicate test file; values test number.
78 todo_tests = new 'Hash'
80 .local pmc skip_tests # keys indicate tests ID; values reasons.
81 skip_tests = new 'Hash'
83 .local string test_dir # the directory containing tests
86 .local pmc test_files # values are test file names to run.
87 test_files = new 'ResizablePMCArray'
89 # populate the list of test files
90 push test_files, 'sprintf_tests'
93 .local pmc file_iterator # iterate over list of files..
94 file_iterator = new 'Iterator', test_files
96 .local int test_number # the number of the test we're running
99 # these vars are in the loops below
100 .local string test_line # one line of one test file, a single test
101 .local int ok # is this a passing test?
103 # for any given test:
104 .local string template # the sprintf template
105 .local string data # the data to format with the template
106 .local string expected # expected result of this test
107 .local string description # user-facing description of the test
108 .local string actual # actual result of the test
110 todo_tests = 'set_todo_info'()
111 skip_tests = 'set_skip_info'()
113 # how many tests to run?
114 # XXX: this should be summed automatically from test_files data
115 # until then, it's set to no plan
119 unless file_iterator goto end_outer_loop
120 .local string test_name # file name of the current test file
121 test_name = shift file_iterator
123 .local string test_file # full name of the current test file
124 test_file = test_dir . test_name
126 .local int local_test_number # local test number in test file
127 local_test_number = 0
130 .local pmc file_handle # currently open file
131 file_handle = open test_file, '<'
133 unless file_handle goto bad_file
135 # loop over the file, one at a time.
138 # read in the file one line at a time...
139 $I0 = file_handle.'eof'()
142 test_line = readline file_handle
144 # skip lines without tabs, and comment lines
145 $I0 = index test_line, "\t"
146 if $I0 == -1 goto loop
147 $I0 = index test_line, '#'
148 if $I0 == 0 goto loop
150 inc local_test_number
154 ( template, data, expected, description ) = parse_data( test_line )
157 # prepend test filename and line number to description
158 description = 'build_test_desc'( description, template )
161 data_hash = new .Hash
163 data_hash['2**32-1'] = 0xffffffff
165 data_hash['2**38'] = $N0
166 data_hash["'string'"] = 'string'
168 $I0 = exists data_hash[data]
169 unless $I0 goto got_data
170 data = data_hash[data]
173 # data = backslash_escape (data)
174 # expected = backslash_escape (expected)
176 # Should this test be skipped?
177 $I0 = exists skip_tests[test_name]
178 unless $I0 goto not_skip
179 $P0 = skip_tests[test_name]
180 $I0 = exists $P0[local_test_number]
181 unless $I0 goto not_skip
182 $S0 = $P0[local_test_number]
188 actual = 'sprintf'(template, data)
190 unless_null actual, sprintf_ok
191 $P1 = new 'Exception'
192 $P1[0] = 'sprintf error'
196 if expected == actual goto is_ok
197 description .= ' actual: >'
198 description .= actual
203 $S0 = substr expected, 0, 1
204 if $S0 != "/" goto eh_bad_line
205 substr expected, 0, 1, ''
206 substr expected, -1, 1, ''
208 $I0 = index $S1, expected
209 if $I0 == -1 goto is_nok
219 $I0 = exists todo_tests[test_name]
220 unless $I0 goto not_todo
221 $P0 = todo_tests[test_name]
222 $I0 = exists $P0[local_test_number]
223 unless $I0 goto not_todo
224 test.'todo'(ok,description)
227 test.'ok'(ok,description)
239 print "Unable to open '"
246 get_results '(0,0)', exception, message
247 $I0 = index message, 'is not a valid sprintf format'
248 if $I0 == -1 goto other_error
249 $I0 = index expected, ' INVALID'
250 if $I0 == -1 goto bad_error
258 $S0 = "Test not formatted properly!"
266 .param pmc args :slurpy
269 $S1 = sprintf $S0, args
275 # set todo information
277 .local pmc todo_tests # keys indicate test file; values test number
278 todo_tests = new 'Hash'
281 todo_info = new 'Hash'
283 .local string test_file
286 test_file = 'sprintf_tests'
288 todo_info[64] = 'undecided perl5 vs. posix behavior'
289 todo_info[153] = '%hf should be rejected'
290 todo_info[187] = '%h alone is invalid'
291 todo_info[191] = '%l alone is invalid'
292 todo_info[223] = '%v alone is invalid, but a valid parrot extension'
293 todo_info[304] = 'undecided'
294 todo_info[305] = 'undecided'
295 todo_info[306] = 'undecided'
298 todo_tests[test_file] = todo_info
303 todo_info = new .Hash
307 if $I0 > $I1 goto end_loop
316 # set skip information
318 .local pmc skip_tests # keys indicate test file; values test number
319 skip_tests = new 'Hash'
322 skip_info = new 'Hash'
324 .local string test_file
327 test_file = 'sprintf_tests'
328 skip_info[5] = 'parrot extension (%B)'
329 skip_info[7] = 'perl5-specific extension (%D)'
330 skip_info[9] = 'perl5-specific extension (%F)'
331 skip_info[16] = 'parrot extension (%H)'
332 skip_info[20] = 'parrot extension (%L)'
333 skip_info[23] = 'perl5-specific extension (%O)'
334 skip_info[24] = 'parrot extension (%P)'
335 skip_info[27] = 'parrot extension (%S)'
336 skip_info[29] = 'perl5-specific extension (%U)'
338 $S0 = 'perl5-specific extension (%v...)'
343 skip_info[114] = 'harness needs support for * modifier'
344 skip_info[144] = 'perl5 expresssion as test value'
345 skip_info[131] = 'harness needs support for * modifier'
346 skip_info[141] = 'harness needs support for * modifier'
347 skip_info[161] = 'harness needs support for * modifier'
348 skip_info[166] = 'harness needs support for * modifier'
349 skip_info[193] = 'perl5-specific test'
350 skip_info[200] = 'perl5-specific test'
351 skip_info[201] = 'perl5-specific test'
352 skip_info[202] = 'parrot extension (%p)'
353 skip_info[204] = 'parrot extension (%r)'
354 skip_info[210] = 'harness needs support for * modifier'
355 skip_info[214] = 'harness needs support for * modifier'
356 skip_info[233] = 'harness needs support for * modifier'
357 skip_info[234] = 'perl5-specific extension (%v...)'
358 skip_info[235] = 'perl5-specific extension (%v...)'
360 $S0 = 'perl5-specific test'
365 $S0 = 'perl5-specific extension (%v...)'
370 skip_info[307] = 'perl5-specific extension (%v...)'
371 skip_info[308] = 'perl5-specific extension (%v...)'
373 skip_tests[test_file] = skip_info
378 skip_info = new .Hash
382 if $I0 > $I1 goto end_loop
383 if $S0 != '' goto set_skip_info
384 $S0 = 'unknown reason'
396 .param string record # the data record
398 .local string template # the sprintf template
399 .local string data # the data to format with the template
400 .local string expected # expected result of this test
401 .local string description # user-facing description of the test
403 # NOTE: there can be multiple tabs between entries, so skip until
405 # remove the trailing newline from record
407 $P1 = split "\t", record
408 $I0 = elements $P1 # length of array
409 .local int tab_number
412 if tab_number >= $I0 goto bad_line
413 template = $P1[tab_number]
415 if template == '' goto get_template
417 if tab_number >= $I0 goto bad_line
418 data = $P1[tab_number]
420 if data == '' goto get_data
423 if tab_number >= $I0 goto empty_expected
424 expected = $P1[tab_number]
426 if expected == '' goto get_expected
427 ## FIXME: description handling
429 if tab_number >= $I0 goto no_desc
430 description = $P1[tab_number]
432 if description == '' goto get_description
435 # substr description, -1, 1, ''
439 .return ( template, data, expected, description )
446 $P1 = new 'Exception'
447 $P1[0] = 'invalid data format'
452 .sub 'build_test_desc'
454 .param string testname
460 desc = concat $S0, desc
466 # The following tests are not currently run, for the reasons stated:
472 >%.0f< >1.5< >2< >Standard vague: no rounding rules<
473 >%.0f< >2.5< >2< >Standard vague: no rounding rules<
479 # vim: sw=4 expandtab