Completed
Branch master (5c1aa1)
by Greg
02:05
created

GherkinParam   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 8
Bugs 3 Features 2
Metric Value
wmc 17
c 8
b 3
f 2
lcom 1
cbo 5
dl 0
loc 110
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getValueFromParam() 0 15 4
A getValueFromConfig() 0 18 4
A getValueFromArray() 0 13 2
A beforeSuite() 0 4 1
B beforeStep() 0 31 6
1
<?php
2
/**
3
 * Before step hook that provide parameter syntax notation
4
 * for accessing fixture data between Gherkin steps/tests
5
 * example:
6
 *  I see "{{param}}"
7
 *  {{param}} will be replaced by the value of Fixtures::get('param')
8
 *
9
 */
10
namespace Codeception\Extension;
11
12
use Codeception\Util\Fixtures;
13
use Behat\Gherkin\Node\TableNode;
14
use ReflectionProperty;
15
16
class GherkinParam extends \Codeception\Platform\Extension
17
{
18
  // list events to listen to
19
  public static $events = array(
20
    //run before any suite
21
    'suite.before' => 'beforeSuite',
22
    //run before any steps
23
    'step.before' => 'beforeStep'
24
  );
25
26
  private static $suite_config;
27
28
  private static $regEx = Array(
29
                          'match'  => '/^{{[A-z0-9_:-]+}}$/',
30
                          'filter' => '/[{}]/',
31
                          'config' => '/(?:^config)?:([A-z0-9_-]+)+(?=:|$)/',
32
                          'array'  => '/^(?P<var>[A-z0-9_-]+)(?:\[(?P<key>.+)])$/'
33
                        );
34
35
  // parse param and replace {{.*}} by its Fixtures::get() value if exists
36
  protected function getValueFromParam($param)
37
  {
38
    if (preg_match(static::$regEx['match'], $param)) {
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
39
      $arg = preg_filter(static::$regEx['filter'], '', $param);
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
40
      if (preg_match(static::$regEx['config'], $arg)) {
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
41
        return $this->getValueFromConfig($arg);
42
      } elseif (preg_match(static::$regEx['array'], $arg)) {
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
43
        return $this->getValueFromArray($arg);
44
      }else {
45
        return Fixtures::get($arg);
46
      }
47
    } else {
48
      return $param;
49
    }
50
  }
51
52
  protected function getValueFromConfig($param)
53
  {
54
    $value = null;
55
    $config = static::$suite_config;
1 ignored issue
show
Bug introduced by
Since $suite_config is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $suite_config to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
56
57
    preg_match_all(static::$regEx['config'], $param, $args, PREG_PATTERN_ORDER);
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
58
    foreach ($args[1] as $arg) {
59
      if (array_key_exists($arg, $config)) {
60
        $value = $config[$arg];
61
        if (is_array($value)) {
62
          $config = $value;
63
        } else {
64
          break;
65
        }
66
      }
67
    }
68
    return $value;
69
  }
70
71
  protected function getValueFromArray($param)
72
  {
73
    $value = null;
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
74
75
    preg_match_all(static::$regEx['array'], $param, $args);
1 ignored issue
show
Bug introduced by
Since $regEx is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $regEx to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
76
    $array = Fixtures::get($args['var'][0]);
77
    if (array_key_exists($args['key'][0], $array)) {
78
        $value = $array[$args['key'][0]];
79
    } else {
80
      return null;
81
    }
82
    return $value;
83
  }
84
85
  /**
86
   * @codeCoverageIgnore
87
   */
88
  public function beforeSuite(\Codeception\Event\SuiteEvent $e)
89
  {
90
    static::$suite_config = $e->getSettings();
1 ignored issue
show
Bug introduced by
Since $suite_config is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $suite_config to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
91
  }
92
93
  public function beforeStep(\Codeception\Event\StepEvent $e)
94
  {
95
    $step = $e->getStep();
96
    // access to the protected property using reflection
97
    $refArgs = new ReflectionProperty(get_class($step), 'arguments');
98
    // change property accessibility to public
99
    $refArgs->setAccessible(true);
100
    // retrieve 'arguments' value
101
    $args = $refArgs->getValue($step);
102
    foreach ($args as $index => $arg) {
103
      if (is_string($arg)) {
104
      // case if arg is a string
105
      // e.g. I see "{{param}}"
106
        $args[$index] = $this->getValueFromParam($arg);
107
      } elseif (is_a($arg, '\Behat\Gherkin\Node\TableNode')) {
108
      // case if arg is a table
109
      // e.g. I see :
110
      //  | paramater |
111
      //  | {{param}} |
112
        $table = Array();
113
        foreach ($arg->getRows() as $i => $row) {
114
          foreach ($row as $j => $cell) {
115
              $table[$i][$j] = $this->getValueFromParam($cell);
116
          }
117
        }
118
        $args[$index] = new TableNode($table);
119
      }
120
    }
121
    // set new arguments value
122
    $refArgs->setValue($step, $args);
123
  }
124
125
}
126