<?php

namespace DrupalCodeGenerator\Tests\Generator;

use DrupalCodeGenerator\GeneratorTester;
use DrupalCodeGenerator\Tests\BaseTestCase;

/**
 * Base class for generators tests.
 */
abstract class GeneratorBaseTest extends BaseTestCase {

  protected $class;

  /**
   * Generator tester.
   *
   * @var \DrupalCodeGenerator\GeneratorTester
   */
  protected $tester;

  protected $fixtures;

  protected $interaction;

  /**
   * Command to test.
   *
   * @var \Symfony\Component\Console\Command\Command
   */
  protected $command;

  /**
   * Test callback.
   */
  public function testGenerator() {
    $this->doTest($this->interaction, $this->fixtures);
  }

  /**
   * Executes tests using provided interaction and fixtures.
   */
  public function doTest(array $interaction, array $fixtures) {

    $command_class = 'DrupalCodeGenerator\Command\\' . $this->class;

    $this->tester = new GeneratorTester(new $command_class());

    $this->tester->setDirectory($this->directory);

    $this->tester->setInteraction($interaction);

    $this->tester->setFixtures($fixtures);

    $this->tester->execute();

    static::assertEquals($this->getExpectedDisplay(), $this->getDisplay());

    foreach ($this->tester->getFixtures() as $target => $fixture) {
      $path = $this->tester->getDirectory() . '/' . $target;
      if (is_array($fixture)) {
        self::assertDirectoryExists($path);
      }
      elseif ($fixture !== NULL) {
        self::assertFileEquals($fixture, $path, $fixture);
      }
      else {
        self::markTestIncomplete();
      }
    }
  }

  /**
   * Returns the display returned by the last execution of the command.
   *
   * @return string
   *   The display.
   */
  protected function getDisplay() {
    return $this->tester->getDisplay();
  }

  /**
   * Returns expected display.
   *
   * @return string
   *   Expected display.
   */
  protected function getExpectedDisplay() {
    return $this->tester->getExpectedDisplay();
  }

}
