xref: /PHP-8.3/ext/spl/tests/bug55701.phpt (revision b6207338)
1--TEST--
2Bug #55701 (GlobIterator throws LogicException with message 'The parent constructor was not called')
3--FILE--
4<?php
5
6//
7// Some methods of GlobIterator do not throw a RuntimeException when the glob pattern doesn't match any file.
8// Most methods of GlobIterator throw a RuntimeException when the glob pattern doesn't match any file
9// because they get the properties of the current file
10function testBaseClass($f) {
11    // The tested iterator is in an invalid state; the behaviour of most of its methods is undefined
12    try {
13        $f();
14        echo "ran normally (expected)\n";
15    } catch (RuntimeException $e) {
16        // Throwing a RuntimeException is the correct behaviour for some methods
17        echo "ran normally (expected)\n";
18    } catch (\Error $e) {
19        // Throwing a LogicException is not correct
20        echo "threw LogicException (unexpected)\n";
21    }
22}
23
24//
25// The derived classes must throw LogicException if the parent class constructor was not called
26function testChildClass($f) {
27    try {
28        $f();
29        echo "didn't throw (unexpected)\n";
30    } catch (\Error $e) {
31        echo "threw Error (expected)\n";
32    } catch (Exception $e) {
33        echo "threw other exception (unexpected)\n";
34    }
35}
36
37
38
39//
40// It must not throw LogicException when the iterator is not valid
41echo "->count()... ";
42testBaseClass( function() {
43    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
44    $o->count();
45} );
46
47echo "->rewind()... ";
48testBaseClass( function() {
49    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
50    $o->rewind();
51} );
52
53echo "->getFlags()... ";
54testBaseClass( function() {
55    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
56    $o->getFlags();
57} );
58
59echo "->setFlags()... ";
60testBaseClass( function() {
61    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
62    $o->setFlags(FilesystemIterator::KEY_AS_PATHNAME);
63} );
64
65echo "->valid()... ";
66testBaseClass( function() {
67    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
68    $o->valid();
69} );
70
71
72
73//
74// When the iterator is not valid, the behaviour of the next methods is undefined
75// Some of them throw a RuntimeException while others just return an invalid value
76// However, they must not throw LogicException
77echo "->current()... ";
78testBaseClass( function() {
79    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
80    $o->current();
81} );
82
83echo "->key()... ";
84testBaseClass( function() {
85    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
86    $o->key();
87} );
88
89echo "->next()... ";
90testBaseClass( function() {
91    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
92    $o->next();
93} );
94
95echo "->getATime()... ";
96testBaseClass( function() {
97    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
98    $o->getATime();
99} );
100
101echo "->getBasename()... ";
102testBaseClass( function() {
103    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
104    $o->getBasename();
105} );
106
107echo "->getCTime()... ";
108testBaseClass( function() {
109    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
110    $o->getCTime();
111} );
112
113echo "->getExtension()... ";
114testBaseClass( function() {
115    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
116    $o->getExtension();
117} );
118
119echo "->getFilename()... ";
120testBaseClass( function() {
121    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
122    $o->getFilename();
123} );
124
125echo "->getGroup()... ";
126testBaseClass( function() {
127    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
128    $o->getGroup();
129} );
130
131echo "->getInode()... ";
132testBaseClass( function() {
133    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
134    $o->getInode();
135} );
136
137echo "->getMTime()... ";
138testBaseClass( function() {
139    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
140    $o->getMTime();
141} );
142
143echo "->getOwner()... ";
144testBaseClass( function() {
145    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
146    $o->getOwner();
147} );
148
149echo "->getPath()... ";
150testBaseClass( function() {
151    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
152    $o->getPath();
153} );
154
155echo "->getPathname()... ";
156testBaseClass( function() {
157    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
158    $o->getPathname();
159} );
160
161echo "->getPerms()... ";
162testBaseClass( function() {
163    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
164    $o->getPerms();
165} );
166
167echo "->getSize()... ";
168testBaseClass( function() {
169    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
170    $o->getSize();
171} );
172
173echo "->getType()... ";
174testBaseClass( function() {
175    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
176    $o->getType();
177} );
178
179echo "->isDir()... ";
180testBaseClass( function() {
181    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
182    $o->isDir();
183} );
184
185echo "->isDot()... ";
186testBaseClass( function() {
187    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
188    $o->isDot();
189} );
190
191echo "->isExecutable()... ";
192testBaseClass( function() {
193    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
194    $o->isExecutable();
195} );
196
197echo "->isFile()... ";
198testBaseClass( function() {
199    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
200    $o->isFile();
201} );
202
203echo "->isLink()... ";
204testBaseClass( function() {
205    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
206    $o->isLink();
207} );
208
209echo "->isReadable()... ";
210testBaseClass( function() {
211    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
212    $o->isReadable();
213} );
214
215echo "->isWritable()... ";
216testBaseClass( function() {
217    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
218    $o->isWritable();
219} );
220
221echo "->seek()... ";
222testBaseClass( function() {
223    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
224    $o->seek(0);
225} );
226
227echo "->__toString()... ";
228testBaseClass( function() {
229    $o = new GlobIterator(__DIR__.'/*.abcdefghij');
230    $o->__toString();
231} );
232
233
234//
235// Supplemental test: no method should throw LogicException if it is invoked
236// after a successful iteration over a non-empty list of files.
237echo "non-empty GlobIterator... ";
238testBaseClass( function() {
239    $o = new GlobIterator(__DIR__.'/*.phpt');
240    foreach ($o as $file) {
241        // nothing here, just consume all the items
242    }
243    // This must not throw an exception
244    $o->count();
245} );
246
247
248//
249// The correct existing behaviour must not change
250// The classes SplFileObject and SplTempFileObject are not affected by the bug
251echo "======================= test there are no regressions =======================\n";
252
253echo "SplFileObject existent file... ";
254testBaseClass( function() {
255    $o = new SplFileObject(__FILE__);
256    $o->fread(1);
257} );
258
259echo "SplFileObject non-existent file... ";
260testBaseClass( function() {
261    $o = new SplFileObject('/tmp/abcdefghij.abcdefghij');
262    $o->fread(1);
263} );
264
265
266
267//
268// Check that when derived classes do not call GlobIterator::__construct()
269// the LogicException is thrown (don't break the behaviour introduced to fix bug #54384)
270echo "extends GlobIterator... ";
271class GlobIteratorChild extends GlobIterator {
272    public function __construct() {}
273}
274testChildClass( function() {
275    $o = new GlobIteratorChild();
276    $o->count();
277} );
278
279echo "extends SplFileObject... ";
280class SplFileObjectChild extends SplFileObject {
281    public function __construct() {}
282}
283testChildClass( function() {
284    $o = new SplFileObjectChild();
285    $o->count();
286} );
287
288echo "extends SplTempFileObject... ";
289class SplTempFileObjectChild extends SplTempFileObject {
290    public function __construct() {}
291}
292testChildClass( function() {
293    $o = new SplTempFileObjectChild();
294    $o->count();
295} );
296?>
297--EXPECT--
298->count()... ran normally (expected)
299->rewind()... ran normally (expected)
300->getFlags()... ran normally (expected)
301->setFlags()... ran normally (expected)
302->valid()... ran normally (expected)
303->current()... ran normally (expected)
304->key()... ran normally (expected)
305->next()... ran normally (expected)
306->getATime()... ran normally (expected)
307->getBasename()... ran normally (expected)
308->getCTime()... ran normally (expected)
309->getExtension()... ran normally (expected)
310->getFilename()... ran normally (expected)
311->getGroup()... ran normally (expected)
312->getInode()... ran normally (expected)
313->getMTime()... ran normally (expected)
314->getOwner()... ran normally (expected)
315->getPath()... ran normally (expected)
316->getPathname()... ran normally (expected)
317->getPerms()... ran normally (expected)
318->getSize()... ran normally (expected)
319->getType()... ran normally (expected)
320->isDir()... ran normally (expected)
321->isDot()... ran normally (expected)
322->isExecutable()... ran normally (expected)
323->isFile()... ran normally (expected)
324->isLink()... ran normally (expected)
325->isReadable()... ran normally (expected)
326->isWritable()... ran normally (expected)
327->seek()... ran normally (expected)
328->__toString()... ran normally (expected)
329non-empty GlobIterator... ran normally (expected)
330======================= test there are no regressions =======================
331SplFileObject existent file... ran normally (expected)
332SplFileObject non-existent file... ran normally (expected)
333extends GlobIterator... threw Error (expected)
334extends SplFileObject... threw Error (expected)
335extends SplTempFileObject... threw Error (expected)
336