|
| 1 | +--TEST-- |
| 2 | +Bug #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 does't match any file |
| 9 | +// because they get the properties of the current file |
| 10 | +function 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 (LogicException $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 |
| 26 | +function testChildClass($f) { |
| 27 | + try { |
| 28 | + $f(); |
| 29 | + echo "didn't throw (unexpected)\n"; |
| 30 | + } catch (LogicException $e) { |
| 31 | + echo "threw LogicException (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 |
| 41 | +echo "->count()... "; |
| 42 | +testBaseClass( function() { |
| 43 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 44 | + $o->count(); |
| 45 | +} ); |
| 46 | + |
| 47 | +echo "->rewind()... "; |
| 48 | +testBaseClass( function() { |
| 49 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 50 | + $o->rewind(); |
| 51 | +} ); |
| 52 | + |
| 53 | +echo "->getFlags()... "; |
| 54 | +testBaseClass( function() { |
| 55 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 56 | + $o->getFlags(); |
| 57 | +} ); |
| 58 | + |
| 59 | +echo "->setFlags()... "; |
| 60 | +testBaseClass( function() { |
| 61 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 62 | + $o->setFlags(FilesystemIterator::KEY_AS_PATHNAME); |
| 63 | +} ); |
| 64 | + |
| 65 | +echo "->valid()... "; |
| 66 | +testBaseClass( 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 |
| 77 | +echo "->current()... "; |
| 78 | +testBaseClass( function() { |
| 79 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 80 | + $o->current(); |
| 81 | +} ); |
| 82 | + |
| 83 | +echo "->key()... "; |
| 84 | +testBaseClass( function() { |
| 85 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 86 | + $o->key(); |
| 87 | +} ); |
| 88 | + |
| 89 | +echo "->next()... "; |
| 90 | +testBaseClass( function() { |
| 91 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 92 | + $o->next(); |
| 93 | +} ); |
| 94 | + |
| 95 | +echo "->getATime()... "; |
| 96 | +testBaseClass( function() { |
| 97 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 98 | + $o->getATime(); |
| 99 | +} ); |
| 100 | + |
| 101 | +echo "->getBasename()... "; |
| 102 | +testBaseClass( function() { |
| 103 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 104 | + $o->getBasename(); |
| 105 | +} ); |
| 106 | + |
| 107 | +echo "->getCTime()... "; |
| 108 | +testBaseClass( function() { |
| 109 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 110 | + $o->getCTime(); |
| 111 | +} ); |
| 112 | + |
| 113 | +echo "->getExtension()... "; |
| 114 | +testBaseClass( function() { |
| 115 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 116 | + $o->getExtension(); |
| 117 | +} ); |
| 118 | + |
| 119 | +echo "->getFilename()... "; |
| 120 | +testBaseClass( function() { |
| 121 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 122 | + $o->getFilename(); |
| 123 | +} ); |
| 124 | + |
| 125 | +echo "->getGroup()... "; |
| 126 | +testBaseClass( function() { |
| 127 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 128 | + $o->getGroup(); |
| 129 | +} ); |
| 130 | + |
| 131 | +echo "->getInode()... "; |
| 132 | +testBaseClass( function() { |
| 133 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 134 | + $o->getInode(); |
| 135 | +} ); |
| 136 | + |
| 137 | +echo "->getMTime()... "; |
| 138 | +testBaseClass( function() { |
| 139 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 140 | + $o->getMTime(); |
| 141 | +} ); |
| 142 | + |
| 143 | +echo "->getOwner()... "; |
| 144 | +testBaseClass( function() { |
| 145 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 146 | + $o->getOwner(); |
| 147 | +} ); |
| 148 | + |
| 149 | +echo "->getPath()... "; |
| 150 | +testBaseClass( function() { |
| 151 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 152 | + $o->getPath(); |
| 153 | +} ); |
| 154 | + |
| 155 | +echo "->getPathname()... "; |
| 156 | +testBaseClass( function() { |
| 157 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 158 | + $o->getPathname(); |
| 159 | +} ); |
| 160 | + |
| 161 | +echo "->getPerms()... "; |
| 162 | +testBaseClass( function() { |
| 163 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 164 | + $o->getPerms(); |
| 165 | +} ); |
| 166 | + |
| 167 | +echo "->getSize()... "; |
| 168 | +testBaseClass( function() { |
| 169 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 170 | + $o->getSize(); |
| 171 | +} ); |
| 172 | + |
| 173 | +echo "->getType()... "; |
| 174 | +testBaseClass( function() { |
| 175 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 176 | + $o->getType(); |
| 177 | +} ); |
| 178 | + |
| 179 | +echo "->isDir()... "; |
| 180 | +testBaseClass( function() { |
| 181 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 182 | + $o->isDir(); |
| 183 | +} ); |
| 184 | + |
| 185 | +echo "->isDot()... "; |
| 186 | +testBaseClass( function() { |
| 187 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 188 | + $o->isDot(); |
| 189 | +} ); |
| 190 | + |
| 191 | +echo "->isExecutable()... "; |
| 192 | +testBaseClass( function() { |
| 193 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 194 | + $o->isExecutable(); |
| 195 | +} ); |
| 196 | + |
| 197 | +echo "->isFile()... "; |
| 198 | +testBaseClass( function() { |
| 199 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 200 | + $o->isFile(); |
| 201 | +} ); |
| 202 | + |
| 203 | +echo "->isLink()... "; |
| 204 | +testBaseClass( function() { |
| 205 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 206 | + $o->isLink(); |
| 207 | +} ); |
| 208 | + |
| 209 | +echo "->isReadable()... "; |
| 210 | +testBaseClass( function() { |
| 211 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 212 | + $o->isReadable(); |
| 213 | +} ); |
| 214 | + |
| 215 | +echo "->isWritable()... "; |
| 216 | +testBaseClass( function() { |
| 217 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 218 | + $o->isWritable(); |
| 219 | +} ); |
| 220 | + |
| 221 | +echo "->seek()... "; |
| 222 | +testBaseClass( function() { |
| 223 | + $o = new GlobIterator(__DIR__.'/*.abcdefghij'); |
| 224 | + $o->seek(0); |
| 225 | +} ); |
| 226 | + |
| 227 | +echo "->__toString()... "; |
| 228 | +testBaseClass( 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. |
| 237 | +echo "non-empty GlobIterator... "; |
| 238 | +testBaseClass( 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 |
| 251 | +echo "======================= test there are no regressions =======================\n"; |
| 252 | + |
| 253 | +echo "SplFileObject existent file... "; |
| 254 | +testBaseClass( function() { |
| 255 | + $o = new SplFileObject(__FILE__); |
| 256 | + $o->fread(1); |
| 257 | +} ); |
| 258 | + |
| 259 | +echo "SplFileObject non-existent file... "; |
| 260 | +testBaseClass( 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) |
| 270 | +echo "extends GlobIterator... "; |
| 271 | +class GlobIteratorChild extends GlobIterator { |
| 272 | + public function __construct() {} |
| 273 | +} |
| 274 | +testChildClass( function() { |
| 275 | + $o = new GlobIteratorChild(); |
| 276 | + $o->count(); |
| 277 | +} ); |
| 278 | + |
| 279 | +echo "extends SplFileObject... "; |
| 280 | +class SplFileObjectChild extends SplFileObject { |
| 281 | + public function __construct() {} |
| 282 | +} |
| 283 | +testChildClass( function() { |
| 284 | + $o = new SplFileObjectChild(); |
| 285 | + $o->count(); |
| 286 | +} ); |
| 287 | + |
| 288 | +echo "extends SplTempFileObject... "; |
| 289 | +class SplTempFileObjectChild extends SplTempFileObject { |
| 290 | + public function __construct() {} |
| 291 | +} |
| 292 | +testChildClass( function() { |
| 293 | + $o = new SplTempFileObjectChild(); |
| 294 | + $o->count(); |
| 295 | +} ); |
| 296 | + |
| 297 | + |
| 298 | + |
| 299 | +--EXPECT-- |
| 300 | +->count()... ran normally (expected) |
| 301 | +->rewind()... ran normally (expected) |
| 302 | +->getFlags()... ran normally (expected) |
| 303 | +->setFlags()... ran normally (expected) |
| 304 | +->valid()... ran normally (expected) |
| 305 | +->current()... ran normally (expected) |
| 306 | +->key()... ran normally (expected) |
| 307 | +->next()... ran normally (expected) |
| 308 | +->getATime()... ran normally (expected) |
| 309 | +->getBasename()... ran normally (expected) |
| 310 | +->getCTime()... ran normally (expected) |
| 311 | +->getExtension()... ran normally (expected) |
| 312 | +->getFilename()... ran normally (expected) |
| 313 | +->getGroup()... ran normally (expected) |
| 314 | +->getInode()... ran normally (expected) |
| 315 | +->getMTime()... ran normally (expected) |
| 316 | +->getOwner()... ran normally (expected) |
| 317 | +->getPath()... ran normally (expected) |
| 318 | +->getPathname()... ran normally (expected) |
| 319 | +->getPerms()... ran normally (expected) |
| 320 | +->getSize()... ran normally (expected) |
| 321 | +->getType()... ran normally (expected) |
| 322 | +->isDir()... ran normally (expected) |
| 323 | +->isDot()... ran normally (expected) |
| 324 | +->isExecutable()... ran normally (expected) |
| 325 | +->isFile()... ran normally (expected) |
| 326 | +->isLink()... ran normally (expected) |
| 327 | +->isReadable()... ran normally (expected) |
| 328 | +->isWritable()... ran normally (expected) |
| 329 | +->seek()... ran normally (expected) |
| 330 | +->__toString()... ran normally (expected) |
| 331 | +non-empty GlobIterator... ran normally (expected) |
| 332 | +======================= test there are no regressions ======================= |
| 333 | +SplFileObject existent file... ran normally (expected) |
| 334 | +SplFileObject non-existent file... ran normally (expected) |
| 335 | +extends GlobIterator... threw LogicException (expected) |
| 336 | +extends SplFileObject... threw LogicException (expected) |
| 337 | +extends SplTempFileObject... threw LogicException (expected) |
0 commit comments