Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code activities to the ch5 (behat-hooks-background) #19

Merged
merged 5 commits into from
Oct 20, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one extra ] at the end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Didn't see it in activity runner

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense - runner doesn't render markdown :)


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('Method `afterStepHook()` doesn\'t found in the `FeatureContext` class. Did you create it?');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

The afterStepHook() method wasn't found in the FeatureContext class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better 👍 I just keep it consistent with oo tut. We start message with Method methodName() ... there.

}
if (!$featureContextClass->getMethod('afterStepHook')->isPublic()) {
throw new GradingException('Method `afterStepHook()` 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('Method `afterStepHook()` should get one required parameter.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about:

Make sure you give the afterStepHook() method exactly one argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
if (0 !== strcmp('event', $afterStepHookParameters[0]->getName())) {
throw new GradingException('First argument in the `afterStepHook()` method should be named `$event`.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to be clear that we want it to be called $event, but it doesn't need to be for functionality purposes:

Though you can really call it anything, let's call the argument to `afterStepHook()`
`$event` for clarity.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I also wondering should we check somehow that student call $event->getTestResult()->isPassed() and dump result in 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;
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('Method `afterStepHook()` doesn\'t found in the `FeatureContext` class. Did you create it?');
}
if (!$featureContextClass->getMethod('afterStepHook')->isPublic()) {
throw new GradingException('Method `afterStepHook()` 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.');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice grading 👍

}

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