execjs-async 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm gemset use execjs-async
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in execjs-async.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ execjs-async (0.0.1)
5
+ execjs (~> 1.1.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ execjs (1.1.3)
11
+ multi_json (~> 1.0)
12
+ multi_json (1.0.3)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ execjs-async!
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ task :default => :test
5
+
6
+ desc "Run tests"
7
+ Rake::TestTask.new("test") { |t|
8
+ t.libs << "test"
9
+ t.verbose = true
10
+ t.warning = true
11
+ }
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "execjs-async/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "execjs-async"
7
+ s.version = Execjs::Async::VERSION
8
+ s.authors = ["Eric Allam"]
9
+ s.email = ["rubymaverick@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Enables Asynchronous Javascript Execution in ExecJS}
12
+ s.description = %q{Enables Asynchronous Javascript Execution in ExecJS}
13
+
14
+ s.rubyforge_project = "execjs-async"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ s.add_runtime_dependency "execjs", '~> 1.1.0'
24
+ end
@@ -0,0 +1,62 @@
1
+ require "execjs-async/version"
2
+ require 'execjs'
3
+
4
+ module Execjs
5
+ module Async
6
+
7
+ # extend from nodes external runtime context, and
8
+ # overwrite compile to use the async source.
9
+ class Context < ExecJS::ExternalRuntime::Context
10
+ ASYNC_SOURCE = <<-'JAVASCRIPT'
11
+ (function(program, execJS, module, exports, require) { execJS(program) })(function(callback) { #{source}
12
+ }, function(program) {
13
+ var output, print = function(string) {
14
+ process.stdout.write('' + string);
15
+ };
16
+ try {
17
+ program(function(result){
18
+ if (typeof result == 'undefined' && result !== null) {
19
+ print('["ok"]');
20
+ } else {
21
+ try {
22
+ print(JSON.stringify(['ok', result]));
23
+ } catch (err) {
24
+ print('["err"]');
25
+ }
26
+ }
27
+ });
28
+ } catch (err) {
29
+ print(JSON.stringify(['err', '' + err]));
30
+ }
31
+ });
32
+ JAVASCRIPT
33
+
34
+ def compile(source)
35
+ ASYNC_SOURCE.dup.tap do |output|
36
+ output.sub!('#{source}') do
37
+ source
38
+ end
39
+ output.sub!('#{encoded_source}') do
40
+ encoded_source = encode_unicode_codepoints(source)
41
+ MultiJson.encode("(function(){ #{encoded_source} })()")
42
+ end
43
+ output.sub!('#{json2_source}') do
44
+ IO.read(ExecJS.root + "/support/json2.js")
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def compile_async(source)
51
+ Context.new(self, source)
52
+ end
53
+ end
54
+
55
+ ExecJS::Runtimes::Node.singleton_class.send(:include, Async)
56
+
57
+ ExecJS.module_eval do
58
+ def self.compile_async(source)
59
+ runtime.compile_async(source)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module Execjs
2
+ module Async
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/test/support.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "test/unit"
2
+ require "execjs/module"
3
+
4
+ begin
5
+ require "execjs-async"
6
+ rescue ExecJS::RuntimeUnavailable => e
7
+ warn e
8
+ exit 2
9
+ end
10
+
11
+
@@ -0,0 +1,58 @@
1
+ require "support"
2
+
3
+ class TestExecJS < Test::Unit::TestCase
4
+ def test_exec
5
+ assert_equal true, ExecJS.exec("return true")
6
+ end
7
+
8
+ def test_eval
9
+ assert_equal ["red", "yellow", "blue"], ExecJS.eval("'red yellow blue'.split(' ')")
10
+ end
11
+
12
+ def test_runtime_available
13
+ runtime = ExecJS::ExternalRuntime.new(:command => "nonexistent")
14
+ assert !runtime.available?
15
+
16
+ runtime = ExecJS::ExternalRuntime.new(:command => "ruby")
17
+ assert runtime.available?
18
+ end
19
+
20
+ def test_runtime_assignment
21
+ original_runtime = ExecJS.runtime
22
+ runtime = ExecJS::ExternalRuntime.new(:command => "nonexistent")
23
+ assert_raises(ExecJS::RuntimeUnavailable) { ExecJS.runtime = runtime }
24
+ assert_equal original_runtime, ExecJS.runtime
25
+
26
+ runtime = ExecJS::ExternalRuntime.new(:command => "ruby")
27
+ ExecJS.runtime = runtime
28
+ assert_equal runtime, ExecJS.runtime
29
+ end
30
+
31
+ def test_compile
32
+ context = ExecJS.compile("foo = function() { return \"bar\"; }")
33
+ assert_equal "bar", context.exec("return foo()")
34
+ assert_equal "bar", context.eval("foo()")
35
+ end
36
+
37
+ def test_compile_async
38
+ context = ExecJS.compile_async("foo = function() { callback('bar') }")
39
+ assert_equal "bar", context.eval("foo()")
40
+ end
41
+
42
+ def test_context_call
43
+ context = ExecJS.compile("id = function(v) { return v; }")
44
+ assert_equal "bar", context.call("id", "bar")
45
+ end
46
+
47
+ def test_nested_context_call
48
+ context = ExecJS.compile("a = {}; a.b = {}; a.b.id = function(v) { return v; }")
49
+ assert_equal "bar", context.call("a.b.id", "bar")
50
+ end
51
+
52
+ def test_context_call_missing_function
53
+ context = ExecJS.compile("")
54
+ assert_raises ExecJS::ProgramError do
55
+ context.call("missing")
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,117 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "support"
3
+
4
+ class TestRuntime < Test::Unit::TestCase
5
+ def setup
6
+ # only use node for now
7
+ @runtime = ExecJS::Runtimes::Node
8
+ end
9
+
10
+ def test_exec
11
+ assert_nil @runtime.exec("1")
12
+ assert_nil @runtime.exec("return")
13
+ assert_nil @runtime.exec("return null")
14
+ assert_nil @runtime.exec("return function() {}")
15
+ assert_equal 0, @runtime.exec("return 0")
16
+ assert_equal true, @runtime.exec("return true")
17
+ assert_equal [1, 2], @runtime.exec("return [1, 2]")
18
+ assert_equal "hello", @runtime.exec("return 'hello'")
19
+ assert_equal({"a"=>1,"b"=>2}, @runtime.exec("return {a:1,b:2}"))
20
+ assert_equal "café", @runtime.exec("return 'café'")
21
+ assert_equal "☃", @runtime.exec('return "☃"')
22
+ assert_equal "☃", @runtime.exec('return "\u2603"')
23
+ assert_equal "\\", @runtime.exec('return "\\\\"')
24
+ end
25
+
26
+ def test_eval
27
+ assert_nil @runtime.eval("")
28
+ assert_nil @runtime.eval(" ")
29
+ assert_nil @runtime.eval("null")
30
+ assert_nil @runtime.eval("function() {}")
31
+ assert_equal 0, @runtime.eval("0")
32
+ assert_equal true, @runtime.eval("true")
33
+ assert_equal [1, 2], @runtime.eval("[1, 2]")
34
+ assert_equal [1, nil], @runtime.eval("[1, function() {}]")
35
+ assert_equal "hello", @runtime.eval("'hello'")
36
+ assert_equal({"a"=>1,"b"=>2}, @runtime.eval("{a:1,b:2}"))
37
+ assert_equal({"a"=>true}, @runtime.eval("{a:true,b:function (){}}"))
38
+ assert_equal "café", @runtime.eval("'café'")
39
+ assert_equal "☃", @runtime.eval('"☃"')
40
+ assert_equal "☃", @runtime.eval('"\u2603"')
41
+ assert_equal "\\", @runtime.eval('"\\\\"')
42
+ end
43
+
44
+ if defined? Encoding
45
+ def test_encoding
46
+ utf8 = Encoding.find('UTF-8')
47
+
48
+ assert_equal utf8, @runtime.exec("return 'hello'").encoding
49
+ assert_equal utf8, @runtime.eval("'☃'").encoding
50
+
51
+ ascii = "'hello'".encode('US-ASCII')
52
+ result = @runtime.eval(ascii)
53
+ assert_equal "hello", result
54
+ assert_equal utf8, result.encoding
55
+
56
+ assert_raise Encoding::UndefinedConversionError do
57
+ binary = "\xde\xad\xbe\xef".force_encoding("BINARY")
58
+ @runtime.eval(binary)
59
+ end
60
+ end
61
+
62
+ def test_encoding_compile
63
+ utf8 = Encoding.find('UTF-8')
64
+
65
+ context = @runtime.compile("foo = function(v) { return '¶' + v; }".encode("ISO8859-15"))
66
+
67
+ assert_equal utf8, context.exec("return foo('hello')").encoding
68
+ assert_equal utf8, context.eval("foo('☃')").encoding
69
+
70
+ ascii = "foo('hello')".encode('US-ASCII')
71
+ result = context.eval(ascii)
72
+ assert_equal "¶hello", result
73
+ assert_equal utf8, result.encoding
74
+
75
+ assert_raise Encoding::UndefinedConversionError do
76
+ binary = "\xde\xad\xbe\xef".force_encoding("BINARY")
77
+ context.eval(binary)
78
+ end
79
+ end
80
+ end
81
+
82
+ def test_compile
83
+ context = @runtime.compile("foo = function() { return \"bar\"; }")
84
+ assert_equal "bar", context.exec("return foo()")
85
+ assert_equal "bar", context.eval("foo()")
86
+ assert_equal "bar", context.call("foo")
87
+ end
88
+
89
+ def test_compile_with_async
90
+ context = @runtime.compile_async("foo = function() { callback('bar') }")
91
+ assert_equal "bar", context.call("foo")
92
+ assert_equal "bar", context.eval("foo()")
93
+ assert_equal "bar", context.exec("return foo()")
94
+ end
95
+
96
+ def test_this_is_global_scope
97
+ assert_equal true, @runtime.eval("this === (function() {return this})()")
98
+ assert_equal true, @runtime.exec("return this === (function() {return this})()")
99
+ end
100
+
101
+ def test_compile_large_scripts
102
+ body = "var foo = 'bar';\n" * 100_000
103
+ assert @runtime.exec("function foo() {\n#{body}\n};\nreturn true")
104
+ end
105
+
106
+ def test_syntax_error
107
+ assert_raise ExecJS::RuntimeError do
108
+ @runtime.exec(")")
109
+ end
110
+ end
111
+
112
+ def test_thrown_exception
113
+ assert_raise ExecJS::ProgramError do
114
+ @runtime.exec("throw 'hello'")
115
+ end
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: execjs-async
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Allam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-28 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: execjs
16
+ requirement: &70268197049220 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70268197049220
25
+ description: Enables Asynchronous Javascript Execution in ExecJS
26
+ email:
27
+ - rubymaverick@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .rvmrc
34
+ - Gemfile
35
+ - Gemfile.lock
36
+ - Rakefile
37
+ - execjs-async.gemspec
38
+ - lib/execjs-async.rb
39
+ - lib/execjs-async/version.rb
40
+ - test/support.rb
41
+ - test/test_execjs.rb
42
+ - test/test_runtime.rb
43
+ homepage: ''
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project: execjs-async
63
+ rubygems_version: 1.8.6
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Enables Asynchronous Javascript Execution in ExecJS
67
+ test_files:
68
+ - test/support.rb
69
+ - test/test_execjs.rb
70
+ - test/test_runtime.rb