<commit_before><?php

namespace Phamda\Builder\Tests;

use Phamda\Builder\BuilderInterface;
use PhpParser\BuilderFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt;

class BasicTestMethodBuilder implements BuilderInterface
{
    private $factory;
    private $name;
    private $source;

    public function __construct($name, Expr\Closure $source)
    {
        $this->name   = $name;
        $this->source = $source;

        $this->factory = new BuilderFactory();
    }

    public function build()
    {
        return $this->factory->method($this->getHelperMethodName('test%s'))
            ->setDocComment($this->createComment())
            ->addParams($this->createParams())
            ->addStmts($this->createStatements())
        ;
    }

    private function createComment()
    {
        return <<<EOT
/**
 * @dataProvider {$this->getHelperMethodName('get%sData')}
 */
EOT;
    }

    private function getHelperMethodName($format)
    {
        return sprintf($format, ucfirst(trim($this->name, '_')));
    }

    private function returnsCallable()
    {
        return $this->getReturnStatement()->expr instanceof Expr\Closure;
    }

    private function getReturnStatement()
    {
        foreach ($this->source->stmts as $statement) {
            if ($statement instanceof Stmt\Return_) {
                /** @var Stmt\Return_ $statement */
                return $statement;
            }
        }

        return null;
    }

    private function getInnerFunctionParams()
    {
        return $this->returnsCallable() ? $this->getReturnStatement()->expr->params : [];
    }

    private function createParams()
    {
        $params = [];
        foreach ($this->source->uses as $index => $use) {
            $params[] = $this->factory->param($use->var);
        }

        foreach ($this->source->params as $param) {
            $newParam = clone $param;

            $params[] = $newParam;
        }

        $params[] = $this->factory->param('expected');

        $params = array_merge($params, $this->getInnerFunctionParams());

        return $params;
    }

    private function createStatements()
    {
        return $this->source->uses
            ? $this->createUseStatements()
            : $this->createParameterStatements();
    }

    private function createUseStatements()
    {
        $function = new Expr\Variable('wrapped');

        return [
            new Expr\Assign($function, $this->createFunctionCall($this->source->uses)),
            $this->createAssert($this->createFunctionCall($this->source->params, $function))
        ];
    }<commit_msg>Make expected value the first argument in tests<commit_after><?php

namespace Phamda\Builder\Tests;

use Phamda\Builder\BuilderInterface;
use PhpParser\BuilderFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt;

class BasicTestMethodBuilder implements BuilderInterface
{
    private $factory;
    private $name;
    private $source;

    public function __construct($name, Expr\Closure $source)
    {
        $this->name   = $name;
        $this->source = $source;

        $this->factory = new BuilderFactory();
    }

    public function build()
    {
        return $this->factory->method($this->getHelperMethodName('test%s'))
            ->setDocComment($this->createComment())
            ->addParams($this->createParams())
            ->addStmts($this->createStatements())
        ;
    }

    private function createComment()
    {
        return <<<EOT
/**
 * @dataProvider {$this->getHelperMethodName('get%sData')}
 */
EOT;
    }

    private function getHelperMethodName($format)
    {
        return sprintf($format, ucfirst(trim($this->name, '_')));
    }

    private function returnsCallable()
    {
        return $this->getReturnStatement()->expr instanceof Expr\Closure;
    }

    private function getReturnStatement()
    {
        foreach ($this->source->stmts as $statement) {
            if ($statement instanceof Stmt\Return_) {
                /** @var Stmt\Return_ $statement */
                return $statement;
            }
        }

        return null;
    }

    private function getInnerFunctionParams()
    {
        return $this->returnsCallable() ? $this->getReturnStatement()->expr->params : [];
    }

    private function createParams()
    {
        $params = [$this->factory->param('expected')];

        foreach ($this->source->uses as $index => $use) {
            $params[] = $this->factory->param($use->var);
        }

        foreach ($this->source->params as $param) {
            $newParam = clone $param;

            $params[] = $newParam;
        }

        $params = array_merge($params, $this->getInnerFunctionParams());

        return $params;
    }

    private function createStatements()
    {
        return $this->source->uses
            ? $this->createUseStatements()
            : $this->createParameterStatements();
    }

    private function createUseStatements()
    {
        $function = new Expr\Variable('wrapped');

        return [
            new Expr\Assign($function, $this->createFunctionCall($this->source->uses)),
            $this->createAssert($this->createFunctionCall($this->source->params, $function))
        ];
    }
{'fraction_non_alphanumeric': 0.13941769316909294, 'fraction_numerical': 0.0, 'mean_word_length': 2.4199106573069558, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2392130', 'n_tokens_mistral': 1517, 'n_tokens_neox': 1474, 'n_words': 282}