Skip to content
This repository has been archived by the owner on Jul 29, 2022. It is now read-only.

Commit

Permalink
wip: behat tests are dirty passing, keep going
Browse files Browse the repository at this point in the history
  • Loading branch information
Rodrigue Villetard committed Jul 26, 2017
1 parent c3260ae commit a7bbc31
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 106 deletions.
28 changes: 28 additions & 0 deletions argumentsExt/Annotation/StepInjectorArgument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

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

namespace Gorghoa\StepArgumentInjectorBehatExtension\Annotation;

/**
* @author Rodrigue Villetard <[email protected]>
*/
interface StepInjectorArgument
{
/**
* @return string
*/
public function getName();

/**
* @return string
*/
public function getArgument();
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
<?php

/*
* This file is part of the ScenarioStateBehatExtension project.
* This file is part of the StepArgumentInjectorBehatExtension project.
*
* (c) Rodrigue Villetard <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gorghoa\ScenarioStateBehatExtension\Argument;
namespace Gorghoa\StepArgumentInjectorBehatExtension\Argument;

use Behat\Testwork\Argument\ArgumentOrganiser;
use Behat\Testwork\Argument\ArgumentOrganiser as BehatArgumentOrganiser;
use Doctrine\Common\Annotations\Reader;
use Gorghoa\ScenarioStateBehatExtension\Annotation\ScenarioStateArgument;
use Gorghoa\ScenarioStateBehatExtension\Context\Initializer\ScenarioStateInitializer;
use Gorghoa\StepArgumentInjectorBehatExtension\Annotation\StepArgumentInjectorArgument;
use Gorghoa\StepArgumentInjectorBehatExtension\Annotation\StepInjectorArgument;
// use Gorghoa\StepArgumentInjectorBehatExtension\Context\Initializer\StepArgumentInjectorInitializer;
use ReflectionFunctionAbstract;

/**
* @author Rodrigue Villetard <[email protected]>
* @author Vincent Chalamon <[email protected]>
*/
final class ScenarioStateArgumentOrganiser implements ArgumentOrganiser
final class ArgumentOrganiser implements BehatArgumentOrganiser
{
/**
* @var ArgumentOrganiser
* @var BehatArgumentOrganiser
*/
private $baseOrganiser;

/**
* @var ScenarioStateInitializer
* @var StepArgumentInjectorInitializer
*/
private $store;
private $hookers;

/**
* @var Reader
*/
private $reader;

public function __construct(ArgumentOrganiser $organiser, ScenarioStateInitializer $store, Reader $reader)
public function __construct(BehatArgumentOrganiser $organiser, array $hookers, Reader $reader)
{
$this->baseOrganiser = $organiser;
$this->store = $store;
$this->hookers = $hookers;
$this->reader = $reader;
}

Expand All @@ -59,16 +60,21 @@ public function organiseArguments(ReflectionFunctionAbstract $function, array $m
return $this->baseOrganiser->organiseArguments($function, $match);
}

/** @var ScenarioStateArgument[] $annotations */
/** @var StepArgumentInjectorArgument[] $annotations */
$annotations = $this->reader->getMethodAnnotations($function);
$store = $this->store->getStore();

foreach ($annotations as $annotation) {
if ($annotation instanceof ScenarioStateArgument &&
in_array($annotation->getArgument(), $paramsKeys) &&
$store->hasStateFragment($annotation->getName())
if ($annotation instanceof StepInjectorArgument &&
in_array($annotation->getArgument(), $paramsKeys)
) {
$match[$annotation->getArgument()] = $store->getStateFragment($annotation->getName());
$match[strval(++$i)] = $store->getStateFragment($annotation->getName());
foreach ($this->hookers as $hooker) {
if ($hooker->hasStepArgumentFor($annotation->getName())) {
$match[$annotation->getArgument()]
= $match[strval(++$i)]
= $hooker->getStepArgumentFor($annotation->getName())
;
}
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions argumentsExt/Argument/StepArgumentHolder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

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

namespace Gorghoa\StepArgumentInjectorBehatExtension\Argument;

/**
* @author Rodrigue Villetard <[email protected]>
*/
interface StepArgumentHolder
{
public function hasStepArgumentFor($key);

public function getStepArgumentFor($key);
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<?php

/*
* This file is part of the ScenarioStateBehatExtension project.
* This file is part of the StepArgumentInjectorBehatExtension project.
*
* (c) Rodrigue Villetard <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gorghoa\ScenarioStateBehatExtension\Call\Handler;
namespace Gorghoa\StepArgumentInjectorBehatExtension\Call\Handler;

use Behat\Behat\Transformation\Call\TransformationCall;
use Behat\Testwork\Call\Call;
use Behat\Testwork\Call\Handler\CallHandler;
use Behat\Testwork\Environment\Call\EnvironmentCall;
use Behat\Testwork\Hook\Call\HookCall;
use Gorghoa\ScenarioStateBehatExtension\Resolver\ArgumentsResolver;
use Gorghoa\StepArgumentInjectorBehatExtension\Resolver\ArgumentsResolver;

/**
* @author Vincent Chalamon <[email protected]>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@
<?php

/*
* This file is part of the ScenarioStateBehatExtension project.
* This file is part of the StepArgumentInjectorBehatExtension project.
*
* (c) Rodrigue Villetard <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gorghoa\ScenarioStateBehatExtension\Resolver;
namespace Gorghoa\StepArgumentInjectorBehatExtension\Resolver;

use Doctrine\Common\Annotations\Reader;
use Gorghoa\ScenarioStateBehatExtension\Annotation\ScenarioStateArgument;
use Gorghoa\ScenarioStateBehatExtension\Context\Initializer\ScenarioStateInitializer;
use Gorghoa\StepArgumentInjectorBehatExtension\Annotation\StepInjectorArgument;

/**
* @author Vincent Chalamon <[email protected]>
*/
class ArgumentsResolver
{
/**
* @var ScenarioStateInitializer
* @var Reader
*/
private $store;
private $reader;

/**
* @var Reader
* @var array
*/
private $reader;
private $hookers;

/**
* @param ScenarioStateInitializer $store
* @param Reader $reader
* @param Reader $reader
*/
public function __construct(ScenarioStateInitializer $store, Reader $reader)
public function __construct(array $hookers, Reader $reader)
{
$this->store = $store;
$this->hookers = $hookers;
$this->reader = $reader;
}

Expand All @@ -48,25 +46,27 @@ public function __construct(ScenarioStateInitializer $store, Reader $reader)
*/
public function resolve(\ReflectionMethod $function, array $arguments)
{
// No `@ScenarioStateArgument` annotation found
if (null === $this->reader->getMethodAnnotation($function, ScenarioStateArgument::class)) {
// No `@StepArgumentInjectorArgument` annotation found
if (null === $this->reader->getMethodAnnotation($function, StepInjectorArgument::class)) {
return $arguments;
}

$paramsKeys = array_map(function (\ReflectionParameter $element) {
return $element->getName();
}, $function->getParameters());
$store = $this->store->getStore();

// Prepare arguments from annotations
/** @var ScenarioStateArgument[] $annotations */
/** @var StepArgumentInjectorArgument[] $annotations */
$annotations = $this->reader->getMethodAnnotations($function);
foreach ($annotations as $annotation) {
if ($annotation instanceof ScenarioStateArgument &&
in_array($annotation->getArgument(), $paramsKeys) &&
$store->hasStateFragment($annotation->getName())
if ($annotation instanceof StepInjectorArgument &&
in_array($annotation->getArgument(), $paramsKeys)
) {
$arguments[$annotation->getArgument()] = $store->getStateFragment($annotation->getName());
foreach ($this->hookers as $hooker) {
if ($hooker->hasStepArgumentFor($annotation->getName())) {
$arguments[$annotation->getArgument()] = $hooker->getStepArgumentFor($annotation->getName());
}
}
}
}

Expand Down
123 changes: 123 additions & 0 deletions argumentsExt/ServiceContainer/StepArgumentInjectorExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

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

namespace Gorghoa\StepArgumentInjectorBehatExtension\ServiceContainer;

use Behat\Testwork\Argument\ServiceContainer\ArgumentExtension;
use Behat\Testwork\Call\ServiceContainer\CallExtension;
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
use Behat\Testwork\ServiceContainer\ExtensionManager;
use Doctrine\Common\Annotations\AnnotationReader;
use Gorghoa\StepArgumentInjectorBehatExtension\Argument\ArgumentOrganiser;
use Gorghoa\StepArgumentInjectorBehatExtension\Call\Handler\RuntimeCallHandler;
use Gorghoa\StepArgumentInjectorBehatExtension\Resolver\ArgumentsResolver;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
* Behat store for Behat contexts.
*
* @author Rodrigue Villetard <[email protected]>
* @author Vincent Chalamon <[email protected]>
*/
class StepArgumentInjectorExtension implements ExtensionInterface
{
const STEP_ARGUMENT_INJECTOR_ARGUMENT_ORGANISER_ID = 'argument.step_argument_injector.organiser';
const STEP_ARGUMENT_INJECTOR_DISPATCHER_ID = 'hook.step_argument_injector.dispatcher';
const STEP_ARGUMENT_INJECTOR_TESTER_ID = 'tester.step_argument_injector.wrapper';
const STEP_ARGUMENT_INJECTOR_CALL_HANDLER_ID = 'call.step_argument_injector.call_handler';
const STEP_ARGUMENT_INJECTOR_ARGUMENTS_RESOLVER_ID = 'step_argument_injector.arguments_resolver';
const STEP_ARGUMENT_INJECTOR_STORE_ID = 'behatstore.context_initializer.store_aware';
const STEP_ARGUMENT_INJECTOR_DOCTRINE_READER_ID = 'doctrine.reader.annotation';
const STEP_ARGUMENT_INJECTOR_HOOK_TAG_ID = 'step_argument_injector.hook_tag_id';

/**
* {@inheritdoc}
*/
public function getConfigKey()
{
return 'stepargumentinjector';
}

/**
* {@inheritdoc}
*/
public function initialize(ExtensionManager $extensionManager)
{
}

/**
* {@inheritdoc}
*/
public function configure(ArrayNodeDefinition $builder)
{
}

/**
* {@inheritdoc}
*/
public function load(ContainerBuilder $container, array $config)
{
// Declare Doctrine annotation reader as service
$container->register(self::STEP_ARGUMENT_INJECTOR_DOCTRINE_READER_ID, AnnotationReader::class)
// Ignore Behat annotations in reader
->addMethodCall('addGlobalIgnoredName', ['Given'])
->addMethodCall('addGlobalIgnoredName', ['When'])
->addMethodCall('addGlobalIgnoredName', ['Then'])
->addMethodCall('addGlobalIgnoredName', ['Transform'])
->addMethodCall('addGlobalIgnoredName', ['BeforeStep'])
->addMethodCall('addGlobalIgnoredName', ['BeforeScenario'])
->addMethodCall('addGlobalIgnoredName', ['BeforeFeature'])
->addMethodCall('addGlobalIgnoredName', ['BeforeSuite'])
->addMethodCall('addGlobalIgnoredName', ['AfterStep'])
->addMethodCall('addGlobalIgnoredName', ['AfterScenario'])
->addMethodCall('addGlobalIgnoredName', ['AfterFeature'])
->addMethodCall('addGlobalIgnoredName', ['AfterSuite']);

$taggedServices = array_map(function ($serviceId) {
return new Reference($serviceId);
}, array_keys($container->findTaggedServiceIds(self::STEP_ARGUMENT_INJECTOR_HOOK_TAG_ID)));

// Arguments resolver: resolve StepArgumentInjector arguments from annotation
$container->register(self::STEP_ARGUMENT_INJECTOR_ARGUMENTS_RESOLVER_ID, ArgumentsResolver::class)
->setArguments([
$taggedServices,
new Reference(self::STEP_ARGUMENT_INJECTOR_DOCTRINE_READER_ID),
]);

// Argument organiser
$container->register(self::STEP_ARGUMENT_INJECTOR_ARGUMENT_ORGANISER_ID, ArgumentOrganiser::class)
->setDecoratedService(ArgumentExtension::PREG_MATCH_ARGUMENT_ORGANISER_ID)
->setPublic(false)
->setArguments([
new Reference(sprintf('%s.inner', self::STEP_ARGUMENT_INJECTOR_ARGUMENT_ORGANISER_ID)),
$taggedServices,
new Reference(self::STEP_ARGUMENT_INJECTOR_DOCTRINE_READER_ID),
new Reference(self::STEP_ARGUMENT_INJECTOR_ARGUMENTS_RESOLVER_ID),
]);

// Override calls process
$container->register(self::STEP_ARGUMENT_INJECTOR_CALL_HANDLER_ID, RuntimeCallHandler::class)
->setDecoratedService(CallExtension::CALL_HANDLER_TAG.'.runtime')
->setArguments([
new Reference(self::STEP_ARGUMENT_INJECTOR_CALL_HANDLER_ID.'.inner'),
new Reference(self::STEP_ARGUMENT_INJECTOR_ARGUMENTS_RESOLVER_ID),
]);
}

/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

"autoload": {
"psr-4": {
"Gorghoa\\StepArgumentInjectorBehatExtension\\": "argumentsExt/",
"Gorghoa\\ScenarioStateBehatExtension\\": "src/",
"Symfony\\Component\\Process\\": "vendor/symfony/process/"
}
Expand Down
1 change: 1 addition & 0 deletions src/.php_cs.cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"php":"7.1.7-1+0~20170711133214.5+stretch~1.gbp5284f4","version":"2.4.0:v2.4.0#63661f3add3609e90e4ab8115113e189ae547bb4","rules":{"binary_operator_spaces":{"align_double_arrow":false,"align_equals":false},"blank_line_after_opening_tag":true,"blank_line_before_statement":{"statements":["return"]},"braces":{"allow_single_line_closure":true},"cast_spaces":true,"class_definition":{"singleLine":true},"concat_space":{"spacing":"none"},"declare_equal_normalize":true,"function_typehint_space":true,"hash_to_slash_comment":true,"include":true,"lowercase_cast":true,"magic_constant_casing":true,"method_argument_space":true,"method_separation":true,"native_function_casing":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_consecutive_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":{"use":"echo"},"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"php_unit_fqcn_annotation":true,"phpdoc_align":true,"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_empty_return":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_types":true,"phpdoc_var_without_name":true,"pre_increment":true,"protected_to_private":true,"return_type_declaration":true,"self_accessor":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_class_element_per_statement":true,"single_quote":true,"space_after_semicolon":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"blank_line_after_namespace":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_constants":true,"lowercase_keywords":true,"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true},"hashes":{"\/ScenarioStateInterface.php":2824836438,"\/Annotation\/ScenarioStateArgument.php":2979727378,"\/Context\/Initializer\/ScenarioStateInitializer.php":781987277,"\/Context\/ScenarioStateAwareTrait.php":2441401241,"\/Context\/ScenarioStateAwareContext.php":1438795547,"\/ScenarioState.php":3549039778,"\/ServiceContainer\/ScenarioStateExtension.php":1698856486,"\/Exception\/MissingStateException.php":1656618837}}
Loading

0 comments on commit a7bbc31

Please sign in to comment.