javascript 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 544e1722b5fdd2b8b5e4413429f6b2dbcc712510
4
+ data.tar.gz: 3223853a5070525beec270b95deb495daeef882d
5
+ SHA512:
6
+ metadata.gz: 87f978520f3e4852bae730566faac9b46685ef8874991a2ef2151827ba3d50e52d4de43910d4dbc893dea83350fecf45bbeaba7aea5fcc8284130fcf46e90d97
7
+ data.tar.gz: 3180b93400097eee3fd7d6e09d135f2c3d4e2cb39d87d48bf3298bf856dd4fddea42f1e24f5829b9e28d42dc417d2212b794c6e096634683dee2f343e9ce5756
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.3
4
+ - ruby-head
5
+
6
+ notifications:
7
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in javascript.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Godfrey Chan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,164 @@
1
+ # JavaScript
2
+
3
+ As much as we love writing Ruby, when you need to *get closer to the metal*, you
4
+ have no choice but to use JavaScript. With this gem, Rubyists can finally
5
+ harness the raw power of their machines by dropping down to the metal *right
6
+ inside their Ruby applications*.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'javascript'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install javascript
23
+
24
+ ## Usage
25
+
26
+ ```ruby
27
+ require "javascript"
28
+
29
+ puts "This is totally Ruby"
30
+
31
+ javascript {
32
+
33
+ console.log("ZOMG JavaScript");
34
+
35
+ var a = 1;
36
+
37
+ console.log(a);
38
+
39
+ a = a + 1;
40
+
41
+ console.log(a);
42
+
43
+ var b = function(x) {
44
+ console.log(x + 1);
45
+ };
46
+
47
+ b(3);
48
+
49
+ function c(x) {
50
+ console.log(x + 2);
51
+ }
52
+
53
+ c(4);
54
+
55
+ function inspectArguments() {
56
+ var args = Array.prototype.join.call(arguments, ", ");
57
+ console.log("Arguments: " + args);
58
+ }
59
+
60
+ inspectArguments("a", "b", "c");
61
+
62
+ inspectArguments(1, 2, 3, 4, 5);
63
+
64
+ }
65
+
66
+ puts "This is Ruby again"
67
+ ```
68
+
69
+ Output:
70
+
71
+ ```
72
+ % ruby test.rb
73
+ This is totally Ruby
74
+ ZOMG JavaScript
75
+ 1
76
+ 2
77
+ 4
78
+ 6
79
+ Arguments: a, b, c
80
+ Arguments: 1, 2, 3, 4, 5
81
+ This is Ruby again
82
+ %
83
+ ```
84
+
85
+ ### JavaScript + Rails = <3
86
+
87
+ Because Rails embraces callbacks, this gem is the perfectly compliment for your
88
+ Rails application. For example:
89
+
90
+ ```ruby
91
+ require "javascript"
92
+
93
+ class Post < ActiveRecord::Base
94
+ before_create &javascript {
95
+ function(post) {
96
+ post.slug = post.title.parameterize();
97
+ }
98
+ }
99
+ end
100
+ ```
101
+
102
+ Alternatively:
103
+
104
+ ```ruby
105
+ require "javascript"
106
+
107
+ class Post < ActiveRecord::Base
108
+ before_create &javascript {
109
+ function() {
110
+ this.slug = this.title.parameterize();
111
+ }
112
+ }
113
+ end
114
+ ```
115
+
116
+ ### No Conflict Mode
117
+
118
+ If the `javascript` helper conflicts with an existing method, you use this gem
119
+ in the "no conflict" mode:
120
+
121
+ ```ruby
122
+ require "javascript/no_conflict"
123
+
124
+ # Or add this to your Gemfile:
125
+ #
126
+ # gem "javascript", require: "javascript/no_conflict"
127
+ #
128
+
129
+ JavaScript.eval {
130
+ console.log("JavaScript here");
131
+ }
132
+
133
+ # You can also define your own helper method
134
+
135
+ module Kernel
136
+ private def metal(&block)
137
+ JavaScript.eval(&block)
138
+ end
139
+ end
140
+
141
+ metal {
142
+ console.log("JavaScript here");
143
+ }
144
+ ```
145
+
146
+ ## Pros
147
+
148
+ * Gives you the illusion of programming in a *closer to the metal* syntax.
149
+ * The examples in this README actually work.
150
+ [![Build Status](https://travis-ci.org/vanruby/javascript.svg)](https://travis-ci.org/vanruby/javascript)
151
+
152
+ ## Cons
153
+
154
+ * Things that aren't covered in the examples probably won't ever work.
155
+ ([Check the tests](/test/javascript_test.rb))
156
+ * [Not enough jQuery](http://meta.stackexchange.com/questions/45176/when-is-use-jquery-not-a-valid-answer-to-a-javascript-question)
157
+
158
+ ## Contributing
159
+
160
+ 1. Fork it ( https://github.com/vanruby/javascript/fork )
161
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
162
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
163
+ 4. Push to the branch (`git push origin my-new-feature`)
164
+ 5. Create a new Pull Request
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ desc 'Run tests'
5
+ test_task = Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'test'
7
+ t.pattern = 'test/**/*_test.rb'
8
+ t.verbose = true
9
+ end
10
+
11
+ task default: :test
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "javascript/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "javascript"
8
+ spec.version = JavaScript::VERSION
9
+ spec.authors = ["Godfrey Chan"]
10
+ spec.email = ["godfreykfc@gmail.com"]
11
+ spec.summary = "Seamlessly drop down to the metal with JavaScript"
12
+ spec.description = "With this gem you can finally get closer to the metal" \
13
+ "and harness the raw power of your machine by writing " \
14
+ "JavaScript code right within your Ruby applications."
15
+ spec.homepage = "https://github.com/vanruby/javascript"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^test/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.required_ruby_version = ">= 2.1.0"
24
+
25
+ spec.add_dependency "binding_of_caller", "~> 0.7.0"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.7"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "minitest", "~> 5.0"
30
+ spec.add_development_dependency "activesupport", "~> 4.1.0"
31
+ end
@@ -0,0 +1,326 @@
1
+ require "javascript/version"
2
+ require "binding_of_caller"
3
+
4
+ def supress_warnings
5
+ verbose, $VERBOSE = $VERBOSE, nil
6
+ yield
7
+ ensure
8
+ $VERBOSE = verbose
9
+ end
10
+
11
+ module JavaScript
12
+ def self.eval(&block)
13
+ Scope.new.__eval__(&block)
14
+ end
15
+
16
+ def self.current_scope
17
+ @scope
18
+ end
19
+
20
+ def self.current_scope=(scope)
21
+ @scope = scope
22
+ end
23
+
24
+ # Make it an `Object` instead of `BasicObject` so that we can bind
25
+ # any instance methods from `Object` and call them here
26
+ class BlankObject
27
+ supress_warnings do
28
+ instance_methods(true).each { |meth| undef_method(meth) }
29
+ private_instance_methods(true).each { |meth| undef_method(meth) }
30
+ end
31
+ end
32
+
33
+ module Internals
34
+ supress_warnings do
35
+ def __send__(meth, *args, &block)
36
+ __method__(:public_send).call(meth, *args, &block)
37
+ end
38
+ end
39
+
40
+ private
41
+ def __method__(name)
42
+ ::Object.instance_method(name).bind(self)
43
+ end
44
+
45
+ def __binding__
46
+ __method__(:binding).call.of_caller(1)
47
+ end
48
+
49
+ def __caller__
50
+ __binding__.of_caller(2)
51
+ end
52
+ end
53
+
54
+ class Object < BlankObject
55
+ include Internals
56
+
57
+ def initialize(proto = nil)
58
+ @hash = { __proto__: proto }
59
+ end
60
+
61
+ def [](key)
62
+ if @hash.key?(key)
63
+ @hash[key]
64
+ elsif __proto__
65
+ __proto__[key]
66
+ else
67
+ nil
68
+ end
69
+ end
70
+
71
+ def []=(key, value)
72
+ @hash[key.to_sym] = value
73
+ end
74
+
75
+ def ==(other)
76
+ __method__(:==).call(other)
77
+ end
78
+
79
+ def ===(other)
80
+ self == other
81
+ end
82
+
83
+ def !=(other)
84
+ !(self == other)
85
+ end
86
+
87
+ def __hash__
88
+ @hash
89
+ end
90
+
91
+ def __proto__
92
+ @hash[:__proto__]
93
+ end
94
+
95
+ def __defined__?(key)
96
+ @hash.key?(key) || (__proto__ && __proto__.__defined__?(key))
97
+ end
98
+
99
+ private
100
+ def method_missing(name, *args, &block)
101
+ if name =~ /=\z/
102
+ self[name[0...-1].to_sym] = args[0]
103
+ elsif Function === self[name]
104
+ self[name].apply(self, args)
105
+ else
106
+ self[name]
107
+ end
108
+ end
109
+ end
110
+
111
+ class GlobalObject < Object
112
+ def initialize
113
+ super
114
+ @hash[:console] = Console.new
115
+ end
116
+ end
117
+
118
+ module Syntax
119
+ private
120
+ def window
121
+ @global
122
+ end
123
+
124
+ def global
125
+ @global
126
+ end
127
+
128
+ def this
129
+ @target
130
+ end
131
+
132
+ def undefined
133
+ nil
134
+ end
135
+
136
+ def var(*identifiers)
137
+ end
138
+
139
+ def new(identifier)
140
+ ::Object.const_get(identifier.name).new(*identifier.args)
141
+ end
142
+
143
+ def function(*args, &block)
144
+ if args.length == 1 && Function === args[0]
145
+ hash = @parent ? @locals : global.__hash__
146
+ hash[args[0].name] = args[0]
147
+ else
148
+ Function.new(nil, args, block)
149
+ end
150
+ end
151
+ end
152
+
153
+ class Scope < BlankObject
154
+ include Internals
155
+ include Syntax
156
+
157
+ def initialize(parent = nil, target = nil, locals = {})
158
+ @parent = parent
159
+ @global = parent ? parent.__global__ : GlobalObject.new
160
+ @locals = locals
161
+
162
+ if Scope === target
163
+ @target = target.__target__
164
+ else
165
+ @target = target || global
166
+ end
167
+ end
168
+
169
+ def __global__
170
+ @global
171
+ end
172
+
173
+ def __target__
174
+ @target
175
+ end
176
+
177
+ def __spawn__(target = nil, locals = {})
178
+ Scope.new(self, target, locals)
179
+ end
180
+
181
+ def __eval__(*args, &block)
182
+ JavaScript.current_scope = self
183
+ __method__(:instance_exec).call(*args, &block)
184
+ ensure
185
+ JavaScript.current_scope = @parent
186
+ end
187
+
188
+ private
189
+ def method_missing(name, *args, &block)
190
+ found = false
191
+ value = nil
192
+ defined = __caller__.local_variable_defined?(name) rescue nil
193
+
194
+ if defined
195
+ found = true
196
+ value = __caller__.local_variable_get(name)
197
+ elsif @locals.key?(name)
198
+ found = true
199
+ value = @locals[name]
200
+ elsif !@parent && @global.__defined__?(name)
201
+ found = true
202
+ value = @global[name]
203
+ end
204
+
205
+ if found && Function === value
206
+ value.apply(nil, args)
207
+ elsif found
208
+ value
209
+ elsif @parent
210
+ @parent.__send__(name, *args, &block)
211
+ elsif block.nil?
212
+ Identifier.new(name, args)
213
+ else
214
+ Function.new(name, args, block)
215
+ end
216
+ end
217
+ end
218
+
219
+ class Identifier < Struct.new(:name, :args); end
220
+
221
+ class Function < Struct.new(:name, :args, :body)
222
+ def initialize(*)
223
+ @scope = JavaScript.current_scope
224
+ super
225
+ end
226
+
227
+ def arity
228
+ args.length
229
+ end
230
+
231
+ def call(target = nil, *arg_values)
232
+ ::Object.instance_method(:instance_exec).bind(target).call(*arg_values, &self)
233
+ end
234
+
235
+ def apply(target = nil, arg_values)
236
+ call(target, *arg_values)
237
+ end
238
+
239
+ def bind(target)
240
+ BoundFunction.new(target, name, args, body)
241
+ end
242
+
243
+ def to_proc
244
+ parent_scope = @scope
245
+ arg_names = args.map(&:name)
246
+ unwrapped = body
247
+
248
+ FunctionWrapper.new(arg_names) do |*arg_values|
249
+ locals = Hash[ arg_names.zip(arg_values) ]
250
+ locals[:arguments] = arg_values
251
+ parent_scope.__spawn__(self, locals).__eval__(*arg_values, &unwrapped)
252
+ end
253
+ end
254
+ end
255
+
256
+ class BoundFunction < Function
257
+ def initialize(target, name, args, body)
258
+ super(name, args, body)
259
+ @target = target
260
+ end
261
+
262
+ def call(_, *arg_values)
263
+ super(@target, *arg_values)
264
+ end
265
+
266
+ def apply(_, arg_values)
267
+ super(@target, arg_values)
268
+ end
269
+
270
+ def bind(_)
271
+ self
272
+ end
273
+ end
274
+
275
+ class FunctionWrapper < Proc
276
+ def initialize(args, &block)
277
+ @args = args
278
+ super(&block)
279
+ end
280
+
281
+ def arity
282
+ @args.length
283
+ end
284
+
285
+ def parameters
286
+ @args.map { |arg| [:required, arg.to_sym] }
287
+ end
288
+ end
289
+
290
+ class Prototype < Object
291
+ def initialize(klass)
292
+ super(nil)
293
+ @klass = klass
294
+ end
295
+
296
+ private
297
+ def method_missing(name, *args, &block)
298
+ meth = @klass.instance_method(name)
299
+ args = meth.parameters.map { |_, name| name && Identifier.new(name) }.compact
300
+ body = ->(*args) { meth.bind(this).call(*args) }
301
+ Function.new(name, args, body)
302
+ rescue NameError
303
+ super
304
+ end
305
+ end
306
+
307
+ class Console
308
+ def log(*args)
309
+ puts(*args)
310
+ end
311
+ end
312
+ end
313
+
314
+ unless defined?(JavaScript::NO_CONFLICT)
315
+ module Kernel
316
+ def javascript(&block)
317
+ JavaScript.eval(&block)
318
+ end
319
+ end
320
+
321
+ class Class
322
+ def prototype
323
+ JavaScript::Prototype.new(self)
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,5 @@
1
+ module JavaScript
2
+ NO_CONFLICT = true
3
+ end
4
+
5
+ require "javascript"
@@ -0,0 +1,3 @@
1
+ module JavaScript
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,276 @@
1
+ require "test_helper"
2
+
3
+ $messages = []
4
+
5
+ module JavaScript
6
+ class Console
7
+ private def puts(message)
8
+ $messages << message
9
+ end
10
+ end
11
+ end
12
+
13
+ class JavaScriptTest < TestCase
14
+ teardown do
15
+ $messages.clear
16
+ end
17
+
18
+ test "undefined" do
19
+ require "javascript"
20
+ assert_nil javascript { undefined }
21
+ end
22
+
23
+ test "this" do
24
+ require "javascript"
25
+
26
+ javascript do
27
+ console.log(this === window);
28
+ console.log(this === global);
29
+ end
30
+
31
+ assert_messages true, true
32
+ end
33
+
34
+ test "Local variables" do
35
+ require "javascript"
36
+
37
+ javascript {
38
+ var a = 1, b = 2;
39
+
40
+ console.log(a);
41
+ console.log(b);
42
+
43
+ a = a + 1;
44
+ b = a + b;
45
+
46
+ console.log(a);
47
+ console.log(b);
48
+ }
49
+
50
+ assert_messages 1, 2, 2, 4
51
+ end
52
+
53
+ test "Global variables" do
54
+ require "javascript"
55
+
56
+ javascript {
57
+ window.a = 1;
58
+ global.b = 2;
59
+
60
+ console.log(a);
61
+ console.log(b);
62
+
63
+ console.log(a === window.a);
64
+ console.log(a === global.a);
65
+
66
+ console.log(b === window.b);
67
+ console.log(b === global.b);
68
+ }
69
+
70
+ assert_messages 1, 2, true, true, true, true
71
+ end
72
+
73
+ test "Global object is not shared between different javascript blocks" do
74
+ require "javascript"
75
+
76
+ javascript { window.a = 1; }
77
+ assert_nil javascript { window.a; }
78
+ end
79
+
80
+ test "Functions" do
81
+ require "javascript"
82
+
83
+ javascript {
84
+ var a = function(msg) {
85
+ console.log("a: " + msg);
86
+ };
87
+
88
+ function b(msg) {
89
+ console.log("b: " + msg);
90
+ }
91
+
92
+ var c = "c";
93
+
94
+ a("hello");
95
+ b("hello");
96
+
97
+ a(c);
98
+ b(c);
99
+ }
100
+
101
+ assert_messages "a: hello", "b: hello", "a: c", "b: c"
102
+ end
103
+
104
+ test "arguments" do
105
+ require "javascript"
106
+
107
+ javascript {
108
+ function inspect() {
109
+ console.log(arguments.length);
110
+ console.log(arguments);
111
+ }
112
+
113
+ inspect("a", "b", "c");
114
+ inspect(1, 2, 3, 4, 5);
115
+ inspect();
116
+ }
117
+
118
+ assert_messages 3, ["a", "b", "c"], 5, [1, 2, 3, 4, 5], 0, []
119
+ end
120
+
121
+ test "Function#call" do
122
+ require "javascript"
123
+
124
+ javascript do
125
+ var thisCheck = function(expected) {
126
+ console.log(this === expected);
127
+ };
128
+
129
+ thisCheck(this);
130
+ thisCheck("abc");
131
+
132
+ thisCheck.call(this, this);
133
+ thisCheck.call(this, "abc");
134
+
135
+ thisCheck.call("abc", "abc");
136
+ thisCheck.call("abc", this);
137
+
138
+ var argsCheck = function() {
139
+ console.log(this == arguments);
140
+ };
141
+
142
+ argsCheck.call([1, 2, 3], 1, 2, 3);
143
+ argsCheck.call([1, 2, 3], 4, 5, 6);
144
+ argsCheck.call([1, 2, 3], [1, 2, 3]);
145
+ end
146
+
147
+ assert_messages true, false, true, false, true, false, true, false, false
148
+ end
149
+
150
+ test "Function#apply" do
151
+ require "javascript"
152
+
153
+ javascript do
154
+ var thisCheck = function(expected) {
155
+ console.log(this === expected);
156
+ };
157
+
158
+ thisCheck(this);
159
+ thisCheck("abc");
160
+
161
+ thisCheck.apply(this, [this]);
162
+ thisCheck.apply(this, ["abc"]);
163
+
164
+ thisCheck.apply("abc", ["abc"]);
165
+ thisCheck.apply("abc", [this]);
166
+
167
+ var argsCheck = function() {
168
+ console.log(this == arguments);
169
+ };
170
+
171
+ argsCheck.apply([1, 2, 3], [1, 2, 3]);
172
+ argsCheck.apply([1, 2, 3], [4, 5, 6]);
173
+ end
174
+
175
+ assert_messages true, false, true, false, true, false, true, false
176
+ end
177
+
178
+ test "Function#bind" do
179
+ require "javascript"
180
+
181
+ javascript do
182
+ var thisCheck = function(expected) {
183
+ console.log(this === expected);
184
+ };
185
+
186
+ thisCheck = thisCheck.bind("abc");
187
+
188
+ thisCheck(this);
189
+ thisCheck("abc");
190
+
191
+ thisCheck.call(this, this);
192
+ thisCheck.call(this, "abc");
193
+ thisCheck.call("abc", "abc");
194
+
195
+ var argsCheck = function() {
196
+ console.log(this == arguments);
197
+ };
198
+
199
+ argsCheck = argsCheck.bind([1, 2, 3]);
200
+
201
+ argsCheck.call("abc", 1, 2, 3);
202
+ argsCheck.apply("abc", [1, 2, 3]);
203
+
204
+ argsCheck.call("abc", 4, 5, 6);
205
+ argsCheck.apply("abc", [4, 5, 6]);
206
+ end
207
+
208
+ assert_messages false, true, false, true, true, true, true, false, false
209
+ end
210
+
211
+ test "Prototype" do
212
+ require "javascript"
213
+
214
+ javascript {
215
+ var join = Array.prototype.join;
216
+
217
+ console.log(join.call(["a", "b", "c"], "+"));
218
+ console.log(join.call([1, 2, 3, 4, 5], "-"));
219
+ }
220
+
221
+ assert_messages "a+b+c", "1-2-3-4-5"
222
+ end
223
+
224
+ test "Callback" do
225
+ require "javascript"
226
+ require "active_support/callbacks"
227
+ require "active_support/core_ext/string/inflections"
228
+
229
+ class Post < Struct.new(:title, :slug)
230
+ include ActiveSupport::Callbacks
231
+
232
+ define_callbacks :create, :destroy
233
+
234
+ set_callback :create, :before, &javascript {
235
+ function(post) {
236
+ console.log("Before");
237
+ post.slug = post.title.parameterize();
238
+ }
239
+ }
240
+
241
+ set_callback :destroy, :after, &javascript {
242
+ function() {
243
+ console.log("After");
244
+ this.slug = undefined;
245
+ }
246
+ }
247
+
248
+ def create
249
+ run_callbacks(:create)
250
+ end
251
+
252
+ def destroy
253
+ run_callbacks(:destroy)
254
+ end
255
+ end
256
+
257
+ post = Post.new("Hello world!")
258
+
259
+ assert_nil post.slug
260
+
261
+ post.create
262
+
263
+ assert_equal "hello-world", post.slug
264
+
265
+ post.destroy
266
+
267
+ assert_nil post.slug
268
+
269
+ assert_messages "Before", "After"
270
+ end
271
+
272
+ private
273
+ def assert_messages(*messages)
274
+ assert_equal messages, $messages
275
+ end
276
+ end
@@ -0,0 +1,23 @@
1
+ require "test_helper"
2
+
3
+ class NoConflictTest < TestCase
4
+ test "Global `javascript` helper is not available in no-conflict mode" do
5
+ require "javascript/no_conflict"
6
+ assert_raises(NoMethodError) { javascript { 1 } }
7
+ end
8
+
9
+ test "Global monkey-patch is not available in no-conflict mode" do
10
+ require "javascript/no_conflict"
11
+ assert_raises(NoMethodError) { JavaScript.eval { Array.prototype } }
12
+ end
13
+
14
+ test "Defining custom helper in no-conflict mode" do
15
+ require "javascript/no_conflict"
16
+
17
+ def metal(&block)
18
+ JavaScript.eval(&block)
19
+ end
20
+
21
+ assert_equal 1, metal { 1 }
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require "bundler/setup"
2
+ require "minitest/autorun"
3
+ require "minitest/pride"
4
+ require "active_support"
5
+ require "active_support/testing/declarative"
6
+ require "active_support/testing/setup_and_teardown"
7
+ require "active_support/testing/isolation"
8
+
9
+ I18n.enforce_available_locales = true
10
+
11
+ class TestCase < Minitest::Test
12
+ extend ActiveSupport::Testing::Declarative
13
+ include ActiveSupport::Testing::SetupAndTeardown
14
+ include ActiveSupport::Testing::Isolation
15
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: javascript
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Godfrey Chan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: binding_of_caller
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.1.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.1.0
83
+ description: With this gem you can finally get closer to the metaland harness the
84
+ raw power of your machine by writing JavaScript code right within your Ruby applications.
85
+ email:
86
+ - godfreykfc@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - javascript.gemspec
98
+ - lib/javascript.rb
99
+ - lib/javascript/no_conflict.rb
100
+ - lib/javascript/version.rb
101
+ - test/javascript_test.rb
102
+ - test/no_conflict_test.rb
103
+ - test/test_helper.rb
104
+ homepage: https://github.com/vanruby/javascript
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 2.1.0
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.2.2
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Seamlessly drop down to the metal with JavaScript
128
+ test_files:
129
+ - test/javascript_test.rb
130
+ - test/no_conflict_test.rb
131
+ - test/test_helper.rb