graphs 0.1.0-x86-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|