seafoam 0.5 → 0.9

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 (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