<?php
namespace nulib\schema\types;

use Exception;
use nulib\schema\_scalar\ScalarWrapper;
use nulib\schema\Schema;
use nulib\tests\TestCase;

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

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

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

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

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

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

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

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

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

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

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

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

  }

  function testBool() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, "bool", $schema, $wrapper);
    $wrapperSetter = function($value) use($wrapper) {
      return function() use($wrapper, $value) {
        $wrapper->set($value);
      };
    };

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

    $this->commonTests($wrapper, $value, $wrapperSetter);
  }

  function testNbool() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, "?bool", $schema, $wrapper);
    $wrapperSetter = function($value) use($wrapper) {
      return function() use($wrapper, $value) {
        $wrapper->set($value);
      };
    };

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

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

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

    $this->commonTests($wrapper, $value, $wrapperSetter);
  }
}
