spade 0.1.0 → 0.1.1.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.
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