File Coverage

blib/lib/Graphviz/DSL.pm
Criterion Covered Total %
statement 134 141 95.0
branch 2 2 100.0
condition 0 4 0.0
subroutine 45 48 93.7
pod n/a
total 181 195 92.8


line stmt bran cond sub pod time code
1             package Graphviz::DSL;
2 6     6   167845 use strict;
  6         15  
  6         259  
3 6     6   31 use warnings;
  6         14  
  6         178  
4 6     6   152 use 5.008_001;
  6         23  
  6         250  
5              
6 6     6   37 use Carp ();
  6         10  
  6         158  
7 6     6   8084 use Encode ();
  6         92851  
  6         149  
8 6     6   5581 use File::Which ();
  6         6739  
  6         131  
9              
10 6     6   3713 use Graphviz::DSL::Graph;
  6         21  
  6         371  
11 6     6   6380 use Graphviz::DSL::Edge;
  6         15  
  6         166  
12 6     6   6728 use Graphviz::DSL::Node;
  6         19  
  6         627  
13              
14             our $VERSION = '0.03';
15              
16             sub import {
17 6     6   57 my $class = shift;
18 6         17 my $pkg = caller;
19              
20 6     6   47 no strict 'refs';
  6         12  
  6         192  
21 6     6   30 no warnings 'redefine';
  6         12  
  6         4557  
22              
23 6         19 *{"$pkg\::graph"} = _build_graph();
  6         38  
24 6     9   23 *{"$pkg\::add"} = sub { goto &add };
  6         60  
  9         53  
25 6     30   19 *{"$pkg\::route"} = sub { goto &route };
  6         26  
  30         219  
26 6     6   18 *{"$pkg\::node"} = sub { goto &node };
  6         30  
  6         39  
27 6     4   24 *{"$pkg\::edge"} = sub { goto &edge };
  6         31  
  4         41  
28 6     1   31 *{"$pkg\::nodes"} = sub { goto &nodes };
  6         32  
  1         9  
29 6     1   22 *{"$pkg\::edges"} = sub { goto &edges };
  6         27  
  1         6  
30 6     1   46 *{"$pkg\::nodeset"} = sub { goto &nodeset };
  6         28  
  1         7  
31 6     1   21 *{"$pkg\::edgeset"} = sub { goto &edgeset };
  6         33  
  1         9  
32 6     2   22 *{"$pkg\::global"} = sub { goto &global };
  6         48  
  2         13  
33 6     3   26 *{"$pkg\::rank"} = sub { goto &rank };
  6         26  
  3         23  
34 6     1   39 *{"$pkg\::name"} = sub { goto &name };
  6         35  
  1         8  
35 6     3   19 *{"$pkg\::type"} = sub { goto &type };
  6         29  
  3         19  
36 6     3   37 *{"$pkg\::subgraph"} = (sub { sub (&) { goto &subgraph } })->();
  6         69  
  6         18  
  1         8  
37 6     2   18 *{"$pkg\::multi_route"} = sub { goto &multi_route };
  6         13952  
  2         29  
38             }
39              
40             sub _new {
41 0     0   0 my ($class, %args) = @_;
42              
43 0   0     0 my $name = delete $args{name} || 'G';
44 0   0     0 my $type = delete $args{type} || 'digraph';
45              
46 0         0 bless {
47             name => $name,
48             type => $type,
49             edges => [],
50             nodes => [],
51             gnode_attrs => [],
52             gedge_attrs => [],
53             graph_attrs => [],
54             subgraphs => [],
55             ranks => [],
56             objects => [],
57             }, $class;
58             }
59              
60             sub _build_nodes {
61 0     0   0 my $self = shift;
62              
63             sub {
64 0     0   0 $self->_nodes;
65 0         0 };
66             }
67              
68             sub _build_graph {
69 7     7   16 my ($subgraph) = @_;
70              
71             sub (&) {
72 35     35   72138 my $code = shift;
73              
74 35 100       296 my $graph = defined $subgraph ? $subgraph : Graphviz::DSL::Graph->new();
75              
76 6     6   39 no warnings 'redefine';
  6         10  
  6         4680  
77              
78 35     39   21234 my $add_code = sub { $graph->add(@_) };
  39         185  
79              
80 35         203 local *add = \&$add_code;
81 35         83 local *route = \&$add_code;
82 35     6   142 local *node = sub { $graph->node(@_) };
  6         24  
83 35     4   160 local *edge = sub { $graph->edge(@_) };
  4         22  
84 35     1   130 local *nodes = sub { $graph->update_attrs('gnode_attrs', @_) };
  1         7  
85 35     1   133 local *edges = sub { $graph->update_attrs('gedge_attrs', @_) };
  1         7  
86 35     1   276 local *nodeset = sub { @{$graph->{nodes}} };
  1         2  
  1         5  
87 35     1   151 local *edgeset = sub { @{$graph->{edges}} };
  1         1  
  1         7  
88 35     2   128 local *global = sub { $graph->update_attrs('graph_attrs', @_) };
  2         13  
89 35     3   203 local *rank = sub { $graph->rank(@_) };
  3         15  
90 35     1   124 local *name = sub { $graph->name(@_) };
  1         6  
91 35     3   133 local *type = sub { $graph->type(@_) };
  3         14  
92 35         100 local *subgraph = _build_subgraph($graph);
93 35     2   137 local *multi_route = sub { $graph->multi_route(@_) };
  2         13  
94              
95 35         90 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
96              
97 35         175 $code->();
98 31         1038 $graph;
99             }
100 7         39 }
101              
102             sub _build_subgraph {
103 35     35   180 my $parent = shift;
104              
105             sub (&) {
106 1     1   3 my $code = shift;
107 1         2 my $num = scalar @{$parent->{subgraphs}};
  1         4  
108              
109 1         8 my $self = Graphviz::DSL::Graph->new(
110             id => "cluster${num}",
111             type => $parent->{type},
112             subgraph => 1,
113             );
114 1         6 my $graph = _build_graph($self);
115              
116 1         3 my $subgraph = $graph->($code);
117 1         2 push @{$parent->{subgraphs}}, $subgraph;
  1         3  
118 1         3 push @{$parent->{objects}}, $subgraph;
  1         8  
119 35         211 };
120             }
121              
122             sub __stub {
123 84     84   106 my $func = shift;
124             return sub {
125 13     13   7356 Carp::croak "Can't call $func() outside graph block";
126 84         303 };
127             }
128              
129             *route = __stub 'route';
130             *add = __stub 'add';
131             *node = __stub 'node';
132             *edge = __stub 'edge';
133             *nodes = __stub 'nodes';
134             *edges = __stub 'edges';
135             *nodeset = __stub 'nodeset';
136             *edgeset = __stub 'edgeset';
137             *global = __stub 'global';
138             *rank = __stub 'rank';
139             *subgraph = __stub 'subgraph';
140             *name = __stub 'name';
141             *type = __stub 'type';
142             *multi_route = __stub 'multi_route';
143              
144             1;
145              
146             __END__