1#!/usr/bin/perl -w 2 3use Test::More; 4use strict; 5 6BEGIN 7 { 8 plan tests => 86; 9 chdir 't' if -d 't'; 10 use lib '../lib'; 11 use_ok ("Graph::Easy::Parser") or die($@); 12 use_ok ("Graph::Easy") or die($@); 13 }; 14 15can_ok ("Graph::Easy::Parser", qw/ 16 _parse_attributes 17 /); 18 19 20############################################################################# 21# parser object 22 23my $parser = Graph::Easy::Parser->new(); 24 25is (ref($parser), 'Graph::Easy::Parser'); 26is ($parser->error(), '', 'no error yet'); 27 28my $line = 0; 29$parser->no_fatal_errors(1); 30 31foreach (<DATA>) 32 { 33 chomp; 34 next if $_ =~ /^(\s*\z|#)/; # skip empty lines or comments 35 36 my ($in,$result) = split /\|/, $_; 37 38 my $txt = $in; 39 $txt =~ s/\\n/\n/g; # insert real newlines 40 41 # ^ => to '|' since '|' is the sep. 42 $txt =~ s/[\^]/\|/g; 43 44 $parser->reset(); 45 46 my $class = 'node'; 47 $class = 'edge' if $txt =~ /^(start|end|labelcolor|arrow)/; 48 $class = 'graph' if $txt =~ /^labelpos/; 49 50 # need to cache this value 51 $parser->{_match_single_attribute} = $parser->_match_single_attribute(); 52 53 my $att = $parser->_parse_attributes($txt, $class); # reuse parser object 54 55 if ($parser->error()) 56 { 57 if ($result =~ /^error=/) 58 { 59 my $res = $result; $res =~ s/^error=//; my $resq = quotemeta($res); 60 like ($parser->error(), qr/$resq/, $res); 61 } 62 else 63 { 64 print '# Got unexpected error: ' . $parser->error(), "\n"; 65 fail ("$txt"); 66 } 67 next; 68 } 69 70 my $exp = ''; 71 foreach my $k (sort keys %$att) 72 { 73 if (ref($att->{$k}) eq 'ARRAY') 74 { 75 $exp .= "$k="; 76 for my $k1 (@{$att->{$k}}) 77 { 78 my $v = $parser->{_graph}->unquote_attribute('graph',$k,$k1); 79 $exp .= "$v,"; 80 } 81 $exp =~ s/,\z//; 82 $exp .= ";"; 83 } 84 else 85 { 86 my $v = $parser->{_graph}->unquote_attribute('graph',$k,$att->{$k}); 87 $exp .= "$k=$v;"; 88 } 89 } 90 91 is ($exp, $result, $in); 92 } 93 94__DATA__ 95| 96color: red;|color=red; 97color : red;|color=red; 98 color : lime ; |color=lime; 99 color : yellow |color=yellow; 100color: rgb(1,1,1);|color=rgb(1,1,1); 101color: rgb(255,1,1);|color=rgb(255,1,1); 102color: rgb(255,255,1);|color=rgb(255,255,1); 103color: rgb(255,255,255);|color=rgb(255,255,255); 104color: #ff0;|color=#ff0; 105color: #0f0;|color=#0f0; 106color: slategrey;|color=slategrey; 107color: slategrey;|color=slategrey; 108color: gray;|color=gray; 109color: gray;|color=gray; 110# color names are case-insensitive 111color: Slategrey;|color=slategrey; 112color: SlateGrey;|color=slategrey; 113color: SLATEGREY;|color=slategrey; 114colorscheme: w3c;|colorscheme=w3c; 115colorscheme: x11;|colorscheme=x11; 116colorscheme: puor6;|colorscheme=puor6; 117colorscheme: puor16|error=Error in attribute: 'puor16' is not a valid colorscheme for a node 118border-style: double;|borderstyle=double; 119border-width: 1;|borderwidth=1; 120border-color: red;|bordercolor=red; 121color: red; border: none; |border=none;color=red; 122color:|error=Error in attribute: 'color:' doesn't look valid 123: red;|error=Error in attribute: ': red;' doesn't look valid 124: red|error=Error in attribute: ': red' doesn't look valid 125color: reddish|error=Error in attribute: 'reddish' is not a valid color for a node 126color:;background: red|error=Error in attribute: 'color:;background: red' doesn't look valid 127shape:fruggle;|error=Error in attribute: 'fruggle' is not a valid shape for a node 128color: rgb(256, 0, 0);|error=Error in attribute: 'rgb(256, 0, 0)' is not a valid color for a node 129color: rgb(0, 256, 0);|error=Error in attribute: 'rgb(0, 256, 0)' is not a valid color for a node 130color: rgb(0, 0, 256);|error=Error in attribute: 'rgb(0, 0, 256)' is not a valid color for a node 131shape: qiggle;|error=Error in attribute: 'qiggle' is not a valid shape for a node 132offset: -3,-2;|offset=-3,-2; 133offset: 3,-2;|offset=3,-2; 134offset: -3,2;|offset=-3,2; 135offset: 2, 0;|offset=2, 0; 136offset: 2 , 0;|offset=2 , 0; 137offset: 2 , 0;|offset=2 , 0; 138offset: 2 , 0 ;|offset=2 , 0; 139fill: brown;|fill=brown; 140point-style: qiggle;|error=Error in attribute: 'qiggle' is not a valid pointstyle for a node 141toint-shape: qiggle;|error=Error in attribute: 'toint-shape' is not a valid attribute name for a node 142autolink: qiggle;|error=Error in attribute: 'qiggle' is not a valid autolink for a node 143size: 1, 2;|size=1, 2; 144start: south, 1;|start=south, 1; 145start: south , 1;|start=south , 1; 146start: right , -1;|start=right , -1; 147end: south, 1;|end=south, 1; 148end: south , 1;|end=south , 1; 149end: right , -1;|end=right , -1; 150end: right,12345;|error=Error in attribute: 'right,12345' is not a valid end for a edge 151start: right,12345;|error=Error in attribute: 'right,12345' is not a valid start for a edge 152autolabel: 20;|autolabel=20; 153autolabel: name,1;|error=Error in attribute: 'name,1' is not a valid autolabel for a node 154autolabel: name,10;|autolabel=name,10; 155autolabel: name, 10;|autolabel=name, 10; 156autolabel: name ,10;|autolabel=name ,10; 157autolabel: name , 10;|autolabel=name , 10; 158fill: red^green^yellow;|fill=red,green,yellow; 159link: http://bloodgate.com/^index.html^/test;|link=http://bloodgate.com/,index.html,/test; 160link: http://bloodgate.com/ ^ index.html^/test;|link=http://bloodgate.com/,index.html,/test; 161shape: rect^img^rect;|shape=rect,img,rect; 162# attribute with a ";" inside quotes, and escaped quotes 163label: "baz;bar"; color: red;|color=red;label=baz;bar; 164label: "test";|label=test; 165label: "test;";|label=test;; 166label: "\"test\"";|label="test"; 167label: "\"test;\"";|label="test;"; 168# alias names 169bordercolor: red;|bordercolor=red; 170borderstyle: solid;|borderstyle=solid; 171borderwidth: 1px;|borderwidth=1px; 172fontsize: 80%;|fontsize=80%; 173textstyle: bold;|textstyle=bold; 174textwrap: auto;|textwrap=auto; 175pointstyle: diamond;|pointstyle=diamond; 176arrowstyle: filled;|arrowstyle=filled; 177labelcolor: peachpuff;|labelcolor=peachpuff; 178labelpos: bottom;|labelpos=bottom; 179