rack-webconsole-pry 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-webconsole-pry (0.1.8)
4
+ rack-webconsole-pry (0.1.9)
5
5
  json
6
6
  multi_json (>= 1.0.3)
7
7
  pry
@@ -11,23 +11,23 @@ GEM
11
11
  remote: http://rubygems.org/
12
12
  specs:
13
13
  bluecloth (2.2.0)
14
- coderay (1.0.6)
15
- json (1.7.3)
14
+ coderay (1.0.8)
15
+ json (1.7.6)
16
16
  metaclass (0.0.1)
17
- method_source (0.7.1)
17
+ method_source (0.8.1)
18
18
  minitest (2.11.4)
19
19
  mocha (0.10.5)
20
20
  metaclass (~> 0.0.1)
21
- multi_json (1.3.6)
22
- pry (0.9.9.6)
21
+ multi_json (1.5.0)
22
+ pry (0.9.10)
23
23
  coderay (~> 1.0.5)
24
- method_source (~> 0.7.1)
25
- slop (>= 2.4.4, < 3)
24
+ method_source (~> 0.8)
25
+ slop (~> 3.3.1)
26
26
  purdytest (1.0.0)
27
27
  minitest (~> 2.2)
28
- rack (1.4.1)
28
+ rack (1.4.4)
29
29
  rake (0.9.2.2)
30
- slop (2.4.4)
30
+ slop (3.3.3)
31
31
  yard (0.7.5)
32
32
 
33
33
  PLATFORMS
@@ -23,7 +23,7 @@ module Rack
23
23
  # variables and giving a true IRB-esque experience.
24
24
  #
25
25
  class Webconsole
26
- @@config = {:inject_jquery => false, :key_code => "96"}
26
+ @@config = {:inject_jquery => false, :key_code => "[96]"}
27
27
 
28
28
  class << self
29
29
  # Returns whether the Asset injecter must inject JQuery or not.
@@ -24,6 +24,8 @@ module Rack
24
24
  # @param [Hash] env a Rack request environment.
25
25
  def call(env)
26
26
  status, headers, response = @app.call(env)
27
+ response.extend(ResponseMethods)
28
+
27
29
  return [status, headers, response] unless check_html?(headers, response) && status == 200
28
30
 
29
31
  if response.respond_to?(:body)
@@ -69,5 +71,14 @@ module Rack
69
71
  body =~ %r{<html.*</html>}m
70
72
  end
71
73
  end
74
+
75
+ module ResponseMethods
76
+ def first
77
+ obj = nil
78
+ self.each { |e| obj = e; break }
79
+ obj
80
+ end
81
+ end
82
+
72
83
  end
73
84
  end
@@ -21,6 +21,7 @@ module Rack
21
21
  @@tokens.delete(k) if v <= Time.now
22
22
  end
23
23
  end
24
+
24
25
  # Returns the autogenerated security token
25
26
  #
26
27
  # @return [String] the autogenerated token
@@ -50,6 +51,7 @@ module Rack
50
51
  def request=(request)
51
52
  @@request = request
52
53
  end
54
+
53
55
  end
54
56
 
55
57
  # Honor the Rack contract by saving the passed Rack application in an ivar.
@@ -58,6 +60,7 @@ module Rack
58
60
  # middleware chain.
59
61
  def initialize(app)
60
62
  @app = app
63
+
61
64
  end
62
65
 
63
66
  # Evaluates a string as Ruby code and returns the evaluated result as
@@ -83,6 +86,7 @@ module Rack
83
86
  if $pry.nil?
84
87
  Pry.pager = false
85
88
  $pry = Pry.new(:output => $pry_output, :pager => false)
89
+ Pry.initial_session_setup
86
90
  end
87
91
  pry = $pry
88
92
 
@@ -96,16 +100,50 @@ module Rack
96
100
  pry.inject_sticky_locals(target)
97
101
  code = params['query']
98
102
  hash[:prompt] = pry.select_prompt("", target) + Pry::Code.new(code).to_s
103
+ got_output = false
99
104
  begin
100
- if !pry.process_command(code, "", target)
101
- result = target.eval(code, Pry.eval_path, Pry.current_line)
102
- pry.set_last_result(result, target, code)
103
- pry.show_result(result) if pry.should_print?
104
- end
105
+ read_pipe, write_pipe = IO.pipe
106
+ end_line = "~~~~~ rack-webconsole end output ~~~~~\n"
107
+
108
+ thr = Thread.new do
109
+ while true
110
+ new_line = read_pipe.readline
111
+ break if new_line == end_line
112
+ $pry_output << new_line
113
+ end
114
+ end
115
+
116
+ old_stdout = STDOUT.dup
117
+ old_stderr = STDERR.dup
118
+ STDOUT.reopen(write_pipe)
119
+ STDERR.reopen(write_pipe)
120
+ if !pry.process_command(code, "", target)
121
+ result = target.eval(code, Pry.eval_path, Pry.current_line)
122
+ got_output = true
123
+ end
105
124
  rescue StandardError => e
106
- $pry_output.write("Error: " + e.message)
125
+ error_out = "Error: " + e.message
126
+ ensure
127
+ write_pipe << end_line
128
+
129
+ thr.join
130
+ read_pipe.close
131
+ write_pipe.close
132
+ STDOUT.reopen(old_stdout)
133
+ STDERR.reopen(old_stderr)
134
+
107
135
  end
108
-
136
+
137
+ if got_output
138
+ pry.set_last_result(result, target, code)
139
+ Pry.print.call($pry_output, result) if pry.should_print?
140
+ # the below line doesn't work well with custom printers
141
+ # (like awesome_print) for some reason
142
+ #pry.show_result(result) if pry.should_print?
143
+ end
144
+
145
+ $pry_output.write(error_out) if error_out
146
+
109
147
  # cleanup (supposed to call when $pry is destroyed)
110
148
  # pry.repl_epilogue(target)
111
149
 
@@ -2,6 +2,6 @@
2
2
  module Rack
3
3
  class Webconsole
4
4
  # rack-webconsole version number.
5
- VERSION = "0.1.8"
5
+ VERSION = "0.1.9"
6
6
  end
7
7
  end
@@ -1 +0,0 @@
1
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
@@ -12,76 +12,96 @@ module Rack
12
12
  end
13
13
 
14
14
  describe "#call" do
15
- it 'evaluates the :query param in a sandbox and returns the result' do
16
- @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
17
- env = {}
18
- Webconsole::Repl.stubs(:token_valid?).returns(true)
19
- request = OpenStruct.new(:params => {'query' => 'a = 4; a * 2'}, :post? => true)
15
+ let(:app) { lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] } }
16
+ let(:repl) { Webconsole::Repl.new(app) }
17
+ before(:each) do
18
+ @app = app
19
+ end
20
+ let(:environment) { {} }
21
+ let(:use_post) { true }
22
+
23
+ # sends input query using the webconsole, returning the response
24
+ # query: The pry input to use
25
+ # token:(optional) The authentication token
26
+ def response_to(query, token = nil)
27
+ params = {'query' => query }
28
+ params['token'] = token if token
29
+ request = OpenStruct.new(:params => params, :post? => use_post)
20
30
  Rack::Request.stubs(:new).returns request
31
+ repl.call(environment)
32
+ end
21
33
 
22
- @repl = Webconsole::Repl.new(@app)
23
-
24
- response = @repl.call(env).last.first
34
+ # same as send_input, but extracts the result out of the query
35
+ def query(input, token = nil)
36
+ response = response_to(input, token)
37
+ MultiJson.load(response.last.first)['result']
38
+ end
25
39
 
26
- MultiJson.load(response)['result'].must_include "8" # include because of coloring characters
40
+ def with_token(token)
41
+ Webconsole::Repl.send(:class_variable_set, :@@tokens, {token => Time.now + 30 * 60})
27
42
  end
28
43
 
29
- it 'maintains local state in subsequent calls thanks to an evil global variable' do
30
- @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
31
- env = {}
32
- Webconsole::Repl.stubs(:token_valid?).returns(true)
33
- request = OpenStruct.new(:params => {'query' => 'a = 4'}, :post? => true)
34
- Rack::Request.stubs(:new).returns request
35
- @repl = Webconsole::Repl.new(@app)
44
+ it 'handles a request with a correct token' do
45
+ with_token('abc')
46
+ response_to('unknown_method', 'abc').wont_equal app.call(environment)
47
+ end
36
48
 
37
- @repl.call(env) # call 1 sets a to 4
49
+ it 'rejects a request with an invalid token' do
50
+ with_token('abc')
51
+ response_to('unknown_method', 'cba').must_equal app.call(environment)
52
+ end
38
53
 
39
- request = OpenStruct.new(:params => {'query' => 'a * 8', 'token' => 'abc'}, :post? => true)
40
- Rack::Request.stubs(:new).returns request
54
+ describe "with a valid token" do
55
+ before(:each) do
56
+ Webconsole::Repl.stubs(:token_valid?).returns(true)
57
+ end
41
58
 
42
- response = @repl.call(env).last.first # call 2 retrieves a and multiplies it by 8
59
+ it 'evaluates the :query param in a sandbox and returns the result' do
60
+ query('a = 4; a * 2').must_include "8"
61
+ end
43
62
 
44
- MultiJson.decode(response)['result'].must_include "32" # include because of coloring characters
45
- end
63
+ it 'displays data sent to stdout' do
64
+ query('puts "hello world"').must_include "hello world"
65
+ end
46
66
 
47
- it "returns any found errors prepended with 'Error:'" do
48
- @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
49
- env = {}
50
- Webconsole::Repl.stubs(:token_valid?).returns(true)
51
- request = OpenStruct.new(:params => {'query' => 'unknown_method'}, :post? => true)
52
- Rack::Request.stubs(:new).returns request
53
- @repl = Webconsole::Repl.new(@app)
67
+ it 'displays data sent to stderr' do
68
+ query('warn "Warning"').must_include "Warning"
69
+ end
54
70
 
55
- response = @repl.call(env).last.first
71
+ it 'displays data sent to stdout after a delay' do
72
+ query('.sleep 0.5; echo command output').must_include 'command output'
73
+ end
56
74
 
57
- MultiJson.decode(response)['result'].must_match /Error:/
58
- end
75
+ it "Outputs the result of the computation after an stdout data" do
76
+ output = query('puts "stdout";"result"')
77
+ result_loc = output.match("result").begin(0)
78
+ stdout_loc = output.match("stdout").begin(0)
79
+ (stdout_loc < result_loc).must_equal true
80
+ end
59
81
 
60
- it 'rejects non-post requests' do
61
- @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
62
- env = {}
63
- Webconsole::Repl.stubs(:token).returns('abc')
64
- request = OpenStruct.new(:params => {'query' => 'unknown_method', 'token' => 'abc'}, :post? => false)
65
- Rack::Request.stubs(:new).returns request
66
- @repl = Webconsole::Repl.new(@app)
82
+ it 'displays stdout data from external processes' do
83
+ query('.echo command output').must_include 'command output'
84
+ end
67
85
 
68
- $sandbox.expects(:instance_eval).never
86
+ it 'maintains local state in subsequent calls thanks to an evil global variable' do
87
+ query('a = 4')
88
+ query('a * 8').must_include "32"
89
+ end
69
90
 
70
- @repl.call(env).must_equal @app.call(env)
91
+ it "returns any found errors prepended with 'Error:'" do
92
+ query('unknown_method').must_match /Error:/
93
+ end
71
94
  end
72
95
 
73
- it 'rejects requests with invalid token' do
74
- @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
75
- env = {}
76
- Webconsole::Repl.stubs(:token).returns('abc')
77
- request = OpenStruct.new(:params => {'query' => 'unknown_method', 'token' => 'cba'}, :post? => true)
78
- Rack::Request.stubs(:new).returns request
79
- @repl = Webconsole::Repl.new(@app)
80
-
81
- $sandbox.expects(:instance_eval).never
82
-
83
- @repl.call(env).must_equal @app.call(env)
96
+ describe "with non-post requests" do
97
+ let(:use_post) { false }
98
+ it "rejects the request" do
99
+ with_token('abc')
100
+ response = response_to('unknown_method', 'abc')
101
+ response.must_equal app.call(environment)
102
+ end
84
103
  end
104
+
85
105
  end
86
106
 
87
107
  describe 'class methods' do
@@ -10,6 +10,11 @@ module Rack
10
10
  @webconsole.instance_variable_get(:@app).must_equal @app
11
11
  end
12
12
 
13
+ it 'initializes config' do
14
+ Webconsole.inject_jquery.must_equal false
15
+ Webconsole.key_code.must_equal "[96]"
16
+ end
17
+
13
18
  describe "#call" do
14
19
  it 'delegates the call to the Repl middleware when the path is /webconsole' do
15
20
  @app = stub
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-webconsole-pry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-06-11 00:00:00.000000000 Z
15
+ date: 2013-02-04 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rack
@@ -203,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
203
  version: '0'
204
204
  segments:
205
205
  - 0
206
- hash: 1992267155081239539
206
+ hash: 1934120066910343012
207
207
  required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  none: false
209
209
  requirements:
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  version: '0'
213
213
  segments:
214
214
  - 0
215
- hash: 1992267155081239539
215
+ hash: 1934120066910343012
216
216
  requirements: []
217
217
  rubyforge_project: rack-webconsole-pry
218
218
  rubygems_version: 1.8.24