File Coverage

blib/lib/Test/Mimic.pm
Criterion Covered Total %
statement 42 57 73.6
branch 9 16 56.2
condition 2 5 40.0
subroutine 8 8 100.0
pod 0 2 0.0
total 61 88 69.3


line stmt bran cond sub pod time code
1             package Test::Mimic;
2              
3 1     1   38835 use strict;
  1         3  
  1         42  
4 1     1   5 use warnings;
  1         2  
  1         37  
5              
6 1         120 use Test::Mimic::Library qw<
7             load_records
8             init_records
9             load_preferences
10             ARBITRARY
11 1     1   1155 >;
  1         48439  
12 1     1   1141 use Test::Mimic::Generator;
  1         7007  
  1         559  
13              
14             our $VERSION = 0.009_007;
15              
16             # Preloaded methods go here.
17              
18             # Private to the Test::Mimic suite.
19             {
20             my @pristine_INC;
21              
22             # Returns @INC to its state prior to when require_from was called.
23             # Generated packages must call this before using any external modules.
24             sub prepare_for_use {
25 2 100   2 0 8 if (@pristine_INC) {
26 1         4 @INC = @pristine_INC;
27 1         17 @pristine_INC = ();
28             }
29             }
30            
31             # Accepts a package to require and a directory name to load it from.
32             # This will modify @INC while it is running, but return restore it
33             # prior to exiting.
34             sub require_from {
35 1     1 0 2 my ( $package, $dir ) = @_;
36            
37 1         6 @pristine_INC = @INC;
38 1         3 @INC = ($dir);
39            
40             # Load the package
41 1         56 my $success = eval( "require $package; 1" );
42              
43             # Undo the @INC change
44 1         5 prepare_for_use();
45              
46 1         4 return $success;
47             }
48             }
49              
50             my $save_to; # The directory to read/write recorded behavior.
51             my $recording_required; # Will be set to true iff a package was requrested that has not yet been recorded.
52              
53             # See the POD below.
54             sub import {
55 1     1   17 my ( $class, $user_preferences ) = @_;
56              
57 1 50       5 if ( ! defined($user_preferences) ) {
58 0         0 die 'No preference hash reference passed to import in Test::Mimic.';
59             }
60              
61 1         1 my %preferences = %{$user_preferences};
  1         6  
62              
63 1 50       5 if ( ! defined( $preferences{'packages'} ) ) {
64 0         0 die 'No packages selected to mimic.';
65             }
66              
67 1         1 $preferences{'test_mimic'} = ARBITRARY;
68 1   50     9 $save_to = $preferences{'save'} ||= '.test_mimic_data';
69              
70             # Setup the library to behave per user preferences.
71 1         4 my $history = $save_to . '/history_for_playback.rec';
72 1 50       25 if ( -e $history ) { # This won't be true if we haven't recorded at all before.
73 1         5 load_records($history);
74             }
75             else {
76 0         0 init_records();
77             }
78 1         1460 load_preferences(\%preferences);
79              
80             # Attempt to load mimicked versions of each package. Note those that have not been recorded.
81 1         18 my $lib_dir = $save_to . '/lib';
82 1         1 my $playback_stage = 0;
83 1         2 my @to_record;
84 1         2 for my $package_to_mimic ( keys %{ $preferences{'packages'} } ) {
  1         4  
85 1 50       5 if ( ! require_from( $package_to_mimic, $lib_dir ) ) {
86 0         0 push( @to_record, $package_to_mimic );
87             }
88             else {
89 1         131 $playback_stage = 1;
90             }
91             }
92              
93             # Prevent playback/recording conflicts.
94 1 50 33     12 if ( $playback_stage && @to_record > 0 ) {
95 0         0 die "The playback stage and the recording stage can not coincide. Either delete the current" .
96             "recordings or stop mimicking the following package(s): @to_record";
97             }
98              
99             # Record the missing packages.
100 1 50       30 if ( @to_record != 0 ) {
101 0           $recording_required = 1;
102 0           require Test::Mimic::Recorder;
103 0           my %recorder_prefs = %preferences;
104              
105             #Only include those packages that need recording.
106 0           $recorder_prefs{'packages'} = {};
107 0           for my $package (@to_record) {
108 0           $recorder_prefs{'packages'}->{$package} = $preferences{'packages'}->{$package};
109             }
110 0           Test::Mimic::Recorder->import(\%recorder_prefs);
111             }
112             }
113              
114             # Handles the code generation after the recording is complete.
115             # NOTE: This relies on the LIFO structure of END block execution.
116             END {
117 1 50   1   586 if ($recording_required) {
118 0         0 my $generator = Test::Mimic::Generator->new();
119 0         0 $generator->load($save_to);
120 0         0 $generator->write($save_to);
121             }
122             }
123              
124             1;
125             __END__