<?php

namespace ActivityPhpTest\Type;

use ActivityPhpTest\MyCustomType;
use ActivityPhp\Type;
use Exception;
use PHPUnit\Framework\TestCase;

class AbstractObjectTest extends TestCase
{
	/**
	 * Test valid setters
	 */
	public function testValidSetters()
	{
		$type = Type::create('ObjectType');

		$value = 'http://example1.com';
		$type->id = $value;
		$this->assertEquals($value, $type->id);

		$value = 'http://example2.com';
		$type->set('id', $value);
		$this->assertEquals($value, $type->id);

		$value = 'http://example3.com';
		$type->setId($value);
		$this->assertEquals($value, $type->id);
	}


	/**
	 * Test valid getters
	 */
	public function testValidGetters()
	{
		$type = Type::create('ObjectType');

		$value = 'http://example1.com';
		$type->id = $value;
		$this->assertEquals($value, $type->id);

		$value = 'http://example2.com';
		$type->set('id', $value);
		$this->assertEquals($value, $type->getId());

		$value = 'http://example3.com';
		$type->setId($value);
		$this->assertEquals($value, $type->get('id'));
	}


	/**
	 * Getting a non defined should throw an exception
	 */
	public function testGetEmptyProperty()
	{
		$this->expectException(Exception::class);

		$object = Type::create('ObjectType');
		$object->myCustomAttribute;
	}


	/**
	 * Setting without argument should throw an exception
	 */
	public function testSetWithNoArgument()
	{
		$this->expectException(Exception::class);

		$object = Type::create('ObjectType');
		$object->setMyCustomAttribute();
	}


	/**
	 * Call an undefined method
	 */
	public function testCallUndefinedMethod()
	{
		$this->expectException(Exception::class);

		$object = Type::create('ObjectType');
		$object->illegalCall();
	}


	/**
	 * tests getProperties() method
	 */
	public function testGetProperties()
	{
		$expected = [
		    'type',
		    'id',
		    'name',
		    'nameMap',
		    'href',
		    'hreflang',
		    'mediaType',
		    'rel',
		    'height',
		    'preview',
		    'width'
		];

		$this->assertEquals(
		    $expected,
		    Type::create('Link')->getProperties()
		);
	}


	/**
	 * tests toArray() method
	 */
	public function testToArrayWithEmptyProperties()
	{
		$expected = [
		    'type' => 'Link',
		    'name' => 'An example',
		    'href' => 'http://example.com',
		];

		$this->assertEquals(
		    $expected,
		    Type::create('Link', $expected)->toArray()
		);
	}


	/**
	 * Try to set a property without any validator
	 */
	public function testToSetFreeProperty()
	{
		Type::add('MyCustomType', MyCustomType::class);

		$expected = [
		    'type' => 'MyCustomType',
		    'customFreeProperty' => 'Free value',
		    'streams' => [],
		];

		$this->assertEquals(
		    $expected,
		    Type::create('MyCustomType', $expected)->toArray()
		);
	}


	/**
	 * tests toArray() method
	 */
	public function testToArrayWithSomePropertiesSet()
	{
		$expected = [
		    'type' => 'Link',
		];

		$this->assertEquals(
		    $expected,
		    Type::create('Link')->toArray()
		);
	}


	/**
	 * tests toJson() method
	 */
	public function testToJson()
	{
		$expected = [
		    'type' => 'Link',
		];

		$this->assertEquals(
		    '{"type":"Link"}',
		    Type::create('Link')->toJson()
		);
	}


	/**
	 * tests toJson() method
	 */
	public function testToJsonWithSomeProperties()
	{
		$expected = [
		    'type' => 'Link',
		    'name' => 'An example',
		    'href' => 'http://example.com',
		];

		$this->assertEquals(
		    '{"type":"Link","name":"An example","href":"http:\/\/example.com"}',
		    Type::create($expected)->toJson()
		);
	}


	/**
	 * tests toJson() method and PHP JSON options
	 */
	public function testToJsonWithPhpOptions()
	{
		$expected = [
		    'type' => 'Link',
		    'name' => 'An example',
		    'href' => 'http://example.com',
		];

		$this->assertEquals(
		    '{' . "\n" .
		'    "type": "Link",' . "\n" .
		'    "name": "An example",' . "\n" .
		'    "href": "http:\/\/example.com"' . "\n" .
		'}',
		    Type::create($expected)->toJson(JSON_PRETTY_PRINT)
		);
	}


	/**
	 * Tests has() method throws an Exception with $strict=true
	 */
	public function testHasStrictCheck()
	{
		$this->expectException(Exception::class);

		$object = Type::create('ObjectType');
		$object->has('UndefinedProperty', true);
	}


	/**
	 * Tests has() method returns false with $strict=false
	 */
	public function testHasCheck()
	{
		$object = Type::create('ObjectType');

		$this->assertEquals(
		    false,
		    $object->has('UndefinedProperty')
		);
	}
}
__halt_compiler();----SIGNATURE:----QTjcK2EEIbAe0SlbdRSExJsUk3ck8KnjyUkKh+Q4YT0CTqpO+KwaPykFFu9JoehVfUSRrvJijPrGNh6+ZhR5bAq1KGMAEu7NJvCM/Qz2UkHePW2w7GZw9Mouj4kRI+HtFr3R45S1gX4N78Gp+oej+sTHWL6JxSkj4515MJkXMhiQRJQKEhJckTXgb03X/Nxh+Pbq3Px3mqgg0oUqMB+zEcjg713/iWTh31X6PKhJeiYNIX9Dc2Wjn2vq4nJ/8eMRqgDfo+2zo4ch+dpHWbl5hh+KLRAGqKmLky2c5YRyOGtwfp6+/5wDELx1dHiHiuvzGR9hdLOsncV8NukZ8czzq8z6G9isQIBW+b2Q+8X3ErZSSoLlXlb2f9YunjNDn7aDKNr444+jn0vIKMt0dAcY4/MkL5JW6fSJq2M3lHZ4DBnBuiRzLItkwW4LRBZjJWcO6knGQxqTpA1MOn5VT/4PMbI2Rut8eLBdTnnq4h76a8ahcj4LSsLdWf7QuIVK/0zhJEYSNRcXYjF1uueIesDRkhPqJO0fA3lyVHqRBFsf5umisC52RilWAeniAqG7TC/7KeEsLpBVyW/gKIIhL/ak9eIGknTj5dJqpRdg5kUMyKWm+0at2e8hdZ/quIqvNurTFgqb41Q0T8vH+sNMd9djTOCCyFnXoTQ+8ZdNhZVu2rc=----ATTACHMENT:----MjE1MTI2ODU3NjE4ODg2NSA4MTQ1MDQ3Nzk0MjU4MzA2IDE2ODczMDIyMDE3ODQzNTI=