| // Copyright ©2018 The Gonum Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package gexf12 |
| |
| import ( |
| "encoding/xml" |
| "io/ioutil" |
| "path/filepath" |
| "reflect" |
| "testing" |
| "time" |
| ) |
| |
| var gexfExampleTests = []struct { |
| path string |
| unmarshaled Content |
| marshaled string |
| }{ |
| { |
| path: "basic.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Meta: nil, |
| Graph: Graph{ |
| Attributes: nil, |
| Nodes: Nodes{ |
| Nodes: []Node{ |
| {ID: "0", Label: "Hello"}, |
| {ID: "1", Label: "Word"}, |
| }, |
| }, |
| Edges: Edges{ |
| Edges: []Edge{ |
| {ID: "0", Source: "0", Target: "1"}, |
| }, |
| }, |
| DefaultEdgeType: "directed", |
| Mode: "static", |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <graph defaultedgetype="directed" mode="static"> |
| <nodes> |
| <node id="0" label="Hello"></node> |
| <node id="1" label="Word"></node> |
| </nodes> |
| <edges> |
| <edge id="0" source="0" target="1"></edge> |
| </edges> |
| </graph> |
| </gexf>`, |
| }, |
| { |
| path: "data.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Meta: &Meta{ |
| Creator: "Gephi.org", |
| Description: "A Web network", |
| LastModified: time.Date(2009, 03, 20, 0, 0, 0, 0, time.UTC), |
| }, |
| Graph: Graph{ |
| Attributes: []Attributes{{ |
| Class: "node", |
| Attributes: []Attribute{ |
| { |
| ID: "0", |
| Title: "url", |
| Type: "string", |
| }, |
| { |
| ID: "1", |
| Title: "indegree", |
| Type: "float", |
| }, |
| { |
| ID: "2", |
| Title: "frog", |
| Type: "boolean", |
| Default: "true", |
| }, |
| }, |
| }}, |
| Nodes: Nodes{ |
| Nodes: []Node{ |
| { |
| ID: "0", Label: "Gephi", |
| AttValues: &AttValues{AttValues: []AttValue{ |
| {For: "0", Value: "http://gephi.org"}, |
| {For: "1", Value: "1"}, |
| }}, |
| }, |
| { |
| ID: "1", Label: "Webatlas", |
| AttValues: &AttValues{AttValues: []AttValue{ |
| {For: "0", Value: "http://webatlas.fr"}, |
| {For: "1", Value: "2"}, |
| }}, |
| }, |
| { |
| ID: "2", Label: "RTGI", |
| AttValues: &AttValues{AttValues: []AttValue{ |
| {For: "0", Value: "http://rtgi.fr"}, |
| {For: "1", Value: "1"}, |
| }}, |
| }, |
| { |
| ID: "3", Label: "BarabasiLab", |
| AttValues: &AttValues{AttValues: []AttValue{ |
| {For: "0", Value: "http://barabasilab.com"}, |
| {For: "1", Value: "1"}, |
| {For: "2", Value: "false"}, |
| }}, |
| }, |
| }, |
| }, |
| Edges: Edges{ |
| Edges: []Edge{ |
| {ID: "0", Source: "0", Target: "1"}, |
| {ID: "1", Source: "0", Target: "2"}, |
| {ID: "2", Source: "1", Target: "0"}, |
| {ID: "3", Source: "2", Target: "1"}, |
| {ID: "4", Source: "0", Target: "3"}, |
| }, |
| }, |
| DefaultEdgeType: "directed", |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <meta lastmodifieddate="2009-03-20"> |
| <creator>Gephi.org</creator> |
| <description>A Web network</description> |
| </meta> |
| <graph defaultedgetype="directed"> |
| <attributes class="node"> |
| <attribute id="0" title="url" type="string"></attribute> |
| <attribute id="1" title="indegree" type="float"></attribute> |
| <attribute id="2" title="frog" type="boolean"> |
| <default>true</default> |
| </attribute> |
| </attributes> |
| <nodes> |
| <node id="0" label="Gephi"> |
| <attvalues> |
| <attvalue for="0" value="http://gephi.org"></attvalue> |
| <attvalue for="1" value="1"></attvalue> |
| </attvalues> |
| </node> |
| <node id="1" label="Webatlas"> |
| <attvalues> |
| <attvalue for="0" value="http://webatlas.fr"></attvalue> |
| <attvalue for="1" value="2"></attvalue> |
| </attvalues> |
| </node> |
| <node id="2" label="RTGI"> |
| <attvalues> |
| <attvalue for="0" value="http://rtgi.fr"></attvalue> |
| <attvalue for="1" value="1"></attvalue> |
| </attvalues> |
| </node> |
| <node id="3" label="BarabasiLab"> |
| <attvalues> |
| <attvalue for="0" value="http://barabasilab.com"></attvalue> |
| <attvalue for="1" value="1"></attvalue> |
| <attvalue for="2" value="false"></attvalue> |
| </attvalues> |
| </node> |
| </nodes> |
| <edges> |
| <edge id="0" source="0" target="1"></edge> |
| <edge id="1" source="0" target="2"></edge> |
| <edge id="2" source="1" target="0"></edge> |
| <edge id="3" source="2" target="1"></edge> |
| <edge id="4" source="0" target="3"></edge> |
| </edges> |
| </graph> |
| </gexf>`, |
| }, |
| { |
| path: "hierarchy1.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Meta: &Meta{ |
| Creator: "Gephi.org", |
| Description: "A hierarchy file", |
| LastModified: time.Date(2009, 10, 1, 0, 0, 0, 0, time.UTC), |
| }, |
| Graph: Graph{ |
| Nodes: Nodes{ |
| Nodes: []Node{{ |
| ID: "a", |
| Label: "Kevin Bacon", |
| Nodes: &Nodes{ |
| Nodes: []Node{ |
| { |
| ID: "b", Label: "God", |
| Nodes: &Nodes{ |
| Nodes: []Node{ |
| {ID: "c", Label: "human1"}, |
| {ID: "d", Label: "human2"}, |
| {ID: "i", Label: "human3"}, |
| }, |
| }, |
| }, |
| { |
| ID: "e", Label: "Me", |
| Nodes: &Nodes{ |
| Nodes: []Node{ |
| {ID: "f", Label: "frog1"}, |
| {ID: "g", Label: "frog2"}, |
| {ID: "h", Label: "frog3"}, |
| }, |
| }, |
| }, |
| { |
| ID: "j", Label: "You", |
| }, |
| }, |
| }, |
| }}, |
| }, |
| Edges: Edges{ |
| Edges: []Edge{ |
| {ID: "0", Source: "b", Target: "e"}, |
| {ID: "1", Source: "c", Target: "d"}, |
| {ID: "2", Source: "c", Target: "i"}, |
| {ID: "3", Source: "g", Target: "b"}, |
| {ID: "4", Source: "f", Target: "a"}, |
| {ID: "5", Source: "f", Target: "g"}, |
| {ID: "6", Source: "f", Target: "h"}, |
| {ID: "7", Source: "g", Target: "h"}, |
| {ID: "8", Source: "a", Target: "j"}, |
| }, |
| }, |
| DefaultEdgeType: "directed", |
| Mode: "static", |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <meta lastmodifieddate="2009-10-01"> |
| <creator>Gephi.org</creator> |
| <description>A hierarchy file</description> |
| </meta> |
| <graph defaultedgetype="directed" mode="static"> |
| <nodes> |
| <node id="a" label="Kevin Bacon"> |
| <nodes> |
| <node id="b" label="God"> |
| <nodes> |
| <node id="c" label="human1"></node> |
| <node id="d" label="human2"></node> |
| <node id="i" label="human3"></node> |
| </nodes> |
| </node> |
| <node id="e" label="Me"> |
| <nodes> |
| <node id="f" label="frog1"></node> |
| <node id="g" label="frog2"></node> |
| <node id="h" label="frog3"></node> |
| </nodes> |
| </node> |
| <node id="j" label="You"></node> |
| </nodes> |
| </node> |
| </nodes> |
| <edges> |
| <edge id="0" source="b" target="e"></edge> |
| <edge id="1" source="c" target="d"></edge> |
| <edge id="2" source="c" target="i"></edge> |
| <edge id="3" source="g" target="b"></edge> |
| <edge id="4" source="f" target="a"></edge> |
| <edge id="5" source="f" target="g"></edge> |
| <edge id="6" source="f" target="h"></edge> |
| <edge id="7" source="g" target="h"></edge> |
| <edge id="8" source="a" target="j"></edge> |
| </edges> |
| </graph> |
| </gexf>`, |
| }, |
| { |
| path: "hierarchy4.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Meta: &Meta{ |
| Creator: "Gephi.org", |
| Keywords: "", |
| Description: "A hierarchy file", |
| LastModified: time.Date(2009, 10, 1, 0, 0, 0, 0, time.UTC), |
| }, |
| Graph: Graph{ |
| Nodes: Nodes{ |
| Nodes: []Node{ |
| {ID: "g", Label: "frog2", ParentID: "e"}, |
| {ID: "a", Label: "Kevin Bacon"}, |
| {ID: "c", Label: "human1", ParentID: "b"}, |
| {ID: "b", Label: "God", ParentID: "a"}, |
| {ID: "e", Label: "Me", ParentID: "a"}, |
| {ID: "d", Label: "human2", ParentID: "b"}, |
| {ID: "f", Label: "frog1", ParentID: "e"}, |
| }, |
| }, |
| Edges: Edges{ |
| Edges: []Edge{ |
| {ID: "0", Source: "b", Target: "e"}, |
| {ID: "1", Source: "c", Target: "d"}, |
| {ID: "2", Source: "g", Target: "b"}, |
| {ID: "3", Source: "f", Target: "a"}, |
| }, |
| }, |
| DefaultEdgeType: "directed", |
| Mode: "static", |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <meta lastmodifieddate="2009-10-01"> |
| <creator>Gephi.org</creator> |
| <description>A hierarchy file</description> |
| </meta> |
| <graph defaultedgetype="directed" mode="static"> |
| <nodes> |
| <node id="g" label="frog2" pid="e"></node> |
| <node id="a" label="Kevin Bacon"></node> |
| <node id="c" label="human1" pid="b"></node> |
| <node id="b" label="God" pid="a"></node> |
| <node id="e" label="Me" pid="a"></node> |
| <node id="d" label="human2" pid="b"></node> |
| <node id="f" label="frog1" pid="e"></node> |
| </nodes> |
| <edges> |
| <edge id="0" source="b" target="e"></edge> |
| <edge id="1" source="c" target="d"></edge> |
| <edge id="2" source="g" target="b"></edge> |
| <edge id="3" source="f" target="a"></edge> |
| </edges> |
| </graph> |
| </gexf>`, |
| }, |
| { |
| path: "phylogeny.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Graph: Graph{ |
| Nodes: Nodes{ |
| Nodes: []Node{ |
| {ID: "a", Label: "cheese"}, |
| {ID: "b", Label: "cherry"}, |
| {ID: "c", Label: "cake", Parents: &Parents{ |
| Parents: []Parent{ |
| {For: "a"}, |
| {For: "b"}, |
| }, |
| }, |
| }, |
| }, |
| }, |
| Edges: Edges{ |
| Edges: nil, |
| Count: 0, |
| }, |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <graph> |
| <nodes> |
| <node id="a" label="cheese"></node> |
| <node id="b" label="cherry"></node> |
| <node id="c" label="cake"> |
| <parents> |
| <parent for="a"></parent> |
| <parent for="b"></parent> |
| </parents> |
| </node> |
| </nodes> |
| <edges></edges> |
| </graph> |
| </gexf>`, |
| }, |
| { |
| path: "viz.gexf", |
| unmarshaled: Content{ |
| XMLName: xml.Name{Space: "http://www.gexf.net/1.2draft", Local: "gexf"}, |
| Graph: Graph{ |
| Nodes: Nodes{ |
| Nodes: []Node{ |
| { |
| ID: "a", |
| Label: "glossy", |
| Color: &Color{ |
| R: 239, |
| G: 173, |
| B: 66, |
| A: 0.6, |
| }, |
| Position: &Position{ |
| X: 15.783598, |
| Y: 40.109245, |
| Z: 0, |
| }, |
| Size: &Size{ |
| Value: 2.0375757, |
| }, |
| }, |
| }, |
| }, |
| Edges: Edges{}, |
| }, |
| Version: "1.2", |
| }, |
| marshaled: `<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2"> |
| <graph> |
| <nodes> |
| <node id="a" label="glossy"> |
| <color xmlns="http://www.gexf.net/1.2draft/viz" r="239" g="173" b="66" a="0.6"></color> |
| <position xmlns="http://www.gexf.net/1.2draft/viz" x="15.783598" y="40.109245" z="0"></position> |
| <size xmlns="http://www.gexf.net/1.2draft/viz" value="2.0375757"></size> |
| </node> |
| </nodes> |
| <edges></edges> |
| </graph> |
| </gexf>`, |
| }, |
| } |
| |
| func TestUnmarshal(t *testing.T) { |
| for _, test := range gexfExampleTests { |
| data, err := ioutil.ReadFile(filepath.Join("testdata", test.path)) |
| if err != nil { |
| t.Errorf("failed to read %q: %v", test.path, err) |
| continue |
| } |
| var got Content |
| err = xml.Unmarshal(data, &got) |
| if !reflect.DeepEqual(got, test.unmarshaled) { |
| t.Errorf("unexpected result for %q:\ngot:\n%#v\nwant:\n%#v", test.path, got, test.unmarshaled) |
| } |
| } |
| } |
| |
| // TODO(kortschak): Update this test when/if namespace |
| // prefix handling in encoding/xml is fixed. |
| func TestMarshal(t *testing.T) { |
| for _, test := range gexfExampleTests { |
| got, err := xml.MarshalIndent(test.unmarshaled, "", "\t") |
| if err != nil { |
| t.Errorf("failed to marshal %q: %v", test.path, err) |
| continue |
| } |
| if string(got) != test.marshaled { |
| t.Errorf("unexpected result for %q:\ngot:\n%s\nwant:\n%s", test.path, got, test.marshaled) |
| } |
| } |
| } |