The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!perl -T

=head1 PURPOSE

Test setting fields and corresponding values with set().

=cut

use strict;
use warnings;

use DBIx::NinjaORM;
use Test::Deep;
use Test::Exception;
use Test::More tests => 7;


# Verify that the main class supports the method.
can_ok(
	'DBIx::NinjaORM',
	'set',
);

# Verify inheritance.
can_ok(
	'DBIx::NinjaORM::Test',
	'set',
);

ok(
	my $object = DBIx::NinjaORM::Test->new(),
	'Create new object.',
);

dies_ok(
	sub
	{
		$object->set(
			field => 'value',
		)
	},
	'The first argument must be a hashref.',
);

# Make sure that read-only fields cannot be set via set() by default.
subtest(
	'Set a read-only field without the "force" argument.',
	sub
	{
		plan( tests => 2 );
		
		ok(
			!exists( $object->{'readonly_field'} ),
			'"readonly_field" does not exist on the object.',
		);
		
		dies_ok(
			sub
			{
				$object->set(
					{
						readonly_field => 'value',
					}
				);
			},
			'Set value fails.',
		);
	}
);

# Make sure that read-only fields cannot be set via set() without 'force'.
subtest(
	'Set a read-only field with force=0.',
	sub
	{
		plan( tests => 2 );
		
		ok(
			!exists( $object->{'readonly_field'} ),
			'"readonly_field" does not exist on the object.',
		);
		
		dies_ok(
			sub
			{
				$object->set(
					{
						readonly_field => 'value',
					},
					force => 0,
				);
			},
			'Set value fails.',
		);
	}
);

# Make sure that readonly fields can be set via set() when the 'force' argument
# is specified and set to 1.
subtest(
	'Set a read-only field with force=1.',
	sub
	{
		plan( tests => 3 );
		
		ok(
			!exists( $object->{'readonly_field'} ),
			'"readonly_field" does not exist on the object.',
		);
		
		lives_ok(
			sub
			{
				$object->set(
					{
						readonly_field => 'value',
					},
					force => 1,
				);
			},
			'Set value.',
		);
		
		is(
			$object->{'readonly_field'},
			'value',
			'The read-only field is set.',
		);
	}
);


# Test subclass with read-only fields and a primary key name set.
package DBIx::NinjaORM::Test;

use strict;
use warnings;

use base 'DBIx::NinjaORM';


sub static_class_info
{
	return
	{
		'readonly_fields'   => [ 'readonly_field' ],
		'primary_key_name' => 'test_pk',
	};
}


1;