<?php
namespace nur\sery\schema\types;

use Exception;
use nulib\tests\TestCase;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\Schema;

class boolTest extends TestCase {
  function commonTests($destv, &$dest, callable $destvSetter): void {
    $destv->set(true);
    self::assertSame(true, $destv->get());
    self::assertSame(true, $dest);
    self::assertSame("Oui", $destv->format());
    self::assertSame("Oui", $destv->format("OuiNonNull"));
    self::assertSame("O", $destv->format("ON"));
    self::assertSame("O", $destv->format("ONN"));

    $destv->set(false);
    self::assertSame(false, $destv->get());
    self::assertSame(false, $dest);
    self::assertSame("Non", $destv->format());
    self::assertSame("Non", $destv->format("OuiNonNull"));
    self::assertSame("N", $destv->format("ON"));
    self::assertSame("N", $destv->format("ONN"));

    $destv->set("yes");
    self::assertSame(true, $destv->get());

    $destv->set(" yes ");
    self::assertSame(true, $destv->get());

    $destv->set("12");
    self::assertSame(true, $destv->get());

    $destv->set(12);
    self::assertSame(true, $destv->get());

    $destv->set("no");
    self::assertSame(false, $destv->get());

    $destv->set(" no ");
    self::assertSame(false, $destv->get());

    $destv->set("0");
    self::assertSame(false, $destv->get());

    $destv->set(0);
    self::assertSame(false, $destv->get());

    $destv->set(12.34);
    self::assertSame(true, $destv->get());

    self::assertException(Exception::class, $destvSetter("a"));
    self::assertException(Exception::class, $destvSetter([]));
    self::assertException(Exception::class, $destvSetter(["a"]));

  }

  function testBool() {
    /** @var ScalarValue $destv */
    Schema::nv($destv, $dest, null, $schema, "bool");
    $destvSetter = function($value) use($destv) {
      return function() use($destv, $value) {
        $destv->set($value);
      };
    };

    self::assertException(Exception::class, $destvSetter(null));
    self::assertException(Exception::class, $destvSetter(""));
    self::assertException(Exception::class, $destvSetter(" "));

    $this->commonTests($destv, $dest, $destvSetter);
  }

  function testNbool() {
    /** @var ScalarValue $destv */
    Schema::nv($destv, $dest, null, $schema, "?bool");
    $destvSetter = function($value) use($destv) {
      return function() use($destv, $value) {
        $destv->set($value);
      };
    };

    $destv->set(null);
    self::assertNull($destv->get());
    self::assertNull($dest);
    self::assertSame("Non", $destv->format());
    self::assertSame("", $destv->format("OuiNonNull"));
    self::assertSame("N", $destv->format("ON"));
    self::assertSame("", $destv->format("ONN"));

    $destv->set("");
    self::assertNull($destv->get());
    self::assertNull($dest);
    self::assertSame("Non", $destv->format());
    self::assertSame("", $destv->format("OuiNonNull"));
    self::assertSame("N", $destv->format("ON"));
    self::assertSame("", $destv->format("ONN"));

    $destv->set(" ");
    self::assertNull($destv->get());
    self::assertNull($dest);
    self::assertSame("Non", $destv->format());
    self::assertSame("", $destv->format("OuiNonNull"));
    self::assertSame("N", $destv->format("ON"));
    self::assertSame("", $destv->format("ONN"));

    $this->commonTests($destv, $dest, $destvSetter);
  }
}
