#! /usr/local/bin/perl -w

use lib qw(.. t);
use strict;
use Test_Framework;
use Class::Generate qw(&class &subclass);

# Test user-defined protected methods, and use of accessors of
# protected members.

use vars qw($o);

Test {
    class Parent => {
	mem => "\$",
	prot_mem => { type => '@', protected => 1 },
	priv_mem => { type => '%', private => 1 },
	'&meth' => 'return $#prot_mem >= 0 ? $prot_mem[0] + 1 : $mem + 2',
	'&prot_meth_1' => {
	    body => 'return $#prot_mem >= 0 ? $prot_mem[0] + 2 : $mem + 2',
	    protected => 1
	},
	'&prot_meth_2' => {
	    body => '$priv_mem{$mem} = $#prot_mem;',
	    protected => 1
	},
	'&set_prot_mem' => '@prot_mem = @_;',
        '&use_prot_meths' => '@prot_mem = localtime;
			      &prot_meth_2();
			      $priv_mem{&prot_meth_1} = &last_prot_mem;',
	new => { style => 'positional mem' }
    }
};

Test { ($o = (new Parent 1))->mem == 1 };		# Object creation and access of public members should still work...
Test { $o->meth == 3 };					# Access of protected member works from public method.
Test {							# Ditto.
    $o->set_prot_mem(2, 3, 4);
    $o->meth == 3;
};
Test { $o->use_prot_meths };				# Ditto.
Test_Failure { (new Parent 1)->prot_meth_1 == 1 };	# But you can't access a protected method.

Test {
    subclass Child => {
	cmem => { type => "\$", assert => '&prot_meth_1 != $cmem && &prot_meth_1() != $cmem' },
	new => { style => 'positional cmem', post => '@prot_mem = (3, 4, 5);' }
    }, -parent => 'Parent'
};

Test { ($o = (new Child 1, 2))->cmem == 1 && $o->mem == 2 };
Test { ! defined $o->cmem(10) };
Test { $o->use_prot_meths };
Test_Failure { $o->cmem(5) };				# The assertion should fail.
Test_Failure { $o->prot_meth_1 };			# You can't access a protected method from a child, either.
Test_Failure { $o->prot_meth_2 };			# Ditto.

Report_Results;
