rjr 0.19.1 → 0.19.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.
@@ -16,31 +16,64 @@ class JSONParser
16
16
  # Returns the message and remaining portion of the data string,
17
17
  # if message is found, else nil
18
18
  #
19
- # TODO efficiency can probably be optimized in the case closing '}'
20
- # hasn't arrived yet
21
- #
22
- # FIXME if uneven brackets appears in string data (such as in params)
23
- # this will break, detect when in string and ignore in counts
19
+ # TODO efficiency can probably be optimized in the case of multiple calls
20
+ # to this when the case closing '}' hasn't arrived yet
24
21
  def self.extract_json_from(data)
25
22
  return nil if data.nil? || data.empty?
23
+ # start at beginning of data, find opening quote
26
24
  start = 0
27
25
  start += 1 until start == data.length || data[start].chr == '{'
28
- on = mi = 0
26
+
27
+ escaped = false
28
+ in_quotes = false
29
+ quote_char = nil
30
+ open_brackets = mark = 0
31
+
32
+ # iterate over data stream
29
33
  start.upto(data.length - 1).each { |i|
30
- if data[i].chr == '{'
31
- on += 1
32
- elsif data[i].chr == '}'
33
- on -= 1
34
+
35
+ # toggle escaped flag in case of '\' or '\\'
36
+ if in_quotes && data[i].chr == '\\'
37
+ escaped = !escaped
38
+
39
+ else
40
+ # ignore escaped chars
41
+ if !escaped
42
+
43
+ # ignore brackets in quotes
44
+ if !in_quotes
45
+ if data[i].chr == '{'
46
+ open_brackets += 1
47
+
48
+ elsif data[i].chr == '}'
49
+ open_brackets -= 1
50
+ end
51
+ end
52
+
53
+ # track opening quote
54
+ if data[i].chr == "'" || data[i].chr == '"'
55
+ if !in_quotes
56
+ in_quotes = true
57
+ quote_char = data[i]
58
+ elsif quote_char == data[i]
59
+ in_quotes = false
60
+ end
61
+ end
62
+ end
63
+
64
+ escaped = false
34
65
  end
35
66
 
36
- if on == 0
37
- mi = i
67
+
68
+ # finish at end of one json message
69
+ if open_brackets == 0
70
+ mark = i
38
71
  break
39
72
  end
40
73
  }
41
74
 
42
- return nil if mi == 0
43
- return data[start..mi], data[(mi+1)..-1]
75
+ return nil if mark == 0
76
+ return data[start..mark], data[(mark+1)..-1]
44
77
  end
45
78
 
46
79
  # Return bool indicating if json class is invalid in context
@@ -52,15 +52,17 @@ class Logger
52
52
  def self.method_missing(method_id, *args)
53
53
  _instantiate_logger
54
54
  @logger_mutex.synchronize {
55
+ # TODO option to indent & prepend configurable prefix to extra log lines after first entry
55
56
  args = args.first if args.first.is_a?(Array)
57
+ shouldnt_log = args.any? { |a| @filters.any? { |f| !f.call a } }
56
58
  args.each { |a|
57
59
  # run highlights / filters against output before
58
60
  # sending formatted output to logger
59
61
  # TODO allow user to customize highlight mechanism/text
60
62
  na = @highlights.any? { |h| h.call a } ?
61
63
  "\e[1m\e[31m#{a}\e[0m\e[0m" : a
62
- @logger.send(method_id, na) if @filters.all? { |f| f.call a }
63
- }
64
+ @logger.send(method_id, na)
65
+ } unless shouldnt_log
64
66
  }
65
67
  end
66
68
 
data/lib/rjr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RJR
2
- VERSION = '0.19.1'
2
+ VERSION = '0.19.2'
3
3
  end
data/specs/args_spec.rb CHANGED
@@ -115,14 +115,14 @@ module RJR
115
115
  context "arguments includes tag" do
116
116
  it "returns true" do
117
117
  a = Arguments.new :args => ['with_id', 42]
118
- a.specifies?('with_id').should be_true
118
+ a.specifies?('with_id').should be_truthy
119
119
  end
120
120
  end
121
121
 
122
122
  context "arguments does not include tag" do
123
123
  it "returns false" do
124
124
  a = Arguments.new :args => ['with_id', 42]
125
- a.specifies?('with_name').should be_false
125
+ a.specifies?('with_name').should be_falsey
126
126
  end
127
127
  end
128
128
  end
@@ -167,14 +167,14 @@ module RJR
167
167
  d = Dispatcher.new
168
168
  cb = proc {}
169
169
  d.handle 'foobar', cb
170
- d.handles?('foobar').should be_true
170
+ d.handles?('foobar').should be_truthy
171
171
  end
172
172
  end
173
173
 
174
174
  context "dispatcher does not have handler" do
175
175
  it "returns false" do
176
176
  d = Dispatcher.new
177
- d.handles?('foobar').should be_false
177
+ d.handles?('foobar').should be_falsey
178
178
  end
179
179
  end
180
180
  end
@@ -245,14 +245,14 @@ module RJR
245
245
  d.dispatch :rjr_method => 'foobar'
246
246
  end
247
247
 
248
- it "extends request w/ method environment" do
248
+ it "sets request environment" do
249
249
  d = Dispatcher.new
250
250
  d.env 'foobar', 'fooenv'
251
251
  d.handle 'foobar', proc {}
252
252
 
253
253
  r = Request.new
254
254
  Request.should_receive(:new).and_return(r)
255
- r.should_receive(:extend).with('fooenv')
255
+ r.should_receive(:set_env).with('fooenv')
256
256
  d.dispatch :rjr_method => 'foobar'
257
257
  end
258
258
 
@@ -337,7 +337,7 @@ module RJR
337
337
  h = proc {}
338
338
  d.handle('foobar', h)
339
339
  d.handlers['foobar'].should == h
340
- d.handles?('foobar').should be_true
340
+ d.handles?('foobar').should be_truthy
341
341
  end
342
342
 
343
343
  it "should set handler from block param" do
@@ -345,7 +345,7 @@ module RJR
345
345
  h = proc {}
346
346
  d.handle('foobar', &h)
347
347
  d.handlers['foobar'].should == h
348
- d.handles?('foobar').should be_true
348
+ d.handles?('foobar').should be_truthy
349
349
  end
350
350
 
351
351
  it "should register handler for multiple methods" do
@@ -354,8 +354,8 @@ module RJR
354
354
  d.handle(['foobar', 'barfoo'], &h)
355
355
  d.handlers['foobar'].should == h
356
356
  d.handlers['barfoo'].should == h
357
- d.handles?('foobar').should be_true
358
- d.handles?('barfoo').should be_true
357
+ d.handles?('foobar').should be_truthy
358
+ d.handles?('barfoo').should be_truthy
359
359
  end
360
360
  end
361
361
 
@@ -376,7 +376,7 @@ module RJR
376
376
  d.handle('foobar', &h)
377
377
 
378
378
  d.dispatch :rjr_method => 'foobar'
379
- invoked.should be_true
379
+ invoked.should be_truthy
380
380
  end
381
381
 
382
382
  it "should pass params to handler" do
@@ -14,7 +14,7 @@ module RJR
14
14
  describe "#start" do
15
15
  it "should start the reactor" do
16
16
  @em.start
17
- @em.reactor_running?.should be_true
17
+ @em.reactor_running?.should be_truthy
18
18
  ['sleep', 'run'].should include(@em.reactor_thread.status)
19
19
  end
20
20
 
@@ -33,7 +33,7 @@ module RJR
33
33
 
34
34
  @em.halt
35
35
  @em.join
36
- @em.reactor_running?.should be_false
36
+ @em.reactor_running?.should be_falsey
37
37
  @em.reactor_thread.should be_nil
38
38
  end
39
39
  end
@@ -65,7 +65,7 @@ module RJR
65
65
  m.synchronize { c.wait m, 0.5 }
66
66
  end
67
67
  end
68
- invoked.should be_true
68
+ invoked.should be_truthy
69
69
  end
70
70
 
71
71
  end
@@ -59,13 +59,13 @@ module RJR
59
59
 
60
60
  context "handler exists" do
61
61
  it "returns true" do
62
- HandlesMethodsTest.has_handler_for?(:handle).should be_true
62
+ HandlesMethodsTest.has_handler_for?(:handle).should be_truthy
63
63
  end
64
64
  end
65
65
 
66
66
  context "handler does not exist" do
67
67
  it "returns false" do
68
- HandlesMethodsTest.has_handler_for?(:foobar).should be_false
68
+ HandlesMethodsTest.has_handler_for?(:foobar).should be_falsey
69
69
  end
70
70
  end
71
71
  end
@@ -1,4 +1,5 @@
1
1
  require 'rjr/util/json_parser'
2
+ require 'rjr/core_ext'
2
3
 
3
4
  module RJR
4
5
  describe JSONParser do
@@ -13,6 +14,31 @@ describe JSONParser do
13
14
  complete = "#{json}remaining"
14
15
  JSONParser.extract_json_from(complete).should == [json, 'remaining']
15
16
  end
17
+
18
+ it "handles brackets in quoted data" do
19
+ json = '{"foo":"val{"}'
20
+ JSONParser.extract_json_from(json).should == [json, '']
21
+ end
22
+
23
+ it "handles nested quotes" do
24
+ json = '{"foo":"val\'{\'"}'
25
+ JSONParser.extract_json_from(json).should == [json, '']
26
+ end
27
+
28
+ it "handles uneven quotes" do
29
+ json = '{"foo":"val\'"}'
30
+ JSONParser.extract_json_from(json).should == [json, '']
31
+ end
32
+
33
+ it "handles escaped quotes" do
34
+ json = '{"foo":"val\\""}'
35
+ JSONParser.extract_json_from(json).should == [json, '']
36
+ end
37
+
38
+ it "handles escaped chars" do
39
+ json = '{"foo":"val\\\\"}'
40
+ JSONParser.extract_json_from(json).should == [json, '']
41
+ end
16
42
  end
17
43
 
18
44
  describe "#invalid_json_class?" do
@@ -32,14 +58,14 @@ describe JSONParser do
32
58
  context "class not on permitted classes list" do
33
59
  it "returns true" do
34
60
  Class.should_receive(:permitted_json_classes).and_return([])
35
- JSONParser.invalid_json_class?('foobar').should be_true
61
+ JSONParser.invalid_json_class?('foobar').should be_truthy
36
62
  end
37
63
  end
38
64
 
39
65
  context "class on permitted classes list" do
40
66
  it "returns false" do
41
67
  Class.should_receive(:permitted_json_classes).and_return(['foobar'])
42
- JSONParser.invalid_json_class?('foobar').should be_false
68
+ JSONParser.invalid_json_class?('foobar').should be_falsey
43
69
  end
44
70
  end
45
71
  end
@@ -51,13 +77,13 @@ describe JSONParser do
51
77
 
52
78
  context "class not on ruby heirarchy" do
53
79
  it "returns true" do
54
- JSONParser.invalid_json_class?('Foobar').should be_true
80
+ JSONParser.invalid_json_class?('Foobar').should be_truthy
55
81
  end
56
82
  end
57
83
 
58
84
  context "class on ruby heirarchy" do
59
85
  it "returns false" do
60
- JSONParser.invalid_json_class?('Integer').should be_false
86
+ JSONParser.invalid_json_class?('Integer').should be_falsey
61
87
  end
62
88
  end
63
89
  end
@@ -0,0 +1,58 @@
1
+ require 'rjr/common'
2
+ require 'rjr/messages/intermediate'
3
+
4
+ module RJR
5
+ module Messages
6
+ describe Intermediate do
7
+ describe "#keys" do
8
+ it "returns extracted data keys" do
9
+ msg = Intermediate.new :data => {:foo => :bar, :mo => :money}
10
+ msg.keys.should == [:foo, :mo]
11
+ end
12
+ end
13
+
14
+ describe "#[]" do
15
+ it "returns value from extracted data" do
16
+ msg = Intermediate.new :data => {'foo' => 'bar'}
17
+ msg['foo'].should == 'bar'
18
+ msg[:foo].should == 'bar'
19
+ end
20
+ end
21
+
22
+ describe "#has?" do
23
+ context "data has key" do
24
+ it "returns true" do
25
+ msg = Intermediate.new :data => {'foo' => 'bar'}
26
+ msg.has?('foo').should be_truthy
27
+ end
28
+ end
29
+
30
+ context "data does not have key" do
31
+ it "returns false" do
32
+ msg = Intermediate.new
33
+ msg.has?('foo').should be_falsey
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "::parse" do
39
+ it "returns new intermediate instance with original message and parsed data" do
40
+ json = '{"foo":"bar"}'
41
+ msg = Intermediate.parse json
42
+ msg.json.should == json
43
+ msg.data.should == {"foo" => "bar"}
44
+ end
45
+
46
+ describe "error parsing json" do
47
+ it "propagates err" do
48
+ json = '{"foo":"bar"}'
49
+ JSONParser.should_receive(:parse).with(json).and_raise(RuntimeError)
50
+ lambda {
51
+ Intermediate.parse json
52
+ }.should raise_error(RuntimeError)
53
+ end
54
+ end
55
+ end
56
+ end # describe Intermediate
57
+ end # module Messages
58
+ end # module RJR
@@ -1,4 +1,5 @@
1
1
  require 'rjr/messages/notification'
2
+ require 'rjr/messages/intermediate'
2
3
 
3
4
  module RJR
4
5
  module Messages
@@ -16,9 +17,9 @@ module Messages
16
17
  it "should return bool indicating if string is a notification msg"
17
18
 
18
19
  it "should produce valid json" do
19
- msg = Notification.new :method => 'test',
20
- :args => ['a', 1],
21
- :headers => {:h => 2}
20
+ msg = Notification.new :method => 'test',
21
+ :args => ['a', 1],
22
+ :headers => {:h => 2}
22
23
 
23
24
  msg_string = msg.to_s
24
25
  msg_string.should include('"h":2')
@@ -31,8 +32,10 @@ module Messages
31
32
  it "should parse notification message string" do
32
33
  msg_string = '{"jsonrpc": "2.0", ' +
33
34
  '"method": "test", "params": ["a", 1]}'
34
- msg = Notification.new :message => msg_string
35
- msg.json_message.should == msg_string
35
+ inter = Intermediate.parse msg_string
36
+
37
+ msg = Notification.new :message => inter
38
+ msg.message.should == inter
36
39
  msg.jr_method.should == 'test'
37
40
  msg.jr_args.should =~ ['a', 1]
38
41
  end
@@ -41,19 +44,15 @@ module Messages
41
44
  msg_string = '{"jsonrpc": "2.0", ' +
42
45
  '"method": "test", "params": ["a", 1], ' +
43
46
  '"h": 2}'
44
- msg = Notification.new :message => msg_string, :headers => {'f' => 'g'}
45
- msg.json_message.should == msg_string
47
+ inter = Intermediate.parse msg_string
48
+
49
+ msg = Notification.new :message => inter, :headers => {'f' => 'g'}
50
+ msg.message.should == inter
46
51
  msg.headers.should have_key 'h'
47
52
  msg.headers.should have_key 'f'
48
53
  msg.headers['h'].should == 2
49
54
  msg.headers['f'].should == 'g'
50
55
  end
51
-
52
- it "should fail if parsing invalid message string" do
53
- lambda {
54
- msg = Notification.new :message => 'foobar'
55
- }.should raise_error JSON::ParserError
56
- end
57
56
  end # describe Notification
58
57
  end # module Messages
59
58
  end # module RJR
@@ -1,13 +1,15 @@
1
1
  require 'rjr/common'
2
2
  require 'rjr/messages/request'
3
+ require 'rjr/messages/intermediate'
3
4
 
4
5
  module RJR
5
6
  module Messages
6
7
  describe Request do
7
8
  it "should accept request parameters" do
8
- msg = Request.new :method => 'test',
9
- :args => ['a', 1],
10
- :headers => {:h => 2}
9
+ msg = Request.new :method => 'test',
10
+ :args => ['a', 1],
11
+ :headers => {:h => 2}
12
+
11
13
  msg.jr_method.should == "test"
12
14
  msg.jr_args.should =~ ['a', 1]
13
15
  msg.headers.should have_key(:h)
@@ -18,9 +20,9 @@ module Messages
18
20
  it "should return bool indicating if string is a request msg"
19
21
 
20
22
  it "should produce valid json" do
21
- msg = Request.new :method => 'test',
22
- :args => ['a', 1],
23
- :headers => {:h => 2}
23
+ msg = Request.new :method => 'test',
24
+ :args => ['a', 1],
25
+ :headers => {:h => 2}
24
26
 
25
27
  msg_string = msg.to_s
26
28
  msg_string.should include('"h":2')
@@ -35,8 +37,10 @@ module Messages
35
37
  msg_string = '{"jsonrpc": "2.0", ' +
36
38
  '"id": "' + msg_uuid + '", ' +
37
39
  '"method": "test", "params": ["a", 1]}'
38
- msg = Request.new :message => msg_string
39
- msg.json_message.should == msg_string
40
+ inter = Intermediate.parse msg_string
41
+
42
+ msg = Request.new :message => inter
43
+ msg.message.should == inter
40
44
  msg.jr_method.should == 'test'
41
45
  msg.jr_args.should =~ ['a', 1]
42
46
  msg.msg_id.should == msg_uuid
@@ -48,19 +52,15 @@ module Messages
48
52
  '"id": "' + msg_uuid + '", ' +
49
53
  '"method": "test", "params": ["a", 1], ' +
50
54
  '"h": 2}'
51
- msg = Request.new :message => msg_string, :headers => {'f' => 'g'}
52
- msg.json_message.should == msg_string
55
+ inter = Intermediate.parse msg_string
56
+
57
+ msg = Request.new :message => inter, :headers => {'f' => 'g'}
58
+ msg.message.should == inter
53
59
  msg.headers.should have_key 'h'
54
60
  msg.headers.should have_key 'f'
55
61
  msg.headers['h'].should == 2
56
62
  msg.headers['f'].should == 'g'
57
63
  end
58
-
59
- it "should fail if parsing invalid message string" do
60
- lambda {
61
- msg = Request.new :message => 'foobar'
62
- }.should raise_error JSON::ParserError
63
- end
64
64
  end # describe Request
65
65
  end # module Messages
66
66
  end # module RJR
@@ -1,6 +1,7 @@
1
1
  require 'rjr/common'
2
2
  require 'rjr/result'
3
3
  require 'rjr/messages/response'
4
+ require 'rjr/messages/intermediate'
4
5
 
5
6
  module RJR
6
7
  module Messages
@@ -21,8 +22,8 @@ module Messages
21
22
  it "should produce valid result response json" do
22
23
  msg_id = gen_uuid
23
24
  msg = Response.new :id => msg_id,
24
- :result => RJR::Result.new(:result => 'success'),
25
- :headers => {:h => 2}
25
+ :result => RJR::Result.new(:result => 'success'),
26
+ :headers => {:h => 2}
26
27
  msg_string = msg.to_s
27
28
  msg_string.should include('"id":"'+msg_id+'"')
28
29
  msg_string.should include('"result":"success"')
@@ -52,8 +53,10 @@ module Messages
52
53
  msg_id = gen_uuid
53
54
  msg_string = '{"id":"' + msg_id + '", ' +
54
55
  '"result":"success","jsonrpc":"2.0"}'
55
- msg = Response.new :message => msg_string
56
- msg.json_message.should == msg_string
56
+ inter = Intermediate.parse msg_string
57
+
58
+ msg = Response.new :message => inter
59
+ msg.message.should == inter
57
60
  msg.msg_id.should == msg_id
58
61
  msg.result.success.should == true
59
62
  msg.result.failed.should == false
@@ -64,8 +67,10 @@ module Messages
64
67
  msg_id = gen_uuid
65
68
  msg_string = '{"id":"' + msg_id + '", ' +
66
69
  '"error":{"code":404,"message":"not found","class":"ArgumentError"}, "jsonrpc":"2.0"}'
67
- msg = Response.new :message => msg_string
68
- msg.json_message.should == msg_string
70
+ inter = Intermediate.parse msg_string
71
+
72
+ msg = Response.new :message => inter
73
+ msg.message.should == inter
69
74
  msg.msg_id.should == msg_id
70
75
  msg.result.success.should == false
71
76
  msg.result.failed.should == true
@@ -78,17 +83,13 @@ module Messages
78
83
  msg_id = gen_uuid
79
84
  msg_string = '{"id":"' + msg_id + '", ' +
80
85
  '"result":"success","h":2,"jsonrpc":"2.0"}'
81
- msg = Response.new :message => msg_string
82
- msg.json_message.should == msg_string
86
+ inter = Intermediate.parse msg_string
87
+
88
+ msg = Response.new :message => inter
89
+ msg.message.should == inter
83
90
  msg.headers.should have_key 'h'
84
91
  msg.headers['h'].should == 2
85
92
  end
86
-
87
- it "should fail if parsing invalid message string" do
88
- lambda {
89
- msg = Response.new :message => 'foobar'
90
- }.should raise_error JSON::ParserError
91
- end
92
93
  end # describe Response
93
94
  end # module Messages
94
95
  end # module RJR