gusto 1.0.0.beta2
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.
- checksums.yaml +7 -0
- data/bin/gusto +28 -0
- data/lib/HtmlReport.coffee +63 -0
- data/lib/Spec/DSL.coffee +119 -0
- data/lib/Spec/DelayedExpectation.coffee +61 -0
- data/lib/Spec/Matchers.coffee +69 -0
- data/lib/Spec/MethodStub/PossibleCall.coffee +81 -0
- data/lib/Spec/MethodStub.coffee +55 -0
- data/lib/Spec/MockObject.coffee +6 -0
- data/lib/Spec/ObjectDSL.coffee +26 -0
- data/lib/Spec/Report.coffee +23 -0
- data/lib/Spec/Suite.coffee +30 -0
- data/lib/Spec/Test.coffee +21 -0
- data/lib/Spec/Util.coffee +86 -0
- data/lib/Spec.coffee +62 -0
- data/lib/gusto/runner.rb +40 -0
- data/lib/gusto/server.rb +34 -0
- data/lib/gusto/version.rb +3 -0
- data/lib/gusto.rb +162 -0
- data/public/ie.js +5 -0
- data/public/jquery-1.5.2.js +8374 -0
- data/public/jsdiff.js +161 -0
- data/public/stacktrace.js +446 -0
- data/views/index.slim +19 -0
- metadata +180 -0
data/lib/Spec.coffee
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#= require Spec/Util
|
2
|
+
#= require Spec/Test
|
3
|
+
#= require Spec/Suite
|
4
|
+
#= require Spec/Report
|
5
|
+
#= require Spec/ObjectDSL
|
6
|
+
#= require Spec/DSL
|
7
|
+
#= require Spec/Matchers
|
8
|
+
#= require Spec/MethodStub
|
9
|
+
#= require Spec/MethodStub/PossibleCall
|
10
|
+
#= require Spec/DelayedExpectation
|
11
|
+
#= require Spec/MockObject
|
12
|
+
|
13
|
+
# Seaweed Coffeescript spec framework
|
14
|
+
|
15
|
+
window.Spec ||= {}
|
16
|
+
|
17
|
+
class window.Spec.ExpectationError extends Error
|
18
|
+
constructor: (@message) ->
|
19
|
+
|
20
|
+
class window.Spec.PendingError extends Error
|
21
|
+
constructor: (@message) ->
|
22
|
+
@status = Spec.Report.Pending
|
23
|
+
|
24
|
+
Spec.Util.extend window.Spec,
|
25
|
+
environmentExtended: false
|
26
|
+
suites: []
|
27
|
+
root: window
|
28
|
+
|
29
|
+
# Executes a test case
|
30
|
+
describe: (title, definition) ->
|
31
|
+
@extendEnvironment() unless @environmentExtended
|
32
|
+
suite = new Spec.Suite(title, definition)
|
33
|
+
suite.load window
|
34
|
+
@suites.push suite
|
35
|
+
|
36
|
+
# Extends a class or instance with object DSL
|
37
|
+
extend: (objects...) ->
|
38
|
+
for object in objects
|
39
|
+
Spec.Util.extend object, Spec.ObjectDSL
|
40
|
+
Spec.Util.extend object.prototype, Spec.ObjectDSL if object.prototype
|
41
|
+
|
42
|
+
# Extends the environment with test methods
|
43
|
+
extendEnvironment: ->
|
44
|
+
@environmentExtended = true
|
45
|
+
|
46
|
+
Spec.Util.extend(@root,
|
47
|
+
Spec.DSL,
|
48
|
+
Spec.Matchers
|
49
|
+
)
|
50
|
+
|
51
|
+
@extend(
|
52
|
+
Array,
|
53
|
+
Boolean,
|
54
|
+
Date,
|
55
|
+
Function,
|
56
|
+
Number,
|
57
|
+
RegExp,
|
58
|
+
String,
|
59
|
+
Element,
|
60
|
+
jQuery,
|
61
|
+
Spec.MockObject
|
62
|
+
)
|
data/lib/gusto/runner.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
|
4
|
+
module Gusto
|
5
|
+
class Runner
|
6
|
+
def load_gusto
|
7
|
+
require File.join(File.dirname(__FILE__), '..', 'gusto')
|
8
|
+
Gusto.load_configuration
|
9
|
+
Gusto.port = @port
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_gusto_version
|
13
|
+
require File.join(File.dirname(__FILE__), '..', 'gusto', 'version')
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize mode, options={}, parser=nil
|
17
|
+
@port = options[:port] || 4567
|
18
|
+
|
19
|
+
if options[:version]
|
20
|
+
load_gusto_version
|
21
|
+
puts "Gusto Version #{Gusto::VERSION}"
|
22
|
+
else
|
23
|
+
case mode
|
24
|
+
when 's', 'server'
|
25
|
+
puts "Starting gusto server at http://127.0.0.1:#{@port}/"
|
26
|
+
load_gusto
|
27
|
+
Gusto.server
|
28
|
+
when 'c', 'cli'
|
29
|
+
load_gusto
|
30
|
+
Gusto.cli
|
31
|
+
when 'a', 'auto'
|
32
|
+
load_gusto
|
33
|
+
Gusto.autotest
|
34
|
+
else
|
35
|
+
puts parser || "Unknown mode “#{mode}”"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/gusto/server.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'sinatra'
|
4
|
+
require 'sass'
|
5
|
+
require 'slim'
|
6
|
+
require 'coffee-script'
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/../gusto')
|
8
|
+
|
9
|
+
module Gusto
|
10
|
+
class Server < Sinatra::Application
|
11
|
+
# Configure paths
|
12
|
+
set :public_folder, ROOT + '/public'
|
13
|
+
set :views, ROOT + '/views'
|
14
|
+
|
15
|
+
# Configure slim for prettier code formatting
|
16
|
+
Slim::Engine.set_default_options :pretty => true
|
17
|
+
|
18
|
+
# Hide redundant log messages
|
19
|
+
disable :logging
|
20
|
+
|
21
|
+
# Processes request for page index
|
22
|
+
get "/" do
|
23
|
+
# Fetch list of all specification files in specs path
|
24
|
+
@scripts = []
|
25
|
+
Gusto.specs.each do |path|
|
26
|
+
Dir["#{Gusto::PROJECT_ROOT}/#{path}/**/*spec.coffee"].each do |file|
|
27
|
+
@scripts << $1 if file.match Regexp.new("^#{Regexp.escape Gusto::PROJECT_ROOT}\\/#{Regexp.escape path}\\/(.*).coffee$")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
render :slim, :index
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/gusto.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'sprockets'
|
5
|
+
require 'net/http'
|
6
|
+
require 'rack'
|
7
|
+
require 'json'
|
8
|
+
require File.join(File.dirname(__FILE__), 'gusto', 'version')
|
9
|
+
|
10
|
+
module Gusto
|
11
|
+
ROOT = File.expand_path File.join(File.dirname(__FILE__), '..')
|
12
|
+
PROJECT_ROOT = File.expand_path "."
|
13
|
+
|
14
|
+
CONFIG_PATHS = [
|
15
|
+
File.join(PROJECT_ROOT, 'gusto.json'),
|
16
|
+
File.join(PROJECT_ROOT, 'config', 'gusto.json')
|
17
|
+
]
|
18
|
+
|
19
|
+
@configuration = {}
|
20
|
+
|
21
|
+
class << self
|
22
|
+
|
23
|
+
def load_configuration
|
24
|
+
# Set configuration defaults
|
25
|
+
@configuration['port'] = 4567
|
26
|
+
@configuration['lib_paths'] = %w(lib)
|
27
|
+
@configuration['spec_paths'] = %w(spec)
|
28
|
+
|
29
|
+
# Load custom configuration file
|
30
|
+
CONFIG_PATHS.each do |path|
|
31
|
+
if File.exists? path
|
32
|
+
@configuration.merge! JSON.parse(File.read(path))
|
33
|
+
puts "Loaded configuration from “#{path}”"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def port
|
39
|
+
@configuration['port']
|
40
|
+
end
|
41
|
+
|
42
|
+
def port= value
|
43
|
+
@configuration['port'] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
def root_url
|
47
|
+
"http://localhost:#{port}/"
|
48
|
+
end
|
49
|
+
|
50
|
+
def libs
|
51
|
+
@configuration['lib_paths']
|
52
|
+
end
|
53
|
+
|
54
|
+
def specs
|
55
|
+
@configuration['spec_paths']
|
56
|
+
end
|
57
|
+
|
58
|
+
def all_paths
|
59
|
+
libs + specs
|
60
|
+
end
|
61
|
+
|
62
|
+
def server
|
63
|
+
trap_sigint
|
64
|
+
spawn_server
|
65
|
+
Process.waitall
|
66
|
+
end
|
67
|
+
|
68
|
+
def cli
|
69
|
+
trap_sigint
|
70
|
+
spawn_server
|
71
|
+
result = run_suite
|
72
|
+
shut_down(result ? 0 : 1)
|
73
|
+
end
|
74
|
+
|
75
|
+
def autotest
|
76
|
+
trap_sigint
|
77
|
+
spawn_server
|
78
|
+
run_suite
|
79
|
+
watch_for_changes
|
80
|
+
Process.waitall
|
81
|
+
end
|
82
|
+
|
83
|
+
# Prepares a Sprockets::Environment object to serve coffeescript assets
|
84
|
+
def sprockets_environment
|
85
|
+
@environment ||= Sprockets::Environment.new.tap do |environment|
|
86
|
+
environment.append_path File.join(ROOT, 'lib')
|
87
|
+
environment.append_path File.join(ROOT, 'assets')
|
88
|
+
all_paths.each do |path|
|
89
|
+
environment.append_path path
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def start_server
|
95
|
+
app = Rack::Builder.app do
|
96
|
+
map '/assets' do
|
97
|
+
run Gusto::sprockets_environment
|
98
|
+
end
|
99
|
+
|
100
|
+
map '/' do
|
101
|
+
run Gusto::Server
|
102
|
+
end
|
103
|
+
end
|
104
|
+
Rack::Handler.default.run app, :Port => port
|
105
|
+
end
|
106
|
+
|
107
|
+
def spawn_server
|
108
|
+
@server = Process.fork{ $0 = 'gusto server'; start_server }
|
109
|
+
wait_for_server_at(root_url)
|
110
|
+
end
|
111
|
+
|
112
|
+
def run_suite
|
113
|
+
if @browser
|
114
|
+
@browser.navigate.refresh
|
115
|
+
else
|
116
|
+
require 'selenium/webdriver'
|
117
|
+
@browser = Selenium::WebDriver.for :firefox, profile: Selenium::WebDriver::Firefox::Profile.new
|
118
|
+
@browser.get "#{root_url}#terminal"
|
119
|
+
end
|
120
|
+
result = @browser[css: '.results'].text
|
121
|
+
puts result
|
122
|
+
!!result.match('passed, 0 failed')
|
123
|
+
end
|
124
|
+
|
125
|
+
def watch_for_changes
|
126
|
+
require 'listen'
|
127
|
+
|
128
|
+
@listener = Listen.to(PROJECT_ROOT)
|
129
|
+
|
130
|
+
# Match .coffee files in any project paths
|
131
|
+
@listener.filter Regexp.new('^(' + all_paths.map{ |s| Regexp.escape s}.join('|') + ')\/.*\.coffee$')
|
132
|
+
|
133
|
+
@listener.change { run_suite }
|
134
|
+
@listener.start false
|
135
|
+
end
|
136
|
+
|
137
|
+
def shut_down(status=0)
|
138
|
+
@listener.stop if @listener
|
139
|
+
@browser.close if @browser
|
140
|
+
Process.kill 'TERM', @server if @server
|
141
|
+
exit status
|
142
|
+
end
|
143
|
+
|
144
|
+
def trap_sigint
|
145
|
+
trap('SIGINT') do
|
146
|
+
puts "Shutting down..."
|
147
|
+
shut_down
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def wait_for_server_at(url)
|
154
|
+
page = Net::HTTP.get URI.parse(url)
|
155
|
+
rescue Errno::ECONNREFUSED
|
156
|
+
sleep 1
|
157
|
+
retry
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
require File.expand_path(File.dirname(__FILE__) + '/gusto/server')
|