dag 0.0.4 → 0.0.5
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 +7 -0
- data/Gemfile +1 -8
- data/Gemfile.lock +18 -20
- data/lib/dag/vertex.rb +27 -2
- data/lib/dag.rb +55 -4
- data/spec/lib/dag/vertex_spec.rb +46 -24
- data/spec/lib/dag_spec.rb +87 -16
- data/spec/spec_helper.rb +0 -6
- metadata +16 -38
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0902242dbbc24972c53aff3dff22f001f7db4f9d
|
4
|
+
data.tar.gz: 42d773c5d7036e62f8727bdbbe6b63e8f97dcee1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a15741d978e1d0e89a19af621342a786acabf96e28a820bb7582ad619e87641c052d6667553d4f3f2da8e68588073e9b4cc0750a83b8849b3537c44f2483fe78
|
7
|
+
data.tar.gz: a43973369d8803cf5948683c7e3a86b0fbc5d7cf624c565de8cc294d11b00139c38d1ac4118c2d921175ac45322ec4c8c0693931b36c26148eb95946989f4066
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,32 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dag (0.0.
|
4
|
+
dag (0.0.5)
|
5
5
|
|
6
6
|
GEM
|
7
|
-
remote:
|
7
|
+
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
diff-lcs (1.2.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
rspec-
|
14
|
-
rspec-
|
15
|
-
|
16
|
-
|
17
|
-
rspec-expectations (
|
18
|
-
diff-lcs (>= 1.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
simplecov-html (0.7.1)
|
9
|
+
diff-lcs (1.2.5)
|
10
|
+
rake (10.4.2)
|
11
|
+
rspec (3.1.0)
|
12
|
+
rspec-core (~> 3.1.0)
|
13
|
+
rspec-expectations (~> 3.1.0)
|
14
|
+
rspec-mocks (~> 3.1.0)
|
15
|
+
rspec-core (3.1.7)
|
16
|
+
rspec-support (~> 3.1.0)
|
17
|
+
rspec-expectations (3.1.2)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.1.0)
|
20
|
+
rspec-mocks (3.1.3)
|
21
|
+
rspec-support (~> 3.1.0)
|
22
|
+
rspec-support (3.1.2)
|
24
23
|
|
25
24
|
PLATFORMS
|
26
25
|
ruby
|
27
26
|
|
28
27
|
DEPENDENCIES
|
29
28
|
dag!
|
30
|
-
rake (~> 10
|
31
|
-
rspec (~>
|
32
|
-
simplecov
|
29
|
+
rake (~> 10)
|
30
|
+
rspec (~> 3)
|
data/lib/dag/vertex.rb
CHANGED
@@ -39,7 +39,7 @@ class DAG
|
|
39
39
|
#
|
40
40
|
def has_path_to?(other)
|
41
41
|
raise ArgumentError.new('You must supply a vertex in this DAG') unless
|
42
|
-
other
|
42
|
+
is_vertex_in_my_dag?(other)
|
43
43
|
successors.include?(other) || successors.any? {|v| v.has_path_to?(other) }
|
44
44
|
end
|
45
45
|
|
@@ -54,7 +54,7 @@ class DAG
|
|
54
54
|
#
|
55
55
|
def has_ancestor?(other)
|
56
56
|
raise ArgumentError.new('You must supply a vertex in this DAG') unless
|
57
|
-
other
|
57
|
+
is_vertex_in_my_dag?(other)
|
58
58
|
predecessors.include?(other) || predecessors.any? {|v| v.has_ancestor?(other) }
|
59
59
|
end
|
60
60
|
|
@@ -71,6 +71,31 @@ class DAG
|
|
71
71
|
@payload[key]
|
72
72
|
end
|
73
73
|
|
74
|
+
def ancestors(result_set = Set.new)
|
75
|
+
predecessors.each do |v|
|
76
|
+
unless result_set.include? v
|
77
|
+
result_set.add(v)
|
78
|
+
v.ancestors(result_set)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
return result_set
|
82
|
+
end
|
83
|
+
|
84
|
+
def descendants(result_set = Set.new)
|
85
|
+
successors.each do |v|
|
86
|
+
unless result_set.include? v
|
87
|
+
result_set.add(v)
|
88
|
+
v.descendants(result_set)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
return result_set
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def is_vertex_in_my_dag?(v)
|
97
|
+
v.kind_of?(Vertex) and v.dag == self.dag
|
98
|
+
end
|
74
99
|
end
|
75
100
|
|
76
101
|
end
|
data/lib/dag.rb
CHANGED
@@ -2,7 +2,7 @@ require_relative 'dag/vertex'
|
|
2
2
|
|
3
3
|
class DAG
|
4
4
|
|
5
|
-
Edge = Struct.new(:origin, :destination)
|
5
|
+
Edge = Struct.new(:origin, :destination, :properties)
|
6
6
|
|
7
7
|
attr_reader :vertices, :edges
|
8
8
|
|
@@ -28,13 +28,64 @@ class DAG
|
|
28
28
|
def add_edge(attrs)
|
29
29
|
origin = attrs[:origin] || attrs[:source] || attrs[:from] || attrs[:start]
|
30
30
|
destination = attrs[:destination] || attrs[:sink] || attrs[:to] || attrs[:end]
|
31
|
+
properties = attrs[:properties] || {}
|
31
32
|
raise ArgumentError.new('Origin must be a vertex in this DAG') unless
|
32
|
-
origin
|
33
|
+
is_my_vertex?(origin)
|
33
34
|
raise ArgumentError.new('Destination must be a vertex in this DAG') unless
|
34
|
-
|
35
|
+
is_my_vertex?(destination)
|
35
36
|
raise ArgumentError.new('A DAG must not have cycles') if origin == destination
|
36
37
|
raise ArgumentError.new('A DAG must not have cycles') if destination.has_path_to?(origin)
|
37
|
-
Edge.new(origin, destination).tap {|e| @edges << e }
|
38
|
+
Edge.new(origin, destination, properties).tap {|e| @edges << e }
|
39
|
+
end
|
40
|
+
|
41
|
+
def subgraph(predecessors_of = [], successors_of = [])
|
42
|
+
|
43
|
+
|
44
|
+
(predecessors_of + successors_of).each { |v|
|
45
|
+
raise ArgumentError.new('You must supply a vertex in this DAG') unless
|
46
|
+
is_my_vertex?(v)
|
47
|
+
}
|
48
|
+
|
49
|
+
result = DAG.new({mixin: @mixin})
|
50
|
+
vertex_mapping = {}
|
51
|
+
|
52
|
+
# Get the set of predecessors verticies and add a copy to the result
|
53
|
+
predecessors_set = Set.new(predecessors_of)
|
54
|
+
predecessors_of.each { |v| v.ancestors(predecessors_set) }
|
55
|
+
|
56
|
+
predecessors_set.each do |v|
|
57
|
+
vertex_mapping[v] = result.add_vertex(payload=v.payload)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get the set of successor vertices and add a copy to the result
|
61
|
+
successors_set = Set.new(successors_of)
|
62
|
+
successors_of.each { |v| v.descendants(successors_set) }
|
63
|
+
|
64
|
+
successors_set.each do |v|
|
65
|
+
vertex_mapping[v] = result.add_vertex(payload=v.payload) unless vertex_mapping.include? v
|
66
|
+
end
|
67
|
+
|
68
|
+
# get the unique edges
|
69
|
+
edge_set = (
|
70
|
+
predecessors_set.flat_map(&:incoming_edges) +
|
71
|
+
successors_set.flat_map(&:outgoing_edges)
|
72
|
+
).uniq
|
73
|
+
|
74
|
+
# Add them to the result via the vertex mapping
|
75
|
+
edge_set.each do |e|
|
76
|
+
result.add_edge(
|
77
|
+
from: vertex_mapping[e.origin],
|
78
|
+
to: vertex_mapping[e.destination],
|
79
|
+
properties: e.properties)
|
80
|
+
end
|
81
|
+
|
82
|
+
return result
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def is_my_vertex?(v)
|
88
|
+
v.kind_of?(Vertex) and v.dag == self
|
38
89
|
end
|
39
90
|
|
40
91
|
end
|
data/spec/lib/dag/vertex_spec.rb
CHANGED
@@ -31,18 +31,18 @@ describe DAG::Vertex do
|
|
31
31
|
subject { dag.add_vertex(name: 'Fred', size: 34) }
|
32
32
|
|
33
33
|
it 'allows the payload to be accessed' do
|
34
|
-
subject[:name].
|
35
|
-
subject[:size].
|
36
|
-
subject.payload.
|
34
|
+
expect(subject[:name]).to eq('Fred')
|
35
|
+
expect(subject[:size]).to eq(34)
|
36
|
+
expect(subject.payload).to eq({name: 'Fred', size: 34})
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'returns nil for missing payload key' do
|
40
|
-
subject[56].
|
40
|
+
expect(subject[56]).to be_nil
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'allows the payload to be changed' do
|
44
44
|
subject.payload[:another] = 'ha'
|
45
|
-
subject[:another].
|
45
|
+
expect(subject[:another]).to eq('ha')
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -52,25 +52,30 @@ describe DAG::Vertex do
|
|
52
52
|
dag.add_edge from: v2, to: subject
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
it 'has the correct predecessors' do
|
56
|
+
expect(subject.predecessors).to eq([v1, v2])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'has no successors' do
|
60
|
+
expect(subject.successors).to be_empty
|
61
|
+
end
|
57
62
|
|
58
63
|
it 'has no paths to its predecessors' do
|
59
|
-
subject.has_path_to?(v1).
|
60
|
-
subject.has_path_to?(v2).
|
64
|
+
expect(subject.has_path_to?(v1)).to be_falsey
|
65
|
+
expect(subject.has_path_to?(v2)).to be_falsey
|
61
66
|
end
|
62
67
|
|
63
68
|
context 'with multiple paths' do
|
64
69
|
it 'lists each predecessor only once' do
|
65
70
|
dag.add_edge from: v1, to: subject
|
66
|
-
subject.predecessors.
|
71
|
+
expect(subject.predecessors).to eq([v1, v2])
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
70
75
|
it 'has the correct ancestors' do
|
71
|
-
subject.has_ancestor?(v1).
|
72
|
-
subject.has_ancestor?(v2).
|
73
|
-
subject.has_ancestor?(v3).
|
76
|
+
expect(subject.has_ancestor?(v1)).to be_truthy
|
77
|
+
expect(subject.has_ancestor?(v2)).to be_truthy
|
78
|
+
expect(subject.has_ancestor?(v3)).to be_falsey
|
74
79
|
end
|
75
80
|
end
|
76
81
|
|
@@ -80,24 +85,29 @@ describe DAG::Vertex do
|
|
80
85
|
dag.add_edge from: subject, to: v2
|
81
86
|
end
|
82
87
|
|
83
|
-
|
84
|
-
|
88
|
+
it 'has no predecessors' do
|
89
|
+
expect(subject.predecessors).to be_empty
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'has the correct successors' do
|
93
|
+
expect(subject.successors).to eq([v1, v2])
|
94
|
+
end
|
85
95
|
|
86
96
|
it 'has paths to its successors' do
|
87
|
-
subject.has_path_to?(v1).
|
88
|
-
subject.has_path_to?(v2).
|
97
|
+
expect(subject.has_path_to?(v1)).to be_truthy
|
98
|
+
expect(subject.has_path_to?(v2)).to be_truthy
|
89
99
|
end
|
90
100
|
|
91
101
|
context 'with multiple paths' do
|
92
102
|
it 'lists each successor only once' do
|
93
103
|
dag.add_edge from: subject, to: v1
|
94
|
-
subject.successors.
|
104
|
+
expect(subject.successors).to eq([v1, v2])
|
95
105
|
end
|
96
106
|
end
|
97
107
|
|
98
108
|
it 'has no ancestors' do
|
99
|
-
subject.has_ancestor?(v1).
|
100
|
-
subject.has_ancestor?(v2).
|
109
|
+
expect(subject.has_ancestor?(v1)).to be_falsey
|
110
|
+
expect(subject.has_ancestor?(v2)).to be_falsey
|
101
111
|
end
|
102
112
|
end
|
103
113
|
|
@@ -108,17 +118,29 @@ describe DAG::Vertex do
|
|
108
118
|
end
|
109
119
|
|
110
120
|
it 'has a deep path to v2' do
|
111
|
-
subject.has_path_to?(v2).
|
121
|
+
expect(subject.has_path_to?(v2)).to be_truthy
|
112
122
|
end
|
113
123
|
|
114
124
|
it 'has no path to v3' do
|
115
|
-
subject.has_path_to?(v3).
|
125
|
+
expect(subject.has_path_to?(v3)).to be_falsey
|
116
126
|
end
|
117
127
|
|
118
128
|
it 'recognises that it is an ancestor of v2' do
|
119
|
-
v2.has_ancestor?(subject).
|
129
|
+
expect(v2.has_ancestor?(subject)).to be_truthy
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'is known to all descendants' do
|
133
|
+
expect(v2.ancestors).to eq(Set.new([v1, subject]))
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'knows has no ancestors' do
|
137
|
+
expect(subject.ancestors).to eq(Set.new())
|
120
138
|
end
|
139
|
+
|
140
|
+
it 'knows has all descendants' do
|
141
|
+
expect(subject.descendants).to eq(Set.new([v1, v2]))
|
142
|
+
end
|
143
|
+
|
121
144
|
end
|
122
145
|
|
123
146
|
end
|
124
|
-
|
data/spec/lib/dag_spec.rb
CHANGED
@@ -2,21 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DAG do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
it 'when new' do
|
6
|
+
expect(subject.vertices).to be_empty
|
7
|
+
expect(subject.edges).to be_empty
|
8
8
|
end
|
9
9
|
|
10
10
|
context 'with one vertex' do
|
11
11
|
it 'has only that vertex' do
|
12
12
|
v = subject.add_vertex
|
13
|
-
subject.vertices.
|
13
|
+
expect(subject.vertices).to eq([v])
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'has no edges' do
|
17
17
|
v = subject.add_vertex
|
18
|
-
v.outgoing_edges.
|
19
|
-
v.incoming_edges.
|
18
|
+
expect(v.outgoing_edges).to be_empty
|
19
|
+
expect(v.incoming_edges).to be_empty
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -31,11 +31,11 @@ describe DAG do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'mixes the module into evey vertex' do
|
34
|
-
(Thing === v).
|
34
|
+
expect((Thing === v)).to be_truthy
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'allows the module to access the payload' do
|
38
|
-
v.my_name.
|
38
|
+
expect(v.my_name).to eq('Fred')
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -47,21 +47,30 @@ describe DAG do
|
|
47
47
|
let!(:e1) { subject.add_edge(origin: v1, destination: v2) }
|
48
48
|
|
49
49
|
it 'leaves the origin vertex' do
|
50
|
-
v1.outgoing_edges.
|
50
|
+
expect(v1.outgoing_edges).to eq([e1])
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'arrives at the destination vertex' do
|
54
|
-
v2.incoming_edges.
|
54
|
+
expect(v2.incoming_edges).to eq([e1])
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'adds no other edges' do
|
58
|
-
v1.incoming_edges.
|
59
|
-
v2.outgoing_edges.
|
58
|
+
expect(v1.incoming_edges).to be_empty
|
59
|
+
expect(v2.outgoing_edges).to be_empty
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'it has no properties' do
|
63
|
+
expect(e1.properties).to be_empty
|
60
64
|
end
|
61
65
|
|
62
66
|
it 'allows multiple edges between a pair of vertices' do
|
63
67
|
expect { subject.add_edge(origin: v1, destination: v2) }.to_not raise_error
|
64
68
|
end
|
69
|
+
|
70
|
+
it 'can specify properties' do
|
71
|
+
e2 = subject.add_edge(origin: v1, destination: v2, properties: {foo: 'bar'})
|
72
|
+
expect(e2.properties[:foo]).to eq('bar')
|
73
|
+
end
|
65
74
|
end
|
66
75
|
|
67
76
|
context 'when invalid' do
|
@@ -105,20 +114,82 @@ describe DAG do
|
|
105
114
|
let!(:e1) { subject.add_edge(origin: v1, destination: v2) }
|
106
115
|
|
107
116
|
it 'allows :source and :sink' do
|
108
|
-
subject.add_edge(source: v1, sink: v2).
|
117
|
+
expect(subject.add_edge(source: v1, sink: v2)).to eq(e1)
|
109
118
|
end
|
110
119
|
|
111
120
|
it 'allows :from and :to' do
|
112
|
-
subject.add_edge(from: v1, to: v2).
|
121
|
+
expect(subject.add_edge(from: v1, to: v2)).to eq(e1)
|
113
122
|
end
|
114
123
|
|
115
124
|
it 'allows :start and :end' do
|
116
|
-
subject.add_edge(start: v1, end: v2).
|
125
|
+
expect(subject.add_edge(start: v1, end: v2)).to eq(e1)
|
117
126
|
end
|
118
127
|
|
119
128
|
end
|
120
129
|
|
121
130
|
end
|
122
131
|
|
123
|
-
|
132
|
+
context 'given a dag' do
|
133
|
+
subject { DAG.new(mixin: Thing) }
|
134
|
+
module Thing
|
135
|
+
def my_name
|
136
|
+
payload[:name]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
let(:joe) { subject.add_vertex(name: "joe") }
|
141
|
+
let(:bob) { subject.add_vertex(name: "bob") }
|
142
|
+
let(:jane) { subject.add_vertex(name: "jane") }
|
143
|
+
let!(:e1) { subject.add_edge(origin: joe, destination: bob, properties: {name: "father of"} ) }
|
144
|
+
let!(:e2) { subject.add_edge(origin: joe, destination: jane) }
|
145
|
+
let!(:e3) { subject.add_edge(origin: bob, destination: jane) }
|
146
|
+
|
147
|
+
describe '.subgraph' do
|
148
|
+
it 'returns a graph' do
|
149
|
+
expect(subject.subgraph()).to be_an_instance_of(DAG)
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'of joe and his ancestors' do
|
153
|
+
subgraph = subject.subgraph([joe,],[])
|
154
|
+
expect(subgraph.vertices.length).to eq(1)
|
155
|
+
expect(subgraph.vertices[0].my_name).to eq("joe")
|
156
|
+
expect(subgraph.edges).to be_empty
|
157
|
+
end
|
124
158
|
|
159
|
+
it 'of joe and his descendants' do
|
160
|
+
subgraph = subject.subgraph([],[joe,])
|
161
|
+
expect(Set.new(subgraph.vertices.map(&:my_name))).to eq(Set.new(["joe","bob","jane"]))
|
162
|
+
expect(subgraph.edges.length).to eq(3)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'of Jane and her ancestors' do
|
166
|
+
subgraph = subject.subgraph([jane,],[])
|
167
|
+
expect(Set.new(subgraph.vertices.map(&:my_name))).to eq(Set.new(["joe","bob","jane"]))
|
168
|
+
expect(subgraph.edges.length).to eq(3)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'of jane and her descendants' do
|
172
|
+
subgraph = subject.subgraph([],[jane,])
|
173
|
+
expect(Set.new(subgraph.vertices.map(&:my_name))).to eq(Set.new(["jane"]))
|
174
|
+
expect(subgraph.edges).to be_empty
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'of bob and his descendants' do
|
178
|
+
subgraph = subject.subgraph([],[bob,])
|
179
|
+
expect(Set.new(subgraph.vertices.map(&:my_name))).to eq(Set.new(["bob","jane"]))
|
180
|
+
expect(subgraph.edges.length).to eq(1)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'there is something incestuous going on here' do
|
184
|
+
subgraph = subject.subgraph([bob,],[bob,])
|
185
|
+
expect(Set.new(subgraph.vertices.map(&:my_name))).to eq(Set.new(["bob","jane","joe"]))
|
186
|
+
expect(subgraph.edges.length).to eq(2)
|
187
|
+
expect(subgraph.edges[0].properties).to eq({name: "father of"})
|
188
|
+
expect(subgraph.edges[1].properties).to eq({})
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.5
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kevin Rutherford
|
@@ -14,59 +13,39 @@ dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: 10
|
19
|
+
version: '10'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 10
|
26
|
+
version: '10'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
33
|
+
version: '3'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: simplecov
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
40
|
+
version: '3'
|
62
41
|
description: Directed acyclic graphs
|
63
42
|
email: kevin@rutherford-software.com
|
64
43
|
executables: []
|
65
44
|
extensions: []
|
66
45
|
extra_rdoc_files: []
|
67
46
|
files:
|
68
|
-
- .rspec
|
69
|
-
- .yardopts
|
47
|
+
- ".rspec"
|
48
|
+
- ".yardopts"
|
70
49
|
- Gemfile
|
71
50
|
- Gemfile.lock
|
72
51
|
- README.md
|
@@ -78,27 +57,26 @@ files:
|
|
78
57
|
- spec/spec_helper.rb
|
79
58
|
homepage: http://github.com/kevinrutherford/dag
|
80
59
|
licenses: []
|
60
|
+
metadata: {}
|
81
61
|
post_install_message:
|
82
62
|
rdoc_options: []
|
83
63
|
require_paths:
|
84
64
|
- lib
|
85
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
-
none: false
|
87
66
|
requirements:
|
88
|
-
- -
|
67
|
+
- - ">="
|
89
68
|
- !ruby/object:Gem::Version
|
90
69
|
version: '0'
|
91
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
-
none: false
|
93
71
|
requirements:
|
94
|
-
- -
|
72
|
+
- - ">="
|
95
73
|
- !ruby/object:Gem::Version
|
96
74
|
version: '0'
|
97
75
|
requirements: []
|
98
76
|
rubyforge_project:
|
99
|
-
rubygems_version:
|
77
|
+
rubygems_version: 2.2.2
|
100
78
|
signing_key:
|
101
|
-
specification_version:
|
79
|
+
specification_version: 4
|
102
80
|
summary: Directed acyclic graphs
|
103
81
|
test_files:
|
104
82
|
- spec/lib/dag/vertex_spec.rb
|