* Dariusz RumiƄski * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\Tests\Fixer\Whitespace; use PhpCsFixer\Tests\Test\AbstractFixerTestCase; use PhpCsFixer\WhitespacesFixerConfig; /** * @internal * * @covers \PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer */ final class NoExtraBlankLinesFixerTest extends AbstractFixerTestCase { private $template = <<<'EOF' format('Y')); throw $e; } public function testBreak($a) { switch($a) { case 1: echo $a; break; case 2: echo 'test'; break; } } protected static function testContinueAndReturn($a, $b) { while($a < 100) { if ($b < time()) { continue; } return $b; } return $a; } private function test(){ // comment } private function test123(){ // comment } } EOF; /** * @group legacy * @expectedDeprecation Passing NULL to set default configuration is deprecated and will not be supported in 3.0, use an empty array instead. */ public function testLegacyConfigNull() { $this->fixer->configure(null); $this->doTest($this->removeLinesFromString($this->template, [23, 24]), $this->template); } /** * @param int[] $lineNumberRemoved Line numbers expected to be removed after fixing * * @group legacy * @dataProvider provideWithConfigCases * @expectedDeprecation Passing "tokens" at the root of the configuration for rule "no_extra_blank_lines" is deprecated and will not be supported in 3.0, use "tokens" => array(...) option instead. */ public function testLegacyWithConfig(array $lineNumberRemoved, array $config) { $this->fixer->configure($config); $this->doTest($this->removeLinesFromString($this->template, $lineNumberRemoved), $this->template); } /** * @param int[] $lineNumberRemoved Line numbers expected to be removed after fixing * * @dataProvider provideWithConfigCases */ public function testWithConfig(array $lineNumberRemoved, array $config) { $this->fixer->configure(['tokens' => $config]); $this->doTest($this->removeLinesFromString($this->template, $lineNumberRemoved), $this->template); } public function provideWithConfigCases() { $tests = [ [ [9, 14, 21, 43, 45, 49, 53, 57], ['curly_brace_block'], ], [ [3, 5], ['use'], ], [ [23, 24], ['extra'], ], [ [49, 53], ['return'], ], [ [45], ['continue'], ], [ [32], ['break'], ], [ [14, 21], ['throw'], ], ]; $all = [[], []]; foreach ($tests as $test) { $all[0] = array_merge($test[0], $all[0]); $all[1] = array_merge($test[1], $all[1]); } $tests[] = $all; return $tests; } public function testFix() { $expected = <<<'EOF' doTest($expected, $input); } public function testFixWithManyEmptyLines() { $expected = <<<'EOF' doTest($expected, $input); } public function testFixWithHeredoc() { $expected = ' doTest($expected); } public function testFixWithNowdoc() { $expected = ' doTest($expected); } public function testFixWithEncapsulatedNowdoc() { $expected = ' doTest($expected); } public function testFixWithMultilineString() { $expected = <<<'EOF' doTest($expected); } public function testFixWithTrickyMultilineStrings() { $expected = <<<'EOF' doTest($expected, $input); } public function testFixWithCommentWithQuote() { $expected = <<<'EOF' doTest($expected, $input); } public function testFixWithTrailingInlineBlock() { $expected = " \$a = 0; //a "; $this->doTest($expected); } /** * @param string $expected * @param string $input * * @dataProvider provideCommentCases */ public function testFixWithComments($expected, $input) { $this->doTest($expected, $input); } public function provideCommentCases() { return [ [ <<<'EOF' doTest($expected, $input); } public function provideLineBreakCases() { $input = 'expectException(\PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches('/^\[no_extra_blank_lines\] Invalid configuration: The option "tokens" .*\.$/'); $this->fixer->configure(['tokens' => ['__TEST__']]); } /** * @param string $expected * @param null|string $input * * @dataProvider provideBetweenUseCases */ public function testBetweenUse($expected, $input = null) { $this->fixer->configure(['tokens' => ['use']]); $this->doTest($expected, $input); } public function provideBetweenUseCases() { return [ [''], ['\n\n"], ['fixer->configure(['tokens' => ['use']]); $this->doTest($expected, $input); } /** * @param string $expected * @param null|string $input * * @dataProvider provideRemoveLinesBetweenUseStatements70Cases * @requires PHP 7.0 */ public function testRemoveLinesBetweenUseStatements70($expected, $input = null) { $this->fixer->configure(['tokens' => ['use']]); $this->doTest($expected, $input); } public function provideRemoveLinesBetweenUseStatements70Cases() { return [ [ 'fixer->configure(['tokens' => ['use']]); $this->doTest($expected); } public function provideWithoutUsesCases() { return [ [ '', ], [ '', ], ]; } /** * @dataProvider provideRemoveBetweenUseTraitsCases * * @param string $expected * @param string $input */ public function testRemoveBetweenUseTraits($expected, $input) { $this->fixer->configure(['tokens' => ['use_trait']]); $this->doTest($expected, $input); } public function provideRemoveBetweenUseTraitsCases() { yield [ 'fixer->configure(['tokens' => ['useTrait']]); $this->doTest( 'fixer->configure(['tokens' => [ 'break', 'continue', 'return', 'throw', 'curly_brace_block', 'square_brace_block', 'parenthesis_brace_block', ]]); $this->doTest($expected, $input); } public function provideOneAndInLineCases() { $tests = [ [ "{'Test'};\nfunction test(){}\n", ], ]; foreach ($tests as $index => $test) { yield $index => $test; } if (\PHP_VERSION_ID < 80000) { yield [ "fixer->configure(['tokens' => [ 'break', 'continue', 'return', 'throw', 'curly_brace_block', 'square_brace_block', 'parenthesis_brace_block', ]]); $this->doTest($expected, $input); } public function provideOneAndInLine70Cases() { return [ [ "fixer->configure($config); $this->doTest($expected, $input); } public function provideBraceCases() { return [ [ ['tokens' => ['curly_brace_block']], " ['curly_brace_block']], " ['parenthesis_brace_block']], ' ['parenthesis_brace_block']], " ['parenthesis_brace_block']], 'd(e( )); foreach ($a as $x) { } }', ], [ ['tokens' => ['return']], ' ['square_brace_block']], "fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n")); $this->fixer->configure($config); $this->doTest($expected, $input); } public function provideMessyWhitespacesCases() { return [ [ [], " ['parenthesis_brace_block']], " ['square_brace_block']], " ['square_brace_block']], "fixer->configure(['tokens' => $config]); $this->doTest($expected, $input); } public function provideSwitchCases() { return [ [ [ 'break', 'continue', 'extra', 'return', 'throw', ], 'getValue()); case 7: return new ConstantNode($token->getValue()); case 8: return 8; default: echo 1; }', 'getValue()); case 7: return new ConstantNode($token->getValue()); '.' case 8: return 8; '.' default: echo 1; }', ], [ [ 'switch', 'case', 'default', ], 'doTest( 'fixer->configure(['tokens' => ['use']]); $this->doTest($expected, $input); } public function provideFix72Cases() { yield [ 'fixer->configure(['tokens' => ['throw']]); $this->doTest($expected); } public function provideFix80Cases() { yield [ '