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   13350 use 5.006;
  13         98  
  13         411  
2 13     13   55 use strict;
  13         18  
  13         356  
3 13     13   50 use warnings;
  13         19  
  13         520  
4              
5             package Test::Net::LDAP::Mock::Node;
6              
7 13     13   2250 use Net::LDAP::Util qw(canonical_dn ldap_explode_dn);
  13         4549  
  13         760  
8 13     13   60 use Scalar::Util qw(blessed);
  13         15  
  13         6732  
9              
10             sub new {
11 111     111 0 131 my ($class) = @_;
12            
13 111         775 return bless {
14             entry => undef,
15             submap => {},
16             password => undef,
17             }, $class;
18             }
19              
20             sub entry {
21 341     341 0 279 my $self = shift;
22            
23 341 100       466 if (@_) {
24 48         54 my $old = $self->{entry};
25 48         50 $self->{entry} = shift;
26 48         91 return $old;
27             } else {
28 293         667 return $self->{entry};
29             }
30             }
31              
32             sub make_node {
33 50     50 0 68 my ($self, $spec) = @_;
34            
35             return $self->_descend_path($spec, sub {
36 147     147   127 my ($node, $rdn) = @_;
37 147         198 return $node->_make_subnode($rdn);
38 50         205 });
39             }
40              
41             sub get_node {
42 107     107 0 131 my ($self, $spec) = @_;
43            
44             return $self->_descend_path($spec, sub {
45 227     227   209 my ($node, $rdn) = @_;
46 227         335 return $node->_get_subnode($rdn);
47 107         448 });
48             }
49              
50             sub traverse {
51 45     45 0 59 my ($self, $callback, $scope) = @_;
52 45   100     86 $scope ||= 0; # 0: base, 1: one, 2: sub
53            
54 45         41 my $visit;
55             $visit = sub {
56 195     195   209 my ($node, $deep) = @_;
57 195         298 $callback->($node);
58            
59             # $deep == 0 or 1
60 195 100       1985 if ($scope > $deep) {
61             $node->_each_subnode(sub {
62 150         120 my ($subnode) = @_;
63 150         248 $visit->($subnode, 1);
64 153         460 });
65             }
66 45         121 };
67            
68 45         74 $visit->($self, 0);
69             }
70              
71             sub password {
72 8     8 0 9 my $self = shift;
73 8         8 my $password = $self->{password};
74 8 100       14 $self->{password} = shift if @_;
75 8         31 return $password;
76             }
77              
78             sub _descend_path {
79 157     157   182 my ($self, $spec, $callback) = @_;
80            
81 157 100       288 if (ref $spec eq 'HASH') {
82 7         9 my $node = $callback->($self, $spec);
83 7         27 return $node;
84             } else {
85 150         125 my $dn_list;
86            
87 150 100       235 if (ref $spec eq 'ARRAY') {
88 95         95 $dn_list = $spec;
89             } else {
90 55 50       147 my $dn = blessed($spec) ? $spec->dn : $spec;
91 55         111 $dn_list = ldap_explode_dn($dn, casefold => 'lower');
92             }
93            
94 150         3794 my $node = $self;
95 150         132 my $parent;
96            
97 150         236 for my $rdn (reverse @$dn_list) {
98 367         323 $parent = $node;
99 367 100       455 $node = $callback->($node, $rdn) or last;
100             }
101            
102 150         515 return $node;
103             }
104             }
105              
106             sub _make_subnode {
107 147     147   123 my ($self, $rdn) = @_;
108             # E.g. $rdn == {ou => 'Sales'}
109 147         297 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
110 147   66     3774 return $self->{submap}{$canonical} ||= ref($self)->new;
111             }
112              
113             sub _get_subnode {
114 227     227   190 my ($self, $rdn) = @_;
115             # E.g. $rdn == {ou => 'Sales'}
116 227         486 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
117 227         5785 return $self->{submap}{$canonical};
118             }
119              
120             sub _each_subnode {
121 153     153   129 my ($self, $callback) = @_;
122 153         147 my $submap = $self->{submap};
123            
124 153         482 for my $canonical (keys %$submap) {
125 150         196 $callback->($submap->{$canonical});
126             }
127             }
128              
129             1;