spade 0.1.0 → 0.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.gitignore +0 -11
  2. data/.gitmodules +3 -6
  3. data/Gemfile +10 -0
  4. data/bin/spade +3 -1
  5. data/lib/spade.rb +70 -0
  6. data/lib/spade/bundle.rb +180 -0
  7. data/lib/spade/cli.rb +1 -17
  8. data/lib/spade/cli/base.rb +182 -0
  9. data/lib/spade/console.rb +39 -0
  10. data/lib/spade/context.rb +107 -0
  11. data/lib/spade/evaluator.rb +34 -0
  12. data/lib/spade/exports.rb +70 -0
  13. data/lib/spade/loader.rb +208 -0
  14. data/lib/spade/package/.gitignore +1 -0
  15. data/lib/spade/package/Gemfile +15 -0
  16. data/lib/spade/package/lib/spade.js +1283 -0
  17. data/lib/spade/package/lib/wrapper.js +15 -0
  18. data/lib/spade/package/package.json +17 -0
  19. data/lib/spade/package/spec/javascript/async-test.js +123 -0
  20. data/lib/spade/package/spec/javascript/compiler/javascript.js +13 -0
  21. data/lib/spade/package/spec/javascript/compiler/ruby.js +14 -0
  22. data/lib/spade/package/spec/javascript/loader-test.js +64 -0
  23. data/lib/spade/package/spec/javascript/normalize-test.js +73 -0
  24. data/lib/spade/package/spec/javascript/packages-test.js +50 -0
  25. data/lib/spade/package/spec/javascript/relative-require-test.js +72 -0
  26. data/lib/spade/package/spec/javascript/require-test.js +117 -0
  27. data/lib/spade/package/spec/javascript/sandbox/creation.js +44 -0
  28. data/lib/spade/package/spec/javascript/sandbox/evaluate.js +37 -0
  29. data/lib/spade/package/spec/javascript/sandbox/format.js +79 -0
  30. data/lib/spade/package/spec/javascript/sandbox/misc.js +58 -0
  31. data/lib/spade/package/spec/javascript/sandbox/preprocessor.js +81 -0
  32. data/lib/spade/package/spec/javascript/sandbox/require.js +48 -0
  33. data/lib/spade/package/spec/javascript/sandbox/run-command.js +21 -0
  34. data/lib/spade/package/spec/javascript/spade/externs.js +14 -0
  35. data/lib/spade/package/spec/javascript/spade/load-factory.js +15 -0
  36. data/lib/spade/package/spec/javascript/spade/misc.js +23 -0
  37. data/lib/spade/package/spec/javascript/spade/ready.js +12 -0
  38. data/lib/spade/package/spec/javascript/spade/register.js +13 -0
  39. data/lib/spade/package/spec/javascript_spec.rb +7 -0
  40. data/lib/spade/package/spec/spec_helper.rb +3 -0
  41. data/lib/spade/package/spec/support/core_test.rb +67 -0
  42. data/lib/spade/reactor.rb +159 -0
  43. data/lib/spade/server.rb +66 -0
  44. data/lib/spade/shell.rb +85 -0
  45. data/lib/spade/version.rb +1 -1
  46. data/spade.gemspec +15 -4
  47. data/spec/cli/update_spec.rb +65 -0
  48. data/spec/spec_helper.rb +22 -0
  49. data/spec/support/cli.rb +103 -0
  50. data/spec/support/matchers.rb +12 -0
  51. data/spec/support/path.rb +66 -0
  52. metadata +146 -78
  53. data/.rspec +0 -1
  54. data/Buildfile +0 -18
  55. data/README.md +0 -152
  56. data/Rakefile +0 -9
  57. data/examples/format-app/lib/hello.coffee +0 -1
  58. data/examples/format-app/lib/main.js +0 -6
  59. data/examples/format-app/package.json +0 -10
  60. data/examples/format-app/resources/README.txt +0 -1
  61. data/examples/format-app/resources/config.json +0 -3
  62. data/examples/path-test/lib/hello.js +0 -1
  63. data/examples/path-test/lib/main.js +0 -1
  64. data/examples/path-test/package.json +0 -5
  65. data/examples/sc-app/index.html +0 -13
  66. data/examples/sc-app/lib/main.js +0 -24
  67. data/examples/sc-app/package.json +0 -8
  68. data/examples/single-file.js +0 -22
  69. data/examples/todos/index.html +0 -11
  70. data/examples/todos/lib/main.js +0 -11
  71. data/examples/todos/lib/todos.js +0 -93
  72. data/examples/todos/package.json +0 -10
  73. data/examples/todos/resources/stylesheets/todos.css +0 -162
  74. data/examples/todos/resources/templates/todos.handlebars +0 -31
  75. data/examples/web-app/README.md +0 -83
  76. data/examples/web-app/index.html +0 -12
  77. data/examples/web-app/lib/main.js +0 -3
  78. data/examples/web-app/package.json +0 -6
  79. data/examples/web-app/tests.html +0 -12
  80. data/examples/web-app/tests/ct-example-test.js +0 -39
  81. data/examples/web-app/tests/qunit-test.js +0 -23
@@ -0,0 +1,21 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+
7
+ var Ct = require('core-test/sync'),
8
+ Spade = require('spade').Spade,
9
+ Sandbox = require('spade').Sandbox;
10
+
11
+ Ct.module('spade: Sandbox runCommand');
12
+
13
+ // TODO: Add the next 3 tests when adding Ruby and node.js support
14
+ Ct.test('success');
15
+
16
+ Ct.test('failure');
17
+
18
+ Ct.test('not supported');
19
+
20
+ // Not really sure how to test this, other than a bunch of stubbing
21
+ Ct.test('browser');
@@ -0,0 +1,14 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+ //
7
+
8
+ var Ct = require('core-test/sync');
9
+
10
+ Ct.module('spade: Spade externs');
11
+
12
+ Ct.test('works');
13
+
14
+
@@ -0,0 +1,15 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+ //
7
+
8
+ var Ct = require('core-test/sync');
9
+
10
+ Ct.module('spade: Spade loadFactory');
11
+
12
+ Ct.test('works');
13
+
14
+
15
+
@@ -0,0 +1,23 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+ //
7
+
8
+ var Ct = require('core-test/sync');
9
+
10
+ Ct.module('spade: Spade miscellaneous');
11
+
12
+ Ct.test('globalize works');
13
+
14
+ Ct.test('noConflict works');
15
+
16
+ Ct.test('sandbox works');
17
+
18
+ Ct.test('factoryExists works');
19
+
20
+ Ct.test('package works');
21
+
22
+
23
+
@@ -0,0 +1,12 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+ //
7
+
8
+ var Ct = require('core-test/sync');
9
+
10
+ Ct.module('spade: Spade ready');
11
+
12
+ Ct.test('works');
@@ -0,0 +1,13 @@
1
+ // ==========================================================================
2
+ // Project: Spade - CommonJS Runtime
3
+ // Copyright: ©2011 Strobe Inc. All rights reserved.
4
+ // License: Licened under MIT license (see __preamble__.js)
5
+ // ==========================================================================
6
+ //
7
+
8
+ var Ct = require('core-test/sync');
9
+
10
+ Ct.module('spade: Spade miscellaneous');
11
+
12
+ Ct.test('register works');
13
+
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe "Javascript Tests" do
4
+ Dir["#{File.dirname(__FILE__)}/javascript/**/*.js"].each do |path|
5
+ run_core_tests(path)
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ Bundler.require :default, :development
2
+
3
+ require 'support/core_test'
@@ -0,0 +1,67 @@
1
+ require 'spade/context'
2
+
3
+ module Spade
4
+ def self.jspath
5
+ File.expand_path("../../../lib/spade.js", __FILE__)
6
+ end
7
+ end
8
+
9
+ RSpec::Matchers.define :be_ct_success do
10
+ match do |actual|
11
+ actual.first == 'passed'
12
+ end
13
+
14
+ failure_message_for_should do |actual|
15
+ actual.last
16
+ end
17
+
18
+ failure_message_for_should_not do |actual|
19
+ "expected not to be a success"
20
+ end
21
+
22
+ description do
23
+ "be a success"
24
+ end
25
+ end
26
+
27
+ module RSpecCoreTest
28
+ def run_core_tests(path, &block)
29
+ describe "#{path}" do
30
+ rootdir = File.expand_path(File.join(__FILE__, '/../../../'));
31
+ context = Spade::MainContext.new(:rootdir => rootdir) do |ctx|
32
+ ctx['checkRSpec'] = lambda do |status, test_info, message|
33
+ it "#{test_info.module.name}: #{test_info.name}" do
34
+ if status == 'warnings' && message == "Not Yet Implemented"
35
+ pending
36
+ else
37
+ [status.to_s, message.to_s].should be_ct_success
38
+ end
39
+ end
40
+ end
41
+
42
+ ctx.eval <<END
43
+ var Ct;
44
+ try {
45
+ Ct = require('core-test');
46
+ } catch (e) { }
47
+
48
+ if (Ct) {
49
+ RubyLogger = require('core-test/utils').extend(Ct.DefaultLogger, {
50
+ add: function(status, testInfo, message){
51
+ checkRSpec(status, testInfo, message);
52
+ }
53
+ });
54
+ Ct.defaultLogger = new RubyLogger('ruby');
55
+
56
+ require('file:#{path}');
57
+
58
+ Ct.run();
59
+ } else {
60
+ console.log("CoreTest is not installed. Use `spade install core-test`.");
61
+ }
62
+ END
63
+ end
64
+ end
65
+ end
66
+ end
67
+ RSpec::Core::ExampleGroup.extend(RSpecCoreTest)
@@ -0,0 +1,159 @@
1
+ # ==========================================================================
2
+ # Project: Spade - CommonJS Runtime
3
+ # Copyright: ©2010 Strobe Inc. All rights reserved.
4
+ # License: Licened under MIT license (see LICENSE)
5
+ # ==========================================================================
6
+
7
+ require 'eventmachine'
8
+
9
+ module Spade
10
+
11
+ # The reactor exposes some API
12
+ class Reactor
13
+
14
+ attr_reader :timers, :running, :holds, :stopped
15
+
16
+ def initialize(ctx)
17
+ @timers = []
18
+ @running = false
19
+ @stopped = false
20
+ @holds = 0
21
+ end
22
+
23
+ # Starts the event loop
24
+ def start
25
+ return if @running
26
+
27
+ @running = true
28
+ add_hold # release when finish is called
29
+
30
+ EventMachine.run do
31
+ @running = true
32
+ @timers.each { |t| t.start unless t.running }
33
+
34
+ yield if block_given?
35
+
36
+ @stopped = true
37
+ release_hold
38
+ end
39
+
40
+ end
41
+
42
+ def exit(status=0)
43
+ stop_loop
44
+ Kernel.exit(status)
45
+ end
46
+
47
+ def next_tick(&block)
48
+ if @running
49
+ add_hold
50
+ EventMachine.next_tick do
51
+ yield
52
+ release_hold
53
+ end
54
+ else
55
+ add_timer(0) { yield }
56
+ end
57
+ end
58
+
59
+ ######################################################
60
+ ## Holds
61
+ ##
62
+ ## Prevents the loop from exiting
63
+
64
+ def add_hold
65
+ @holds = @holds + 1
66
+ end
67
+
68
+ def release_hold
69
+ @holds = @holds - 1
70
+ stop_loop if @stopped && @holds <= 0
71
+ end
72
+
73
+ def stop_loop
74
+ @running = false
75
+ EventMachine.stop_event_loop
76
+ end
77
+
78
+
79
+ ######################################################
80
+ ## Timers
81
+ ##
82
+
83
+ def add_timer(interval, periodic = false, &block)
84
+ add_hold
85
+ Timer.new(self).tap do |timer|
86
+ timer.periodic = periodic
87
+ timer.interval = interval
88
+ timer.callback = block
89
+ @timers << timer
90
+ timer.start if @running
91
+ end
92
+ end
93
+
94
+ def remove_timer(timer)
95
+ 'remove_timer'
96
+ release_hold if @timers.delete(timer)
97
+ end
98
+
99
+ def set_timeout(callback, interval)
100
+ add_timer interval, false do
101
+ callback.methodcall(self)
102
+ end
103
+ end
104
+
105
+ def set_interval(callback, interval)
106
+ add_timer interval, true do
107
+ callback.methodcall(self)
108
+ end
109
+ end
110
+
111
+ def clear_timeout(timer)
112
+ timer.cancel
113
+ end
114
+
115
+ def clear_interval(timer)
116
+ timer.cancel
117
+ end
118
+
119
+ class Timer
120
+
121
+ attr_accessor :periodic, :interval, :callback
122
+ attr_reader :running
123
+
124
+ def initialize(reactor)
125
+ @interval = 0
126
+ @periodic = false
127
+ @callback = nil
128
+ @reactor = reactor
129
+ @running = false
130
+ end
131
+
132
+ def start
133
+ @running = true
134
+ if @periodic
135
+ @timer = EventMachine.add_periodic_timer(@interval.to_f / 1000) do
136
+ @callback.call
137
+ end
138
+ else
139
+ @timer = EventMachine.add_timer(@interval.to_f / 1000) do
140
+ @callback.call
141
+ @timer = nil
142
+ @reactor.remove_timer(self)
143
+ end
144
+ end
145
+ end
146
+
147
+ def cancel
148
+ EventMachine.cancel_timer(@timer) if @timer
149
+ @timer = nil
150
+ @reactor.remove_timer(self)
151
+ end
152
+ end
153
+
154
+
155
+
156
+ end
157
+
158
+ end
159
+
@@ -0,0 +1,66 @@
1
+ require 'rack'
2
+ require 'rack/static'
3
+ require 'tempfile'
4
+ require 'child_labor'
5
+
6
+ module Spade
7
+ module Server
8
+ def self.run(working, port)
9
+ rootdir = Spade.discover_root(working)
10
+ static = Rack::Static.new(nil, :urls => ['/'], :root => rootdir)
11
+ static = CommandRunner.new(static)
12
+ static = Rack::ShowStatus.new(Rack::ShowExceptions.new(Rack::Chunked.new(Rack::ContentLength.new(static))))
13
+
14
+ Rack::Handler::WEBrick.run static, :Port => port.to_i
15
+ end
16
+
17
+ def self.shutdown
18
+ Rack::Handler::WEBrick.shutdown
19
+ end
20
+
21
+ class CommandRunner
22
+ def initialize(app)
23
+ @app = app
24
+ end
25
+
26
+ #FIXME: This is not very safe, we should have some restrictions
27
+ def call(env)
28
+ if env['PATH_INFO'] == '/_spade/command'
29
+ rack_input = env["rack.input"].read
30
+ params = Rack::Utils.parse_query(rack_input, "&")
31
+
32
+ command_path = params['command']
33
+ return [500, {}, "command required"] if command_path.nil? || command_path.empty?
34
+
35
+ if ((root = params['pkgRoot']) && !root.nil?)
36
+ command_path = File.expand_path(File.join(command_path), root)
37
+ end
38
+
39
+ tempfile = Tempfile.new('spade-server')
40
+ tempfile.write(params['code'])
41
+ tempfile.close
42
+
43
+
44
+ puts "Running: #{command_path}"
45
+
46
+ output, error = nil
47
+ process = ChildLabor.subprocess("#{command_path} < #{tempfile.path}") do |p|
48
+ output = p.read
49
+ error = p.read_stderr
50
+ end
51
+
52
+ tempfile.delete
53
+
54
+ if process.exit_status == 0
55
+ [200, {}, output]
56
+ else
57
+ [500, {}, error]
58
+ end
59
+ else
60
+ env['PATH_INFO'] == '/index.html' if env['PATH_INFO'] == '/'
61
+ @app.call(env)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,85 @@
1
+ # ==========================================================================
2
+ # Project: Spade - CommonJS Runtime
3
+ # Copyright: ©2010 Strobe Inc. All rights reserved.
4
+ # License: Licened under MIT license (see LICENSE)
5
+ # ==========================================================================
6
+
7
+ require 'readline'
8
+ require 'fileutils'
9
+
10
+ # Global object used for the shell.
11
+ module Spade
12
+ class Shell
13
+
14
+ METHODS = [:to_s, :exit, :quit, :help, :evalrb, :inspectjs]
15
+
16
+ def initialize
17
+ @history_path = File.expand_path("~/.spadehistory")
18
+ load_history
19
+ end
20
+
21
+ def inject(ctx)
22
+ @ctx = ctx
23
+ METHODS.each{|meth| @ctx[meth.to_s] = method(meth) }
24
+ true
25
+ end
26
+
27
+ def to_s
28
+ "[object Shell]"
29
+ end
30
+
31
+ def exit(status=0)
32
+ save_history
33
+ ensure
34
+ @ctx.reactor.exit(status)
35
+ end
36
+
37
+ alias_method :quit, :exit
38
+
39
+ def help(*args)
40
+ <<-HELP
41
+ print(msg)
42
+ print msg to STDOUT
43
+
44
+ exit(status = 0)
45
+ exit the shell
46
+ also: quit()
47
+
48
+ evalrb(source)
49
+ evaluate some ruby source
50
+ HELP
51
+ end
52
+
53
+ def evalrb(str)
54
+ Kernel.eval str, binding
55
+ end
56
+
57
+ def inspectjs(obj)
58
+ # check for exact class match so we don't match things like arrays
59
+ spacer = (obj.class == V8::Object) ? 2 : nil
60
+ # the self[] uses the JS version of JSON
61
+ json = @ctx['JSON'].stringify(obj, nil, spacer)
62
+ # Some things can't be converted into json
63
+ json || obj.inspect
64
+ end
65
+
66
+ private
67
+
68
+ def load_history
69
+ return unless File.exist?(@history_path)
70
+ File.readlines(@history_path).each{|l| Readline::HISTORY << l.chomp }
71
+ end
72
+
73
+ def save_history
74
+ FileUtils.mkdir_p(File.dirname(@history_path))
75
+ File.open(@history_path, 'w') do |f|
76
+ Readline::HISTORY.to_a.last(100).each do |l|
77
+ l.chomp!
78
+ next if l.empty?
79
+ next if l =~ /^(exit|quit)\(/
80
+ f.puts l
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end