stomp_parser 1.0.0-universal-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ describe StompParser::RubyParser do
2
+ it_behaves_like "a stomp_parser parser"
3
+ end
@@ -0,0 +1,9 @@
1
+ describe StompParser do
2
+ specify { defined?(StompParser::VERSION).should be_true }
3
+
4
+ describe ".max_frame_size" do
5
+ it "has a sane default value" do
6
+ StompParser.max_frame_size.should be_a(Fixnum)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,268 @@
1
+ # encoding: UTF-8
2
+ RSpec.shared_examples_for "a stomp_parser parser" do
3
+ let(:parser) { described_class.new }
4
+
5
+ context "#parse" do
6
+ def parse_all(data)
7
+ frames = []
8
+ parser.parse(data) { |m| frames << m }
9
+ frames
10
+ end
11
+
12
+ it "parses frame as binary" do
13
+ frames = parse_all("CONNECT\n\n\x00")
14
+ frames.length.should eq(1)
15
+ frames[0].command.encoding.should eq Encoding::BINARY
16
+ end
17
+
18
+ context "command" do
19
+ it "can parse commands" do
20
+ frames = parse_all("CONNECT\n\n\x00")
21
+ frames.length.should eq(1)
22
+ frames[0].command.should eq("CONNECT")
23
+ end
24
+ end
25
+
26
+ context "headers" do
27
+ it "can parse simple headers" do
28
+ frames = parse_all("CONNECT\nmoo:cow\n\n\x00")
29
+ frames.length.should eq(1)
30
+ frames[0].headers.should eq("moo" => "cow")
31
+ end
32
+
33
+ it "can parse multiple headers" do
34
+ frames = parse_all("CONNECT\nmoo:cow\nbaah:sheep\n\n\x00")
35
+ frames.length.should eq(1)
36
+ frames[0].headers.should eq("moo" => "cow", "baah" => "sheep")
37
+ end
38
+
39
+ it "can parse headers with NULLs in them" do
40
+ frames = parse_all("CONNECT\nnull\x00:null\x00\n\n\x00")
41
+ frames.length.should eq(1)
42
+ frames[0].headers.should eq("null\x00" => "null\x00")
43
+ end
44
+
45
+ it "can parse headers with escape characters" do
46
+ frames = parse_all("CONNECT\nnull\\c:\\r\\n\\c\\\\\n\n\x00")
47
+ frames.length.should eq(1)
48
+ frames[0].headers.should eq("null:" => "\r\n:\\")
49
+ end
50
+
51
+ it "can parse headers with no value" do
52
+ frames = parse_all("CONNECT\nmoo:\n\n\x00")
53
+ frames.length.should eq(1)
54
+ frames[0].headers.should eq("moo" => nil)
55
+ end
56
+
57
+ it "nullifies previous headers" do
58
+ frames = parse_all("CONNECT\nmoo:\nmoo:hello\n\n\x00")
59
+ frames.length.should eq(1)
60
+ frames[0].headers.should eq("moo" => nil)
61
+ end
62
+
63
+ it "prioritises first header when given multiple of same key" do
64
+ frames = parse_all("CONNECT\nkey:first\nkey:second\n\n\x00")
65
+ frames.length.should eq(1)
66
+ frames[0].headers.should eq("key" => "first")
67
+ end
68
+
69
+ it "parses multibyte headers as UTF-8 even if content type specifies something else" do
70
+ frames = parse_all("MESSAGE\ncontent-type:text/plain;charset=ISO-8859-1\nwhät:üp\n\n\x00")
71
+ frames.length.should eq(1)
72
+
73
+ key, value = frames[0].headers.to_a[1]
74
+
75
+ key.should eq "wh\xC3\xA4t".force_encoding("UTF-8")
76
+ key.encoding.should eq Encoding::UTF_8
77
+
78
+ value.should eq "\xC3\xBCp".force_encoding("UTF-8")
79
+ value.encoding.should eq Encoding::UTF_8
80
+ end
81
+ end
82
+
83
+ context "body" do
84
+ it "can parse body" do
85
+ frames = parse_all("CONNECT\n\nbody\x00")
86
+ frames.length.should eq(1)
87
+ frames[0].body.should eq "body"
88
+ end
89
+
90
+ it "can parse binary body" do
91
+ frames = parse_all("CONNECT\ncontent-length:5\n\nbo\x00dy\x00")
92
+ frames.length.should eq(1)
93
+ frames[0].body.should eq "bo\x00dy"
94
+ end
95
+
96
+ it "parses body as binary string when no content-type given" do
97
+ frames = parse_all("MESSAGE\n\nWhat üp\x00")
98
+ frames.length.should eq(1)
99
+ frames[0].body.should eq "What \xC3\xBCp".force_encoding("BINARY")
100
+ frames[0].body.encoding.should eq Encoding::BINARY
101
+ end
102
+
103
+ it "parses body as encoded string when content-type is a text type and charset is given" do
104
+ frames = parse_all("MESSAGE\ncontent-type:text/plain;charset=ISO-8859-1\n\nWhat \xFCp\x00")
105
+ frames.length.should eq(1)
106
+ frames[0].body.should eq "What \xFCp".force_encoding("iso-8859-1")
107
+ frames[0].body.encoding.should eq Encoding::ISO_8859_1
108
+ end
109
+
110
+ it "parses body as encoded string when content-type is not a text type and charset is given" do
111
+ frames = parse_all("MESSAGE\ncontent-type:application/octet-stream;charset=ISO-8859-1\n\nWhat \xFCp\x00")
112
+ frames.length.should eq(1)
113
+ frames[0].body.should eq "What \xFCp".force_encoding("iso-8859-1")
114
+ frames[0].body.encoding.should eq Encoding::ISO_8859_1
115
+ end
116
+
117
+ it "parses body as utf-8 encoded string when content-type is a text type and charset is not given" do
118
+ frames = parse_all("MESSAGE\ncontent-type:text/plain\n\nWhat üp\x00")
119
+ frames.length.should eq(1)
120
+ frames[0].body.should eq "What \xC3\xBCp".force_encoding("UTF-8")
121
+ frames[0].body.encoding.should eq Encoding::UTF_8
122
+ end
123
+
124
+ it "parses body as binary string when content-type is not a text type and charset is not given" do
125
+ frames = parse_all("MESSAGE\ncontent-type:application/octet-stream\n\nWhat \xFCp\x00")
126
+ frames.length.should eq(1)
127
+ frames[0].body.should eq "What \xFCp".force_encoding("BINARY")
128
+ frames[0].body.encoding.should eq Encoding::BINARY
129
+ end
130
+ end
131
+
132
+ context "multiple frames" do
133
+ it "yields multiple frames in a single invocation" do
134
+ frames = parse_all("CONNECT\n\n\x00CONNECT\n\n\x00CONNECT\n\n\x00")
135
+ frames.length.should eq(3)
136
+ frames.map(&:command).should eq %w[CONNECT CONNECT CONNECT]
137
+ frames.uniq.length.should eq(3)
138
+ end
139
+
140
+ it "allows newlines between frames" do
141
+ frames = parse_all("\n\r\n\nCONNECT\n\n\x00\n\n\r\nCONNECT\n\n\x00\n\n")
142
+ frames.length.should eq(2)
143
+ frames.map(&:command).should eq %w[CONNECT CONNECT]
144
+ frames.uniq.length.should eq(2)
145
+ end
146
+ end
147
+
148
+ context "multiple invocations" do
149
+ it "parses simple split up frames" do
150
+ frames = parse_all("CONNECT\n")
151
+ frames.should be_empty
152
+
153
+ frames = parse_all("\n\x00")
154
+ frames.length.should eq(1)
155
+ frames[0].command.should eq "CONNECT"
156
+ end
157
+
158
+ it "parses frames split across buffer markings" do
159
+ frames = parse_all("\n\nCONN")
160
+ frames.should be_empty
161
+
162
+ frames = parse_all("ECT\n\n\x00")
163
+ frames.length.should eq(1)
164
+ frames[0].command.should eq "CONNECT"
165
+ end
166
+
167
+ it "parses frames split across header keys" do
168
+ frames = parse_all("CONNECT\nheader:")
169
+ frames.should be_empty
170
+
171
+ frames = parse_all("value\n\n\x00")
172
+ frames.length.should eq(1)
173
+ frames[0].command.should eq "CONNECT"
174
+ frames[0].headers.should eq("header" => "value")
175
+ end
176
+
177
+ it "parses binary frame split across body" do
178
+ frames = parse_all("CONNECT\ncontent-length:4\n\n\x00a")
179
+ frames.should be_empty
180
+
181
+ frames = parse_all("b\x00\x00")
182
+ frames.length.should eq(1)
183
+ frames[0].command.should eq "CONNECT"
184
+ frames[0].body.should eq("\x00ab\x00")
185
+ end
186
+
187
+ it "parses frames split across frames" do
188
+ frames = parse_all("CONNECT\n")
189
+ frames.should be_empty
190
+
191
+ frames = parse_all("\n\x00CONNEC")
192
+ frames.length.should eq(1)
193
+ frames[0].command.should eq "CONNECT"
194
+
195
+ frames = parse_all("T\n\n\x00")
196
+ frames.length.should eq(1)
197
+ frames[0].command.should eq "CONNECT"
198
+ end
199
+ end
200
+
201
+ context "fails on invalid frames" do
202
+ specify "no block given" do
203
+ expect { parser.parse("CONNECT\n\n\x00") }.to raise_error(LocalJumpError)
204
+ end
205
+
206
+ specify "invalid command" do
207
+ expect { parser.parse("CONNET\n\n\x00") }.to raise_error(StompParser::ParseError)
208
+ end
209
+
210
+ specify "unfinished command" do
211
+ expect { parser.parse("CONNECT\x00") }.to raise_error(StompParser::ParseError)
212
+ end
213
+
214
+ specify "header with colon" do
215
+ expect { parser.parse("CONNECT\nfoo: :bar\n\n\x00") }.to raise_error(StompParser::ParseError)
216
+ end
217
+
218
+ specify "header with invalid escape" do
219
+ expect { parser.parse("CONNECT\nfoo:\\t\n\n\x00") }.to raise_error(StompParser::ParseError)
220
+ end
221
+
222
+ specify "body longer than content length" do
223
+ expect { parser.parse("CONNECT\ncontent-length:0\n\nx\x00") }.to raise_error(StompParser::ParseError)
224
+ end
225
+
226
+ specify "invalid content length" do
227
+ expect { parser.parse("CONNECT\ncontent-length:LAWL\n\nx\x00") }.to raise_error(StompParser::Error, /invalid content length "LAWL"/)
228
+ end
229
+
230
+ specify "re-trying invocation after an error" do
231
+ first_error = begin
232
+ parser.parse("CONNET")
233
+ rescue StompParser::ParseError => ex
234
+ ex
235
+ end
236
+
237
+ first_error.should be_a(StompParser::ParseError)
238
+
239
+ second_error = begin
240
+ parser.parse("")
241
+ rescue StompParser::ParseError => ex
242
+ ex
243
+ end
244
+
245
+ second_error.should eql(first_error)
246
+ end
247
+
248
+ specify "total size bigger than global max frame size setting" do
249
+ StompParser.stub(:max_frame_size => 30)
250
+ parser = described_class.new
251
+ parser.parse("CONNECT\n") # 8
252
+ parser.parse("header:value\n") # 21
253
+ expect {
254
+ parser.parse("other:val\n") # 31
255
+ }.to raise_error(StompParser::FrameSizeExceeded)
256
+ end
257
+
258
+ specify "total size bigger than local max frame size setting" do
259
+ parser = described_class.new(max_frame_size = 30)
260
+ parser.parse("CONNECT\n") # 8
261
+ parser.parse("header:value\n") # 21
262
+ expect {
263
+ parser.parse("other:val\n") # 31
264
+ }.to raise_error(StompParser::FrameSizeExceeded)
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'stomp_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "stomp_parser"
8
+ spec.version = StompParser::VERSION
9
+ spec.authors = ["Kim Burgestrand", "Jonas Nicklas"]
10
+ spec.email = ["kim@burgestrand.se", "jonas.nicklas@gmail.com"]
11
+ spec.summary = %q{STOMP frame parser.}
12
+ spec.homepage = "https://github.com/stompede/stomp_parser"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.files += ["lib/stomp_parser/ruby_parser.rb"]
17
+ spec.files += ["ext/stomp_parser/c_parser.c"]
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+ spec.extensions = %w[ext/stomp_parser/extconf.rb]
22
+
23
+ spec.add_development_dependency "bundler", "~> 0"
24
+ spec.add_development_dependency "rake", "~> 0"
25
+ spec.add_development_dependency "rake-compiler", "~> 0"
26
+ spec.add_development_dependency "rspec", "~> 0"
27
+ spec.add_development_dependency "pry", "~> 0"
28
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stomp_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: universal-java
6
+ authors:
7
+ - Kim Burgestrand
8
+ - Jonas Nicklas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake-compiler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description:
85
+ email:
86
+ - kim@burgestrand.se
87
+ - jonas.nicklas@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rspec"
94
+ - ".travis.yml"
95
+ - Brewfile
96
+ - Gemfile
97
+ - MIT-LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - ext/java/stomp_parser/JavaParser.java.rl
101
+ - ext/java/stomp_parser/JavaParserService.java
102
+ - ext/stomp_parser/c_parser.c
103
+ - ext/stomp_parser/c_parser.c.rl
104
+ - ext/stomp_parser/extconf.rb
105
+ - lib/stomp_parser.rb
106
+ - lib/stomp_parser/error.rb
107
+ - lib/stomp_parser/frame.rb
108
+ - lib/stomp_parser/java_parser.jar
109
+ - lib/stomp_parser/ruby_parser.rb
110
+ - lib/stomp_parser/ruby_parser.rb.rl
111
+ - lib/stomp_parser/version.rb
112
+ - parser_common.rl
113
+ - spec/bench_helper.rb
114
+ - spec/benchmarks/message_bench.rb
115
+ - spec/benchmarks/parser_bench.rb
116
+ - spec/profile.rb
117
+ - spec/profile/.gitkeep
118
+ - spec/spec_helper.rb
119
+ - spec/stomp_parser/c_parser_spec.rb
120
+ - spec/stomp_parser/java_parser_spec.rb
121
+ - spec/stomp_parser/message_spec.rb
122
+ - spec/stomp_parser/ruby_parser_spec.rb
123
+ - spec/stomp_parser_spec.rb
124
+ - spec/support/shared_parser_examples.rb
125
+ - stomp_parser.gemspec
126
+ homepage: https://github.com/stompede/stomp_parser
127
+ licenses:
128
+ - MIT
129
+ metadata: {}
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubyforge_project:
146
+ rubygems_version: 2.2.0.rc.1
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: STOMP frame parser.
150
+ test_files:
151
+ - spec/bench_helper.rb
152
+ - spec/benchmarks/message_bench.rb
153
+ - spec/benchmarks/parser_bench.rb
154
+ - spec/profile.rb
155
+ - spec/profile/.gitkeep
156
+ - spec/spec_helper.rb
157
+ - spec/stomp_parser/c_parser_spec.rb
158
+ - spec/stomp_parser/java_parser_spec.rb
159
+ - spec/stomp_parser/message_spec.rb
160
+ - spec/stomp_parser/ruby_parser_spec.rb
161
+ - spec/stomp_parser_spec.rb
162
+ - spec/support/shared_parser_examples.rb