Skip to content

Commit

Permalink
[5.4] Support numeric arguments in break and continue (#17603)
Browse files Browse the repository at this point in the history
* Support numeric arguments in break and continue

As per the [PHP documentation](http://php.net/manual/en/control-structures.break.php)
>break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. The default value is 1, only the immediate enclosing structure is broken out of.

* Set maximum value to be used

Minimum count of structures to break out of is 1

* Regex update

Allow for values greater than 9

* Formatting fixes

* Update CompilesLoops.php

* Update CompilesLoops.php

* Adding tests for optional numeric argument

Testing for a proper argument passed as well as white-spaced and a faulty (less than 1) ones

* Support negative arguments

Arguments that are less than zero are now caught by the regexp

* Adding tests for optional numeric argument

Testing for a proper argument passed as well as white-spaced and a faulty (less than 1) ones
  • Loading branch information
michaeltintiuc authored and taylorotwell committed Jan 31, 2017
1 parent dc3fa7c commit b375161
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/Illuminate/View/Compilers/Concerns/CompilesLoops.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ protected function compileForeach($expression)
*/
protected function compileBreak($expression)
{
return $expression ? "<?php if{$expression} break; ?>" : '<?php break; ?>';
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);

return $matches ? '<?php break '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} break; ?>";
}

return '<?php break; ?>';
}

/**
Expand All @@ -107,7 +113,13 @@ protected function compileBreak($expression)
*/
protected function compileContinue($expression)
{
return $expression ? "<?php if{$expression} continue; ?>" : '<?php continue; ?>';
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);

return $matches ? '<?php continue '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} continue; ?>";
}

return '<?php continue; ?>';
}

/**
Expand Down
42 changes: 42 additions & 0 deletions tests/View/Blade/BladeBreakStatementsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,48 @@ public function testBreakStatementsWithExpressionAreCompiled()
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testBreakStatementsWithArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@break(2)
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php break 2; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testBreakStatementsWithSpacedArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@break( 2 )
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php break 2; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testBreakStatementsWithFaultyArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@break(-2)
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php break 1; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

protected function getFiles()
{
return m::mock('Illuminate\Filesystem\Filesystem');
Expand Down
42 changes: 42 additions & 0 deletions tests/View/Blade/BladeContinueStatementsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,48 @@ public function testContinueStatementsWithExpressionAreCompiled()
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testContinueStatementsWithArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@continue(2)
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php continue 2; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testContinueStatementsWithSpacedArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@continue( 2 )
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php continue 2; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

public function testContinueStatementsWithFaultyArgumentAreCompiled()
{
$compiler = new BladeCompiler($this->getFiles(), __DIR__);
$string = '@for ($i = 0; $i < 10; $i++)
test
@continue(-2)
@endfor';
$expected = '<?php for($i = 0; $i < 10; $i++): ?>
test
<?php continue 1; ?>
<?php endfor; ?>';
$this->assertEquals($expected, $compiler->compileString($string));
}

protected function getFiles()
{
return m::mock('Illuminate\Filesystem\Filesystem');
Expand Down

0 comments on commit b375161

Please sign in to comment.