<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

/**
 * Generated by PHPUnit_SkeletonGenerator on 2017-03-24 at 12:06:44.
 */
class CleanDatamodulForHtmlTest extends \PHPUnit\Framework\TestCase
{
  private function getFakeDatamodul()
  {
    $unsauberesDatamodul = new FakeDatamodul();
    $unsauberesDatamodul->extDatamodul = new FakeInneresDatamodul();

    return $unsauberesDatamodul;
  }

  private function getCleanDatamodul($unsauberesDatamodul)
  {
    return new CleanDatamodulForHtml($unsauberesDatamodul);
  }

  /**
   * @covers CleanDatamodulForHtml::getVarValue
   * @test
   */
  public function getVarValue_NormalValues_CleanForHtml()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $init = function($name, $value) use ($unsauberesDatamodul) {
      $unsauberesDatamodul->{$name} = $value;
    };

    $call = function($name) use ($cleanDatamodul) {
      return $cleanDatamodul->getVarValue($name);
    };

    $this->assertMultipleVariables($init, $call);
  }

  /**
   * @covers CleanDatamodulForHtml::getVarValueEx
   * @test
   */
  public function getVarValueEx_NormalValues_CleanForHtml()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $init = function($name, $value) use ($unsauberesDatamodul) {
      $unsauberesDatamodul->extDatamodul->{$name} = $value;
    };

    $call = function($name) use ($cleanDatamodul) {
      return $cleanDatamodul->getVarValueEx($name, 'FakeInneresDatamodul');
    };

    $this->assertMultipleVariables($init, $call);
  }

  /**
   * @covers CleanDatamodulForHtml::__get
   * @test
   */
  public function getMagicFunction_Attribut_CleanForHtml()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $init = function($name, $value) use ($unsauberesDatamodul) {
      $unsauberesDatamodul->{$name} = $value;
    };

    $call = function($name) use ($cleanDatamodul) {
      return $cleanDatamodul->{$name};
    };

    $this->assertMultipleVariables($init, $call);
  }

  /**
   * @covers CleanDatamodulForHtml::__get
   * @test
   */
  public function getMagicFunction_AttributFromExtDatamodul_CleanForHtml()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $init = function($name, $value) use ($unsauberesDatamodul) {
      $unsauberesDatamodul->extDatamodul->{$name} = $value;
    };

    $call = function($name) use ($cleanDatamodul) {
      return $cleanDatamodul->extDatamodul->{$name};
    };

    $this->assertMultipleVariables($init, $call);
  }

  /**
   * Hilfsfunktion zum Testen der verschiedenen Variablentypen.
   *
   * @param callable $init Funktion zum Vorbelegen der Variablen
   * @param callable $call Funktion die die zu testende Funktion aufruft.
   */
  private function assertMultipleVariables($init, $call)
  {
    call_user_func($init, 'text', 'abcABC0123456789');
    $this->assertEquals('abcABC0123456789', call_user_func($call, 'text'));

    call_user_func($init, 'text', 'äöüÄÖÜß€@ _-');
    $this->assertEquals('&auml;&ouml;&uuml;&Auml;&Ouml;&Uuml;&szlig;&euro;@ _-', call_user_func($call, 'text'));

    call_user_func($init, 'text', '<>&');
    $this->assertEquals('&lt;&gt;&amp;', call_user_func($call, 'text'));

    call_user_func($init, 'int', '1');
    $this->assertEquals('1', call_user_func($call, 'int'));

    call_user_func($init, 'int', '');
    $this->assertEquals('0', call_user_func($call, 'int'));

    call_user_func($init, 'int', 'drei');
    $this->assertEquals('0', call_user_func($call, 'int'));

    call_user_func($init, 'floatMitKomma', '1,10');
    $this->assertEquals('1,10', call_user_func($call, 'floatMitKomma'));

    call_user_func($init, 'floatMitKomma', '1.10');
    $this->assertEquals('0', call_user_func($call, 'floatMitKomma'));

    call_user_func($init, 'floatMitPunkt', '1.10');
    $this->assertEquals(1.10, call_user_func($call, 'floatMitPunkt'));

    call_user_func($init, 'floatMitPunkt', '1,10');
    $this->assertEquals(0, call_user_func($call, 'floatMitPunkt'));

    call_user_func($init, 'date', '29.02.2016'); // Schaltjahr
    $this->assertEquals('29.02.2016', call_user_func($call, 'date'));

    call_user_func($init, 'date', '29.02.2017');
    $this->assertEquals('30.12.1899', call_user_func($call, 'date'));

    call_user_func($init, 'time', '23:59');
    $this->assertEquals('23:59', call_user_func($call, 'time'));

    call_user_func($init, 'time', '24:00');
    $this->assertEquals('00:00', call_user_func($call, 'time'));

    // TODO Boolean und weitere Testfälle testen sobald umgesetzt. Bzw. was ist der Boolean-Wert in Html?
  }

  /**
   * @covers CleanDatamodulForHtml::__set
   * @test
   */
  public function setMagicFunction_setAttribut_AttributGetsSet()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $cleanDatamodul->int = 10;
    $this->assertEquals(10, $unsauberesDatamodul->int);

    $cleanDatamodul->extDatamodul->text = 'äöü';
    $this->assertEquals('äöü', $unsauberesDatamodul->extDatamodul->text);
  }

  /**
   * @covers CleanDatamodulForHtml::__call
   * @test
   */
  public function callMagicFunction_callFunction_FunctionGetsCalled()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $unsauberesDatamodul->funcGetCalled = false;
    $this->assertEquals('abc', $cleanDatamodul->funcStrToLower('ABC'));
    $this->assertTrue($unsauberesDatamodul->funcGetCalled);
  }

  /**
   * @covers CleanDatamodulForHtml::__call
   * @test
   */
  public function callMagicFunction_setValue2Var_VariablesGetSet()
  {
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $cleanDatamodul->setValue2Var('int', 10);
    $this->assertEquals(10, $unsauberesDatamodul->int);

    $cleanDatamodul->setValue2VarEx('text', 'äöü', 'FakeInneresDatamodul');
    $this->assertEquals('äöü', $unsauberesDatamodul->extDatamodul->text);
  }

  /**
   * @covers CleanDatamodulForHtml::__staticCall
   * @ignore test
   */
  public function callStaticMagicFunction_callFunction_FunctionGetsCalled()
  {
    /* Wird derzeit nicht unterstützt, da ich nicht das konkrete Datamodul kenne! Das doofe ist: Sogar wenn auf dem Objekt die Funktion statisch aufgerufen wird kann ich nicht auf $this zugreifen.
    $unsauberesDatamodul = $this->getFakeDatamodul();
    $cleanDatamodul = $this->getCleanDatamodul($unsauberesDatamodul);

    $unsauberesDatamodul::$staticFuncGetCalled = false;
    $this->assertEquals('abc', $cleanDatamodul::staticFuncStrToLower('ABC'));
    $this->assertTrue($unsauberesDatamodul::$staticFuncGetCalled);
     */
  }
}

class FakeDatamodul extends Datamodul
{
  public $extDatamodul; // FakeInneresDatamodul. Das innere Objekt darf nicht von der gleichen Klasse sein, sonst geht getVarValueEx nicht darauf ein.

  public $text;

  public $int;

  public $floatMitPunkt;

  public $floatMitKomma;

  public $date;

  public $time;

  public $dateTime;

  public $bool;
  public $boolJn;
  public $boolWf;

  public $wfEmpty;
  public $binary;
  public $array;

  public function getTyp($name)
  {
    switch ($name) {
      default: return parent::getTyp($name);
      case 'text': return \DatamodulVarType::TYPE_STRING;
      case 'int': return \DatamodulVarType::TYPE_INT;
      case 'floatMitPunkt': return \DatamodulVarType::TYPE_FLOAT_DOT;
      case 'floatMitKomma': return \DatamodulVarType::TYPE_FLOAT;
      case 'date': return \DatamodulVarType::TYPE_DATE;
      case 'time': return \DatamodulVarType::TYPE_TIME;
      case 'dateTime': return \DatamodulVarType::TYPE_DATETIME;
      case 'bool': return \DatamodulVarType::TYPE_BOOL;
      case 'boolJn': return \DatamodulVarType::TYPE_BOOL_JN;
      case 'boolWf': return \DatamodulVarType::TYPE_BOOL_WF;
      case 'wfEmpty': return \DatamodulVarType::TYPE_WF_EMPTY;
      case 'binary': return \DatamodulVarType::TYPE_BINARY;
      case 'array': return \DatamodulVarType::TYPE_ARRAY;
    }
  }

  public $funcGetCalled = false;

  public function funcStrToLower($value)
  {
    $this->funcGetCalled = true;

    return strtolower($value);
  }

  public static $staticFuncGetCalled = false;

  public static function staticFuncStrToLower($value)
  {
    self::$staticFuncGetCalled = true;

    return strtolower($value);
  }
}

class FakeInneresDatamodul extends FakeDatamodul
{
}
