123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- <?php
- /*
- * This file is part of PHP CS Fixer.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- * Dariusz Rumiński <dariusz.ruminski@gmail.com>
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
- namespace PhpCsFixer\Tests;
- use PhpCsFixer\ConfigurationException\InvalidForEnvFixerConfigurationException;
- use PhpCsFixer\FixerFactory;
- use PhpCsFixer\RuleSet;
- use PhpCsFixer\Test\AccessibleObject;
- use PHPUnit\Framework\TestCase;
- /**
- * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
- *
- * @internal
- *
- * @covers \PhpCsFixer\RuleSet
- */
- final class RuleSetTest extends TestCase
- {
- public function testCreate()
- {
- $ruleSet = RuleSet::create();
- $this->assertInstanceOf('PhpCsFixer\RuleSet', $ruleSet);
- }
- /**
- * @param string $ruleName
- * @param string $setName
- * @param array|bool $ruleConfig
- *
- * @dataProvider provideAllRulesFromSetsCases
- */
- public function testIfAllRulesInSetsExists($setName, $ruleName, $ruleConfig)
- {
- $factory = new FixerFactory();
- $factory->registerBuiltInFixers();
- $fixers = array();
- foreach ($factory->getFixers() as $fixer) {
- $fixers[$fixer->getName()] = $fixer;
- }
- $this->assertArrayHasKey($ruleName, $fixers, sprintf('RuleSet "%s" contains unknown rule.', $setName));
- if (true === $ruleConfig) {
- return; // rule doesn't need configuration.
- }
- $fixer = $fixers[$ruleName];
- $this->assertInstanceOf('PhpCsFixer\Fixer\ConfigurableFixerInterface', $fixer, sprintf('RuleSet "%s" contains configuration for rule "%s" which cannot be configured.', $setName, $ruleName));
- try {
- $fixer->configure($ruleConfig); // test fixer accepts the configuration
- } catch (InvalidForEnvFixerConfigurationException $exception) {
- // ignore
- }
- }
- public function provideAllRulesFromSetsCases()
- {
- $cases = array();
- foreach (RuleSet::create()->getSetDefinitionNames() as $setName) {
- foreach (RuleSet::create(array($setName => true))->getRules() as $rule => $config) {
- $cases[] = array(
- $setName,
- $rule,
- $config,
- );
- }
- }
- return $cases;
- }
- public function testGetBuildInSetDefinitionNames()
- {
- $setNames = RuleSet::create()->getSetDefinitionNames();
- $this->assertInternalType('array', $setNames);
- $this->assertNotEmpty($setNames);
- }
- /**
- * @dataProvider provideSetDefinitionNameCases
- *
- * @param mixed $setName
- */
- public function testBuildInSetDefinitionNames($setName)
- {
- $this->assertInternalType('string', $setName);
- $this->assertSame('@', substr($setName, 0, 1));
- }
- public function testResolveRulesWithInvalidSet()
- {
- $this->setExpectedException(
- 'InvalidArgumentException',
- 'Set "@foo" does not exist.'
- );
- RuleSet::create(array(
- '@foo' => true,
- ));
- }
- public function testResolveRulesWithMissingRuleValue()
- {
- $this->setExpectedException(
- 'InvalidArgumentException',
- 'Missing value for "braces" rule/set.'
- );
- RuleSet::create(array(
- 'braces',
- ));
- }
- public function testResolveRulesWithSet()
- {
- $ruleSet = RuleSet::create(array(
- '@PSR1' => true,
- 'braces' => true,
- 'encoding' => false,
- 'line_ending' => true,
- 'strict_comparison' => true,
- ));
- $this->assertSameRules(
- array(
- 'braces' => true,
- 'full_opening_tag' => true,
- 'line_ending' => true,
- 'strict_comparison' => true,
- ),
- $ruleSet->getRules()
- );
- }
- public function testResolveRulesWithNestedSet()
- {
- $ruleSet = RuleSet::create(array(
- '@PSR2' => true,
- 'strict_comparison' => true,
- ));
- $this->assertSameRules(
- array(
- 'blank_line_after_namespace' => true,
- 'braces' => true,
- 'class_definition' => true,
- 'elseif' => true,
- 'encoding' => true,
- 'full_opening_tag' => true,
- 'function_declaration' => true,
- 'indentation_type' => true,
- 'line_ending' => true,
- 'lowercase_constants' => true,
- 'lowercase_keywords' => true,
- 'method_argument_space' => true,
- 'no_closing_tag' => true,
- 'no_spaces_after_function_name' => true,
- 'no_spaces_inside_parenthesis' => true,
- 'no_trailing_whitespace' => true,
- 'no_trailing_whitespace_in_comment' => true,
- 'single_blank_line_at_eof' => true,
- 'single_class_element_per_statement' => array('elements' => array('property')),
- 'single_import_per_statement' => true,
- 'single_line_after_imports' => true,
- 'strict_comparison' => true,
- 'switch_case_semicolon_to_colon' => true,
- 'switch_case_space' => true,
- 'visibility_required' => true,
- ),
- $ruleSet->getRules()
- );
- }
- public function testResolveRulesWithDisabledSet()
- {
- $ruleSet = RuleSet::create(array(
- '@PSR2' => true,
- '@PSR1' => false,
- 'encoding' => true,
- ));
- $this->assertSameRules(
- array(
- 'blank_line_after_namespace' => true,
- 'braces' => true,
- 'class_definition' => true,
- 'elseif' => true,
- 'encoding' => true,
- 'function_declaration' => true,
- 'indentation_type' => true,
- 'line_ending' => true,
- 'lowercase_constants' => true,
- 'lowercase_keywords' => true,
- 'method_argument_space' => true,
- 'no_closing_tag' => true,
- 'no_spaces_after_function_name' => true,
- 'no_spaces_inside_parenthesis' => true,
- 'no_trailing_whitespace' => true,
- 'no_trailing_whitespace_in_comment' => true,
- 'single_blank_line_at_eof' => true,
- 'single_class_element_per_statement' => array('elements' => array('property')),
- 'single_import_per_statement' => true,
- 'single_line_after_imports' => true,
- 'switch_case_semicolon_to_colon' => true,
- 'switch_case_space' => true,
- 'visibility_required' => true,
- ),
- $ruleSet->getRules()
- );
- }
- /**
- * @dataProvider provideSetDefinitionNameCases
- *
- * @param string $setDefinitionName
- */
- public function testSetDefinitionsAreSorted($setDefinitionName)
- {
- $ruleSet = RuleSet::create();
- $method = new \ReflectionMethod(
- 'PhpCsFixer\RuleSet',
- 'getSetDefinition'
- );
- $method->setAccessible(true);
- $setDefinition = $method->invoke(
- $ruleSet,
- $setDefinitionName
- );
- $sortedSetDefinition = $setDefinition;
- $this->sort($sortedSetDefinition);
- $this->assertSame($sortedSetDefinition, $setDefinition, sprintf(
- 'Failed to assert that the set definition for "%s" is sorted by key',
- $setDefinitionName
- ));
- }
- /**
- * @return array
- */
- public function provideSetDefinitionNameCases()
- {
- $setDefinitionNames = RuleSet::create()->getSetDefinitionNames();
- return array_map(function ($setDefinitionName) {
- return array($setDefinitionName);
- }, $setDefinitionNames);
- }
- /**
- * @param array $set
- * @param bool $safe
- *
- * @dataProvider provideSafeSetCases
- */
- public function testRiskyRulesInSet(array $set, $safe)
- {
- try {
- $fixers = FixerFactory::create()
- ->registerBuiltInFixers()
- ->useRuleSet(new RuleSet($set))
- ->getFixers()
- ;
- } catch (InvalidForEnvFixerConfigurationException $exception) {
- $this->markTestSkipped($exception->getMessage());
- }
- $fixerNames = array();
- foreach ($fixers as $fixer) {
- if ($safe === $fixer->isRisky()) {
- $fixerNames[] = $fixer->getName();
- }
- }
- $this->assertCount(
- 0,
- $fixerNames,
- sprintf(
- 'Set should only contain %s fixers, got: \'%s\'.',
- $safe ? 'safe' : 'risky',
- implode('\', \'', $fixerNames)
- )
- );
- }
- public function provideSafeSetCases()
- {
- $sets = array();
- $ruleSet = new RuleSet();
- foreach ($ruleSet->getSetDefinitionNames() as $name) {
- $sets[$name] = array(
- array($name => true),
- false === strpos($name, ':risky'),
- );
- }
- $sets['@Symfony:risky_and_@Symfony'] = array(
- array(
- '@Symfony:risky' => true,
- '@Symfony' => false,
- ),
- false,
- );
- return $sets;
- }
- public function testInvalidConfigNestedSets()
- {
- $this->setExpectedExceptionRegExp(
- '\UnexpectedValueException',
- '#^Nested rule set "@PSR1" configuration must be a boolean\.$#'
- );
- new RuleSet(
- array('@PSR1' => array('@PSR2' => 'no'))
- );
- }
- public function testGetSetDefinitionNames()
- {
- $ruleSet = $this->createRuleSetToTestWith(array());
- $this->assertSame(
- array_keys(self::getRuleSetDefinitionsToTestWith()),
- $ruleSet->getSetDefinitionNames()
- );
- }
- /**
- * @param array $expected
- * @param array $rules
- *
- * @dataProvider provideResolveRulesCases
- */
- public function testResolveRules(array $expected, array $rules)
- {
- $ruleSet = $this->createRuleSetToTestWith($rules);
- $this->assertSameRules($expected, $ruleSet->getRules());
- }
- public function provideResolveRulesCases()
- {
- return array(
- '@Foo + C\' -D' => array(
- array('A' => true, 'B' => true, 'C' => 56),
- array('@Foo' => true, 'C' => 56, 'D' => false),
- ),
- '@Foo + @Bar' => array(
- array('A' => true, 'B' => true, 'D' => 34, 'E' => true),
- array('@Foo' => true, '@Bar' => true),
- ),
- '@Foo - @Bar' => array(
- array('B' => true),
- array('@Foo' => true, '@Bar' => false),
- ),
- '@A - @E (set in set)' => array(
- array('AA' => true), // 'AB' => false, 'AC' => false
- array('@A' => true, '@E' => false),
- ),
- '@A + @E (set in set)' => array(
- array('AA' => true, 'AB' => '_AB', 'AC' => 'b', 'Z' => true),
- array('@A' => true, '@E' => true),
- ),
- '@E + @A (set in set) + rule override' => array(
- array('AC' => 'd', 'AB' => true, 'Z' => true, 'AA' => true),
- array('@E' => true, '@A' => true, 'AC' => 'd'),
- ),
- 'nest single set' => array(
- array('AC' => 'b', 'AB' => '_AB', 'Z' => 'E'),
- array('@F' => true),
- ),
- 'Set reconfigure rule in other set, reconfigure rule.' => array(
- array(
- 'AA' => true,
- 'AB' => true,
- 'AC' => 'abc',
- ),
- array(
- '@A' => true,
- '@D' => true,
- 'AC' => 'abc',
- ),
- ),
- 'Set reconfigure rule in other set.' => array(
- array(
- 'AA' => true,
- 'AB' => true,
- 'AC' => 'b',
- ),
- array(
- '@A' => true,
- '@D' => true,
- ),
- ),
- 'Set minus two sets minus rule' => array(
- array(
- 'AB' => true,
- ),
- array(
- '@A' => true,
- '@B' => false,
- '@C' => false,
- 'AC' => false,
- ),
- ),
- 'Set minus two sets' => array(
- array(
- 'AB' => true,
- 'AC' => 'a',
- ),
- array(
- '@A' => true,
- '@B' => false,
- '@C' => false,
- ),
- ),
- 'Set minus rule test.' => array(
- array(
- 'AA' => true,
- 'AC' => 'a',
- ),
- array(
- '@A' => true,
- 'AB' => false,
- ),
- ),
- 'Set minus set test.' => array(
- array(
- 'AB' => true,
- 'AC' => 'a',
- ),
- array(
- '@A' => true,
- '@B' => false,
- ),
- ),
- 'Set to rules test.' => array(
- array(
- 'AA' => true,
- 'AB' => true,
- 'AC' => 'a',
- ),
- array(
- '@A' => true,
- ),
- ),
- '@A - @C' => array(
- array(
- 'AB' => true,
- 'AC' => 'a',
- ),
- array(
- '@A' => true,
- '@C' => false,
- ),
- ),
- '@A - @D' => array(
- array(
- 'AA' => true,
- 'AB' => true,
- ),
- array(
- '@A' => true,
- '@D' => false,
- ),
- ),
- );
- }
- public function testGetMissingRuleConfiguration()
- {
- $ruleSet = new RuleSet();
- $this->setExpectedExceptionRegExp(
- 'InvalidArgumentException',
- '#^Rule "_not_exists" is not in the set\.$#'
- );
- $ruleSet->getRuleConfiguration('_not_exists');
- }
- private function assertSameRules(array $expected, array $actual, $message = '')
- {
- ksort($expected);
- ksort($actual);
- $this->assertSame($expected, $actual, $message);
- }
- /**
- * Sorts an array of rule set definitions recursively.
- *
- * Sometimes keys are all string, sometimes they are integers - we need to account for that.
- *
- * @param array $data
- */
- private function sort(array &$data)
- {
- $keys = array_keys($data);
- if ($this->allInteger($keys)) {
- sort($data);
- } else {
- ksort($data);
- }
- foreach ($data as $key => $value) {
- if (is_array($value)) {
- $this->sort($data[$key]);
- }
- }
- }
- /**
- * @param array $values
- *
- * @return bool
- */
- private function allInteger(array $values)
- {
- foreach ($values as $value) {
- if (!is_int($value)) {
- return false;
- }
- }
- return true;
- }
- private function createRuleSetToTestWith(array $rules)
- {
- $ruleSet = new RuleSet();
- $reflection = new AccessibleObject($ruleSet);
- $reflection->setDefinitions = self::getRuleSetDefinitionsToTestWith();
- $reflection->set = $rules;
- $reflection->resolveSet();
- return $ruleSet;
- }
- private static function getRuleSetDefinitionsToTestWith()
- {
- static $testSet = array(
- '@A' => array(
- 'AA' => true,
- 'AB' => true,
- 'AC' => 'a',
- ),
- '@B' => array(
- 'AA' => true,
- ),
- '@C' => array(
- 'AA' => false,
- ),
- '@D' => array(
- 'AC' => 'b',
- ),
- '@E' => array(
- '@D' => true,
- 'AB' => '_AB',
- 'Z' => true,
- ),
- '@F' => array(
- '@E' => true,
- 'Z' => 'E',
- ),
- '@Foo' => array('A' => true, 'B' => true, 'C' => true, 'D' => 12),
- '@Bar' => array('A' => true, 'C' => false, 'D' => 34, 'E' => true, 'F' => false),
- );
- return $testSet;
- }
- }
|