#!/usr/bin/perl use strict; use warnings; use Test::More; use Test::Moose; use Bread::Board; { # Abstract items ... package Desk; use Moose::Role; package Chair; use Moose::Role; package WorkArea; use Moose::Role; has 'desk' => ( is => 'ro', does => 'Desk', required => 1, ); has 'chair' => ( is => 'ro', does => 'Chair', required => 1, ); } # crappy stuff { package CheapMetalDesk; use Moose; with 'Desk'; package CheapOfficeChair; use Moose; with 'Chair'; package Cubicle; use Moose; with 'WorkArea'; } # good stuff { package NiceWoodenDesk; use Moose; with 'Desk'; package AeronChair; use Moose; with 'Chair'; package Office; use Moose; with 'WorkArea'; } { package Employee; use Moose; has [ 'first_name', 'last_name' ] => ( is => 'ro', isa => 'Str', required => 1, ); has 'work_area' => ( is => 'ro', does => 'WorkArea', required => 1, ); package Manager; use Moose; extends 'Employee'; has '+work_area' => ( isa => 'Office' ); } my $c = container 'Initech' => as { # Employees ... typemap 'Desk' => infer( class => 'CheapMetalDesk' ); typemap 'Chair' => infer( class => 'CheapOfficeChair' ); typemap 'WorkArea' => infer( class => 'Cubicle' ); # Managers ... service 'managers_desk' => (class => 'NiceWoodenDesk'); service 'managers_chair' => (class => 'AeronChair'); typemap 'Office' => infer( dependencies => { desk => depends_on('managers_desk'), chair => depends_on('managers_chair') } ); typemap 'Employee' => infer; typemap 'Manager' => infer; }; my $micheal = $c->resolve( type => 'Employee', parameters => { first_name => 'Micheal', last_name => 'Bolton' } ); my $samir = $c->resolve( type => 'Employee', parameters => { first_name => 'Samir', last_name => 'Nagheenanajar' } ); isa_ok($micheal, 'Employee'); is($micheal->first_name, 'Micheal', '... got the right first name'); is($micheal->last_name, 'Bolton', '... got the right last name'); does_ok($micheal->work_area, 'WorkArea'); isa_ok($micheal->work_area, 'Cubicle'); does_ok($micheal->work_area->desk, 'Desk'); isa_ok($micheal->work_area->desk, 'CheapMetalDesk'); does_ok($micheal->work_area->chair, 'Chair'); isa_ok($micheal->work_area->chair, 'CheapOfficeChair'); isa_ok($samir, 'Employee'); is($samir->first_name, 'Samir', '... got the right first name'); is($samir->last_name, 'Nagheenanajar', '... got the right last name'); does_ok($samir->work_area, 'WorkArea'); isa_ok($samir->work_area, 'Cubicle'); does_ok($samir->work_area->desk, 'Desk'); isa_ok($samir->work_area->desk, 'CheapMetalDesk'); does_ok($samir->work_area->chair, 'Chair'); isa_ok($samir->work_area->chair, 'CheapOfficeChair'); isnt($micheal, $samir, '... two different employees'); isnt($micheal->work_area, $samir->work_area, '... two different cubicles'); isnt($micheal->work_area->chair, $samir->work_area->chair, '... two different cubicle chairs'); isnt($micheal->work_area->desk, $samir->work_area->desk, '... two different cubicle desks'); # managers my $lundberg = $c->resolve( type => 'Manager', parameters => { first_name => 'Bill', last_name => 'Lundberg' } ); isa_ok($lundberg, 'Manager'); is($lundberg->first_name, 'Bill', '... got the right first name'); is($lundberg->last_name, 'Lundberg', '... got the right last name'); does_ok($lundberg->work_area, 'WorkArea'); isa_ok($lundberg->work_area, 'Office'); does_ok($lundberg->work_area->desk, 'Desk'); isa_ok($lundberg->work_area->desk, 'NiceWoodenDesk'); does_ok($lundberg->work_area->chair, 'Chair'); isa_ok($lundberg->work_area->chair, 'AeronChair'); done_testing;