newjs 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ body, div, p, h1, h2, h3, ul, ol, span, a, table, td, form, img, li {
2
+ font-family: sans-serif;
3
+ }
4
+
5
+ body {
6
+ font-size:0.8em;
7
+ }
8
+
9
+ #log {
10
+ padding-bottom: 1em;
11
+ border-bottom: 2px solid #000;
12
+ margin-bottom: 2em;
13
+ }
14
+
15
+ .logsummary {
16
+ margin-top: 1em;
17
+ margin-bottom: 1em;
18
+ padding: 1ex;
19
+ border: 1px solid #000;
20
+ font-weight: bold;
21
+ }
22
+
23
+ .logtable {
24
+ width:100%;
25
+ border-collapse: collapse;
26
+ border: 1px dotted #666;
27
+ }
28
+
29
+ .logtable td, .logtable th {
30
+ text-align: left;
31
+ padding: 3px 8px;
32
+ border: 1px dotted #666;
33
+ }
34
+
35
+ .logtable .passed {
36
+ background-color: #cfc;
37
+ }
38
+
39
+ .logtable .failed, .logtable .error {
40
+ background-color: #fcc;
41
+ }
42
+
43
+ .logtable td div.action_buttons {
44
+ display: inline;
45
+ }
46
+
47
+ .logtable td div.action_buttons input {
48
+ margin: 0 5px;
49
+ font-size: 10px;
50
+ }
@@ -0,0 +1,10 @@
1
+ javascript_unittest plugin
2
+
3
+ This plugin was installed by newjs' javascript_test generator for Rails 2.0+ applications.
4
+
5
+ Its purpose is to provide the 'rake test:javascripts' test runner.
6
+
7
+ See http://newjs.rubyforge.org for more details.
8
+
9
+ Author:
10
+ Dr Nic Williams, drnicwilliams@gmail.com
@@ -0,0 +1,382 @@
1
+ require 'rake/tasklib'
2
+ require 'thread'
3
+ require 'webrick'
4
+ require 'fileutils'
5
+ include FileUtils
6
+
7
+ class Browser
8
+ def supported?; true; end
9
+ def setup ; end
10
+ def open(url) ; end
11
+ def teardown ; end
12
+
13
+ def host
14
+ require 'rbconfig'
15
+ Config::CONFIG['host']
16
+ end
17
+
18
+ def macos?
19
+ host.include?('darwin')
20
+ end
21
+
22
+ def windows?
23
+ host.include?('mswin')
24
+ end
25
+
26
+ def linux?
27
+ host.include?('linux')
28
+ end
29
+
30
+ def applescript(script)
31
+ raise "Can't run AppleScript on #{host}" unless macos?
32
+ system "osascript -e '#{script}' 2>&1 >/dev/null"
33
+ end
34
+ end
35
+
36
+ class FirefoxBrowser < Browser
37
+ def initialize(path=File.join(ENV['ProgramFiles'] || 'c:\Program Files', '\Mozilla Firefox\firefox.exe'))
38
+ @path = path
39
+ end
40
+
41
+ def visit(url)
42
+ system("open -a Firefox '#{url}'") if macos?
43
+ system("#{@path} #{url}") if windows?
44
+ system("firefox #{url}") if linux?
45
+ end
46
+
47
+ def to_s
48
+ "Firefox"
49
+ end
50
+ end
51
+
52
+ class SafariBrowser < Browser
53
+ def supported?
54
+ macos?
55
+ end
56
+
57
+ def setup
58
+ applescript('tell application "Safari" to make new document')
59
+ end
60
+
61
+ def visit(url)
62
+ applescript('tell application "Safari" to set URL of front document to "' + url + '"')
63
+ end
64
+
65
+ def teardown
66
+ #applescript('tell application "Safari" to close front document')
67
+ end
68
+
69
+ def to_s
70
+ "Safari"
71
+ end
72
+ end
73
+
74
+ class IEBrowser < Browser
75
+ def setup
76
+ require 'win32ole' if windows?
77
+ end
78
+
79
+ def supported?
80
+ windows?
81
+ end
82
+
83
+ def visit(url)
84
+ if windows?
85
+ ie = WIN32OLE.new('InternetExplorer.Application')
86
+ ie.visible = true
87
+ ie.Navigate(url)
88
+ while ie.ReadyState != 4 do
89
+ sleep(1)
90
+ end
91
+ end
92
+ end
93
+
94
+ def to_s
95
+ "Internet Explorer"
96
+ end
97
+ end
98
+
99
+ class KonquerorBrowser < Browser
100
+ @@configDir = File.join((ENV['HOME'] || ''), '.kde', 'share', 'config')
101
+ @@globalConfig = File.join(@@configDir, 'kdeglobals')
102
+ @@konquerorConfig = File.join(@@configDir, 'konquerorrc')
103
+
104
+ def supported?
105
+ linux?
106
+ end
107
+
108
+ # Forces KDE's default browser to be Konqueror during the tests, and forces
109
+ # Konqueror to open external URL requests in new tabs instead of a new
110
+ # window.
111
+ def setup
112
+ cd @@configDir, :verbose => false do
113
+ copy @@globalConfig, "#{@@globalConfig}.bak", :preserve => true, :verbose => false
114
+ copy @@konquerorConfig, "#{@@konquerorConfig}.bak", :preserve => true, :verbose => false
115
+ # Too lazy to write it in Ruby... Is sed dependency so bad?
116
+ system "sed -ri /^BrowserApplication=/d '#{@@globalConfig}'"
117
+ system "sed -ri /^KonquerorTabforExternalURL=/s:false:true: '#{@@konquerorConfig}'"
118
+ end
119
+ end
120
+
121
+ def teardown
122
+ cd @@configDir, :verbose => false do
123
+ copy "#{@@globalConfig}.bak", @@globalConfig, :preserve => true, :verbose => false
124
+ copy "#{@@konquerorConfig}.bak", @@konquerorConfig, :preserve => true, :verbose => false
125
+ end
126
+ end
127
+
128
+ def visit(url)
129
+ system("kfmclient openURL #{url}")
130
+ end
131
+
132
+ def to_s
133
+ "Konqueror"
134
+ end
135
+ end
136
+
137
+ class OperaBrowser < Browser
138
+ def initialize(path='c:\Program Files\Opera\Opera.exe')
139
+ @path = path
140
+ end
141
+
142
+ def setup
143
+ if windows?
144
+ puts %{
145
+ MAJOR ANNOYANCE on Windows.
146
+ You have to shut down Opera manually after each test
147
+ for the script to proceed.
148
+ Any suggestions on fixing this is GREATLY appreciated!
149
+ Thank you for your understanding.
150
+ }
151
+ end
152
+ end
153
+
154
+ def visit(url)
155
+ applescript('tell application "Opera" to GetURL "' + url + '"') if macos?
156
+ system("#{@path} #{url}") if windows?
157
+ system("opera #{url}") if linux?
158
+ end
159
+
160
+ def to_s
161
+ "Opera"
162
+ end
163
+ end
164
+
165
+ # shut up, webrick :-)
166
+ class ::WEBrick::HTTPServer
167
+ def access_log(config, req, res)
168
+ # nop
169
+ end
170
+ end
171
+
172
+ class ::WEBrick::BasicLog
173
+ def log(level, data)
174
+ # nop
175
+ end
176
+ end
177
+
178
+ class WEBrick::HTTPResponse
179
+ alias send send_response
180
+ def send_response(socket)
181
+ send(socket) unless fail_silently?
182
+ end
183
+
184
+ def fail_silently?
185
+ @fail_silently
186
+ end
187
+
188
+ def fail_silently
189
+ @fail_silently = true
190
+ end
191
+ end
192
+
193
+ class WEBrick::HTTPRequest
194
+ def to_json
195
+ headers = []
196
+ each { |k, v| headers.push "#{k.inspect}: #{v.inspect}" }
197
+ headers = "{" << headers.join(', ') << "}"
198
+ %({ "headers": #{headers}, "body": #{body.inspect}, "method": #{request_method.inspect} })
199
+ end
200
+ end
201
+
202
+ class WEBrick::HTTPServlet::AbstractServlet
203
+ def prevent_caching(res)
204
+ res['ETag'] = nil
205
+ res['Last-Modified'] = Time.now + 100**4
206
+ res['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
207
+ res['Pragma'] = 'no-cache'
208
+ res['Expires'] = Time.now - 100**4
209
+ end
210
+ end
211
+
212
+ class BasicServlet < WEBrick::HTTPServlet::AbstractServlet
213
+ def do_GET(req, res)
214
+ prevent_caching(res)
215
+ res['Content-Type'] = "text/plain"
216
+
217
+ req.query.each do |k, v|
218
+ res[k] = v unless k == 'responseBody'
219
+ end
220
+ res.body = req.query["responseBody"]
221
+
222
+ raise WEBrick::HTTPStatus::OK
223
+ end
224
+
225
+ def do_POST(req, res)
226
+ do_GET(req, res)
227
+ end
228
+ end
229
+
230
+ class SlowServlet < BasicServlet
231
+ def do_GET(req, res)
232
+ sleep(2)
233
+ super
234
+ end
235
+ end
236
+
237
+ class DownServlet < BasicServlet
238
+ def do_GET(req, res)
239
+ res.fail_silently
240
+ end
241
+ end
242
+
243
+ class InspectionServlet < BasicServlet
244
+ def do_GET(req, res)
245
+ prevent_caching(res)
246
+ res['Content-Type'] = "application/json"
247
+ res.body = req.to_json
248
+ raise WEBrick::HTTPStatus::OK
249
+ end
250
+ end
251
+
252
+ class NonCachingFileHandler < WEBrick::HTTPServlet::FileHandler
253
+ def do_GET(req, res)
254
+ super
255
+ set_default_content_type(res, req.path)
256
+ prevent_caching(res)
257
+ end
258
+
259
+ def set_default_content_type(res, path)
260
+ res['Content-Type'] = case path
261
+ when /\.js$/ then 'text/javascript'
262
+ when /\.html$/ then 'text/html'
263
+ when /\.css$/ then 'text/css'
264
+ else 'text/plain'
265
+ end
266
+ end
267
+ end
268
+
269
+ class JavaScriptTestTask < ::Rake::TaskLib
270
+
271
+ def initialize(name=:test, port=4711)
272
+ @name = name
273
+ @tests = []
274
+ @browsers = []
275
+ @port = port
276
+ @queue = Queue.new
277
+
278
+ @server = WEBrick::HTTPServer.new(:Port => @port) # TODO: make port configurable
279
+ @server.mount_proc("/results") do |req, res|
280
+ @queue.push({
281
+ :tests => req.query['tests'].to_i,
282
+ :assertions => req.query['assertions'].to_i,
283
+ :failures => req.query['failures'].to_i,
284
+ :errors => req.query['errors'].to_i
285
+ })
286
+ res.body = "OK"
287
+ end
288
+ @server.mount("/response", BasicServlet)
289
+ @server.mount("/slow", SlowServlet)
290
+ @server.mount("/down", DownServlet)
291
+ @server.mount("/inspect", InspectionServlet)
292
+ yield self if block_given?
293
+ define
294
+ end
295
+
296
+ def define
297
+ task @name do
298
+ trap("INT") { @server.shutdown }
299
+ t = Thread.new { @server.start }
300
+
301
+ # run all combinations of browsers and tests
302
+ @browsers.each do |browser|
303
+ if browser.supported?
304
+ t0 = Time.now
305
+ results = {:tests => 0, :assertions => 0, :failures => 0, :errors => 0}
306
+ errors = []
307
+ failures = []
308
+ browser.setup
309
+ puts "\nStarted tests in #{browser}"
310
+ @tests.each do |test|
311
+ params = "resultsURL=http://localhost:#{@port}/results&t=" + ("%.6f" % Time.now.to_f)
312
+ if test.is_a?(Hash)
313
+ params << "&tests=#{test[:testcases]}" if test[:testcases]
314
+ test = test[:url]
315
+ end
316
+ browser.visit("http://localhost:#{@port}#{test}?#{params}")
317
+
318
+ result = @queue.pop
319
+ result.each { |k, v| results[k] += v }
320
+ value = "."
321
+
322
+ if result[:failures] > 0
323
+ value = "F"
324
+ failures.push(test)
325
+ end
326
+
327
+ if result[:errors] > 0
328
+ value = "E"
329
+ errors.push(test)
330
+ end
331
+
332
+ print value
333
+ end
334
+
335
+ puts "\nFinished in #{(Time.now - t0).round.to_s} seconds."
336
+ puts " Failures: #{failures.join(', ')}" unless failures.empty?
337
+ puts " Errors: #{errors.join(', ')}" unless errors.empty?
338
+ puts "#{results[:tests]} tests, #{results[:assertions]} assertions, #{results[:failures]} failures, #{results[:errors]} errors"
339
+ browser.teardown
340
+ else
341
+ puts "\nSkipping #{browser}, not supported on this OS"
342
+ end
343
+ end
344
+
345
+ @server.shutdown
346
+ t.join
347
+ end
348
+ end
349
+
350
+ def mount(path, dir=nil)
351
+ dir = Dir.pwd + path unless dir
352
+
353
+ # don't cache anything in our tests
354
+ @server.mount(path, NonCachingFileHandler, dir)
355
+ end
356
+
357
+ # test should be specified as a url or as a hash of the form
358
+ # {:url => "url", :testcases => "testFoo,testBar"}
359
+ def run(test)
360
+ @tests<<test
361
+ end
362
+
363
+ def browser(browser)
364
+ browser =
365
+ case(browser)
366
+ when :firefox
367
+ FirefoxBrowser.new
368
+ when :safari
369
+ SafariBrowser.new
370
+ when :ie
371
+ IEBrowser.new
372
+ when :konqueror
373
+ KonquerorBrowser.new
374
+ when :opera
375
+ OperaBrowser.new
376
+ else
377
+ browser
378
+ end
379
+
380
+ @browsers<<browser
381
+ end
382
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../lib/jstest'
2
+
3
+ namespace :test do
4
+ desc "Runs all the JavaScript unit tests and collects the results"
5
+ JavaScriptTestTask.new(:javascripts, 4711) do |t|
6
+ testcases = ENV['TESTCASES']
7
+ tests_to_run = ENV['TESTS'] && ENV['TESTS'].split(',')
8
+ browsers_to_test = ENV['BROWSERS'] && ENV['BROWSERS'].split(',')
9
+
10
+ t.mount("/dist")
11
+ t.mount("/src")
12
+ t.mount("/test")
13
+
14
+ Dir["test/javascript/*_test.html"].sort.each do |test_file|
15
+ tests = testcases ? { :url => "/#{test_file}", :testcases => testcases } : "/#{test_file}"
16
+ test_filename = test_file[/.*\/(.+?)\.html/, 1]
17
+ t.run(tests) unless tests_to_run && !tests_to_run.include?(test_filename)
18
+ end
19
+
20
+ %w( safari firefox ie konqueror opera ).each do |browser|
21
+ t.browser(browser.to_sym) unless browsers_to_test && !browsers_to_test.include?(browser)
22
+ end
23
+ end
24
+ end