mementus 0.5.5 → 0.5.6

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.
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