├── tests ├── classes │ ├── IFooFace.php │ ├── IFooFaceTwo.php │ ├── FooBar.php │ ├── NoFooFacePartialInterface.php │ ├── Qux.php │ ├── NoFooFace.php │ ├── AbstractFoo.php │ ├── FooFace.php │ ├── FooFaceTrait.php │ ├── FooFaceNoUse.php │ ├── Bar.php │ ├── FooFaceTraitUnused.php │ ├── FooFaceNoRegister.php │ ├── NoFooFacePartial.php │ └── Foo.php ├── Rule.php ├── UnlinkTest.php ├── Printing.php ├── Mock.php └── Path.php ├── src └── mimus │ ├── Exception.php │ ├── Rule.php │ ├── Path.php │ └── Double.php ├── composer.json ├── phpunit.xml ├── LICENSE.md ├── .travis.yml ├── README.md └── composer.lock /tests/classes/IFooFace.php: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /tests/classes/IFooFaceTwo.php: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /tests/classes/FooBar.php: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /tests/classes/Qux.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /tests/classes/NoFooFace.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /tests/classes/AbstractFoo.php: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /tests/classes/FooFace.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /tests/classes/FooFaceTrait.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/mimus/Exception.php: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /tests/classes/Bar.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /tests/classes/FooFaceTraitUnused.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /tests/classes/FooFaceNoRegister.php: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /tests/classes/NoFooFacePartial.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /tests/Rule.php: -------------------------------------------------------------------------------- 1 | rule("publicMethod"); 11 | 12 | $rule->expects(); 13 | 14 | $this->expectException(\mimus\Exception::class); 15 | 16 | $rule->expects(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "krakjoe/mimus", 3 | "require": { 4 | "php": "^7.2|^8.0", 5 | "ext-componere": "^3.0.0" 6 | }, 7 | "require-dev": { 8 | "phpunit/phpunit": "^8.0 || ^9.0", 9 | "php-coveralls/php-coveralls": "^2.1" 10 | }, 11 | "autoload": { 12 | "psr-4": { 13 | "mimus\\": "src/mimus" 14 | } 15 | }, 16 | "autoload-dev": { 17 | "psr-4": { 18 | "mimus\\tests\\": "tests/" 19 | } 20 | }, 21 | "license": "MIT", 22 | "minimum-stability": "dev", 23 | "prefer-stable": true 24 | } 25 | -------------------------------------------------------------------------------- /src/mimus/Rule.php: -------------------------------------------------------------------------------- 1 | method = $method; 8 | } 9 | 10 | public function expects(...$args) : Path { 11 | if (isset($this->path)) { 12 | throw new Exception(null, 13 | "expectation already set for %s", $this->method); 14 | } 15 | 16 | return $this->path = new Path(...$args); 17 | } 18 | 19 | public function match(?Exception $except, bool $count, ...$args) : ?Path { 20 | if ($this->path->try($except, $count, ...$args)) { 21 | return $this->path; 22 | } 23 | } 24 | 25 | private $method; 26 | private $path; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tests/Mock.php 5 | 6 | 7 | tests/Path.php 8 | 9 | 10 | tests/Rule.php 11 | 12 | 13 | tests/Printing.php 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/UnlinkTest.php: -------------------------------------------------------------------------------- 1 | rule("bar") 15 | ->expects() 16 | ->returns('foo'); 17 | 18 | $this->assertEquals('foo', $fb->bar()); 19 | 20 | var_dump(double::exists(FooBar::class)); 21 | 22 | double::unlink(FooBar::class); 23 | //double::clear(); 24 | //$builder->reset('bar'); 25 | var_dump(double::exists(FooBar::class)); 26 | $this->assertEquals('bar', $fb->bar()); 27 | 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/classes/Foo.php: -------------------------------------------------------------------------------- 1 | protectedMethod($bool); 7 | } 8 | 9 | protected function protectedMethod(bool $bool) { 10 | return $this->privateMethod($bool); 11 | } 12 | 13 | private function privateMethod(bool $bool) { 14 | return !$bool; 15 | } 16 | 17 | public static function publicStaticMethod(bool $bool) { 18 | return self::protectedStaticMethod($bool); 19 | } 20 | 21 | protected static function protectedStaticMethod(bool $bool) { 22 | return self::privateStaticMethod($bool); 23 | } 24 | 25 | private static function privateStaticMethod(bool $bool) { 26 | return !$bool; 27 | } 28 | 29 | final public function publicFinalMethod(bool $bool) { 30 | return !$bool; 31 | } 32 | 33 | public function publicAcceptAndReturnFoo(Foo $object) : Foo { 34 | return $this; 35 | } 36 | } 37 | } 38 | ?> 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019 Joe Watkins 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.2 5 | - 7.3 6 | - 7.4 7 | - nightly 8 | 9 | env: 10 | matrix: 11 | - OPCACHE=0 12 | - OPCACHE=1 13 | 14 | before_install: 15 | - alias composer=composer\ -n && composer self-update 16 | - git clone https://github.com/krakjoe/componere $HOME/componere 17 | - cd $HOME/componere 18 | - phpize 19 | - ./configure 20 | - make 21 | - make install 22 | - echo "extension=componere.so" > $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/componere.ini 23 | - echo "variables_order=EGPCS" >> $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/php.ini 24 | - echo > $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/xdebug.ini 25 | - echo "opcache.optimization_level=0" >> $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/opcache.ini 26 | - echo "opcache.enable_cli=$OPCACHE" >> $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/opcache.ini 27 | - pecl install pcov 28 | - cd $TRAVIS_BUILD_DIR 29 | 30 | install: 31 | - composer install --ignore-platform-reqs 32 | 33 | before_script: 34 | - mkdir -p build/logs 35 | 36 | script: 37 | - php vendor/bin/phpunit --coverage-text --coverage-clover=build/logs/clover.xml 38 | 39 | after_success: 40 | - vendor/bin/php-coveralls -v 41 | -------------------------------------------------------------------------------- /tests/Printing.php: -------------------------------------------------------------------------------- 1 | rule("publicMethod") 11 | ->expects(42); 12 | 13 | $object = $builder->getInstance(); 14 | 15 | $this->expectException(\mimus\Exception::class); 16 | $this->assertNull($object->publicMethod(43)); 17 | } 18 | 19 | public function testPrintDouble() { 20 | $builder = double::class(\mimus\tests\classes\Foo::class); 21 | 22 | $builder->rule("publicMethod") 23 | ->expects(4.2); 24 | 25 | $object = $builder->getInstance(); 26 | 27 | $this->expectException(\mimus\Exception::class); 28 | $this->assertNull($object->publicMethod(4.3)); 29 | } 30 | 31 | public function testPrintString() { 32 | $builder = double::class(\mimus\tests\classes\Foo::class); 33 | 34 | $builder->rule("publicMethod") 35 | ->expects("hello"); 36 | 37 | $object = $builder->getInstance(); 38 | 39 | $this->expectException(\mimus\Exception::class); 40 | $this->assertNull($object->publicMethod("world")); 41 | } 42 | 43 | public function testPrintArray() { 44 | $builder = double::class(\mimus\tests\classes\Foo::class); 45 | 46 | $builder->rule("publicMethod") 47 | ->expects([1,2,3]); 48 | 49 | $object = $builder->getInstance(); 50 | 51 | $this->expectException(\mimus\Exception::class); 52 | $this->assertNull($object->publicMethod([4,5,6])); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/mimus/Path.php: -------------------------------------------------------------------------------- 1 | accepts = $accepts; 10 | } else $this->accepts = Path::$sentinal; 11 | $this->returns = Path::$sentinal; 12 | } 13 | 14 | public function executes(\Closure $body = null) : Path { 15 | if ($body === null) { 16 | $this->executes = true; 17 | } else $this->executes = $body; 18 | 19 | return $this; 20 | } 21 | 22 | public function returns($value) : Path { 23 | if ($this->void) { 24 | throw new \LogicException( 25 | "cannot return from void path"); 26 | } 27 | $this->returns = $value; 28 | 29 | return $this; 30 | } 31 | 32 | public function void() : Path { 33 | if ($this->returns !== Path::$sentinal) { 34 | throw new \LogicException( 35 | "void path cannot return"); 36 | } 37 | $this->void = true; 38 | 39 | return $this; 40 | } 41 | 42 | public function throws(string $class) : Path { 43 | if ($this->executes === false) { 44 | throw new \LogicException( 45 | "non executable path cannot throw"); 46 | } 47 | 48 | $this->throws = $class; 49 | 50 | return $this; 51 | } 52 | 53 | public function never() : Path { 54 | $this->limit = true; 55 | 56 | return $this; 57 | } 58 | 59 | public function once() : Path { 60 | $this->limit = 1; 61 | 62 | return $this; 63 | } 64 | 65 | public function limit(int $times) : Path { 66 | $this->limit = $times; 67 | 68 | return $this; 69 | } 70 | 71 | public function try(?Exception $except, bool $count, ...$args) : bool { 72 | if ($this->accepts == Path::$sentinal) { 73 | return true; 74 | } 75 | 76 | if ($count && count($args) != count($this->accepts)) { 77 | throw new Exception($except, 78 | "expected %d arguments, got %d", 79 | count($this->accepts), count($args)); 80 | } 81 | 82 | foreach ($this->accepts as $idx => $arg) { 83 | $expected = gettype($arg); 84 | $got = gettype($args[$idx]); 85 | 86 | if (($expected == 'string' || $expected == 'object') && is_object($args[$idx])) { 87 | if (!$args[$idx] instanceof $arg) { 88 | throw new Exception($except, 89 | "argument %d expected to be %s got %s", 90 | $idx, 91 | \mimus\printable($arg), 92 | \mimus\printable($args[$idx])); 93 | } 94 | continue; 95 | } 96 | 97 | if ($expected != $got) { 98 | throw new Exception($except, 99 | "argument %d expected to be of type %s, got type %s", 100 | $idx, $expected, $got); 101 | } 102 | 103 | switch ($expected) { 104 | case 'null': 105 | case 'string': 106 | case 'integer': 107 | case 'double': 108 | case 'boolean': 109 | case 'array': 110 | if ($arg !== $args[$idx]) { 111 | throw new Exception($except, 112 | "argument %d expected to be %s got %s", 113 | $idx, 114 | \mimus\printable($arg), 115 | \mimus\printable($args[$idx])); 116 | } 117 | break; 118 | 119 | default: 120 | throw new Exception($except, 121 | "argument %d is an unknown type, %s", 122 | $idx, gettype($arg)); 123 | } 124 | } 125 | 126 | return true; 127 | } 128 | 129 | private function verifyException(\Throwable $thrown = null) { 130 | if (!$thrown || !($thrown instanceof $this->throws)) { 131 | throw new Exception(null, 132 | "expected exception of type %s, %s thrown", 133 | $this->throws, $thrown ? get_class($thrown) : "nothing"); 134 | } 135 | 136 | return true; 137 | } 138 | 139 | private function verifyReturn($value = null) { 140 | if ($this->void && $value !== null) { 141 | throw new Exception(null, 142 | "return value not expected, got %s", 143 | \mimus\printable($value)); 144 | } 145 | 146 | if ($this->returns === self::$sentinal) { 147 | return; 148 | } 149 | 150 | if ($this->returns && $value === null) { 151 | throw new Exception(null, 152 | "return value expected to be of type %s, got null", 153 | gettype($this->returns)); 154 | } 155 | 156 | if (gettype($this->returns) != gettype($value)) { 157 | if (gettype($this->returns) != 'string' && gettype($value) != 'object') { 158 | throw new Exception(null, 159 | "return value expected to be of type %s, got %s", 160 | gettype($this->returns), 161 | gettype($value)); 162 | } 163 | } 164 | 165 | if (gettype($this->returns) == 'object' || gettype($value) == 'object') { 166 | if (gettype($value) != 'object' || !$value instanceof $this->returns) { 167 | throw new Exception(null, 168 | "return value expected to be of class %s, got %s", 169 | $this->returns, 170 | gettype($value) == 'object' ? 171 | get_class($value) : gettype($value)); 172 | } 173 | return; 174 | } 175 | 176 | if ($value !== $this->returns) { 177 | throw new Exception(null, 178 | "return value expected to be %s, got %s", 179 | \mimus\printable($this->returns), 180 | \mimus\printable($value)); 181 | } 182 | } 183 | 184 | private function verifyValidators(?object $object, $retval = null) : void { 185 | $except = null; 186 | 187 | if (!$this->validators) { 188 | return; 189 | } 190 | 191 | foreach ($this->validators as $idx => $validator) { 192 | $result = $object ? 193 | $validator->call($object, $retval) : 194 | $validator($retval); 195 | 196 | if (!$result) { 197 | $except = new Exception($except, 198 | "validator %d failed", 199 | $idx); 200 | } 201 | } 202 | 203 | if ($except) 204 | throw $except; 205 | } 206 | 207 | public function travel(?object $object, \Closure $prototype, ...$args) { 208 | $retval = null; 209 | $thrown = null; 210 | if ($this->limit !== false) { 211 | if ($this->limit === true || 212 | ++$this->count > $this->limit) { 213 | throw new Exception(null, 214 | "limit of %d exceeded", $this->limit); 215 | } 216 | } 217 | try { 218 | if ($this->executes === false) { 219 | $retval = $this->returns; 220 | } else if ($this->executes === true) { 221 | $retval = $object ? 222 | $prototype->call($object, ...$args) : 223 | $prototype(...$args); 224 | } else { 225 | $retval = $object ? 226 | $this->executes->call($object, $prototype->bindTo($object), ...$args) : 227 | ($this->executes)($prototype, ...$args); 228 | } 229 | } catch (\Throwable $thrown) { 230 | if ($this->throws) { 231 | $this->verifyException($thrown); 232 | } 233 | 234 | throw $thrown; 235 | } 236 | 237 | if ($this->throws) { 238 | $this->verifyException(null); 239 | } 240 | 241 | $this->verifyReturn($retval); 242 | 243 | $this->verifyValidators($object, $retval); 244 | 245 | return $retval; 246 | } 247 | 248 | public function validates(\Closure $validator) : Path { 249 | $this->validators[] = $validator; 250 | 251 | return $this; 252 | } 253 | 254 | private $accepts; 255 | private $returns; 256 | private $void; 257 | private $throws; 258 | private $executes = false; 259 | private $limit = false; 260 | private $count = 0; 261 | private $validators = []; 262 | } 263 | 264 | Path::$sentinal = new class{}; 265 | } 266 | -------------------------------------------------------------------------------- /src/mimus/Double.php: -------------------------------------------------------------------------------- 1 | reset(); 42 | } 43 | 44 | return double::$doubles[$name]; 45 | } 46 | 47 | private function __construct(\Componere\Definition $definition) { 48 | $this->definition = $definition; 49 | $this->reflector = $this->definition->getReflector(); 50 | 51 | foreach ($this->reflector->getInterfaceNames() as $interface) { 52 | $this->interfaces[$interface] = true; 53 | } 54 | 55 | if ($this->reflector->isAbstract()) { 56 | throw new \LogicException( 57 | "cannot mock an abstract class"); 58 | } 59 | } 60 | 61 | private function build() { 62 | $closures = $this->definition->getClosures(); 63 | 64 | foreach ($closures as $name => $closure) { 65 | $prototype = $this->reflector->getMethod($name); 66 | $static = $prototype->isStatic(); 67 | 68 | 69 | $this->table[$name] = []; 70 | 71 | $table =& $this->table[$name]; 72 | 73 | $implementation = new \Componere\Method(function(...$args) 74 | use($static, $closure, &$table) { 75 | $except = null; 76 | $path = null; 77 | 78 | if (!$table) { 79 | return; 80 | } 81 | 82 | foreach ($table as $idx => $rule) { 83 | try { 84 | $path = $rule->match($except, true, ...$args); 85 | } catch (Exception $ex) { 86 | $except = $ex; 87 | } 88 | 89 | if ($path) { 90 | $except = null; 91 | break; 92 | } 93 | } 94 | 95 | if ($except) { 96 | throw $except; 97 | } 98 | 99 | if ($static) { 100 | return $path->travel(null, $closure, ...$args); 101 | } 102 | 103 | return $path->travel($this, $closure, ...$args); 104 | }); 105 | 106 | if ($static) { 107 | $implementation->setStatic(); 108 | } 109 | 110 | if ($prototype->isPrivate()) { 111 | $implementation->setPrivate(); 112 | } else if ($prototype->isProtected()) { 113 | $implementation->setProtected(); 114 | } 115 | 116 | if ($prototype->isFinal()) { 117 | $implementation->setFinal(); 118 | } 119 | 120 | $this->definition->addMethod($name, $implementation); 121 | } 122 | 123 | $this->definition->register(); 124 | } 125 | 126 | public function use(string $class, bool $partialize = false) : Double { 127 | if (isset($this->traits[$class])) { 128 | if ($partialize) { 129 | $this->partialize($class); 130 | } 131 | return $this; 132 | } 133 | 134 | if ($this->definition->isRegistered()) { 135 | throw new \LogicException( 136 | "use() must be invoked before rule() or getInstance()"); 137 | } 138 | 139 | if (!trait_exists($class)) { 140 | throw new \LogicException( 141 | "trait {$class} does not exist, or is not a trait"); 142 | } 143 | 144 | $this->definition->addTrait($class); 145 | 146 | if ($partialize) { 147 | $this->partialize($class); 148 | } 149 | 150 | $this->traits[$class] = true; 151 | 152 | return $this; 153 | } 154 | 155 | public function implements(string $class, bool $partialize = false) : Double { 156 | if (isset($this->interfaces[$class])) { 157 | if ($partialize) { 158 | $this->partialize($class); 159 | } 160 | return $this; 161 | } 162 | 163 | if ($this->definition->isRegistered()) { 164 | throw new \LogicException( 165 | "implements() must be invoked before rule() or getInstance()"); 166 | } 167 | 168 | if (!interface_exists($class)) { 169 | throw new \LogicException( 170 | "interface {$class} does not exist, or is not an interface"); 171 | } 172 | 173 | $this->definition->addInterface($class); 174 | 175 | if ($partialize) { 176 | $this->partialize($class); 177 | } 178 | 179 | $this->interfaces[$class] = true; 180 | 181 | return $this; 182 | } 183 | 184 | public function partialize($on, array $except = []) : Double { 185 | if (!is_array($on) && !is_string($on)) { 186 | throw new \LogicException( 187 | "expected an array of method names or the name of a valid class"); 188 | } 189 | 190 | if (is_array($on) && count($except)) { 191 | throw new \LogicException( 192 | "expected a class name and array of excluded methods"); 193 | } 194 | 195 | if (is_array($on)) { 196 | foreach ($on as $method) { 197 | if ($this->reset($method)) { 198 | $this->rule($method) /* must be first rule */ 199 | ->expects() 200 | ->executes(); 201 | } 202 | } 203 | } else { 204 | try { 205 | $reflector = new \ReflectionClass($on); 206 | } catch (\ReflectionException $re) { 207 | throw new \LogicException( 208 | "expected a valid class name, {$on} cannot be loaded"); 209 | } 210 | 211 | foreach ($reflector->getMethods() as $method) { 212 | if (!count($except) || !in_array($method->getName(), $except)) { 213 | if ($this->reset($method->getName())) { 214 | $this->rule($method->getName()) 215 | ->expects() 216 | ->executes(); 217 | } 218 | } 219 | } 220 | } 221 | return $this; 222 | } 223 | 224 | public function defines(string $name, $value) : Double { 225 | if ($this->reflector->hasConstant($name)) { 226 | $this->definition->setConstant( 227 | $name, new \Componere\Value($value)); 228 | } else { 229 | $this->definition->addConstant( 230 | $name, new \Componere\Value($value)); 231 | } 232 | return $this; 233 | } 234 | 235 | public function rule(string $name) : Rule { 236 | self::commit(); 237 | 238 | if (!isset($this->table[$name])) { 239 | throw new \LogicException( 240 | "method {$name} does not exist, or is whitelisted"); 241 | } 242 | 243 | return $this->table[$name][] = new Rule($name); 244 | } 245 | 246 | public function reset(string $name = null) : bool { 247 | if (!$this->definition->isRegistered()) { 248 | return true; 249 | } 250 | 251 | if ($this->table) { 252 | if ($name === null) { 253 | foreach ($this->table as $name => $rules) { 254 | if (!$this->reset($name)) { 255 | return false; 256 | } 257 | } 258 | return true; 259 | } else if (isset($this->table[$name])) { 260 | foreach ($this->table[$name] as $idx => $rule) { 261 | unset($this->table[$name][$idx]); 262 | } 263 | return true; 264 | } 265 | } 266 | 267 | return false; 268 | } 269 | 270 | public function commit() : void { 271 | if (!$this->definition->isRegistered()) { 272 | $this->build(); 273 | } 274 | } 275 | 276 | public function getInstance(...$args) : object { 277 | self::commit(); 278 | 279 | if (!func_num_args()) { 280 | return $this->reflector->newInstanceWithoutConstructor(); 281 | } 282 | return $this->reflector->newInstanceArgs($args); 283 | } 284 | 285 | private $definition; 286 | private $traits = []; 287 | private $interfaces = []; 288 | private $reflector; 289 | private $table; 290 | 291 | private static $doubles = []; 292 | } 293 | 294 | function printable($value) { 295 | switch (gettype($value)) { 296 | case 'null': 297 | return 'null'; 298 | case 'boolean': 299 | return $value ? "bool(true)" : "bool(false)"; 300 | case 'integer': 301 | return sprintf("int(%d)", $value); 302 | case 'double': 303 | return sprintf("float(%s)", $value); 304 | case 'string': /* TODO limit length */ 305 | if (class_exists($value, 0)) 306 | return $value; 307 | return sprintf("string(%d) \"%s\"", strlen($value), $value); 308 | case 'array': /* TODO limit length */ 309 | return sprintf("array(%d) [%s]", count($value), implode(',', $value)); 310 | case 'object': 311 | return get_class($value); 312 | default: 313 | return 'unknown'; 314 | } 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /tests/Mock.php: -------------------------------------------------------------------------------- 1 | expectException(\LogicException::class); 10 | 11 | double::class(None::class); 12 | } 13 | 14 | public function testClassMock() { 15 | $builder = double::class(\mimus\tests\classes\Foo::class); 16 | 17 | $object = $builder->getInstance(); 18 | 19 | $this->assertInstanceOf(\mimus\tests\classes\Foo::class, $object); 20 | } 21 | 22 | public function testAbstractMockFails() { 23 | $this->expectException(\LogicException::class); 24 | $builder = double::class(myabstract::class, 25 | \mimus\tests\classes\AbstractFoo::class); 26 | } 27 | 28 | public function testMake() { 29 | $builder = double::make(DateTime::class, [\DateTime::class]); 30 | 31 | $object = $builder->getInstance(); 32 | 33 | $this->assertInstanceOf(\DateTime::class, $object); 34 | $this->assertInstanceof(DateTime::class, $object); 35 | } 36 | 37 | public function testMakeAbstract() { 38 | $builder = double::make(myabstract::class, 39 | [\mimus\tests\classes\AbstractFoo::class]); 40 | 41 | $object = $builder->getInstance(); 42 | 43 | $this->assertInstanceOf(myabstract::class, $object); 44 | $this->assertInstanceof(\mimus\tests\classes\AbstractFoo::class, $object); 45 | } 46 | 47 | public function testMakeParentAndInterfaces() { 48 | $builder = double::make(complex::class, [ 49 | /* extends */ \mimus\tests\classes\AbstractFoo::class, 50 | /* implements */ [ 51 | \mimus\tests\classes\IFooFace::class, 52 | \mimus\tests\classes\IFooFaceTwo::class 53 | ] 54 | ]); 55 | 56 | $object = $builder->getInstance(); 57 | 58 | $this->assertInstanceOf(complex::class, $object); 59 | $this->assertInstanceOf(\mimus\tests\classes\AbstractFoo::class, $object); 60 | $this->assertInstanceOf(\mimus\tests\classes\IFooFace::class, $object); 61 | $this->assertInstanceOf(\mimus\tests\classes\IFooFaceTwo::class, $object); 62 | } 63 | 64 | public function testMockNonExistentMethodLogicException() { 65 | $builder = double::class(\mimus\tests\classes\Bar::class); 66 | 67 | $this->expectException(\LogicException::class); 68 | 69 | $builder->rule("nonExistentMethod"); 70 | } 71 | 72 | public function testMockImplementsClassDoesNotExist() { 73 | $builder = double::class(\mimus\tests\classes\NoFooFace::class); 74 | 75 | $this->expectException(\LogicException::class); 76 | 77 | $builder->implements(\mimus\tests\classes\IFooFaceDoesNotExist::class); 78 | } 79 | 80 | public function testMockImplements() { 81 | $builder = double::class(\mimus\tests\classes\NoFooFace::class); 82 | $builder->implements(\mimus\tests\classes\IFooFace::class); 83 | 84 | $object = $builder->getInstance(); 85 | 86 | $this->assertInstanceOf(\mimus\tests\classes\IFooFace::class, $object); 87 | } 88 | 89 | public function testMockImplementsPartial() { 90 | $builder = double::class(\mimus\tests\classes\NoFooFacePartial::class); 91 | $builder->implements(\mimus\tests\classes\NoFooFacePartialInterface::class, true); 92 | 93 | $object = $builder->getInstance(); 94 | 95 | $this->assertInstanceOf(\mimus\tests\classes\NoFooFacePartialInterface::class, $object); 96 | $this->assertTrue($object->partialized(false)); 97 | $this->assertNull($object->notPartialized(false)); 98 | } 99 | 100 | public function testMockUsesNonTrait() { 101 | $builder = double::class(\mimus\tests\classes\FooFaceNoUse::class); 102 | 103 | $this->expectException(\LogicException::class); 104 | 105 | $builder->use(\mimus\tests\classes\NoFooFacePartialInterface::class); 106 | } 107 | 108 | public function testMockUses() { 109 | $builder = double::class(\mimus\tests\classes\FooFaceNoUse::class); 110 | $builder->use(\mimus\tests\classes\FooFaceTrait::class) 111 | ->rule("nonTraitMethod") 112 | ->expects() 113 | ->executes(); 114 | $builder->rule("traitMethod") 115 | ->expects() 116 | ->executes(); 117 | 118 | $object = $builder->getInstance(); 119 | 120 | $this->assertFalse($object->nonTraitMethod()); /* comes from class */ 121 | $this->assertTrue($object->traitMethod()); /* comes from trait */ 122 | } 123 | 124 | public function testMockUsesAlreadyRegisteredException() { 125 | $builder = double::class(\mimus\tests\classes\FooFaceNoUse::class); 126 | 127 | $this->expectException(\LogicException::class); 128 | 129 | $builder->use(\mimus\tests\classes\FooFaceTraitUnused::class); 130 | } 131 | 132 | public function testMockUsesAlreadyRegisteredOkay() { 133 | /* this only seems to be a duplicate test */ 134 | $builder = double::class(\mimus\tests\classes\FooFaceNoUse::class); 135 | 136 | $builder->use(\mimus\tests\classes\FooFaceTrait::class) 137 | ->rule("nonTraitMethod") 138 | ->expects() 139 | ->executes(); 140 | $builder->rule("traitMethod") 141 | ->expects() 142 | ->executes(); 143 | 144 | $object = $builder->getInstance(); 145 | 146 | $this->assertFalse($object->nonTraitMethod()); /* comes from class */ 147 | $this->assertTrue($object->traitMethod()); /* comes from trait */ 148 | } 149 | 150 | public function testMockUsesPartial() { 151 | $builder = double::class(\mimus\tests\classes\FooFaceNoUse::class); 152 | $builder->use(\mimus\tests\classes\FooFaceTrait::class, true); 153 | 154 | $object = $builder->getInstance(); 155 | 156 | $this->assertTrue($object->traitMethod()); 157 | } 158 | 159 | public function testMockUsesUnregisteredPartial() { 160 | $builder = double::class(\mimus\tests\classes\FooFaceNoRegister::class); 161 | $builder->use(\mimus\tests\classes\FooFaceTrait::class, true); 162 | 163 | $object = $builder->getInstance(); 164 | 165 | $this->assertTrue($object->traitMethod()); 166 | } 167 | 168 | public function testMockImplementsAlreadyRegistered() { 169 | $builder = double::class(\mimus\tests\classes\NoFooFace::class); 170 | 171 | $object = $builder->getInstance(); 172 | 173 | $this->assertInstanceOf(\mimus\tests\classes\IFooFace::class, $object); 174 | } 175 | 176 | public function testMockImplementsAlreadyBuilt() { 177 | $builder = double::class(\mimus\tests\classes\NoFooFace::class); 178 | $builder->implements(\mimus\tests\classes\IFooFace::class); 179 | 180 | $this->expectException(\LogicException::class); 181 | 182 | $builder->implements(\mimus\tests\classes\IFooFaceTwo::class); 183 | } 184 | 185 | public function testMockImplementsAlreadyRegisteredPartial() { 186 | $builder = double::class(\mimus\tests\classes\NoFooFace::class); 187 | $builder->implements(\mimus\tests\classes\IFooFace::class, true); 188 | 189 | $object = $builder->getInstance(); 190 | 191 | $this->assertInstanceOf(\mimus\tests\classes\IFooFace::class, $object); 192 | $this->assertTrue($object->publicMethod(false)); 193 | $this->assertFalse($object->publicMethod(true)); 194 | } 195 | 196 | public function testPartialLogicExceptionArgs() { 197 | $builder = double::class(\mimus\tests\classes\Foo::class); 198 | 199 | $this->expectException(\LogicException::class); 200 | 201 | $builder->partialize(42); 202 | } 203 | 204 | public function testPartialLogicExceptionArgNotValidClass() { 205 | $builder = double::class(\mimus\tests\classes\Foo::class); 206 | 207 | $this->expectException(\LogicException::class); 208 | 209 | $builder->partialize("none"); 210 | } 211 | 212 | public function testPartialMockArray() { 213 | $builder = double::class(\mimus\tests\classes\Foo::class); 214 | $builder->partialize([ 215 | "publicMethod", 216 | "privateMethod", 217 | "protectedMethod" 218 | ]); 219 | $object = $builder->getInstance(); 220 | $this->assertFalse($object->publicMethod(true)); 221 | } 222 | 223 | public function testPartialMockClass() { 224 | $builder = double::class(\mimus\tests\classes\FooFace::class); 225 | $builder->partialize(\mimus\tests\classes\IFooFace::class); 226 | $object = $builder->getInstance(); 227 | $this->assertFalse($object->publicMethod(true)); 228 | } 229 | 230 | public function testMockGetInstanceConstructed() { 231 | $builder = double::class(\mimus\tests\classes\Qux::class); 232 | $builder->partialize([ 233 | "__construct" 234 | ]); 235 | 236 | $this->expectException(\Error::class); 237 | $builder->getInstance(true); 238 | } 239 | 240 | public function testMockUnlink() { 241 | $this->assertTrue(double::exists(\mimus\tests\classes\Foo::class)); 242 | double::unlink(\mimus\tests\classes\Foo::class); 243 | $this->assertFalse(double::exists(\mimus\tests\classes\Foo::class)); 244 | $this->expectException(\LogicException::class); 245 | double::unlink(ClassDoesNotExist::class); 246 | } 247 | 248 | public function testMockCommit() { 249 | if (double::exists(\mimus\tests\classes\Foo::class)) 250 | double::unlink(\mimus\tests\classes\Foo::class); 251 | 252 | $this->assertFalse(double::exists(\mimus\tests\classes\Foo::class)); 253 | 254 | $builder = 255 | double::class(\mimus\tests\classes\Foo::class) 256 | ->implements(\mimus\tests\classes\IFooFace::class); 257 | 258 | $this->assertTrue(double::exists(\mimus\tests\classes\Foo::class)); 259 | 260 | $builder->commit(\mimus\tests\classes\Foo::class); 261 | 262 | $object = new \mimus\tests\classes\Foo; 263 | 264 | $this->assertTrue($object instanceof \mimus\tests\classes\IFooFace); 265 | } 266 | 267 | public function testMockClear() { 268 | $this->assertTrue(double::exists(\mimus\tests\classes\Foo::class)); 269 | 270 | double::clear(); 271 | 272 | $this->assertFalse(double::exists(\mimus\tests\classes\Foo::class)); 273 | } 274 | 275 | public function testMockDefines() { 276 | $builder = double::class(\mimus\tests\classes\Foo::class); 277 | $builder->defines("BAR", 42); 278 | $builder->commit(); 279 | 280 | $this->assertSame(\mimus\tests\classes\Foo::BAR, 42); 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /tests/Path.php: -------------------------------------------------------------------------------- 1 | expectException(\LogicException::class); 12 | 13 | $builder->rule("publicMethod") 14 | ->expects(true) 15 | ->returns(true) 16 | ->void(); 17 | } 18 | 19 | public function testLogicExceptionVoidCannotReturn() { 20 | $builder = double::class(\mimus\tests\classes\Foo::class); 21 | 22 | $this->expectException(\LogicException::class); 23 | 24 | $builder->rule("publicMethod") 25 | ->expects(true) 26 | ->void() 27 | ->returns(true); 28 | } 29 | 30 | public function testLogicExceptionNoneExecutablePathCannotThrow() { 31 | $builder = double::class(\mimus\tests\classes\Foo::class); 32 | 33 | $this->expectException(\LogicException::class); 34 | 35 | $builder->rule("publicMethod") 36 | ->expects() 37 | ->throws(\Throwable::class); 38 | } 39 | 40 | public function testWrongArgumentCount() { 41 | $builder = double::class(\mimus\tests\classes\Foo::class); 42 | 43 | $builder->rule("publicMethod") 44 | ->expects(true) 45 | ->executes(function(){}); 46 | 47 | $object = $builder->getInstance(); 48 | 49 | $this->expectException(\mimus\Exception::class); 50 | $this->assertNull($object->publicMethod(true, true)); 51 | } 52 | 53 | public function testUnexpectedObject() { 54 | $builder = double::class(\mimus\tests\classes\Foo::class); 55 | 56 | $builder->rule("publicMethod") 57 | ->expects(\stdClass::class) 58 | ->executes(function(){}); 59 | 60 | $object = $builder->getInstance(); 61 | 62 | $this->expectException(\mimus\Exception::class); 63 | $this->assertNull($object->publicMethod(new class{})); 64 | } 65 | 66 | public function testUnexpectedType() { 67 | $builder = double::class(\mimus\tests\classes\Foo::class); 68 | 69 | $builder->rule("publicMethod") 70 | ->expects(1) 71 | ->executes(function(){}); 72 | 73 | $object = $builder->getInstance(); 74 | 75 | $this->expectException(\mimus\Exception::class); 76 | $this->assertNull($object->publicMethod(true)); 77 | } 78 | 79 | public function testUnexpectedValue() { 80 | $builder = double::class(\mimus\tests\classes\Foo::class); 81 | $builder->rule("publicMethod") 82 | ->expects(true) 83 | ->executes(function(){}); 84 | 85 | $object = $builder->getInstance(); 86 | 87 | $this->expectException(\mimus\Exception::class); 88 | $this->assertNull($object->publicMethod(false)); 89 | } 90 | 91 | public function testExecutes() { 92 | $builder = double::class(\mimus\tests\classes\Foo::class); 93 | $builder->rule("publicMethod") 94 | ->expects() 95 | ->executes(); 96 | $builder->rule("privateMethod") 97 | ->expects() 98 | ->executes(); 99 | $builder->rule("protectedMethod") 100 | ->expects() 101 | ->executes(); 102 | 103 | $object = $builder->getInstance(); 104 | 105 | $this->assertFalse($object->publicMethod(true)); 106 | } 107 | 108 | public function testException() { 109 | $builder = double::class(\mimus\tests\classes\Foo::class); 110 | 111 | $builder->rule("publicMethod") 112 | ->expects(true) 113 | ->executes(function(){ 114 | throw new \Error(); 115 | }) 116 | ->throws(\Error::class); 117 | 118 | $object = $builder->getInstance(); 119 | 120 | $this->expectException(\Error::class); 121 | $this->assertNull($object->publicMethod(true)); 122 | } 123 | 124 | public function testExpectedException() { 125 | $builder = double::class(\mimus\tests\classes\Foo::class); 126 | 127 | $builder->rule("publicMethod") 128 | ->expects(true) 129 | ->executes(function(){ 130 | 131 | }) 132 | ->throws(\Error::class); 133 | 134 | $object = $builder->getInstance(); 135 | 136 | $this->expectException(\mimus\Exception::class); 137 | $this->assertNull($object->publicMethod(true)); 138 | } 139 | 140 | public function testReturnMissing() { 141 | $builder = double::class(\mimus\tests\classes\Foo::class); 142 | 143 | $builder->rule("publicMethod") 144 | ->expects(true) 145 | ->executes(function(){ 146 | 147 | }) 148 | ->returns(true); 149 | 150 | $object = $builder->getInstance(); 151 | 152 | $this->expectException(\mimus\Exception::class); 153 | $this->assertNull($object->publicMethod(true)); 154 | } 155 | 156 | public function testReturnUnexpected() { 157 | $builder = double::class(\mimus\tests\classes\Foo::class); 158 | $builder->rule("publicMethod") 159 | ->expects(true) 160 | ->executes(function(){ 161 | return true; 162 | }) 163 | ->void(); 164 | 165 | $object = $builder->getInstance(); 166 | 167 | $this->expectException(\mimus\Exception::class); 168 | $this->assertNull($object->publicMethod(true)); 169 | } 170 | 171 | public function testReturnTypeMismatch() { 172 | $builder = double::class(\mimus\tests\classes\Foo::class); 173 | 174 | $builder->rule("publicMethod") 175 | ->expects(true) 176 | ->executes(function(){ 177 | return "hello"; 178 | }) 179 | ->returns(true); 180 | 181 | $object = $builder->getInstance(); 182 | 183 | $this->expectException(\mimus\Exception::class); 184 | $this->assertNull($object->publicMethod(true)); 185 | } 186 | 187 | public function testReturnTypeWrongObject() { 188 | $builder = double::class(\mimus\tests\classes\Foo::class); 189 | 190 | $builder->rule("publicMethod") 191 | ->expects(true) 192 | ->executes(function(){ 193 | return new class{}; 194 | }) 195 | ->returns(\stdClass::class); 196 | 197 | $object = $builder->getInstance(); 198 | 199 | $this->expectException(\mimus\Exception::class); 200 | $this->assertNull($object->publicMethod(true)); 201 | } 202 | 203 | public function testReturnTypeCorrectObject() { 204 | $builder = double::class(\mimus\tests\classes\Foo::class); 205 | 206 | $builder->rule("publicMethod") 207 | ->expects(true) 208 | ->executes(function(){ 209 | return new \stdClass; 210 | }) 211 | ->returns(\stdClass::class); 212 | 213 | $object = $builder->getInstance(); 214 | 215 | $this->assertTrue($object->publicMethod(true) instanceof \stdClass); 216 | } 217 | 218 | public function testReturnMismatch() { 219 | $builder = double::class(\mimus\tests\classes\Foo::class); 220 | 221 | $builder->rule("publicMethod") 222 | ->expects(true) 223 | ->executes(function(){ 224 | return false; 225 | }) 226 | ->returns(true); 227 | 228 | $object = $builder->getInstance(); 229 | 230 | $this->expectException(\mimus\Exception::class); 231 | $this->assertNull($object->publicMethod(true)); 232 | } 233 | 234 | public function testExpectsAny() { 235 | $builder = double::class(\mimus\tests\classes\Foo::class); 236 | 237 | $builder->rule("publicMethod") 238 | ->expects() 239 | ->executes(function(){ 240 | return "mimus"; 241 | }) 242 | ->returns("mimus"); 243 | 244 | $object = $builder->getInstance(); 245 | 246 | $this->assertSame("mimus", $object->publicMethod(true)); 247 | } 248 | 249 | public function testExpectsAnyFallback() { 250 | $builder = double::class(\mimus\tests\classes\Foo::class); 251 | 252 | $builder->rule("publicMethod") 253 | ->expects("unused") 254 | ->executes(function(){ 255 | return "unused"; 256 | }); 257 | $builder->rule("publicMethod") 258 | ->expects() 259 | ->executes(function(){ 260 | return "mimus"; 261 | }) 262 | ->returns("mimus"); 263 | 264 | $object = $builder->getInstance(); 265 | 266 | $this->assertSame("mimus", $object->publicMethod(true)); 267 | } 268 | 269 | public function testLimitToOnce() { 270 | $builder = double::class(\mimus\tests\classes\Foo::class); 271 | 272 | $builder->rule("publicMethod") 273 | ->expects() 274 | ->executes(function(){ 275 | return true; 276 | }) 277 | ->once(); 278 | 279 | $object = $builder->getInstance(); 280 | 281 | $this->assertTrue($object->publicMethod(true)); 282 | $this->expectException(\mimus\Exception::class); 283 | $this->assertTrue($object->publicMethod(true)); 284 | } 285 | 286 | public function testLimitToNever() { 287 | $builder = double::class(\mimus\tests\classes\Foo::class); 288 | 289 | $builder->rule("publicMethod") 290 | ->expects() 291 | ->executes(function(){ 292 | return true; 293 | }) 294 | ->never(); 295 | 296 | $object = $builder->getInstance(); 297 | $this->expectException(\mimus\Exception::class); 298 | $this->assertNull($object->publicMethod(true)); 299 | 300 | } 301 | 302 | public function testLimitToN() { 303 | $builder = double::class(\mimus\tests\classes\Foo::class); 304 | 305 | $builder->rule("publicMethod") 306 | ->expects() 307 | ->executes(function(){ 308 | return true; 309 | }) 310 | ->limit(2); 311 | 312 | $object = $builder->getInstance(); 313 | 314 | $this->assertTrue($object->publicMethod(true)); 315 | $this->assertTrue($object->publicMethod(true)); 316 | 317 | $this->expectException(\mimus\Exception::class); 318 | 319 | $this->assertNull($object->publicMethod(true)); 320 | } 321 | 322 | public function testValidatorsFail() { 323 | $builder = double::class(\mimus\tests\classes\Foo::class); 324 | 325 | $builder->rule("publicMethod") 326 | ->expects() 327 | ->executes() 328 | ->validates(function($retval = null) : bool { 329 | return false; 330 | }); 331 | 332 | $object = $builder->getInstance(); 333 | 334 | $this->expectException(\mimus\Exception::class); 335 | $this->assertTrue($object->publicMethod(true)); 336 | } 337 | 338 | public function testValidatorsSuccess() { 339 | $builder = double::class(\mimus\tests\classes\Foo::class); 340 | 341 | $builder->rule("publicMethod") 342 | ->expects() 343 | ->returns(true) 344 | ->validates(function($retval = null) : bool { 345 | return true; 346 | }); 347 | 348 | $object = $builder->getInstance(); 349 | 350 | $this->assertTrue($object->publicMethod(true)); 351 | } 352 | 353 | public function testExecutesGetsPrototype() { 354 | $builder = double::class(\mimus\tests\classes\Foo::class); 355 | $count = 0; 356 | 357 | $builder->rule("publicAcceptAndReturnFoo") 358 | ->expects() 359 | ->executes(function(\Closure $prototype, ...$args) use(&$count) { 360 | $count++; 361 | 362 | return $prototype(...$args); 363 | }); 364 | 365 | $object = $builder->getInstance(); 366 | 367 | $this->assertInstanceOf( 368 | \mimus\tests\classes\Foo::class, 369 | $object->publicAcceptAndReturnFoo($object)); 370 | 371 | $this->assertSame(1, $count); 372 | } 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mimus 2 | ===== 3 | 4 | [![Build Status](https://travis-ci.org/krakjoe/mimus.svg?branch=master)](https://travis-ci.org/krakjoe/mimus) 5 | [![Coverage Status](https://coveralls.io/repos/github/krakjoe/mimus/badge.svg?branch=master)](https://coveralls.io/github/krakjoe/mimus?branch=master) 6 | 7 | Requirements 8 | ============ 9 | 10 | * PHP 7.2+ 11 | * [Componere](https://github.com/krakjoe/componere) 12 | 13 | Doubles 14 | ======= 15 | 16 | A test double is an object that takes the place of an object of a formal type while a system is under test: 17 | 18 | ```php 19 | getInstance(); 35 | ?> 36 | ``` 37 | 38 | At this time,```$object``` is ```instanceof Foo``` with the same interface as declaration ```Foo```, but none of it's methods do anything - they have been stubbed. 39 | 40 | It's important to note that while mimus supports a familiar pattern (```getInstance```) to allow injecting dependencies, __mimus has replaced the declaration of ```Foo``` internally__, so that subsequent calls to ```new Foo``` will create a test double, making the code above and the following code functionally equivalent: 41 | 42 | ```php 43 | commit(); /* would be committed on getInstance() or rule() */ 58 | 59 | $object = new Foo(); 60 | ?> 61 | ``` 62 | 63 | Given that ```Foo``` was already declared when ```double::class``` was called, this behaviour is impossible to achieve in userland PHP alone: This is the reason that mimus must depend on Componere, and is one of the main differences between mimus and any other mocking framwork for PHP. 64 | 65 | Stubs 66 | ===== 67 | 68 | To make the stubs do something, you must tell ```mimus``` what the method should, or will do: 69 | 70 | ```php 71 | rule("doesSomethingAndReturnsBool") 87 | ->expects() /* take any arguments */ 88 | ->returns(true); /* return true; */ 89 | 90 | $object = $builder->getInstance(); 91 | 92 | var_dump($object->doesSomethingAndReturnsBool()); // bool(true) 93 | ?> 94 | ``` 95 | 96 | In some cases, our method needs to return a different value for different input: 97 | 98 | ```php 99 | rule("doesSomethingAndReturnsBool") 115 | ->expects(true) /* takes these arguments */ 116 | ->returns(true); /* return true; */ 117 | $builder->rule("doesSomethingAndReturnsBool") 118 | ->expects(false) /* takes these arguments */ 119 | ->returns(false); /* return false; */ 120 | 121 | $object = $builder->getInstance(); 122 | 123 | var_dump($object->doesSomethingAndReturnsBool(true)); // bool(true) 124 | var_dump($object->doesSomethingAndReturnsBool(false)); // bool(false) 125 | ?> 126 | ``` 127 | 128 | At this time, we have defined two valid paths through the method based on the arguments given at runtime, should the method be invoked like this: 129 | 130 | ```php 131 | doesSomethingAndReturnsBool("mimus")); 133 | ``` 134 | 135 | mimus will raise ```\mimus\Exception``` for each rule that has been broken (2). 136 | 137 | Paths 138 | ===== 139 | 140 | A path may: 141 | 142 | * expect (or set) a return value (previous examples) 143 | * execute original implementation 144 | * execute different implementation 145 | * expect an exception 146 | * expect to be entered a maximum number of times (or never) 147 | 148 | Execute Original Implementation 149 | ------------------------------- 150 | 151 | Suppose we want to allow the original implementation to execute, and to ensure that the return value is as expected: 152 | 153 | ```php 154 | rule("doesSomethingAndReturnsBool") 170 | ->expects("yes") 171 | ->executes() // executes original 172 | ->returns(true); 173 | $builder->rule("doesSomethingAndReturnsBool") 174 | ->expects("no") 175 | ->executes() // executes original 176 | ->returns(false); 177 | 178 | $object = $builder->getInstance(); 179 | 180 | var_dump($object->doesSomethingAndReturnsBool("yes")); // bool(true) 181 | var_dump($object->doesSomethingAndReturnsBool("no")); 182 | ?> 183 | ``` 184 | 185 | While the first call will succeed, the second will raise ```\mimus\Exception: return value expected to be bool(false), got bool(true)```. 186 | 187 | 188 | Execute Different Implementation 189 | -------------------------------- 190 | 191 | Suppose we want to execute a different implementation in place of the original: 192 | 193 | ```php 194 | rule("doesSomethingAndReturnsBool") 210 | ->expects("yes") 211 | ->executes() // executes original code 212 | ->returns(true); 213 | $builder->rule("doesSomethingAndReturnsBool") 214 | ->expects("no") 215 | ->executes(function(){ 216 | return false; 217 | }); // no need for returns() 218 | 219 | $object = $builder->getInstance(); 220 | 221 | var_dump($object->doesSomethingAndReturnsBool("yes")); // bool(true) 222 | var_dump($object->doesSomethingAndReturnsBool("no")); // bool(false) 223 | ?> 224 | ``` 225 | 226 | While the first call will invoke the original implementation, the second will invoke the given implementation. 227 | 228 | Exceptions 229 | ---------- 230 | 231 | Suppose we want to verify that a Path throws an exception: 232 | 233 | ```php 234 | rule("doesSomethingAndReturnsBool") 252 | ->expects(true) 253 | ->executes() 254 | ->throws(Exception::class); 255 | $builder->rule("doesSomethingAndReturnsBool") 256 | ->expects(false) 257 | ->executes() 258 | ->throws(Exception::class); 259 | 260 | $object = $builder->getInstance(); 261 | 262 | try { 263 | $object->doesSomethingAndReturnsBool(true); 264 | } catch (Exception $ex) { 265 | 266 | } 267 | 268 | $object->doesSomethingAndReturnsBool(false); 269 | ?> 270 | ``` 271 | 272 | While the first call will succeed and the resulting exception caught, the second will raise (uncaught): ```mimus\Exception: expected exception of type Exception, nothing thrown```. 273 | 274 | Limits 275 | ------ 276 | 277 | Suppose we want to limit the number of times a method is entered: 278 | 279 | ```php 280 | rule("doesSomethingAndReturnsBool") 296 | ->expects(true) 297 | ->returns(true) 298 | ->once(); // limit() and never() also available 299 | 300 | $object = $builder->getInstance(); 301 | 302 | var_dump($object->doesSomethingAndReturnsBool(true)); // bool(true) 303 | var_dump($object->doesSomethingAndReturnsBool(true)); 304 | ?> 305 | ``` 306 | 307 | While the first call will succeed, the second will raise: ```mimus\Exception: limit of 1 exceeded```. 308 | 309 | Partial Mocks 310 | ============= 311 | 312 | Partial mocks are used, for example, to allow an object of a mocked type to execute an interface as implemented: 313 | 314 | ```php 315 | partialize([ 337 | "interfaceMethod" 338 | ]); 339 | $builder->rule("nonInterfaceMethod") 340 | ->expects() 341 | ->never(); 342 | 343 | $object = $builder->getInstance(); 344 | 345 | var_dump($object->interfaceMethod()); // bool(true) 346 | var_dump($object->nonInterfaceMethod()); 347 | ``` 348 | 349 | While the first call will be executed as implemented, the second will raise ```mimus\Exception: limit of 1 exceeded```. 350 | 351 | ```double::partialize``` also accepts the name of a valid class, the call above could be written: 352 | 353 | ```php 354 | /* ... */ 355 | $builder->partialize(IFace::class); 356 | /* ... */ 357 | ``` 358 | 359 | Interfaces 360 | ========== 361 | 362 | It is sometimes useful to mock an interface without an implementation, we can use a test double for this: 363 | 364 | ```php 365 | rule("publicMethod") 381 | ->expects() 382 | ->executes(function(){ 383 | return true; 384 | }); 385 | 386 | $object = $builder->getInstance(); 387 | 388 | var_dump($object->publicMethod()); // bool(true) 389 | ``` 390 | 391 | The ```$object``` will be ```instanceof IFace``` with the name ```myinterfaces```. 392 | 393 | The method ```Double::implements``` can be used to add an interface to a double after construction. 394 | 395 | Traits 396 | ====== 397 | 398 | Traits are treated like copy-pastable units of code by the compiler; When there is a ```use``` in a class declaration 399 | the interface of the trait is pasted into the current declaration such that the declarations inline will overwrite the 400 | declarations in the trait. 401 | 402 | For mocks, we wants to use traits a little differently: We want to paste on top of the class declaration so that the trait 403 | becomes the source of truth for implementations. 404 | 405 | ```php 406 | use(FooDoubleMethods::class); 427 | 428 | $builder->rule("doesSomethingAndReturnsBool") 429 | ->expects() 430 | ->executes(); 431 | 432 | $object = $builder->getInstance(); 433 | 434 | var_dump($object->doesSomethingAndReturnsBool()); // bool(false) 435 | ?> 436 | ``` 437 | 438 | *Note that ```use``` does not imply that the double should be partialized.* 439 | 440 | Life Cycle of a Double 441 | ====================== 442 | 443 | The named constructors ```Double::class``` and ```Double::make``` will try to return a cached double based on the ```$name``` passed to the constructor, they may optionally ```$reset``` the double as they retrieve it. 444 | 445 | From the first call to ```Double::getInstance``` or ```Double::rule``` the class exists in the engine with exactly the ```$name``` given; Certain actions such as implementing interfaces and using traits are no longer possible and must be performed previously to these calls taking place. 446 | 447 | The class remains present until it is explicitly removed with ```Double::unlink```: When a double is removed any class which it replaced is restored to it's original implementation. 448 | 449 | API 450 | === 451 | 452 | ```php 453 | =5.5" 194 | }, 195 | "require-dev": { 196 | "symfony/phpunit-bridge": "^4.4 || ^5.1" 197 | }, 198 | "type": "library", 199 | "extra": { 200 | "branch-alias": { 201 | "dev-master": "1.4-dev" 202 | } 203 | }, 204 | "autoload": { 205 | "psr-4": { 206 | "GuzzleHttp\\Promise\\": "src/" 207 | }, 208 | "files": [ 209 | "src/functions_include.php" 210 | ] 211 | }, 212 | "notification-url": "https://packagist.org/downloads/", 213 | "license": [ 214 | "MIT" 215 | ], 216 | "authors": [ 217 | { 218 | "name": "Michael Dowling", 219 | "email": "mtdowling@gmail.com", 220 | "homepage": "https://github.com/mtdowling" 221 | } 222 | ], 223 | "description": "Guzzle promises library", 224 | "keywords": [ 225 | "promise" 226 | ], 227 | "time": "2020-09-30T07:37:28+00:00" 228 | }, 229 | { 230 | "name": "guzzlehttp/psr7", 231 | "version": "1.7.0", 232 | "source": { 233 | "type": "git", 234 | "url": "https://github.com/guzzle/psr7.git", 235 | "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" 236 | }, 237 | "dist": { 238 | "type": "zip", 239 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", 240 | "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", 241 | "shasum": "" 242 | }, 243 | "require": { 244 | "php": ">=5.4.0", 245 | "psr/http-message": "~1.0", 246 | "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" 247 | }, 248 | "provide": { 249 | "psr/http-message-implementation": "1.0" 250 | }, 251 | "require-dev": { 252 | "ext-zlib": "*", 253 | "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" 254 | }, 255 | "suggest": { 256 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" 257 | }, 258 | "type": "library", 259 | "extra": { 260 | "branch-alias": { 261 | "dev-master": "1.7-dev" 262 | } 263 | }, 264 | "autoload": { 265 | "psr-4": { 266 | "GuzzleHttp\\Psr7\\": "src/" 267 | }, 268 | "files": [ 269 | "src/functions_include.php" 270 | ] 271 | }, 272 | "notification-url": "https://packagist.org/downloads/", 273 | "license": [ 274 | "MIT" 275 | ], 276 | "authors": [ 277 | { 278 | "name": "Michael Dowling", 279 | "email": "mtdowling@gmail.com", 280 | "homepage": "https://github.com/mtdowling" 281 | }, 282 | { 283 | "name": "Tobias Schultze", 284 | "homepage": "https://github.com/Tobion" 285 | } 286 | ], 287 | "description": "PSR-7 message implementation that also provides common utility methods", 288 | "keywords": [ 289 | "http", 290 | "message", 291 | "psr-7", 292 | "request", 293 | "response", 294 | "stream", 295 | "uri", 296 | "url" 297 | ], 298 | "time": "2020-09-30T07:37:11+00:00" 299 | }, 300 | { 301 | "name": "myclabs/deep-copy", 302 | "version": "1.10.1", 303 | "source": { 304 | "type": "git", 305 | "url": "https://github.com/myclabs/DeepCopy.git", 306 | "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" 307 | }, 308 | "dist": { 309 | "type": "zip", 310 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", 311 | "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", 312 | "shasum": "" 313 | }, 314 | "require": { 315 | "php": "^7.1 || ^8.0" 316 | }, 317 | "replace": { 318 | "myclabs/deep-copy": "self.version" 319 | }, 320 | "require-dev": { 321 | "doctrine/collections": "^1.0", 322 | "doctrine/common": "^2.6", 323 | "phpunit/phpunit": "^7.1" 324 | }, 325 | "type": "library", 326 | "autoload": { 327 | "psr-4": { 328 | "DeepCopy\\": "src/DeepCopy/" 329 | }, 330 | "files": [ 331 | "src/DeepCopy/deep_copy.php" 332 | ] 333 | }, 334 | "notification-url": "https://packagist.org/downloads/", 335 | "license": [ 336 | "MIT" 337 | ], 338 | "description": "Create deep copies (clones) of your objects", 339 | "keywords": [ 340 | "clone", 341 | "copy", 342 | "duplicate", 343 | "object", 344 | "object graph" 345 | ], 346 | "funding": [ 347 | { 348 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 349 | "type": "tidelift" 350 | } 351 | ], 352 | "time": "2020-06-29T13:22:24+00:00" 353 | }, 354 | { 355 | "name": "nikic/php-parser", 356 | "version": "v4.10.2", 357 | "source": { 358 | "type": "git", 359 | "url": "https://github.com/nikic/PHP-Parser.git", 360 | "reference": "658f1be311a230e0907f5dfe0213742aff0596de" 361 | }, 362 | "dist": { 363 | "type": "zip", 364 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", 365 | "reference": "658f1be311a230e0907f5dfe0213742aff0596de", 366 | "shasum": "" 367 | }, 368 | "require": { 369 | "ext-tokenizer": "*", 370 | "php": ">=7.0" 371 | }, 372 | "require-dev": { 373 | "ircmaxell/php-yacc": "^0.0.7", 374 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" 375 | }, 376 | "bin": [ 377 | "bin/php-parse" 378 | ], 379 | "type": "library", 380 | "extra": { 381 | "branch-alias": { 382 | "dev-master": "4.9-dev" 383 | } 384 | }, 385 | "autoload": { 386 | "psr-4": { 387 | "PhpParser\\": "lib/PhpParser" 388 | } 389 | }, 390 | "notification-url": "https://packagist.org/downloads/", 391 | "license": [ 392 | "BSD-3-Clause" 393 | ], 394 | "authors": [ 395 | { 396 | "name": "Nikita Popov" 397 | } 398 | ], 399 | "description": "A PHP parser written in PHP", 400 | "keywords": [ 401 | "parser", 402 | "php" 403 | ], 404 | "time": "2020-09-26T10:30:38+00:00" 405 | }, 406 | { 407 | "name": "phar-io/manifest", 408 | "version": "2.0.1", 409 | "source": { 410 | "type": "git", 411 | "url": "https://github.com/phar-io/manifest.git", 412 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" 413 | }, 414 | "dist": { 415 | "type": "zip", 416 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", 417 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", 418 | "shasum": "" 419 | }, 420 | "require": { 421 | "ext-dom": "*", 422 | "ext-phar": "*", 423 | "ext-xmlwriter": "*", 424 | "phar-io/version": "^3.0.1", 425 | "php": "^7.2 || ^8.0" 426 | }, 427 | "type": "library", 428 | "extra": { 429 | "branch-alias": { 430 | "dev-master": "2.0.x-dev" 431 | } 432 | }, 433 | "autoload": { 434 | "classmap": [ 435 | "src/" 436 | ] 437 | }, 438 | "notification-url": "https://packagist.org/downloads/", 439 | "license": [ 440 | "BSD-3-Clause" 441 | ], 442 | "authors": [ 443 | { 444 | "name": "Arne Blankerts", 445 | "email": "arne@blankerts.de", 446 | "role": "Developer" 447 | }, 448 | { 449 | "name": "Sebastian Heuer", 450 | "email": "sebastian@phpeople.de", 451 | "role": "Developer" 452 | }, 453 | { 454 | "name": "Sebastian Bergmann", 455 | "email": "sebastian@phpunit.de", 456 | "role": "Developer" 457 | } 458 | ], 459 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 460 | "time": "2020-06-27T14:33:11+00:00" 461 | }, 462 | { 463 | "name": "phar-io/version", 464 | "version": "3.0.2", 465 | "source": { 466 | "type": "git", 467 | "url": "https://github.com/phar-io/version.git", 468 | "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" 469 | }, 470 | "dist": { 471 | "type": "zip", 472 | "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", 473 | "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", 474 | "shasum": "" 475 | }, 476 | "require": { 477 | "php": "^7.2 || ^8.0" 478 | }, 479 | "type": "library", 480 | "autoload": { 481 | "classmap": [ 482 | "src/" 483 | ] 484 | }, 485 | "notification-url": "https://packagist.org/downloads/", 486 | "license": [ 487 | "BSD-3-Clause" 488 | ], 489 | "authors": [ 490 | { 491 | "name": "Arne Blankerts", 492 | "email": "arne@blankerts.de", 493 | "role": "Developer" 494 | }, 495 | { 496 | "name": "Sebastian Heuer", 497 | "email": "sebastian@phpeople.de", 498 | "role": "Developer" 499 | }, 500 | { 501 | "name": "Sebastian Bergmann", 502 | "email": "sebastian@phpunit.de", 503 | "role": "Developer" 504 | } 505 | ], 506 | "description": "Library for handling version information and constraints", 507 | "time": "2020-06-27T14:39:04+00:00" 508 | }, 509 | { 510 | "name": "php-coveralls/php-coveralls", 511 | "version": "v2.4.1", 512 | "source": { 513 | "type": "git", 514 | "url": "https://github.com/php-coveralls/php-coveralls.git", 515 | "reference": "c3f682e7cd50191ce0a9c396bc4dee8cbcf05383" 516 | }, 517 | "dist": { 518 | "type": "zip", 519 | "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/c3f682e7cd50191ce0a9c396bc4dee8cbcf05383", 520 | "reference": "c3f682e7cd50191ce0a9c396bc4dee8cbcf05383", 521 | "shasum": "" 522 | }, 523 | "require": { 524 | "ext-json": "*", 525 | "ext-simplexml": "*", 526 | "guzzlehttp/guzzle": "^6.0 || ^7.0", 527 | "php": "^5.5 || ^7.0 || ^8.0", 528 | "psr/log": "^1.0", 529 | "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0", 530 | "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0", 531 | "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0", 532 | "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0" 533 | }, 534 | "require-dev": { 535 | "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || ^8.0 || ^9.0", 536 | "sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0" 537 | }, 538 | "suggest": { 539 | "symfony/http-kernel": "Allows Symfony integration" 540 | }, 541 | "bin": [ 542 | "bin/php-coveralls" 543 | ], 544 | "type": "library", 545 | "autoload": { 546 | "psr-4": { 547 | "PhpCoveralls\\": "src/" 548 | } 549 | }, 550 | "notification-url": "https://packagist.org/downloads/", 551 | "license": [ 552 | "MIT" 553 | ], 554 | "authors": [ 555 | { 556 | "name": "Kitamura Satoshi", 557 | "email": "with.no.parachute@gmail.com", 558 | "homepage": "https://www.facebook.com/satooshi.jp", 559 | "role": "Original creator" 560 | }, 561 | { 562 | "name": "Takashi Matsuo", 563 | "email": "tmatsuo@google.com" 564 | }, 565 | { 566 | "name": "Google Inc" 567 | }, 568 | { 569 | "name": "Dariusz Ruminski", 570 | "email": "dariusz.ruminski@gmail.com", 571 | "homepage": "https://github.com/keradus" 572 | }, 573 | { 574 | "name": "Contributors", 575 | "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors" 576 | } 577 | ], 578 | "description": "PHP client library for Coveralls API", 579 | "homepage": "https://github.com/php-coveralls/php-coveralls", 580 | "keywords": [ 581 | "ci", 582 | "coverage", 583 | "github", 584 | "test" 585 | ], 586 | "time": "2020-10-05T23:08:28+00:00" 587 | }, 588 | { 589 | "name": "phpdocumentor/reflection-common", 590 | "version": "2.2.0", 591 | "source": { 592 | "type": "git", 593 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 594 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" 595 | }, 596 | "dist": { 597 | "type": "zip", 598 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", 599 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", 600 | "shasum": "" 601 | }, 602 | "require": { 603 | "php": "^7.2 || ^8.0" 604 | }, 605 | "type": "library", 606 | "extra": { 607 | "branch-alias": { 608 | "dev-2.x": "2.x-dev" 609 | } 610 | }, 611 | "autoload": { 612 | "psr-4": { 613 | "phpDocumentor\\Reflection\\": "src/" 614 | } 615 | }, 616 | "notification-url": "https://packagist.org/downloads/", 617 | "license": [ 618 | "MIT" 619 | ], 620 | "authors": [ 621 | { 622 | "name": "Jaap van Otterdijk", 623 | "email": "opensource@ijaap.nl" 624 | } 625 | ], 626 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 627 | "homepage": "http://www.phpdoc.org", 628 | "keywords": [ 629 | "FQSEN", 630 | "phpDocumentor", 631 | "phpdoc", 632 | "reflection", 633 | "static analysis" 634 | ], 635 | "time": "2020-06-27T09:03:43+00:00" 636 | }, 637 | { 638 | "name": "phpdocumentor/reflection-docblock", 639 | "version": "5.2.2", 640 | "source": { 641 | "type": "git", 642 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 643 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" 644 | }, 645 | "dist": { 646 | "type": "zip", 647 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", 648 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", 649 | "shasum": "" 650 | }, 651 | "require": { 652 | "ext-filter": "*", 653 | "php": "^7.2 || ^8.0", 654 | "phpdocumentor/reflection-common": "^2.2", 655 | "phpdocumentor/type-resolver": "^1.3", 656 | "webmozart/assert": "^1.9.1" 657 | }, 658 | "require-dev": { 659 | "mockery/mockery": "~1.3.2" 660 | }, 661 | "type": "library", 662 | "extra": { 663 | "branch-alias": { 664 | "dev-master": "5.x-dev" 665 | } 666 | }, 667 | "autoload": { 668 | "psr-4": { 669 | "phpDocumentor\\Reflection\\": "src" 670 | } 671 | }, 672 | "notification-url": "https://packagist.org/downloads/", 673 | "license": [ 674 | "MIT" 675 | ], 676 | "authors": [ 677 | { 678 | "name": "Mike van Riel", 679 | "email": "me@mikevanriel.com" 680 | }, 681 | { 682 | "name": "Jaap van Otterdijk", 683 | "email": "account@ijaap.nl" 684 | } 685 | ], 686 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 687 | "time": "2020-09-03T19:13:55+00:00" 688 | }, 689 | { 690 | "name": "phpdocumentor/type-resolver", 691 | "version": "1.4.0", 692 | "source": { 693 | "type": "git", 694 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 695 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" 696 | }, 697 | "dist": { 698 | "type": "zip", 699 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 700 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 701 | "shasum": "" 702 | }, 703 | "require": { 704 | "php": "^7.2 || ^8.0", 705 | "phpdocumentor/reflection-common": "^2.0" 706 | }, 707 | "require-dev": { 708 | "ext-tokenizer": "*" 709 | }, 710 | "type": "library", 711 | "extra": { 712 | "branch-alias": { 713 | "dev-1.x": "1.x-dev" 714 | } 715 | }, 716 | "autoload": { 717 | "psr-4": { 718 | "phpDocumentor\\Reflection\\": "src" 719 | } 720 | }, 721 | "notification-url": "https://packagist.org/downloads/", 722 | "license": [ 723 | "MIT" 724 | ], 725 | "authors": [ 726 | { 727 | "name": "Mike van Riel", 728 | "email": "me@mikevanriel.com" 729 | } 730 | ], 731 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", 732 | "time": "2020-09-17T18:55:26+00:00" 733 | }, 734 | { 735 | "name": "phpspec/prophecy", 736 | "version": "1.12.1", 737 | "source": { 738 | "type": "git", 739 | "url": "https://github.com/phpspec/prophecy.git", 740 | "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" 741 | }, 742 | "dist": { 743 | "type": "zip", 744 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", 745 | "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", 746 | "shasum": "" 747 | }, 748 | "require": { 749 | "doctrine/instantiator": "^1.2", 750 | "php": "^7.2 || ~8.0, <8.1", 751 | "phpdocumentor/reflection-docblock": "^5.2", 752 | "sebastian/comparator": "^3.0 || ^4.0", 753 | "sebastian/recursion-context": "^3.0 || ^4.0" 754 | }, 755 | "require-dev": { 756 | "phpspec/phpspec": "^6.0", 757 | "phpunit/phpunit": "^8.0 || ^9.0 <9.3" 758 | }, 759 | "type": "library", 760 | "extra": { 761 | "branch-alias": { 762 | "dev-master": "1.11.x-dev" 763 | } 764 | }, 765 | "autoload": { 766 | "psr-4": { 767 | "Prophecy\\": "src/Prophecy" 768 | } 769 | }, 770 | "notification-url": "https://packagist.org/downloads/", 771 | "license": [ 772 | "MIT" 773 | ], 774 | "authors": [ 775 | { 776 | "name": "Konstantin Kudryashov", 777 | "email": "ever.zet@gmail.com", 778 | "homepage": "http://everzet.com" 779 | }, 780 | { 781 | "name": "Marcello Duarte", 782 | "email": "marcello.duarte@gmail.com" 783 | } 784 | ], 785 | "description": "Highly opinionated mocking framework for PHP 5.3+", 786 | "homepage": "https://github.com/phpspec/prophecy", 787 | "keywords": [ 788 | "Double", 789 | "Dummy", 790 | "fake", 791 | "mock", 792 | "spy", 793 | "stub" 794 | ], 795 | "time": "2020-09-29T09:10:42+00:00" 796 | }, 797 | { 798 | "name": "phpunit/php-code-coverage", 799 | "version": "9.2.0", 800 | "source": { 801 | "type": "git", 802 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 803 | "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972" 804 | }, 805 | "dist": { 806 | "type": "zip", 807 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/53a4b737e83be724efd2bc4e7b929b9a30c48972", 808 | "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972", 809 | "shasum": "" 810 | }, 811 | "require": { 812 | "ext-dom": "*", 813 | "ext-libxml": "*", 814 | "ext-xmlwriter": "*", 815 | "nikic/php-parser": "^4.8", 816 | "php": ">=7.3", 817 | "phpunit/php-file-iterator": "^3.0.3", 818 | "phpunit/php-text-template": "^2.0.2", 819 | "sebastian/code-unit-reverse-lookup": "^2.0.2", 820 | "sebastian/complexity": "^2.0", 821 | "sebastian/environment": "^5.1.2", 822 | "sebastian/lines-of-code": "^1.0", 823 | "sebastian/version": "^3.0.1", 824 | "theseer/tokenizer": "^1.2.0" 825 | }, 826 | "require-dev": { 827 | "phpunit/phpunit": "^9.3" 828 | }, 829 | "suggest": { 830 | "ext-pcov": "*", 831 | "ext-xdebug": "*" 832 | }, 833 | "type": "library", 834 | "extra": { 835 | "branch-alias": { 836 | "dev-master": "9.2-dev" 837 | } 838 | }, 839 | "autoload": { 840 | "classmap": [ 841 | "src/" 842 | ] 843 | }, 844 | "notification-url": "https://packagist.org/downloads/", 845 | "license": [ 846 | "BSD-3-Clause" 847 | ], 848 | "authors": [ 849 | { 850 | "name": "Sebastian Bergmann", 851 | "email": "sebastian@phpunit.de", 852 | "role": "lead" 853 | } 854 | ], 855 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 856 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 857 | "keywords": [ 858 | "coverage", 859 | "testing", 860 | "xunit" 861 | ], 862 | "funding": [ 863 | { 864 | "url": "https://github.com/sebastianbergmann", 865 | "type": "github" 866 | } 867 | ], 868 | "time": "2020-10-02T03:37:32+00:00" 869 | }, 870 | { 871 | "name": "phpunit/php-file-iterator", 872 | "version": "3.0.5", 873 | "source": { 874 | "type": "git", 875 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 876 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" 877 | }, 878 | "dist": { 879 | "type": "zip", 880 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", 881 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", 882 | "shasum": "" 883 | }, 884 | "require": { 885 | "php": ">=7.3" 886 | }, 887 | "require-dev": { 888 | "phpunit/phpunit": "^9.3" 889 | }, 890 | "type": "library", 891 | "extra": { 892 | "branch-alias": { 893 | "dev-master": "3.0-dev" 894 | } 895 | }, 896 | "autoload": { 897 | "classmap": [ 898 | "src/" 899 | ] 900 | }, 901 | "notification-url": "https://packagist.org/downloads/", 902 | "license": [ 903 | "BSD-3-Clause" 904 | ], 905 | "authors": [ 906 | { 907 | "name": "Sebastian Bergmann", 908 | "email": "sebastian@phpunit.de", 909 | "role": "lead" 910 | } 911 | ], 912 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 913 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 914 | "keywords": [ 915 | "filesystem", 916 | "iterator" 917 | ], 918 | "funding": [ 919 | { 920 | "url": "https://github.com/sebastianbergmann", 921 | "type": "github" 922 | } 923 | ], 924 | "time": "2020-09-28T05:57:25+00:00" 925 | }, 926 | { 927 | "name": "phpunit/php-invoker", 928 | "version": "3.1.1", 929 | "source": { 930 | "type": "git", 931 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 932 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" 933 | }, 934 | "dist": { 935 | "type": "zip", 936 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 937 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 938 | "shasum": "" 939 | }, 940 | "require": { 941 | "php": ">=7.3" 942 | }, 943 | "require-dev": { 944 | "ext-pcntl": "*", 945 | "phpunit/phpunit": "^9.3" 946 | }, 947 | "suggest": { 948 | "ext-pcntl": "*" 949 | }, 950 | "type": "library", 951 | "extra": { 952 | "branch-alias": { 953 | "dev-master": "3.1-dev" 954 | } 955 | }, 956 | "autoload": { 957 | "classmap": [ 958 | "src/" 959 | ] 960 | }, 961 | "notification-url": "https://packagist.org/downloads/", 962 | "license": [ 963 | "BSD-3-Clause" 964 | ], 965 | "authors": [ 966 | { 967 | "name": "Sebastian Bergmann", 968 | "email": "sebastian@phpunit.de", 969 | "role": "lead" 970 | } 971 | ], 972 | "description": "Invoke callables with a timeout", 973 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 974 | "keywords": [ 975 | "process" 976 | ], 977 | "funding": [ 978 | { 979 | "url": "https://github.com/sebastianbergmann", 980 | "type": "github" 981 | } 982 | ], 983 | "time": "2020-09-28T05:58:55+00:00" 984 | }, 985 | { 986 | "name": "phpunit/php-text-template", 987 | "version": "2.0.3", 988 | "source": { 989 | "type": "git", 990 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 991 | "reference": "18c887016e60e52477e54534956d7b47bc52cd84" 992 | }, 993 | "dist": { 994 | "type": "zip", 995 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/18c887016e60e52477e54534956d7b47bc52cd84", 996 | "reference": "18c887016e60e52477e54534956d7b47bc52cd84", 997 | "shasum": "" 998 | }, 999 | "require": { 1000 | "php": ">=7.3" 1001 | }, 1002 | "require-dev": { 1003 | "phpunit/phpunit": "^9.3" 1004 | }, 1005 | "type": "library", 1006 | "extra": { 1007 | "branch-alias": { 1008 | "dev-master": "2.0-dev" 1009 | } 1010 | }, 1011 | "autoload": { 1012 | "classmap": [ 1013 | "src/" 1014 | ] 1015 | }, 1016 | "notification-url": "https://packagist.org/downloads/", 1017 | "license": [ 1018 | "BSD-3-Clause" 1019 | ], 1020 | "authors": [ 1021 | { 1022 | "name": "Sebastian Bergmann", 1023 | "email": "sebastian@phpunit.de", 1024 | "role": "lead" 1025 | } 1026 | ], 1027 | "description": "Simple template engine.", 1028 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1029 | "keywords": [ 1030 | "template" 1031 | ], 1032 | "funding": [ 1033 | { 1034 | "url": "https://github.com/sebastianbergmann", 1035 | "type": "github" 1036 | } 1037 | ], 1038 | "time": "2020-09-28T06:03:05+00:00" 1039 | }, 1040 | { 1041 | "name": "phpunit/php-timer", 1042 | "version": "5.0.2", 1043 | "source": { 1044 | "type": "git", 1045 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1046 | "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7" 1047 | }, 1048 | "dist": { 1049 | "type": "zip", 1050 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/c9ff14f493699e2f6adee9fd06a0245b276643b7", 1051 | "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7", 1052 | "shasum": "" 1053 | }, 1054 | "require": { 1055 | "php": ">=7.3" 1056 | }, 1057 | "require-dev": { 1058 | "phpunit/phpunit": "^9.3" 1059 | }, 1060 | "type": "library", 1061 | "extra": { 1062 | "branch-alias": { 1063 | "dev-master": "5.0-dev" 1064 | } 1065 | }, 1066 | "autoload": { 1067 | "classmap": [ 1068 | "src/" 1069 | ] 1070 | }, 1071 | "notification-url": "https://packagist.org/downloads/", 1072 | "license": [ 1073 | "BSD-3-Clause" 1074 | ], 1075 | "authors": [ 1076 | { 1077 | "name": "Sebastian Bergmann", 1078 | "email": "sebastian@phpunit.de", 1079 | "role": "lead" 1080 | } 1081 | ], 1082 | "description": "Utility class for timing", 1083 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1084 | "keywords": [ 1085 | "timer" 1086 | ], 1087 | "funding": [ 1088 | { 1089 | "url": "https://github.com/sebastianbergmann", 1090 | "type": "github" 1091 | } 1092 | ], 1093 | "time": "2020-09-28T06:00:25+00:00" 1094 | }, 1095 | { 1096 | "name": "phpunit/phpunit", 1097 | "version": "9.4.1", 1098 | "source": { 1099 | "type": "git", 1100 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1101 | "reference": "1f09a12726593737e8a228ebb1c8647305d07c41" 1102 | }, 1103 | "dist": { 1104 | "type": "zip", 1105 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1f09a12726593737e8a228ebb1c8647305d07c41", 1106 | "reference": "1f09a12726593737e8a228ebb1c8647305d07c41", 1107 | "shasum": "" 1108 | }, 1109 | "require": { 1110 | "doctrine/instantiator": "^1.3.1", 1111 | "ext-dom": "*", 1112 | "ext-json": "*", 1113 | "ext-libxml": "*", 1114 | "ext-mbstring": "*", 1115 | "ext-xml": "*", 1116 | "ext-xmlwriter": "*", 1117 | "myclabs/deep-copy": "^1.10.1", 1118 | "phar-io/manifest": "^2.0.1", 1119 | "phar-io/version": "^3.0.2", 1120 | "php": ">=7.3", 1121 | "phpspec/prophecy": "^1.12.1", 1122 | "phpunit/php-code-coverage": "^9.2", 1123 | "phpunit/php-file-iterator": "^3.0.5", 1124 | "phpunit/php-invoker": "^3.1.1", 1125 | "phpunit/php-text-template": "^2.0.3", 1126 | "phpunit/php-timer": "^5.0.2", 1127 | "sebastian/cli-parser": "^1.0.1", 1128 | "sebastian/code-unit": "^1.0.6", 1129 | "sebastian/comparator": "^4.0.5", 1130 | "sebastian/diff": "^4.0.3", 1131 | "sebastian/environment": "^5.1.3", 1132 | "sebastian/exporter": "^4.0.3", 1133 | "sebastian/global-state": "^5.0.1", 1134 | "sebastian/object-enumerator": "^4.0.3", 1135 | "sebastian/resource-operations": "^3.0.3", 1136 | "sebastian/type": "^2.3", 1137 | "sebastian/version": "^3.0.2" 1138 | }, 1139 | "require-dev": { 1140 | "ext-pdo": "*", 1141 | "phpspec/prophecy-phpunit": "^2.0.1" 1142 | }, 1143 | "suggest": { 1144 | "ext-soap": "*", 1145 | "ext-xdebug": "*" 1146 | }, 1147 | "bin": [ 1148 | "phpunit" 1149 | ], 1150 | "type": "library", 1151 | "extra": { 1152 | "branch-alias": { 1153 | "dev-master": "9.4-dev" 1154 | } 1155 | }, 1156 | "autoload": { 1157 | "classmap": [ 1158 | "src/" 1159 | ], 1160 | "files": [ 1161 | "src/Framework/Assert/Functions.php" 1162 | ] 1163 | }, 1164 | "notification-url": "https://packagist.org/downloads/", 1165 | "license": [ 1166 | "BSD-3-Clause" 1167 | ], 1168 | "authors": [ 1169 | { 1170 | "name": "Sebastian Bergmann", 1171 | "email": "sebastian@phpunit.de", 1172 | "role": "lead" 1173 | } 1174 | ], 1175 | "description": "The PHP Unit Testing framework.", 1176 | "homepage": "https://phpunit.de/", 1177 | "keywords": [ 1178 | "phpunit", 1179 | "testing", 1180 | "xunit" 1181 | ], 1182 | "funding": [ 1183 | { 1184 | "url": "https://phpunit.de/donate.html", 1185 | "type": "custom" 1186 | }, 1187 | { 1188 | "url": "https://github.com/sebastianbergmann", 1189 | "type": "github" 1190 | } 1191 | ], 1192 | "time": "2020-10-11T07:41:19+00:00" 1193 | }, 1194 | { 1195 | "name": "psr/container", 1196 | "version": "1.0.0", 1197 | "source": { 1198 | "type": "git", 1199 | "url": "https://github.com/php-fig/container.git", 1200 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 1201 | }, 1202 | "dist": { 1203 | "type": "zip", 1204 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1205 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1206 | "shasum": "" 1207 | }, 1208 | "require": { 1209 | "php": ">=5.3.0" 1210 | }, 1211 | "type": "library", 1212 | "extra": { 1213 | "branch-alias": { 1214 | "dev-master": "1.0.x-dev" 1215 | } 1216 | }, 1217 | "autoload": { 1218 | "psr-4": { 1219 | "Psr\\Container\\": "src/" 1220 | } 1221 | }, 1222 | "notification-url": "https://packagist.org/downloads/", 1223 | "license": [ 1224 | "MIT" 1225 | ], 1226 | "authors": [ 1227 | { 1228 | "name": "PHP-FIG", 1229 | "homepage": "http://www.php-fig.org/" 1230 | } 1231 | ], 1232 | "description": "Common Container Interface (PHP FIG PSR-11)", 1233 | "homepage": "https://github.com/php-fig/container", 1234 | "keywords": [ 1235 | "PSR-11", 1236 | "container", 1237 | "container-interface", 1238 | "container-interop", 1239 | "psr" 1240 | ], 1241 | "time": "2017-02-14T16:28:37+00:00" 1242 | }, 1243 | { 1244 | "name": "psr/http-client", 1245 | "version": "1.0.1", 1246 | "source": { 1247 | "type": "git", 1248 | "url": "https://github.com/php-fig/http-client.git", 1249 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" 1250 | }, 1251 | "dist": { 1252 | "type": "zip", 1253 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", 1254 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", 1255 | "shasum": "" 1256 | }, 1257 | "require": { 1258 | "php": "^7.0 || ^8.0", 1259 | "psr/http-message": "^1.0" 1260 | }, 1261 | "type": "library", 1262 | "extra": { 1263 | "branch-alias": { 1264 | "dev-master": "1.0.x-dev" 1265 | } 1266 | }, 1267 | "autoload": { 1268 | "psr-4": { 1269 | "Psr\\Http\\Client\\": "src/" 1270 | } 1271 | }, 1272 | "notification-url": "https://packagist.org/downloads/", 1273 | "license": [ 1274 | "MIT" 1275 | ], 1276 | "authors": [ 1277 | { 1278 | "name": "PHP-FIG", 1279 | "homepage": "http://www.php-fig.org/" 1280 | } 1281 | ], 1282 | "description": "Common interface for HTTP clients", 1283 | "homepage": "https://github.com/php-fig/http-client", 1284 | "keywords": [ 1285 | "http", 1286 | "http-client", 1287 | "psr", 1288 | "psr-18" 1289 | ], 1290 | "time": "2020-06-29T06:28:15+00:00" 1291 | }, 1292 | { 1293 | "name": "psr/http-message", 1294 | "version": "1.0.1", 1295 | "source": { 1296 | "type": "git", 1297 | "url": "https://github.com/php-fig/http-message.git", 1298 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 1299 | }, 1300 | "dist": { 1301 | "type": "zip", 1302 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 1303 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 1304 | "shasum": "" 1305 | }, 1306 | "require": { 1307 | "php": ">=5.3.0" 1308 | }, 1309 | "type": "library", 1310 | "extra": { 1311 | "branch-alias": { 1312 | "dev-master": "1.0.x-dev" 1313 | } 1314 | }, 1315 | "autoload": { 1316 | "psr-4": { 1317 | "Psr\\Http\\Message\\": "src/" 1318 | } 1319 | }, 1320 | "notification-url": "https://packagist.org/downloads/", 1321 | "license": [ 1322 | "MIT" 1323 | ], 1324 | "authors": [ 1325 | { 1326 | "name": "PHP-FIG", 1327 | "homepage": "http://www.php-fig.org/" 1328 | } 1329 | ], 1330 | "description": "Common interface for HTTP messages", 1331 | "homepage": "https://github.com/php-fig/http-message", 1332 | "keywords": [ 1333 | "http", 1334 | "http-message", 1335 | "psr", 1336 | "psr-7", 1337 | "request", 1338 | "response" 1339 | ], 1340 | "time": "2016-08-06T14:39:51+00:00" 1341 | }, 1342 | { 1343 | "name": "psr/log", 1344 | "version": "1.1.3", 1345 | "source": { 1346 | "type": "git", 1347 | "url": "https://github.com/php-fig/log.git", 1348 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" 1349 | }, 1350 | "dist": { 1351 | "type": "zip", 1352 | "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", 1353 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", 1354 | "shasum": "" 1355 | }, 1356 | "require": { 1357 | "php": ">=5.3.0" 1358 | }, 1359 | "type": "library", 1360 | "extra": { 1361 | "branch-alias": { 1362 | "dev-master": "1.1.x-dev" 1363 | } 1364 | }, 1365 | "autoload": { 1366 | "psr-4": { 1367 | "Psr\\Log\\": "Psr/Log/" 1368 | } 1369 | }, 1370 | "notification-url": "https://packagist.org/downloads/", 1371 | "license": [ 1372 | "MIT" 1373 | ], 1374 | "authors": [ 1375 | { 1376 | "name": "PHP-FIG", 1377 | "homepage": "http://www.php-fig.org/" 1378 | } 1379 | ], 1380 | "description": "Common interface for logging libraries", 1381 | "homepage": "https://github.com/php-fig/log", 1382 | "keywords": [ 1383 | "log", 1384 | "psr", 1385 | "psr-3" 1386 | ], 1387 | "time": "2020-03-23T09:12:05+00:00" 1388 | }, 1389 | { 1390 | "name": "ralouphie/getallheaders", 1391 | "version": "3.0.3", 1392 | "source": { 1393 | "type": "git", 1394 | "url": "https://github.com/ralouphie/getallheaders.git", 1395 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 1396 | }, 1397 | "dist": { 1398 | "type": "zip", 1399 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 1400 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 1401 | "shasum": "" 1402 | }, 1403 | "require": { 1404 | "php": ">=5.6" 1405 | }, 1406 | "require-dev": { 1407 | "php-coveralls/php-coveralls": "^2.1", 1408 | "phpunit/phpunit": "^5 || ^6.5" 1409 | }, 1410 | "type": "library", 1411 | "autoload": { 1412 | "files": [ 1413 | "src/getallheaders.php" 1414 | ] 1415 | }, 1416 | "notification-url": "https://packagist.org/downloads/", 1417 | "license": [ 1418 | "MIT" 1419 | ], 1420 | "authors": [ 1421 | { 1422 | "name": "Ralph Khattar", 1423 | "email": "ralph.khattar@gmail.com" 1424 | } 1425 | ], 1426 | "description": "A polyfill for getallheaders.", 1427 | "time": "2019-03-08T08:55:37+00:00" 1428 | }, 1429 | { 1430 | "name": "sebastian/cli-parser", 1431 | "version": "1.0.1", 1432 | "source": { 1433 | "type": "git", 1434 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 1435 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" 1436 | }, 1437 | "dist": { 1438 | "type": "zip", 1439 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1440 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1441 | "shasum": "" 1442 | }, 1443 | "require": { 1444 | "php": ">=7.3" 1445 | }, 1446 | "require-dev": { 1447 | "phpunit/phpunit": "^9.3" 1448 | }, 1449 | "type": "library", 1450 | "extra": { 1451 | "branch-alias": { 1452 | "dev-master": "1.0-dev" 1453 | } 1454 | }, 1455 | "autoload": { 1456 | "classmap": [ 1457 | "src/" 1458 | ] 1459 | }, 1460 | "notification-url": "https://packagist.org/downloads/", 1461 | "license": [ 1462 | "BSD-3-Clause" 1463 | ], 1464 | "authors": [ 1465 | { 1466 | "name": "Sebastian Bergmann", 1467 | "email": "sebastian@phpunit.de", 1468 | "role": "lead" 1469 | } 1470 | ], 1471 | "description": "Library for parsing CLI options", 1472 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 1473 | "funding": [ 1474 | { 1475 | "url": "https://github.com/sebastianbergmann", 1476 | "type": "github" 1477 | } 1478 | ], 1479 | "time": "2020-09-28T06:08:49+00:00" 1480 | }, 1481 | { 1482 | "name": "sebastian/code-unit", 1483 | "version": "1.0.7", 1484 | "source": { 1485 | "type": "git", 1486 | "url": "https://github.com/sebastianbergmann/code-unit.git", 1487 | "reference": "59236be62b1bb9919e6d7f60b0b832dc05cef9ab" 1488 | }, 1489 | "dist": { 1490 | "type": "zip", 1491 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/59236be62b1bb9919e6d7f60b0b832dc05cef9ab", 1492 | "reference": "59236be62b1bb9919e6d7f60b0b832dc05cef9ab", 1493 | "shasum": "" 1494 | }, 1495 | "require": { 1496 | "php": ">=7.3" 1497 | }, 1498 | "require-dev": { 1499 | "phpunit/phpunit": "^9.3" 1500 | }, 1501 | "type": "library", 1502 | "extra": { 1503 | "branch-alias": { 1504 | "dev-master": "1.0-dev" 1505 | } 1506 | }, 1507 | "autoload": { 1508 | "classmap": [ 1509 | "src/" 1510 | ] 1511 | }, 1512 | "notification-url": "https://packagist.org/downloads/", 1513 | "license": [ 1514 | "BSD-3-Clause" 1515 | ], 1516 | "authors": [ 1517 | { 1518 | "name": "Sebastian Bergmann", 1519 | "email": "sebastian@phpunit.de", 1520 | "role": "lead" 1521 | } 1522 | ], 1523 | "description": "Collection of value objects that represent the PHP code units", 1524 | "homepage": "https://github.com/sebastianbergmann/code-unit", 1525 | "funding": [ 1526 | { 1527 | "url": "https://github.com/sebastianbergmann", 1528 | "type": "github" 1529 | } 1530 | ], 1531 | "time": "2020-10-02T14:47:54+00:00" 1532 | }, 1533 | { 1534 | "name": "sebastian/code-unit-reverse-lookup", 1535 | "version": "2.0.3", 1536 | "source": { 1537 | "type": "git", 1538 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1539 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 1540 | }, 1541 | "dist": { 1542 | "type": "zip", 1543 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1544 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1545 | "shasum": "" 1546 | }, 1547 | "require": { 1548 | "php": ">=7.3" 1549 | }, 1550 | "require-dev": { 1551 | "phpunit/phpunit": "^9.3" 1552 | }, 1553 | "type": "library", 1554 | "extra": { 1555 | "branch-alias": { 1556 | "dev-master": "2.0-dev" 1557 | } 1558 | }, 1559 | "autoload": { 1560 | "classmap": [ 1561 | "src/" 1562 | ] 1563 | }, 1564 | "notification-url": "https://packagist.org/downloads/", 1565 | "license": [ 1566 | "BSD-3-Clause" 1567 | ], 1568 | "authors": [ 1569 | { 1570 | "name": "Sebastian Bergmann", 1571 | "email": "sebastian@phpunit.de" 1572 | } 1573 | ], 1574 | "description": "Looks up which function or method a line of code belongs to", 1575 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1576 | "funding": [ 1577 | { 1578 | "url": "https://github.com/sebastianbergmann", 1579 | "type": "github" 1580 | } 1581 | ], 1582 | "time": "2020-09-28T05:30:19+00:00" 1583 | }, 1584 | { 1585 | "name": "sebastian/comparator", 1586 | "version": "4.0.5", 1587 | "source": { 1588 | "type": "git", 1589 | "url": "https://github.com/sebastianbergmann/comparator.git", 1590 | "reference": "7a8ff306445707539c1a6397372a982a1ec55120" 1591 | }, 1592 | "dist": { 1593 | "type": "zip", 1594 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7a8ff306445707539c1a6397372a982a1ec55120", 1595 | "reference": "7a8ff306445707539c1a6397372a982a1ec55120", 1596 | "shasum": "" 1597 | }, 1598 | "require": { 1599 | "php": ">=7.3", 1600 | "sebastian/diff": "^4.0", 1601 | "sebastian/exporter": "^4.0" 1602 | }, 1603 | "require-dev": { 1604 | "phpunit/phpunit": "^9.3" 1605 | }, 1606 | "type": "library", 1607 | "extra": { 1608 | "branch-alias": { 1609 | "dev-master": "4.0-dev" 1610 | } 1611 | }, 1612 | "autoload": { 1613 | "classmap": [ 1614 | "src/" 1615 | ] 1616 | }, 1617 | "notification-url": "https://packagist.org/downloads/", 1618 | "license": [ 1619 | "BSD-3-Clause" 1620 | ], 1621 | "authors": [ 1622 | { 1623 | "name": "Sebastian Bergmann", 1624 | "email": "sebastian@phpunit.de" 1625 | }, 1626 | { 1627 | "name": "Jeff Welch", 1628 | "email": "whatthejeff@gmail.com" 1629 | }, 1630 | { 1631 | "name": "Volker Dusch", 1632 | "email": "github@wallbash.com" 1633 | }, 1634 | { 1635 | "name": "Bernhard Schussek", 1636 | "email": "bschussek@2bepublished.at" 1637 | } 1638 | ], 1639 | "description": "Provides the functionality to compare PHP values for equality", 1640 | "homepage": "https://github.com/sebastianbergmann/comparator", 1641 | "keywords": [ 1642 | "comparator", 1643 | "compare", 1644 | "equality" 1645 | ], 1646 | "funding": [ 1647 | { 1648 | "url": "https://github.com/sebastianbergmann", 1649 | "type": "github" 1650 | } 1651 | ], 1652 | "time": "2020-09-30T06:47:25+00:00" 1653 | }, 1654 | { 1655 | "name": "sebastian/complexity", 1656 | "version": "2.0.1", 1657 | "source": { 1658 | "type": "git", 1659 | "url": "https://github.com/sebastianbergmann/complexity.git", 1660 | "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff" 1661 | }, 1662 | "dist": { 1663 | "type": "zip", 1664 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ba8cc2da0c0bfbc813d03b56406734030c7f1eff", 1665 | "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff", 1666 | "shasum": "" 1667 | }, 1668 | "require": { 1669 | "nikic/php-parser": "^4.7", 1670 | "php": ">=7.3" 1671 | }, 1672 | "require-dev": { 1673 | "phpunit/phpunit": "^9.3" 1674 | }, 1675 | "type": "library", 1676 | "extra": { 1677 | "branch-alias": { 1678 | "dev-master": "2.0-dev" 1679 | } 1680 | }, 1681 | "autoload": { 1682 | "classmap": [ 1683 | "src/" 1684 | ] 1685 | }, 1686 | "notification-url": "https://packagist.org/downloads/", 1687 | "license": [ 1688 | "BSD-3-Clause" 1689 | ], 1690 | "authors": [ 1691 | { 1692 | "name": "Sebastian Bergmann", 1693 | "email": "sebastian@phpunit.de", 1694 | "role": "lead" 1695 | } 1696 | ], 1697 | "description": "Library for calculating the complexity of PHP code units", 1698 | "homepage": "https://github.com/sebastianbergmann/complexity", 1699 | "funding": [ 1700 | { 1701 | "url": "https://github.com/sebastianbergmann", 1702 | "type": "github" 1703 | } 1704 | ], 1705 | "time": "2020-09-28T06:05:03+00:00" 1706 | }, 1707 | { 1708 | "name": "sebastian/diff", 1709 | "version": "4.0.3", 1710 | "source": { 1711 | "type": "git", 1712 | "url": "https://github.com/sebastianbergmann/diff.git", 1713 | "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092" 1714 | }, 1715 | "dist": { 1716 | "type": "zip", 1717 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ffc949a1a2aae270ea064453d7535b82e4c32092", 1718 | "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092", 1719 | "shasum": "" 1720 | }, 1721 | "require": { 1722 | "php": ">=7.3" 1723 | }, 1724 | "require-dev": { 1725 | "phpunit/phpunit": "^9.3", 1726 | "symfony/process": "^4.2 || ^5" 1727 | }, 1728 | "type": "library", 1729 | "extra": { 1730 | "branch-alias": { 1731 | "dev-master": "4.0-dev" 1732 | } 1733 | }, 1734 | "autoload": { 1735 | "classmap": [ 1736 | "src/" 1737 | ] 1738 | }, 1739 | "notification-url": "https://packagist.org/downloads/", 1740 | "license": [ 1741 | "BSD-3-Clause" 1742 | ], 1743 | "authors": [ 1744 | { 1745 | "name": "Sebastian Bergmann", 1746 | "email": "sebastian@phpunit.de" 1747 | }, 1748 | { 1749 | "name": "Kore Nordmann", 1750 | "email": "mail@kore-nordmann.de" 1751 | } 1752 | ], 1753 | "description": "Diff implementation", 1754 | "homepage": "https://github.com/sebastianbergmann/diff", 1755 | "keywords": [ 1756 | "diff", 1757 | "udiff", 1758 | "unidiff", 1759 | "unified diff" 1760 | ], 1761 | "funding": [ 1762 | { 1763 | "url": "https://github.com/sebastianbergmann", 1764 | "type": "github" 1765 | } 1766 | ], 1767 | "time": "2020-09-28T05:32:55+00:00" 1768 | }, 1769 | { 1770 | "name": "sebastian/environment", 1771 | "version": "5.1.3", 1772 | "source": { 1773 | "type": "git", 1774 | "url": "https://github.com/sebastianbergmann/environment.git", 1775 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac" 1776 | }, 1777 | "dist": { 1778 | "type": "zip", 1779 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", 1780 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac", 1781 | "shasum": "" 1782 | }, 1783 | "require": { 1784 | "php": ">=7.3" 1785 | }, 1786 | "require-dev": { 1787 | "phpunit/phpunit": "^9.3" 1788 | }, 1789 | "suggest": { 1790 | "ext-posix": "*" 1791 | }, 1792 | "type": "library", 1793 | "extra": { 1794 | "branch-alias": { 1795 | "dev-master": "5.1-dev" 1796 | } 1797 | }, 1798 | "autoload": { 1799 | "classmap": [ 1800 | "src/" 1801 | ] 1802 | }, 1803 | "notification-url": "https://packagist.org/downloads/", 1804 | "license": [ 1805 | "BSD-3-Clause" 1806 | ], 1807 | "authors": [ 1808 | { 1809 | "name": "Sebastian Bergmann", 1810 | "email": "sebastian@phpunit.de" 1811 | } 1812 | ], 1813 | "description": "Provides functionality to handle HHVM/PHP environments", 1814 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1815 | "keywords": [ 1816 | "Xdebug", 1817 | "environment", 1818 | "hhvm" 1819 | ], 1820 | "funding": [ 1821 | { 1822 | "url": "https://github.com/sebastianbergmann", 1823 | "type": "github" 1824 | } 1825 | ], 1826 | "time": "2020-09-28T05:52:38+00:00" 1827 | }, 1828 | { 1829 | "name": "sebastian/exporter", 1830 | "version": "4.0.3", 1831 | "source": { 1832 | "type": "git", 1833 | "url": "https://github.com/sebastianbergmann/exporter.git", 1834 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" 1835 | }, 1836 | "dist": { 1837 | "type": "zip", 1838 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", 1839 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", 1840 | "shasum": "" 1841 | }, 1842 | "require": { 1843 | "php": ">=7.3", 1844 | "sebastian/recursion-context": "^4.0" 1845 | }, 1846 | "require-dev": { 1847 | "ext-mbstring": "*", 1848 | "phpunit/phpunit": "^9.3" 1849 | }, 1850 | "type": "library", 1851 | "extra": { 1852 | "branch-alias": { 1853 | "dev-master": "4.0-dev" 1854 | } 1855 | }, 1856 | "autoload": { 1857 | "classmap": [ 1858 | "src/" 1859 | ] 1860 | }, 1861 | "notification-url": "https://packagist.org/downloads/", 1862 | "license": [ 1863 | "BSD-3-Clause" 1864 | ], 1865 | "authors": [ 1866 | { 1867 | "name": "Sebastian Bergmann", 1868 | "email": "sebastian@phpunit.de" 1869 | }, 1870 | { 1871 | "name": "Jeff Welch", 1872 | "email": "whatthejeff@gmail.com" 1873 | }, 1874 | { 1875 | "name": "Volker Dusch", 1876 | "email": "github@wallbash.com" 1877 | }, 1878 | { 1879 | "name": "Adam Harvey", 1880 | "email": "aharvey@php.net" 1881 | }, 1882 | { 1883 | "name": "Bernhard Schussek", 1884 | "email": "bschussek@gmail.com" 1885 | } 1886 | ], 1887 | "description": "Provides the functionality to export PHP variables for visualization", 1888 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1889 | "keywords": [ 1890 | "export", 1891 | "exporter" 1892 | ], 1893 | "funding": [ 1894 | { 1895 | "url": "https://github.com/sebastianbergmann", 1896 | "type": "github" 1897 | } 1898 | ], 1899 | "time": "2020-09-28T05:24:23+00:00" 1900 | }, 1901 | { 1902 | "name": "sebastian/global-state", 1903 | "version": "5.0.1", 1904 | "source": { 1905 | "type": "git", 1906 | "url": "https://github.com/sebastianbergmann/global-state.git", 1907 | "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7" 1908 | }, 1909 | "dist": { 1910 | "type": "zip", 1911 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ea779cb749a478b22a2564ac41cd7bda79c78dc7", 1912 | "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7", 1913 | "shasum": "" 1914 | }, 1915 | "require": { 1916 | "php": ">=7.3", 1917 | "sebastian/object-reflector": "^2.0", 1918 | "sebastian/recursion-context": "^4.0" 1919 | }, 1920 | "require-dev": { 1921 | "ext-dom": "*", 1922 | "phpunit/phpunit": "^9.3" 1923 | }, 1924 | "suggest": { 1925 | "ext-uopz": "*" 1926 | }, 1927 | "type": "library", 1928 | "extra": { 1929 | "branch-alias": { 1930 | "dev-master": "5.0-dev" 1931 | } 1932 | }, 1933 | "autoload": { 1934 | "classmap": [ 1935 | "src/" 1936 | ] 1937 | }, 1938 | "notification-url": "https://packagist.org/downloads/", 1939 | "license": [ 1940 | "BSD-3-Clause" 1941 | ], 1942 | "authors": [ 1943 | { 1944 | "name": "Sebastian Bergmann", 1945 | "email": "sebastian@phpunit.de" 1946 | } 1947 | ], 1948 | "description": "Snapshotting of global state", 1949 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1950 | "keywords": [ 1951 | "global state" 1952 | ], 1953 | "funding": [ 1954 | { 1955 | "url": "https://github.com/sebastianbergmann", 1956 | "type": "github" 1957 | } 1958 | ], 1959 | "time": "2020-09-28T05:54:06+00:00" 1960 | }, 1961 | { 1962 | "name": "sebastian/lines-of-code", 1963 | "version": "1.0.1", 1964 | "source": { 1965 | "type": "git", 1966 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 1967 | "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54" 1968 | }, 1969 | "dist": { 1970 | "type": "zip", 1971 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/6514b8f21906b8b46f520d1fbd17a4523fa59a54", 1972 | "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54", 1973 | "shasum": "" 1974 | }, 1975 | "require": { 1976 | "nikic/php-parser": "^4.6", 1977 | "php": ">=7.3" 1978 | }, 1979 | "require-dev": { 1980 | "phpunit/phpunit": "^9.3" 1981 | }, 1982 | "type": "library", 1983 | "extra": { 1984 | "branch-alias": { 1985 | "dev-master": "1.0-dev" 1986 | } 1987 | }, 1988 | "autoload": { 1989 | "classmap": [ 1990 | "src/" 1991 | ] 1992 | }, 1993 | "notification-url": "https://packagist.org/downloads/", 1994 | "license": [ 1995 | "BSD-3-Clause" 1996 | ], 1997 | "authors": [ 1998 | { 1999 | "name": "Sebastian Bergmann", 2000 | "email": "sebastian@phpunit.de", 2001 | "role": "lead" 2002 | } 2003 | ], 2004 | "description": "Library for counting the lines of code in PHP source code", 2005 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 2006 | "funding": [ 2007 | { 2008 | "url": "https://github.com/sebastianbergmann", 2009 | "type": "github" 2010 | } 2011 | ], 2012 | "time": "2020-09-28T06:07:27+00:00" 2013 | }, 2014 | { 2015 | "name": "sebastian/object-enumerator", 2016 | "version": "4.0.3", 2017 | "source": { 2018 | "type": "git", 2019 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 2020 | "reference": "f6f5957013d84725427d361507e13513702888a4" 2021 | }, 2022 | "dist": { 2023 | "type": "zip", 2024 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f6f5957013d84725427d361507e13513702888a4", 2025 | "reference": "f6f5957013d84725427d361507e13513702888a4", 2026 | "shasum": "" 2027 | }, 2028 | "require": { 2029 | "php": ">=7.3", 2030 | "sebastian/object-reflector": "^2.0", 2031 | "sebastian/recursion-context": "^4.0" 2032 | }, 2033 | "require-dev": { 2034 | "phpunit/phpunit": "^9.3" 2035 | }, 2036 | "type": "library", 2037 | "extra": { 2038 | "branch-alias": { 2039 | "dev-master": "4.0-dev" 2040 | } 2041 | }, 2042 | "autoload": { 2043 | "classmap": [ 2044 | "src/" 2045 | ] 2046 | }, 2047 | "notification-url": "https://packagist.org/downloads/", 2048 | "license": [ 2049 | "BSD-3-Clause" 2050 | ], 2051 | "authors": [ 2052 | { 2053 | "name": "Sebastian Bergmann", 2054 | "email": "sebastian@phpunit.de" 2055 | } 2056 | ], 2057 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 2058 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 2059 | "funding": [ 2060 | { 2061 | "url": "https://github.com/sebastianbergmann", 2062 | "type": "github" 2063 | } 2064 | ], 2065 | "time": "2020-09-28T05:55:06+00:00" 2066 | }, 2067 | { 2068 | "name": "sebastian/object-reflector", 2069 | "version": "2.0.3", 2070 | "source": { 2071 | "type": "git", 2072 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 2073 | "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5" 2074 | }, 2075 | "dist": { 2076 | "type": "zip", 2077 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5", 2078 | "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5", 2079 | "shasum": "" 2080 | }, 2081 | "require": { 2082 | "php": ">=7.3" 2083 | }, 2084 | "require-dev": { 2085 | "phpunit/phpunit": "^9.3" 2086 | }, 2087 | "type": "library", 2088 | "extra": { 2089 | "branch-alias": { 2090 | "dev-master": "2.0-dev" 2091 | } 2092 | }, 2093 | "autoload": { 2094 | "classmap": [ 2095 | "src/" 2096 | ] 2097 | }, 2098 | "notification-url": "https://packagist.org/downloads/", 2099 | "license": [ 2100 | "BSD-3-Clause" 2101 | ], 2102 | "authors": [ 2103 | { 2104 | "name": "Sebastian Bergmann", 2105 | "email": "sebastian@phpunit.de" 2106 | } 2107 | ], 2108 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 2109 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 2110 | "funding": [ 2111 | { 2112 | "url": "https://github.com/sebastianbergmann", 2113 | "type": "github" 2114 | } 2115 | ], 2116 | "time": "2020-09-28T05:56:16+00:00" 2117 | }, 2118 | { 2119 | "name": "sebastian/recursion-context", 2120 | "version": "4.0.3", 2121 | "source": { 2122 | "type": "git", 2123 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 2124 | "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7" 2125 | }, 2126 | "dist": { 2127 | "type": "zip", 2128 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/ed8c9cd355089134bc9cba421b5cfdd58f0eaef7", 2129 | "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7", 2130 | "shasum": "" 2131 | }, 2132 | "require": { 2133 | "php": ">=7.3" 2134 | }, 2135 | "require-dev": { 2136 | "phpunit/phpunit": "^9.3" 2137 | }, 2138 | "type": "library", 2139 | "extra": { 2140 | "branch-alias": { 2141 | "dev-master": "4.0-dev" 2142 | } 2143 | }, 2144 | "autoload": { 2145 | "classmap": [ 2146 | "src/" 2147 | ] 2148 | }, 2149 | "notification-url": "https://packagist.org/downloads/", 2150 | "license": [ 2151 | "BSD-3-Clause" 2152 | ], 2153 | "authors": [ 2154 | { 2155 | "name": "Sebastian Bergmann", 2156 | "email": "sebastian@phpunit.de" 2157 | }, 2158 | { 2159 | "name": "Jeff Welch", 2160 | "email": "whatthejeff@gmail.com" 2161 | }, 2162 | { 2163 | "name": "Adam Harvey", 2164 | "email": "aharvey@php.net" 2165 | } 2166 | ], 2167 | "description": "Provides functionality to recursively process PHP variables", 2168 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 2169 | "funding": [ 2170 | { 2171 | "url": "https://github.com/sebastianbergmann", 2172 | "type": "github" 2173 | } 2174 | ], 2175 | "time": "2020-09-28T05:17:32+00:00" 2176 | }, 2177 | { 2178 | "name": "sebastian/resource-operations", 2179 | "version": "3.0.3", 2180 | "source": { 2181 | "type": "git", 2182 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 2183 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" 2184 | }, 2185 | "dist": { 2186 | "type": "zip", 2187 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 2188 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 2189 | "shasum": "" 2190 | }, 2191 | "require": { 2192 | "php": ">=7.3" 2193 | }, 2194 | "require-dev": { 2195 | "phpunit/phpunit": "^9.0" 2196 | }, 2197 | "type": "library", 2198 | "extra": { 2199 | "branch-alias": { 2200 | "dev-master": "3.0-dev" 2201 | } 2202 | }, 2203 | "autoload": { 2204 | "classmap": [ 2205 | "src/" 2206 | ] 2207 | }, 2208 | "notification-url": "https://packagist.org/downloads/", 2209 | "license": [ 2210 | "BSD-3-Clause" 2211 | ], 2212 | "authors": [ 2213 | { 2214 | "name": "Sebastian Bergmann", 2215 | "email": "sebastian@phpunit.de" 2216 | } 2217 | ], 2218 | "description": "Provides a list of PHP built-in functions that operate on resources", 2219 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 2220 | "funding": [ 2221 | { 2222 | "url": "https://github.com/sebastianbergmann", 2223 | "type": "github" 2224 | } 2225 | ], 2226 | "time": "2020-09-28T06:45:17+00:00" 2227 | }, 2228 | { 2229 | "name": "sebastian/type", 2230 | "version": "2.3.0", 2231 | "source": { 2232 | "type": "git", 2233 | "url": "https://github.com/sebastianbergmann/type.git", 2234 | "reference": "fa592377f3923946cb90bf1f6a71ba2e5f229909" 2235 | }, 2236 | "dist": { 2237 | "type": "zip", 2238 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fa592377f3923946cb90bf1f6a71ba2e5f229909", 2239 | "reference": "fa592377f3923946cb90bf1f6a71ba2e5f229909", 2240 | "shasum": "" 2241 | }, 2242 | "require": { 2243 | "php": ">=7.3" 2244 | }, 2245 | "require-dev": { 2246 | "phpunit/phpunit": "^9.3" 2247 | }, 2248 | "type": "library", 2249 | "extra": { 2250 | "branch-alias": { 2251 | "dev-master": "2.3-dev" 2252 | } 2253 | }, 2254 | "autoload": { 2255 | "classmap": [ 2256 | "src/" 2257 | ] 2258 | }, 2259 | "notification-url": "https://packagist.org/downloads/", 2260 | "license": [ 2261 | "BSD-3-Clause" 2262 | ], 2263 | "authors": [ 2264 | { 2265 | "name": "Sebastian Bergmann", 2266 | "email": "sebastian@phpunit.de", 2267 | "role": "lead" 2268 | } 2269 | ], 2270 | "description": "Collection of value objects that represent the types of the PHP type system", 2271 | "homepage": "https://github.com/sebastianbergmann/type", 2272 | "funding": [ 2273 | { 2274 | "url": "https://github.com/sebastianbergmann", 2275 | "type": "github" 2276 | } 2277 | ], 2278 | "time": "2020-10-06T08:41:03+00:00" 2279 | }, 2280 | { 2281 | "name": "sebastian/version", 2282 | "version": "3.0.2", 2283 | "source": { 2284 | "type": "git", 2285 | "url": "https://github.com/sebastianbergmann/version.git", 2286 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 2287 | }, 2288 | "dist": { 2289 | "type": "zip", 2290 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 2291 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 2292 | "shasum": "" 2293 | }, 2294 | "require": { 2295 | "php": ">=7.3" 2296 | }, 2297 | "type": "library", 2298 | "extra": { 2299 | "branch-alias": { 2300 | "dev-master": "3.0-dev" 2301 | } 2302 | }, 2303 | "autoload": { 2304 | "classmap": [ 2305 | "src/" 2306 | ] 2307 | }, 2308 | "notification-url": "https://packagist.org/downloads/", 2309 | "license": [ 2310 | "BSD-3-Clause" 2311 | ], 2312 | "authors": [ 2313 | { 2314 | "name": "Sebastian Bergmann", 2315 | "email": "sebastian@phpunit.de", 2316 | "role": "lead" 2317 | } 2318 | ], 2319 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 2320 | "homepage": "https://github.com/sebastianbergmann/version", 2321 | "funding": [ 2322 | { 2323 | "url": "https://github.com/sebastianbergmann", 2324 | "type": "github" 2325 | } 2326 | ], 2327 | "time": "2020-09-28T06:39:44+00:00" 2328 | }, 2329 | { 2330 | "name": "symfony/config", 2331 | "version": "v5.1.7", 2332 | "source": { 2333 | "type": "git", 2334 | "url": "https://github.com/symfony/config.git", 2335 | "reference": "6ad8be6e1280f6734150d8a04a9160dd34ceb191" 2336 | }, 2337 | "dist": { 2338 | "type": "zip", 2339 | "url": "https://api.github.com/repos/symfony/config/zipball/6ad8be6e1280f6734150d8a04a9160dd34ceb191", 2340 | "reference": "6ad8be6e1280f6734150d8a04a9160dd34ceb191", 2341 | "shasum": "" 2342 | }, 2343 | "require": { 2344 | "php": ">=7.2.5", 2345 | "symfony/deprecation-contracts": "^2.1", 2346 | "symfony/filesystem": "^4.4|^5.0", 2347 | "symfony/polyfill-ctype": "~1.8", 2348 | "symfony/polyfill-php80": "^1.15" 2349 | }, 2350 | "conflict": { 2351 | "symfony/finder": "<4.4" 2352 | }, 2353 | "require-dev": { 2354 | "symfony/event-dispatcher": "^4.4|^5.0", 2355 | "symfony/finder": "^4.4|^5.0", 2356 | "symfony/messenger": "^4.4|^5.0", 2357 | "symfony/service-contracts": "^1.1|^2", 2358 | "symfony/yaml": "^4.4|^5.0" 2359 | }, 2360 | "suggest": { 2361 | "symfony/yaml": "To use the yaml reference dumper" 2362 | }, 2363 | "type": "library", 2364 | "extra": { 2365 | "branch-alias": { 2366 | "dev-master": "5.1-dev" 2367 | } 2368 | }, 2369 | "autoload": { 2370 | "psr-4": { 2371 | "Symfony\\Component\\Config\\": "" 2372 | }, 2373 | "exclude-from-classmap": [ 2374 | "/Tests/" 2375 | ] 2376 | }, 2377 | "notification-url": "https://packagist.org/downloads/", 2378 | "license": [ 2379 | "MIT" 2380 | ], 2381 | "authors": [ 2382 | { 2383 | "name": "Fabien Potencier", 2384 | "email": "fabien@symfony.com" 2385 | }, 2386 | { 2387 | "name": "Symfony Community", 2388 | "homepage": "https://symfony.com/contributors" 2389 | } 2390 | ], 2391 | "description": "Symfony Config Component", 2392 | "homepage": "https://symfony.com", 2393 | "funding": [ 2394 | { 2395 | "url": "https://symfony.com/sponsor", 2396 | "type": "custom" 2397 | }, 2398 | { 2399 | "url": "https://github.com/fabpot", 2400 | "type": "github" 2401 | }, 2402 | { 2403 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2404 | "type": "tidelift" 2405 | } 2406 | ], 2407 | "time": "2020-09-02T16:23:27+00:00" 2408 | }, 2409 | { 2410 | "name": "symfony/console", 2411 | "version": "v5.1.7", 2412 | "source": { 2413 | "type": "git", 2414 | "url": "https://github.com/symfony/console.git", 2415 | "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8" 2416 | }, 2417 | "dist": { 2418 | "type": "zip", 2419 | "url": "https://api.github.com/repos/symfony/console/zipball/ae789a8a2ad189ce7e8216942cdb9b77319f5eb8", 2420 | "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8", 2421 | "shasum": "" 2422 | }, 2423 | "require": { 2424 | "php": ">=7.2.5", 2425 | "symfony/polyfill-mbstring": "~1.0", 2426 | "symfony/polyfill-php73": "^1.8", 2427 | "symfony/polyfill-php80": "^1.15", 2428 | "symfony/service-contracts": "^1.1|^2", 2429 | "symfony/string": "^5.1" 2430 | }, 2431 | "conflict": { 2432 | "symfony/dependency-injection": "<4.4", 2433 | "symfony/dotenv": "<5.1", 2434 | "symfony/event-dispatcher": "<4.4", 2435 | "symfony/lock": "<4.4", 2436 | "symfony/process": "<4.4" 2437 | }, 2438 | "provide": { 2439 | "psr/log-implementation": "1.0" 2440 | }, 2441 | "require-dev": { 2442 | "psr/log": "~1.0", 2443 | "symfony/config": "^4.4|^5.0", 2444 | "symfony/dependency-injection": "^4.4|^5.0", 2445 | "symfony/event-dispatcher": "^4.4|^5.0", 2446 | "symfony/lock": "^4.4|^5.0", 2447 | "symfony/process": "^4.4|^5.0", 2448 | "symfony/var-dumper": "^4.4|^5.0" 2449 | }, 2450 | "suggest": { 2451 | "psr/log": "For using the console logger", 2452 | "symfony/event-dispatcher": "", 2453 | "symfony/lock": "", 2454 | "symfony/process": "" 2455 | }, 2456 | "type": "library", 2457 | "extra": { 2458 | "branch-alias": { 2459 | "dev-master": "5.1-dev" 2460 | } 2461 | }, 2462 | "autoload": { 2463 | "psr-4": { 2464 | "Symfony\\Component\\Console\\": "" 2465 | }, 2466 | "exclude-from-classmap": [ 2467 | "/Tests/" 2468 | ] 2469 | }, 2470 | "notification-url": "https://packagist.org/downloads/", 2471 | "license": [ 2472 | "MIT" 2473 | ], 2474 | "authors": [ 2475 | { 2476 | "name": "Fabien Potencier", 2477 | "email": "fabien@symfony.com" 2478 | }, 2479 | { 2480 | "name": "Symfony Community", 2481 | "homepage": "https://symfony.com/contributors" 2482 | } 2483 | ], 2484 | "description": "Symfony Console Component", 2485 | "homepage": "https://symfony.com", 2486 | "funding": [ 2487 | { 2488 | "url": "https://symfony.com/sponsor", 2489 | "type": "custom" 2490 | }, 2491 | { 2492 | "url": "https://github.com/fabpot", 2493 | "type": "github" 2494 | }, 2495 | { 2496 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2497 | "type": "tidelift" 2498 | } 2499 | ], 2500 | "time": "2020-10-07T15:23:00+00:00" 2501 | }, 2502 | { 2503 | "name": "symfony/deprecation-contracts", 2504 | "version": "v2.2.0", 2505 | "source": { 2506 | "type": "git", 2507 | "url": "https://github.com/symfony/deprecation-contracts.git", 2508 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" 2509 | }, 2510 | "dist": { 2511 | "type": "zip", 2512 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", 2513 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", 2514 | "shasum": "" 2515 | }, 2516 | "require": { 2517 | "php": ">=7.1" 2518 | }, 2519 | "type": "library", 2520 | "extra": { 2521 | "branch-alias": { 2522 | "dev-master": "2.2-dev" 2523 | }, 2524 | "thanks": { 2525 | "name": "symfony/contracts", 2526 | "url": "https://github.com/symfony/contracts" 2527 | } 2528 | }, 2529 | "autoload": { 2530 | "files": [ 2531 | "function.php" 2532 | ] 2533 | }, 2534 | "notification-url": "https://packagist.org/downloads/", 2535 | "license": [ 2536 | "MIT" 2537 | ], 2538 | "authors": [ 2539 | { 2540 | "name": "Nicolas Grekas", 2541 | "email": "p@tchwork.com" 2542 | }, 2543 | { 2544 | "name": "Symfony Community", 2545 | "homepage": "https://symfony.com/contributors" 2546 | } 2547 | ], 2548 | "description": "A generic function and convention to trigger deprecation notices", 2549 | "homepage": "https://symfony.com", 2550 | "funding": [ 2551 | { 2552 | "url": "https://symfony.com/sponsor", 2553 | "type": "custom" 2554 | }, 2555 | { 2556 | "url": "https://github.com/fabpot", 2557 | "type": "github" 2558 | }, 2559 | { 2560 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2561 | "type": "tidelift" 2562 | } 2563 | ], 2564 | "time": "2020-09-07T11:33:47+00:00" 2565 | }, 2566 | { 2567 | "name": "symfony/filesystem", 2568 | "version": "v5.1.7", 2569 | "source": { 2570 | "type": "git", 2571 | "url": "https://github.com/symfony/filesystem.git", 2572 | "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae" 2573 | }, 2574 | "dist": { 2575 | "type": "zip", 2576 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/1a8697545a8d87b9f2f6b1d32414199cc5e20aae", 2577 | "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae", 2578 | "shasum": "" 2579 | }, 2580 | "require": { 2581 | "php": ">=7.2.5", 2582 | "symfony/polyfill-ctype": "~1.8" 2583 | }, 2584 | "type": "library", 2585 | "extra": { 2586 | "branch-alias": { 2587 | "dev-master": "5.1-dev" 2588 | } 2589 | }, 2590 | "autoload": { 2591 | "psr-4": { 2592 | "Symfony\\Component\\Filesystem\\": "" 2593 | }, 2594 | "exclude-from-classmap": [ 2595 | "/Tests/" 2596 | ] 2597 | }, 2598 | "notification-url": "https://packagist.org/downloads/", 2599 | "license": [ 2600 | "MIT" 2601 | ], 2602 | "authors": [ 2603 | { 2604 | "name": "Fabien Potencier", 2605 | "email": "fabien@symfony.com" 2606 | }, 2607 | { 2608 | "name": "Symfony Community", 2609 | "homepage": "https://symfony.com/contributors" 2610 | } 2611 | ], 2612 | "description": "Symfony Filesystem Component", 2613 | "homepage": "https://symfony.com", 2614 | "funding": [ 2615 | { 2616 | "url": "https://symfony.com/sponsor", 2617 | "type": "custom" 2618 | }, 2619 | { 2620 | "url": "https://github.com/fabpot", 2621 | "type": "github" 2622 | }, 2623 | { 2624 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2625 | "type": "tidelift" 2626 | } 2627 | ], 2628 | "time": "2020-09-27T14:02:37+00:00" 2629 | }, 2630 | { 2631 | "name": "symfony/polyfill-ctype", 2632 | "version": "v1.18.1", 2633 | "source": { 2634 | "type": "git", 2635 | "url": "https://github.com/symfony/polyfill-ctype.git", 2636 | "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" 2637 | }, 2638 | "dist": { 2639 | "type": "zip", 2640 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", 2641 | "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", 2642 | "shasum": "" 2643 | }, 2644 | "require": { 2645 | "php": ">=5.3.3" 2646 | }, 2647 | "suggest": { 2648 | "ext-ctype": "For best performance" 2649 | }, 2650 | "type": "library", 2651 | "extra": { 2652 | "branch-alias": { 2653 | "dev-master": "1.18-dev" 2654 | }, 2655 | "thanks": { 2656 | "name": "symfony/polyfill", 2657 | "url": "https://github.com/symfony/polyfill" 2658 | } 2659 | }, 2660 | "autoload": { 2661 | "psr-4": { 2662 | "Symfony\\Polyfill\\Ctype\\": "" 2663 | }, 2664 | "files": [ 2665 | "bootstrap.php" 2666 | ] 2667 | }, 2668 | "notification-url": "https://packagist.org/downloads/", 2669 | "license": [ 2670 | "MIT" 2671 | ], 2672 | "authors": [ 2673 | { 2674 | "name": "Gert de Pagter", 2675 | "email": "BackEndTea@gmail.com" 2676 | }, 2677 | { 2678 | "name": "Symfony Community", 2679 | "homepage": "https://symfony.com/contributors" 2680 | } 2681 | ], 2682 | "description": "Symfony polyfill for ctype functions", 2683 | "homepage": "https://symfony.com", 2684 | "keywords": [ 2685 | "compatibility", 2686 | "ctype", 2687 | "polyfill", 2688 | "portable" 2689 | ], 2690 | "funding": [ 2691 | { 2692 | "url": "https://symfony.com/sponsor", 2693 | "type": "custom" 2694 | }, 2695 | { 2696 | "url": "https://github.com/fabpot", 2697 | "type": "github" 2698 | }, 2699 | { 2700 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2701 | "type": "tidelift" 2702 | } 2703 | ], 2704 | "time": "2020-07-14T12:35:20+00:00" 2705 | }, 2706 | { 2707 | "name": "symfony/polyfill-intl-grapheme", 2708 | "version": "v1.18.1", 2709 | "source": { 2710 | "type": "git", 2711 | "url": "https://github.com/symfony/polyfill-intl-grapheme.git", 2712 | "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5" 2713 | }, 2714 | "dist": { 2715 | "type": "zip", 2716 | "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b740103edbdcc39602239ee8860f0f45a8eb9aa5", 2717 | "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5", 2718 | "shasum": "" 2719 | }, 2720 | "require": { 2721 | "php": ">=5.3.3" 2722 | }, 2723 | "suggest": { 2724 | "ext-intl": "For best performance" 2725 | }, 2726 | "type": "library", 2727 | "extra": { 2728 | "branch-alias": { 2729 | "dev-master": "1.18-dev" 2730 | }, 2731 | "thanks": { 2732 | "name": "symfony/polyfill", 2733 | "url": "https://github.com/symfony/polyfill" 2734 | } 2735 | }, 2736 | "autoload": { 2737 | "psr-4": { 2738 | "Symfony\\Polyfill\\Intl\\Grapheme\\": "" 2739 | }, 2740 | "files": [ 2741 | "bootstrap.php" 2742 | ] 2743 | }, 2744 | "notification-url": "https://packagist.org/downloads/", 2745 | "license": [ 2746 | "MIT" 2747 | ], 2748 | "authors": [ 2749 | { 2750 | "name": "Nicolas Grekas", 2751 | "email": "p@tchwork.com" 2752 | }, 2753 | { 2754 | "name": "Symfony Community", 2755 | "homepage": "https://symfony.com/contributors" 2756 | } 2757 | ], 2758 | "description": "Symfony polyfill for intl's grapheme_* functions", 2759 | "homepage": "https://symfony.com", 2760 | "keywords": [ 2761 | "compatibility", 2762 | "grapheme", 2763 | "intl", 2764 | "polyfill", 2765 | "portable", 2766 | "shim" 2767 | ], 2768 | "funding": [ 2769 | { 2770 | "url": "https://symfony.com/sponsor", 2771 | "type": "custom" 2772 | }, 2773 | { 2774 | "url": "https://github.com/fabpot", 2775 | "type": "github" 2776 | }, 2777 | { 2778 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2779 | "type": "tidelift" 2780 | } 2781 | ], 2782 | "time": "2020-07-14T12:35:20+00:00" 2783 | }, 2784 | { 2785 | "name": "symfony/polyfill-intl-normalizer", 2786 | "version": "v1.18.1", 2787 | "source": { 2788 | "type": "git", 2789 | "url": "https://github.com/symfony/polyfill-intl-normalizer.git", 2790 | "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" 2791 | }, 2792 | "dist": { 2793 | "type": "zip", 2794 | "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", 2795 | "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", 2796 | "shasum": "" 2797 | }, 2798 | "require": { 2799 | "php": ">=5.3.3" 2800 | }, 2801 | "suggest": { 2802 | "ext-intl": "For best performance" 2803 | }, 2804 | "type": "library", 2805 | "extra": { 2806 | "branch-alias": { 2807 | "dev-master": "1.18-dev" 2808 | }, 2809 | "thanks": { 2810 | "name": "symfony/polyfill", 2811 | "url": "https://github.com/symfony/polyfill" 2812 | } 2813 | }, 2814 | "autoload": { 2815 | "psr-4": { 2816 | "Symfony\\Polyfill\\Intl\\Normalizer\\": "" 2817 | }, 2818 | "files": [ 2819 | "bootstrap.php" 2820 | ], 2821 | "classmap": [ 2822 | "Resources/stubs" 2823 | ] 2824 | }, 2825 | "notification-url": "https://packagist.org/downloads/", 2826 | "license": [ 2827 | "MIT" 2828 | ], 2829 | "authors": [ 2830 | { 2831 | "name": "Nicolas Grekas", 2832 | "email": "p@tchwork.com" 2833 | }, 2834 | { 2835 | "name": "Symfony Community", 2836 | "homepage": "https://symfony.com/contributors" 2837 | } 2838 | ], 2839 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 2840 | "homepage": "https://symfony.com", 2841 | "keywords": [ 2842 | "compatibility", 2843 | "intl", 2844 | "normalizer", 2845 | "polyfill", 2846 | "portable", 2847 | "shim" 2848 | ], 2849 | "funding": [ 2850 | { 2851 | "url": "https://symfony.com/sponsor", 2852 | "type": "custom" 2853 | }, 2854 | { 2855 | "url": "https://github.com/fabpot", 2856 | "type": "github" 2857 | }, 2858 | { 2859 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2860 | "type": "tidelift" 2861 | } 2862 | ], 2863 | "time": "2020-07-14T12:35:20+00:00" 2864 | }, 2865 | { 2866 | "name": "symfony/polyfill-mbstring", 2867 | "version": "v1.18.1", 2868 | "source": { 2869 | "type": "git", 2870 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2871 | "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a" 2872 | }, 2873 | "dist": { 2874 | "type": "zip", 2875 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a", 2876 | "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a", 2877 | "shasum": "" 2878 | }, 2879 | "require": { 2880 | "php": ">=5.3.3" 2881 | }, 2882 | "suggest": { 2883 | "ext-mbstring": "For best performance" 2884 | }, 2885 | "type": "library", 2886 | "extra": { 2887 | "branch-alias": { 2888 | "dev-master": "1.18-dev" 2889 | }, 2890 | "thanks": { 2891 | "name": "symfony/polyfill", 2892 | "url": "https://github.com/symfony/polyfill" 2893 | } 2894 | }, 2895 | "autoload": { 2896 | "psr-4": { 2897 | "Symfony\\Polyfill\\Mbstring\\": "" 2898 | }, 2899 | "files": [ 2900 | "bootstrap.php" 2901 | ] 2902 | }, 2903 | "notification-url": "https://packagist.org/downloads/", 2904 | "license": [ 2905 | "MIT" 2906 | ], 2907 | "authors": [ 2908 | { 2909 | "name": "Nicolas Grekas", 2910 | "email": "p@tchwork.com" 2911 | }, 2912 | { 2913 | "name": "Symfony Community", 2914 | "homepage": "https://symfony.com/contributors" 2915 | } 2916 | ], 2917 | "description": "Symfony polyfill for the Mbstring extension", 2918 | "homepage": "https://symfony.com", 2919 | "keywords": [ 2920 | "compatibility", 2921 | "mbstring", 2922 | "polyfill", 2923 | "portable", 2924 | "shim" 2925 | ], 2926 | "funding": [ 2927 | { 2928 | "url": "https://symfony.com/sponsor", 2929 | "type": "custom" 2930 | }, 2931 | { 2932 | "url": "https://github.com/fabpot", 2933 | "type": "github" 2934 | }, 2935 | { 2936 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2937 | "type": "tidelift" 2938 | } 2939 | ], 2940 | "time": "2020-07-14T12:35:20+00:00" 2941 | }, 2942 | { 2943 | "name": "symfony/polyfill-php73", 2944 | "version": "v1.18.1", 2945 | "source": { 2946 | "type": "git", 2947 | "url": "https://github.com/symfony/polyfill-php73.git", 2948 | "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca" 2949 | }, 2950 | "dist": { 2951 | "type": "zip", 2952 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca", 2953 | "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca", 2954 | "shasum": "" 2955 | }, 2956 | "require": { 2957 | "php": ">=5.3.3" 2958 | }, 2959 | "type": "library", 2960 | "extra": { 2961 | "branch-alias": { 2962 | "dev-master": "1.18-dev" 2963 | }, 2964 | "thanks": { 2965 | "name": "symfony/polyfill", 2966 | "url": "https://github.com/symfony/polyfill" 2967 | } 2968 | }, 2969 | "autoload": { 2970 | "psr-4": { 2971 | "Symfony\\Polyfill\\Php73\\": "" 2972 | }, 2973 | "files": [ 2974 | "bootstrap.php" 2975 | ], 2976 | "classmap": [ 2977 | "Resources/stubs" 2978 | ] 2979 | }, 2980 | "notification-url": "https://packagist.org/downloads/", 2981 | "license": [ 2982 | "MIT" 2983 | ], 2984 | "authors": [ 2985 | { 2986 | "name": "Nicolas Grekas", 2987 | "email": "p@tchwork.com" 2988 | }, 2989 | { 2990 | "name": "Symfony Community", 2991 | "homepage": "https://symfony.com/contributors" 2992 | } 2993 | ], 2994 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 2995 | "homepage": "https://symfony.com", 2996 | "keywords": [ 2997 | "compatibility", 2998 | "polyfill", 2999 | "portable", 3000 | "shim" 3001 | ], 3002 | "funding": [ 3003 | { 3004 | "url": "https://symfony.com/sponsor", 3005 | "type": "custom" 3006 | }, 3007 | { 3008 | "url": "https://github.com/fabpot", 3009 | "type": "github" 3010 | }, 3011 | { 3012 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3013 | "type": "tidelift" 3014 | } 3015 | ], 3016 | "time": "2020-07-14T12:35:20+00:00" 3017 | }, 3018 | { 3019 | "name": "symfony/polyfill-php80", 3020 | "version": "v1.18.1", 3021 | "source": { 3022 | "type": "git", 3023 | "url": "https://github.com/symfony/polyfill-php80.git", 3024 | "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981" 3025 | }, 3026 | "dist": { 3027 | "type": "zip", 3028 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981", 3029 | "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981", 3030 | "shasum": "" 3031 | }, 3032 | "require": { 3033 | "php": ">=7.0.8" 3034 | }, 3035 | "type": "library", 3036 | "extra": { 3037 | "branch-alias": { 3038 | "dev-master": "1.18-dev" 3039 | }, 3040 | "thanks": { 3041 | "name": "symfony/polyfill", 3042 | "url": "https://github.com/symfony/polyfill" 3043 | } 3044 | }, 3045 | "autoload": { 3046 | "psr-4": { 3047 | "Symfony\\Polyfill\\Php80\\": "" 3048 | }, 3049 | "files": [ 3050 | "bootstrap.php" 3051 | ], 3052 | "classmap": [ 3053 | "Resources/stubs" 3054 | ] 3055 | }, 3056 | "notification-url": "https://packagist.org/downloads/", 3057 | "license": [ 3058 | "MIT" 3059 | ], 3060 | "authors": [ 3061 | { 3062 | "name": "Ion Bazan", 3063 | "email": "ion.bazan@gmail.com" 3064 | }, 3065 | { 3066 | "name": "Nicolas Grekas", 3067 | "email": "p@tchwork.com" 3068 | }, 3069 | { 3070 | "name": "Symfony Community", 3071 | "homepage": "https://symfony.com/contributors" 3072 | } 3073 | ], 3074 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 3075 | "homepage": "https://symfony.com", 3076 | "keywords": [ 3077 | "compatibility", 3078 | "polyfill", 3079 | "portable", 3080 | "shim" 3081 | ], 3082 | "funding": [ 3083 | { 3084 | "url": "https://symfony.com/sponsor", 3085 | "type": "custom" 3086 | }, 3087 | { 3088 | "url": "https://github.com/fabpot", 3089 | "type": "github" 3090 | }, 3091 | { 3092 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3093 | "type": "tidelift" 3094 | } 3095 | ], 3096 | "time": "2020-07-14T12:35:20+00:00" 3097 | }, 3098 | { 3099 | "name": "symfony/service-contracts", 3100 | "version": "v2.2.0", 3101 | "source": { 3102 | "type": "git", 3103 | "url": "https://github.com/symfony/service-contracts.git", 3104 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" 3105 | }, 3106 | "dist": { 3107 | "type": "zip", 3108 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", 3109 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", 3110 | "shasum": "" 3111 | }, 3112 | "require": { 3113 | "php": ">=7.2.5", 3114 | "psr/container": "^1.0" 3115 | }, 3116 | "suggest": { 3117 | "symfony/service-implementation": "" 3118 | }, 3119 | "type": "library", 3120 | "extra": { 3121 | "branch-alias": { 3122 | "dev-master": "2.2-dev" 3123 | }, 3124 | "thanks": { 3125 | "name": "symfony/contracts", 3126 | "url": "https://github.com/symfony/contracts" 3127 | } 3128 | }, 3129 | "autoload": { 3130 | "psr-4": { 3131 | "Symfony\\Contracts\\Service\\": "" 3132 | } 3133 | }, 3134 | "notification-url": "https://packagist.org/downloads/", 3135 | "license": [ 3136 | "MIT" 3137 | ], 3138 | "authors": [ 3139 | { 3140 | "name": "Nicolas Grekas", 3141 | "email": "p@tchwork.com" 3142 | }, 3143 | { 3144 | "name": "Symfony Community", 3145 | "homepage": "https://symfony.com/contributors" 3146 | } 3147 | ], 3148 | "description": "Generic abstractions related to writing services", 3149 | "homepage": "https://symfony.com", 3150 | "keywords": [ 3151 | "abstractions", 3152 | "contracts", 3153 | "decoupling", 3154 | "interfaces", 3155 | "interoperability", 3156 | "standards" 3157 | ], 3158 | "funding": [ 3159 | { 3160 | "url": "https://symfony.com/sponsor", 3161 | "type": "custom" 3162 | }, 3163 | { 3164 | "url": "https://github.com/fabpot", 3165 | "type": "github" 3166 | }, 3167 | { 3168 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3169 | "type": "tidelift" 3170 | } 3171 | ], 3172 | "time": "2020-09-07T11:33:47+00:00" 3173 | }, 3174 | { 3175 | "name": "symfony/stopwatch", 3176 | "version": "v5.1.7", 3177 | "source": { 3178 | "type": "git", 3179 | "url": "https://github.com/symfony/stopwatch.git", 3180 | "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323" 3181 | }, 3182 | "dist": { 3183 | "type": "zip", 3184 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0f7c58cf81dbb5dd67d423a89d577524a2ec0323", 3185 | "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323", 3186 | "shasum": "" 3187 | }, 3188 | "require": { 3189 | "php": ">=7.2.5", 3190 | "symfony/service-contracts": "^1.0|^2" 3191 | }, 3192 | "type": "library", 3193 | "extra": { 3194 | "branch-alias": { 3195 | "dev-master": "5.1-dev" 3196 | } 3197 | }, 3198 | "autoload": { 3199 | "psr-4": { 3200 | "Symfony\\Component\\Stopwatch\\": "" 3201 | }, 3202 | "exclude-from-classmap": [ 3203 | "/Tests/" 3204 | ] 3205 | }, 3206 | "notification-url": "https://packagist.org/downloads/", 3207 | "license": [ 3208 | "MIT" 3209 | ], 3210 | "authors": [ 3211 | { 3212 | "name": "Fabien Potencier", 3213 | "email": "fabien@symfony.com" 3214 | }, 3215 | { 3216 | "name": "Symfony Community", 3217 | "homepage": "https://symfony.com/contributors" 3218 | } 3219 | ], 3220 | "description": "Symfony Stopwatch Component", 3221 | "homepage": "https://symfony.com", 3222 | "funding": [ 3223 | { 3224 | "url": "https://symfony.com/sponsor", 3225 | "type": "custom" 3226 | }, 3227 | { 3228 | "url": "https://github.com/fabpot", 3229 | "type": "github" 3230 | }, 3231 | { 3232 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3233 | "type": "tidelift" 3234 | } 3235 | ], 3236 | "time": "2020-05-20T17:43:50+00:00" 3237 | }, 3238 | { 3239 | "name": "symfony/string", 3240 | "version": "v5.1.7", 3241 | "source": { 3242 | "type": "git", 3243 | "url": "https://github.com/symfony/string.git", 3244 | "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e" 3245 | }, 3246 | "dist": { 3247 | "type": "zip", 3248 | "url": "https://api.github.com/repos/symfony/string/zipball/4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", 3249 | "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", 3250 | "shasum": "" 3251 | }, 3252 | "require": { 3253 | "php": ">=7.2.5", 3254 | "symfony/polyfill-ctype": "~1.8", 3255 | "symfony/polyfill-intl-grapheme": "~1.0", 3256 | "symfony/polyfill-intl-normalizer": "~1.0", 3257 | "symfony/polyfill-mbstring": "~1.0", 3258 | "symfony/polyfill-php80": "~1.15" 3259 | }, 3260 | "require-dev": { 3261 | "symfony/error-handler": "^4.4|^5.0", 3262 | "symfony/http-client": "^4.4|^5.0", 3263 | "symfony/translation-contracts": "^1.1|^2", 3264 | "symfony/var-exporter": "^4.4|^5.0" 3265 | }, 3266 | "type": "library", 3267 | "extra": { 3268 | "branch-alias": { 3269 | "dev-master": "5.1-dev" 3270 | } 3271 | }, 3272 | "autoload": { 3273 | "psr-4": { 3274 | "Symfony\\Component\\String\\": "" 3275 | }, 3276 | "files": [ 3277 | "Resources/functions.php" 3278 | ], 3279 | "exclude-from-classmap": [ 3280 | "/Tests/" 3281 | ] 3282 | }, 3283 | "notification-url": "https://packagist.org/downloads/", 3284 | "license": [ 3285 | "MIT" 3286 | ], 3287 | "authors": [ 3288 | { 3289 | "name": "Nicolas Grekas", 3290 | "email": "p@tchwork.com" 3291 | }, 3292 | { 3293 | "name": "Symfony Community", 3294 | "homepage": "https://symfony.com/contributors" 3295 | } 3296 | ], 3297 | "description": "Symfony String component", 3298 | "homepage": "https://symfony.com", 3299 | "keywords": [ 3300 | "grapheme", 3301 | "i18n", 3302 | "string", 3303 | "unicode", 3304 | "utf-8", 3305 | "utf8" 3306 | ], 3307 | "funding": [ 3308 | { 3309 | "url": "https://symfony.com/sponsor", 3310 | "type": "custom" 3311 | }, 3312 | { 3313 | "url": "https://github.com/fabpot", 3314 | "type": "github" 3315 | }, 3316 | { 3317 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3318 | "type": "tidelift" 3319 | } 3320 | ], 3321 | "time": "2020-09-15T12:23:47+00:00" 3322 | }, 3323 | { 3324 | "name": "symfony/yaml", 3325 | "version": "v5.1.7", 3326 | "source": { 3327 | "type": "git", 3328 | "url": "https://github.com/symfony/yaml.git", 3329 | "reference": "e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a" 3330 | }, 3331 | "dist": { 3332 | "type": "zip", 3333 | "url": "https://api.github.com/repos/symfony/yaml/zipball/e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a", 3334 | "reference": "e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a", 3335 | "shasum": "" 3336 | }, 3337 | "require": { 3338 | "php": ">=7.2.5", 3339 | "symfony/deprecation-contracts": "^2.1", 3340 | "symfony/polyfill-ctype": "~1.8" 3341 | }, 3342 | "conflict": { 3343 | "symfony/console": "<4.4" 3344 | }, 3345 | "require-dev": { 3346 | "symfony/console": "^4.4|^5.0" 3347 | }, 3348 | "suggest": { 3349 | "symfony/console": "For validating YAML files using the lint command" 3350 | }, 3351 | "bin": [ 3352 | "Resources/bin/yaml-lint" 3353 | ], 3354 | "type": "library", 3355 | "extra": { 3356 | "branch-alias": { 3357 | "dev-master": "5.1-dev" 3358 | } 3359 | }, 3360 | "autoload": { 3361 | "psr-4": { 3362 | "Symfony\\Component\\Yaml\\": "" 3363 | }, 3364 | "exclude-from-classmap": [ 3365 | "/Tests/" 3366 | ] 3367 | }, 3368 | "notification-url": "https://packagist.org/downloads/", 3369 | "license": [ 3370 | "MIT" 3371 | ], 3372 | "authors": [ 3373 | { 3374 | "name": "Fabien Potencier", 3375 | "email": "fabien@symfony.com" 3376 | }, 3377 | { 3378 | "name": "Symfony Community", 3379 | "homepage": "https://symfony.com/contributors" 3380 | } 3381 | ], 3382 | "description": "Symfony Yaml Component", 3383 | "homepage": "https://symfony.com", 3384 | "funding": [ 3385 | { 3386 | "url": "https://symfony.com/sponsor", 3387 | "type": "custom" 3388 | }, 3389 | { 3390 | "url": "https://github.com/fabpot", 3391 | "type": "github" 3392 | }, 3393 | { 3394 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3395 | "type": "tidelift" 3396 | } 3397 | ], 3398 | "time": "2020-09-27T03:44:28+00:00" 3399 | }, 3400 | { 3401 | "name": "theseer/tokenizer", 3402 | "version": "1.2.0", 3403 | "source": { 3404 | "type": "git", 3405 | "url": "https://github.com/theseer/tokenizer.git", 3406 | "reference": "75a63c33a8577608444246075ea0af0d052e452a" 3407 | }, 3408 | "dist": { 3409 | "type": "zip", 3410 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", 3411 | "reference": "75a63c33a8577608444246075ea0af0d052e452a", 3412 | "shasum": "" 3413 | }, 3414 | "require": { 3415 | "ext-dom": "*", 3416 | "ext-tokenizer": "*", 3417 | "ext-xmlwriter": "*", 3418 | "php": "^7.2 || ^8.0" 3419 | }, 3420 | "type": "library", 3421 | "autoload": { 3422 | "classmap": [ 3423 | "src/" 3424 | ] 3425 | }, 3426 | "notification-url": "https://packagist.org/downloads/", 3427 | "license": [ 3428 | "BSD-3-Clause" 3429 | ], 3430 | "authors": [ 3431 | { 3432 | "name": "Arne Blankerts", 3433 | "email": "arne@blankerts.de", 3434 | "role": "Developer" 3435 | } 3436 | ], 3437 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 3438 | "funding": [ 3439 | { 3440 | "url": "https://github.com/theseer", 3441 | "type": "github" 3442 | } 3443 | ], 3444 | "time": "2020-07-12T23:59:07+00:00" 3445 | }, 3446 | { 3447 | "name": "webmozart/assert", 3448 | "version": "1.9.1", 3449 | "source": { 3450 | "type": "git", 3451 | "url": "https://github.com/webmozart/assert.git", 3452 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" 3453 | }, 3454 | "dist": { 3455 | "type": "zip", 3456 | "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", 3457 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", 3458 | "shasum": "" 3459 | }, 3460 | "require": { 3461 | "php": "^5.3.3 || ^7.0 || ^8.0", 3462 | "symfony/polyfill-ctype": "^1.8" 3463 | }, 3464 | "conflict": { 3465 | "phpstan/phpstan": "<0.12.20", 3466 | "vimeo/psalm": "<3.9.1" 3467 | }, 3468 | "require-dev": { 3469 | "phpunit/phpunit": "^4.8.36 || ^7.5.13" 3470 | }, 3471 | "type": "library", 3472 | "autoload": { 3473 | "psr-4": { 3474 | "Webmozart\\Assert\\": "src/" 3475 | } 3476 | }, 3477 | "notification-url": "https://packagist.org/downloads/", 3478 | "license": [ 3479 | "MIT" 3480 | ], 3481 | "authors": [ 3482 | { 3483 | "name": "Bernhard Schussek", 3484 | "email": "bschussek@gmail.com" 3485 | } 3486 | ], 3487 | "description": "Assertions to validate method input/output with nice error messages.", 3488 | "keywords": [ 3489 | "assert", 3490 | "check", 3491 | "validate" 3492 | ], 3493 | "time": "2020-07-08T17:02:28+00:00" 3494 | } 3495 | ], 3496 | "aliases": [], 3497 | "minimum-stability": "dev", 3498 | "stability-flags": [], 3499 | "prefer-stable": true, 3500 | "prefer-lowest": false, 3501 | "platform": { 3502 | "php": "^7.2", 3503 | "ext-componere": "^3.0.0" 3504 | }, 3505 | "platform-dev": [], 3506 | "plugin-api-version": "1.1.0" 3507 | } 3508 | --------------------------------------------------------------------------------