Skip to content

Commit

Permalink
Merge pull request #19 from knpuniversity/code-activities-ch5
Browse files Browse the repository at this point in the history
Add code activities to the ch5 (behat-hooks-background)
  • Loading branch information
weaverryan committed Oct 20, 2015
2 parents 6e7ad60 + 99a8f8c commit 03e1902
Show file tree
Hide file tree
Showing 3 changed files with 400 additions and 0 deletions.
209 changes: 209 additions & 0 deletions knpu/Challenges/BehatHooksBackground/CheckStepTestResultCoding.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<?php

namespace Challenges\BehatHooksBackground;

use KnpU\ActivityRunner\Activity\CodingChallenge\CodingContext;
use KnpU\ActivityRunner\Activity\CodingChallenge\CorrectAnswer;
use KnpU\ActivityRunner\Activity\CodingChallengeInterface;
use KnpU\ActivityRunner\Activity\CodingChallenge\CodingExecutionResult;
use KnpU\ActivityRunner\Activity\CodingChallenge\FileBuilder;
use KnpU\ActivityRunner\Activity\Exception\GradingException;

class CheckStepTestResultCoding implements CodingChallengeInterface
{
/**
* @return string
*/
public function getQuestion()
{
return <<<EOF
Whenever you have a hook function, you're actually passed an `\$event`
argument object that contains information about what's happening inside Behat
at this moment. The exact object depends on which hook you're using
(see [Behat Hooks](http://docs.behat.org/en/v3.0/guides/3.hooks.html#hooks)).
In `afterStepHook()`, add an `\$event` argument and use it to figure out
if the step that was just executed passed or failed. Replace `var_dump('After Step!')`
with `var_dump(\$isPassed)` where `\$isPassed` is equal to whether or not
the previous step passed/failed.
EOF;
}

public function getFileBuilder()
{
$fileBuilder = new FileBuilder();
$fileBuilder
->addFileContents('features/bootstrap/FeatureContext.php', <<<EOF
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
class FeatureContext implements Context, SnippetAcceptingContext
{
private \$output;
/**
* @AfterStep
*/
public function afterStepHook()
{
var_dump('After Step!');
}
/**
* @Given I have a file named :filename
*/
public function iHaveAFileNamed(\$filename)
{
touch(\$filename);
}
/**
* @When I run :command
*/
public function iRun(\$command)
{
\$this->output = shell_exec(\$command);
}
/**
* @Then I should see :string in the output
*/
public function iShouldSeeInTheOutput(\$string)
{
if (strpos(\$this->output, \$string) === false) {
throw new \Exception(sprintf('Did not see "%s" in output "%s"', \$string, \$this->output));
}
}
}
EOF
)
->addFileContents('ls.feature', <<<EOF
Feature: ls
In order to see the directory structure
As a UNIX user
I need to be able to list the current directory's contents
Scenario: List 2 files in a directory
Given I have a file named "john"
And I have a file named "hammond"
When I run "ls"
Then I should see "john" in the output
And I should see "hammond" in the output
EOF
, true)
->setEntryPointFilename('features/bootstrap/FeatureContext.php')
;

return $fileBuilder;
}

public function getExecutionMode()
{
return self::EXECUTION_MODE_PHP_NORMAL;
}

public function setupContext(CodingContext $context)
{
// Create dummy interfaces if not exists that implemented by FeatureContext class.
if (!class_exists('\Behat\Behat\Context\Context')) {
eval(<<<EOF
namespace Behat\Behat\Context;
interface Context
{
}
EOF
);
}
if (!class_exists('\Behat\Behat\Context\SnippetAcceptingContext')) {
eval(<<<EOF
namespace Behat\Behat\Context;
interface SnippetAcceptingContext
{
}
EOF
);
}
}

public function grade(CodingExecutionResult $result)
{
$featureContextClass = new \ReflectionClass('FeatureContext');
if (!$featureContextClass->hasMethod('afterStepHook')) {
throw new GradingException('The `afterStepHook()` method wasn\'t found in the `FeatureContext` class.');
}
if (!$featureContextClass->getMethod('afterStepHook')->isPublic()) {
throw new GradingException('The `afterStepHook()` method should be public.');
}
$afterStepHookMethod = $featureContextClass->getMethod('afterStepHook');
$docComment = $afterStepHookMethod->getDocComment();
if (false === strpos($docComment, '@AfterStep')) {
throw new GradingException('You should to use `@AfterStep` annotation for `afterStepHook()` method.');
}
$afterStepHookParameters = $afterStepHookMethod->getParameters();
if (1 !== $afterStepHookMethod->getNumberOfRequiredParameters()) {
throw new GradingException('Make sure you give the `afterStepHook()` method exactly one argument.');
}
if (0 !== strcmp('event', $afterStepHookParameters[0]->getName())) {
throw new GradingException('Though you can really call it anything, let\'s call the argument to `afterStepHook()` `$event` for clarity.');
}
}

public function configureCorrectAnswer(CorrectAnswer $correctAnswer)
{
$correctAnswer
->setFileContents('features/bootstrap/FeatureContext.php', <<<EOF
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Behat\Hook\Scope\AfterStepScope;
class FeatureContext implements Context, SnippetAcceptingContext
{
private \$output;
/**
* @AfterStep
*/
public function afterStepHook(AfterStepScope \$event)
{
\$isPassed = \$event->getTestResult()->isPassed();
var_dump(\$isPassed);
}
/**
* @Given I have a file named :filename
*/
public function iHaveAFileNamed(\$filename)
{
touch(\$filename);
}
/**
* @When I run :command
*/
public function iRun(\$command)
{
\$this->output = shell_exec(\$command);
}
/**
* @Then I should see :string in the output
*/
public function iShouldSeeInTheOutput(\$string)
{
if (strpos(\$this->output, \$string) === false) {
throw new \Exception(sprintf('Did not see "%s" in output "%s"', \$string, \$this->output));
}
}
}
EOF
)
;
}
}
188 changes: 188 additions & 0 deletions knpu/Challenges/BehatHooksBackground/afterStepHookCoding.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<?php

namespace Challenges\BehatHooksBackground;

use KnpU\ActivityRunner\Activity\CodingChallenge\CodingContext;
use KnpU\ActivityRunner\Activity\CodingChallenge\CorrectAnswer;
use KnpU\ActivityRunner\Activity\CodingChallengeInterface;
use KnpU\ActivityRunner\Activity\CodingChallenge\CodingExecutionResult;
use KnpU\ActivityRunner\Activity\CodingChallenge\FileBuilder;
use KnpU\ActivityRunner\Activity\Exception\GradingException;

class afterStepHookCoding implements CodingChallengeInterface
{
/**
* @return string
*/
public function getQuestion()
{
return <<<EOF
As a challenge, create a new function called `afterStepHook()` that
is called after *every* individual step in a scenario. Inside of
this, just execute `var_dump('After Step!');`.
**Hint**
See [hooking into the test process](http://docs.behat.org/en/v3.0/guides/3.hooks.html)
for the annotation needed to do things after every step.
EOF;
}

public function getFileBuilder()
{
$fileBuilder = new FileBuilder();
$fileBuilder
->addFileContents('features/bootstrap/FeatureContext.php', <<<EOF
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
class FeatureContext implements Context, SnippetAcceptingContext
{
private \$output;
/**
* @Given I have a file named :filename
*/
public function iHaveAFileNamed(\$filename)
{
touch(\$filename);
}
/**
* @When I run :command
*/
public function iRun(\$command)
{
\$this->output = shell_exec(\$command);
}
/**
* @Then I should see :string in the output
*/
public function iShouldSeeInTheOutput(\$string)
{
if (strpos(\$this->output, \$string) === false) {
throw new \Exception(sprintf('Did not see "%s" in output "%s"', \$string, \$this->output));
}
}
}
EOF
)
->addFileContents('ls.feature', <<<EOF
Feature: ls
In order to see the directory structure
As a UNIX user
I need to be able to list the current directory's contents
Scenario: List 2 files in a directory
Given I have a file named "john"
And I have a file named "hammond"
When I run "ls"
Then I should see "john" in the output
And I should see "hammond" in the output
EOF
, true)
->setEntryPointFilename('features/bootstrap/FeatureContext.php')
;

return $fileBuilder;
}

public function getExecutionMode()
{
return self::EXECUTION_MODE_PHP_NORMAL;
}

public function setupContext(CodingContext $context)
{
// Create dummy interfaces if not exists that implemented by FeatureContext class.
if (!class_exists('\Behat\Behat\Context\Context')) {
eval(<<<EOF
namespace Behat\Behat\Context;
interface Context
{
}
EOF
);
}
if (!class_exists('\Behat\Behat\Context\SnippetAcceptingContext')) {
eval(<<<EOF
namespace Behat\Behat\Context;
interface SnippetAcceptingContext
{
}
EOF
);
}
}

public function grade(CodingExecutionResult $result)
{
$featureContextClass = new \ReflectionClass('FeatureContext');
if (!$featureContextClass->hasMethod('afterStepHook')) {
throw new GradingException('The `afterStepHook()` method wasn\'t found in the `FeatureContext` class.');
}
if (!$featureContextClass->getMethod('afterStepHook')->isPublic()) {
throw new GradingException('The `afterStepHook()` method should be public.');
}
$docComment = $featureContextClass->getMethod('afterStepHook')->getDocComment();
if (false === strpos($docComment, '@AfterStep')) {
throw new GradingException('You should to use `@AfterStep` annotation for `afterStepHook()` method.');
}
}

public function configureCorrectAnswer(CorrectAnswer $correctAnswer)
{
$correctAnswer
->setFileContents('features/bootstrap/FeatureContext.php', <<<EOF
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
class FeatureContext implements Context, SnippetAcceptingContext
{
private \$output;
/**
* @AfterStep
*/
public function afterStepHook()
{
var_dump('After Step!');
}
/**
* @Given I have a file named :filename
*/
public function iHaveAFileNamed(\$filename)
{
touch(\$filename);
}
/**
* @When I run :command
*/
public function iRun(\$command)
{
\$this->output = shell_exec(\$command);
}
/**
* @Then I should see :string in the output
*/
public function iShouldSeeInTheOutput(\$string)
{
if (strpos(\$this->output, \$string) === false) {
throw new \Exception(sprintf('Did not see "%s" in output "%s"', \$string, \$this->output));
}
}
}
EOF
)
;
}
}
Loading

0 comments on commit 03e1902

Please sign in to comment.