<?php
namespace nulib\schema\_scalar;

use nulib\schema\SchemaException;
use nulib\tests\TestCase;

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,
    "size" => null,
    "precision" => null,
    "" => [
      "scalar",
      "compute_func" => null,
      "validate_func" => null,
    ],
    "schema" => null,
    "name" => null,
    "pkey" => null,
    "header" => null,
    "computed" => null,
  ];

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

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

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

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

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

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