seafoam 0.8 → 0.12

Sign up to get free protection for your applications and to get access to all the features.
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