<?php
namespace nulib\schema\types;

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

class floatTest extends TestCase {
  function commonTests($wrapper, &$value, callable $wrapperSetter): void {
    $wrapper->set(12);
    self::assertSame(12.0, $wrapper->get());
    self::assertSame(12.0, $value);
    self::assertSame("12", $wrapper->format());
    self::assertSame("0012", $wrapper->format("%04u"));

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

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

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

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

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

  function testFloat() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, "float", $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(" "));

    // valeur non requise donc retourne null
    $wrapper->set(false);
    self::assertNull($wrapper->get());

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

  function testRequiredFloat() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, [
      "float", null,
      "required" => true,
    ], $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(" "));

    // valeur requise donc lance une exception
    self::assertException(Exception::class, $wrapperSetter(false));

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

  function testNfloat() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, "?float", $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("", $wrapper->format());

    $wrapper->set("");
    self::assertNull($wrapper->get());
    self::assertNull($value);
    self::assertSame("", $wrapper->format());

    $wrapper->set(" ");
    self::assertNull($wrapper->get());
    self::assertNull($value);
    self::assertSame("", $wrapper->format());

    // valeur non requise donc retourne null
    $wrapper->set(false);
    self::assertNull($wrapper->get());

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

  function testRequiredNfloat() {
    /** @var ScalarWrapper $wrapper */
    Schema::nw($value, null, [
      "?float", null,
      "required" => true,
    ], $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("", $wrapper->format());

    $wrapper->set("");
    self::assertNull($wrapper->get());
    self::assertNull($value);
    self::assertSame("", $wrapper->format());

    $wrapper->set(" ");
    self::assertNull($wrapper->get());
    self::assertNull($value);
    self::assertSame("", $wrapper->format());

    // valeur requise donc lance une exception
    self::assertException(Exception::class, $wrapperSetter(false));

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