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