graphs 0.1.0-x86-linux
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/graph.rb +81 -0
- data/lib/graphs/gdf.rb +182 -0
- data/tests/tests_gdf.rb +220 -0
- data/tests/tests_gexf.rb +5 -0
- data/tests/tests_graph.rb +174 -0
- metadata +53 -0
data/lib/graph.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
class Graph
|
6
|
+
|
7
|
+
class NodeArray < Array
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super(*args)
|
11
|
+
@defaults = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_default(dict)
|
15
|
+
@defaults.update(dict)
|
16
|
+
self.map! { |e| e.update(@defaults) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def push(o)
|
20
|
+
if (!o.is_a?(Hash))
|
21
|
+
raise TypeError.new "#{o.inspect} is not an Hash!"
|
22
|
+
end
|
23
|
+
o2 = o.clone
|
24
|
+
o2.update(@defaults)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class EdgeArray < NodeArray
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :nodes, :edges
|
33
|
+
|
34
|
+
def initialize(nodes=nil, edges=nil)
|
35
|
+
@nodes = NodeArray.new(nodes || [])
|
36
|
+
@edges = EdgeArray.new(edges || [])
|
37
|
+
end
|
38
|
+
|
39
|
+
def ==(other)
|
40
|
+
if (!other.is_a?(Graph))
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
(self.nodes === other.nodes) && (self.edges == other.edges)
|
44
|
+
end
|
45
|
+
|
46
|
+
def &(other)
|
47
|
+
if (!other.is_a?(Graph))
|
48
|
+
return nil
|
49
|
+
end
|
50
|
+
|
51
|
+
nodes = @nodes & other.nodes
|
52
|
+
edges = @edges & other.edges
|
53
|
+
|
54
|
+
Graph.new(nodes, edges)
|
55
|
+
end
|
56
|
+
|
57
|
+
def write(filename, opts=nil)
|
58
|
+
|
59
|
+
has_ext = filename.split('.')
|
60
|
+
|
61
|
+
if ((has_ext.length == 1) || (has_ext[-1] == 'yml'))
|
62
|
+
# YAML (default)
|
63
|
+
nodes = self.nodes.to_a
|
64
|
+
edges = self.edges.to_a
|
65
|
+
|
66
|
+
data = {'nodes'=>nodes, 'edges'=>edges}.to_yaml
|
67
|
+
f = open(filename+'.yml', 'w')
|
68
|
+
f.write(data)
|
69
|
+
f.close
|
70
|
+
else
|
71
|
+
ext = has_ext[-1]
|
72
|
+
|
73
|
+
m = (self.methods - Object.methods).map {|e| e.to_s}
|
74
|
+
|
75
|
+
if (m.include? '_write_'+ext.downcase)
|
76
|
+
self.send('_write_'+ext.downcase, filename, opts)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/lib/graphs/gdf.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
require_relative '../graph'
|
4
|
+
|
5
|
+
class Graph
|
6
|
+
def to_gdf(opts=nil)
|
7
|
+
GDF::unparse(self, opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def _write_gdf(filename, opts=nil)
|
11
|
+
gdf = GDF::unparse(self, opts)
|
12
|
+
f = File.open(filename, 'w')
|
13
|
+
f.write(gdf)
|
14
|
+
f.close
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module GDF
|
19
|
+
|
20
|
+
def self.load(filename)
|
21
|
+
self.parse(File.read(filename))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse(content)
|
25
|
+
|
26
|
+
if (content.nil? || content.length == 0)
|
27
|
+
return Graph.new([],[])
|
28
|
+
end
|
29
|
+
|
30
|
+
content = content.split("\n")
|
31
|
+
|
32
|
+
# lines index of 'nodedef>' and 'edgedef>'
|
33
|
+
nodes_def_index = -1
|
34
|
+
edges_def_index = -1
|
35
|
+
|
36
|
+
content.each_with_index {|l,i|
|
37
|
+
if l.start_with? 'nodedef>'
|
38
|
+
nodes_def_index = i
|
39
|
+
elsif l.start_with? 'edgedef>'
|
40
|
+
edges_def_index = i
|
41
|
+
end
|
42
|
+
|
43
|
+
if ((nodes_def_index >= 0) && (edges_def_index >= 0))
|
44
|
+
break
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
# no edges
|
49
|
+
if (edges_def_index == -1)
|
50
|
+
edges = []
|
51
|
+
edges_def_index = content.length
|
52
|
+
else
|
53
|
+
edges = content[edges_def_index+1..content.length]
|
54
|
+
end
|
55
|
+
|
56
|
+
fields_split = /[\t ]*,[\t ]*/
|
57
|
+
|
58
|
+
# only nodes lines
|
59
|
+
nodes = content[nodes_def_index+1..[edges_def_index-1, content.length].min] || []
|
60
|
+
|
61
|
+
nodes_def = content[nodes_def_index]
|
62
|
+
nodes_def = nodes_def['nodedef>'.length..nodes_def.length].strip.split(fields_split)
|
63
|
+
nodes_def.each_index {|i|
|
64
|
+
nodes_def[i] = read_def(nodes_def[i])
|
65
|
+
}
|
66
|
+
|
67
|
+
nodes.each_with_index {|n,i|
|
68
|
+
n2 = {}
|
69
|
+
n = n.split(fields_split)
|
70
|
+
n.zip(nodes_def).each {|val,label_type|
|
71
|
+
label, type = label_type
|
72
|
+
n2[label] = parse_field(val, type)
|
73
|
+
}
|
74
|
+
nodes[i] = n2
|
75
|
+
}
|
76
|
+
|
77
|
+
if (edges === [])
|
78
|
+
return Graph.new(nodes)
|
79
|
+
end
|
80
|
+
|
81
|
+
# only edges lines
|
82
|
+
edges_def = content[edges_def_index]
|
83
|
+
edges_def = edges_def['edgedef>'.length..edges_def.length].strip.split(fields_split)
|
84
|
+
edges_def.each_index {|i|
|
85
|
+
edges_def[i] = read_def(edges_def[i])
|
86
|
+
}
|
87
|
+
|
88
|
+
edges.each_with_index {|e,i|
|
89
|
+
e2 = {}
|
90
|
+
e = e.split(fields_split)
|
91
|
+
|
92
|
+
e.zip(edges_def).each {|val,label_type|
|
93
|
+
label, type = label_type
|
94
|
+
e2[label] = parse_field(val, type)
|
95
|
+
}
|
96
|
+
edges[i] = e2
|
97
|
+
}
|
98
|
+
|
99
|
+
Graph.new(nodes, edges)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.unparse(graph, opts=nil)
|
103
|
+
|
104
|
+
# nodes
|
105
|
+
gdf_s = 'nodedef>'
|
106
|
+
|
107
|
+
if (graph.nodes.length == 0)
|
108
|
+
return gdf_s
|
109
|
+
end
|
110
|
+
|
111
|
+
keys = graph.nodes[0].keys
|
112
|
+
nodedef = keys.map { |k| [k, self.get_type(graph.nodes[0][k], opts)] }
|
113
|
+
|
114
|
+
gdf_s += (nodedef.map {|nd| nd.join(' ')}).join(',') + "\n"
|
115
|
+
|
116
|
+
graph.nodes.each { |n|
|
117
|
+
gdf_s += n.values.join(',') + "\n"
|
118
|
+
}
|
119
|
+
|
120
|
+
# edges
|
121
|
+
gdf_s += 'edgedef>'
|
122
|
+
|
123
|
+
if (graph.edges.length == 0)
|
124
|
+
return gdf_s
|
125
|
+
end
|
126
|
+
|
127
|
+
keys = graph.edges[0].keys
|
128
|
+
edgedef = keys.map { |k| [k, self.get_type(graph.edges[0][k], opts)] }
|
129
|
+
|
130
|
+
gdf_s += (edgedef.map {|ed| ed.join(' ')}).join(',') + "\n"
|
131
|
+
|
132
|
+
graph.edges.each { |e|
|
133
|
+
gdf_s += e.values.join(',') + "\n"
|
134
|
+
}
|
135
|
+
|
136
|
+
gdf_s
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
# read the value of a node|edge field, and return the value's type (String)
|
142
|
+
def self.get_type(v, opts=nil)
|
143
|
+
opts = opts || {}
|
144
|
+
|
145
|
+
if v.is_a?(Fixnum)
|
146
|
+
return 'INT'
|
147
|
+
elsif v.is_a?(Bignum)
|
148
|
+
return opts[:gephi] ? 'INT' : 'BIGINT'
|
149
|
+
elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
150
|
+
return 'BOOLEAN'
|
151
|
+
elsif v.is_a?(Float)
|
152
|
+
return 'FLOAT'
|
153
|
+
else
|
154
|
+
return 'VARCHAR'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# read a (node|edge)def, and return ['label', 'type of value']
|
159
|
+
def self.read_def(s)
|
160
|
+
*label, value_type = s.split /\s+/
|
161
|
+
if /((tiny|small|medium|big)?int|integer)/i.match(value_type)
|
162
|
+
value_type = 'int'
|
163
|
+
elsif /(float|real|double)/i.match(value_type)
|
164
|
+
value_type = 'float'
|
165
|
+
elsif (value_type.downcase === 'boolean')
|
166
|
+
value_type = 'boolean'
|
167
|
+
end
|
168
|
+
|
169
|
+
[label.join(' '), value_type]
|
170
|
+
end
|
171
|
+
|
172
|
+
# read a field and return its value
|
173
|
+
def self.parse_field(f, value_type)
|
174
|
+
case value_type
|
175
|
+
when 'int' then f.to_i
|
176
|
+
when 'float' then f.to_f
|
177
|
+
when 'boolean' then !(/(null|false)/i =~ f)
|
178
|
+
else f
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
data/tests/tests_gdf.rb
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
#! /usr/bin/ruby1.9.1
|
2
|
+
|
3
|
+
require '../lib/graph'
|
4
|
+
require '../lib/graphes/gdf'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
module Utils
|
8
|
+
def self.get_sample_graph
|
9
|
+
@@sample_graph_1
|
10
|
+
end
|
11
|
+
|
12
|
+
@@sample_graph_1 = "nodedef>label VARCHAR,num INT,biglabel VARCHAR\n"
|
13
|
+
@@sample_graph_1 += "toto,14,TOTO\nlala,5,LALA\ntiti,988,TITI\n"
|
14
|
+
@@sample_graph_1 += "edgedef>node1 VARCHAR,node2 VARCHAR,directed BOOLEAN\n"
|
15
|
+
@@sample_graph_1 += "toto,lala,true\nlala,titi,true\n"
|
16
|
+
@@sample_graph_1 += "titi,lala,false\ntiti,toto,true\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
class GDF_Graph_test < Test::Unit::TestCase
|
20
|
+
|
21
|
+
# == Graph#to_gdf == #
|
22
|
+
|
23
|
+
def test_empty_graph_to_gdf
|
24
|
+
g = Graph.new
|
25
|
+
empty_gdf = "nodedef>"
|
26
|
+
|
27
|
+
assert_equal(empty_gdf, g.to_gdf)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_sample_graph_to_gdf
|
31
|
+
gdf = Utils::get_sample_graph
|
32
|
+
g = GDF::parse(gdf)
|
33
|
+
assert_equal(gdf, g.to_gdf)
|
34
|
+
end
|
35
|
+
|
36
|
+
# == Graph#write('….gdf') == #
|
37
|
+
|
38
|
+
def test_empty_graph_write_gdf
|
39
|
+
g = Graph.new
|
40
|
+
g.write('/tmp/_graph_test.gdf')
|
41
|
+
g2 = GDF.load('/tmp/_graph_test.gdf')
|
42
|
+
assert_equal(g, g2)
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup
|
46
|
+
if File.exists? '/tmp/_graph_test.gdf'
|
47
|
+
File.delete '/tmp/_graph_test.gdf'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class GDF_test < Test::Unit::TestCase
|
53
|
+
|
54
|
+
# == GDF::parse == #
|
55
|
+
|
56
|
+
def test_parse_empty_graph
|
57
|
+
g = GDF::parse('')
|
58
|
+
|
59
|
+
assert_equal([], g.nodes)
|
60
|
+
assert_equal([], g.edges)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_parse_empty_graph_with_nodedef
|
64
|
+
|
65
|
+
s = "nodedef>label VARCHAR\n"
|
66
|
+
|
67
|
+
g = GDF::parse(s)
|
68
|
+
|
69
|
+
assert_equal([], g.nodes)
|
70
|
+
assert_equal([], g.edges)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_parse_empty_graph_with_nodedef_and_edgedef
|
74
|
+
s = "nodedef>label VARCHAR\nedgedef>node1 VARCHAR,node2 VARCHAR\n"
|
75
|
+
g = GDF::parse(s)
|
76
|
+
|
77
|
+
assert_equal([], g.nodes)
|
78
|
+
assert_equal([], g.edges)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_parse_one_node_no_edge_string_field
|
82
|
+
s = "nodedef>label VARCHAR\nfoo\n"
|
83
|
+
g = GDF::parse(s)
|
84
|
+
|
85
|
+
assert_equal(1, g.nodes.length)
|
86
|
+
assert_equal('foo', g.nodes[0]['label'])
|
87
|
+
assert_equal([], g.edges)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_parse_one_node_no_edge_tinyint_field
|
91
|
+
s = "nodedef>num TINYINT\n3\n"
|
92
|
+
g = GDF::parse(s)
|
93
|
+
|
94
|
+
assert_equal(1, g.nodes.length)
|
95
|
+
assert_equal(3, g.nodes[0]['num'])
|
96
|
+
assert_equal([], g.edges)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_parse_one_node_no_edge_smallint_field
|
100
|
+
s = "nodedef>num SMALLINT\n3\n"
|
101
|
+
g = GDF::parse(s)
|
102
|
+
|
103
|
+
assert_equal(1, g.nodes.length)
|
104
|
+
assert_equal(3, g.nodes[0]['num'])
|
105
|
+
assert_equal([], g.edges)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_parse_one_node_no_edge_int_field
|
109
|
+
s = "nodedef>num INT\n3\n"
|
110
|
+
g = GDF::parse(s)
|
111
|
+
|
112
|
+
assert_equal(1, g.nodes.length)
|
113
|
+
assert_equal(3, g.nodes[0]['num'])
|
114
|
+
assert_equal([], g.edges)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_parse_one_node_no_edge_negative_int_field
|
118
|
+
s = "nodedef>num INT\n-1337\n"
|
119
|
+
g = GDF::parse(s)
|
120
|
+
|
121
|
+
assert_equal(1, g.nodes.length)
|
122
|
+
assert_equal(-1337, g.nodes[0]['num'])
|
123
|
+
assert_equal([], g.edges)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_parse_one_node_no_edge_bigint_field
|
127
|
+
s = "nodedef>num BIGINT\n3\n"
|
128
|
+
g = GDF::parse(s)
|
129
|
+
|
130
|
+
assert_equal(1, g.nodes.length)
|
131
|
+
assert_equal(3, g.nodes[0]['num'])
|
132
|
+
assert_equal([], g.edges)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_parse_one_node_no_edge_float_field
|
136
|
+
s = "nodedef>num FLOAT\n3\n"
|
137
|
+
g = GDF::parse(s)
|
138
|
+
|
139
|
+
assert_equal(1, g.nodes.length)
|
140
|
+
assert_equal(3.0, g.nodes[0]['num'])
|
141
|
+
assert_equal([], g.edges)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_parse_one_node_no_edge_double_field
|
145
|
+
s = "nodedef>num FLOAT\n3\n"
|
146
|
+
g = GDF::parse(s)
|
147
|
+
|
148
|
+
assert_equal(1, g.nodes.length)
|
149
|
+
assert_equal(3.0, g.nodes[0]['num'])
|
150
|
+
assert_equal([], g.edges)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_parse_one_node_no_edge_real_field
|
154
|
+
s = "nodedef>num FLOAT\n3\n"
|
155
|
+
g = GDF::parse(s)
|
156
|
+
|
157
|
+
assert_equal(1, g.nodes.length)
|
158
|
+
assert_equal(3.0, g.nodes[0]['num'])
|
159
|
+
assert_equal([], g.edges)
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_parse_one_node_no_edge_negative_real_field
|
163
|
+
s = "nodedef>num FLOAT\n-42.14\n"
|
164
|
+
g = GDF::parse(s)
|
165
|
+
|
166
|
+
assert_equal(1, g.nodes.length)
|
167
|
+
assert_equal(-42.14, g.nodes[0]['num'])
|
168
|
+
assert_equal([], g.edges)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_parse_one_node_no_edge_unknow_field_type
|
172
|
+
s = "nodedef>foo BAR\nfoobar"
|
173
|
+
g = GDF::parse(s)
|
174
|
+
|
175
|
+
assert_equal(1, g.nodes.length)
|
176
|
+
assert_equal('foobar', g.nodes[0]['foo'])
|
177
|
+
assert_equal([], g.edges)
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_parse_sample_graph
|
181
|
+
g = GDF::parse(Utils::get_sample_graph)
|
182
|
+
|
183
|
+
assert_equal(3, g.nodes.length)
|
184
|
+
assert_equal(4, g.edges.length)
|
185
|
+
|
186
|
+
assert_equal('toto', g.nodes[0]['label'])
|
187
|
+
assert_equal('TOTO', g.nodes[0]['biglabel'])
|
188
|
+
assert_equal(988, g.nodes[2]['num'])
|
189
|
+
|
190
|
+
assert_equal('toto', g.edges[0]['node1'])
|
191
|
+
assert_equal('lala', g.edges[0]['node2'])
|
192
|
+
assert_equal(false, g.edges[2]['directed'])
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
# == GDF::unparse == #
|
197
|
+
|
198
|
+
def test_unparse_empty_graph
|
199
|
+
g = Graph.new
|
200
|
+
|
201
|
+
s = GDF::unparse(g)
|
202
|
+
|
203
|
+
assert_equal("nodedef>", s)
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_unparse_sample_graph
|
207
|
+
g1 = GDF::parse(Utils::get_sample_graph)
|
208
|
+
g2 = GDF::parse(GDF::unparse(g1))
|
209
|
+
|
210
|
+
assert_equal(g1, g2)
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_unparse_big_int_gephi
|
214
|
+
g = Graph.new([{'n'=>9999999999999999}])
|
215
|
+
gdf = GDF::unparse(g, {:gephi=>true})
|
216
|
+
|
217
|
+
assert_equal("nodedef>n INT\n9999999999999999\nedgedef>", gdf)
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
data/tests/tests_gexf.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
#! /usr/bin/ruby1.9.1
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'yaml'
|
6
|
+
require_relative '../lib/graph'
|
7
|
+
|
8
|
+
class Graph_test < Test::Unit::TestCase
|
9
|
+
|
10
|
+
@@sample_graph = Graph.new(
|
11
|
+
[
|
12
|
+
{'label'=>'foo', 'id'=>2},
|
13
|
+
{'label'=>'bar', 'id'=>1},
|
14
|
+
{'label'=>'chuck', 'id'=>3}
|
15
|
+
],
|
16
|
+
[
|
17
|
+
{'node1'=>'foo', 'node2'=>'bar'},
|
18
|
+
{'node1'=>'bar', 'node2'=>'foo'},
|
19
|
+
{'node1'=>'bar', 'node2'=>'chuck'},
|
20
|
+
{'node1'=>'foo', 'node2'=>'chuck'}
|
21
|
+
]
|
22
|
+
)
|
23
|
+
|
24
|
+
def test_new_empty_graph
|
25
|
+
g = Graph.new
|
26
|
+
|
27
|
+
assert_equal([], g.nodes)
|
28
|
+
assert_equal([], g.edges)
|
29
|
+
end
|
30
|
+
|
31
|
+
# == Graph#== == #
|
32
|
+
|
33
|
+
def test_equal_graphs
|
34
|
+
g1 = @@sample_graph
|
35
|
+
g2 = @@sample_graph.clone()
|
36
|
+
|
37
|
+
assert_equal(true, g1==g2)
|
38
|
+
end
|
39
|
+
|
40
|
+
# == Graph::NodeArray#set_default == #
|
41
|
+
|
42
|
+
def test_nodearray_set_default_unexisting_property
|
43
|
+
g = Graph.new([{'name'=>'foo'}, {'name'=>'bar'}])
|
44
|
+
g.nodes.set_default 'age' => 21
|
45
|
+
|
46
|
+
assert_equal(21, g.nodes[0]['age'])
|
47
|
+
assert_equal(21, g.nodes[1]['age'])
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_nodearray_set_default_existing_property
|
51
|
+
g = Graph.new([{'name'=>'foo', 'age'=>42}, {'name'=>'bar'}])
|
52
|
+
g.nodes.set_default 'age' => 21
|
53
|
+
|
54
|
+
assert_equal(21, g.nodes[0]['age'])
|
55
|
+
assert_equal(21, g.nodes[1]['age'])
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_nodearray_set_default_unexisting_property_before_push
|
59
|
+
g = Graph.new([{'name'=>'foo'}])
|
60
|
+
g.nodes.set_default 'city' => 'Paris'
|
61
|
+
g.nodes.push({'name' => 'bar'})
|
62
|
+
|
63
|
+
assert_equal('Paris', g.nodes[0]['city'])
|
64
|
+
assert_equal('Paris', g.nodes[0]['city'])
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_nodearray_set_default_existing_property_before_push
|
68
|
+
g = Graph.new([{'name'=>'foo', 'city'=>'London'}])
|
69
|
+
g.nodes.set_default 'city' => 'Paris'
|
70
|
+
g.nodes.push({'name' => 'bar'})
|
71
|
+
|
72
|
+
assert_equal('Paris', g.nodes[0]['city'])
|
73
|
+
assert_equal('Paris', g.nodes[0]['city'])
|
74
|
+
end
|
75
|
+
|
76
|
+
# == Graph::edgeArray#set_default == #
|
77
|
+
|
78
|
+
def test_edgearray_set_default_unexisting_property
|
79
|
+
g = Graph.new([],[{'node1'=>'foo', 'node2'=>'bar'}])
|
80
|
+
g.edges.set_default 'directed' => true
|
81
|
+
|
82
|
+
assert_equal(true, g.edges[0]['directed'])
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_edgearray_set_default_existing_property
|
86
|
+
g = Graph.new([],
|
87
|
+
[{'node1'=>'foo', 'node2'=>'bar', 'directed'=>true},
|
88
|
+
{'node1'=>'bar', 'node2'=>'foo'}])
|
89
|
+
g.edges.set_default 'directed' => false
|
90
|
+
|
91
|
+
assert_equal(false, g.edges[0]['directed'])
|
92
|
+
assert_equal(false, g.edges[1]['directed'])
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_edgearray_set_default_unexisting_property_before_push
|
96
|
+
g = Graph.new([], [{'node1'=>'foo', 'node2'=>'bar'}])
|
97
|
+
g.edges.set_default 'directed' => true
|
98
|
+
g.edges.push({'node1' => 'bar', 'node2'=>'foo'})
|
99
|
+
|
100
|
+
assert_equal(true, g.edges[0]['directed'])
|
101
|
+
assert_equal(true, g.edges[0]['directed'])
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_edgearray_set_default_existing_property_before_push
|
105
|
+
g = Graph.new([],
|
106
|
+
[{'node1'=>'foo', 'node2'=>'bar', 'directed'=>true}])
|
107
|
+
g.edges.set_default 'node2' => 'foo'
|
108
|
+
g.edges.push({'node1' => 'bar', 'node2' => 'foo'})
|
109
|
+
|
110
|
+
assert_equal('foo', g.edges[0]['node2'])
|
111
|
+
assert_equal('foo', g.edges[0]['node2'])
|
112
|
+
end
|
113
|
+
|
114
|
+
# == Graph#& == #
|
115
|
+
|
116
|
+
def test_empty_graph_AND_empty_graph
|
117
|
+
g1 = Graph.new
|
118
|
+
g2 = Graph.new
|
119
|
+
|
120
|
+
assert_equal(g1, g1 & g2)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_one_node_graph_AND_empty_graph
|
124
|
+
g = Graph.new([{'label'=>'foo'}])
|
125
|
+
empty = Graph.new
|
126
|
+
|
127
|
+
assert_equal(empty, g & empty)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_empty_graph_AND_one_node_graph
|
131
|
+
g = Graph.new([{'label'=>'foo'}])
|
132
|
+
empty = Graph.new
|
133
|
+
|
134
|
+
assert_equal(empty, empty & g)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_sample_graph_AND_itself
|
138
|
+
g = @@sample_graph
|
139
|
+
|
140
|
+
assert_equal(g, g & g)
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_one_node_graph_AND_one_other_node_graph
|
144
|
+
g = Graph.new([{'label'=>'foo'}])
|
145
|
+
h = Graph.new([{'label'=>'bar'}])
|
146
|
+
empty = Graph.new
|
147
|
+
|
148
|
+
assert_equal(empty, g & h)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_sample_graph_AND_no_graph
|
152
|
+
g = @@sample_graph
|
153
|
+
|
154
|
+
assert_equal(nil, g & 2)
|
155
|
+
assert_equal(nil, g & true)
|
156
|
+
assert_equal(nil, g & false)
|
157
|
+
assert_equal(nil, g & ['foo', 'bar'])
|
158
|
+
assert_equal(nil, g & {'foo'=>'bar'})
|
159
|
+
assert_equal(nil, g & 'foo')
|
160
|
+
end
|
161
|
+
|
162
|
+
# == Graph#write == #
|
163
|
+
|
164
|
+
def test_graph_write_no_ext
|
165
|
+
g = @@sample_graph
|
166
|
+
f = '/tmp/_graph_test'
|
167
|
+
g.write(f)
|
168
|
+
assert_equal(true, File.exists?(f))
|
169
|
+
|
170
|
+
dict = YAML.load(File.open(f))
|
171
|
+
assert_equal(g.nodes, dict['nodes'])
|
172
|
+
assert_equal(g.edges, dict['edges'])
|
173
|
+
end
|
174
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: x86-linux
|
7
|
+
authors:
|
8
|
+
- Baptiste Fontaine
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Provide functions to (un)parse GDF files and generate graphs
|
15
|
+
email: batifon@yahoo.fr
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/graph.rb
|
21
|
+
- lib/graphs/gdf.rb
|
22
|
+
- tests/tests_gexf.rb
|
23
|
+
- tests/tests_graph.rb
|
24
|
+
- tests/tests_gdf.rb
|
25
|
+
homepage: https://github.com/bfontaine/Graph.rb
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 1.8.24
|
47
|
+
signing_key:
|
48
|
+
specification_version: 3
|
49
|
+
summary: Utilities to manipulate graph files
|
50
|
+
test_files:
|
51
|
+
- tests/tests_gexf.rb
|
52
|
+
- tests/tests_graph.rb
|
53
|
+
- tests/tests_gdf.rb
|