File Coverage

ex/change_engine_example.pl
Criterion Covered Total %
statement 88 94 93.6
branch 11 18 61.1
condition 2 3 66.6
subroutine 25 31 80.6
pod 0 7 0.0
total 126 153 82.3


line stmt bran cond sub pod time code
1             #! /usr/bin/env perl
2              
3 1     1   646 use v5.10;
  1         3  
  1         53  
4 1     1   5 use warnings;
  1         4  
  1         45  
5              
6             #===================================
7             package ClobalConstructor;
8              
9             #===================================
10              
11 1     1   1055 use Moo;
  1         19681  
  1         7  
12 1     1   2416 use Kaiten::Container;
  1         5  
  1         1048  
13              
14             has 'config' => ( is => 'rw', );
15              
16             # just private method
17             my $logger_init;
18              
19             sub create_container {
20 2     2 0 4 my $self = shift;
21 2         19 my $config = $self->config;
22              
23             my $init_conf = {
24             host_production => {
25 2     2   17 handler => sub { 'www.coolsite.com' },
26 2     2   8 probe => sub { 1 }
27             },
28             host_develop => {
29 0     0   0 handler => sub { 'localhost' },
30 0     0   0 probe => sub { 1 }
31             },
32             host_full_name => {
33             handler => sub {
34 2     2   14 my $c = shift;
35              
36             # no need checking - if entity absence - all die
37 2         13 my $host = $c->get_by_name( 'host_' . $config->{mode} );
38 2         7 return $host;
39             },
40 2     2   8 probe => sub { 1 }
41             },
42             debug_level => {
43             handler => sub {
44 0     0   0 die 'original method have huge dependecies';
45             },
46 0     0   0 probe => sub { shift }
47             },
48             system_logger => {
49             handler => sub {
50 2     2   16 my $c = shift;
51              
52              
53 2         3 my $loger_engine;
54 2 100       11 if ( $config->{logger} eq 'engine1' ){
    50          
55 1         3 $loger_engine = 'system_logger1';
56             }
57             elsif( $config->{logger} eq 'engine2' ){
58 1         2 $loger_engine = 'system_logger2';
59             }
60            
61 2         9 my $selected_logger = $c->get_by_name($loger_engine);
62              
63 2         5 my $ilogger;
64 2         4 eval {
65 2         6 $ilogger = $c->get_by_name('ilogger');
66 2         9 $ilogger->engine($selected_logger);
67             };
68              
69             # we are have simple default resolver
70 2 50 66     17 $ilogger = $selected_logger if ( ( $config->{logger} eq 'engine1' ) && !$ilogger );
71 2 50       7 die 'unresolved dependencies [logger] ' unless $ilogger;
72              
73 2         6 return $ilogger;
74              
75             },
76 2     2   10 probe => sub { 1 }
77             },
78             system_logger1 => {
79             handler => sub {
80 1     1   8 my $c = shift;
81              
82 1         8 my $debugger = $c->get_by_name('logger_engine');
83 1         4 my $level = $c->get_by_name('debug_level');
84              
85 1         5 $debugger->set_level($level);
86              
87 1         3 return $debugger;
88              
89             },
90 1     1   4 probe => sub { 1 }
91             },
92             system_logger2 => {
93             handler => sub {
94 1     1   9 my $c = shift;
95              
96 1         5 my $debugger = $c->get_by_name('logger_engine2');
97 1         5 my $level = $c->get_by_name('debug_level');
98              
99 1         5 $debugger->set_level2($level);
100              
101             # you MAY change some properties of object after creation
102 1 50       8 $debugger->color_message( $config->{message_color} ) if $config->{message_color};
103              
104 1         3 return $debugger;
105              
106             },
107 1     1   4 probe => sub { 1 }
108             },
109             deadly_things => {
110             handler => sub {
111 0     0   0 die 'just died if you touch this';
112             },
113 0     0   0 probe => sub { shift }
114             },
115 2         91 };
116              
117 2         38 my $container = Kaiten::Container->new( init => $init_conf );
118              
119 2         25 my $loggers_config = $logger_init->($config);
120              
121 2         11 while ( my ( $name, $conf ) = each %$loggers_config ) {
122 6         23 $container->add( $name, $conf );
123             }
124              
125 2         9 return $container;
126             }
127              
128             # here we ara should to build all Loggers to initialize container properly
129             $logger_init = sub {
130             my $config = shift;
131              
132             my $debug_color = $config->{debug_color} ? $config->{debug_color} : 'white';
133              
134             my $loggers_config = {
135              
136             logger_engine => {
137             handler => sub { LoggerEngine->new() },
138             probe => sub {
139             my $self = shift;
140             $self->self_check( 'self-testing at livel [' . $self->level . '] ok' );
141             },
142             },
143             # you MAY init objects on create too
144             logger_engine2 => {
145             handler => sub { LoggerEngine2->new( color_debug => $debug_color) },
146             probe => sub {
147             my $self = shift;
148             $self->self_check2( 'self-testing at livel [' . $self->level2 . '] ok' );
149             },
150             },
151              
152             ilogger => {
153             handler => sub { ILoggerEngine->new() },
154             probe => sub { shift->self_check },
155             },
156              
157             };
158              
159             return $loggers_config;
160              
161             };
162              
163             #===================================
164             package LoggerEngine;
165              
166             #===================================
167              
168 1     1   12 use Moo;
  1         2  
  1         5  
169              
170             has 'level' => (
171             is => 'rw',
172             writer => 'set_level',
173             default => sub { 0 },
174             );
175              
176             sub output {
177 1     1 0 2 my $self = shift;
178 1         2 my $message = shift;
179              
180 1 50       252 say( ( $self->level ? 'DEBUG ON: ' : 'DEBUG OFF: ' ) . $message );
181              
182             }
183              
184             sub self_check {
185 1     1 0 2 my $self = shift;
186 1         2 my $message = shift;
187              
188 1         275 say "** CHECK:[$message] **";
189              
190             }
191              
192             #===================================
193             package LoggerEngine2;
194              
195             #===================================
196              
197 1     1   513 use Moo;
  1         2  
  1         5  
198 1     1   1501 use Term::ANSIColor;
  1         9257  
  1         373  
199              
200             has 'level2' => (
201             is => 'rw',
202             writer => 'set_level2',
203             default => sub { 0 },
204             );
205              
206             has 'color_message' => (
207             is => 'rw',
208             default => sub { 'red' },
209             );
210              
211             has 'color_debug' => (
212             is => 'rw',
213             default => sub { 'cyan' },
214             );
215              
216             sub output2 {
217 1     1 0 34 my $self = shift;
218 1         3 my $message = shift;
219              
220 1         6 print color $self->color_message;
221 1 50       174 say( 'logger2 ' . ( $self->level2 ? 'DEBUG ON: ' : 'DEBUG OFF: ' ) . $message );
222 1         5 print color 'reset';
223             }
224              
225             sub self_check2 {
226 1     1 0 3 my $self = shift;
227 1         2 my $message = shift;
228              
229 1         8 print color $self->color_debug;
230 1         277 say 'logger2 ' . "** CHECK:[$message] **";
231 1         6 print color 'reset';
232             }
233              
234             #===================================
235             package ILoggerEngine;
236              
237             #===================================
238              
239 1     1   13 use Moo;
  1         3  
  1         9  
240              
241             has 'engine' => ( is => 'rw', );
242              
243             sub output {
244 2     2 0 3 my $self = shift;
245 2         3 my $message = shift;
246              
247 2         9 my $engine = $self->engine;
248              
249             # no need check |else| - container filter it
250 2 100       11 if ( ref $engine eq 'LoggerEngine' ){
    50          
251 1         5 $engine->output($message)
252             }
253             elsif( ref $engine eq 'LoggerEngine2' ){
254 1         4 $engine->output2($message)
255             }
256              
257             }
258              
259 2     2 0 10 sub self_check { 1 }
260              
261             #===================================
262             package main;
263              
264             #===================================
265              
266             =pod
267              
268             Q. How I can use different module to make something without changing CODE, only by config?
269             A. Just create routing at container, may be you should to create an Interface to translate one command to another.
270              
271             =cut
272              
273             foreach my $log_engine ( 'engine1', 'engine2' ) {
274              
275             say "\n====test with [$log_engine]";
276              
277             my $stable_config = {
278             mode => 'production',
279             logger => $log_engine,
280             # next two settings working only for engine2 and have no effect to engine1
281             message_color => 'bold yellow',
282             debug_color => 'black on_white'
283             };
284              
285             my $global_constructor = ClobalConstructor->new( config => $stable_config );
286             my $container = $global_constructor->create_container();
287              
288             # ok, its seems little complexly, but this way can used to replace handler with mock
289             my $mock_object = {
290             handler => sub { 1 },
291             probe => sub { 1 }
292             };
293              
294             $container->remove('debug_level')->add( 'debug_level' => $mock_object );
295              
296             my $logger = $container->get_by_name('system_logger');
297             my $full_name = $container->get_by_name('host_full_name');
298              
299             $logger->output( 'it is worked at - ' . $full_name );
300              
301             }
302              
303             say "\n all ok";