ellington 0.2.1 → 0.2.2
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 +4 -4
- data/README.md +10 -1
- data/lib/ellington/connection.rb +5 -13
- data/lib/ellington/route.rb +2 -3
- data/lib/ellington/version.rb +1 -1
- data/lib/ellington/visualizer.rb +39 -122
- data/test/connection_test.rb +1 -1
- data/test/example.rb +2 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0663ec76ffb5ce9f6a83f9d705fa0db42140d321
|
4
|
+
data.tar.gz: 4276cb5695eec75a1ee57fe0ba24d26c16ecb688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e5b8999a2d59992f03f1d38ddf3b79c6dfb6e07df1bb4c574b3648e3f3ef92ef83b23ccfeab47a1bf2a7128fb1ac45b9cb55628288b93869dde9876a7468c7b
|
7
|
+
data.tar.gz: 95f942f7ff068d9dea4c0447279a5716869b6432655db10733fe5873b117c6e7e37854d0d9b528cc6561e380a3599b0b5adac7e373b18809e34e55d3ce5ef47c
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
2
|
[](https://codeclimate.com/github/hopsoft/ellington)
|
3
3
|
[](https://gemnasium.com/hopsoft/ellington)
|
4
4
|
[](https://travis-ci.org/hopsoft/ellington)
|
@@ -7,6 +7,15 @@
|
|
7
7
|
|
8
8
|
# Ellington
|
9
9
|
|
10
|
+
### Important
|
11
|
+
|
12
|
+
__The wiki docs are out of date!__
|
13
|
+
|
14
|
+
You'll have to review the examples & code itself for now.
|
15
|
+
I'll be working to bring the wiki docs current soon.
|
16
|
+
|
17
|
+
---
|
18
|
+
|
10
19
|
Named after [Duke Ellington](http://www.dukeellington.com/) whose signature tune was ["Take the 'A' Train"](http://en.wikipedia.org/wiki/Take_the_%22A%22_Train).
|
11
20
|
The song was written about [New York City's A train](http://en.wikipedia.org/wiki/A_%28New_York_City_Subway_service%29).
|
12
21
|
|
data/lib/ellington/connection.rb
CHANGED
@@ -1,25 +1,17 @@
|
|
1
1
|
module Ellington
|
2
2
|
class Connection
|
3
|
-
attr_reader :line, :
|
3
|
+
attr_reader :line, :states, :strict
|
4
4
|
|
5
|
-
def initialize(line,
|
5
|
+
def initialize(line, *states, strict: false)
|
6
6
|
@line = line
|
7
|
-
@type = type
|
8
7
|
@states = Ellington::Target.new(*states)
|
8
|
+
@strict = strict
|
9
9
|
end
|
10
10
|
|
11
11
|
def required?(passenger)
|
12
12
|
return false if line.boarded?(passenger)
|
13
|
-
|
14
|
-
|
15
|
-
return states.satisfied?(passenger)
|
16
|
-
end
|
17
|
-
|
18
|
-
if type == :if_all
|
19
|
-
return (passenger.state_history & states).length == states.length
|
20
|
-
end
|
21
|
-
|
22
|
-
false
|
13
|
+
return (passenger.state_history & states).length == states.length if strict
|
14
|
+
states.satisfied?(passenger)
|
23
15
|
end
|
24
16
|
|
25
17
|
end
|
data/lib/ellington/route.rb
CHANGED
@@ -92,9 +92,8 @@ module Ellington
|
|
92
92
|
@connections ||= Ellington::ConnectionList.new
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
connections << Ellington::Connection.new(line,
|
97
|
-
connections << Ellington::Connection.new(line, :if_all, if_all) unless if_all.empty?
|
95
|
+
def connect(line, after: [], strict: false)
|
96
|
+
connections << Ellington::Connection.new(line, *after, strict: false)
|
98
97
|
end
|
99
98
|
|
100
99
|
def passenger_attrs_to_log
|
data/lib/ellington/version.rb
CHANGED
data/lib/ellington/visualizer.rb
CHANGED
@@ -41,28 +41,28 @@ module Ellington
|
|
41
41
|
@short_names = short_names
|
42
42
|
end
|
43
43
|
|
44
|
-
FONTNAME
|
45
|
-
RANKSEP
|
46
|
-
NODE_COLOR
|
47
|
-
NODE_COLOR_VIRTUAL
|
48
|
-
NODE_COLOR_LINE_GOAL
|
49
|
-
NODE_COLOR_ROUTE_GOAL
|
50
|
-
NODE_COLOR_PASSENGER_HIT
|
51
|
-
NODE_FILLCOLOR
|
52
|
-
NODE_FILLCOLOR_LINE_GOAL
|
53
|
-
NODE_FILLCOLOR_ROUTE_GOAL
|
54
|
-
NODE_FONTCOLOR_VIRTUAL
|
55
|
-
NODE_SHAPE
|
56
|
-
NODE_STYLE
|
57
|
-
NODE_STYLE_VIRTUAL
|
44
|
+
FONTNAME = "Helvetica"
|
45
|
+
RANKSEP = 0.4
|
46
|
+
NODE_COLOR = "white"
|
47
|
+
NODE_COLOR_VIRTUAL = "gray50"
|
48
|
+
NODE_COLOR_LINE_GOAL = "green2"
|
49
|
+
NODE_COLOR_ROUTE_GOAL = "gold"
|
50
|
+
NODE_COLOR_PASSENGER_HIT = "royalblue1"
|
51
|
+
NODE_FILLCOLOR = "white"
|
52
|
+
NODE_FILLCOLOR_LINE_GOAL = "green2"
|
53
|
+
NODE_FILLCOLOR_ROUTE_GOAL = "gold"
|
54
|
+
NODE_FONTCOLOR_VIRTUAL = "gray40"
|
55
|
+
NODE_SHAPE = "box"
|
56
|
+
NODE_STYLE = "filled,rounded"
|
57
|
+
NODE_STYLE_VIRTUAL = "rounded"
|
58
58
|
NODE_PENWIDTH_PASSENGER_HIT = 2
|
59
59
|
EDGE_PENWIDTH_PASSENGER_HIT = 2
|
60
|
-
EDGE_COLOR_PASSENGER_HIT
|
61
|
-
EDGE_STYLE_PASSENGER_MISS
|
62
|
-
CLUSTER_STYLE
|
63
|
-
CLUSTER_COLOR
|
64
|
-
CLUSTER_FILLCOLOR
|
65
|
-
CLUSTER_PENCOLOR
|
60
|
+
EDGE_COLOR_PASSENGER_HIT = "royalblue1"
|
61
|
+
EDGE_STYLE_PASSENGER_MISS = "dotted"
|
62
|
+
CLUSTER_STYLE = "filled"
|
63
|
+
CLUSTER_COLOR = "gray70"
|
64
|
+
CLUSTER_FILLCOLOR = "gray70"
|
65
|
+
CLUSTER_PENCOLOR = "gray50"
|
66
66
|
|
67
67
|
def class_label(obj)
|
68
68
|
klass = obj
|
@@ -76,77 +76,6 @@ module Ellington
|
|
76
76
|
state.split(" ").map { |part| part.split("::").last }.join(" | ")
|
77
77
|
end
|
78
78
|
|
79
|
-
def graph_lines_basic(passenger=nil)
|
80
|
-
g = Node.new(nil, GraphViz.new("GraphLinesBasic"))
|
81
|
-
set_graph_defaults g.viz
|
82
|
-
g.viz[:label] = "#{class_label(route)} Lines - basic"
|
83
|
-
|
84
|
-
route.lines.each_with_index do |line, index|
|
85
|
-
line_cluster = g.add(Node.new(line, g.viz.add_graph("cluster#{index}")))
|
86
|
-
set_cluster_defaults line_cluster.viz
|
87
|
-
line_cluster.viz[:label] = class_label(line)
|
88
|
-
|
89
|
-
line.stations.each do |station|
|
90
|
-
states = station.states.keys
|
91
|
-
station_node = line_cluster.add(Node.new(station, line_cluster.viz.add_nodes(class_label(station))))
|
92
|
-
style_node_for_line(station_node, line, *states)
|
93
|
-
style_node_for_route(station_node, route, *states)
|
94
|
-
style_node_for_passenger(station_node, passenger, *states)
|
95
|
-
end
|
96
|
-
|
97
|
-
line_cluster.each_with_index.each do |node, node_index|
|
98
|
-
next_node = line_cluster[node_index + 1]
|
99
|
-
if next_node
|
100
|
-
#station = node.base
|
101
|
-
#next_station = next_node.base
|
102
|
-
edge = line_cluster.viz.add_edges(node.viz, next_node.viz)
|
103
|
-
if passenger
|
104
|
-
if color_name(node.viz[:color]) == NODE_COLOR_PASSENGER_HIT &&
|
105
|
-
color_name(next_node.viz[:color]) == NODE_COLOR_PASSENGER_HIT
|
106
|
-
edge["color"] = EDGE_COLOR_PASSENGER_HIT
|
107
|
-
edge["penwidth"] = EDGE_PENWIDTH_PASSENGER_HIT
|
108
|
-
else
|
109
|
-
edge["style"] = EDGE_STYLE_PASSENGER_MISS
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
g.viz.output(format => String)
|
117
|
-
end
|
118
|
-
|
119
|
-
def graph_lines(passenger=nil)
|
120
|
-
g = Node.new(nil, GraphViz.new("GraphLines"))
|
121
|
-
set_graph_defaults g.viz
|
122
|
-
g.viz[:label] = "#{class_label(route)} Lines"
|
123
|
-
|
124
|
-
route.lines.each_with_index do |line, index|
|
125
|
-
line_cluster = g.add(Node.new(line, g.viz.add_graph("cluster#{index}")))
|
126
|
-
set_cluster_defaults line_cluster.viz
|
127
|
-
line_cluster.viz[:label] = class_label(line)
|
128
|
-
add_state_nodes_for_line line_cluster, line, passenger
|
129
|
-
|
130
|
-
line.states.each do |state, transitions|
|
131
|
-
a = line_cluster.find(state)
|
132
|
-
(transitions || []).each do |transition|
|
133
|
-
b = line_cluster.find(transition)
|
134
|
-
edge = line_cluster.viz.add_edges(a.viz, b.viz)
|
135
|
-
if passenger
|
136
|
-
if passenger.state_history_includes?(state, transition)
|
137
|
-
edge["color"] = EDGE_COLOR_PASSENGER_HIT
|
138
|
-
edge["penwidth"] = EDGE_PENWIDTH_PASSENGER_HIT
|
139
|
-
else
|
140
|
-
edge["style"] = EDGE_STYLE_PASSENGER_MISS
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
g.viz.output(format => String)
|
148
|
-
end
|
149
|
-
|
150
79
|
def graph_route_basic(passenger=nil)
|
151
80
|
g = Node.new(nil, GraphViz.new("GraphRouteBasic"))
|
152
81
|
set_graph_defaults g.viz
|
@@ -158,13 +87,12 @@ module Ellington
|
|
158
87
|
set_cluster_defaults line_cluster.viz
|
159
88
|
line_cluster.viz[:label] = class_label(line)
|
160
89
|
|
161
|
-
passenger_hit = false
|
162
90
|
%w{PASS FAIL ERROR}.each do |state|
|
163
91
|
state_node = line_cluster.add(Node.new(state, line_cluster.viz.add_nodes("#{line.class.name}#{state}", "label" => state)))
|
164
|
-
states = line.stations.map{ |s| "#{state} #{
|
92
|
+
states = line.stations.map{ |s| "#{state} #{s.name}" }
|
165
93
|
style_node_for_line(state_node, line, *states)
|
166
94
|
style_node_for_route(state_node, route, *states)
|
167
|
-
|
95
|
+
style_node_for_passenger(state_node, passenger, *line.send("#{state.downcase}ed"))
|
168
96
|
end
|
169
97
|
end
|
170
98
|
|
@@ -198,15 +126,6 @@ module Ellington
|
|
198
126
|
node_name = nodes.map{ |n| n.base.class.name }.join + state
|
199
127
|
node_label = nodes.map{ |n| state_label(state) }.join("\n")
|
200
128
|
viz = g.viz.add_nodes(node_name, :label => node_label)
|
201
|
-
viz[:style] = NODE_STYLE_VIRTUAL
|
202
|
-
viz[:color] = NODE_COLOR_VIRTUAL
|
203
|
-
viz[:fontcolor] = NODE_FONTCOLOR_VIRTUAL
|
204
|
-
|
205
|
-
nodes.each do |node|
|
206
|
-
from_viz = node.viz.get_node("#{node.base.class.name}#{state}")
|
207
|
-
g.viz.add_edges from_viz, viz
|
208
|
-
end
|
209
|
-
|
210
129
|
g.viz.add_edges(
|
211
130
|
viz,
|
212
131
|
to_node.viz.get_node("#{connection.line.class.name}#{state}"),
|
@@ -272,7 +191,7 @@ module Ellington
|
|
272
191
|
from_viz,
|
273
192
|
to_viz
|
274
193
|
)
|
275
|
-
edge[
|
194
|
+
edge[:style] = EDGE_STYLE_PASSENGER_MISS if passenger
|
276
195
|
end
|
277
196
|
end
|
278
197
|
end
|
@@ -294,25 +213,23 @@ module Ellington
|
|
294
213
|
def style_node(node, color)
|
295
214
|
node.viz[:color] = color
|
296
215
|
node.viz[:fillcolor] = color
|
297
|
-
true
|
298
216
|
end
|
299
217
|
|
300
218
|
def style_node_for_line(node, line, *states)
|
301
|
-
return
|
219
|
+
return if (line.goal & states).empty?
|
302
220
|
style_node node, NODE_COLOR_LINE_GOAL
|
303
221
|
end
|
304
222
|
|
305
223
|
def style_node_for_route(node, route, *states)
|
306
|
-
return
|
224
|
+
return if (route.goal & states).empty?
|
307
225
|
style_node node, NODE_COLOR_ROUTE_GOAL
|
308
226
|
end
|
309
227
|
|
310
228
|
def style_node_for_passenger(node, passenger, *states)
|
311
|
-
return
|
312
|
-
return
|
229
|
+
return if passenger.nil?
|
230
|
+
return if (passenger.state_history & states).empty?
|
313
231
|
node.viz[:color] = NODE_COLOR_PASSENGER_HIT
|
314
232
|
node.viz[:penwidth] = NODE_PENWIDTH_PASSENGER_HIT
|
315
|
-
true
|
316
233
|
end
|
317
234
|
|
318
235
|
def color_name(graphviz_color)
|
@@ -320,21 +237,21 @@ module Ellington
|
|
320
237
|
end
|
321
238
|
|
322
239
|
def set_graph_defaults(graph)
|
323
|
-
graph[
|
324
|
-
graph[
|
325
|
-
graph[
|
326
|
-
graph.node[
|
327
|
-
graph.node[
|
328
|
-
graph.node[
|
329
|
-
graph.node[
|
330
|
-
graph.node[
|
240
|
+
graph[:compound] = true
|
241
|
+
graph[:ranksep] = RANKSEP
|
242
|
+
graph[:fontname] = FONTNAME
|
243
|
+
graph.node[:fontname] = FONTNAME
|
244
|
+
graph.node[:shape] = NODE_SHAPE
|
245
|
+
graph.node[:style] = NODE_STYLE
|
246
|
+
graph.node[:color] = NODE_COLOR
|
247
|
+
graph.node[:fillcolor] = NODE_FILLCOLOR
|
331
248
|
end
|
332
249
|
|
333
250
|
def set_cluster_defaults(cluster)
|
334
|
-
cluster[
|
335
|
-
cluster[
|
336
|
-
cluster[
|
337
|
-
cluster[
|
251
|
+
cluster[:style] = CLUSTER_STYLE
|
252
|
+
cluster[:color] = CLUSTER_COLOR
|
253
|
+
cluster[:fillcolor] = CLUSTER_FILLCOLOR
|
254
|
+
cluster[:pencolor] = CLUSTER_PENCOLOR
|
338
255
|
end
|
339
256
|
|
340
257
|
end
|
data/test/connection_test.rb
CHANGED
@@ -5,7 +5,7 @@ class ConnectionTest < PryTest::Test
|
|
5
5
|
before do
|
6
6
|
@route = BasicMath.new
|
7
7
|
@line = @route.lines.first
|
8
|
-
@connection = Ellington::Connection.new(@route.lines[1],
|
8
|
+
@connection = Ellington::Connection.new(@route.lines[1], @line.passed)
|
9
9
|
end
|
10
10
|
|
11
11
|
test "line" do
|
data/test/example.rb
CHANGED
@@ -115,9 +115,8 @@ class BasicMath < Ellington::Route
|
|
115
115
|
|
116
116
|
goal division.passed, multiplication.passed
|
117
117
|
|
118
|
-
|
119
|
-
|
118
|
+
connect division, after: addition.passed
|
119
|
+
connect multiplication, after: addition.failed
|
120
120
|
|
121
121
|
set_passenger_attrs_to_log :original_value, :current_value
|
122
122
|
end
|
123
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ellington
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hero
|