<?php
namespace nur\sery\schema;

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

class schemaTest extends TestCase {
  function testInt() {
    /** @var ScalarValue $intv */
    Schema::nv($intv, $int, null, $schema, "int");
    $f = function($value) use($intv) {
      return function() use($intv, $value) {
        $intv->set($value);
      };
    };

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

    $intv->set(12);
    self::assertSame(12, $intv->get());
    self::assertSame(12, $int);
    self::assertSame("12", $intv->format());
    self::assertSame("0012", $intv->format("%4u"));

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

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

    self::assertException(Exception::class, $f(true));
    self::assertException(Exception::class, $f(false));
    self::assertException(Exception::class, $f("a"));
    self::assertException(Exception::class, $f([]));
    self::assertException(Exception::class, $f(["a"]));
  }

  function testNint() {
    /** @var ScalarValue $intv */
    Schema::nv($intv, $int, null, $schema, "?int");
    $f = function($value) use($intv) {
      return function() use($intv, $value) {
        $intv->set($value);
      };
    };

    $intv->set(null);
    self::assertNull($intv->get());
    self::assertNull($int);
    self::assertSame("", $intv->format());

    $intv->set("");
    self::assertNull($intv->get());
    self::assertNull($int);
    self::assertSame("", $intv->format());

    $intv->set(" ");
    self::assertNull($intv->get());
    self::assertNull($int);
    self::assertSame("", $intv->format());

    $intv->set(12);
    self::assertSame(12, $intv->get());
    self::assertSame(12, $int);
    self::assertSame("12", $intv->format());
    self::assertSame("0012", $intv->format("%4u"));

    $intv->set("12");
    self::assertSame(12, $int);

    $intv->set(" 12 ");
    self::assertSame(12, $int);

    self::assertException(Exception::class, $f(true));
    self::assertException(Exception::class, $f(false));
    self::assertException(Exception::class, $f("a"));
    self::assertException(Exception::class, $f([]));
    self::assertException(Exception::class, $f(["a"]));
  }

  function testUnionTypes() {
    ## l'ordre des types doit être respecté
    
    # string puis int
    /** @var ScalarValue $siv */
    Schema::nv($siv, $si, null, $sis, "string|int");

    $siv->set("12");
    self::assertSame("12", $si);
    $siv->set(12);
    self::assertSame(12, $si);

    # int puis string
    Schema::nv($isv, $is, null, $iss, "int|string");

    $isv->set("12");
    self::assertSame(12, $is);
    $isv->set(12);
    self::assertSame(12, $is);
  }
}
