mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
greatly simplify the rhino interface by tieing context to a scope
This commit is contained in:
parent
a87b7f5085
commit
6239a0ba60
5 changed files with 50 additions and 76 deletions
|
@ -4,41 +4,41 @@ module Rhino
|
|||
end
|
||||
|
||||
class Context
|
||||
|
||||
attr_reader :scope
|
||||
|
||||
class << self
|
||||
def open
|
||||
def open(options = {})
|
||||
ContextFactory.new.call do |native|
|
||||
yield new(native)
|
||||
yield new(native, options)
|
||||
end
|
||||
end
|
||||
|
||||
def open_std(options = {})
|
||||
open do |cxt|
|
||||
yield cxt, cxt.init_standard_objects(options)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private :new
|
||||
end
|
||||
|
||||
def initialize(native) #:nodoc:
|
||||
def initialize(native, options) #:nodoc:
|
||||
@native = native
|
||||
end
|
||||
|
||||
def init_standard_objects(options = {})
|
||||
NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true)).tap do |objects|
|
||||
unless options[:java]
|
||||
for package in ["Packages", "java", "org", "com"]
|
||||
objects.j.delete(package)
|
||||
end
|
||||
@scope = NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true))
|
||||
unless options[:java]
|
||||
for package in ["Packages", "java", "org", "com"]
|
||||
@scope.j.delete(package)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def eval(str, scope = @native.initStandardObjects())
|
||||
def [](k)
|
||||
@scope[k]
|
||||
end
|
||||
|
||||
def []=(k,v)
|
||||
@scope[k] = v
|
||||
end
|
||||
|
||||
def eval(str)
|
||||
str = str.to_s
|
||||
begin
|
||||
To.ruby @native.evaluateString(To.javascript(scope), str, "<eval>", 1, nil)
|
||||
To.ruby @native.evaluateString(@scope.j, str, "<eval>", 1, nil)
|
||||
rescue J::RhinoException => e
|
||||
raise Rhino::RhinoError, e
|
||||
end
|
||||
|
@ -48,11 +48,7 @@ module Rhino
|
|||
@native.setInstructionObserverThreshold(limit);
|
||||
@native.factory.instruction_limit = limit
|
||||
end
|
||||
|
||||
def standard
|
||||
yield @native.initStandardObjects()
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
class Function < J::BaseFunction
|
||||
|
|
|
@ -6,7 +6,6 @@ module Rhino
|
|||
def ruby(object)
|
||||
case object
|
||||
when *JS_UNDEF then nil
|
||||
when Rhino::RubyObject then object
|
||||
when J::Wrapper then object.unwrap
|
||||
when J::Scriptable then NativeObject.new(object)
|
||||
else object
|
||||
|
|
|
@ -18,66 +18,47 @@ describe Rhino::Context do
|
|||
|
||||
it "can embed primitive ruby object into javascript" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
scope["foo"] = "Hello World"
|
||||
cxt.eval("foo", scope).unwrap.should == "Hello World"
|
||||
end
|
||||
cxt['foo'] = "Hello World"
|
||||
cxt.eval("foo").should == "Hello World"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Initalizing Standard Javascript Objects" do
|
||||
it "provides the standard objects without java integration by default" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
scope["Object"].should_not be_nil
|
||||
scope["Math"].should_not be_nil
|
||||
scope["String"].should_not be_nil
|
||||
scope["Function"].should_not be_nil
|
||||
scope["Packages"].should be_nil
|
||||
scope["java"].should be_nil
|
||||
scope["org"].should be_nil
|
||||
scope["com"].should be_nil
|
||||
end
|
||||
cxt["Object"].should_not be_nil
|
||||
cxt["Math"].should_not be_nil
|
||||
cxt["String"].should_not be_nil
|
||||
cxt["Function"].should_not be_nil
|
||||
cxt["Packages"].should be_nil
|
||||
cxt["java"].should be_nil
|
||||
cxt["org"].should be_nil
|
||||
cxt["com"].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it "provides unsealed standard object by default" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
cxt.eval("Object.foop = 'blort'", scope)
|
||||
scope["Object"]['foop'].should == 'blort'
|
||||
end
|
||||
cxt.eval("Object.foop = 'blort'")
|
||||
cxt["Object"]['foop'].should == 'blort'
|
||||
end
|
||||
end
|
||||
|
||||
it "allows you to seal the standard objects so that they cannot be modified" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects(:sealed => true).tap do |scope|
|
||||
lambda {
|
||||
cxt.eval("Object.foop = 'blort'", scope)
|
||||
}.should raise_error(Rhino::RhinoError)
|
||||
|
||||
lambda {
|
||||
cxt.eval("Object.prototype.toString = function() {}", scope)
|
||||
}.should raise_error(Rhino::RhinoError)
|
||||
|
||||
end
|
||||
Context.open(:sealed => true) do |cxt|
|
||||
lambda {
|
||||
cxt.eval("Object.foop = 'blort'")
|
||||
}.should raise_error(Rhino::RhinoError)
|
||||
|
||||
lambda {
|
||||
cxt.eval("Object.prototype.toString = function() {}")
|
||||
}.should raise_error(Rhino::RhinoError)
|
||||
end
|
||||
end
|
||||
|
||||
it "allows java integration to be turned on when initializing standard objects" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects(:java => true).tap do |scope|
|
||||
scope["Packages"].should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "provides a convenience method for initializing scopes" do
|
||||
Context.open_std(:sealed => true, :java => true) do |cxt, scope|
|
||||
scope["Object"].should_not be_nil
|
||||
scope["java"].should_not be_nil
|
||||
cxt.eval("new java.lang.String('foo')", scope).should == "foo"
|
||||
Context.open(:java => true) do |cxt|
|
||||
cxt["Packages"].should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -85,16 +66,14 @@ describe Rhino::Context do
|
|||
|
||||
it "can call ruby functions from javascript" do
|
||||
Context.open do |cxt|
|
||||
cxt.standard do |scope|
|
||||
scope.put("say", scope, function {|word, times| word * times})
|
||||
cxt.eval("say('Hello',2)", scope).should == "HelloHello"
|
||||
end
|
||||
cxt["say"] = function {|word, times| word * times}
|
||||
cxt.eval("say('Hello',2)").should == "HelloHello"
|
||||
end
|
||||
end
|
||||
|
||||
it "can limit the number of instructions that are executed in the context" do
|
||||
lambda {
|
||||
Context.open_std do |cxt, scope|
|
||||
Context.open do |cxt|
|
||||
cxt.instruction_limit = 100 * 1000
|
||||
timeout(1) do
|
||||
cxt.eval('while (true);')
|
||||
|
|
|
@ -19,9 +19,9 @@ describe Rhino::NativeObject do
|
|||
|
||||
it "doesn't matter if you use a symbol or a string to set a value" do
|
||||
@o[:foo] = "bar"
|
||||
@o['foo'].unwrap.should == "bar"
|
||||
@o['foo'].should == "bar"
|
||||
@o['baz'] = "bang"
|
||||
@o[:baz].unwrap.should == "bang"
|
||||
@o[:baz].should == "bang"
|
||||
end
|
||||
|
||||
it "returns nil when the value is null, null, or not defined" do
|
||||
|
|
|
@ -25,7 +25,7 @@ describe Rhino::To do
|
|||
|
||||
it "it unwraps wrapped java objects" do
|
||||
Context.open do |cx|
|
||||
scope = cx.init_standard_objects
|
||||
scope = cx.scope
|
||||
Java::JavaLang::String.new("Hello World").tap do |str|
|
||||
J::NativeJavaObject.new(scope.j, str, str.getClass()).tap do |o|
|
||||
To.ruby(o).should == "Hello World"
|
||||
|
|
Loading…
Reference in a new issue