composer update

This commit is contained in:
2019-12-01 06:37:45 +00:00
parent fa199eef05
commit 3115ab75a5
3650 changed files with 72361 additions and 147137 deletions

View File

@@ -0,0 +1 @@
patreon: s_bergmann

View File

@@ -1,40 +0,0 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- enhancement
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had activity within the last 60 days. It will be closed after 7 days if no further activity occurs. Thank you for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue has been automatically closed because it has not had activity since it was marked as stale. Thank you for your contributions.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues

View File

@@ -4,7 +4,7 @@ php:
- 7.1
- 7.2
- 7.3
- master
- 7.4snapshot
sudo: false

View File

@@ -2,6 +2,24 @@
All notable changes to `sebastianbergmann/php-token-stream` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [3.1.1] - 2019-09-17
### Fixed
* Fixed [#84](https://github.com/sebastianbergmann/php-token-stream/issues/84): Methods named `class` are not handled correctly
## [3.1.0] - 2019-07-25
### Added
* Added support for `FN` and `COALESCE_EQUAL` tokens introduced in PHP 7.4
## [3.0.2] - 2019-07-08
### Changed
* Implemented [#82](https://github.com/sebastianbergmann/php-token-stream/issues/82): Make sure this component works when its classes are prefixed using php-scoper
## [3.0.1] - 2018-10-30
### Fixed
@@ -29,6 +47,9 @@ All notable changes to `sebastianbergmann/php-token-stream` are documented in th
## [2.0.0] - 2017-08-03
[3.1.1]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.0...3.1.1
[3.1.0]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.2...3.1.0
[3.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.1...3.0.2
[3.0.1]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0...3.0.0
[2.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0.1...2.0.2

View File

@@ -1,6 +1,6 @@
php-token-stream
Copyright (c) 2009-2018, Sebastian Bergmann <sebastian@phpunit.de>.
Copyright (c) 2009-2019, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -33,7 +33,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-master": "3.1-dev"
}
}
}

View File

@@ -1,13 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.4/phpunit.xsd"
bootstrap="tests/bootstrap.php"
forceCoversAnnotation="false"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
verbose="true">
<testsuite>
<directory suffix="Test.php">tests</directory>
</testsuite>
<testsuites>
<testsuite name="default">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">

View File

@@ -186,7 +186,7 @@ abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
$tokens[$i] instanceof PHP_Token_PROTECTED ||
$tokens[$i] instanceof PHP_Token_PUBLIC)) {
return strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$i]))
str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
);
}
if (isset($tokens[$i]) &&
@@ -220,7 +220,7 @@ abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
$tokens[$i] instanceof PHP_Token_FINAL ||
$tokens[$i] instanceof PHP_Token_ABSTRACT)) {
$keywords[] = strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$i]))
str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
);
}
}
@@ -272,7 +272,7 @@ abstract class PHP_Token_Includes extends PHP_Token
if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
$this->name = trim($tokens[$this->id + 2], "'\"");
$this->type = strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$this->id]))
);
}
}
@@ -405,7 +405,7 @@ class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
$tokens = $this->tokenStream->tokens();
for ($i = $this->id; $i <= $end; $i++) {
switch (get_class($tokens[$i])) {
switch (PHP_Token_Util::getClass($tokens[$i])) {
case 'PHP_Token_IF':
case 'PHP_Token_ELSEIF':
case 'PHP_Token_FOR':
@@ -1350,3 +1350,12 @@ class PHP_Token_SPACESHIP extends PHP_Token
class PHP_Token_YIELD_FROM extends PHP_Token
{
}
// Tokens introduced in PHP 7.4
class PHP_Token_COALESCE_EQUAL extends PHP_Token
{
}
class PHP_Token_FN extends PHP_Token
{
}

View File

@@ -303,7 +303,7 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
];
foreach ($this->tokens as $token) {
switch (get_class($token)) {
switch (PHP_Token_Util::getClass($token)) {
case 'PHP_Token_REQUIRE_ONCE':
case 'PHP_Token_REQUIRE':
case 'PHP_Token_INCLUDE_ONCE':
@@ -358,7 +358,7 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
$interfaceEndLine = false;
foreach ($this->tokens as $token) {
switch (get_class($token)) {
switch (PHP_Token_Util::getClass($token)) {
case 'PHP_Token_HALT_COMPILER':
return;
@@ -392,15 +392,17 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
'file' => $this->filename
];
if ($token instanceof PHP_Token_CLASS) {
$class[] = $token->getName();
$classEndLine[] = $token->getEndLine();
if ($token->getName() !== null) {
if ($token instanceof PHP_Token_CLASS) {
$class[] = $token->getName();
$classEndLine[] = $token->getEndLine();
$this->classes[$class[count($class) - 1]] = $tmp;
} else {
$trait = $token->getName();
$traitEndLine = $token->getEndLine();
$this->traits[$trait] = $tmp;
$this->classes[$class[count($class) - 1]] = $tmp;
} else {
$trait = $token->getName();
$traitEndLine = $token->getEndLine();
$this->traits[$trait] = $tmp;
}
}
break;

View File

@@ -0,0 +1,19 @@
<?php declare(strict_types=1);
/*
* This file is part of php-token-stream.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
final class PHP_Token_Util
{
public static function getClass($object): string
{
$parts = explode('\\', get_class($object));
return array_pop($parts);
}
}

View File

@@ -24,9 +24,7 @@ class PHP_Token_ClassTest extends TestCase
protected function setUp()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source2.php');
foreach ($ts as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source2.php') as $token) {
if ($token instanceof PHP_Token_CLASS) {
$this->class = $token;
}
@@ -38,25 +36,16 @@ class PHP_Token_ClassTest extends TestCase
}
}
/**
* @covers PHP_Token_CLASS::getKeywords
*/
public function testGetClassKeywords()
{
$this->assertEquals('abstract', $this->class->getKeywords());
}
/**
* @covers PHP_Token_FUNCTION::getKeywords
*/
public function testGetFunctionKeywords()
{
$this->assertEquals('abstract,static', $this->function->getKeywords());
}
/**
* @covers PHP_Token_FUNCTION::getVisibility
*/
public function testGetFunctionVisibility()
{
$this->assertEquals('public', $this->function->getVisibility());
@@ -64,9 +53,7 @@ class PHP_Token_ClassTest extends TestCase
public function testIssue19()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'issue19.php');
foreach ($ts as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'issue19.php') as $token) {
if ($token instanceof PHP_Token_CLASS) {
$this->assertFalse($token->hasInterfaces());
}
@@ -143,9 +130,7 @@ class PHP_Token_ClassTest extends TestCase
*/
public function testClassWithMethodNamedEmptyIsHandledCorrectly()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_named_empty.php');
$classes = $ts->getClasses();
$classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_named_empty.php'))->getClasses();
$this->assertArrayHasKey('class_with_method_named_empty', $classes);
$this->assertArrayHasKey('empty', $classes['class_with_method_named_empty']['methods']);
@@ -156,9 +141,7 @@ class PHP_Token_ClassTest extends TestCase
*/
public function testAnonymousFunctionDoesNotAffectStartAndEndLineOfMethod()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'php-code-coverage-issue-424.php');
$classes = $ts->getClasses();
$classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'php-code-coverage-issue-424.php'))->getClasses();
$this->assertSame(5, $classes['Example']['methods']['even']['startLine']);
$this->assertSame(12, $classes['Example']['methods']['even']['endLine']);

View File

@@ -19,18 +19,13 @@ class PHP_Token_ClosureTest extends TestCase
protected function setUp()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'closure.php');
foreach ($ts as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'closure.php') as $token) {
if ($token instanceof PHP_Token_FUNCTION) {
$this->functions[] = $token;
}
}
}
/**
* @covers PHP_Token_FUNCTION::getArguments
*/
public function testGetArguments()
{
$this->assertEquals(['$foo' => null, '$bar' => null], $this->functions[0]->getArguments());
@@ -41,9 +36,6 @@ class PHP_Token_ClosureTest extends TestCase
$this->assertEquals([], $this->functions[5]->getArguments());
}
/**
* @covers PHP_Token_FUNCTION::getName
*/
public function testGetName()
{
$this->assertEquals('anonymousFunction:2#5', $this->functions[0]->getName());
@@ -54,9 +46,6 @@ class PHP_Token_ClosureTest extends TestCase
$this->assertEquals('anonymousFunction:7#106', $this->functions[5]->getName());
}
/**
* @covers PHP_Token::getLine
*/
public function testGetLine()
{
$this->assertEquals(2, $this->functions[0]->getLine());
@@ -65,9 +54,6 @@ class PHP_Token_ClosureTest extends TestCase
$this->assertEquals(5, $this->functions[3]->getLine());
}
/**
* @covers PHP_TokenWithScope::getEndLine
*/
public function testGetEndLine()
{
$this->assertEquals(2, $this->functions[0]->getLine());

View File

@@ -19,32 +19,27 @@ class PHP_Token_FunctionTest extends TestCase
protected function setUp()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source.php');
foreach ($ts as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source.php') as $token) {
if ($token instanceof PHP_Token_FUNCTION) {
$this->functions[] = $token;
}
}
}
/**
* @covers PHP_Token_FUNCTION::getArguments
*/
public function testGetArguments()
{
$this->assertEquals([], $this->functions[0]->getArguments());
$this->assertEquals(
['$baz' => 'Baz'], $this->functions[1]->getArguments()
['$baz' => 'Baz'], $this->functions[1]->getArguments()
);
$this->assertEquals(
['$foobar' => 'Foobar'], $this->functions[2]->getArguments()
['$foobar' => 'Foobar'], $this->functions[2]->getArguments()
);
$this->assertEquals(
['$barfoo' => 'Barfoo'], $this->functions[3]->getArguments()
['$barfoo' => 'Barfoo'], $this->functions[3]->getArguments()
);
$this->assertEquals([], $this->functions[4]->getArguments());
@@ -52,9 +47,6 @@ class PHP_Token_FunctionTest extends TestCase
$this->assertEquals(['$x' => null, '$y' => null], $this->functions[5]->getArguments());
}
/**
* @covers PHP_Token_FUNCTION::getName
*/
public function testGetName()
{
$this->assertEquals('foo', $this->functions[0]->getName());
@@ -64,9 +56,6 @@ class PHP_Token_FunctionTest extends TestCase
$this->assertEquals('baz', $this->functions[4]->getName());
}
/**
* @covers PHP_Token::getLine
*/
public function testGetLine()
{
$this->assertEquals(5, $this->functions[0]->getLine());
@@ -77,9 +66,6 @@ class PHP_Token_FunctionTest extends TestCase
$this->assertEquals(37, $this->functions[6]->getLine());
}
/**
* @covers PHP_TokenWithScope::getEndLine
*/
public function testGetEndLine()
{
$this->assertEquals(5, $this->functions[0]->getEndLine());
@@ -90,21 +76,18 @@ class PHP_Token_FunctionTest extends TestCase
$this->assertEquals(41, $this->functions[6]->getEndLine());
}
/**
* @covers PHP_Token_FUNCTION::getDocblock
*/
public function testGetDocblock()
{
$this->assertNull($this->functions[0]->getDocblock());
$this->assertEquals(
"/**\n * @param Baz \$baz\n */",
$this->functions[1]->getDocblock()
"/**\n * @param Baz \$baz\n */",
$this->functions[1]->getDocblock()
);
$this->assertEquals(
"/**\n * @param Foobar \$foobar\n */",
$this->functions[2]->getDocblock()
"/**\n * @param Foobar \$foobar\n */",
$this->functions[2]->getDocblock()
);
$this->assertNull($this->functions[3]->getDocblock());
@@ -113,29 +96,29 @@ class PHP_Token_FunctionTest extends TestCase
public function testSignature()
{
$ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source5.php');
$f = $ts->getFunctions();
$c = $ts->getClasses();
$i = $ts->getInterfaces();
$tokens = new PHP_Token_Stream(TEST_FILES_PATH . 'source5.php');
$functions = $tokens->getFunctions();
$classes = $tokens->getClasses();
$interfaces = $tokens->getInterfaces();
$this->assertEquals(
'foo($a, array $b, array $c = array())',
$f['foo']['signature']
'foo($a, array $b, array $c = array())',
$functions['foo']['signature']
);
$this->assertEquals(
'm($a, array $b, array $c = array())',
$c['c']['methods']['m']['signature']
'm($a, array $b, array $c = array())',
$classes['c']['methods']['m']['signature']
);
$this->assertEquals(
'm($a, array $b, array $c = array())',
$c['a']['methods']['m']['signature']
'm($a, array $b, array $c = array())',
$classes['a']['methods']['m']['signature']
);
$this->assertEquals(
'm($a, array $b, array $c = array())',
$i['i']['methods']['m']['signature']
'm($a, array $b, array $c = array())',
$interfaces['i']['methods']['m']['signature']
);
}
}

View File

@@ -22,44 +22,32 @@ class PHP_Token_IncludeTest extends TestCase
$this->ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source3.php');
}
/**
* @covers PHP_Token_Includes::getName
* @covers PHP_Token_Includes::getType
*/
public function testGetIncludes()
{
$this->assertSame(
['test4.php', 'test3.php', 'test2.php', 'test1.php'],
$this->ts->getIncludes()
['test4.php', 'test3.php', 'test2.php', 'test1.php'],
$this->ts->getIncludes()
);
}
/**
* @covers PHP_Token_Includes::getName
* @covers PHP_Token_Includes::getType
*/
public function testGetIncludesCategorized()
{
$this->assertSame(
[
'require_once' => ['test4.php'],
'require' => ['test3.php'],
'include_once' => ['test2.php'],
'include' => ['test1.php']
],
$this->ts->getIncludes(true)
[
'require_once' => ['test4.php'],
'require' => ['test3.php'],
'include_once' => ['test2.php'],
'include' => ['test1.php']
],
$this->ts->getIncludes(true)
);
}
/**
* @covers PHP_Token_Includes::getName
* @covers PHP_Token_Includes::getType
*/
public function testGetIncludesCategory()
{
$this->assertSame(
['test4.php'],
$this->ts->getIncludes(true, 'require_once')
['test4.php'],
$this->ts->getIncludes(true, 'require_once')
);
}
}

View File

@@ -37,9 +37,6 @@ class PHP_Token_InterfaceTest extends TestCase
}
}
/**
* @covers PHP_Token_INTERFACE::getName
*/
public function testGetName()
{
$this->assertEquals(
@@ -47,9 +44,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::getParent
*/
public function testGetParentNotExists()
{
$this->assertFalse(
@@ -57,9 +51,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::hasParent
*/
public function testHasParentNotExists()
{
$this->assertFalse(
@@ -67,9 +58,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::getParent
*/
public function testGetParentExists()
{
$this->assertEquals(
@@ -77,9 +65,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::hasParent
*/
public function testHasParentExists()
{
$this->assertTrue(
@@ -87,9 +72,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::getInterfaces
*/
public function testGetInterfacesExists()
{
$this->assertEquals(
@@ -98,9 +80,6 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::hasInterfaces
*/
public function testHasInterfacesExists()
{
$this->assertTrue(
@@ -108,13 +87,9 @@ class PHP_Token_InterfaceTest extends TestCase
);
}
/**
* @covers PHP_Token_INTERFACE::getPackage
*/
public function testGetPackageNamespace()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
foreach ($tokenStream as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
if ($token instanceof PHP_Token_INTERFACE) {
$package = $token->getPackage();
$this->assertSame('Foo\\Bar', $package['namespace']);
@@ -122,7 +97,6 @@ class PHP_Token_InterfaceTest extends TestCase
}
}
public function provideFilesWithClassesWithinMultipleNamespaces()
{
return [
@@ -133,12 +107,12 @@ class PHP_Token_InterfaceTest extends TestCase
/**
* @dataProvider provideFilesWithClassesWithinMultipleNamespaces
* @covers PHP_Token_INTERFACE::getPackage
*/
public function testGetPackageNamespaceForFileWithMultipleNamespaces($filepath)
{
$tokenStream = new PHP_Token_Stream($filepath);
$firstClassFound = false;
foreach ($tokenStream as $token) {
if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
$package = $token->getPackage();
@@ -167,13 +141,11 @@ class PHP_Token_InterfaceTest extends TestCase
}
}
/**
* @covers PHP_Token_INTERFACE::getPackage
*/
public function testGetPackageNamespaceWhenExtentingFromNamespaceClass()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classExtendsNamespacedClass.php');
$firstClassFound = false;
foreach ($tokenStream as $token) {
if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
$package = $token->getPackage();
@@ -182,6 +154,7 @@ class PHP_Token_InterfaceTest extends TestCase
$firstClassFound = true;
continue;
}
if ($token instanceof PHP_Token_INTERFACE) {
$package = $token->getPackage();
$this->assertSame('Extender', $token->getName());
@@ -190,6 +163,7 @@ class PHP_Token_InterfaceTest extends TestCase
return;
}
}
$this->fail('Searching for 2 classes failed');
}
}

View File

@@ -12,9 +12,6 @@ use PHPUnit\Framework\TestCase;
class PHP_Token_NamespaceTest extends TestCase
{
/**
* @covers PHP_Token_NAMESPACE::getName
*/
public function testGetName()
{
$tokenStream = new PHP_Token_Stream(
@@ -30,8 +27,7 @@ class PHP_Token_NamespaceTest extends TestCase
public function testGetStartLineWithUnscopedNamespace()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
foreach ($tokenStream as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
if ($token instanceof PHP_Token_NAMESPACE) {
$this->assertSame(2, $token->getLine());
}
@@ -40,8 +36,7 @@ class PHP_Token_NamespaceTest extends TestCase
public function testGetEndLineWithUnscopedNamespace()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
foreach ($tokenStream as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
if ($token instanceof PHP_Token_NAMESPACE) {
$this->assertSame(2, $token->getEndLine());
}
@@ -49,8 +44,7 @@ class PHP_Token_NamespaceTest extends TestCase
}
public function testGetStartLineWithScopedNamespace()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php');
foreach ($tokenStream as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) {
if ($token instanceof PHP_Token_NAMESPACE) {
$this->assertSame(2, $token->getLine());
}
@@ -59,8 +53,7 @@ class PHP_Token_NamespaceTest extends TestCase
public function testGetEndLineWithScopedNamespace()
{
$tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php');
foreach ($tokenStream as $token) {
foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) {
if ($token instanceof PHP_Token_NAMESPACE) {
$this->assertSame(8, $token->getEndLine());
}

View File

@@ -7,5 +7,8 @@ indent_style = space
indent_size = 4
charset = utf-8
[*.yml]
indent_size = 2
[tests/_files/*_result_cache.txt]
insert_final_newline = false

View File

@@ -1,5 +1,6 @@
/build export-ignore
/tools export-ignore
/tools/* binary
*.php diff=php

View File

@@ -1,47 +0,0 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- blocked
- enhancement
- backward-compatibility-break
- feature-removal
- php-support-removal
- process
- rfc
- refactoring
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had activity within the last 60 days. It will be closed after 7 days if no further activity occurs. Thank you for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue has been automatically closed because it has not had activity since it was marked as stale. Thank you for your contributions.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues

View File

@@ -0,0 +1,18 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
on:
- push
- pull_request
name: CI
jobs:
coding-guidelines:
name: Coding Guidelines
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Run friendsofphp/php-cs-fixer
run: php7.3 tools/php-cs-fixer fix --diff-format=udiff --dry-run --show-progress=dots --using-cache=no --verbose

View File

@@ -171,7 +171,7 @@ return PhpCsFixer\Config::create()
'semicolon_after_instruction' => true,
'set_type_to_cast' => true,
'short_scalar_cast' => true,
'simplified_null_return' => true,
'simplified_null_return' => false,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
@@ -195,7 +195,6 @@ return PhpCsFixer\Config::create()
->setFinder(
PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/build')
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->notName('*.phpt')

View File

@@ -44,13 +44,3 @@ after_success:
notifications:
email: false
jobs:
include:
- stage: Static Code Analysis
php: 7.3
env: php-cs-fixer
install:
- phpenv config-rm xdebug.ini
script:
- ./tools/php-cs-fixer fix --dry-run -v --show-progress=dots --diff-format=udiff

View File

@@ -2,6 +2,32 @@
All notable changes of the PHPUnit 7.5 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [7.5.17] - 2019-10-28
### Fixed
* Fixed [#3727](https://github.com/sebastianbergmann/phpunit/issues/3727): Problem hidden by PHPUnit's error handler
* Fixed [#3863](https://github.com/sebastianbergmann/phpunit/pull/3863): `\Countable` needs to be checked before `\EmptyIterator`
## [7.5.16] - 2019-09-14
### Fixed
* Fixed [#3801](https://github.com/sebastianbergmann/phpunit/issues/3801): Class constant as default parameter is undefined
* Fixed [#3834](https://github.com/sebastianbergmann/phpunit/issues/3834): Trailing slash breaks code coverage on Windows
## [7.5.15] - 2019-08-21
### Changed
* Implemented [#3765](https://github.com/sebastianbergmann/phpunit/pull/3765): Use `ReflectionType::getName()` instead of `ReflectionType::__toString()` (which is deprecated in PHP 7.4)
## [7.5.14] - 2019-07-15
### Fixed
* Fixed [#3743](https://github.com/sebastianbergmann/phpunit/issues/3743): `EmptyIterator` instances are not handled correctly by `Count` and `IsEmpty` constraints
## [7.5.13] - 2019-06-19
### Fixed
@@ -126,6 +152,10 @@ All notable changes of the PHPUnit 7.5 release series are documented in this fil
* Fixed [#3429](https://github.com/sebastianbergmann/phpunit/pull/3429): Inefficient loop in `getHookMethods()`
* Fixed [#3437](https://github.com/sebastianbergmann/phpunit/pull/3437): JUnit logger skips PHPT tests
[7.5.17]: https://github.com/sebastianbergmann/phpunit/compare/7.5.16...7.5.17
[7.5.16]: https://github.com/sebastianbergmann/phpunit/compare/7.5.15...7.5.16
[7.5.15]: https://github.com/sebastianbergmann/phpunit/compare/7.5.14...7.5.15
[7.5.14]: https://github.com/sebastianbergmann/phpunit/compare/7.5.13...7.5.14
[7.5.13]: https://github.com/sebastianbergmann/phpunit/compare/7.5.12...7.5.13
[7.5.12]: https://github.com/sebastianbergmann/phpunit/compare/7.5.11...7.5.12
[7.5.11]: https://github.com/sebastianbergmann/phpunit/compare/7.5.10...7.5.11

View File

@@ -153,6 +153,12 @@
</fileset>
</copy>
<copy todir="${basedir}/build/phar/php-invoker">
<fileset dir="${basedir}/vendor/phpunit/php-invoker/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/phpunit/php-text-template/LICENSE" tofile="${basedir}/build/phar/php-text-template/LICENSE"/>
<copy todir="${basedir}/build/phar/php-text-template">
<fileset dir="${basedir}/vendor/phpunit/php-text-template/src">
@@ -209,20 +215,6 @@
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/recursion-context/LICENSE" tofile="${basedir}/build/phar/sebastian-recursion-context/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-recursion-context">
<fileset dir="${basedir}/vendor/sebastian/recursion-context/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/resource-operations/LICENSE" tofile="${basedir}/build/phar/sebastian-resource-operations/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-resource-operations">
<fileset dir="${basedir}/vendor/sebastian/resource-operations/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/global-state/LICENSE" tofile="${basedir}/build/phar/sebastian-global-state/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-global-state">
<fileset dir="${basedir}/vendor/sebastian/global-state/src">
@@ -244,6 +236,20 @@
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/recursion-context/LICENSE" tofile="${basedir}/build/phar/sebastian-recursion-context/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-recursion-context">
<fileset dir="${basedir}/vendor/sebastian/recursion-context/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/resource-operations/LICENSE" tofile="${basedir}/build/phar/sebastian-resource-operations/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-resource-operations">
<fileset dir="${basedir}/vendor/sebastian/resource-operations/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/sebastian/version/LICENSE" tofile="${basedir}/build/phar/sebastian-version/LICENSE"/>
<copy todir="${basedir}/build/phar/sebastian-version">
<fileset dir="${basedir}/vendor/sebastian/version/src">
@@ -258,8 +264,23 @@
</fileset>
</copy>
<copy todir="${basedir}/build/phar/php-invoker">
<fileset dir="${basedir}/vendor/phpunit/php-invoker/src">
<copy file="${basedir}/vendor/myclabs/deep-copy/LICENSE" tofile="${basedir}/build/phar/myclabs-deep-copy/LICENSE"/>
<copy todir="${basedir}/build/phar/myclabs-deep-copy">
<fileset dir="${basedir}/vendor/myclabs/deep-copy/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/phar-io/manifest/LICENSE" tofile="${basedir}/build/phar/phar-io-manifest/LICENSE"/>
<copy todir="${basedir}/build/phar/phar-io-manifest">
<fileset dir="${basedir}/vendor/phar-io/manifest/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/phar-io/version/LICENSE" tofile="${basedir}/build/phar/phar-io-version/LICENSE"/>
<copy todir="${basedir}/build/phar/phar-io-version">
<fileset dir="${basedir}/vendor/phar-io/version/src">
<include name="**/*.php" />
</fileset>
</copy>
@@ -292,9 +313,9 @@
</fileset>
</copy>
<copy file="${basedir}/vendor/myclabs/deep-copy/LICENSE" tofile="${basedir}/build/phar/myclabs-deep-copy/LICENSE"/>
<copy todir="${basedir}/build/phar/myclabs-deep-copy">
<fileset dir="${basedir}/vendor/myclabs/deep-copy/src">
<copy file="${basedir}/vendor/theseer/tokenizer/LICENSE" tofile="${basedir}/build/phar/theseer-tokenizer/LICENSE"/>
<copy todir="${basedir}/build/phar/theseer-tokenizer">
<fileset dir="${basedir}/vendor/theseer/tokenizer/src">
<include name="**/*.php" />
</fileset>
</copy>
@@ -305,27 +326,6 @@
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/phar-io/manifest/LICENSE" tofile="${basedir}/build/phar/phar-io-manifest/LICENSE"/>
<copy todir="${basedir}/build/phar/phar-io-manifest">
<fileset dir="${basedir}/vendor/phar-io/manifest/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/phar-io/version/LICENSE" tofile="${basedir}/build/phar/phar-io-version/LICENSE"/>
<copy todir="${basedir}/build/phar/phar-io-version">
<fileset dir="${basedir}/vendor/phar-io/version/src">
<include name="**/*.php" />
</fileset>
</copy>
<copy file="${basedir}/vendor/theseer/tokenizer/LICENSE" tofile="${basedir}/build/phar/theseer-tokenizer/LICENSE"/>
<copy todir="${basedir}/build/phar/theseer-tokenizer">
<fileset dir="${basedir}/vendor/theseer/tokenizer/src">
<include name="**/*.php" />
</fileset>
</copy>
</target>
<target name="-phar-build" depends="-phar-determine-version">

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpab" version="^1.25" installed="1.25.6" location="./tools/phpab" copy="true"/>
<phar name="php-cs-fixer" version="^2.14" installed="2.15.1" location="./tools/php-cs-fixer" copy="true"/>
<phar name="php-cs-fixer" version="^2.14" installed="2.15.3" location="./tools/php-cs-fixer" copy="true"/>
<phar name="phpdox" version="^0.11" installed="0.12.0" location="./tools/phpdox" copy="true"/>
<phar name="phploc" version="^4.0" installed="4.0.1" location="./tools/phploc" copy="true"/>
</phive>

View File

@@ -13,7 +13,7 @@ if (version_compare('7.1.0', PHP_VERSION, '>')) {
fwrite(
STDERR,
sprintf(
'This version of PHPUnit is supported on PHP 7.1 and PHP 7.2.' . PHP_EOL .
'This version of PHPUnit is supported on PHP 7.1, PHP 7.2, and PHP 7.3.' . PHP_EOL .
'You are using PHP %s (%s).' . PHP_EOL,
PHP_VERSION,
PHP_BINARY

View File

@@ -233,7 +233,7 @@
<xs:attribute name="bootstrap" type="xs:anyURI"/>
<xs:attribute name="cacheResult" type="xs:boolean" default="false"/>
<xs:attribute name="cacheResultFile" type="xs:anyURI"/>
<xs:attribute name="cacheTokens" type="xs:boolean"/>
<xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
<xs:attribute name="colors" type="xs:boolean" default="false"/>
<xs:attribute name="columns" type="columnsType" default="80"/>
<xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>

View File

@@ -12,6 +12,6 @@ namespace PHPUnit;
/**
* Marker interface for PHPUnit exceptions.
*/
interface Exception
interface Exception extends \Throwable
{
}

View File

@@ -55,6 +55,10 @@ class Count extends Constraint
return \count($other);
}
if ($other instanceof \EmptyIterator) {
return 0;
}
if ($other instanceof Traversable) {
while ($other instanceof IteratorAggregate) {
$other = $other->getIterator();

View File

@@ -32,6 +32,10 @@ class IsEmpty extends Constraint
*/
protected function matches($other): bool
{
if ($other instanceof \EmptyIterator) {
return true;
}
if ($other instanceof Countable) {
return \count($other) === 0;
}

View File

@@ -9,6 +9,8 @@
*/
namespace PHPUnit\Framework\Constraint;
use PHPUnit\Util\InvalidArgumentHelper;
/**
* Constraint that asserts that the string it is evaluated for begins with a
* given prefix.
@@ -24,6 +26,10 @@ class StringStartsWith extends Constraint
{
parent::__construct();
if (\strlen($prefix) === 0) {
throw InvalidArgumentHelper::factory(1, 'non-empty string');
}
$this->prefix = $prefix;
}

View File

@@ -24,6 +24,10 @@ class DataProviderTestSuite extends TestSuite
$this->dependencies = $dependencies;
foreach ($this->tests as $test) {
if (!$test instanceof TestCase) {
continue;
}
$test->setDependencies($dependencies);
}
}

View File

@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;
/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class InvalidParameterGroupException extends Exception
{
}

View File

@@ -12,6 +12,6 @@ namespace PHPUnit\Framework\MockObject;
/**
* Interface for exceptions used by PHPUnit_MockObject.
*/
interface Exception
interface Exception extends \Throwable
{
}

View File

@@ -12,6 +12,7 @@ namespace PHPUnit\Framework\MockObject\Matcher;
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\Constraint\IsEqual;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\InvalidParameterGroupException;
use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
/**
@@ -42,6 +43,16 @@ class ConsecutiveParameters extends StatelessInvocation
public function __construct(array $parameterGroups)
{
foreach ($parameterGroups as $index => $parameters) {
if (!\is_iterable($parameters)) {
throw new InvalidParameterGroupException(
\sprintf(
'Parameter group #%d must be an array or Traversable, got %s',
$index,
\gettype($parameters)
)
);
}
foreach ($parameters as $parameter) {
if (!$parameter instanceof Constraint) {
$parameter = new IsEqual($parameter);

View File

@@ -102,7 +102,7 @@ final class MockMethod
}
if ($method->hasReturnType()) {
$returnType = (string) $method->getReturnType();
$returnType = $method->getReturnType()->getName();
} else {
$returnType = '';
}
@@ -301,8 +301,8 @@ final class MockMethod
$nullable = '?';
}
if ($parameter->hasType() && (string) $parameter->getType() !== 'self') {
$typeDeclaration = $parameter->getType() . ' ';
if ($parameter->hasType() && $parameter->getType()->getName() !== 'self') {
$typeDeclaration = $parameter->getType()->getName() . ' ';
} else {
try {
$class = $parameter->getClass();
@@ -326,13 +326,14 @@ final class MockMethod
if (!$parameter->isVariadic()) {
if ($parameter->isDefaultValueAvailable()) {
$value = $parameter->getDefaultValueConstantName();
if ($value === null) {
try {
$value = \var_export($parameter->getDefaultValue(), true);
} elseif (!\defined($value)) {
$rootValue = \preg_replace('/^.*\\\\/', '', $value);
$value = \defined($rootValue) ? $rootValue : $value;
} catch (\ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
$default = ' = ' . $value;

View File

@@ -1662,22 +1662,16 @@ abstract class TestCase extends Assert implements SelfDescribing, Test
if ($this->prophet !== null) {
try {
$this->prophet->checkPredictions();
} catch (Throwable $t) {
/* Intentionally left empty */
}
foreach ($this->prophet->getProphecies() as $objectProphecy) {
foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
/** @var MethodProphecy[] $methodProphecies */
foreach ($methodProphecies as $methodProphecy) {
$this->numAssertions += \count($methodProphecy->getCheckedPredictions());
} finally {
foreach ($this->prophet->getProphecies() as $objectProphecy) {
foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
/** @var MethodProphecy[] $methodProphecies */
foreach ($methodProphecies as $methodProphecy) {
$this->numAssertions += \count($methodProphecy->getCheckedPredictions());
}
}
}
}
if (isset($t)) {
throw $t;
}
}
}

View File

@@ -863,13 +863,16 @@ class TestResult implements Countable
if ($name && $reflected->hasMethod($name)) {
$reflected = $reflected->getMethod($name);
}
$this->addFailure(
$test,
new RiskyTestError(\sprintf(
"This test did not perform any assertions\n\n%s:%d",
$reflected->getFileName(),
$reflected->getStartLine()
)),
new RiskyTestError(
\sprintf(
"This test did not perform any assertions\n\n%s:%d",
$reflected->getFileName(),
$reflected->getStartLine()
)
),
$time
);
} elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
@@ -877,10 +880,12 @@ class TestResult implements Countable
$test->getNumAssertions() > 0) {
$this->addFailure(
$test,
new RiskyTestError(\sprintf(
'This test is annotated with "@doesNotPerformAssertions" but performed %d assertions',
$test->getNumAssertions()
)),
new RiskyTestError(
\sprintf(
'This test is annotated with "@doesNotPerformAssertions" but performed %d assertions',
$test->getNumAssertions()
)
),
$time
);
} elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) {

View File

@@ -61,7 +61,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
/**
* The tests in the test suite.
*
* @var TestCase[]
* @var Test[]
*/
protected $tests = [];
@@ -800,6 +800,8 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
/**
* Returns the tests as an enumeration.
*
* @return Test[]
*/
public function tests(): array
{
@@ -808,6 +810,8 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
/**
* Set tests of the test suite
*
* @param Test[] $tests
*/
public function setTests(array $tests): void
{

View File

@@ -19,7 +19,7 @@ final class TestSuiteIterator implements RecursiveIterator
/**
* @var int
*/
private $position;
private $position = 0;
/**
* @var Test[]
@@ -58,7 +58,7 @@ final class TestSuiteIterator implements RecursiveIterator
/**
* Returns the current element.
*/
public function current(): Test
public function current(): ?Test
{
return $this->valid() ? $this->tests[$this->position] : null;
}
@@ -73,12 +73,22 @@ final class TestSuiteIterator implements RecursiveIterator
/**
* Returns the sub iterator for the current element.
*
* @throws \UnexpectedValueException if the current element is no TestSuite
*/
public function getChildren(): self
{
return new self(
$this->tests[$this->position]
);
if (!$this->hasChildren()) {
throw new UnexpectedValueException(
'The current item is no TestSuite instance and hence cannot have any children.',
1567849414
);
}
/** @var TestSuite $current */
$current = $this->current();
return new self($current);
}
/**
@@ -86,6 +96,6 @@ final class TestSuiteIterator implements RecursiveIterator
*/
public function hasChildren(): bool
{
return $this->tests[$this->position] instanceof TestSuite;
return $this->current() instanceof TestSuite;
}
}

View File

@@ -0,0 +1,14 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;
final class UnexpectedValueException extends Exception
{
}

View File

@@ -35,17 +35,17 @@ class PhptTestCase implements SelfDescribing, Test
'auto_prepend_file=',
'disable_functions=',
'display_errors=1',
'docref_root=',
'docref_ext=.html',
'docref_root=',
'error_append_string=',
'error_prepend_string=',
'error_reporting=-1',
'html_errors=0',
'log_errors=0',
'magic_quotes_runtime=0',
'output_handler=',
'open_basedir=',
'output_buffering=Off',
'output_handler=',
'report_memleaks=0',
'report_zend_debug=0',
'safe_mode=0',
@@ -177,7 +177,7 @@ class PhptTestCase implements SelfDescribing, Test
}
try {
$this->assertPhptExpectation($sections, $jobResult['stdout']);
$this->assertPhptExpectation($sections, $this->output);
} catch (AssertionFailedError $e) {
$failure = $e;
@@ -366,20 +366,20 @@ class PhptTestCase implements SelfDescribing, Test
$section = '';
$unsupportedSections = [
'REDIRECTTEST',
'REQUEST',
'POST',
'PUT',
'POST_RAW',
'GZIP_POST',
'DEFLATE_POST',
'GET',
'COOKIE',
'HEADERS',
'CGI',
'COOKIE',
'DEFLATE_POST',
'EXPECTHEADERS',
'EXTENSIONS',
'GET',
'GZIP_POST',
'HEADERS',
'PHPDBG',
'POST',
'POST_RAW',
'PUT',
'REDIRECTTEST',
'REQUEST',
];
foreach (\file($this->filename) as $line) {

View File

@@ -177,7 +177,10 @@ final class TestSuiteSorter
}
if ($resolveDependencies && !($suite instanceof DataProviderTestSuite) && $this->suiteOnlyContainsTests($suite)) {
$suite->setTests($this->resolveDependencies($suite->tests()));
/** @var TestCase[] $tests */
$tests = $suite->tests();
$suite->setTests($this->resolveDependencies($tests));
}
}

View File

@@ -30,7 +30,7 @@ class Version
}
if (self::$version === null) {
$version = new VersionId('7.5.13', \dirname(__DIR__, 2));
$version = new VersionId('7.5.17', \dirname(__DIR__, 2));
self::$version = $version->getVersion();
}

View File

@@ -45,7 +45,7 @@ class JUnit extends Printer implements TestListener
/**
* @var bool
*/
protected $reportUselessTests = false;
protected $reportRiskyTests = false;
/**
* @var bool
@@ -104,7 +104,7 @@ class JUnit extends Printer implements TestListener
*
* @throws \PHPUnit\Framework\Exception
*/
public function __construct($out = null, bool $reportUselessTests = false)
public function __construct($out = null, bool $reportRiskyTests = false)
{
$this->document = new DOMDocument('1.0', 'UTF-8');
$this->document->formatOutput = true;
@@ -114,7 +114,7 @@ class JUnit extends Printer implements TestListener
parent::__construct($out);
$this->reportUselessTests = $reportUselessTests;
$this->reportRiskyTests = $reportRiskyTests;
}
/**
@@ -175,7 +175,7 @@ class JUnit extends Printer implements TestListener
*/
public function addRiskyTest(Test $test, \Throwable $t, float $time): void
{
if (!$this->reportUselessTests || $this->currentTestCase === null) {
if (!$this->reportRiskyTests || $this->currentTestCase === null) {
return;
}

View File

@@ -212,7 +212,7 @@ class TeamCity extends ResultPrinter
} else {
$split = \explode('::', $suiteName);
if (\count($split) === 2 && \method_exists($split[0], $split[1])) {
if (\count($split) === 2 && \class_exists($split[0]) && \method_exists($split[0], $split[1])) {
$fileName = self::getFileName($split[0]);
$parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
$parameters['name'] = $split[1];
@@ -238,7 +238,7 @@ class TeamCity extends ResultPrinter
if (!\class_exists($suiteName, false)) {
$split = \explode('::', $suiteName);
if (\count($split) === 2 && \method_exists($split[0], $split[1])) {
if (\count($split) === 2 && \class_exists($split[0]) && \method_exists($split[0], $split[1])) {
$parameters['name'] = $split[1];
}
}

View File

@@ -42,29 +42,33 @@ class Printer
*/
public function __construct($out = null)
{
if ($out !== null) {
if (\is_string($out)) {
if (\strpos($out, 'socket://') === 0) {
$out = \explode(':', \str_replace('socket://', '', $out));
if (\count($out) !== 2) {
throw new Exception;
}
$this->out = \fsockopen($out[0], $out[1]);
} else {
if (\strpos($out, 'php://') === false && !Filesystem::createDirectory(\dirname($out))) {
throw new Exception(\sprintf('Directory "%s" was not created', \dirname($out)));
}
$this->out = \fopen($out, 'wt');
}
$this->outTarget = $out;
} else {
$this->out = $out;
}
if ($out === null) {
return;
}
if (\is_string($out) === false) {
$this->out = $out;
return;
}
if (\strpos($out, 'socket://') === 0) {
$out = \explode(':', \str_replace('socket://', '', $out));
if (\count($out) !== 2) {
throw new Exception;
}
$this->out = \fsockopen($out[0], $out[1]);
} else {
if (\strpos($out, 'php://') === false && !Filesystem::createDirectory(\dirname($out))) {
throw new Exception(\sprintf('Directory "%s" was not created', \dirname($out)));
}
$this->out = \fopen($out, 'wt');
}
$this->outTarget = $out;
}
/**

View File

@@ -293,7 +293,7 @@ final class Test
foreach ($required['functions'] as $function) {
$pieces = \explode('::', $function);
if (\count($pieces) === 2 && \method_exists($pieces[0], $pieces[1])) {
if (\count($pieces) === 2 && \class_exists($pieces[0]) && \method_exists($pieces[0], $pieces[1])) {
continue;
}

View File

@@ -53,7 +53,10 @@ EOF;
$path = \realpath($directory['path']);
if (\is_string($path)) {
$files[] = \sprintf('%s/', $path);
$files[] = \sprintf(
\addslashes('%s' . \DIRECTORY_SEPARATOR),
$path
);
}
}
}

View File

@@ -0,0 +1,19 @@
--TEST--
phpunit --columns=max BankAccountTest ../../_files/BankAccountTest.php
--FILE--
<?php declare(strict_types=1);
$_SERVER['argv'][1] = '--no-configuration';
$_SERVER['argv'][2] = '--columns=max';
$_SERVER['argv'][3] = 'BankAccountTest';
$_SERVER['argv'][4] = __DIR__ . '/../../_files/BankAccountTest.php';
require __DIR__ . '/../../bootstrap.php';
PHPUnit\TextUI\Command::main();
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.
... 3 / 3 (100%)
Time: %s, Memory: %s
OK (3 tests, 3 assertions)

View File

@@ -0,0 +1,19 @@
--TEST--
phpunit --columns=40 BankAccountTest ../../_files/BankAccountTest.php
--FILE--
<?php declare(strict_types=1);
$_SERVER['argv'][1] = '--no-configuration';
$_SERVER['argv'][2] = '--columns=40';
$_SERVER['argv'][3] = 'BankAccountTest';
$_SERVER['argv'][4] = __DIR__ . '/../../_files/BankAccountTest.php';
require __DIR__ . '/../../bootstrap.php';
PHPUnit\TextUI\Command::main();
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.
... 3 / 3 (100%)
Time: %s, Memory: %s
OK (3 tests, 3 assertions)

View File

@@ -0,0 +1,21 @@
--TEST--
phpunit --generate-configuration
--STDIN--
--FILE--
<?php declare(strict_types=1);
$_SERVER['argv'][1] = '--no-configuration';
$_SERVER['argv'][2] = '--generate-configuration';
require __DIR__ . '/../../bootstrap.php';
chdir(sys_get_temp_dir());
PHPUnit\TextUI\Command::main();
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.
Generating phpunit.xml in %s
Bootstrap script (relative to path shown above; default: vendor/autoload.php): Tests directory (relative to path shown above; default: tests): Source directory (relative to path shown above; default: src):
Generated phpunit.xml in %s

View File

@@ -14,7 +14,7 @@ namespace Is\Namespaced;
*/
const A_CONSTANT = 17;
const PHP_VERSION = "0.0.0";
const PHP_VERSION = "";
class Issue3154
{
@@ -36,7 +36,7 @@ $mock = $generator->generate(
);
print $mock['code'];
--EXPECT--
--EXPECTF--
class Issue3154Mock extends Is\Namespaced\Issue3154 implements PHPUnit\Framework\MockObject\MockObject
{
private $__phpunit_invocationMocker;
@@ -49,7 +49,7 @@ class Issue3154Mock extends Is\Namespaced\Issue3154 implements PHPUnit\Framework
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
}
public function a(int $i = PHP_INT_MAX, int $j = Is\Namespaced\A_CONSTANT, string $v = PHP_VERSION, string $z = '#'): string
public function a(int $i = %d, int $j = 17, string $v = '%s', string $z = '#'): string
{
$__phpunit_arguments = [$i, $j, $v, $z];
$__phpunit_count = func_num_args();

View File

@@ -4,7 +4,7 @@
<?php
class Foo
{
public function bar(int $baz = PHP_INT_MIN)
public function bar(int $baz = PHP_INT_MAX)
{
}
}
@@ -23,7 +23,7 @@ $mock = $generator->generate(
print $mock['code'];
?>
--EXPECT--
--EXPECTF--
class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObject
{
private $__phpunit_invocationMocker;
@@ -36,7 +36,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObject
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
}
public function bar(int $baz = PHP_INT_MIN)
public function bar(int $baz = %d)
{
$__phpunit_arguments = [$baz];
$__phpunit_count = func_num_args();

View File

@@ -1,12 +1,15 @@
--TEST--
Mock static method
--FILE--
<?php
define('FOO_CONST', 1);
<?php declare(strict_types=1);
define('GLOBAL_CONSTANT', 1);
class Foo
{
private function bar($arg = FOO_CONST){}
public const CLASS_CONSTANT_PUBLIC = 2;
protected const CLASS_CONSTANT_PROTECTED = 3;
private const CLASS_CONSTANT_PRIVATE = 4;
private function bar($a = GLOBAL_CONSTANT, $b = self::CLASS_CONSTANT_PUBLIC, $c = self::CLASS_CONSTANT_PROTECTED, $d = self::CLASS_CONSTANT_PRIVATE){}
}
require __DIR__ . '/../../../../vendor/autoload.php';
@@ -24,15 +27,15 @@ print $code;
?>
--EXPECT--
private function bar($arg = FOO_CONST)
private function bar($a = 1, $b = 2, $c = 3, $d = 4)
{
$__phpunit_arguments = [$arg];
$__phpunit_arguments = [$a, $b, $c, $d];
$__phpunit_count = func_num_args();
if ($__phpunit_count > 1) {
if ($__phpunit_count > 4) {
$__phpunit_arguments_tmp = func_get_args();
for ($__phpunit_i = 1; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
for ($__phpunit_i = 4; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
$__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
}
}

View File

@@ -0,0 +1,13 @@
--TEST--
phpunit --version
--FILE--
<?php
$_SERVER['argv'][1] = '--no-configuration';
$_SERVER['argv'][2] = '--version';
require __DIR__ . '/../bootstrap.php';
PHPUnit\TextUI\Command::main();
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

View File

@@ -142,4 +142,14 @@ class CountTest extends ConstraintTestCase
$this->assertNotInstanceOf(\IteratorAggregate::class, $datePeriod);
$this->assertTrue($countConstraint->evaluate($datePeriod, '', true));
}
/**
* @ticket https://github.com/sebastianbergmann/phpunit/issues/3743
*/
public function test_EmptyIterator_is_handled_correctly(): void
{
$constraint = new Count(0);
$this->assertTrue($constraint->evaluate(new \EmptyIterator, '', true));
}
}

View File

@@ -64,4 +64,14 @@ EOF
$this->fail();
}
/**
* @ticket https://github.com/sebastianbergmann/phpunit/issues/3743
*/
public function test_EmptyIterator_is_handled_correctly(): void
{
$constraint = new IsEmpty;
$this->assertTrue($constraint->evaluate(new \EmptyIterator, '', true));
}
}

View File

@@ -35,6 +35,13 @@ class StringStartsWithTest extends ConstraintTestCase
$this->assertTrue($constraint->evaluate('0E1zzz', '', true));
}
public function testConstraintStringStartsWithCorrectSingleZeroAndReturnResult(): void
{
$constraint = new StringStartsWith('0');
$this->assertTrue($constraint->evaluate('0ABC', '', true));
}
public function testConstraintStringStartsWithNotCorrectNumericValueAndReturnResult(): void
{
$constraint = new StringStartsWith('0E1');

View File

@@ -9,6 +9,7 @@
*/
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\InvalidParameterGroupException;
use PHPUnit\Framework\TestCase;
class ConsecutiveParametersTest extends TestCase
@@ -65,4 +66,21 @@ class ConsecutiveParametersTest extends TestCase
$mock->foo('invalid');
}
public function testIntegrationFailsWithNonIterableParameterGroup(): void
{
$mock = $this->getMockBuilder(stdClass::class)
->setMethods(['foo'])
->getMock();
$this->expectException(InvalidParameterGroupException::class);
$this->expectExceptionMessage('Parameter group #1 must be an array or Traversable, got object');
$mock->expects($this->any())
->method('foo')
->withConsecutive(
['bar'],
$this->identicalTo([21, 42]) // this is not an array
);
}
}

View File

@@ -0,0 +1,216 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;
/**
* @small
*/
final class TestSuiteIteratorTest extends TestCase
{
/*
* tests for the initial state with empty test suite
*/
public function testKeyForEmptyTestSuiteInitiallyReturnsZero(): void
{
$testSuite = new TestSuite();
$subject = new TestSuiteIterator($testSuite);
$this->assertSame(0, $subject->key());
}
public function testValidForEmptyTestSuiteInitiallyReturnsFalse(): void
{
$testSuite = new TestSuite();
$subject = new TestSuiteIterator($testSuite);
$this->assertFalse($subject->valid());
}
public function testCurrentForEmptyTestSuiteInitiallyReturnsNull(): void
{
$testSuite = new TestSuite();
$subject = new TestSuiteIterator($testSuite);
$this->assertNull($subject->current());
}
/*
* tests for the initial state with non-empty test suite
*/
public function testKeyForNonEmptyTestSuiteInitiallyReturnsZero(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$this->assertSame(0, $subject->key());
}
public function testValidForNonEmptyTestSuiteInitiallyReturnsTrue(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$this->assertTrue($subject->valid());
}
public function testCurrentForNonEmptyTestSuiteInitiallyReturnsFirstTest(): void
{
$test = new \EmptyTestCaseTest();
$testSuite = new TestSuite();
$testSuite->addTest($test);
$subject = new TestSuiteIterator($testSuite);
$this->assertSame($test, $subject->current());
}
/*
* tests for rewind
*/
public function testRewindResetsKeyToZero(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$subject->next();
$subject->rewind();
$this->assertSame(0, $subject->key());
}
public function testRewindResetsCurrentToFirstElement(): void
{
$testSuite = new TestSuite();
$test = new \EmptyTestCaseTest();
$testSuite->addTest($test);
$subject = new TestSuiteIterator($testSuite);
$subject->next();
$subject->rewind();
$this->assertSame($test, $subject->current());
}
/*
* tests for next
*/
public function testNextIncreasesKeyFromZeroToOne(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$subject->next();
$this->assertSame(1, $subject->key());
}
public function testCurrentAfterLastElementReturnsNull(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$subject->next();
$this->assertNull($subject->current());
}
public function testValidAfterLastElementReturnsFalse(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$subject->next();
$this->assertFalse($subject->valid());
}
/*
* tests for getChildren
*/
public function testGetChildrenForEmptyTestSuiteThrowsException(): void
{
$testSuite = new TestSuite();
$subject = new TestSuiteIterator($testSuite);
$this->expectException(UnexpectedValueException::class);
$subject->getChildren();
}
public function testGetChildrenForCurrentTestThrowsException(): void
{
$testSuite = new TestSuite();
$testSuite->addTest(new \EmptyTestCaseTest());
$subject = new TestSuiteIterator($testSuite);
$this->expectException(UnexpectedValueException::class);
$subject->getChildren();
}
public function testGetChildrenReturnsNewInstanceWithCurrentTestSuite(): void
{
$childSuite = new TestSuite();
$test = new \EmptyTestCaseTest();
$childSuite->addTest($test);
$testSuite = new TestSuite();
$testSuite->addTest($childSuite);
$subject = new TestSuiteIterator($testSuite);
$children = $subject->getChildren();
$this->assertNotSame($subject, $children);
$this->assertSame($test, $children->current());
}
/*
* tests for hasChildren
*/
public function testHasChildrenForCurrentTestSuiteReturnsTrue(): void
{
$testSuite = new TestSuite();
$childSuite = new TestSuite();
$testSuite->addTest($childSuite);
$subject = new TestSuiteIterator($testSuite);
$this->assertTrue($subject->hasChildren());
}
public function testHasChildrenForCurrentTestReturnsFalse(): void
{
$testSuite = new TestSuite();
$test = new \EmptyTestCaseTest();
$testSuite->addTest($test);
$subject = new TestSuiteIterator($testSuite);
$this->assertFalse($subject->hasChildren());
}
public function testHasChildrenForNoTestsReturnsFalse(): void
{
$testSuite = new TestSuite();
$subject = new TestSuiteIterator($testSuite);
$this->assertFalse($subject->hasChildren());
}
}