execjs-async 0.0.1

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.
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