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

use nulib\tests\TestCase;
use nur\sery\wip\schema\_scalar\ScalarSchema;
use nur\sery\wip\schema\SchemaException;

class ScalarSchemaTest extends TestCase {
  const NULL_SCHEMA = [
    "type" => [null],
    "default" => null,
    "title" => null,
    "required" => false,
    "nullable" => true,
    "desc" => null,
    "analyzer_func" => null,
    "extractor_func" => null,
    "parser_func" => null,
    "normalizer_func" => null,
    "messages" => null,
    "formatter_func" => null,
    "format" => null,
    "" => ["scalar"],
    "name" => null,
    "pkey" => null,
    "header" => null,
    "composite" => null,
  ];

  static function schema(array $schema): array {
    return array_merge(self::NULL_SCHEMA, $schema);
  }

  function testNormalize() {
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize(null));
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([]));
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([null]));
    self::assertException(SchemaException::class, function () {
      ScalarSchema::normalize([[]]);
    });
    self::assertException(SchemaException::class, function () {
      ScalarSchema::normalize([[null]]);
    });

    $string = self::schema(["type" => ["string"], "nullable" => false]);
    self::assertSame($string, ScalarSchema::normalize("string"));
    self::assertSame($string, ScalarSchema::normalize(["string"]));

    $nstring = self::schema(["type" => ["string"]]);
    self::assertSame($nstring, ScalarSchema::normalize(["?string"]));
    self::assertSame($nstring, ScalarSchema::normalize(["?string|null"]));
    self::assertSame($nstring, ScalarSchema::normalize(["string|null"]));
    self::assertSame($nstring, ScalarSchema::normalize([["?string", "null"]]));
    self::assertSame($nstring, ScalarSchema::normalize([["string", "null"]]));
    self::assertSame($nstring, ScalarSchema::normalize([["string", null]]));

    $key = self::schema(["type" => ["string", "int"], "nullable" => false]);
    self::assertSame($key, ScalarSchema::normalize("string|int"));

    $nkey = self::schema(["type" => ["string", "int"], "nullable" => true]);
    self::assertSame($nkey, ScalarSchema::normalize("?string|int"));
    self::assertSame($nkey, ScalarSchema::normalize("string|?int"));
  }
}
