-
Notifications
You must be signed in to change notification settings - Fork 32
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
Generator with attributes #162
Comments
Hi @flip111 could you provide a sample snippet? Would be helpful for reasoning about it. |
<?php
#[Attribute]
class IntegerGenerator {
private int $min;
private int $max;
public function __construct(array $options) {
$this->min = $options['min'] ?? PHP_INT_MIN;
$this->max = $options['max'] ?? PHP_INT_MAX;
if (isset($options['preset'])) {
switch ($options['preset']) {
case 'neg':
$this->min = PHP_INT_MIN;
$this->max = -1;
break;
case 'nat':
$this->min = 0;
$this->max = PHP_INT_MAX;
break;
case 'pos':
$this->min = 1;
$this->max = PHP_INT_MAX;
break;
default:
throw new \InvalidArgumentException(sprintf('Preset "%s" is not one of %s', $options['preset'], implode(', ', ['neg', 'nat', 'pos'])));
}
}
}
public function generate() : int {
return random_int($this->min, $this->max);
}
}
class Dummy {
#[IntegerGenerator(['preset' => 'neg'])]
public int $negative;
#[IntegerGenerator(['min' => 0, 'max' => 10])]
public int $custom;
}
$reflClass = new \ReflectionClass(Dummy::class);
$reflProps = $reflClass->getProperties();
$object = new Dummy();
foreach ($reflProps as $reflProp) {
$reflAttrs = $reflProp->getAttributes();
foreach ($reflAttrs as $reflAttr) {
if ($reflAttr->getName() === 'IntegerGenerator') {
$generator = $reflAttr->newInstance();
break;
}
}
$prop_name = $reflProp->getName();
$object->$prop_name = $generator->generate();
}
var_dump($object); I have set the properties directly because they are public. But one could also put attributes on the constructor parameters. Or use a hydrator if you want to write private properties. You could also use symfony's expression language to build own generator specifications. Or you could specify a function or static method to act as generator. |
Hi @flip111 thank you for the snippet, but I was more interested in a sample usage . Maybe you'd like to have a Generators::map(
function (array $args) {
return new Dummy(...$args);
},
Generators::tuple(
Generators::neg(),
Generators::choose(0, 10)
)
) |
Hi @ilario-pierbattista let's compare differences and after talk about whether they are important or not important.
So now let's discuss the points.
You could have 3 different levels for default implementation:
I hope that answers your question |
Hi @flip111, sorry for being so late, thank you for your answer. Let's recap some points:
Did I miss something? |
It would be cool when it's possible to define a default generator as php attribute. Haskell's quickcheck also allows you to define a default implementation through the Arbitrary typeclass.
The text was updated successfully, but these errors were encountered: