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

Remove dependency on PHPUnit #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
"require": {
"php": ">=5.4",
"behat/behat": "~3.0",
"guzzlehttp/guzzle": "4 - 5",
"phpunit/phpunit": "~4.0"
"guzzlehttp/guzzle": "4 - 5"
},

"require-dev": {
"symfony/process": "~2.1",
"silex/silex": "~1"
"silex/silex": "~1",
"phpunit/phpunit": "~4.0"
Copy link
Member

Choose a reason for hiding this comment

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

why is there a dev depending on it ?

Copy link
Author

Choose a reason for hiding this comment

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

I haven't removed assertions from features/bootstrap/FeatureContext.php, though they would be simple to replace.

},

"autoload": {
Expand Down
193 changes: 193 additions & 0 deletions features/exceptions.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
Feature: Feature failures
In order to resolve problems easily
As a WebApi feature tester
I want clear error messages

Background:
Given a file named "behat.yml" with:
"""
default:
formatters:
progress: ~
extensions:
Behat\WebApiExtension:
base_url: http://localhost:8080/

suites:
default:
contexts: ['Behat\WebApiExtension\Context\WebApiContext']
"""

Scenario: Response code
Given a file named "features/authentication.feature" with:
"""
Feature: Accessing an invalid url
In order to known about my mistakes
As an API client
I should receive an error response

Scenario:
When I send a GET request to "/404"
Then the response code should be 200
"""
When I run "behat features/authentication.feature"
Then it should fail with:
"""
.F

--- Failed steps:

Then the response code should be 200 # features/authentication.feature:8
The response code was 404, not 200 (Behat\WebApiExtension\Context\ExpectationException)

1 scenario (1 failed)
2 steps (1 passed, 1 failed)
"""

Scenario: Response contains
Given a file named "features/headers.feature" with:
"""
Feature: Exercise WebApiContext Set Header
In order to validate the set_header step
As a context developer
I need to be able to add headers in a scenario before sending a request

Scenario:
When I send a GET request to "echo"
Then the response should contain "foo"
"""
When I run "behat features/headers.feature"
Then it should fail with:
"""
.F

--- Failed steps:

Then the response should contain "foo" # features/headers.feature:8
Response body does not contain the specified text (Behat\WebApiExtension\Context\ExpectationException)

1 scenario (1 failed)
2 steps (1 passed, 1 failed)
"""

Scenario: Response does not contain
Given a file named "features/headers.feature" with:
"""
Feature: Exercise WebApiContext Set Header
In order to validate the set_header step
As a context developer
I need to be able to add headers in a scenario before sending a request

Scenario:
Given I set header "foo" with value "bar"
When I send a GET request to "echo"
Then the response should not contain "foo"
"""
When I run "behat features/headers.feature"
Then it should fail with:
"""
..F

--- Failed steps:

Then the response should not contain "foo" # features/headers.feature:9
Response body contains the specified text (Behat\WebApiExtension\Context\ExpectationException)

1 scenario (1 failed)
3 steps (2 passed, 1 failed)
"""

Scenario: Response contains JSON (invalid JSON)
Given a file named "features/headers.feature" with:
"""
Feature: Exercise WebApiContext Set Header
In order to validate the set_header step
As a context developer
I need to be able to add headers in a scenario before sending a request

Scenario:
When I send a GET request to "echo"
And the response should contain json:
'''
foo
'''
"""
When I run "behat features/headers.feature"
Then it should fail with:
"""
.F

--- Failed steps:

And the response should contain json: # features/headers.feature:8
Can not convert etalon to json:
foo (LogicException)

1 scenario (1 failed)
2 steps (1 passed, 1 failed)
"""

Scenario: Response contains JSON (missing key)
Given a file named "features/headers.feature" with:
"""
Feature: Exercise WebApiContext Set Header
In order to validate the set_header step
As a context developer
I need to be able to add headers in a scenario before sending a request

Scenario:
When I send a GET request to "echo"
And the response should contain json:
'''
{
"foo" : "bar"
}
'''
"""
When I run "behat features/headers.feature"
Then it should fail with:
"""
.F

--- Failed steps:

And the response should contain json: # features/headers.feature:8
Does not contain the key "foo" (Behat\WebApiExtension\Context\ExpectationException)

1 scenario (1 failed)
2 steps (1 passed, 1 failed)
"""

Scenario: Response contains JSON
Given a file named "features/headers.feature" with:
"""
Feature: Exercise WebApiContext Set Header
In order to validate the set_header step
As a context developer
I need to be able to add headers in a scenario before sending a request

Scenario:
When I send a POST request to "echo" with form data:
'''
foo=bar
'''
And the response should contain json:
'''
{
"foo" : "baz"
}
'''
"""
When I run "behat features/headers.feature"
Then it should fail with:
"""
.F

--- Failed steps:

And the response should contain json: # features/headers.feature:11
Value for the key "foo" does not match (Behat\WebApiExtension\Context\ExpectationException)

1 scenario (1 failed)
2 steps (1 passed, 1 failed)
"""
25 changes: 25 additions & 0 deletions src/Context/ExpectationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/*
* This file is part of the Behat WebApiExtension.
* (c) Konstantin Kudryashov <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Behat\WebApiExtension\Context;

class ExpectationException extends \RuntimeException
{
/**
* Initializes exception.
*
* @param string $message Message.
* @param \Exception $exception Expectation exception.
*/
public function __construct($message = '', \Exception $exception = null)
{
parent::__construct($message, 0, $exception);
}
}
63 changes: 53 additions & 10 deletions src/Context/WebApiContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use PHPUnit_Framework_Assert as Assertions;

/**
* Provides web API description definitions.
Expand Down Expand Up @@ -196,7 +195,7 @@ public function theResponseCodeShouldBe($code)
{
$expected = intval($code);
$actual = intval($this->response->getStatusCode());
Assertions::assertSame($expected, $actual);
$this->assertSame($expected, $actual, sprintf('The response code was %s, not %s', $actual, $expected));
}

/**
Expand All @@ -210,7 +209,7 @@ public function theResponseShouldContain($text)
{
$expectedRegexp = '/' . preg_quote($text) . '/i';
$actual = (string) $this->response->getBody();
Assertions::assertRegExp($expectedRegexp, $actual);
$this->assertRegex($expectedRegexp, $actual, 'Response body does not contain the specified text');
}

/**
Expand All @@ -224,7 +223,12 @@ public function theResponseShouldNotContain($text)
{
$expectedRegexp = '/' . preg_quote($text) . '/';
$actual = (string) $this->response->getBody();
Assertions::assertNotRegExp($expectedRegexp, $actual);
$this->assertNegative(
function () use ($expectedRegexp, $actual) {
$this->assertRegex($expectedRegexp, $actual);
},
'Response body contains the specified text'
);
}

/**
Expand All @@ -244,15 +248,13 @@ public function theResponseShouldContainJson(PyStringNode $jsonString)
$actual = $this->response->json();

if (null === $etalon) {
throw new \RuntimeException(
"Can not convert etalon to json:\n" . $this->replacePlaceHolder($jsonString->getRaw())
throw new \LogicException(
"Can not convert etalon to json:\n" . $this->replacePlaceHolder($jsonString->getRaw())
);
}

Assertions::assertGreaterThanOrEqual(count($etalon), count($actual));
foreach ($etalon as $key => $needle) {
Assertions::assertArrayHasKey($key, $actual);
Assertions::assertEquals($etalon[$key], $actual[$key]);
$this->assertArrayHasKey($key, $actual, sprintf('Does not contain the key "%s"', $key));
$this->assertEquals($etalon[$key], $actual[$key], sprintf('Value for the key "%s" does not match', $key));
}
}

Expand Down Expand Up @@ -379,4 +381,45 @@ private function getClient()

return $this->client;
}

private function assertNegative($callable, $message = 'Passed')
{
try {
call_user_func($callable);
} catch (ExpectationException $e) {
return;
}

throw new ExpectationException($message);
}

private function assertEquals($expected, $actual, $message = 'Not equal')
{
if ($actual != $expected) {
throw new ExpectationException($message);
}
}

private function assertSame($expected, $actual, $message = 'Not the same')
{
if ($actual !== $expected) {
throw new ExpectationException($message);
}
}

private function assertArrayHasKey($key, array $array, $message = 'Does not have key') {
if (!array_key_exists($key, $array)) {
throw new ExpectationException($message);
}
}

private function assertRegex($pattern, $subject, $message = 'Does not match') {
$result = preg_match($pattern, $subject);

if (false === $result) {
throw new \LogicException('Invalid regular expression');
} elseif (0 === $result) {
throw new ExpectationException($message);
}
}
}