seafoam 0.5 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bgv2isabelle +1 -5
  3. data/bin/bgv2json +1 -5
  4. data/bin/cfg2asm +1 -5
  5. data/bin/seafoam +1 -5
  6. data/lib/seafoam/bgv/bgv_parser.rb +10 -2
  7. data/lib/seafoam/commands.rb +53 -32
  8. data/lib/seafoam/graal/pi.rb +18 -0
  9. data/lib/seafoam/graph.rb +33 -1
  10. data/lib/seafoam/graphviz_writer.rb +24 -2
  11. data/lib/seafoam/json_writer.rb +1 -3
  12. data/lib/seafoam/{annotators → passes}/fallback.rb +4 -4
  13. data/lib/seafoam/{annotators → passes}/graal.rb +43 -13
  14. data/lib/seafoam/passes/truffle.rb +58 -0
  15. data/lib/seafoam/passes.rb +61 -0
  16. data/lib/seafoam/version.rb +1 -1
  17. data/lib/seafoam.rb +5 -4
  18. metadata +32 -66
  19. data/.github/probots.yml +0 -2
  20. data/.github/workflows/workflows.yml +0 -39
  21. data/.gitignore +0 -7
  22. data/.rubocop.yml +0 -37
  23. data/.ruby-version +0 -1
  24. data/.seafoam/config +0 -1
  25. data/CODE_OF_CONDUCT.md +0 -128
  26. data/CONTRIBUTING.md +0 -5
  27. data/Gemfile +0 -2
  28. data/LICENSE.md +0 -7
  29. data/README.md +0 -378
  30. data/demos/box-unbox-stats +0 -65
  31. data/docs/annotators.md +0 -43
  32. data/docs/bgv.md +0 -293
  33. data/docs/getting-graphs.md +0 -59
  34. data/docs/images/igv.png +0 -0
  35. data/docs/images/seafoam.png +0 -0
  36. data/docs/images/spotlight-igv.png +0 -0
  37. data/docs/images/spotlight-seafoam.png +0 -0
  38. data/docs/json.md +0 -35
  39. data/examples/Fib.java +0 -24
  40. data/examples/MatMult.java +0 -39
  41. data/examples/fib-java.bgv.gz +0 -0
  42. data/examples/fib.js +0 -15
  43. data/examples/fib.rb +0 -15
  44. data/examples/identity.rb +0 -13
  45. data/examples/java/Irreducible.class +0 -0
  46. data/examples/java/Irreducible.j +0 -35
  47. data/examples/java/IrreducibleDecompiled.java +0 -21
  48. data/examples/java/JavaExamples.java +0 -418
  49. data/examples/matmult.rb +0 -29
  50. data/examples/overflow.rb +0 -13
  51. data/examples/ruby/clamps.rb +0 -20
  52. data/examples/ruby/graal.patch +0 -15
  53. data/examples/ruby/ruby_examples.rb +0 -278
  54. data/lib/seafoam/annotators.rb +0 -54
  55. data/lib/seafoam/config.rb +0 -34
  56. data/seafoam.gemspec +0 -21
  57. data/spec/seafoam/annotators/fallback_spec.rb +0 -69
  58. data/spec/seafoam/annotators/graal_spec.rb +0 -96
  59. data/spec/seafoam/annotators_spec.rb +0 -61
  60. data/spec/seafoam/bgv/bgv_parser_spec.rb +0 -157
  61. data/spec/seafoam/binary/io_binary_reader_spec.rb +0 -176
  62. data/spec/seafoam/cfg/cfg_parser_spec.rb +0 -21
  63. data/spec/seafoam/cfg/disassembler_spec.rb +0 -32
  64. data/spec/seafoam/command_spec.rb +0 -316
  65. data/spec/seafoam/graph_spec.rb +0 -172
  66. data/spec/seafoam/graphviz_writer_spec.rb +0 -63
  67. data/spec/seafoam/json_writer_spec.rb +0 -14
  68. data/spec/seafoam/spec_helpers.rb +0 -34
  69. data/spec/seafoam/spotlight_spec.rb +0 -38
  70. data/tools/render-all +0 -36
@@ -1,316 +0,0 @@
1
- require 'stringio'
2
- require 'tempfile'
3
-
4
- require 'seafoam'
5
-
6
- require 'rspec'
7
-
8
- describe Seafoam::Commands do
9
- before :all do
10
- @fib_java = File.expand_path('../../examples/fib-java.bgv', __dir__)
11
- @fib_ruby = File.expand_path('../../examples/fib-ruby.bgv', __dir__)
12
- end
13
-
14
- before :each do
15
- @out = StringIO.new
16
- @commands = Seafoam::Commands.new(@out, {})
17
- end
18
-
19
- describe '#info' do
20
- it 'prints format and version' do
21
- @commands.send :info, @fib_java
22
- lines = @out.string.lines.map(&:rstrip)
23
- expect(lines.first).to eq 'BGV 7.0'
24
- end
25
-
26
- it 'does not work on a graph' do
27
- expect { @commands.send :info, "#{@fib_java}:0" }.to raise_error(ArgumentError)
28
- end
29
- end
30
-
31
- describe '#list' do
32
- it 'prints graphs' do
33
- @commands.send :list, @fib_java
34
- lines = @out.string.lines.map(&:rstrip)
35
- expect(lines.take(5)).to eq [
36
- "#{@fib_java}:0 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase",
37
- "#{@fib_java}:1 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.PhaseSuite",
38
- "#{@fib_java}:2 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.DeadCodeEliminationPhase",
39
- "#{@fib_java}:3 2:Fib.fib(int)/After parsing",
40
- "#{@fib_java}:4 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.CanonicalizerPhase"
41
- ]
42
- expect(lines.drop(lines.length - 5)).to eq [
43
- "#{@fib_java}:49 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.DeadCodeEliminationPhase",
44
- "#{@fib_java}:50 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.PropagateDeoptimizeProbabilityPhase",
45
- "#{@fib_java}:51 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.schedule.SchedulePhase",
46
- "#{@fib_java}:52 2:Fib.fib(int)/After phase org.graalvm.compiler.core.phases.LowTier",
47
- "#{@fib_java}:53 2:Fib.fib(int)/After low tier"
48
- ]
49
- end
50
-
51
- it 'does not work on a graph' do
52
- expect { @commands.send :list, "#{@fib_java}:0" }.to raise_error(ArgumentError)
53
- end
54
- end
55
-
56
- describe '#search' do
57
- it 'finds terms in files' do
58
- @commands.send :search, @fib_java, 'MethodCallTarget'
59
- lines = @out.string.lines.map(&:rstrip)
60
- expect(lines.take(5)).to eq [
61
- "#{@fib_java}:0:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
62
- "#{@fib_java}:0:17 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
63
- "#{@fib_java}:1:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
64
- "#{@fib_java}:1:17 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
65
- "#{@fib_java}:2:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir..."
66
- ]
67
- end
68
-
69
- it 'finds terms in graphs' do
70
- @commands.send :search, "#{@fib_java}:0", 'MethodCallTarget'
71
- lines = @out.string.lines.map(&:rstrip)
72
- expect(lines).to eq [
73
- "#{@fib_java}:0:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
74
- "#{@fib_java}:0:17 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir..."
75
- ]
76
- end
77
-
78
- it 'is case-insensitive' do
79
- @commands.send :search, @fib_java, 'methodcalltarget'
80
- lines = @out.string.lines.map(&:rstrip)
81
- expect(lines.take(5)).to eq [
82
- "#{@fib_java}:0:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
83
- "#{@fib_java}:0:17 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
84
- "#{@fib_java}:1:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
85
- "#{@fib_java}:1:17 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir...",
86
- "#{@fib_java}:2:12 ...class\":\"org.graalvm.compiler.nodes.java.MethodCallTargetNode\",\"name_template\":\"\",\"inputs\":[{\"dir..."
87
- ]
88
- end
89
-
90
- it 'does not work on a node' do
91
- expect { @commands.send :search, "#{@fib_java}:0:0" }.to raise_error(ArgumentError)
92
- end
93
- end
94
-
95
- describe '#edges' do
96
- it 'prints the number of edges and nodes for a graph' do
97
- @commands.send :edges, "#{@fib_java}:0"
98
- lines = @out.string.lines.map(&:rstrip)
99
- expect(lines.first).to eq '22 nodes, 30 edges'
100
- end
101
-
102
- it 'prints the edges for a node' do
103
- @commands.send :edges, "#{@fib_java}:0:13"
104
- lines = @out.string.lines.map(&:rstrip)
105
- expect(lines).to eq [
106
- 'Input:',
107
- ' 13 (Call Fib.fib) <-() 6 (Begin)',
108
- ' 13 (Call Fib.fib) <-() 14 (FrameState Fib#fib Fib.java:20)',
109
- ' 13 (Call Fib.fib) <-() 12 (MethodCallTarget)',
110
- 'Output:',
111
- ' 13 (Call Fib.fib) ->() 18 (Call Fib.fib)',
112
- ' 13 (Call Fib.fib) ->(values) 14 (FrameState Fib#fib Fib.java:20)',
113
- ' 13 (Call Fib.fib) ->(values) 19 (FrameState Fib#fib Fib.java:20)',
114
- ' 13 (Call Fib.fib) ->(x) 20 (+)'
115
- ]
116
- end
117
-
118
- it 'prints details for an edge' do
119
- @commands.send :edges, "#{@fib_java}:0:13-18"
120
- lines = @out.string.lines.map(&:rstrip)
121
- expect(lines.first).to eq '13 (Call Fib.fib) ->() 18 (Call Fib.fib)'
122
- end
123
-
124
- it 'does not work on a file' do
125
- expect { @commands.send :edges, @fib_java }.to raise_error(ArgumentError)
126
- end
127
- end
128
-
129
- describe '#props' do
130
- it 'prints properties for a file' do
131
- @commands.send :props, @fib_java
132
- expect(@out.string.gsub(/\n\n/, "\n")).to eq "{\n \"vm.uuid\": \"28729\"\n}\n"
133
- end
134
-
135
- it 'prints properties for a graph' do
136
- @commands.send :props, "#{@fib_java}:0"
137
- lines = @out.string.lines.map(&:rstrip)
138
- expect(lines[3]).to include '"name": "2:Fib.fib(int)"'
139
- end
140
-
141
- it 'prints properties for a node' do
142
- @commands.send :props, "#{@fib_java}:0:13"
143
- lines = @out.string.lines.map(&:rstrip)
144
- expect(lines[3]).to include '"declaring_class": "Fib"'
145
- end
146
-
147
- it 'prints properties for an edge' do
148
- @commands.send :props, "#{@fib_java}:0:13-18"
149
- lines = @out.string.lines.map(&:rstrip)
150
- expect(lines[2]).to include '"name": "next"'
151
- end
152
- end
153
-
154
- describe '#source' do
155
- it 'prints source information for a node' do
156
- @commands.send :source, "#{@fib_ruby}:8:2443"
157
- expect(@out.string).to eq <<~SOURCE
158
- java.lang.Math#addExact
159
- org.truffleruby.core.numeric.IntegerNodes$AddNode#add
160
- org.truffleruby.core.numeric.IntegerNodesFactory$AddNodeFactory$AddNodeGen#executeAdd
161
- org.truffleruby.core.inlined.InlinedAddNode#intAdd
162
- org.truffleruby.core.inlined.InlinedAddNodeGen#execute
163
- org.truffleruby.language.control.IfElseNode#execute
164
- org.truffleruby.language.control.SequenceNode#execute
165
- org.truffleruby.language.arguments.CheckArityNode#execute
166
- org.truffleruby.language.control.SequenceNode#execute
167
- org.truffleruby.language.methods.CatchForMethodNode#execute
168
- org.truffleruby.language.methods.ExceptionTranslatingNode#execute
169
- org.truffleruby.language.RubyRootNode#execute
170
- org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#executeRootNode
171
- org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#profiledPERoot
172
- SOURCE
173
- end
174
- end
175
-
176
- describe '#render' do
177
- it 'does not work on a file' do
178
- expect { @commands.send :render, @fib_java }.to raise_error(ArgumentError)
179
- end
180
-
181
- it 'can render all BGV files to dot' do
182
- Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
183
- @commands.send :render, "#{file}:7", '--out', 'out.dot'
184
- end
185
- end
186
-
187
- if Seafoam::SpecHelpers.dependencies_installed?
188
- it 'supports -o out.pdf' do
189
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.pdf'
190
- expect(`file out.pdf`).to start_with 'out.pdf: PDF document'
191
- end
192
-
193
- it 'supports -o out.svg' do
194
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.svg'
195
- expect(`file out.svg`).to start_with 'out.svg: SVG Scalable Vector Graphics image'
196
- end
197
-
198
- it 'supports -o out.png' do
199
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.png'
200
- expect(`file out.png`).to start_with 'out.png: PNG image data'
201
- end
202
-
203
- it 'supports -o out.dot' do
204
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.dot'
205
- expect(`file out.dot`).to start_with 'out.dot: ASCII text'
206
- end
207
-
208
- it 'supports spotlighting nodes' do
209
- @commands.send :render, "#{@fib_java}:0", '--spotlight', '13'
210
- end
211
-
212
- it 'does not work on a node' do
213
- expect { @commands.send :render, "#{@fib_java}:0:13" }.to raise_error(ArgumentError)
214
- end
215
- else
216
- it 'raises an exception if Graphviz is not installed' do
217
- expect do
218
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.pdf'
219
- end.to raise_error(RuntimeError, /Could not run Graphviz - is it installed?/)
220
- end
221
- end
222
- end
223
-
224
- describe '#cfg2asm' do
225
- if Seafoam::SpecHelpers.dependencies_installed?
226
- it 'prints format and version' do
227
- @commands.cfg2asm(File.expand_path('../../examples/java/exampleWhile.cfg', __dir__), '--no-comments')
228
- lines = @out.string.lines.map(&:rstrip)
229
- expect(lines[1]).to include "0x117df59e0:\tnop dword ptr [rax + rax]"
230
- expect(lines[-1]).to include "0x117df5a47:\thlt"
231
- end
232
- else
233
- it 'raises an exception if Capstone is not installed' do
234
- expect do
235
- @commands.cfg2asm(File.expand_path('../../examples/java/exampleWhile.cfg', __dir__), '--no-comments')
236
- end.to raise_error(RuntimeError, /Could not load Capstone - is it installed?/)
237
- end
238
- end
239
- end
240
-
241
- describe '#debug' do
242
- it 'does not work with a graph' do
243
- expect { @commands.send :debug, "#{@fib_java}:0" }.to raise_error(ArgumentError)
244
- end
245
- end
246
-
247
- describe '#help' do
248
- it 'does not take any arguments' do
249
- expect { @commands.send :seafoam, '--help', 'foo' }.to raise_error(ArgumentError)
250
- end
251
- end
252
-
253
- describe '#version' do
254
- it 'does not take any arguments' do
255
- expect { @commands.send :version, 'foo' }.to raise_error(ArgumentError)
256
- end
257
- end
258
-
259
- describe '#parse_name' do
260
- it 'parses file.bgv' do
261
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv')
262
- expect(file).to eq 'file.bgv'
263
- expect(graph).to be_nil
264
- expect(node).to be_nil
265
- expect(edge).to be_nil
266
- end
267
-
268
- it 'parses file.bgv:14' do
269
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14')
270
- expect(file).to eq 'file.bgv'
271
- expect(graph).to eq 14
272
- expect(node).to be_nil
273
- expect(edge).to be_nil
274
- end
275
-
276
- it 'parses file.bgv:14:12' do
277
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14:12')
278
- expect(file).to eq 'file.bgv'
279
- expect(graph).to eq 14
280
- expect(node).to eq 12
281
- expect(edge).to be_nil
282
- end
283
-
284
- it 'parses file.bgv:14:12-81' do
285
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14:12-81')
286
- expect(file).to eq 'file.bgv'
287
- expect(graph).to eq 14
288
- expect(node).to eq 12
289
- expect(edge).to eq 81
290
- end
291
-
292
- it 'parses a realistic knarly BGV file name' do
293
- file, graph, node, edge = @commands.send(:parse_name, '../graal_dumps/2019.11.03.19.35.03.828/TruffleHotSpotCompilation-13320[while_loop_at__Users_chrisseaton_src_github.com_Shopify_truffleruby-shopify_src_main_ruby_truffleruby_core_kernel.rb:360<OSR>].bgv:14:12-81')
294
- expect(file).to eq '../graal_dumps/2019.11.03.19.35.03.828/TruffleHotSpotCompilation-13320[while_loop_at__Users_chrisseaton_src_github.com_Shopify_truffleruby-shopify_src_main_ruby_truffleruby_core_kernel.rb:360<OSR>].bgv'
295
- expect(graph).to eq 14
296
- expect(node).to eq 12
297
- expect(edge).to eq 81
298
- end
299
-
300
- it 'parses a BGV file name with periods and colons' do
301
- file, graph, node, edge = @commands.send(:parse_name, 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv:4')
302
- expect(file).to eq 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv'
303
- expect(graph).to eq 4
304
- expect(node).to be_nil
305
- expect(edge).to be_nil
306
- end
307
-
308
- it 'parses a BGV.gz file name with periods and colons' do
309
- file, graph, node, edge = @commands.send(:parse_name, 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv.gz:4')
310
- expect(file).to eq 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv.gz'
311
- expect(graph).to eq 4
312
- expect(node).to be_nil
313
- expect(edge).to be_nil
314
- end
315
- end
316
- end
@@ -1,172 +0,0 @@
1
- require 'seafoam'
2
-
3
- require 'rspec'
4
-
5
- describe Seafoam::Graph do
6
- describe '#initialize' do
7
- it 'set properties' do
8
- graph = Seafoam::Graph.new(a: 12)
9
- expect(graph.props[:a]).to eq 12
10
- end
11
- end
12
-
13
- describe '#create_node' do
14
- it 'adds a node to the graph' do
15
- graph = Seafoam::Graph.new
16
- node = graph.create_node(14)
17
- expect(graph.nodes.values).to include node
18
- end
19
-
20
- it 'set properties' do
21
- graph = Seafoam::Graph.new
22
- node = graph.create_node(14, a: 12)
23
- expect(node.props[:a]).to eq 12
24
- end
25
-
26
- it 'returns the node' do
27
- graph = Seafoam::Graph.new
28
- node = graph.create_node(14)
29
- expect(node.id).to eq 14
30
- end
31
- end
32
-
33
- describe '#create_edge' do
34
- it 'adds an edge to the graph' do
35
- graph = Seafoam::Graph.new
36
- from = graph.create_node(14)
37
- to = graph.create_node(2)
38
- edge = graph.create_edge(from, to)
39
- expect(graph.edges).to include edge
40
- end
41
-
42
- it 'set properties' do
43
- graph = Seafoam::Graph.new
44
- from = graph.create_node(14)
45
- to = graph.create_node(2)
46
- edge = graph.create_edge(from, to, a: 12)
47
- expect(edge.props[:a]).to eq 12
48
- end
49
-
50
- it 'returns the edge' do
51
- graph = Seafoam::Graph.new
52
- from = graph.create_node(14)
53
- to = graph.create_node(2)
54
- edge = graph.create_edge(from, to)
55
- expect(edge.from).to eq from
56
- expect(edge.to).to eq to
57
- end
58
- end
59
- end
60
-
61
- describe Seafoam::Node do
62
- describe '#inputs' do
63
- it 'returns only input edges' do
64
- graph = Seafoam::Graph.new
65
- node_a = graph.create_node(1)
66
- node_b = graph.create_node(2)
67
- node_c = graph.create_node(3)
68
- node_d = graph.create_node(4)
69
- in_edge = graph.create_edge(node_a, node_b)
70
- out_edge = graph.create_edge(node_b, node_c)
71
- unrelated_edge = graph.create_edge(node_c, node_d)
72
- expect(node_b.inputs).to include in_edge
73
- expect(node_b.inputs).to_not include out_edge
74
- expect(node_b.inputs).to_not include unrelated_edge
75
- end
76
- end
77
-
78
- describe '#outputs' do
79
- it 'returns only output edges' do
80
- graph = Seafoam::Graph.new
81
- node_a = graph.create_node(1)
82
- node_b = graph.create_node(2)
83
- node_c = graph.create_node(3)
84
- node_d = graph.create_node(4)
85
- in_edge = graph.create_edge(node_a, node_b)
86
- out_edge = graph.create_edge(node_b, node_c)
87
- unrelated_edge = graph.create_edge(node_c, node_d)
88
- expect(node_b.outputs).to_not include in_edge
89
- expect(node_b.outputs).to include out_edge
90
- expect(node_b.outputs).to_not include unrelated_edge
91
- end
92
- end
93
-
94
- describe '#edges' do
95
- it 'returns both input and output edges' do
96
- graph = Seafoam::Graph.new
97
- node_a = graph.create_node(1)
98
- node_b = graph.create_node(2)
99
- node_c = graph.create_node(3)
100
- node_d = graph.create_node(4)
101
- in_edge = graph.create_edge(node_a, node_b)
102
- out_edge = graph.create_edge(node_b, node_c)
103
- unrelated_edge = graph.create_edge(node_c, node_d)
104
- expect(node_b.edges).to include in_edge
105
- expect(node_b.edges).to include out_edge
106
- expect(node_b.edges).to_not include unrelated_edge
107
- end
108
- end
109
-
110
- describe '#adjacent' do
111
- it 'returns nodes from both input and output edges' do
112
- graph = Seafoam::Graph.new
113
- node_a = graph.create_node(1)
114
- node_b = graph.create_node(2)
115
- node_c = graph.create_node(3)
116
- node_d = graph.create_node(4)
117
- graph.create_edge node_a, node_b
118
- graph.create_edge node_b, node_c
119
- graph.create_edge node_c, node_d
120
- expect(node_b.adjacent).to include node_a
121
- expect(node_b.adjacent).to include node_c
122
- expect(node_b.adjacent).to_not include node_d
123
- end
124
- end
125
-
126
- describe '#id_and_label' do
127
- it 'returns an id and label if there is one' do
128
- node = Seafoam::Node.new(14, label: 'foo')
129
- expect(node.id_and_label).to eq '14 (foo)'
130
- end
131
-
132
- it 'returns just an id if there is no label' do
133
- node = Seafoam::Node.new(14)
134
- expect(node.id_and_label).to eq '14'
135
- end
136
- end
137
- end
138
-
139
- describe Seafoam::Edge do
140
- describe '#from' do
141
- it 'returns the from node' do
142
- graph = Seafoam::Graph.new
143
- node_a = graph.create_node(1)
144
- node_b = graph.create_node(2)
145
- edge = graph.create_edge(node_a, node_b)
146
- expect(edge.from).to eq node_a
147
- end
148
- end
149
-
150
- describe '#to' do
151
- it 'returns the to node' do
152
- graph = Seafoam::Graph.new
153
- node_a = graph.create_node(1)
154
- node_b = graph.create_node(2)
155
- edge = graph.create_edge(node_a, node_b)
156
- expect(edge.to).to eq node_b
157
- end
158
- end
159
-
160
- describe '#nodes' do
161
- it 'returns both the from and to node' do
162
- graph = Seafoam::Graph.new
163
- node_a = graph.create_node(1)
164
- node_b = graph.create_node(2)
165
- node_c = graph.create_node(3)
166
- edge = graph.create_edge(node_a, node_b)
167
- expect(edge.nodes).to include node_a
168
- expect(edge.nodes).to include node_b
169
- expect(edge.nodes).to_not include node_c
170
- end
171
- end
172
- end
@@ -1,63 +0,0 @@
1
- require 'stringio'
2
-
3
- require 'seafoam'
4
-
5
- require 'rspec'
6
-
7
- require_relative 'spec_helpers'
8
-
9
- describe Seafoam::GraphvizWriter do
10
- describe '#write_graph' do
11
- before :all do
12
- file = File.expand_path('../../examples/fib-java.bgv', __dir__)
13
- parser = Seafoam::BGV::BGVParser.new(file)
14
- parser.read_file_header
15
- parser.read_graph_preheader
16
- parser.read_graph_header
17
- @fib_java_graph = parser.read_graph
18
- end
19
-
20
- before :each do
21
- @stream = StringIO.new
22
- @writer = Seafoam::GraphvizWriter.new(@stream)
23
- end
24
-
25
- it 'writes the header' do
26
- @writer.write_graph @fib_java_graph
27
- expect(@stream.string).to start_with 'digraph G {'
28
- end
29
-
30
- it 'writes all graphs' do
31
- Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
32
- parser = Seafoam::BGV::BGVParser.new(file)
33
- parser.read_file_header
34
- parser.skip_document_props
35
- parser.skip_document_props
36
- loop do
37
- index, = parser.read_graph_preheader
38
- break unless index
39
-
40
- parser.read_graph_header
41
- @writer.write_graph parser.read_graph
42
- end
43
- end
44
- end
45
- end
46
-
47
- describe '#quote' do
48
- it 'adds quotes' do
49
- writer = Seafoam::GraphvizWriter.new(nil)
50
- expect(writer.send(:quote, 'foo')).to eq '"foo"'
51
- end
52
-
53
- it 'escapes an existing quote' do
54
- writer = Seafoam::GraphvizWriter.new(nil)
55
- expect(writer.send(:quote, 'foo"bar')).to eq '"foo\"bar"'
56
- end
57
-
58
- it 'escapes an existing escape' do
59
- writer = Seafoam::GraphvizWriter.new(nil)
60
- expect(writer.send(:quote, 'foo\bar')).to eq '"foo\\bar"'
61
- end
62
- end
63
- end
@@ -1,14 +0,0 @@
1
- require 'seafoam'
2
-
3
- require 'rspec'
4
-
5
- require_relative 'spec_helpers'
6
-
7
- describe Seafoam::JSONWriter do
8
- describe '#prepare_json' do
9
- it 'transforms a NaN to the string [NaN]' do
10
- writer = Seafoam::JSONWriter.new(nil)
11
- expect(writer.send(:prepare_json, { a: 1.0, b: Float::NAN, c: 2.0 })).to eq({ a: 1.0, b: '[NaN]', c: 2.0 })
12
- end
13
- end
14
- end
@@ -1,34 +0,0 @@
1
- module Seafoam
2
- module SpecHelpers
3
- SAMPLE_BGV = [
4
- 'fib-java.bgv',
5
- 'fib-js.bgv',
6
- 'fib-ruby.bgv',
7
- 'matmult-java.bgv',
8
- 'matmult-ruby.bgv'
9
- ].map { |f| File.expand_path("../../examples/#{f}", __dir__) }
10
-
11
- def self.example_graph(file, graph_index)
12
- file = File.expand_path("../../examples/#{file}.bgv", __dir__)
13
- parser = Seafoam::BGV::BGVParser.new(file)
14
- parser.read_file_header
15
- parser.skip_document_props
16
- loop do
17
- index, = parser.read_graph_preheader
18
- raise unless index
19
-
20
- if index == graph_index
21
- parser.read_graph_header
22
- break parser.read_graph
23
- else
24
- parser.skip_graph_header
25
- parser.skip_graph
26
- end
27
- end
28
- end
29
-
30
- def self.dependencies_installed?
31
- ENV['NO_DEPENDENCIES_INSTALLED'].nil?
32
- end
33
- end
34
- end
@@ -1,38 +0,0 @@
1
- require 'seafoam'
2
-
3
- require 'rspec'
4
-
5
- describe Seafoam::Spotlight do
6
- before :each do
7
- file = File.expand_path('../../examples/fib-java.bgv', __dir__)
8
- parser = Seafoam::BGV::BGVParser.new(file)
9
- parser.read_file_header
10
- parser.skip_document_props
11
- parser.read_graph_preheader
12
- parser.read_graph_header
13
- @graph = parser.read_graph
14
- end
15
-
16
- it 'marks individual nodes as lit' do
17
- spotlight = Seafoam::Spotlight.new(@graph)
18
- spotlight.light @graph.nodes[13]
19
- expect(@graph.nodes[13].props[:spotlight]).to eq 'lit'
20
- end
21
-
22
- it 'marks surrounding nodes as shaded' do
23
- spotlight = Seafoam::Spotlight.new(@graph)
24
- spotlight.light @graph.nodes[13]
25
- expect(@graph.nodes.values
26
- .select { |n| n.props[:spotlight] == 'shaded' }
27
- .map(&:id).sort).to eq [6, 12, 14, 18, 19, 20]
28
- end
29
-
30
- it 'marks other nodes as hidden' do
31
- spotlight = Seafoam::Spotlight.new(@graph)
32
- spotlight.light @graph.nodes[13]
33
- spotlight.shade
34
- expect(@graph.nodes.values
35
- .select { |n| n.props[:hidden] }
36
- .map(&:id).sort).to eq [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 21]
37
- end
38
- end
data/tools/render-all DELETED
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $LOAD_PATH.push File.expand_path('../lib', __dir__)
4
- require 'seafoam'
5
-
6
- config = Seafoam::Config.new
7
- commands = Seafoam::Commands.new($stdout, config)
8
-
9
- extra = {
10
- 'exampleArrayRead' => [42],
11
- 'exampleDoubleSynchronized' => [48, 49],
12
- 'exampleFieldRead' => [42],
13
- 'exampleFullEscape' => [33],
14
- 'exampleInstanceOfManyImpls' => [65],
15
- 'exampleInstanceOfOneImpl' => [65],
16
- 'exampleInterfaceCallOneImpl' => [9],
17
- 'exampleInterfaceCallManyImpls' => [9],
18
- 'exampleLocalSynchronized' => [33],
19
- 'exampleNoEscape' => [33],
20
- 'examplePartialEscape' => [33],
21
- 'exampleUnsafeRead' => [42]
22
- }
23
-
24
- Dir.glob(File.expand_path('../examples/java/*.bgv', __dir__)).each do |bgv|
25
- basename = File.basename(bgv, '.bgv')
26
- phases = [6]
27
- phases.push(*(extra[basename] || []))
28
- extra_options = []
29
- if basename == 'exampleLocalVariablesState'
30
- extra_options.push '--show-frame-state'
31
- end
32
- phases.each do |phase|
33
- commands.seafoam "#{bgv}:#{phase}", 'render', *extra_options, '--out', File.expand_path("../#{basename}@#{phase}.png", __dir__)
34
- commands.seafoam "#{bgv}:#{phase}", 'render', *extra_options, '--out', File.expand_path("../#{basename}@#{phase}.svg", __dir__)
35
- end
36
- end