File Coverage

blib/lib/Test/Net/LDAP/Mock/Node.pm
Criterion Covered Total %
statement 71 71 100.0
branch 13 14 92.8
condition 4 5 80.0
subroutine 18 18 100.0
pod 0 6 0.0
total 106 114 92.9


line stmt bran cond sub pod time code
1 13     13   15593 use 5.006;
  13         36  
  13         486  
2 13     13   55 use strict;
  13         29  
  13         382  
3 13     13   57 use warnings;
  13         19  
  13         583  
4              
5             package Test::Net::LDAP::Mock::Node;
6              
7 13     13   2866 use Net::LDAP::Util qw(canonical_dn ldap_explode_dn);
  13         5507  
  13         855  
8 13     13   104 use Scalar::Util qw(blessed);
  13         16  
  13         7607  
9              
10             sub new {
11 106     106 0 163 my ($class) = @_;
12            
13 106         886 return bless {
14             entry => undef,
15             submap => {},
16             password => undef,
17             }, $class;
18             }
19              
20             sub entry {
21 298     298 0 300 my $self = shift;
22            
23 298 100       487 if (@_) {
24 47         53 my $old = $self->{entry};
25 47         55 $self->{entry} = shift;
26 47         102 return $old;
27             } else {
28 251         615 return $self->{entry};
29             }
30             }
31              
32             sub make_node {
33 49     49 0 74 my ($self, $spec) = @_;
34            
35             return $self->_descend_path($spec, sub {
36 144     144   159 my ($node, $rdn) = @_;
37 144         212 return $node->_make_subnode($rdn);
38 49         225 });
39             }
40              
41             sub get_node {
42 105     105 0 166 my ($self, $spec) = @_;
43            
44             return $self->_descend_path($spec, sub {
45 223     223   219 my ($node, $rdn) = @_;
46 223         320 return $node->_get_subnode($rdn);
47 105         482 });
48             }
49              
50             sub traverse {
51 43     43 0 59 my ($self, $callback, $scope) = @_;
52 43   100     100 $scope ||= 0; # 0: base, 1: one, 2: sub
53            
54 43         40 my $visit;
55             $visit = sub {
56 154     154   173 my ($node, $deep) = @_;
57 154         278 $callback->($node);
58            
59             # $deep == 0 or 1
60 154 100       1814 if ($scope > $deep) {
61             $node->_each_subnode(sub {
62 111         111 my ($subnode) = @_;
63 111         223 $visit->($subnode, 1);
64 109         447 });
65             }
66 43         154 };
67            
68 43         85 $visit->($self, 0);
69             }
70              
71             sub password {
72 8     8 0 9 my $self = shift;
73 8         9 my $password = $self->{password};
74 8 100       16 $self->{password} = shift if @_;
75 8         49 return $password;
76             }
77              
78             sub _descend_path {
79 154     154   182 my ($self, $spec, $callback) = @_;
80            
81 154 100       330 if (ref $spec eq 'HASH') {
82 7         9 my $node = $callback->($self, $spec);
83 7         30 return $node;
84             } else {
85 147         152 my $dn_list;
86            
87 147 100       248 if (ref $spec eq 'ARRAY') {
88 93         106 $dn_list = $spec;
89             } else {
90 54 50       162 my $dn = blessed($spec) ? $spec->dn : $spec;
91 54         129 $dn_list = ldap_explode_dn($dn, casefold => 'lower');
92             }
93            
94 147         4364 my $node = $self;
95 147         139 my $parent;
96            
97 147         242 for my $rdn (reverse @$dn_list) {
98 360         317 $parent = $node;
99 360 100       489 $node = $callback->($node, $rdn) or last;
100             }
101            
102 147         580 return $node;
103             }
104             }
105              
106             sub _make_subnode {
107 144     144   150 my ($self, $rdn) = @_;
108             # E.g. $rdn == {ou => 'Sales'}
109 144         328 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
110 144   66     4283 return $self->{submap}{$canonical} ||= ref($self)->new;
111             }
112              
113             sub _get_subnode {
114 223     223   207 my ($self, $rdn) = @_;
115             # E.g. $rdn == {ou => 'Sales'}
116 223         504 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
117 223         6015 return $self->{submap}{$canonical};
118             }
119              
120             sub _each_subnode {
121 109     109   119 my ($self, $callback) = @_;
122 109         128 my $submap = $self->{submap};
123            
124 109         432 for my $canonical (keys %$submap) {
125 111         183 $callback->($submap->{$canonical});
126             }
127             }
128              
129             1;