mementus 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72100572fe7d20e4135b4663a269a8d2bd73cc80
4
- data.tar.gz: 0b337f00327f6090a323f91eb5450f4f80c692c6
3
+ metadata.gz: 3d0e0ff3ecc407016774cd2c78afd992296f7a4a
4
+ data.tar.gz: 0a9d6fcedc13f06dbec244662182cfa0a319fcab
5
5
  SHA512:
6
- metadata.gz: 271a2b5486669883f8ea63c1cd615418195628481dcc1e939511e218bed016032a03b66cc19d03bb2bb856d603223c5a70fc43d45f0f2e7a9e22eeb76f10b063
7
- data.tar.gz: b641562129543c2db046c924ad6fbcabc3cc033bdebe3f127c819ddec5af18ab8d907921f59ac505b20fb66456067b6c65ba67d54aa6125e7914ff31cd6b2a02
6
+ metadata.gz: 3c8c9a6a494b072019580ad80edf5ddcdf15781b0269e747bf615e9c8eb90235c59d7453daf4b90323ae0bd588565d09b7bbfa742459952f6c8f47a7e8c8ce7a
7
+ data.tar.gz: 93e7943eca3b04fb38eb957a0cc6c453e6065fefc7137c895279117ff1d8f66920ff18de51582cd920392424895852a0aa017a9007d74efa0917450370b37588
@@ -13,7 +13,7 @@ module Mementus
13
13
  private
14
14
 
15
15
  def visit(id, &block)
16
- @graph.each_adjacent(id) do |adj_node|
16
+ @graph.adjacent(id).each do |adj_node|
17
17
  next if @visited[adj_node.id]
18
18
 
19
19
  @visited[adj_node.id] = true
@@ -0,0 +1,32 @@
1
+ module Mementus
2
+ class EdgeProxy
3
+ def initialize(edge, graph)
4
+ @edge = edge
5
+ @graph = graph
6
+ end
7
+
8
+ def id
9
+ @edge.id
10
+ end
11
+
12
+ def label
13
+ @edge.label
14
+ end
15
+
16
+ def [](prop)
17
+ @edge[prop]
18
+ end
19
+
20
+ def props
21
+ @edge.props
22
+ end
23
+
24
+ def from
25
+ @graph.node(@edge.from.id)
26
+ end
27
+
28
+ def to
29
+ @graph.node(@edge.to.id)
30
+ end
31
+ end
32
+ end
@@ -52,20 +52,24 @@ module Mementus
52
52
  @structure.nodes(match)
53
53
  end
54
54
 
55
- def adjacent(id)
56
- @structure.adjacent(id)
55
+ def adjacent(id, match=nil)
56
+ @structure.adjacent(id, match)
57
57
  end
58
58
 
59
- def adjacent_edges(id)
60
- @structure.adjacent_edges(id)
59
+ def incoming(id, match=nil)
60
+ @structure.incoming(id, match)
61
61
  end
62
62
 
63
- def each_node(&blk)
64
- @structure.each_node(&blk)
63
+ def adjacent_edges(id, match=nil)
64
+ @structure.adjacent_edges(id, match)
65
+ end
66
+
67
+ def incoming_edges(id, match=nil)
68
+ @structure.incoming_edges(id, match)
65
69
  end
66
70
 
67
- def each_adjacent(node, &blk)
68
- @structure.each_adjacent(node, &blk)
71
+ def each_node(&blk)
72
+ @structure.each_node(&blk)
69
73
  end
70
74
 
71
75
  def each_edge(&blk)
@@ -21,20 +21,28 @@ module Mementus
21
21
  @node.props
22
22
  end
23
23
 
24
+ def out
25
+ Pipeline::Step.new([self], Pipeline::Pipe.new(@graph), @graph).out_e
26
+ end
27
+
24
28
  def out_e
25
- Pipeline::Step.new(adjacent_edges, Pipeline::Pipe.new(@graph), @graph)
29
+ Pipeline::Step.new([self], Pipeline::Pipe.new(@graph), @graph).out_e
26
30
  end
27
31
 
28
32
  def each_adjacent(&block)
29
33
  @graph.each_adjacent(@node.id, &block)
30
34
  end
31
35
 
32
- def adjacent
33
- @graph.adjacent(@node.id)
36
+ def adjacent(match=nil)
37
+ @graph.adjacent(@node.id, match)
38
+ end
39
+
40
+ def incoming(match=nil)
41
+ @graph.incoming(@node.id, match)
34
42
  end
35
43
 
36
- def adjacent_edges
37
- @graph.adjacent_edges(@node.id)
44
+ def adjacent_edges(match=nil)
45
+ @graph.adjacent_edges(@node.id, match)
38
46
  end
39
47
  end
40
48
  end
@@ -58,51 +58,36 @@ module Mementus
58
58
  end
59
59
 
60
60
  # Traverse to the outgoing nodes adjacent to the source elements.
61
- def out
61
+ def out(match=nil)
62
62
  outgoing_nodes = source.inject([]) do |result, node|
63
- result.concat(node.adjacent)
63
+ result.concat(node.adjacent(match))
64
64
  end
65
65
 
66
66
  Step.new(outgoing_nodes)
67
67
  end
68
68
 
69
69
  # Traverse to the incoming nodes pointing to the source elements.
70
- def in
71
- incoming_nodes = []
72
-
73
- source.each do |node|
74
- graph.each_node do |graph_node|
75
- graph.each_adjacent(graph_node.id) do |adj_node|
76
- incoming_nodes << graph_node if adj_node.id == node.id
77
- end
78
- end
70
+ def in(match=nil)
71
+ incoming_nodes = source.inject([]) do |result, node|
72
+ result.concat(node.incoming(match))
79
73
  end
80
74
 
81
75
  Step.new(incoming_nodes)
82
76
  end
83
77
 
84
78
  # Traverse to the outgoing edges from the source elements.
85
- def out_e
86
- outgoing_edges = []
87
-
88
- source.each do |node|
89
- outgoing_edges = graph.each_adjacent(node.id).map do |id|
90
- Mementus::Edge.new(from: node, to: id)
91
- end
79
+ def out_e(match=nil)
80
+ outgoing_edges = source.inject([]) do |result, node|
81
+ result.concat(graph.adjacent_edges(node.id, match))
92
82
  end
93
83
 
94
84
  Step.new(outgoing_edges)
95
85
  end
96
86
 
97
87
  # Traverse to the incoming edges pointing to the source elements.
98
- def in_e
99
- ids = source.map(&:id)
100
- incoming_edges = []
101
-
102
- graph.each_node do |graph_node|
103
- graph.each_adjacent(graph_node.id) do |adj_node|
104
- incoming_edges << Mementus::Edge.new(from: graph_node, to: adj_node) if ids.include?(adj_node.id)
105
- end
88
+ def in_e(match=nil)
89
+ incoming_edges = source.inject([]) do |result, node|
90
+ result.concat(graph.incoming_edges(node.id, match))
106
91
  end
107
92
 
108
93
  Step.new(incoming_edges)
@@ -52,19 +52,11 @@ module Mementus
52
52
  @index[id].to_a
53
53
  end
54
54
 
55
- def each_node(&blk)
56
- nodes.each(&blk)
57
- end
58
-
59
- def each_adjacent(id, &blk)
60
- @index[id].each(&blk)
61
- end
62
-
63
55
  def each_edge(&blk)
64
56
  if directed?
65
- each_node do |from|
66
- each_adjacent(from.id) do |to|
67
- yield Edge.new(from: from, to: to)
57
+ nodes.each do |from|
58
+ adjacent(from.id).each do |to|
59
+ yield EdgeProxy.new(Edge.new(from: from, to: to), self)
68
60
  end
69
61
  end
70
62
  else
@@ -43,7 +43,7 @@ module Mementus
43
43
  set_node(edge.from) unless has_node?(edge.from)
44
44
  set_node(edge.to) unless has_node?(edge.to)
45
45
 
46
- @edges[edge.id] = edge
46
+ @edges[edge.id] = EdgeProxy.new(edge, self)
47
47
  @outgoing[edge.from.id] << edge.to.id
48
48
  @incoming[edge.to.id] << edge.from.id
49
49
  @outgoing_e[edge.from.id] << edge.id
@@ -58,10 +58,6 @@ module Mementus
58
58
  @nodes[id]
59
59
  end
60
60
 
61
- def each_node(&block)
62
- @nodes.values.each(&block)
63
- end
64
-
65
61
  def nodes(match=nil)
66
62
  return @nodes.values unless match
67
63
 
@@ -94,16 +90,62 @@ module Mementus
94
90
  end
95
91
  end
96
92
 
97
- def adjacent(id)
98
- @nodes.values_at(*@outgoing[id])
93
+ def adjacent(id, match=nil, direction=:out)
94
+ directional_index = case direction
95
+ when :out then @outgoing
96
+ when :in then @incoming
97
+ end
98
+
99
+ return @nodes.values_at(*directional_index[id]) unless match
100
+
101
+ if match.is_a?(Hash)
102
+ @nodes.values_at(*directional_index[id]).select do |node|
103
+ key = match.first.first
104
+ val = match.first.last
105
+ node[key] == val
106
+ end
107
+ elsif match.is_a?(Symbol)
108
+ @nodes.values_at(*directional_index[id]).select do |node|
109
+ node.label == match
110
+ end
111
+ end
112
+ end
113
+
114
+ def outgoing(id, match=nil)
115
+ adjacent(id, match, :out)
116
+ end
117
+
118
+ def incoming(id, match=nil)
119
+ adjacent(id, match, :in)
120
+ end
121
+
122
+ def adjacent_edges(id, match=nil, direction=:out)
123
+ directional_index = case direction
124
+ when :out then @outgoing_e
125
+ when :in then @incoming_e
126
+ end
127
+
128
+ return @edges.values_at(*directional_index[id]) unless match
129
+
130
+ if match.is_a?(Hash)
131
+ @edges.values_at(*directional_index[id]).select do |edge|
132
+ key = match.first.first
133
+ val = match.first.last
134
+ edge[key] == val
135
+ end
136
+ elsif match.is_a?(Symbol)
137
+ @edges.values_at(*directional_index[id]).select do |edge|
138
+ edge.label == match
139
+ end
140
+ end
99
141
  end
100
142
 
101
- def each_adjacent(id, &blk)
102
- adjacent(id).each(&blk)
143
+ def outgoing_edges(id, match=nil)
144
+ adjacent_edges(id, match, :out)
103
145
  end
104
146
 
105
- def adjacent_edges(id)
106
- @edges.values_at(*@outgoing_e[id])
147
+ def incoming_edges(id, match=nil)
148
+ adjacent_edges(id, match, :in)
107
149
  end
108
150
  end
109
151
  end
@@ -1,3 +1,3 @@
1
1
  module Mementus
2
- VERSION = '0.5.5'.freeze
2
+ VERSION = '0.5.6'.freeze
3
3
  end
data/lib/mementus.rb CHANGED
@@ -5,6 +5,7 @@ require 'mementus/structure/incidence_list'
5
5
  require 'mementus/node'
6
6
  require 'mementus/edge'
7
7
  require 'mementus/node_proxy'
8
+ require 'mementus/edge_proxy'
8
9
  require 'mementus/pipeline/pipe'
9
10
  require 'mementus/pipeline/filter'
10
11
  require 'mementus/pipeline/transform'
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mementus::EdgeProxy do
4
+ let(:graph) do
5
+ Mementus::Graph.new do
6
+ set_edge(edge_1_2)
7
+ set_edge(edge_1_3)
8
+ end
9
+ end
10
+
11
+ specify '#from' do
12
+ edge_proxy = Mementus::EdgeProxy.new(edge_1_2, graph)
13
+ expect(edge_proxy.from.id).to eq(node_1.id)
14
+ end
15
+
16
+ specify '#to' do
17
+ edge_proxy = Mementus::EdgeProxy.new(edge_1_2, graph)
18
+ expect(edge_proxy.to.id).to eq(node_2.id)
19
+ end
20
+ end
@@ -26,6 +26,7 @@ describe 'pipeline api' do
26
26
  edge.from = 1
27
27
  edge.to = 2
28
28
  edge.label = :choice
29
+ edge.props[:name] = 'e3'
29
30
  end
30
31
 
31
32
  create_edge do |edge|
@@ -33,55 +34,114 @@ describe 'pipeline api' do
33
34
  edge.from = 2
34
35
  edge.to = 4
35
36
  edge.label = :choice
37
+ edge.props[:name] = 'e5'
36
38
  end
37
39
  end
38
40
  end
39
41
 
40
- it 'traverses from the given node id' do
41
- pipeline = graph.n(1)
42
- expect(pipeline.id).to eq(1)
43
- expect(pipeline.first.id).to eq(1)
44
- end
42
+ describe '#n' do
43
+ it 'traverses from the given node id' do
44
+ pipeline = graph.n(1)
45
+ expect(pipeline.id).to eq(1)
46
+ expect(pipeline.first.id).to eq(1)
47
+ end
45
48
 
46
- it 'traverses from the given node match' do
47
- pipeline = graph.n(name: 'one')
48
- expect(pipeline.id).to eq(1)
49
- expect(pipeline.first.id).to eq(1)
50
- end
49
+ it 'traverses from the given label match' do
50
+ pipeline = graph.n(:passage)
51
+ expect(pipeline.id).to eq([1, 2, 4])
52
+ expect(pipeline.first.id).to eq(1)
53
+ end
51
54
 
52
- it 'traverses from the given label match' do
53
- pipeline = graph.n(:passage)
54
- expect(pipeline.id).to eq([1, 2, 4])
55
- expect(pipeline.first.id).to eq(1)
55
+ it 'traverses from the given prop match' do
56
+ pipeline = graph.n(name: 'one')
57
+ expect(pipeline.id).to eq(1)
58
+ expect(pipeline.first.id).to eq(1)
59
+ end
56
60
  end
57
61
 
58
- it 'traverses to outgoing nodes' do
59
- pipeline = graph.n(1).out
60
- expect(pipeline.all.count).to eq(1)
61
- expect(pipeline.all.first.id).to eq(2)
62
- end
62
+ describe '#out' do
63
+ it 'traverses to outgoing nodes' do
64
+ pipeline = graph.n(1).out
65
+ expect(pipeline.all.count).to eq(1)
66
+ expect(pipeline.all.first.id).to eq(2)
67
+ end
63
68
 
64
- it 'traverses to second-degree outgoing nodes' do
65
- pipeline = graph.n(1).out.out
66
- expect(pipeline.all.count).to eq(1)
67
- expect(pipeline.all.first.id).to eq(4)
69
+ it 'traverses to outgoing nodes matching label' do
70
+ pipeline = graph.n(1).out(:passage)
71
+ expect(pipeline.all.count).to eq(1)
72
+ expect(pipeline.all.first.id).to eq(2)
73
+ end
74
+
75
+ it 'traverses to outgoing nodes matching filter' do
76
+ pipeline = graph.n(1).out(name: 'two')
77
+ expect(pipeline.all.count).to eq(1)
78
+ expect(pipeline.all.first.id).to eq(2)
79
+ end
80
+
81
+ it 'traverses to second-degree outgoing nodes' do
82
+ pipeline = graph.n(1).out.out
83
+ expect(pipeline.all.count).to eq(1)
84
+ expect(pipeline.all.first.id).to eq(4)
85
+ end
68
86
  end
69
87
 
70
- it 'traverses to outgoing edges' do
71
- pipeline = graph.n(1).out_e
72
- expect(pipeline.all.count).to eq(1)
73
- expect(pipeline.all.first.to.id).to eq(2)
88
+ describe '#out_e' do
89
+ it 'traverses to outgoing edges' do
90
+ pipeline = graph.n(1).out_e
91
+ expect(pipeline.all.count).to eq(1)
92
+ expect(pipeline.all.first.to.id).to eq(2)
93
+ end
94
+
95
+ it 'traverses to outgoing edges matching label' do
96
+ pipeline = graph.n(1).out_e(:choice)
97
+ expect(pipeline.all.count).to eq(1)
98
+ expect(pipeline.all.first.to.id).to eq(2)
99
+ end
100
+
101
+ it 'traverses to outgoing edges matching filter' do
102
+ pipeline = graph.n(1).out_e(name: 'e3')
103
+ expect(pipeline.all.count).to eq(1)
104
+ expect(pipeline.all.first.to.id).to eq(2)
105
+ end
74
106
  end
75
107
 
76
- it 'traverses to incoming nodes' do
77
- pipeline = graph.n(2).in
78
- expect(pipeline.all.count).to eq(1)
79
- expect(pipeline.all.first.id).to eq(1)
108
+ describe '#in' do
109
+ it 'traverses to incoming nodes' do
110
+ pipeline = graph.n(2).in
111
+ expect(pipeline.all.count).to eq(1)
112
+ expect(pipeline.all.first.id).to eq(1)
113
+ end
114
+
115
+ it 'traverses to incoming nodes matching label' do
116
+ pipeline = graph.n(2).in(:passage)
117
+ expect(pipeline.all.count).to eq(1)
118
+ expect(pipeline.all.first.id).to eq(1)
119
+ end
120
+
121
+ it 'traverses to incoming nodes matching filter' do
122
+ pipeline = graph.n(2).in(name: 'one')
123
+ expect(pipeline.all.count).to eq(1)
124
+ expect(pipeline.all.first.id).to eq(1)
125
+ end
80
126
  end
81
127
 
82
- it 'traverses to incoming edges' do
83
- pipeline = graph.n(2).in_e
84
- expect(pipeline.all.count).to eq(1)
85
- expect(pipeline.all.first.from.id).to eq(1)
128
+ describe '#in_e' do
129
+ it 'traverses to incoming edges' do
130
+ pipeline = graph.n(2).in_e
131
+ expect(pipeline.all.count).to eq(1)
132
+ expect(pipeline.all.first.from.id).to eq(1)
133
+ end
134
+
135
+ it 'traverses to incoming edges matching label' do
136
+ pipeline = graph.n(2).in_e(:choice)
137
+ expect(pipeline.all.count).to eq(1)
138
+ expect(pipeline.all.first.from.id).to eq(1)
139
+ end
140
+
141
+ it 'traverses to incoming edges matching filter' do
142
+ pipeline = graph.n(2).in_e(name: 'e3')
143
+ expect(pipeline.all.count).to eq(1)
144
+ expect(pipeline.all.first.from.id).to eq(1)
145
+ end
86
146
  end
87
147
  end
@@ -0,0 +1,9 @@
1
+ require_relative 'indexed_graph_example'
2
+
3
+ describe Mementus::Structure::AdjacencyList do
4
+ let(:structure) do
5
+ Mementus::Structure::AdjacencyList.new
6
+ end
7
+
8
+ it_behaves_like 'an indexed graph data structure'
9
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a directed graph data structure' do
4
+ it 'enumerates outgoing nodes from the given node' do
5
+ edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
6
+ structure.set_edge(edge)
7
+
8
+ expect(structure.outgoing(1).first.id).to eq(2)
9
+ end
10
+
11
+ it 'enumerates outgoing edges from the given node' do
12
+ edge = Mementus::Edge.new(id: 3, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
13
+ structure.set_edge(edge)
14
+
15
+ expect(structure.outgoing_edges(1).first.id).to eq(3)
16
+ end
17
+
18
+ it 'enumerates incoming nodes from the given node' do
19
+ edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
20
+ structure.set_edge(edge)
21
+
22
+ expect(structure.incoming(2).first.id).to eq(1)
23
+ end
24
+
25
+ it 'enumerates incoming edges from the given node' do
26
+ edge = Mementus::Edge.new(id: 3, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
27
+ structure.set_edge(edge)
28
+
29
+ expect(structure.incoming_edges(2).first.id).to eq(3)
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'indexed_graph_example'
2
+ require_relative 'directed_graph_example'
3
+ require_relative 'property_graph_example'
4
+
5
+ describe Mementus::Structure::IncidenceList do
6
+ let(:structure) do
7
+ Mementus::Structure::IncidenceList.new
8
+ end
9
+
10
+ it_behaves_like 'an indexed graph data structure'
11
+ it_behaves_like 'a directed graph data structure'
12
+ it_behaves_like 'a property graph data structure'
13
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "an indexed graph data structure" do
4
+ describe '#new' do
5
+ it 'starts with empty node list' do
6
+ expect(structure.nodes_count).to eq(0)
7
+ end
8
+
9
+ it 'starts with empty edge list' do
10
+ expect(structure.edges_count).to eq(0)
11
+ end
12
+ end
13
+
14
+ describe '#set_node' do
15
+ it 'assigns a node object to the graph' do
16
+ structure.set_node(Mementus::Node.new(id: 1))
17
+
18
+ expect(structure.nodes_count).to eq(1)
19
+ expect(structure.edges_count).to eq(0)
20
+ end
21
+ end
22
+
23
+ describe '#set_edge' do
24
+ it 'adds an edge object to the graph' do
25
+ structure.set_edge(Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2)))
26
+
27
+ expect(structure.nodes_count).to eq(2)
28
+ expect(structure.edges_count).to eq(1)
29
+ end
30
+ end
31
+
32
+ describe '#has_node?' do
33
+ it 'tests for the presence of a given node' do
34
+ node = Mementus::Node.new(id: 1)
35
+ structure.set_node(node)
36
+
37
+ expect(structure.has_node?(node)).to be true
38
+ end
39
+ end
40
+
41
+ describe '#has_edge?' do
42
+ it 'tests for the presence of a given edge' do
43
+ edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
44
+ structure.set_edge(edge)
45
+
46
+ expect(structure.has_edge?(edge)).to be true
47
+ end
48
+ end
49
+
50
+ describe '#node(id)' do
51
+ it 'finds a node by id' do
52
+ edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
53
+ structure.set_edge(edge)
54
+
55
+ expect(structure.node(1).id).to eq(edge.from.id)
56
+ end
57
+ end
58
+
59
+ describe '#nodes' do
60
+ it 'lists all nodes in the graph' do
61
+ edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
62
+ structure.set_edge(edge)
63
+
64
+ expect(structure.nodes.first.id).to eq(edge.from.id)
65
+ expect(structure.nodes.last.id).to eq(edge.to.id)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a property graph data structure' do
4
+ describe '#nodes(match)' do
5
+ it 'matches all nodes with the given prop' do
6
+ structure.set_node(Mementus::Node.new(id: 1, props: { tag: 'point'}))
7
+ structure.set_node(Mementus::Node.new(id: 2, props: { tag: 'point'}))
8
+ structure.set_node(Mementus::Node.new(id: 3))
9
+
10
+ structure.nodes(tag: 'point').tap do |matched|
11
+ expect(matched.first.id).to eq(1)
12
+ expect(matched.last.id).to eq(2)
13
+ end
14
+ end
15
+
16
+ it 'matches all nodes with the given label' do
17
+ structure.set_node(Mementus::Node.new(id: 1, label: :point))
18
+ structure.set_node(Mementus::Node.new(id: 2, label: :point))
19
+ structure.set_node(Mementus::Node.new(id: 3))
20
+
21
+ structure.nodes(:point).tap do |matched|
22
+ expect(matched.first.id).to eq(1)
23
+ expect(matched.last.id).to eq(2)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#edges' do
29
+ it 'lists all edges in the graph' do
30
+ edge = Mementus::Edge.new(id: 3, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
31
+ structure.set_edge(edge)
32
+
33
+ structure.edges.tap do |matched|
34
+ expect(matched.first.id).to eq(edge.id)
35
+ expect(matched.first.from.id).to eq(edge.from.id)
36
+ expect(matched.first.to.id).to eq(edge.to.id)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#edges(match)' do
42
+ it 'matches all edges with the given prop' do
43
+ edge = Mementus::Edge.new(props: { tag: 'link' }, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
44
+ structure.set_edge(edge)
45
+
46
+ structure.edges(tag: 'link').tap do |matched|
47
+ expect(matched.first.id).to eq(edge.id)
48
+ expect(matched.first.from.id).to eq(edge.from.id)
49
+ expect(matched.first.to.id).to eq(edge.to.id)
50
+ end
51
+ end
52
+
53
+ it 'matches all edges with the given label' do
54
+ edge = Mementus::Edge.new(label: :link, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
55
+ structure.set_edge(edge)
56
+
57
+ structure.edges(:link).tap do |matched|
58
+ expect(matched.first.id).to eq(edge.id)
59
+ expect(matched.first.from.id).to eq(edge.from.id)
60
+ expect(matched.first.to.id).to eq(edge.to.id)
61
+ end
62
+ end
63
+ end
64
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mementus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - maetl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-10 00:00:00.000000000 Z
11
+ date: 2016-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,6 +70,7 @@ files:
70
70
  - lib/mementus/direction.rb
71
71
  - lib/mementus/edge.rb
72
72
  - lib/mementus/edge_builder.rb
73
+ - lib/mementus/edge_proxy.rb
73
74
  - lib/mementus/element_builder.rb
74
75
  - lib/mementus/graph.rb
75
76
  - lib/mementus/graph_builder.rb
@@ -94,6 +95,7 @@ files:
94
95
  - lib/mementus/version.rb
95
96
  - mementus.gemspec
96
97
  - spec/direction_spec.rb
98
+ - spec/edge_proxy_spec.rb
97
99
  - spec/edge_spec.rb
98
100
  - spec/graph_spec.rb
99
101
  - spec/herschel_spec.rb
@@ -103,7 +105,11 @@ files:
103
105
  - spec/pipeline/step_spec.rb
104
106
  - spec/pipeline_spec.rb
105
107
  - spec/spec_helper.rb
106
- - spec/structure_spec.rb
108
+ - spec/structure/adjacency_list_spec.rb
109
+ - spec/structure/directed_graph_example.rb
110
+ - spec/structure/incidence_list_spec.rb
111
+ - spec/structure/indexed_graph_example.rb
112
+ - spec/structure/property_graph_example.rb
107
113
  - spec/traversal_spec.rb
108
114
  homepage: https://github.com/maetl/mementus
109
115
  licenses:
@@ -125,12 +131,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
131
  version: '0'
126
132
  requirements: []
127
133
  rubyforge_project:
128
- rubygems_version: 2.4.5
134
+ rubygems_version: 2.5.1
129
135
  signing_key:
130
136
  specification_version: 4
131
137
  summary: Graph data structure toolkit for Ruby applications.
132
138
  test_files:
133
139
  - spec/direction_spec.rb
140
+ - spec/edge_proxy_spec.rb
134
141
  - spec/edge_spec.rb
135
142
  - spec/graph_spec.rb
136
143
  - spec/herschel_spec.rb
@@ -140,5 +147,9 @@ test_files:
140
147
  - spec/pipeline/step_spec.rb
141
148
  - spec/pipeline_spec.rb
142
149
  - spec/spec_helper.rb
143
- - spec/structure_spec.rb
150
+ - spec/structure/adjacency_list_spec.rb
151
+ - spec/structure/directed_graph_example.rb
152
+ - spec/structure/incidence_list_spec.rb
153
+ - spec/structure/indexed_graph_example.rb
154
+ - spec/structure/property_graph_example.rb
144
155
  - spec/traversal_spec.rb
@@ -1,145 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "a mutable graph data structure" do
4
- describe '#new' do
5
- it 'starts with empty node list' do
6
- expect(structure.nodes_count).to eq(0)
7
- end
8
-
9
- it 'starts with empty edge list' do
10
- expect(structure.edges_count).to eq(0)
11
- end
12
- end
13
-
14
- describe '#set_node' do
15
- it 'assigns a node object to the graph' do
16
- structure.set_node(Mementus::Node.new(id: 1))
17
-
18
- expect(structure.nodes_count).to eq(1)
19
- expect(structure.edges_count).to eq(0)
20
- end
21
- end
22
-
23
- describe '#set_edge' do
24
- it 'adds an edge object to the graph' do
25
- structure.set_edge(Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2)))
26
-
27
- expect(structure.nodes_count).to eq(2)
28
- expect(structure.edges_count).to eq(1)
29
- end
30
- end
31
-
32
- describe '#has_node?' do
33
- it 'tests for the presence of a given node' do
34
- node = Mementus::Node.new(id: 1)
35
- structure.set_node(node)
36
-
37
- expect(structure.has_node?(node)).to be true
38
- end
39
- end
40
-
41
- describe '#has_edge?' do
42
- it 'tests for the presence of a given edge' do
43
- edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
44
- structure.set_edge(edge)
45
-
46
- expect(structure.has_edge?(edge)).to be true
47
- end
48
- end
49
-
50
- describe '#node(id)' do
51
- it 'finds a node by id' do
52
- edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
53
- structure.set_edge(edge)
54
-
55
- expect(structure.node(1).id).to eq(edge.from.id)
56
- end
57
- end
58
-
59
- describe '#nodes' do
60
- it 'lists all nodes in the graph' do
61
- edge = Mementus::Edge.new(from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
62
- structure.set_edge(edge)
63
-
64
- expect(structure.nodes.first.id).to eq(edge.from.id)
65
- expect(structure.nodes.last.id).to eq(edge.to.id)
66
- end
67
- end
68
- end
69
-
70
- describe Mementus::Structure::AdjacencyList do
71
- let(:structure) do
72
- Mementus::Structure::AdjacencyList.new
73
- end
74
-
75
- it_behaves_like "a mutable graph data structure"
76
- end
77
-
78
- describe Mementus::Structure::IncidenceList do
79
- let(:structure) do
80
- Mementus::Structure::IncidenceList.new
81
- end
82
-
83
- it_behaves_like "a mutable graph data structure"
84
-
85
- describe '#nodes(match)' do
86
- it 'matches all nodes with the given prop' do
87
- structure.set_node(Mementus::Node.new(id: 1, props: { tag: 'point'}))
88
- structure.set_node(Mementus::Node.new(id: 2, props: { tag: 'point'}))
89
- structure.set_node(Mementus::Node.new(id: 3))
90
-
91
- structure.nodes(tag: 'point').tap do |matched|
92
- expect(matched.first.id).to eq(1)
93
- expect(matched.last.id).to eq(2)
94
- end
95
- end
96
-
97
- it 'matches all nodes with the given label' do
98
- structure.set_node(Mementus::Node.new(id: 1, label: :point))
99
- structure.set_node(Mementus::Node.new(id: 2, label: :point))
100
- structure.set_node(Mementus::Node.new(id: 3))
101
-
102
- structure.nodes(:point).tap do |matched|
103
- expect(matched.first.id).to eq(1)
104
- expect(matched.last.id).to eq(2)
105
- end
106
- end
107
- end
108
-
109
- describe '#edges' do
110
- it 'lists all edges in the graph' do
111
- edge = Mementus::Edge.new(id: 3, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
112
- structure.set_edge(edge)
113
-
114
- structure.edges.tap do |matched|
115
- expect(matched.first.id).to eq(edge.id)
116
- expect(matched.first.from.id).to eq(edge.from.id)
117
- expect(matched.first.to.id).to eq(edge.to.id)
118
- end
119
- end
120
- end
121
-
122
- describe '#edges(match)' do
123
- it 'matches all edges with the given prop' do
124
- edge = Mementus::Edge.new(props: { tag: 'link' }, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
125
- structure.set_edge(edge)
126
-
127
- structure.edges(tag: 'link').tap do |matched|
128
- expect(matched.first.id).to eq(edge.id)
129
- expect(matched.first.from.id).to eq(edge.from.id)
130
- expect(matched.first.to.id).to eq(edge.to.id)
131
- end
132
- end
133
-
134
- it 'matches all edges with the given label' do
135
- edge = Mementus::Edge.new(label: :link, from: Mementus::Node.new(id: 1), to: Mementus::Node.new(id: 2))
136
- structure.set_edge(edge)
137
-
138
- structure.edges(:link).tap do |matched|
139
- expect(matched.first.id).to eq(edge.id)
140
- expect(matched.first.from.id).to eq(edge.from.id)
141
- expect(matched.first.to.id).to eq(edge.to.id)
142
- end
143
- end
144
- end
145
- end