1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More;
7use Test::Fatal;
8
9use Bread::Board;
10
11{
12    package Thing;
13    use Moose;
14
15    has foo => (is => 'ro', required => 1);
16    has moo => (is => 'ro', required => 1);
17
18    no Moose;
19
20    __PACKAGE__->meta->make_immutable;
21}
22
23{
24    package TestThing;
25    use Moose;
26
27    extends 'Thing';
28
29    has bar  => (is => 'ro', required => 1);
30    has kooh => (is => 'ro', required => 1);
31
32    no Moose;
33
34    __PACKAGE__->meta->make_immutable;
35}
36
37{
38    my $c = container 'MyApp' => as {
39        service foo => 42;
40
41        service thing => (
42            class        => 'Thing',
43            dependencies => [depends_on('foo')],
44            parameters   => {
45                moo => { isa => 'Int' },
46            },
47        );
48    };
49
50    {
51        my $t = $c->resolve(
52            service    => 'thing',
53            parameters => {
54                moo => 123,
55            },
56        );
57
58        isa_ok $t, 'Thing';
59        is $t->foo, 42, '... and has a foo literal';
60        is $t->moo, 123, '... and has a moo literal';
61    }
62
63    container $c => as {
64        service bar => 23;
65
66        service '+thing' => (
67            class        => 'TestThing',
68            dependencies => [depends_on('bar')],
69            parameters   => ['kooh'],
70        );
71    };
72
73    {
74        my $t = $c->resolve(
75            service    => 'thing',
76            parameters => {
77                moo  => 123,
78                kooh => 456,
79            },
80        );
81
82        isa_ok $t, 'TestThing';
83        is $t->foo, 42, '... and has a foo literal';
84        is $t->moo, 123, '... and has moo literal';
85        is $t->bar, 23, '... and has a bar literal';
86        is $t->kooh, 456, '... and has a kooh literal';
87    }
88}
89
90{
91    my $parameterized = container MyApp => ['Config'] => as {
92        service foo => (block => sub { 42 });
93    };
94
95    container $parameterized => as {
96        service '+foo' => (block => sub { 23 });
97    };
98
99    my $c = $parameterized->create(Config => container Config => as {});
100
101    is $c->resolve(service => 'foo'), 23, 'Can resolve foo from parameterized container';
102}
103
104like exception {
105    service '+foo' => 42;
106}, qr/^Service inheritance doesn't make sense for literal services/, 'exception thrown when trying to do service inheritance from literal service';
107
108like exception {
109    container Foo => as {
110        container foo => as {};
111        service '+foo' => (block => sub { 42 });
112    };
113}, qr/^Trying to inherit from service 'foo', but found a Bread::Board::Container/, 'exception thrown when trying to inherit from a container';
114
115like exception {
116    container Foo => as {
117        service foo => 42;
118        service '+foo' => (block => sub { 123 });
119    };
120}, qr/^Trying to inherit from a literal service/, 'exception thrown when trying to inherit from literal service';
121
122{
123    package Bread::Board::FooInjection;
124    use Moose;
125    extends 'Bread::Board::Literal';
126    no Moose;
127}
128
129like exception {
130    container Foo => as {
131        service foo => (block => sub { 123 });
132        service '+foo' => (service_class => 'Bread::Board::FooInjection');
133    };
134}, qr/^Changing a service's class is not possible when inheriting/, 'exception thrown when trying to change a service class when inheriting';
135
136like exception {
137    container Foo => as {
138        service foo => (block => sub { 123 });
139        service '+foo' => (service_type => 'Foo');
140    };
141}, qr/^Changing a service's class is not possible when inheriting/, 'exception thrown when trying to change a service type when inheriting';
142
143{
144    package Foo;
145    use Moose;
146    no Moose;
147}
148
149like exception {
150    container Foo => as {
151        service foo => (block => sub { 123 });
152        service '+foo' => (class => 'Foo');
153    };
154}, qr/^/, 'exception thrown when trying to change a service class for "+foo"';
155
156like exception {
157    container Foo => as {
158        service foo => (class => 'Foo');
159        service '+foo' => (block => sub { 123 });
160    };
161}, qr/^/, 'exception thrown when trying to change a service class for "foo"';
162
163done_testing;
164