Skip to content

Commit

Permalink
Fixes #741 Place methods specifically after the last one
Browse files Browse the repository at this point in the history
  • Loading branch information
shanethehat committed Jul 14, 2015
1 parent 7402e30 commit f365af0
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 2 deletions.
57 changes: 57 additions & 0 deletions features/code_generation/developer_generates_method.feature
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,60 @@ Feature: Developer generates a method
}
"""

Scenario: Generating a method in a class with existing methods and new lines
Given the spec file "spec/MyNamespace/ExistingMethodSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ExistingMethodSpec extends ObjectBehavior
{
function it_should_do_something()
{
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/ExistingMethod.php" contains:
"""
<?php
namespace MyNamespace;
class ExistingMethod
{
public function existing()
{
return 'something';
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/ExistingMethod.php" should contain:
"""
<?php
namespace MyNamespace;
class ExistingMethod
{
public function existing()
{
return 'something';
}
public function foo()
{
// TODO: write logic here
}
}
"""
3 changes: 2 additions & 1 deletion src/PhpSpec/CodeGenerator/Writer/TokenizedCodeWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public function insertMethodFirstInClass($class, $method)
public function insertMethodLastInClass($class, $method)
{
if ($this->analyser->classHasMethods($class)) {
return $this->writeAtEndOfClass($class, $method, true);
$line = $this->analyser->getEndLineOfLastMethod($class);
return $this->insertStringAfterLine($class, $method, $line);
}

return $this->writeAtEndOfClass($class, $method);
Expand Down
35 changes: 34 additions & 1 deletion src/PhpSpec/Util/ClassFileAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ public function getStartLineOfFirstMethod($class)
return $tokens[$index][2];
}

/**
* @param string $class
* @return int
*/
public function getEndLineOfLastMethod($class)
{
$tokens = $this->getTokensForClass($class);
$index = $this->findIndexOfMethodEnd($tokens, $this->findIndexOfLastMethod($tokens));
return $tokens[$index][2];
}

/**
* @param string $class
* @return bool
Expand Down Expand Up @@ -69,7 +80,20 @@ public function getEndLineOfNamedMethod($class, $methodName)
private function findIndexOfFirstMethod(array $tokens)
{
for ($i = 0, $max = count($tokens); $i < $max; $i++) {
if (is_array($tokens[$i]) && $tokens[$i][0] === T_FUNCTION) {
if ($this->tokenIsFunction($tokens[$i])) {
return $i;
}
}
}

/**
* @param array $tokens
* @return int
*/
private function findIndexOfLastMethod(array $tokens)
{
for ($i = count($tokens) - 1; $i >= 0; $i--) {
if ($this->tokenIsFunction($tokens[$i])) {
return $i;
}
}
Expand Down Expand Up @@ -199,4 +223,13 @@ private function findIndexOfMethodEnd(array $tokens, $index)
}
}
}

/**
* @param mixed $token
* @return bool
*/
private function tokenIsFunction($token)
{
return is_array($token) && $token[0] === T_FUNCTION;
}
}

0 comments on commit f365af0

Please sign in to comment.