With codeception is there a way to use constants ( or variables) using the #example annotation ?
I know that we can use doctrine style annotation.
Data is defined via the #example annotation, using JSON or Doctrine-style notation (limited to a single line). Doctrine-style
class PageCest
{
/**
* #example(url="/", title="Welcome")
* #example(url="/info", title="Info")
* #example(url="/about", title="About Us")
* #example(url="/contact", title="Contact Us")
*/
public function staticPages(AcceptanceTester $I, \Codeception\Example $example)
{
$I->amOnPage($example['url']);
$I->see($example['title'], 'h1');
$I->seeInTitle($example['title']);
}
}
But using a constant which is working in doctrine doesn't seems to work here
/**
* #example(url=Class::Constant, title="Welcome")
*/
is there a way to achieve this to run multiple test examples but use constants or variables to provide the values?
It seems that there is no way to do that directly like doctrine's implementation.
the workaround I found is to pass the constant name as a string .
/**
* #example(url="MyConstantName", title="Welcome")
*/
and then within the code use the constant function to find your constant value.
constant('Full\Namespace\MyClass::' . $example['MyConstantName'])
Related
I am trying to define with a PHPDoc inline #var a magic field variable to set the correct type but the IDE is not auto-completing anything.
It is showing "Field accessed via magic method". I tried to remove it from the Inspections settings but then the warning is not showed and still it is not auto-completing.
I have tried different ways without success:
/** #var \NameSpace\SomeClass $this->field */
$this->field->someMethod(); // Not auto-completing
/** #var \NameSpace\SomeClass $this::field */
$this->field->someMethod(); // Not auto-completing
For other hand if I define a new variable it will work:
$field = $this->field;
/** #var \NameSpace\SomeClass $field */
$field->someMethod(); // Auto-completing correctly
Somebody knows how to do it to work the auto-completing feature without define a new variable? Is it possible?
UPDATE: I cannot use the #property attribute because $field is not always the same class in the main class.
It has to be done via #property tag at class-level PHPDoc comment.
/**
* My special class
*
* #property \NameSpace\SomeClass $field Optional my magical variable description
*/
class MySpecialClass {
....
https://docs.phpdoc.org/references/phpdoc/tags/property.html
/** #var \NameSpace\SomeClass $this->field */
This will never work -- you cannot provide typehint for 2nd level variable/element ($this->field) using inline #var. If anything: only first level entities can be typehinted.
It is not possible to provide typehint for 2nd level variable/element ($this->field) using inline #var (thank to #LazyOne).
So a possible solution would be set the #property with all classes using in the main class:
/**
* My special class
*
* #property \NameSpace\SomeClass|OtherSomeClass|OneMore $field
*/
class MySpecialClass {
By this way the magic field $field would be auto-completing with all method of all classes defined.
PhpStorm does not detect undefined variables, when they are passed to a function by reference.
func1($a);
func2($a);
function func1(&$a) {
}
function func2($a) {
}
In this example, only the variable $a in the invocation of func2 is highlighted.
How can I change that?
Put under function func1 something like this:
/**
* func1
*
* #param string $a
* #return mixed
*/
Its better to describe all methods and properties by PHP Annotations. And change string if it is another type.
I have recently started with learning Swift for iOS development. I have a background in scripting languages, especially PHP. Seeing that it is emphasized using let to define a constant in favor of var to have the compiler optimize the resulting code, I wondered: is there an equivalent for PHP? Or does it simply not apply as PHP is not statically compiled?
I tried my luck at searching but found no satisfying information on that point.
No, you can't have locally scoped constants in PHP. All PHP constants are always globally visible. There is also no concept like immutable/mutable variables.
You can implement immutable object members (PHP: immutable public member fields), but it's a different thing.
Actually there is a const keyword in the language, but the docs say:
Note:
As opposed to defining constants using define(), constants defined using the const keyword must be declared at the top-level scope because they are defined at compile-time. This means that they cannot be declared inside functions, loops, if statements or try/ catch blocks.
(from http://php.net/manual/en/language.constants.syntax.php)
Interpreted languages with a dynamic type systems can have something like the swift let statement, so this is not because swift is compiled and PHP is interpreted (for example, there is a javascript proposal to introduce that feature: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/const)
Is there an equivalent of “let” vs. “var” in PHP?
PHP doesn't have let as a native language feature, yet (as of current version 7.1.4 - 04/2017)
But, some high-performance extensions like Phalcon and Ice have support for let, because of the underlying usage of zephir-lang.
So, there is let, but indirectly; using the above mentioned extensions.
There are two use cases:
define a variable from a super global
define a variable in the local PHP symbol table, e.g.
// set variable $price in PHP
let name = "price";
let {name} = 10.2;
As an example take a look at the source for the Ice Router:
namespace Ice\Mvc\Route;
use Ice\Mvc\Route\Parser\ParserInterface;
use Ice\Mvc\Route\DataGenerator\DataGeneratorInterface;
use Ice\Mvc\Route\Parser\Std;
use Ice\Mvc\Route\DataGenerator\GroupCount as Generator;
class Collector
{
private routeParser { set };
private dataGenerator { set };
/**
* Constructs a route collector.
*
* #param RouteParser $routeParser
* #param DataGenerator $dataGenerator
*/
public function __construct(<ParserInterface> routeParser = null, <DataGeneratorInterface> dataGenerator = null)
{
if !routeParser {
let routeParser = new Std();
}
if !dataGenerator {
let dataGenerator = new Generator();
}
let this->routeParser = routeParser,
this->dataGenerator = dataGenerator;
}
/**
* Adds a route to the collection.
*
* The syntax used in the $route string depends on the used route parser.
*
* #param string|array $httpMethod
* #param string $route
* #param mixed $handler
*/
public function addRoute(var httpMethod, string route, handler = null)
{
var routeDatas, routeData, method;
let routeDatas = this->routeParser->parse(route);
if typeof httpMethod == "string" {
let method = httpMethod,
httpMethod = [method];
}
for method in httpMethod {
for routeData in routeDatas {
this->dataGenerator->addRoute(method, routeData, handler);
}
}
}
/**
* Returns the collected route data, as provided by the data generator.
*
* #return array
*/
public function getData()
{
return this->dataGenerator->getData();
}
}
What's the best way to document a method that modifies a protected attribute with phpdoc?
For instance, what is the correct way of documenting the setVar() method below?
class Test {
protected $variables = array();
public function setVar($name, $value) {
$this->$variables[$name] = $value;
}
}
Thanks in advance,
.L.
I suppose it depends on why you are wanting to highlight that the method affects that protected attribute...
If you just want to "say" it, just say so in the description, with or without using an inline #link tag:
/**
* Setter for $variables or {#link Test::$variables}
* ...
By using the inline #link, a hyperlink to the $variables documentation is generated in the method's description.
You could use the #see tag to be a standalone reference to the attribute:
/**
* Setter
* #see Test::$variables
* ...
This also makes a hyperlink to the attribute's doc, but it's more prominent by having its own tag.
If you want to create a "pointer" from the method to the attribute, use the #uses tag:
/**
* Setter
* #uses Test::$variables
* ...
The #uses tag in the method here will automatically place a #usedby tag in the documentation for the $variables property... the result is a hyperlink from the method to the attribute in the method's doc, as well as a hyperlink from the attribute to the method in the attribute's doc. Think of it as analogous to the "secret passages" in the Clue board game that connect corner rooms to their opposite corner rooms.
Another intention that can be satisfied via the #uses tag is that the documentation for $variables will show a list of #usedby tags that show all methods that affect the attribute... assuming, of course, that you have been conscientious about putting #uses tags in those methods.
I usually use something akin to the following, although there is probably a better way.
class Test {
protected $variables = array();
//**
* Setter for $this->variables
*
* #var string
* #var string
* #returns void
*/
public function setVar($name, $value) {
$this->$variables[$name] = $value;
}
}
I want to fetch a method's comments,take below method for example:
/**
* Returns the regex to extract all inputs from a file.
* #param string The class name to search for.
* #return string The regex.
*/
public function method($param)
{
//...
}
the result should be
Returns the regex to extract all inputs from a file.
#param string The class name to search for.
#return string The regex.
the way I find is use a function like file_get_content to get file content -> filter the method I want -> fetch the comment use regexp
it seems a bit complicated , is there any convenient way to archive this?
actually you can get a method's doc comments with getDocComment
$ref=new ReflectionMethod('className', 'methodName');
echo $ref->getDocComment();
If you want to use the comment in PHP for something check out getDocComment in php's reflection api
PHP Doc. Like Java Doc.
For a method dump I use this little function I composed.
It fetches all methods from provided class that are public(and thus of use to you).
I personally use a dump() method to nicely format the outputted array of method names and descriptions, but that's not needed if you wish to use it for something else :-)
function getDocumentation($inspectclass) {
/** Get a list of all methods */
$methods = get_class_methods($inspectclass);
/** Get the class name */
$class =get_class($inspectclass);
$arr = [];
foreach($methods as $method) {
$ref=new ReflectionMethod( $class, $method);
/** No use getting private methods */
if($ref->isPublic()) {
$arr[$method] = $ref->getDocComment();
}
}
/** dump is a formatting function I use, feel free to use your own */
return dump($arr);
}
echo getDocumentation($this);