Skip to content

Commit

Permalink
Add Session#context(obj) method
Browse files Browse the repository at this point in the history
  • Loading branch information
sh19910711 committed Jul 16, 2016
1 parent b6769aa commit d42d509
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/web_console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module WebConsole
autoload :Whitelist
autoload :Template
autoload :Middleware
autoload :Context

autoload_at 'web_console/errors' do
autoload :Error
Expand Down
46 changes: 46 additions & 0 deletions lib/web_console/context.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module WebConsole
# A context lets you get object names related to the current session binding.
class Context
def initialize(binding)
@binding = binding
end

# Extracts entire objects which can be called by the current session unless the objpath is present.
# Otherwise, it extracts methods and constants of the object specified by the objpath.
def extract(objpath)
if objpath.present?
local(objpath)
else
global
end
end

private

GLOBAL_OBJECTS = [
'global_variables',
'local_variables',
'instance_variables',
'instance_methods',
'class_variables',
'methods',
'Object.constants',
'Kernel.methods',
]

def global
GLOBAL_OBJECTS.map { |cmd| eval(cmd) }.flatten
end

def local(objpath)
[
eval("#{objpath}.methods").map { |m| "#{objpath}.#{m}" },
eval("#{objpath}.constants").map { |c| "#{objpath}::#{c}" },
].flatten
end

def eval(cmd)
@binding.eval(cmd) rescue []
end
end
end
2 changes: 1 addition & 1 deletion lib/web_console/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def id_for_repl_session_stack_frame_change(request)

def update_repl_session(id, request)
json_response_with_session(id, request) do |session|
{ output: session.eval(request.params[:input]) }
{ output: session.eval(request.params[:input]), context: session.context(request.params[:context]) }
end
end

Expand Down
9 changes: 7 additions & 2 deletions lib/web_console/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def from(storage)
def initialize(bindings)
@id = SecureRandom.hex(16)
@bindings = bindings
@evaluator = Evaluator.new(bindings.first)
@evaluator = Evaluator.new(@current_binding = bindings.first)

store_into_memory
end
Expand All @@ -59,7 +59,12 @@ def eval(input)
#
# Returns nothing.
def switch_binding_to(index)
@evaluator = Evaluator.new(@bindings[index.to_i])
@evaluator = Evaluator.new(@current_binding = @bindings[index.to_i])
end

# Returns context of the current binding
def context(objpath)
Context.new(@current_binding).extract(objpath)
end

private
Expand Down
28 changes: 28 additions & 0 deletions test/web_console/context_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'test_helper'

module WebConsole
class ContextTest < ActiveSupport::TestCase
test '#extract(empty) includes local variables' do
local_var = 'local'
assert Context.new(binding).extract('').include?(:local_var)
end

test '#extract(empty) includes instance variables' do
@instance_var = 'instance'
assert Context.new(binding).extract('').include?(:@instance_var)
end

test '#extract(empty) includes global variables' do
$global_var = 'global'
assert Context.new(binding).extract('').include?(:$global_var)
end

test '#extract(obj) returns methods' do
assert Context.new(binding).extract('Rails').include?('Rails.root')
end

test '#extract(obj) returns constants' do
assert Context.new(binding).extract('WebConsole').include?('WebConsole::Middleware')
end
end
end

0 comments on commit d42d509

Please sign in to comment.