#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 39;
use Test::Exception;
BEGIN {
use_ok('IOC::Service::ConstructorInjection');
use_ok('IOC::Container');
}
{ # create a package for a dummy service
package Logger;
sub new {
my ($class, $file, $format_string) = @_;
return bless {
file => $file,
format_string => $format_string
} => $class;
}
package File;
sub new { bless {} => $_[0] }
}
can_ok("IOC::Service::ConstructorInjection", 'new');
{
my $service = IOC::Service::ConstructorInjection->new('logger' =>
('Logger', 'new' => [
IOC::Service::ConstructorInjection->ComponentParameter('file'),
"Log %d %s"
]));
isa_ok($service, 'IOC::Service::ConstructorInjection');
isa_ok($service, 'IOC::Service');
my $service2 = IOC::Service::ConstructorInjection->new('file' => ('File', 'new', []));
isa_ok($service2, 'IOC::Service::ConstructorInjection');
isa_ok($service2, 'IOC::Service');
my $container = IOC::Container->new();
isa_ok($container, 'IOC::Container');
$container->register($service);
$container->register($service2);
can_ok($service, 'instance');
my $logger = $service->instance();
isa_ok($logger, 'Logger');
isa_ok($logger->{file}, 'File');
}
{ # find a service from the root
my $logging_container = IOC::Container->new('Logging');
isa_ok($logging_container, 'IOC::Container');
my $service = IOC::Service::ConstructorInjection->new('logger' =>
('Logger', 'new' => [
IOC::Service::ConstructorInjection->ComponentParameter('/Files/file'),
"Log %d %s"
]));
isa_ok($service, 'IOC::Service::ConstructorInjection');
isa_ok($service, 'IOC::Service');
$logging_container->register($service);
my $service2 = IOC::Service::ConstructorInjection->new('file' => ('File', 'new', []));
isa_ok($service2, 'IOC::Service::ConstructorInjection');
isa_ok($service2, 'IOC::Service');
my $files_container = IOC::Container->new('Files');
isa_ok($files_container, 'IOC::Container');
$files_container->register($service2);
my $container = IOC::Container->new();
$container->addSubContainer($files_container);
$container->addSubContainer($logging_container);
my $logger = $service->instance();
isa_ok($logger, 'Logger');
isa_ok($logger->{file}, 'File');
}
{ # find a sub-service
my $logging_container = IOC::Container->new('Logging');
isa_ok($logging_container, 'IOC::Container');
my $service = IOC::Service::ConstructorInjection->new('logger' =>
('Logger', 'new' => [
IOC::Service::ConstructorInjection->ComponentParameter('Files/file'),
"Log %d %s"
]));
isa_ok($service, 'IOC::Service::ConstructorInjection');
isa_ok($service, 'IOC::Service');
$logging_container->register($service);
my $service2 = IOC::Service::ConstructorInjection->new('file' => ('File', 'new', []));
isa_ok($service2, 'IOC::Service::ConstructorInjection');
isa_ok($service2, 'IOC::Service');
my $files_container = IOC::Container->new('Files');
isa_ok($files_container, 'IOC::Container');
$files_container->register($service2);
$logging_container->addSubContainer($files_container);
my $logger = $service->instance();
isa_ok($logger, 'Logger');
isa_ok($logger->{file}, 'File');
}
{ # load a service class
my $container = IOC::Container->new('ClassLoading');
isa_ok($container, 'IOC::Container');
my $service = IOC::Service::ConstructorInjection->new('container' => ('IOC::Container::MethodResolution', 'new' => []));
isa_ok($service, 'IOC::Service::ConstructorInjection');
isa_ok($service, 'IOC::Service');
$container->register($service);
my $instance;
lives_ok {
$instance = $service->instance();
} '... and the service loads correctly';
isa_ok($instance, 'IOC::Container::MethodResolution');
}
# check some errors now
{
throws_ok {
IOC::Service::ConstructorInjection->new('file');
} "IOC::InsufficientArguments", '... cannot create a constructor injection without a component class';
throws_ok {
IOC::Service::ConstructorInjection->new('file' => ("Fail"));
} "IOC::InsufficientArguments", '... cannot create a constructor injection without a component class constructor';
throws_ok {
IOC::Service::ConstructorInjection->new('file' => ("Fail", 'new'));
} "IOC::InsufficientArguments", '... cannot create a constructor injection without a parameter list';
throws_ok {
IOC::Service::ConstructorInjection->new('file' => ("Fail", 'new', "Fail"));
} "IOC::InsufficientArguments", '... cannot create a constructor injection without an array ref as parameter list';
throws_ok {
IOC::Service::ConstructorInjection->new('file' => ("Fail", 'new', {}));
} "IOC::InsufficientArguments", '... cannot create a constructor injection without an array ref as parameter list';
my $container = IOC::Container->new();
throws_ok {
IOC::Service::ConstructorInjection->new('file2' => ("Fail", 'new', []))->setContainer($container)->instance;
} "IOC::ClassLoadingError", '... cannot create a constructor injection without real class';
throws_ok {
IOC::Service::ConstructorInjection->new('file3' => ("File", 'noNew', []))->setContainer($container)->instance;
} "IOC::ConstructorNotFound", '... cannot create a constructor injection without a proper class constructor name';
}