seafoam 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.github/probots.yml +2 -0
  3. data/.github/workflows/rubocop.yml +10 -0
  4. data/.github/workflows/specs.yml +19 -0
  5. data/.gitignore +7 -0
  6. data/.rubocop.yml +34 -0
  7. data/.ruby-version +1 -0
  8. data/.seafoam/config +1 -0
  9. data/CODE_OF_CONDUCT.md +128 -0
  10. data/CONTRIBUTING.md +5 -0
  11. data/Gemfile +2 -0
  12. data/LICENSE.md +7 -0
  13. data/README.md +298 -0
  14. data/bin/bgv2isabelle +53 -0
  15. data/bin/bgv2json +42 -0
  16. data/bin/seafoam +24 -0
  17. data/docs/annotators.md +43 -0
  18. data/docs/bgv.md +284 -0
  19. data/docs/getting-graphs.md +47 -0
  20. data/examples/Fib.java +24 -0
  21. data/examples/MatMult.java +39 -0
  22. data/examples/fib-java.bgv +0 -0
  23. data/examples/fib-js.bgv +0 -0
  24. data/examples/fib-ruby.bgv +0 -0
  25. data/examples/fib.js +15 -0
  26. data/examples/fib.rb +15 -0
  27. data/examples/identity.bgv +0 -0
  28. data/examples/identity.rb +13 -0
  29. data/examples/java/Irreducible.j +35 -0
  30. data/examples/java/IrreducibleDecompiled.java +21 -0
  31. data/examples/java/JavaExamples.java +418 -0
  32. data/examples/java/exampleArithOperator.bgv +0 -0
  33. data/examples/java/exampleArithOperator.cfg +925 -0
  34. data/examples/java/exampleArrayAllocation.bgv +0 -0
  35. data/examples/java/exampleArrayAllocation.cfg +5268 -0
  36. data/examples/java/exampleArrayRead.bgv +0 -0
  37. data/examples/java/exampleArrayRead.cfg +2263 -0
  38. data/examples/java/exampleArrayWrite.bgv +0 -0
  39. data/examples/java/exampleArrayWrite.cfg +2315 -0
  40. data/examples/java/exampleCatch.bgv +0 -0
  41. data/examples/java/exampleCatch.cfg +4150 -0
  42. data/examples/java/exampleCompareOperator.bgv +0 -0
  43. data/examples/java/exampleCompareOperator.cfg +1109 -0
  44. data/examples/java/exampleDoubleSynchronized.bgv +0 -0
  45. data/examples/java/exampleDoubleSynchronized.cfg +26497 -0
  46. data/examples/java/exampleExactArith.bgv +0 -0
  47. data/examples/java/exampleExactArith.cfg +1888 -0
  48. data/examples/java/exampleFieldRead.bgv +0 -0
  49. data/examples/java/exampleFieldRead.cfg +1228 -0
  50. data/examples/java/exampleFieldWrite.bgv +0 -0
  51. data/examples/java/exampleFieldWrite.cfg +1102 -0
  52. data/examples/java/exampleFor.bgv +0 -0
  53. data/examples/java/exampleFor.cfg +3936 -0
  54. data/examples/java/exampleFullEscape.bgv +0 -0
  55. data/examples/java/exampleFullEscape.cfg +5893 -0
  56. data/examples/java/exampleIf.bgv +0 -0
  57. data/examples/java/exampleIf.cfg +2462 -0
  58. data/examples/java/exampleIfNeverTaken.bgv +0 -0
  59. data/examples/java/exampleIfNeverTaken.cfg +2476 -0
  60. data/examples/java/exampleInstanceOfManyImpls.bgv +0 -0
  61. data/examples/java/exampleInstanceOfManyImpls.cfg +6391 -0
  62. data/examples/java/exampleInstanceOfOneImpl.bgv +0 -0
  63. data/examples/java/exampleInstanceOfOneImpl.cfg +2604 -0
  64. data/examples/java/exampleIntSwitch.bgv +0 -0
  65. data/examples/java/exampleIntSwitch.cfg +3121 -0
  66. data/examples/java/exampleInterfaceCallManyImpls.bgv +0 -0
  67. data/examples/java/exampleInterfaceCallManyImpls.cfg +1358 -0
  68. data/examples/java/exampleInterfaceCallOneImpl.bgv +0 -0
  69. data/examples/java/exampleInterfaceCallOneImpl.cfg +3859 -0
  70. data/examples/java/exampleLocalInstanceOf.bgv +0 -0
  71. data/examples/java/exampleLocalInstanceOf.cfg +5276 -0
  72. data/examples/java/exampleLocalSynchronized.bgv +0 -0
  73. data/examples/java/exampleLocalSynchronized.cfg +1364 -0
  74. data/examples/java/exampleLocalVariables.bgv +0 -0
  75. data/examples/java/exampleLocalVariables.cfg +1195 -0
  76. data/examples/java/exampleLocalVariablesState.bgv +0 -0
  77. data/examples/java/exampleLocalVariablesState.cfg +1673 -0
  78. data/examples/java/exampleNestedWhile.bgv +0 -0
  79. data/examples/java/exampleNestedWhile.cfg +15499 -0
  80. data/examples/java/exampleNestedWhileBreak.bgv +0 -0
  81. data/examples/java/exampleNestedWhileBreak.cfg +11162 -0
  82. data/examples/java/exampleNoEscape.bgv +0 -0
  83. data/examples/java/exampleNoEscape.cfg +974 -0
  84. data/examples/java/exampleObjectAllocation.bgv +0 -0
  85. data/examples/java/exampleObjectAllocation.cfg +5287 -0
  86. data/examples/java/examplePartialEscape.bgv +0 -0
  87. data/examples/java/examplePartialEscape.cfg +7042 -0
  88. data/examples/java/examplePhi.bgv +0 -0
  89. data/examples/java/examplePhi.cfg +3227 -0
  90. data/examples/java/exampleReducible.bgv +0 -0
  91. data/examples/java/exampleReducible.cfg +5578 -0
  92. data/examples/java/exampleSimpleCall.bgv +0 -0
  93. data/examples/java/exampleSimpleCall.cfg +1435 -0
  94. data/examples/java/exampleStamp.bgv +0 -0
  95. data/examples/java/exampleStamp.cfg +913 -0
  96. data/examples/java/exampleStaticCall.bgv +0 -0
  97. data/examples/java/exampleStaticCall.cfg +1154 -0
  98. data/examples/java/exampleStringSwitch.bgv +0 -0
  99. data/examples/java/exampleStringSwitch.cfg +15377 -0
  100. data/examples/java/exampleSynchronized.bgv +0 -0
  101. data/examples/java/exampleSynchronized.cfg +26027 -0
  102. data/examples/java/exampleThrow.bgv +0 -0
  103. data/examples/java/exampleThrow.cfg +780 -0
  104. data/examples/java/exampleThrowCatch.bgv +0 -0
  105. data/examples/java/exampleThrowCatch.cfg +744 -0
  106. data/examples/java/exampleUnsafeRead.bgv +0 -0
  107. data/examples/java/exampleUnsafeRead.cfg +912 -0
  108. data/examples/java/exampleUnsafeWrite.bgv +0 -0
  109. data/examples/java/exampleUnsafeWrite.cfg +962 -0
  110. data/examples/java/exampleWhile.bgv +0 -0
  111. data/examples/java/exampleWhile.cfg +3936 -0
  112. data/examples/java/exampleWhileBreak.bgv +0 -0
  113. data/examples/java/exampleWhileBreak.cfg +5963 -0
  114. data/examples/matmult-java.bgv +0 -0
  115. data/examples/matmult-ruby.bgv +0 -0
  116. data/examples/matmult.rb +29 -0
  117. data/examples/overflow.bgv +0 -0
  118. data/examples/overflow.rb +13 -0
  119. data/lib/seafoam.rb +13 -0
  120. data/lib/seafoam/annotators.rb +54 -0
  121. data/lib/seafoam/annotators/fallback.rb +27 -0
  122. data/lib/seafoam/annotators/graal.rb +376 -0
  123. data/lib/seafoam/bgv/bgv_parser.rb +602 -0
  124. data/lib/seafoam/binary/binary_reader.rb +21 -0
  125. data/lib/seafoam/binary/io_binary_reader.rb +88 -0
  126. data/lib/seafoam/colors.rb +18 -0
  127. data/lib/seafoam/commands.rb +447 -0
  128. data/lib/seafoam/config.rb +34 -0
  129. data/lib/seafoam/graph.rb +91 -0
  130. data/lib/seafoam/graphviz_writer.rb +213 -0
  131. data/lib/seafoam/spotlight.rb +28 -0
  132. data/lib/seafoam/version.rb +5 -0
  133. data/seafoam.gemspec +20 -0
  134. data/spec/seafoam/annotators/fallback_spec.rb +69 -0
  135. data/spec/seafoam/annotators/graal_spec.rb +96 -0
  136. data/spec/seafoam/annotators_spec.rb +61 -0
  137. data/spec/seafoam/bgv/bgv_parser_spec.rb +144 -0
  138. data/spec/seafoam/bgv/fixtures/not.bgv +1 -0
  139. data/spec/seafoam/bgv/fixtures/unsupported.bgv +1 -0
  140. data/spec/seafoam/binary/io_binary_reader_spec.rb +176 -0
  141. data/spec/seafoam/command_spec.rb +252 -0
  142. data/spec/seafoam/graph_spec.rb +172 -0
  143. data/spec/seafoam/graphviz_writer_spec.rb +63 -0
  144. data/spec/seafoam/spec_helpers.rb +30 -0
  145. data/spec/seafoam/spotlight_spec.rb +38 -0
  146. data/tools/render-all +36 -0
  147. metadata +238 -0
@@ -0,0 +1,96 @@
1
+ require 'seafoam'
2
+
3
+ require 'rspec'
4
+
5
+ require_relative '../spec_helpers'
6
+
7
+ describe Seafoam::Annotators::GraalAnnotator do
8
+ it 'applies to Graal graphs' do
9
+ expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-java', 0))).to be true
10
+ end
11
+
12
+ it 'does not apply to Truffle trees' do
13
+ expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-js', 0))).to be false
14
+ end
15
+
16
+ it 'applies to Truffle graphs' do
17
+ expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-js', 2))).to be true
18
+ end
19
+
20
+ describe 'when run' do
21
+ describe 'without options' do
22
+ before :all do
23
+ @graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
24
+ annotator = Seafoam::Annotators::GraalAnnotator.new({})
25
+ annotator.annotate @graph
26
+ end
27
+
28
+ it 'annotates all nodes with a kind' do
29
+ expect(@graph.nodes.values.any? { |n| n.props[:kind].nil? }).to be_falsey
30
+ end
31
+
32
+ it 'annotates all nodes with a label' do
33
+ expect(@graph.nodes.values.any? { |n| n.props[:label].nil? }).to be_falsey
34
+ end
35
+
36
+ it 'annotates all edges with a kind' do
37
+ expect(@graph.edges.any? { |e| e.props[:kind].nil? }).to be_falsey
38
+ end
39
+
40
+ it 'annotates negated GuardNodes with "Guard not, else ..."' do
41
+ expect(@graph.nodes[561].props['negated']).to be true
42
+ expect(@graph.nodes[561].props[:label]).to start_with 'Guard not, else'
43
+ end
44
+
45
+ it 'annotates not negated GuardNodes with "Guard, else ..."' do
46
+ expect(@graph.nodes[559].props['negated']).to be false
47
+ expect(@graph.nodes[559].props[:label]).to start_with 'Guard, else'
48
+ end
49
+ end
50
+
51
+ describe 'with :hide_frame_state' do
52
+ before :all do
53
+ @graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
54
+ annotator = Seafoam::Annotators::GraalAnnotator.new(hide_frame_state: true)
55
+ annotator.annotate @graph
56
+ end
57
+
58
+ it 'sets the hidden property on all frame state nodes' do
59
+ frame_state_nodes = @graph.nodes.values.select do |n|
60
+ Seafoam::Annotators::GraalAnnotator::FRAME_STATE_NODES.include?(n.props.dig(:node_class, :node_class))
61
+ end
62
+ expect(frame_state_nodes.all? { |n| n.props[:hidden] }).to be_truthy
63
+ end
64
+ end
65
+
66
+ describe 'with :hide_floating' do
67
+ before :all do
68
+ @graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
69
+ annotator = Seafoam::Annotators::GraalAnnotator.new(hide_floating: true)
70
+ annotator.annotate @graph
71
+ end
72
+
73
+ it 'sets the hidden property on all nodes without a control edge' do
74
+ nodes_without_control_edge = @graph.nodes.values.select do |n|
75
+ n.edges.none? { |e| e.props[:kind] == 'control' }
76
+ end
77
+ expect(nodes_without_control_edge.all? { |n| n.props[:hidden] }).to be_truthy
78
+ end
79
+ end
80
+
81
+ describe 'with :reduce_edges' do
82
+ before :all do
83
+ @graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
84
+ annotator = Seafoam::Annotators::GraalAnnotator.new(reduce_edges: true)
85
+ annotator.annotate @graph
86
+ end
87
+
88
+ it 'inlines all constant nodes' do
89
+ constant_nodes = @graph.nodes.values.select do |n|
90
+ Seafoam::Annotators::GraalAnnotator::SIMPLE_INPUTS.include?(n.props.dig(:node_class, :node_class))
91
+ end
92
+ expect(constant_nodes.all? { |n| n.props[:inlined] }).to be_truthy
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,61 @@
1
+ require 'seafoam'
2
+
3
+ require 'rspec'
4
+
5
+ describe Seafoam::Annotators do
6
+ describe '#annotate' do
7
+ it 'asks annotators if they apply' do
8
+ check_applied = false
9
+
10
+ Class.new(Seafoam::Annotator) do
11
+ singleton_class.define_method(:applies?) do |_graph|
12
+ check_applied = true
13
+ false
14
+ end
15
+ end
16
+
17
+ Seafoam::Annotators.apply(Seafoam::Graph.new)
18
+ expect(check_applied).to be true
19
+ end
20
+
21
+ it 'runs annotators that apply' do
22
+ check_annotated = false
23
+
24
+ Class.new(Seafoam::Annotator) do
25
+ singleton_class.define_method(:applies?) do |_graph|
26
+ true
27
+ end
28
+
29
+ define_method(:annotate) do |_graph|
30
+ check_annotated = true
31
+ end
32
+ end
33
+
34
+ Seafoam::Annotators.apply(Seafoam::Graph.new)
35
+ expect(check_annotated).to be true
36
+ end
37
+ end
38
+
39
+ describe '#annotators' do
40
+ it 'returns the standard annotators' do
41
+ annotators = Seafoam::Annotators.annotators
42
+ expect(annotators).to include Seafoam::Annotators::FallbackAnnotator
43
+ expect(annotators).to include Seafoam::Annotators::GraalAnnotator
44
+ end
45
+
46
+ it 'returns custom annotators' do
47
+ custom_annotator = Class.new(Seafoam::Annotator) do
48
+ def self.applies?(_graph)
49
+ false
50
+ end
51
+ end
52
+ annotators = Seafoam::Annotators.annotators
53
+ expect(annotators).to include custom_annotator
54
+ end
55
+
56
+ it 'returns the FallbackAnnotator annotator last' do
57
+ annotators = Seafoam::Annotators.annotators
58
+ expect(annotators.last).to eq Seafoam::Annotators::FallbackAnnotator
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,144 @@
1
+ require 'seafoam'
2
+
3
+ require 'rspec'
4
+
5
+ require_relative '../spec_helpers'
6
+
7
+ describe Seafoam::BGV::BGVParser do
8
+ before :all do
9
+ @fib_java_bgv = File.expand_path('../../../examples/fib-java.bgv', __dir__)
10
+ end
11
+
12
+ it 'can read full files' do
13
+ Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
14
+ parser = Seafoam::BGV::BGVParser.new(File.new(file))
15
+ parser.read_file_header
16
+ parser.skip_document_props
17
+ loop do
18
+ index, = parser.read_graph_preheader
19
+ break unless index
20
+
21
+ parser.read_graph_header
22
+ parser.read_graph
23
+ end
24
+ end
25
+ end
26
+
27
+ it 'can skip full files' do
28
+ Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
29
+ parser = Seafoam::BGV::BGVParser.new(File.new(file))
30
+ parser.read_file_header
31
+ parser.skip_document_props
32
+ loop do
33
+ index, = parser.read_graph_preheader
34
+ break unless index
35
+
36
+ parser.skip_graph_header
37
+ parser.skip_graph
38
+ end
39
+ end
40
+ end
41
+
42
+ it 'can alternate skipping and reading full files' do
43
+ Seafoam::SpecHelpers::SAMPLE_BGV.each do |file|
44
+ parser = Seafoam::BGV::BGVParser.new(File.new(file))
45
+ parser.read_file_header
46
+ parser.skip_document_props
47
+ skip = false
48
+ loop do
49
+ index, = parser.read_graph_preheader
50
+ break unless index
51
+
52
+ if skip
53
+ parser.skip_graph_header
54
+ parser.skip_graph
55
+ else
56
+ parser.read_graph_header
57
+ parser.read_graph
58
+ end
59
+ skip = !skip
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '#read_file_header' do
65
+ it 'produces a version' do
66
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
67
+ expect(parser.read_file_header).to eq [6, 1]
68
+ end
69
+
70
+ it 'raises an error for files which are not BGV' do
71
+ parser = Seafoam::BGV::BGVParser.new(File.new(File.expand_path('fixtures/not.bgv', __dir__)))
72
+ expect { parser.read_file_header }.to raise_error(EncodingError)
73
+ end
74
+
75
+ it 'raises an error for files which are an unsupported version of BGV' do
76
+ parser = Seafoam::BGV::BGVParser.new(File.new(File.expand_path('fixtures/unsupported.bgv', __dir__)))
77
+ expect { parser.read_file_header }.to raise_error(NotImplementedError)
78
+ end
79
+
80
+ it 'does not raise an error for an unsupported version of BGV if version_check is disabled' do
81
+ parser = Seafoam::BGV::BGVParser.new(File.new(File.expand_path('fixtures/unsupported.bgv', __dir__)))
82
+ expect(parser.read_file_header(version_check: false)).to eq [7, 2]
83
+ end
84
+ end
85
+
86
+ describe '#read_graph_preheader' do
87
+ it 'produces an index and id' do
88
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
89
+ parser.read_file_header
90
+ parser.skip_document_props
91
+ expect(parser.read_graph_preheader).to eq [0, 0]
92
+ end
93
+
94
+ it 'returns nil for end of file' do
95
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
96
+ parser.read_file_header
97
+ parser.skip_document_props
98
+ 51.times do
99
+ expect(parser.read_graph_preheader).to_not be_nil
100
+ parser.skip_graph_header
101
+ parser.skip_graph
102
+ end
103
+ expect(parser.read_graph_preheader).to be_nil
104
+ end
105
+
106
+ it 'returns unique indicies' do
107
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
108
+ parser.read_file_header
109
+ parser.skip_document_props
110
+ indicies = []
111
+ 5.times do
112
+ index, = parser.read_graph_preheader
113
+ expect(indicies).to_not include index
114
+ indicies.push index
115
+ parser.skip_graph_header
116
+ parser.skip_graph
117
+ end
118
+ end
119
+ end
120
+
121
+ describe '#read_graph_header' do
122
+ it 'produces an expected header' do
123
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
124
+ parser.read_file_header
125
+ parser.skip_document_props
126
+ parser.read_graph_preheader
127
+ header = parser.read_graph_header
128
+ expect(header[:props]['scope']).to eq 'main.Compiling.GraalCompiler.FrontEnd.PhaseSuite.GraphBuilderPhase'
129
+ end
130
+ end
131
+
132
+ describe '#read_graph' do
133
+ it 'produces an expected graph' do
134
+ parser = Seafoam::BGV::BGVParser.new(File.new(@fib_java_bgv))
135
+ parser.read_file_header
136
+ parser.skip_document_props
137
+ parser.read_graph_preheader
138
+ parser.read_graph_header
139
+ graph = parser.read_graph
140
+ expect(graph.nodes.size).to eq 22
141
+ expect(graph.edges.size).to eq 30
142
+ end
143
+ end
144
+ end
@@ -0,0 +1 @@
1
+ foobarbaz
@@ -0,0 +1,176 @@
1
+ require 'stringio'
2
+
3
+ require 'seafoam'
4
+
5
+ require 'rspec'
6
+
7
+ describe Seafoam::Binary::IOBinaryReader do
8
+ describe '#read_utf8' do
9
+ it 'reads a UTF-8 string' do
10
+ string = 'abc😀'
11
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new(string))
12
+ expect(reader.read_utf8(string.bytesize)).to eq string
13
+ end
14
+ end
15
+
16
+ describe '#read_bytes' do
17
+ it 'reads bytes' do
18
+ string = 'abc😀'
19
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new(string))
20
+ expect(reader.read_bytes(string.bytesize)).to eq "abc\xF0\x9F\x98\x80".force_encoding(Encoding::ASCII_8BIT)
21
+ end
22
+ end
23
+
24
+ describe '#read_float64' do
25
+ it 'reads a double-precision float' do
26
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[1.5].pack('G')}hello"))
27
+ expect(reader.read_float64).to eq 1.5
28
+ end
29
+ end
30
+
31
+ describe '#read_float32' do
32
+ it 'reads a single-precision float' do
33
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[1.5].pack('g')}hello"))
34
+ expect(reader.read_float32).to eq 1.5
35
+ end
36
+ end
37
+
38
+ describe '#read_sint64' do
39
+ it 'reads a signed 64-bit network-endian integer' do
40
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[1234].pack('q>')}hello"))
41
+ expect(reader.read_sint64).to eq 1234
42
+ end
43
+ end
44
+
45
+ describe '#read_sint32' do
46
+ it 'reads a signed 32-bit network-endian integer' do
47
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[1234].pack('l>')}hello"))
48
+ expect(reader.read_sint32).to eq 1234
49
+ end
50
+ end
51
+
52
+ describe '#read_sint16' do
53
+ it 'reads a signed 16-bit network-endian integer' do
54
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[1234].pack('s>')}hello"))
55
+ expect(reader.read_sint16).to eq 1234
56
+ end
57
+ end
58
+
59
+ describe '#read_sint8' do
60
+ it 'reads a signed 8-bit integer' do
61
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[-123].pack('c')}hello"))
62
+ expect(reader.read_sint8).to eq(-123)
63
+ end
64
+ end
65
+
66
+ describe '#read_uint8' do
67
+ it 'reads an unsigned 8-bit integer' do
68
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new("#{[212].pack('C')}hello"))
69
+ expect(reader.read_uint8).to eq 212
70
+ end
71
+ end
72
+
73
+ describe '#skip_float64' do
74
+ it 'skips 8 bytes' do
75
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('12345678x'))
76
+ reader.skip_float64
77
+ expect(reader.read_uint8).to eq 'x'.ord
78
+ end
79
+
80
+ it 'accepts a count' do
81
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1234567812345678x'))
82
+ reader.skip_float64 2
83
+ expect(reader.read_uint8).to eq 'x'.ord
84
+ end
85
+ end
86
+
87
+ describe '#skip_float32' do
88
+ it 'skips 4 bytes' do
89
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1234x'))
90
+ reader.skip_float32
91
+ expect(reader.read_uint8).to eq 'x'.ord
92
+ end
93
+
94
+ it 'accepts a count' do
95
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('12341234x'))
96
+ reader.skip_float32 2
97
+ expect(reader.read_uint8).to eq 'x'.ord
98
+ end
99
+
100
+ describe '#skip_int64' do
101
+ it 'skips 8 bytes' do
102
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('12345678x'))
103
+ reader.skip_int64
104
+ expect(reader.read_uint8).to eq 'x'.ord
105
+ end
106
+
107
+ it 'accepts a count' do
108
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1234567812345678x'))
109
+ reader.skip_int64 2
110
+ expect(reader.read_uint8).to eq 'x'.ord
111
+ end
112
+ end
113
+
114
+ describe '#skip_int32' do
115
+ it 'skips 4 bytes' do
116
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1234x'))
117
+ reader.skip_int32
118
+ expect(reader.read_uint8).to eq 'x'.ord
119
+ end
120
+
121
+ it 'accepts a count' do
122
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('12341234x'))
123
+ reader.skip_int32 2
124
+ expect(reader.read_uint8).to eq 'x'.ord
125
+ end
126
+ end
127
+
128
+ describe '#skip_int16' do
129
+ it 'skips 2 bytes' do
130
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('12x'))
131
+ reader.skip_int16
132
+ expect(reader.read_uint8).to eq 'x'.ord
133
+ end
134
+
135
+ it 'accepts a count' do
136
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1212x'))
137
+ reader.skip_int16 2
138
+ expect(reader.read_uint8).to eq 'x'.ord
139
+ end
140
+ end
141
+
142
+ describe '#skip_int8' do
143
+ it 'skips 1 byte' do
144
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('1x'))
145
+ reader.skip_int8
146
+ expect(reader.read_uint8).to eq 'x'.ord
147
+ end
148
+
149
+ it 'accepts a count' do
150
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('11x'))
151
+ reader.skip_int8 2
152
+ expect(reader.read_uint8).to eq 'x'.ord
153
+ end
154
+ end
155
+
156
+ describe '#skip' do
157
+ it 'skips n bytes' do
158
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('123x'))
159
+ reader.skip 3
160
+ expect(reader.read_uint8).to eq 'x'.ord
161
+ end
162
+ end
163
+
164
+ describe '#eof?' do
165
+ it 'returns false when not at the end of file' do
166
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new('123'))
167
+ expect(reader.eof?).to be false
168
+ end
169
+
170
+ it 'returns true when at the end of file' do
171
+ reader = Seafoam::Binary::IOBinaryReader.new(StringIO.new(''))
172
+ expect(reader.eof?).to be true
173
+ end
174
+ end
175
+ end
176
+ end