<commit_before><?php

namespace AutoMapperPlus;

use AutoMapperPlus\Configuration\AutoMapperConfig;
use AutoMapperPlus\Configuration\AutoMapperConfigInterface;
use AutoMapperPlus\Test\CustomMapper\EmployeeMapper;
use AutoMapperPlus\MappingOperation\Operation;
use AutoMapperPlus\NameConverter\NamingConvention\CamelCaseNamingConvention;
use AutoMapperPlus\NameConverter\NamingConvention\SnakeCaseNamingConvention;
use AutoMapperPlus\NameResolver\CallbackNameResolver;
use AutoMapperPlus\Test\CustomMapper\EmployeeMapperWithMapperAware;
use AutoMapperPlus\Test\Models\Inheritance\DestinationChild;
use AutoMapperPlus\Test\Models\Inheritance\DestinationParent;
use AutoMapperPlus\Test\Models\Inheritance\SourceChild;
use AutoMapperPlus\Test\Models\Inheritance\SourceParent;
use AutoMapperPlus\Test\Models\Nested\Address;
use AutoMapperPlus\Test\Models\Nested\AddressDto;
use AutoMapperPlus\Test\Models\Nested\Person;
use AutoMapperPlus\Test\Models\Nested\PersonDto;
use AutoMapperPlus\Test\Models\SimpleProperties\HasPrivateProperties;
use AutoMapperPlus\Test\Models\SimpleProperties\NoProperties;
use PHPUnit\Framework\TestCase;
use AutoMapperPlus\Test\Models\Employee\Employee;
use AutoMapperPlus\Test\Models\Employee\EmployeeDto;
use AutoMapperPlus\Test\Models\NamingConventions\CamelCaseSource;
use AutoMapperPlus\Test\Models\NamingConventions\SnakeCaseSource;
use AutoMapperPlus\Test\Models\Nested\ChildClass;
use AutoMapperPlus\Test\Models\Nested\ChildClassDto;
use AutoMapperPlus\Test\Models\Nested\ParentClass;
use AutoMapperPlus\Test\Models\Nested\ParentClassDto;
use AutoMapperPlus\Test\Models\Post\CreatePostViewModel;
use AutoMapperPlus\Test\Models\Post\Post;
use AutoMapperPlus\Test\Models\Prefix\PrefixedSource;
use AutoMapperPlus\Test\Models\Prefix\UnPrefixedSource;
use AutoMapperPlus\Test\Models\SimpleProperties\Destination;
use AutoMapperPlus\Test\Models\SimpleProperties\Source;
use AutoMapperPlus\Test\Models\SpecialConstructor\Source as ConstructorSource;
use AutoMapperPlus\Test\Models\SpecialConstructor\Destination as ConstructorDestination;
use AutoMapperPlus\Test\Models\Visibility\Visibility;
use AutoMapperPlus\Test\Models\SimilarPropertyNames\Source as SimilarSource;
use AutoMapperPlus\Test\Models\SimilarPropertyNames\Destination as SimilarDestination;

/**
 * Class AutoMapperTest
 *
 * @package AutoMapperPlus
 */
class AutoMapperTest extends TestCase
{
    protected $source;
    protected $destination;

    /**
     * @var AutoMapperConfig
     */
    protected $config;

    protected function setUp()
    {
        $this->config = new AutoMapperConfig();
    }

    public function testItCanBeInstantiatedStatically()
    {
        $mapper = AutoMapper::initialize(function (AutoMapperConfigInterface $config) {
            $config->registerMapping(Source::class, Destination::class);
        });

        $destination = $mapper->map(new Source(), Destination::class);
        $this->assertInstanceOf(Destination::class, $destination);
    }

    public function testItMapsAPublicProperty()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);
        $source = new Source();
        $source->name = 'Hello';
        /** @var Destination $destination */
        $destination = $mapper->map($source, Destination::class);

        $this->assertInstanceOf(Destination::class, $destination);
        $this->assertEquals($source->name, $destination->name);
    }

    public function testItCanMapToAnExistingObject()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);

        $source = new Source();
        $source->name = 'Hello';
        $destination = new Destination();
        $destination->anotherProperty = 'another';
        $destination = $mapper->mapToObject($source, $destination);

        $this->assertEquals($source->name, $destination->name);
        // Make sure we don't override other properties.
        $this->assertEquals('another', $destination->anotherProperty);
    }

    public function testSourceDoesntGetOverridden()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);

        $source = new Source();
        $source->name = 'John';
        $result = $mapper->map($source, Destination::class);

        $this->assertEquals('John', $source->name);
    }

    public function testItCanMapWithACallback()
    {
        $this->config->registerMapping(Source::class, Destination::class)
            ->forMember('name', function () {
                return 'NewName';
            });<commit_msg>Add test<commit_after><?php

namespace AutoMapperPlus;

use AutoMapperPlus\Configuration\AutoMapperConfig;
use AutoMapperPlus\Configuration\AutoMapperConfigInterface;
use AutoMapperPlus\Test\CustomMapper\EmployeeMapper;
use AutoMapperPlus\MappingOperation\Operation;
use AutoMapperPlus\NameConverter\NamingConvention\CamelCaseNamingConvention;
use AutoMapperPlus\NameConverter\NamingConvention\SnakeCaseNamingConvention;
use AutoMapperPlus\NameResolver\CallbackNameResolver;
use AutoMapperPlus\Test\CustomMapper\EmployeeMapperWithMapperAware;
use AutoMapperPlus\Test\Models\Inheritance\DestinationChild;
use AutoMapperPlus\Test\Models\Inheritance\DestinationParent;
use AutoMapperPlus\Test\Models\Inheritance\SourceChild;
use AutoMapperPlus\Test\Models\Inheritance\SourceParent;
use AutoMapperPlus\Test\Models\Nested\Address;
use AutoMapperPlus\Test\Models\Nested\AddressDto;
use AutoMapperPlus\Test\Models\Nested\Person;
use AutoMapperPlus\Test\Models\Nested\PersonDto;
use AutoMapperPlus\Test\Models\SimpleProperties\HasPrivateProperties;
use AutoMapperPlus\Test\Models\SimpleProperties\NoProperties;
use PHPUnit\Framework\TestCase;
use AutoMapperPlus\Test\Models\Employee\Employee;
use AutoMapperPlus\Test\Models\Employee\EmployeeDto;
use AutoMapperPlus\Test\Models\NamingConventions\CamelCaseSource;
use AutoMapperPlus\Test\Models\NamingConventions\SnakeCaseSource;
use AutoMapperPlus\Test\Models\Nested\ChildClass;
use AutoMapperPlus\Test\Models\Nested\ChildClassDto;
use AutoMapperPlus\Test\Models\Nested\ParentClass;
use AutoMapperPlus\Test\Models\Nested\ParentClassDto;
use AutoMapperPlus\Test\Models\Post\CreatePostViewModel;
use AutoMapperPlus\Test\Models\Post\Post;
use AutoMapperPlus\Test\Models\Prefix\PrefixedSource;
use AutoMapperPlus\Test\Models\Prefix\UnPrefixedSource;
use AutoMapperPlus\Test\Models\SimpleProperties\Destination;
use AutoMapperPlus\Test\Models\SimpleProperties\Source;
use AutoMapperPlus\Test\Models\SpecialConstructor\Source as ConstructorSource;
use AutoMapperPlus\Test\Models\SpecialConstructor\Destination as ConstructorDestination;
use AutoMapperPlus\Test\Models\Visibility\Visibility;
use AutoMapperPlus\Test\Models\SimilarPropertyNames\Source as SimilarSource;
use AutoMapperPlus\Test\Models\SimilarPropertyNames\Destination as SimilarDestination;

/**
 * Class AutoMapperTest
 *
 * @package AutoMapperPlus
 */
class AutoMapperTest extends TestCase
{
    protected $source;
    protected $destination;

    /**
     * @var AutoMapperConfig
     */
    protected $config;

    protected function setUp()
    {
        $this->config = new AutoMapperConfig();
    }

    public function testItCanBeInstantiatedStatically()
    {
        $mapper = AutoMapper::initialize(function (AutoMapperConfigInterface $config) {
            $config->registerMapping(Source::class, Destination::class);
        });

        $destination = $mapper->map(new Source(), Destination::class);
        $this->assertInstanceOf(Destination::class, $destination);
    }

    public function testItMapsAPublicProperty()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);
        $source = new Source();
        $source->name = 'Hello';
        /** @var Destination $destination */
        $destination = $mapper->map($source, Destination::class);

        $this->assertInstanceOf(Destination::class, $destination);
        $this->assertEquals($source->name, $destination->name);
    }

    public function testItCanMapToAnExistingObject()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);

        $source = new Source();
        $source->name = 'Hello';
        $destination = new Destination();
        $destination->anotherProperty = 'another';
        $destination = $mapper->mapToObject($source, $destination);

        $this->assertEquals($source->name, $destination->name);
        // Make sure we don't override other properties.
        $this->assertEquals('another', $destination->anotherProperty);
    }

    public function testMapToAnExistingObjectContext()
    {
        $source = new Source();
        $source->name = 'Hello';
        $destination = new Destination();
        $destination->anotherProperty = 'another';

        $this->config
            ->registerMapping(Source::class, Destination::class)
            ->forMember('name', Operation::mapFrom(function(Source $source, AutoMapperInterface $mapper, array $context) use ($destination) {
                $this->assertArrayHasKey(AutoMapper::DESTINATION_CONTEXT, $context);
                $this->assertInstanceOf(Destination::class, $context[AutoMapper::DESTINATION_CONTEXT]);
                $this->assertEquals($destination, $context[AutoMapper::DESTINATION_CONTEXT]);

                return $source->name;
            }))
        ;
        $mapper = new AutoMapper($this->config);
        $mapper->mapToObject($source, $destination);

        // Make sure context added only for mapToObject method
        $this->config
            ->getMappingFor(Source::class, Destination::class)
            ->forMember('name', Operation::mapFrom(function(Source $source, AutoMapperInterface $mapper, array $context) {
                $this->assertArrayNotHasKey(AutoMapper::DESTINATION_CONTEXT, $context);

                return $source->name;
            }))
        ;
        $mapper = new AutoMapper($this->config);

        $source = new Source();
        $source->name = 'Hello';
        $mapper->map($source, Destination::class);
    }

    public function testSourceDoesntGetOverridden()
    {
        $this->config->registerMapping(Source::class, Destination::class);
        $mapper = new AutoMapper($this->config);

        $source = new Source();
        $source->name = 'John';
        $result = $mapper->map($source, Destination::class);

        $this->assertEquals('John', $source->name);
    }

    public function testItCanMapWithACallback()
    {
        $this->config->registerMapping(Source::class, Destination::class)
            ->forMember('name', function () {
                return 'NewName';
            });
{'fraction_non_alphanumeric': 0.11515095729013254, 'fraction_numerical': 0.0, 'mean_word_length': 4.198564593301436, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 90, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6402887', 'n_tokens_mistral': 2968, 'n_tokens_neox': 2922, 'n_words': 483}