seafoam 0.8 → 0.12

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bgv2isabelle +1 -5
  3. data/bin/bgv2json +1 -5
  4. data/bin/seafoam +1 -5
  5. data/lib/seafoam/bgv/bgv_parser.rb +1 -2
  6. data/lib/seafoam/commands.rb +135 -101
  7. data/lib/seafoam/formatters/base.rb +88 -0
  8. data/lib/seafoam/formatters/formatters.rb +8 -0
  9. data/lib/seafoam/formatters/json.rb +82 -0
  10. data/lib/seafoam/formatters/text.rb +70 -0
  11. data/lib/seafoam/graal/graph_description.rb +22 -0
  12. data/lib/seafoam/graal/pi.rb +18 -0
  13. data/lib/seafoam/graal/source.rb +5 -9
  14. data/lib/seafoam/graph.rb +9 -1
  15. data/lib/seafoam/graphviz_writer.rb +3 -0
  16. data/lib/seafoam/json_writer.rb +1 -3
  17. data/lib/seafoam/{annotators → passes}/fallback.rb +4 -4
  18. data/lib/seafoam/{annotators → passes}/graal.rb +43 -15
  19. data/lib/seafoam/passes/truffle.rb +58 -0
  20. data/lib/seafoam/passes.rb +61 -0
  21. data/lib/seafoam/version.rb +1 -1
  22. data/lib/seafoam.rb +7 -6
  23. metadata +17 -81
  24. data/.github/probots.yml +0 -2
  25. data/.github/workflows/workflows.yml +0 -40
  26. data/.gitignore +0 -6
  27. data/.rubocop.yml +0 -37
  28. data/.ruby-version +0 -1
  29. data/.seafoam/config +0 -1
  30. data/CODE_OF_CONDUCT.md +0 -128
  31. data/CONTRIBUTING.md +0 -5
  32. data/Gemfile +0 -2
  33. data/Gemfile.lock +0 -59
  34. data/LICENSE.md +0 -7
  35. data/README.md +0 -378
  36. data/bin/cfg2asm +0 -24
  37. data/demos/box-unbox-stats +0 -65
  38. data/docs/annotators.md +0 -43
  39. data/docs/bgv.md +0 -294
  40. data/docs/getting-graphs.md +0 -63
  41. data/docs/images/igv.png +0 -0
  42. data/docs/images/seafoam.png +0 -0
  43. data/docs/images/spotlight-igv.png +0 -0
  44. data/docs/images/spotlight-seafoam.png +0 -0
  45. data/docs/json.md +0 -35
  46. data/examples/Fib.java +0 -24
  47. data/examples/MatMult.java +0 -39
  48. data/examples/fib-java.bgv.gz +0 -0
  49. data/examples/fib.js +0 -15
  50. data/examples/fib.rb +0 -15
  51. data/examples/identity.rb +0 -13
  52. data/examples/java/Irreducible.class +0 -0
  53. data/examples/java/Irreducible.j +0 -35
  54. data/examples/java/IrreducibleDecompiled.java +0 -21
  55. data/examples/java/JavaExamples.java +0 -418
  56. data/examples/matmult.rb +0 -29
  57. data/examples/overflow.rb +0 -13
  58. data/examples/ruby/clamps.rb +0 -20
  59. data/examples/ruby/graal.patch +0 -15
  60. data/examples/ruby/ruby_examples.rb +0 -278
  61. data/lib/seafoam/annotators.rb +0 -54
  62. data/lib/seafoam/cfg/cfg_parser.rb +0 -93
  63. data/lib/seafoam/cfg/disassembler.rb +0 -70
  64. data/lib/seafoam/config.rb +0 -34
  65. data/seafoam.gemspec +0 -22
  66. data/spec/seafoam/annotators/fallback_spec.rb +0 -69
  67. data/spec/seafoam/annotators/graal_spec.rb +0 -96
  68. data/spec/seafoam/annotators_spec.rb +0 -61
  69. data/spec/seafoam/bgv/bgv_parser_spec.rb +0 -167
  70. data/spec/seafoam/binary/io_binary_reader_spec.rb +0 -176
  71. data/spec/seafoam/cfg/cfg_parser_spec.rb +0 -21
  72. data/spec/seafoam/cfg/disassembler_spec.rb +0 -32
  73. data/spec/seafoam/command_spec.rb +0 -314
  74. data/spec/seafoam/graph_spec.rb +0 -172
  75. data/spec/seafoam/graphviz_writer_spec.rb +0 -63
  76. data/spec/seafoam/json_writer_spec.rb +0 -14
  77. data/spec/seafoam/spec_helpers.rb +0 -34
  78. data/spec/seafoam/spotlight_spec.rb +0 -38
  79. data/tools/render-all +0 -36
@@ -1,314 +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 17:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase",
37
- "#{@fib_java}:1 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.PhaseSuite",
38
- "#{@fib_java}:2 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.DeadCodeEliminationPhase",
39
- "#{@fib_java}:3 17:Fib.fib(int)/After parsing",
40
- "#{@fib_java}:4 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.CanonicalizerPhase"
41
- ]
42
- expect(lines.drop(lines.length - 5)).to eq [
43
- "#{@fib_java}:51 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.DeadCodeEliminationPhase",
44
- "#{@fib_java}:52 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.PropagateDeoptimizeProbabilityPhase",
45
- "#{@fib_java}:53 17:Fib.fib(int)/After phase org.graalvm.compiler.phases.schedule.SchedulePhase",
46
- "#{@fib_java}:54 17:Fib.fib(int)/After phase org.graalvm.compiler.core.phases.LowTier",
47
- "#{@fib_java}:55 17: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 '21 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\": \"94468\"\n}\n"
133
- end
134
-
135
- it 'prints properties for a graph' do
136
- @commands.send :props, "#{@fib_java}:0"
137
- expect(@out.string).to include '"scope": "main.Compiling.GraalCompiler.FrontEnd.PhaseSuite.GraphBuilderPhase"'
138
- end
139
-
140
- it 'prints properties for a node' do
141
- @commands.send :props, "#{@fib_java}:0:13"
142
- expect(@out.string).to include '"declaring_class": "Fib"'
143
- end
144
-
145
- it 'prints properties for an edge' do
146
- @commands.send :props, "#{@fib_java}:0:13-18"
147
- lines = @out.string.lines.map(&:rstrip)
148
- expect(lines[2]).to include '"name": "next"'
149
- end
150
- end
151
-
152
- describe '#source' do
153
- it 'prints source information for a node' do
154
- @commands.send :source, "#{@fib_ruby}:8:2443"
155
- expect(@out.string).to eq <<~SOURCE
156
- java.lang.Math#addExact
157
- org.truffleruby.core.numeric.IntegerNodes$AddNode#add
158
- org.truffleruby.core.numeric.IntegerNodesFactory$AddNodeFactory$AddNodeGen#executeAdd
159
- org.truffleruby.core.inlined.InlinedAddNode#intAdd
160
- org.truffleruby.core.inlined.InlinedAddNodeGen#execute
161
- org.truffleruby.language.control.IfElseNode#execute
162
- org.truffleruby.language.control.SequenceNode#execute
163
- org.truffleruby.language.arguments.CheckArityNode#execute
164
- org.truffleruby.language.control.SequenceNode#execute
165
- org.truffleruby.language.methods.CatchForMethodNode#execute
166
- org.truffleruby.language.methods.ExceptionTranslatingNode#execute
167
- org.truffleruby.language.RubyRootNode#execute
168
- org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#executeRootNode
169
- org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#profiledPERoot
170
- SOURCE
171
- end
172
- end
173
-
174
- describe '#render' do
175
- it 'does not work on a file' do
176
- expect { @commands.send :render, @fib_java }.to raise_error(ArgumentError)
177
- end
178
-
179
- it 'can render all BGV files to dot' do
180
- Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
181
- @commands.send :render, "#{file}:7", '--out', 'out.dot'
182
- end
183
- end
184
-
185
- if Seafoam::SpecHelpers.dependencies_installed?
186
- it 'supports -o out.pdf' do
187
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.pdf'
188
- expect(`file out.pdf`).to start_with 'out.pdf: PDF document'
189
- end
190
-
191
- it 'supports -o out.svg' do
192
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.svg'
193
- expect(`file out.svg`).to start_with 'out.svg: SVG Scalable Vector Graphics image'
194
- end
195
-
196
- it 'supports -o out.png' do
197
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.png'
198
- expect(`file out.png`).to start_with 'out.png: PNG image data'
199
- end
200
-
201
- it 'supports -o out.dot' do
202
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.dot'
203
- expect(`file out.dot`).to start_with 'out.dot: ASCII text'
204
- end
205
-
206
- it 'supports spotlighting nodes' do
207
- @commands.send :render, "#{@fib_java}:0", '--spotlight', '13'
208
- end
209
-
210
- it 'does not work on a node' do
211
- expect { @commands.send :render, "#{@fib_java}:0:13" }.to raise_error(ArgumentError)
212
- end
213
- else
214
- it 'raises an exception if Graphviz is not installed' do
215
- expect do
216
- @commands.send :render, "#{@fib_java}:0", '--out', 'out.pdf'
217
- end.to raise_error(RuntimeError, /Could not run Graphviz - is it installed?/)
218
- end
219
- end
220
- end
221
-
222
- describe '#cfg2asm' do
223
- if Seafoam::SpecHelpers.dependencies_installed?
224
- it 'prints format and version' do
225
- @commands.cfg2asm(File.expand_path('../../examples/java/exampleWhile.cfg', __dir__), '--no-comments')
226
- lines = @out.string.lines.map(&:rstrip)
227
- expect(lines[1]).to include "0x117df59e0:\tnop dword ptr [rax + rax]"
228
- expect(lines[-1]).to include "0x117df5a47:\thlt"
229
- end
230
- else
231
- it 'raises an exception if Capstone is not installed' do
232
- expect do
233
- @commands.cfg2asm(File.expand_path('../../examples/java/exampleWhile.cfg', __dir__), '--no-comments')
234
- end.to raise_error(RuntimeError, /Could not load Capstone - is it installed?/)
235
- end
236
- end
237
- end
238
-
239
- describe '#debug' do
240
- it 'does not work with a graph' do
241
- expect { @commands.send :debug, "#{@fib_java}:0" }.to raise_error(ArgumentError)
242
- end
243
- end
244
-
245
- describe '#help' do
246
- it 'does not take any arguments' do
247
- expect { @commands.send :seafoam, '--help', 'foo' }.to raise_error(ArgumentError)
248
- end
249
- end
250
-
251
- describe '#version' do
252
- it 'does not take any arguments' do
253
- expect { @commands.send :version, 'foo' }.to raise_error(ArgumentError)
254
- end
255
- end
256
-
257
- describe '#parse_name' do
258
- it 'parses file.bgv' do
259
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv')
260
- expect(file).to eq 'file.bgv'
261
- expect(graph).to be_nil
262
- expect(node).to be_nil
263
- expect(edge).to be_nil
264
- end
265
-
266
- it 'parses file.bgv:14' do
267
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14')
268
- expect(file).to eq 'file.bgv'
269
- expect(graph).to eq 14
270
- expect(node).to be_nil
271
- expect(edge).to be_nil
272
- end
273
-
274
- it 'parses file.bgv:14:12' do
275
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14:12')
276
- expect(file).to eq 'file.bgv'
277
- expect(graph).to eq 14
278
- expect(node).to eq 12
279
- expect(edge).to be_nil
280
- end
281
-
282
- it 'parses file.bgv:14:12-81' do
283
- file, graph, node, edge = @commands.send(:parse_name, 'file.bgv:14:12-81')
284
- expect(file).to eq 'file.bgv'
285
- expect(graph).to eq 14
286
- expect(node).to eq 12
287
- expect(edge).to eq 81
288
- end
289
-
290
- it 'parses a realistic knarly BGV file name' do
291
- 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')
292
- 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'
293
- expect(graph).to eq 14
294
- expect(node).to eq 12
295
- expect(edge).to eq 81
296
- end
297
-
298
- it 'parses a BGV file name with periods and colons' do
299
- file, graph, node, edge = @commands.send(:parse_name, 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv:4')
300
- expect(file).to eq 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv'
301
- expect(graph).to eq 4
302
- expect(node).to be_nil
303
- expect(edge).to be_nil
304
- end
305
-
306
- it 'parses a BGV.gz file name with periods and colons' do
307
- file, graph, node, edge = @commands.send(:parse_name, 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv.gz:4')
308
- expect(file).to eq 'TruffleHotSpotCompilation-13029[Truffle::ThreadOperations.detect_recursion_<split-3a5973bc>].bgv.gz'
309
- expect(graph).to eq 4
310
- expect(node).to be_nil
311
- expect(edge).to be_nil
312
- end
313
- end
314
- 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, 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