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   14261 use 5.006;
  13         89  
  13         423  
2 13     13   54 use strict;
  13         16  
  13         332  
3 13     13   48 use warnings;
  13         15  
  13         500  
4              
5             package Test::Net::LDAP::Mock::Node;
6              
7 13     13   2370 use Net::LDAP::Util qw(canonical_dn ldap_explode_dn);
  13         4405  
  13         745  
8 13     13   64 use Scalar::Util qw(blessed);
  13         14  
  13         6425  
9              
10             sub new {
11 111     111 0 135 my ($class) = @_;
12            
13 111         780 return bless {
14             entry => undef,
15             submap => {},
16             password => undef,
17             }, $class;
18             }
19              
20             sub entry {
21 347     347 0 298 my $self = shift;
22            
23 347 100       469 if (@_) {
24 48         49 my $old = $self->{entry};
25 48         49 $self->{entry} = shift;
26 48         91 return $old;
27             } else {
28 299         634 return $self->{entry};
29             }
30             }
31              
32             sub make_node {
33 50     50 0 63 my ($self, $spec) = @_;
34            
35             return $self->_descend_path($spec, sub {
36 147     147   120 my ($node, $rdn) = @_;
37 147         197 return $node->_make_subnode($rdn);
38 50         201 });
39             }
40              
41             sub get_node {
42 109     109 0 130 my ($self, $spec) = @_;
43            
44             return $self->_descend_path($spec, sub {
45 233     233   235 my ($node, $rdn) = @_;
46 233         299 return $node->_get_subnode($rdn);
47 109         430 });
48             }
49              
50             sub traverse {
51 47     47 0 63 my ($self, $callback, $scope) = @_;
52 47   100     83 $scope ||= 0; # 0: base, 1: one, 2: sub
53            
54 47         41 my $visit;
55             $visit = sub {
56 201     201   164 my ($node, $deep) = @_;
57 201         300 $callback->($node);
58            
59             # $deep == 0 or 1
60 201 100       1888 if ($scope > $deep) {
61             $node->_each_subnode(sub {
62 154         119 my ($subnode) = @_;
63 154         247 $visit->($subnode, 1);
64 155         439 });
65             }
66 47         117 };
67            
68 47         79 $visit->($self, 0);
69             }
70              
71             sub password {
72 8     8 0 9 my $self = shift;
73 8         5 my $password = $self->{password};
74 8 100       17 $self->{password} = shift if @_;
75 8         36 return $password;
76             }
77              
78             sub _descend_path {
79 159     159   175 my ($self, $spec, $callback) = @_;
80            
81 159 100       283 if (ref $spec eq 'HASH') {
82 7         11 my $node = $callback->($self, $spec);
83 7         29 return $node;
84             } else {
85 152         104 my $dn_list;
86            
87 152 100       215 if (ref $spec eq 'ARRAY') {
88 97         130 $dn_list = $spec;
89             } else {
90 55 50       151 my $dn = blessed($spec) ? $spec->dn : $spec;
91 55         114 $dn_list = ldap_explode_dn($dn, casefold => 'lower');
92             }
93            
94 152         3869 my $node = $self;
95 152         121 my $parent;
96            
97 152         227 for my $rdn (reverse @$dn_list) {
98 373         283 $parent = $node;
99 373 100       453 $node = $callback->($node, $rdn) or last;
100             }
101            
102 152         562 return $node;
103             }
104             }
105              
106             sub _make_subnode {
107 147     147   128 my ($self, $rdn) = @_;
108             # E.g. $rdn == {ou => 'Sales'}
109 147         299 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
110 147   66     3677 return $self->{submap}{$canonical} ||= ref($self)->new;
111             }
112              
113             sub _get_subnode {
114 233     233   171 my ($self, $rdn) = @_;
115             # E.g. $rdn == {ou => 'Sales'}
116 233         480 my $canonical = lc canonical_dn([$rdn], casefold => 'none');
117 233         5639 return $self->{submap}{$canonical};
118             }
119              
120             sub _each_subnode {
121 155     155   132 my ($self, $callback) = @_;
122 155         154 my $submap = $self->{submap};
123            
124 155         492 for my $canonical (keys %$submap) {
125 154         203 $callback->($submap->{$canonical});
126             }
127             }
128              
129             1;