runjs 0.1.0

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.
@@ -0,0 +1,150 @@
1
+ require 'test_helper'
2
+
3
+ describe 'syntax error' do
4
+
5
+ specify 'a JavaScript syntax error raises a CompileError' do
6
+ assert_raises(RunJS::CompileError) do
7
+ RunJS.run(']')
8
+ end
9
+ end
10
+
11
+ specify 'eval with syntax error raises a JavaScriptError' do
12
+ error = assert_raises(RunJS::JavaScriptError) do
13
+ RunJS.eval(']')
14
+ end
15
+ assert_equal 'SyntaxError', error['name']
16
+ end
17
+
18
+ specify 'throw SyntaxError raises a JavaScriptError' do
19
+ error = assert_raises(RunJS::JavaScriptError) do
20
+ RunJS.run('throw new SyntaxError();')
21
+ end
22
+ assert_equal 'SyntaxError', error[:name]
23
+ end
24
+
25
+ end
26
+
27
+ describe 'runtime error' do
28
+
29
+ describe 'raising a JavaScriptError' do
30
+
31
+ specify 'the JavaScript code throws an error' do
32
+ assert_raises(RunJS::JavaScriptError) do
33
+ RunJS.run('throw new Error();')
34
+ end
35
+ end
36
+
37
+ specify 'calling an undefined function' do
38
+ assert_raises(RunJS::JavaScriptError) do
39
+ RunJS.call('notAFunction')
40
+ end
41
+ end
42
+
43
+ specify 'JSON.stringify gets a cyclic structure' do
44
+ assert_raises(RunJS::JavaScriptError) do
45
+ RunJS.run('var cycle = {}; cycle.self = cycle; return cycle;')
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ specify 'the error message' do
52
+ error = RunJS.run('throw new Error("msg");') rescue $!
53
+ assert_equal 'Error: msg', error.message
54
+
55
+ error = RunJS.run('throw new Error();') rescue $!
56
+ assert_equal 'Error', error.message
57
+
58
+ error = RunJS.run('throw "msg";') rescue $!
59
+ assert_equal 'msg', error.message
60
+
61
+ error = RunJS.run('throw "";') rescue $!
62
+ assert_equal '', error.message
63
+
64
+ error = RunJS.run('throw [];') rescue $!
65
+ assert_equal '', error.message
66
+
67
+ error = RunJS.run('throw 0;') rescue $!
68
+ assert_equal '0', error.message
69
+ end
70
+
71
+ describe 'the error object' do
72
+
73
+ it 'contains the thrown JavaScript object' do
74
+ error = RunJS.run('throw "msg";') rescue $!
75
+ assert_equal 'msg', error.error
76
+
77
+ error = RunJS.run('throw 0;') rescue $!
78
+ assert_equal 0, error.error
79
+
80
+ error = RunJS.run('throw null;') rescue $!
81
+ assert_equal nil, error.error
82
+ end
83
+
84
+ it 'captures all the properties of the thrown error object' do
85
+ error = assert_raises(RunJS::JavaScriptError) do
86
+ RunJS.run(
87
+ 'var err = new Error("msg");' <<
88
+ 'err.location = { line: 4, column: 8 };' <<
89
+ 'throw err;'
90
+ )
91
+ end
92
+ assert_equal 'Error', error['name']
93
+ assert_equal 'msg', error['message']
94
+ assert_equal 4, error['location']['line']
95
+
96
+ skip if RunJS.runtime == RunJS::JScript
97
+ skip if RunJS.runtime == RunJS::TheRubyRhino
98
+
99
+ refute_empty error['stack']
100
+ end
101
+
102
+ it 'handles array error objects' do
103
+ error = RunJS.run('throw [false];') rescue $!
104
+ assert_equal [false], error.error
105
+ assert_equal false, error[0]
106
+ end
107
+
108
+ it 'handles error properties that cannot be stringified (cyclic objects)' do
109
+ error = assert_raises(RunJS::JavaScriptError) do
110
+ context = RunJS.context('var cycle = {}; cycle.self = cycle;')
111
+ context.run('throw { name: "Cycle", cycle: cycle };')
112
+ end
113
+ assert_equal 'Cycle', error['name']
114
+ assert_equal '[object Object]', error['cycle']
115
+ end
116
+
117
+ it 'shortens the stack trace produced by SpiderMonkey' do
118
+ error = RunJS.call('notAFunction', 'x' * 2000) rescue $!
119
+ if RunJS.runtime == RunJS::SpiderMonkey
120
+ assert_equal 1005, error.error['stack'].size
121
+ assert_match 'xxx ... xxx', error['stack']
122
+ else
123
+ refute_match ' ... ', error[:stack]
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ describe 'accessing the JavaScript source code that caused the error' do
132
+
133
+ def runner(js)
134
+ if RunJS.runtime == RunJS::JScript
135
+ js = [RunJS::JScript::JSON_JS, js].join("\n")
136
+ end
137
+ RunJS::Runtime::RUNNER % js
138
+ end
139
+
140
+ specify 'CompileError#source contains the runner code' do
141
+ error = assert_raises(RunJS::CompileError) { RunJS.run('(') }
142
+ assert_equal runner('('), error.source
143
+ end
144
+
145
+ specify 'JavaScriptError#source contains the runner code' do
146
+ error = assert_raises(RunJS::JavaScriptError) { RunJS.run('foo();') }
147
+ assert_equal runner('foo();'), error.source
148
+ end
149
+
150
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'run JavaScript' do
6
+
7
+ specify 'call' do
8
+ assert_equal 5, RunJS.call('Math.sqrt', 25)
9
+ assert_equal 0, RunJS.call('Date.parse', 'Jan 1 1970 UTC')
10
+ end
11
+
12
+ specify 'apply' do
13
+ result = RunJS.apply('Array.prototype.concat', '["cat"]', 2, :food => nil)
14
+ assert_equal ['cat', 2, { 'food' => nil }], result
15
+
16
+ skip if RunJS.runtime == RunJS::JScript
17
+
18
+ result = RunJS.apply('Array.prototype.slice', 'cat'.to_json)
19
+ assert_equal ['c', 'a', 't'], result
20
+ end
21
+
22
+ specify 'run' do
23
+ assert_nil RunJS.run('true;')
24
+ assert_nil RunJS.run('return undefined;')
25
+ assert_equal 4, RunJS.run('return 2 + 2;')
26
+ assert_equal false, RunJS.run('var x = 2, y = 2; return x > y;')
27
+ assert_equal [1, 'cat'], RunJS.run('return [1].concat("cat");')
28
+ assert_equal '\\', RunJS.run('return "\\\\";')
29
+ end
30
+
31
+ describe 'eval' do
32
+
33
+ specify 'eval' do
34
+ assert_nil RunJS.eval(nil)
35
+ assert_nil RunJS.eval('')
36
+ assert_equal 4, RunJS.eval('2 + 2')
37
+ assert_equal 4, RunJS.eval('var x = 2, y = 2; x + y')
38
+ assert_equal ['c', 'a', 't'], RunJS.eval('"cat".split("")')
39
+ end
40
+
41
+ it 'requires parentheses around objects' do
42
+ assert_equal Hash['one' => 1], RunJS.eval('({ one: 1 })')
43
+ end
44
+
45
+ it 'requires parentheses around anonymous functions' do
46
+ assert_nil RunJS.eval('(function() {})')
47
+ assert_nil RunJS.eval('function notAnonymous() {}')
48
+ assert_nil RunJS.eval('var notAnonymous = function() {}')
49
+ end
50
+
51
+ end
52
+
53
+ describe 'context' do
54
+
55
+ it 'supports nested context' do
56
+ js = 'a = {}; a.b = {}; a.b.c = function(d) { return d; }'
57
+ assert_equal 'nest', RunJS.context(js).call('a.b.c', 'nest')
58
+ end
59
+
60
+ it 'supports many contexts' do
61
+ heart = 'function heart(s) { return "♥ " + s + " ♥"; }'
62
+ upcase = 'function upcase(s) { return s.toUpperCase(); }'
63
+ decorate = 'function decorate(s) { return heart(upcase(s)); }'
64
+ context = RunJS.context(upcase).context(heart).context(decorate)
65
+ assert_equal '♥ RUBY ♥', context.call('decorate', 'ruby')
66
+ end
67
+
68
+ specify 'using a runtime instance' do
69
+ instance = RunJS.runtime.new
70
+ instance.context('function upcase(s) { return s.toUpperCase(); }')
71
+ instance.context('function star(s) { return "★" + upcase(s) + "★"; }')
72
+ assert_equal '★RUBY★', instance.run('return star("ruby");')
73
+ assert_equal '★RUBY★', instance.apply('star', nil, 'ruby')
74
+ assert_equal '★RUBY★', instance.call('star', 'ruby')
75
+ assert_equal '★RUBY★', instance.eval('star("ruby")')
76
+ end
77
+
78
+ end
79
+
80
+ it 'does not use strict mode by default' do
81
+ js = 'aGlobalVariable = true; return aGlobalVariable;'
82
+ assert_equal true, RunJS.run(js)
83
+
84
+ skip if RunJS.runtime == RunJS::JScript
85
+ skip if RunJS.runtime == RunJS::TheRubyRhino
86
+
87
+ error = assert_raises(RunJS::JavaScriptError) do
88
+ RunJS.run("'use strict'; #{js}")
89
+ end
90
+ assert_equal 'ReferenceError', error[:name]
91
+ end
92
+
93
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+
3
+ describe 'select a runtime' do
4
+
5
+ class AvailableRuntime < RunJS::SystemRuntime
6
+ @cmd = 'ruby'
7
+ end
8
+
9
+ class DeprecatedRuntime < RunJS::SystemRuntime
10
+ @cmd = 'ruby'
11
+ @deprecated = true
12
+ end
13
+
14
+ class UnavailableRuntime < RunJS::SystemRuntime
15
+ @cmd = 'this is not a command'
16
+ end
17
+
18
+ specify 'the runtime is available if @cmd is executable' do
19
+ assert AvailableRuntime.available?
20
+ refute UnavailableRuntime.available?
21
+ end
22
+
23
+ specify 'deprecated' do
24
+ refute AvailableRuntime.deprecated?
25
+ assert DeprecatedRuntime.deprecated?
26
+ end
27
+
28
+ before { @runtime = RunJS.runtime }
29
+ after { RunJS.runtime = @runtime }
30
+
31
+ describe 'setting the runtime manually' do
32
+
33
+ it 'sets the runtime if it is available' do
34
+ RunJS.runtime = AvailableRuntime
35
+ assert_equal AvailableRuntime, RunJS.runtime
36
+ end
37
+
38
+ it 'accepts a deprecated runtime' do
39
+ RunJS.runtime = DeprecatedRuntime
40
+ assert_equal DeprecatedRuntime, RunJS.runtime
41
+ end
42
+
43
+ it 'raises RuntimeUnavailable if the runtime is unavailable' do
44
+ assert_raises(RunJS::RuntimeUnavailable) do
45
+ RunJS.runtime = UnavailableRuntime
46
+ end
47
+ assert_equal @runtime, RunJS.runtime
48
+ end
49
+
50
+ end
51
+
52
+ describe 'selecting a runtime automatically' do
53
+
54
+ before do
55
+ @runtimes = RunJS::RUNTIMES.dup
56
+ @environment = ENV['RUNJS_RUNTIME']
57
+
58
+ ENV['RUNJS_RUNTIME'] = nil
59
+ RunJS.instance_variable_set(:@runtime, nil)
60
+ end
61
+
62
+ after do
63
+ RunJS::RUNTIMES.replace(@runtimes)
64
+ ENV['RUNJS_RUNTIME'] = @environment
65
+ end
66
+
67
+ it 'selects the first available runtime' do
68
+ RunJS::RUNTIMES.replace([UnavailableRuntime, AvailableRuntime] + @runtimes)
69
+ assert_equal AvailableRuntime, RunJS.runtime
70
+ end
71
+
72
+ it 'will not select a deprecated runtime automatically' do
73
+ RunJS::RUNTIMES.replace([DeprecatedRuntime])
74
+ assert_raises(RunJS::RuntimeUnavailable) { RunJS.runtime }
75
+ end
76
+
77
+ it 'raises RuntimeUnavailable if none of the supported runtimes are installed' do
78
+ RunJS::RUNTIMES.replace([UnavailableRuntime, DeprecatedRuntime])
79
+ assert_raises(RunJS::RuntimeUnavailable) { RunJS.runtime }
80
+ end
81
+
82
+ describe 'the RUNJS_RUNTIME environment variable' do
83
+
84
+ it 'selects the runtime set by the environment' do
85
+ ENV['RUNJS_RUNTIME'] = 'AvailableRuntime'
86
+ assert_equal AvailableRuntime, RunJS.runtime
87
+ end
88
+
89
+ it 'will accept a deprecated runtime from the environment' do
90
+ ENV['RUNJS_RUNTIME'] = 'DeprecatedRuntime'
91
+ assert_equal DeprecatedRuntime, RunJS.runtime
92
+ end
93
+
94
+ it 'raises RuntimeUnavailable if the runtime is unavailable' do
95
+ ENV['RUNJS_RUNTIME'] = 'UnavailableRuntime'
96
+ assert_raises(RunJS::RuntimeUnavailable) { RunJS.runtime }
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+
103
+ end
@@ -0,0 +1,17 @@
1
+ require 'runjs'
2
+
3
+ def display_banner(width)
4
+ runtime = RunJS.runtime.class_name rescue ENV['RUNJS_RUNTIME']
5
+ ruby = defined?(JRUBY_VERSION) ? "JRuby #{JRUBY_VERSION}" :
6
+ "Ruby #{RUBY_VERSION}"
7
+ puts
8
+ puts '=' * width
9
+ puts "#{runtime} - #{ruby}".center(width)
10
+ puts '=' * width
11
+ puts
12
+ end
13
+
14
+ display_banner(40)
15
+ RunJS.runtime rescue abort $!.message # abort if no runtime is detected
16
+
17
+ require 'minitest/autorun'
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: runjs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - AS Harbitz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coffee-script-source
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: therubyracer
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: therubyrhino
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: 'You can run JavaScript code from Ruby with RunJS. The supported JavaScript
70
+ engines are: Node, V8, TheRubyRacer, JavaScriptCore and JScript.'
71
+ email: asharbitz@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - LICENSE
77
+ - Rakefile
78
+ - runjs.gemspec
79
+ - README.md
80
+ - lib/runjs/encoding.rb
81
+ - lib/runjs/error.rb
82
+ - lib/runjs/os.rb
83
+ - lib/runjs/runtime.rb
84
+ - lib/runjs/runtimes/java_script_core.rb
85
+ - lib/runjs/runtimes/jscript.rb
86
+ - lib/runjs/runtimes/node.rb
87
+ - lib/runjs/runtimes/spider_monkey.rb
88
+ - lib/runjs/runtimes/the_ruby_racer.rb
89
+ - lib/runjs/runtimes/the_ruby_rhino.rb
90
+ - lib/runjs/runtimes/v8.rb
91
+ - lib/runjs/support/runner.js
92
+ - lib/runjs/system_runtime.rb
93
+ - lib/runjs/vendor/json2.js
94
+ - lib/runjs.rb
95
+ - test/coffeescript_test.rb
96
+ - test/encoding_test.rb
97
+ - test/execjs_test.rb
98
+ - test/javascript_error_test.rb
99
+ - test/javascript_test.rb
100
+ - test/select_runtime_test.rb
101
+ - test/test_helper.rb
102
+ homepage: https://github.com/asharbitz/runjs
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message: |2+
107
+
108
+ If your version of ruby is older than 1.9, you may need to install json:
109
+ gem install json || gem install json_pure
110
+
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: 1.8.7
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.0.3
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Run JavaScript code from Ruby
130
+ test_files:
131
+ - test/coffeescript_test.rb
132
+ - test/encoding_test.rb
133
+ - test/execjs_test.rb
134
+ - test/javascript_error_test.rb
135
+ - test/javascript_test.rb
136
+ - test/select_runtime_test.rb
137
+ - test/test_helper.rb