newjs 1.5.0 → 1.5.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.
- data/History.txt +4 -0
- data/Manifest.txt +18 -0
- data/app_generators/newjs_iphone/USAGE +8 -0
- data/app_generators/newjs_iphone/newjs_iphone_generator.rb +111 -0
- data/app_generators/newjs_iphone/templates/Html/Rakefile.erb +69 -0
- data/app_generators/newjs_iphone/templates/Html/config/javascript_test_autotest.yml.sample +15 -0
- data/app_generators/newjs_iphone/templates/Html/lib/jstest.rb +382 -0
- data/app_generators/newjs_iphone/templates/Html/lib/protodoc.rb +36 -0
- data/app_generators/newjs_iphone/templates/Html/script/js_autotest +1 -0
- data/app_generators/newjs_iphone/templates/Html/script/rstakeout +97 -0
- data/app_generators/newjs_iphone/templates/Html/script/win_script.cmd +1 -0
- data/app_generators/newjs_iphone/templates/Html/src/library.js.erb +1 -0
- data/app_generators/newjs_iphone/templates/Html/tasks/javascript_test_autotest_tasks.rake +46 -0
- data/app_generators/newjs_iphone/templates/Html/test/assets/jsunittest.js +976 -0
- data/app_generators/newjs_iphone/templates/Html/test/assets/prototype.js +4236 -0
- data/app_generators/newjs_iphone/templates/Html/test/assets/unittest.css +50 -0
- data/app_generators/newjs_iphone/templates/Html/test/assets/unittest.js +556 -0
- data/bin/newjs_iphone +17 -0
- data/lib/newjs/version.rb +1 -1
- data/tasks/jsunittest/update.rake +18 -0
- data/website/index.html +1 -1
- metadata +21 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -24,7 +24,23 @@ app_generators/newjs/templates/test/assets/jsunittest.js
|
|
24
24
|
app_generators/newjs/templates/test/assets/prototype.js
|
25
25
|
app_generators/newjs/templates/test/assets/unittest.css
|
26
26
|
app_generators/newjs/templates/test/assets/unittest.js
|
27
|
+
app_generators/newjs_iphone/USAGE
|
28
|
+
app_generators/newjs_iphone/newjs_iphone_generator.rb
|
29
|
+
app_generators/newjs_iphone/templates/Html/Rakefile.erb
|
30
|
+
app_generators/newjs_iphone/templates/Html/config/javascript_test_autotest.yml.sample
|
31
|
+
app_generators/newjs_iphone/templates/Html/lib/jstest.rb
|
32
|
+
app_generators/newjs_iphone/templates/Html/lib/protodoc.rb
|
33
|
+
app_generators/newjs_iphone/templates/Html/script/js_autotest
|
34
|
+
app_generators/newjs_iphone/templates/Html/script/rstakeout
|
35
|
+
app_generators/newjs_iphone/templates/Html/script/win_script.cmd
|
36
|
+
app_generators/newjs_iphone/templates/Html/src/library.js.erb
|
37
|
+
app_generators/newjs_iphone/templates/Html/tasks/javascript_test_autotest_tasks.rake
|
38
|
+
app_generators/newjs_iphone/templates/Html/test/assets/jsunittest.js
|
39
|
+
app_generators/newjs_iphone/templates/Html/test/assets/prototype.js
|
40
|
+
app_generators/newjs_iphone/templates/Html/test/assets/unittest.css
|
41
|
+
app_generators/newjs_iphone/templates/Html/test/assets/unittest.js
|
27
42
|
bin/newjs
|
43
|
+
bin/newjs_iphone
|
28
44
|
config/hoe.rb
|
29
45
|
config/requirements.rb
|
30
46
|
javascript_test_generators/functional_test/USAGE
|
@@ -79,6 +95,7 @@ script/txt2html
|
|
79
95
|
setup.rb
|
80
96
|
tasks/deployment.rake
|
81
97
|
tasks/environment.rake
|
98
|
+
tasks/jsunittest/update.rake
|
82
99
|
tasks/website.rake
|
83
100
|
test/test_functional_test_generator.rb
|
84
101
|
test/test_generator_helper.rb
|
@@ -86,6 +103,7 @@ test/test_helper.rb
|
|
86
103
|
test/test_install_website_generator.rb
|
87
104
|
test/test_javascript_test_generator.rb
|
88
105
|
test/test_newjs_generator.rb
|
106
|
+
test/test_newjs_iphone_generator.rb
|
89
107
|
test/test_plain_theme_generator.rb
|
90
108
|
test/test_unit_test_generator.rb
|
91
109
|
website/images/example-unittest-log.jpg
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Description:
|
2
|
+
The 'newjs_iphone' should only be executed in the root of an Xcode project for an iPhone app that contains a WebKit view.
|
3
|
+
|
4
|
+
All assets must be in the Html/src file, and not use sub-folders as Xcode doesn't like them in its Targets.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
cd my_iphone_project
|
8
|
+
newjs_iphone .
|
@@ -0,0 +1,111 @@
|
|
1
|
+
class NewjsIphoneGenerator < RubiGen::Base
|
2
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
3
|
+
Config::CONFIG['ruby_install_name'])
|
4
|
+
|
5
|
+
default_options :shebang => DEFAULT_SHEBANG,
|
6
|
+
:author => nil,
|
7
|
+
:email => nil,
|
8
|
+
:version => '0.0.1'
|
9
|
+
|
10
|
+
|
11
|
+
attr_reader :name, :module_name
|
12
|
+
attr_reader :version, :version_str, :author, :email
|
13
|
+
attr_reader :title, :url
|
14
|
+
|
15
|
+
|
16
|
+
def initialize(runtime_args, runtime_options = {})
|
17
|
+
super
|
18
|
+
usage if args.empty?
|
19
|
+
@destination_root = File.expand_path(args.shift)
|
20
|
+
@name = base_name
|
21
|
+
@module_name = name.camelize
|
22
|
+
extract_options
|
23
|
+
@title ||= @name.titleize
|
24
|
+
@url ||= "http://NOTE-ENTER-URL.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
def manifest
|
28
|
+
script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
|
29
|
+
windows = (RUBY_PLATFORM =~ /dos|win32|cygwin/i) || (RUBY_PLATFORM =~ /(:?mswin|mingw)/)
|
30
|
+
|
31
|
+
record do |m|
|
32
|
+
# Ensure appropriate folder(s) exists
|
33
|
+
m.directory ''
|
34
|
+
BASEDIRS.each { |path| m.directory path }
|
35
|
+
|
36
|
+
m.file_copy_each %w[unittest.css jsunittest.js], "Html/test/assets"
|
37
|
+
m.file_copy_each %w[javascript_test_autotest_tasks.rake], "Html/tasks"
|
38
|
+
m.file_copy_each %w[javascript_test_autotest.yml.sample], "Html/config"
|
39
|
+
m.file_copy_each %w[protodoc.rb jstest.rb], "Html/lib"
|
40
|
+
m.template_copy_each %w[Rakefile.erb], "Html"
|
41
|
+
m.template "Html/src/library.js.erb", "Html/src/#{name}.js.erb"
|
42
|
+
|
43
|
+
%w[rstakeout js_autotest].each do |file|
|
44
|
+
m.template "Html/script/#{file}", "Html/script/#{file}", script_options
|
45
|
+
m.template "Html/script/win_script.cmd", "Html/script/#{file}.cmd",
|
46
|
+
:assigns => { :filename => file } if windows
|
47
|
+
end
|
48
|
+
|
49
|
+
m.dependency "install_rubigen_scripts",
|
50
|
+
[File.join(destination_root, "Html"),
|
51
|
+
'javascript', 'javascript_test', 'newjs_iphone', 'newjs_theme'],
|
52
|
+
:shebang => options[:shebang], :collision => :force
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def banner
|
58
|
+
<<-EOS
|
59
|
+
Creates a JavaScript project.
|
60
|
+
|
61
|
+
USAGE: #{spec.name} name"
|
62
|
+
EOS
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_options!(opts)
|
66
|
+
opts.separator ''
|
67
|
+
opts.separator 'Options:'
|
68
|
+
# For each option below, place the default
|
69
|
+
# at the top of the file next to "default_options"
|
70
|
+
opts.on("-a", "--author=\"Your Name\"", String,
|
71
|
+
"Default: none") { |x| options[:author] = x }
|
72
|
+
opts.on("-e", "--email=\"your@email.com\"", String,
|
73
|
+
"Your email to be inserted into generated files.",
|
74
|
+
"Default: ~/.rubyforge/user-config.yml[email]") { |x| options[:email] = x }
|
75
|
+
opts.on("-t", "--title=\"Project Title\"", String,
|
76
|
+
"Human-readable/marketing name for project.",
|
77
|
+
"Default: Project Name") { |x| options[:title] = x }
|
78
|
+
opts.on("-u", "--url=\"http://url-to-project.com\"", String,
|
79
|
+
"Default: http://NOTE-ENTER-URL.com") { |x| options[:url] = x }
|
80
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
81
|
+
opts.on("-V", "--set-version=X.Y.Z", String,
|
82
|
+
"Initial version of the project you are creating.",
|
83
|
+
"Default: 0.0.1") { |x| options[:version] = x }
|
84
|
+
end
|
85
|
+
|
86
|
+
def extract_options
|
87
|
+
@version = options[:version].to_s.split(/\./)
|
88
|
+
@version_str = @version.join('.')
|
89
|
+
@author = options[:author]
|
90
|
+
@email = options[:email]
|
91
|
+
unless @author && @email
|
92
|
+
require 'newjs/rubyforge'
|
93
|
+
rubyforge_config = Newjs::Rubyforge.new
|
94
|
+
@author ||= rubyforge_config.full_name
|
95
|
+
@email ||= rubyforge_config.email
|
96
|
+
end
|
97
|
+
@url = options[:url]
|
98
|
+
end
|
99
|
+
|
100
|
+
# Installation skeleton. Intermediate directories are automatically
|
101
|
+
# created so don't sweat their absence here.
|
102
|
+
BASEDIRS = %w(
|
103
|
+
Html/config
|
104
|
+
Html/lib
|
105
|
+
Html/src
|
106
|
+
Html/script
|
107
|
+
Html/tasks
|
108
|
+
Html/test/assets
|
109
|
+
Html/test/unit
|
110
|
+
)
|
111
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'rake'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'This script should only be accessed via the "rake" command.'
|
6
|
+
puts 'Installation: gem install rake'
|
7
|
+
exit
|
8
|
+
end
|
9
|
+
require 'rake'
|
10
|
+
require 'rake/clean'
|
11
|
+
require 'rake/packagetask'
|
12
|
+
|
13
|
+
$:.unshift File.dirname(__FILE__) + "/lib"
|
14
|
+
|
15
|
+
unless ENV['rakefile_just_config']
|
16
|
+
|
17
|
+
task :default => :test_units
|
18
|
+
|
19
|
+
|
20
|
+
desc "Builds the distribution, runs the JavaScript unit + functional tests and collects their results."
|
21
|
+
task :test => [:test_units, :test_functionals]
|
22
|
+
|
23
|
+
require 'jstest'
|
24
|
+
desc "Runs all the JavaScript unit tests and collects the results"
|
25
|
+
JavaScriptTestTask.new(:test_units, 4711) do |t|
|
26
|
+
testcases = ENV['TESTCASES']
|
27
|
+
tests_to_run = ENV['TESTS'] && ENV['TESTS'].split(',')
|
28
|
+
browsers_to_test = ENV['BROWSERS'] && ENV['BROWSERS'].split(',')
|
29
|
+
|
30
|
+
t.mount("/dist")
|
31
|
+
t.mount("/src")
|
32
|
+
t.mount("/test")
|
33
|
+
|
34
|
+
Dir["test/unit/*_test.html"].sort.each do |test_file|
|
35
|
+
tests = testcases ? { :url => "/#{test_file}", :testcases => testcases } : "/#{test_file}"
|
36
|
+
test_filename = test_file[/.*\/(.+?)\.html/, 1]
|
37
|
+
t.run(tests) unless tests_to_run && !tests_to_run.include?(test_filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
%w( safari firefox ie konqueror opera ).each do |browser|
|
41
|
+
t.browser(browser.to_sym) unless browsers_to_test && !browsers_to_test.include?(browser)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Runs all the JavaScript functional tests and collects the results"
|
46
|
+
JavaScriptTestTask.new(:test_functionals, 4712) do |t|
|
47
|
+
testcases = ENV['TESTCASES']
|
48
|
+
tests_to_run = ENV['TESTS'] && ENV['TESTS'].split(',')
|
49
|
+
browsers_to_test = ENV['BROWSERS'] && ENV['BROWSERS'].split(',')
|
50
|
+
|
51
|
+
t.mount("/dist")
|
52
|
+
t.mount("/src")
|
53
|
+
t.mount("/test")
|
54
|
+
|
55
|
+
Dir["test/functional/*_test.html"].sort.each do |test_file|
|
56
|
+
tests = testcases ? { :url => "/#{test_file}", :testcases => testcases } : "/#{test_file}"
|
57
|
+
test_filename = test_file[/.*\/(.+?)\.html/, 1]
|
58
|
+
t.run(tests) unless tests_to_run && !tests_to_run.include?(test_filename)
|
59
|
+
end
|
60
|
+
|
61
|
+
%w( safari firefox ie konqueror opera ).each do |browser|
|
62
|
+
t.browser(browser.to_sym) unless browsers_to_test && !browsers_to_test.include?(browser)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This file has been copied here by the javascript_test_autotest plugin.
|
2
|
+
# Comment/uncomment the browsers you wish to autotest with.
|
3
|
+
# Same schema as per selenium-on-rails plugin, which is nice.
|
4
|
+
browsers:
|
5
|
+
# Windows
|
6
|
+
# firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe'
|
7
|
+
# ie: 'c:\Program Files\Internet Explorer\iexplore.exe'
|
8
|
+
|
9
|
+
# Mac OS X
|
10
|
+
# firefox: '/Applications/Firefox.app/Contents/MacOS/firefox-bin'
|
11
|
+
safari: '/Applications/Safari.app/Contents/MacOS/Safari'
|
12
|
+
|
13
|
+
# Unix
|
14
|
+
# ?
|
15
|
+
# ?
|
@@ -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
|