xian-test-jasmine 0.1.2 → 0.1.3
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/bin/autospec +3 -0
- data/bin/firefox +142 -0
- data/bin/rackup +3 -0
- data/bin/selenium-rc +3 -0
- data/bin/spec +3 -0
- data/bin/thin +3 -0
- data/lib/jasmine.rb +7 -0
- data/lib/jasmine/base.rb +63 -0
- data/lib/jasmine/config.rb +124 -0
- data/lib/{jasmine-ruby → jasmine}/jasmine_helper.rb +1 -1
- data/lib/{jasmine-ruby → jasmine}/jasmine_meta_spec.rb +1 -1
- data/lib/{jasmine-ruby/run.html → jasmine/run.html.erb} +2 -6
- data/lib/jasmine/selenium_driver.rb +44 -0
- data/lib/jasmine/server.rb +130 -0
- data/lib/{jasmine-ruby/jasmine_spec_builder.rb → jasmine/spec_builder.rb} +6 -5
- data/spec/config_spec.rb +53 -0
- data/spec/jasmine_self_test_config.rb +15 -0
- data/spec/jasmine_self_test_spec.rb +18 -0
- data/spec/server_spec.rb +65 -0
- data/spec/spec_helper.rb +3 -0
- data/templates/Rakefile +2 -2
- metadata +28 -12
- data/lib/jasmine-ruby.rb +0 -3
- data/lib/jasmine-ruby/jasmine_runner.rb +0 -300
- data/spec/jasmine_spec.rb +0 -26
- data/templates/example_spec.js +0 -11
- data/templates/jasmine_helper.rb +0 -12
- data/templates/spec_helper.js +0 -1
data/bin/autospec
ADDED
data/bin/firefox
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# ***** BEGIN LICENSE BLOCK *****
|
4
|
+
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
5
|
+
#
|
6
|
+
# The contents of this file are subject to the Mozilla Public License Version
|
7
|
+
# 1.1 (the "License"); you may not use this file except in compliance with
|
8
|
+
# the License. You may obtain a copy of the License at
|
9
|
+
# http://www.mozilla.org/MPL/
|
10
|
+
#
|
11
|
+
# Software distributed under the License is distributed on an "AS IS" basis,
|
12
|
+
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
13
|
+
# for the specific language governing rights and limitations under the
|
14
|
+
# License.
|
15
|
+
#
|
16
|
+
# The Original Code is mozilla.org Code.
|
17
|
+
#
|
18
|
+
# The Initial Developer of the Original Code is
|
19
|
+
# Netscape Communications Corporation.
|
20
|
+
# Portions created by the Initial Developer are Copyright (C) 1998
|
21
|
+
# the Initial Developer. All Rights Reserved.
|
22
|
+
#
|
23
|
+
# Contributor(s):
|
24
|
+
#
|
25
|
+
# Alternatively, the contents of this file may be used under the terms of
|
26
|
+
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
27
|
+
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
28
|
+
# in which case the provisions of the GPL or the LGPL are applicable instead
|
29
|
+
# of those above. If you wish to allow use of your version of this file only
|
30
|
+
# under the terms of either the GPL or the LGPL, and not to allow others to
|
31
|
+
# use your version of this file under the terms of the MPL, indicate your
|
32
|
+
# decision by deleting the provisions above and replace them with the notice
|
33
|
+
# and other provisions required by the GPL or the LGPL. If you do not delete
|
34
|
+
# the provisions above, a recipient may use your version of this file under
|
35
|
+
# the terms of any one of the MPL, the GPL or the LGPL.
|
36
|
+
#
|
37
|
+
# ***** END LICENSE BLOCK *****
|
38
|
+
|
39
|
+
## $Id: mozilla.in,v 1.16 2007/10/05 07:29:26 reed%reedloden.com Exp $
|
40
|
+
##
|
41
|
+
## Usage:
|
42
|
+
##
|
43
|
+
## $ mozilla [args]
|
44
|
+
##
|
45
|
+
## This script is meant to run the mozilla-bin binary from either
|
46
|
+
## mozilla/xpfe/bootstrap or mozilla/dist/bin.
|
47
|
+
##
|
48
|
+
## The script will setup all the environment voodoo needed to make
|
49
|
+
## the mozilla-bin binary to work.
|
50
|
+
##
|
51
|
+
|
52
|
+
#uncomment for debugging
|
53
|
+
#set -x
|
54
|
+
|
55
|
+
moz_libdir=/usr/local/lib/firefox-3.0.9
|
56
|
+
|
57
|
+
# Use run-mozilla.sh in the current dir if it exists
|
58
|
+
# If not, then start resolving symlinks until we find run-mozilla.sh
|
59
|
+
found=0
|
60
|
+
progname="$0"
|
61
|
+
curdir=`dirname "$progname"`
|
62
|
+
progbase=`basename "$progname"`
|
63
|
+
run_moz="$curdir/run-mozilla.sh"
|
64
|
+
if test -x "$run_moz"; then
|
65
|
+
dist_bin="$curdir"
|
66
|
+
found=1
|
67
|
+
else
|
68
|
+
here=`/bin/pwd`
|
69
|
+
while [ -h "$progname" ]; do
|
70
|
+
bn=`basename "$progname"`
|
71
|
+
cd `dirname "$progname"`
|
72
|
+
progname=`/bin/ls -l "$bn" | sed -e 's/^.* -> //' `
|
73
|
+
progbase=`basename "$progname"`
|
74
|
+
if [ ! -x "$progname" ]; then
|
75
|
+
break
|
76
|
+
fi
|
77
|
+
curdir=`dirname "$progname"`
|
78
|
+
run_moz="$curdir/run-mozilla.sh"
|
79
|
+
if [ -x "$run_moz" ]; then
|
80
|
+
cd "$curdir"
|
81
|
+
dist_bin=`pwd`
|
82
|
+
run_moz="$dist_bin/run-mozilla.sh"
|
83
|
+
found=1
|
84
|
+
break
|
85
|
+
fi
|
86
|
+
done
|
87
|
+
cd "$here"
|
88
|
+
fi
|
89
|
+
if [ $found = 0 ]; then
|
90
|
+
# Check default compile-time libdir
|
91
|
+
if [ -x "$moz_libdir/run-mozilla.sh" ]; then
|
92
|
+
dist_bin="$moz_libdir"
|
93
|
+
else
|
94
|
+
echo "Cannot find mozilla runtime directory. Exiting."
|
95
|
+
exit 1
|
96
|
+
fi
|
97
|
+
fi
|
98
|
+
|
99
|
+
script_args=""
|
100
|
+
debugging=0
|
101
|
+
MOZILLA_BIN="${progbase}-bin"
|
102
|
+
|
103
|
+
if [ "$OSTYPE" = "beos" ]; then
|
104
|
+
mimeset -F "$MOZILLA_BIN"
|
105
|
+
fi
|
106
|
+
|
107
|
+
pass_arg_count=0
|
108
|
+
while [ $# -gt $pass_arg_count ]
|
109
|
+
do
|
110
|
+
case "$1" in
|
111
|
+
-p | --pure | -pure)
|
112
|
+
MOZILLA_BIN="${MOZILLA_BIN}.pure"
|
113
|
+
shift
|
114
|
+
;;
|
115
|
+
-g | --debug)
|
116
|
+
script_args="$script_args -g"
|
117
|
+
debugging=1
|
118
|
+
shift
|
119
|
+
;;
|
120
|
+
-d | --debugger)
|
121
|
+
script_args="$script_args -d $2"
|
122
|
+
shift 2
|
123
|
+
;;
|
124
|
+
*)
|
125
|
+
# Move the unrecognized argument to the end of the list.
|
126
|
+
arg="$1"
|
127
|
+
shift
|
128
|
+
set -- "$@" "$arg"
|
129
|
+
pass_arg_count=`expr $pass_arg_count + 1`
|
130
|
+
;;
|
131
|
+
esac
|
132
|
+
done
|
133
|
+
|
134
|
+
if [ $debugging = 1 ]
|
135
|
+
then
|
136
|
+
echo $dist_bin/run-mozilla.sh $script_args $dist_bin/$MOZILLA_BIN "$@"
|
137
|
+
fi
|
138
|
+
"$dist_bin/run-mozilla.sh" $script_args "$dist_bin/$MOZILLA_BIN" "$@"
|
139
|
+
exitcode=$?
|
140
|
+
|
141
|
+
exit $exitcode
|
142
|
+
# EOF.
|
data/bin/rackup
ADDED
data/bin/selenium-rc
ADDED
data/bin/spec
ADDED
data/bin/thin
ADDED
data/lib/jasmine.rb
ADDED
data/lib/jasmine/base.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'erb'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Jasmine
|
6
|
+
def self.root
|
7
|
+
File.expand_path(File.join(File.dirname(__FILE__), '../../jasmine'))
|
8
|
+
end
|
9
|
+
|
10
|
+
# this seemingly-over-complex method is necessary to get an open port on at least some of our Macs
|
11
|
+
def self.open_socket_on_unused_port
|
12
|
+
infos = Socket::getaddrinfo("localhost", nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
|
13
|
+
families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
|
14
|
+
|
15
|
+
return TCPServer.open('0.0.0.0', 0) if families.has_key?('AF_INET')
|
16
|
+
return TCPServer.open('::', 0) if families.has_key?('AF_INET6')
|
17
|
+
return TCPServer.open(0)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find_unused_port
|
21
|
+
socket = open_socket_on_unused_port
|
22
|
+
port = socket.addr[1]
|
23
|
+
socket.close
|
24
|
+
port
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.server_is_listening_on(hostname, port)
|
28
|
+
require 'socket'
|
29
|
+
begin
|
30
|
+
socket = TCPSocket.open(hostname, port)
|
31
|
+
rescue Errno::ECONNREFUSED
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
socket.close
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.wait_for_listener(port, name = "required process", seconds_to_wait = 10)
|
39
|
+
time_out_at = Time.now + seconds_to_wait
|
40
|
+
until server_is_listening_on "localhost", port
|
41
|
+
sleep 0.1
|
42
|
+
puts "Waiting for #{name} on #{port}..."
|
43
|
+
raise "#{name} didn't show up on port #{port} after #{seconds_to_wait} seconds." if Time.now > time_out_at
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.kill_process_group(process_group_id, signal="TERM")
|
48
|
+
Process.kill signal, -process_group_id # negative pid means kill process group. (see man 2 kill)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.cachebust(files, root_dir="", replace=nil, replace_with=nil)
|
52
|
+
require 'digest/md5'
|
53
|
+
files.collect do |file_name|
|
54
|
+
real_file_name = replace && replace_with ? file_name.sub(replace, replace_with) : file_name
|
55
|
+
begin
|
56
|
+
digest = Digest::MD5.hexdigest(File.read("#{root_dir}#{real_file_name}"))
|
57
|
+
rescue
|
58
|
+
digest = "MISSING-FILE"
|
59
|
+
end
|
60
|
+
"#{file_name}?cachebust=#{digest}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class Config
|
3
|
+
def initialize(options = {})
|
4
|
+
require 'selenium_rc'
|
5
|
+
@selenium_jar_path = SeleniumRC::Server.allocate.jar_path
|
6
|
+
@options = options
|
7
|
+
|
8
|
+
@browser = options[:browser] ? options.delete(:browser) : 'firefox'
|
9
|
+
@selenium_pid = nil
|
10
|
+
@jasmine_server_pid = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def start_server(port = 8888)
|
14
|
+
Jasmine::Server.new(port, self).start
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
start_servers
|
19
|
+
@client = Jasmine::SeleniumDriver.new("localhost", @selenium_server_port, "*#{@browser}", "http://localhost:#{@jasmine_server_port}/")
|
20
|
+
@client.connect
|
21
|
+
end
|
22
|
+
|
23
|
+
def stop
|
24
|
+
@client.disconnect
|
25
|
+
stop_servers
|
26
|
+
end
|
27
|
+
|
28
|
+
def start_servers
|
29
|
+
@jasmine_server_port = Jasmine::find_unused_port
|
30
|
+
@selenium_server_port = Jasmine::find_unused_port
|
31
|
+
|
32
|
+
server = Jasmine::Server.new(@jasmine_server_port, self)
|
33
|
+
|
34
|
+
@selenium_pid = fork do
|
35
|
+
Process.setpgrp
|
36
|
+
exec "java -jar #{@selenium_jar_path} -port #{@selenium_server_port} > /dev/null 2>&1"
|
37
|
+
end
|
38
|
+
puts "selenium started. pid is #{@selenium_pid}"
|
39
|
+
|
40
|
+
@jasmine_server_pid = fork do
|
41
|
+
Process.setpgrp
|
42
|
+
server.start
|
43
|
+
exit! 0
|
44
|
+
end
|
45
|
+
puts "jasmine server started. pid is #{@jasmine_server_pid}"
|
46
|
+
|
47
|
+
Jasmine::wait_for_listener(@selenium_server_port, "selenium server")
|
48
|
+
Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
|
49
|
+
end
|
50
|
+
|
51
|
+
def stop_servers
|
52
|
+
puts "shutting down the servers..."
|
53
|
+
Jasmine::kill_process_group(@selenium_pid) if @selenium_pid
|
54
|
+
Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
|
55
|
+
end
|
56
|
+
|
57
|
+
def run
|
58
|
+
begin
|
59
|
+
start
|
60
|
+
puts "servers are listening on their ports -- running the test script..."
|
61
|
+
tests_passed = @client.run
|
62
|
+
ensure
|
63
|
+
stop
|
64
|
+
end
|
65
|
+
return tests_passed
|
66
|
+
end
|
67
|
+
|
68
|
+
def eval_js(script)
|
69
|
+
@client.eval_js(script)
|
70
|
+
end
|
71
|
+
|
72
|
+
def mappings
|
73
|
+
raise "You need to declare a mappings method in #{self.class}!"
|
74
|
+
end
|
75
|
+
|
76
|
+
def stylesheets
|
77
|
+
[]
|
78
|
+
end
|
79
|
+
|
80
|
+
def src_files
|
81
|
+
[]
|
82
|
+
end
|
83
|
+
|
84
|
+
def spec_files
|
85
|
+
raise "You need to declare a spec_files method in #{self.class}!"
|
86
|
+
end
|
87
|
+
|
88
|
+
def match_files(dir, pattern)
|
89
|
+
dir = File.expand_path(dir)
|
90
|
+
Dir.glob(File.join(dir, pattern)).collect {|f| f.sub("#{dir}/", "")}.sort
|
91
|
+
end
|
92
|
+
|
93
|
+
def src_files
|
94
|
+
match_files(src_dir, "**/*.js")
|
95
|
+
end
|
96
|
+
|
97
|
+
def src_path
|
98
|
+
"src"
|
99
|
+
end
|
100
|
+
|
101
|
+
def spec_path
|
102
|
+
"spec"
|
103
|
+
end
|
104
|
+
|
105
|
+
def spec_files
|
106
|
+
match_files(spec_dir, "**/*.js")
|
107
|
+
end
|
108
|
+
|
109
|
+
def mappings
|
110
|
+
{
|
111
|
+
"/" + src_path => src_dir,
|
112
|
+
"/" + spec_path => spec_dir
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def js_files
|
117
|
+
src_files.collect {|f| File.join(src_path, f) } + spec_files.collect {|f| File.join(spec_path, f) }
|
118
|
+
end
|
119
|
+
|
120
|
+
def spec_files_full_paths
|
121
|
+
spec_files.collect {|spec_file| File.join(spec_dir, spec_file) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -34,7 +34,7 @@ class JasmineHelper
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.meta_spec_path
|
37
|
-
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'jasmine
|
37
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'jasmine', 'jasmine_meta_spec.rb'))
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.files
|
@@ -6,7 +6,7 @@ if File.exist?(helper_overrides)
|
|
6
6
|
require helper_overrides
|
7
7
|
end
|
8
8
|
require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_runner.rb"))
|
9
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "
|
9
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_builder"))
|
10
10
|
|
11
11
|
jasmine_runner = Jasmine::Runner.new(SeleniumRC::Server.new.jar_path,
|
12
12
|
Dir.pwd,
|
@@ -11,10 +11,6 @@
|
|
11
11
|
<script src="<%= jasmine_file %>" type="text/javascript"></script>
|
12
12
|
<% end %>
|
13
13
|
|
14
|
-
<% spec_helpers.each do |spec_helper| %>
|
15
|
-
<script src="<%= spec_helper %>" type="text/javascript"></script>
|
16
|
-
<% end %>
|
17
|
-
|
18
14
|
<script type="text/javascript">
|
19
15
|
var jsApiReporter;
|
20
16
|
(function() {
|
@@ -36,8 +32,8 @@
|
|
36
32
|
})();
|
37
33
|
</script>
|
38
34
|
|
39
|
-
<%
|
40
|
-
<script src="<%=
|
35
|
+
<% js_files.each do |js_file| %>
|
36
|
+
<script src="<%= js_file %>" type="text/javascript"></script>
|
41
37
|
<% end %>
|
42
38
|
|
43
39
|
</head>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class SeleniumDriver
|
3
|
+
def initialize(selenium_host, selenium_port, selenium_browser_start_command, http_address)
|
4
|
+
require 'selenium/client'
|
5
|
+
@driver = Selenium::Client::Driver.new(
|
6
|
+
selenium_host,
|
7
|
+
selenium_port,
|
8
|
+
selenium_browser_start_command,
|
9
|
+
http_address
|
10
|
+
)
|
11
|
+
@http_address = http_address
|
12
|
+
end
|
13
|
+
|
14
|
+
def tests_have_finished?
|
15
|
+
@driver.get_eval("window.jasmine.getEnv().currentRunner.finished") == "true"
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
@driver.start
|
20
|
+
@driver.open("/")
|
21
|
+
end
|
22
|
+
|
23
|
+
def disconnect
|
24
|
+
@driver.stop
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
until tests_have_finished? do
|
29
|
+
sleep 0.1
|
30
|
+
end
|
31
|
+
|
32
|
+
puts @driver.get_eval("window.results()")
|
33
|
+
failed_count = @driver.get_eval("window.jasmine.getEnv().currentRunner.results().failedCount").to_i
|
34
|
+
failed_count == 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def eval_js(script)
|
38
|
+
escaped_script = "'" + script.gsub(/(['\\])/) { '\\' + $1 } + "'"
|
39
|
+
|
40
|
+
result = @driver.get_eval(" try { eval(#{escaped_script}, window); } catch(err) { window.eval(#{escaped_script}); }")
|
41
|
+
JSON.parse("[#{result}]")[0]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class RunAdapter
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@jasmine_files = [
|
6
|
+
"/__JASMINE_ROOT__/lib/" + File.basename(Dir.glob("#{Jasmine.root}/lib/jasmine*.js").first),
|
7
|
+
"/__JASMINE_ROOT__/lib/TrivialReporter.js",
|
8
|
+
"/__JASMINE_ROOT__/lib/json2.js",
|
9
|
+
"/__JASMINE_ROOT__/lib/consolex.js",
|
10
|
+
]
|
11
|
+
@jasmine_stylesheets = ["/__JASMINE_ROOT__/lib/jasmine.css"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
run
|
16
|
+
end
|
17
|
+
|
18
|
+
#noinspection RubyUnusedLocalVariable
|
19
|
+
def run
|
20
|
+
jasmine_files = @jasmine_files
|
21
|
+
css_files = @jasmine_stylesheets + (Jasmine.files(@config.stylesheets) || [])
|
22
|
+
js_files = Jasmine.files(@config.js_files)
|
23
|
+
|
24
|
+
body = ERB.new(File.read(File.join(File.dirname(__FILE__), "run.html.erb"))).result(binding)
|
25
|
+
[
|
26
|
+
200,
|
27
|
+
{ 'Content-Type' => 'text/html' },
|
28
|
+
body
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class Redirect
|
36
|
+
def initialize(url)
|
37
|
+
@url = url
|
38
|
+
end
|
39
|
+
|
40
|
+
def call(env)
|
41
|
+
[
|
42
|
+
302,
|
43
|
+
{ 'Location' => @url },
|
44
|
+
[]
|
45
|
+
]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class JsAlert
|
50
|
+
def call(env)
|
51
|
+
[
|
52
|
+
200,
|
53
|
+
{ 'Content-Type' => 'application/javascript' },
|
54
|
+
"document.write('<p>Couldn\\'t load #{env["PATH_INFO"]}!</p>');"
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class FocusedSuite
|
60
|
+
def initialize(config)
|
61
|
+
@config = config
|
62
|
+
# @spec_files_or_proc = Jasmine.files(spec_files_or_proc) || []
|
63
|
+
# @options = options
|
64
|
+
end
|
65
|
+
|
66
|
+
def call(env)
|
67
|
+
spec_files = Jasmine.files(@config.spec_files_or_proc)
|
68
|
+
matching_specs = spec_files.select {|spec_file| spec_file =~ /#{Regexp.escape(env["PATH_INFO"])}/ }.compact
|
69
|
+
if !matching_specs.empty?
|
70
|
+
run_adapter = Jasmine::RunAdapter.new(matching_specs, @options)
|
71
|
+
run_adapter.run
|
72
|
+
else
|
73
|
+
[
|
74
|
+
200,
|
75
|
+
{ 'Content-Type' => 'application/javascript' },
|
76
|
+
"document.write('<p>Couldn\\'t find any specs matching #{env["PATH_INFO"]}!</p>');"
|
77
|
+
]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.files(f)
|
84
|
+
result = f
|
85
|
+
result = result.call if result.respond_to?(:call)
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
class Server
|
90
|
+
attr_reader :thin
|
91
|
+
|
92
|
+
def initialize(port, config)
|
93
|
+
@port = port
|
94
|
+
@config = config
|
95
|
+
|
96
|
+
require 'thin'
|
97
|
+
thin_config = {
|
98
|
+
'/__suite__' => Jasmine::FocusedSuite.new(@config),
|
99
|
+
'/run.html' => Jasmine::Redirect.new('/'),
|
100
|
+
'/' => Jasmine::RunAdapter.new(@config)
|
101
|
+
}
|
102
|
+
|
103
|
+
@config.mappings.each do |from, to|
|
104
|
+
thin_config[from] = Rack::File.new(to)
|
105
|
+
end
|
106
|
+
|
107
|
+
thin_config["/__JASMINE_ROOT__"] = Rack::File.new(Jasmine.root)
|
108
|
+
|
109
|
+
app = Rack::Cascade.new([
|
110
|
+
Rack::URLMap.new(thin_config),
|
111
|
+
JsAlert.new
|
112
|
+
])
|
113
|
+
|
114
|
+
@thin = Thin::Server.new('0.0.0.0', @port, app)
|
115
|
+
end
|
116
|
+
|
117
|
+
def start
|
118
|
+
begin
|
119
|
+
thin.start
|
120
|
+
rescue RuntimeError => e
|
121
|
+
raise e unless e.message == 'no acceptor'
|
122
|
+
raise RuntimeError.new("A server is already running on port #{@port}")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def stop
|
127
|
+
thin.stop
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'enumerator'
|
2
|
-
module Jasmine
|
3
2
|
|
3
|
+
module Jasmine
|
4
4
|
class SpecBuilder
|
5
5
|
attr_accessor :suites
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@spec_files = config.spec_files
|
10
|
+
@runner = config
|
10
11
|
@spec_ids = []
|
11
12
|
end
|
12
13
|
|
@@ -31,7 +32,7 @@ module Jasmine
|
|
31
32
|
|
32
33
|
example_name_parts = []
|
33
34
|
previous_indent_level = 0
|
34
|
-
@
|
35
|
+
@config.spec_files_full_paths.each do |filename|
|
35
36
|
line_number = 1
|
36
37
|
File.open(filename, "r") do |file|
|
37
38
|
file.readlines.each do |line|
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
+
|
3
|
+
describe Jasmine::Config do
|
4
|
+
before(:each) do
|
5
|
+
@template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../templates"))
|
6
|
+
@config = Jasmine::Config.new
|
7
|
+
@config.stub!(:src_dir).and_return(File.join(@template_dir, "public"))
|
8
|
+
@config.stub!(:spec_dir).and_return(File.join(@template_dir, "spec"))
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should provide a list of all src and spec files" do
|
12
|
+
@config.src_files.should == ['javascripts/Example.js']
|
13
|
+
@config.spec_files.should == ['javascript/ExampleSpec.js', 'javascript/SpecHelper.js']
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should provide a list of all spec files with full paths" do
|
17
|
+
@config.spec_files_full_paths.should == [
|
18
|
+
File.join(@template_dir, 'spec/javascript/ExampleSpec.js'),
|
19
|
+
File.join(@template_dir, 'spec/javascript/SpecHelper.js')
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should provide a list of all js files" do
|
24
|
+
@config.js_files.should == [
|
25
|
+
'src/javascripts/Example.js',
|
26
|
+
'spec/javascript/ExampleSpec.js',
|
27
|
+
'spec/javascript/SpecHelper.js',
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should provide dir mappings" do
|
32
|
+
@config.mappings.should == {
|
33
|
+
'/src' => @config.src_dir,
|
34
|
+
'/spec' => @config.spec_dir
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow overriding src and spec paths" do
|
39
|
+
@config.stub!(:src_path).and_return("public")
|
40
|
+
@config.stub!(:spec_path).and_return("spekz")
|
41
|
+
|
42
|
+
@config.js_files.should == [
|
43
|
+
'public/javascripts/Example.js',
|
44
|
+
'spekz/javascript/ExampleSpec.js',
|
45
|
+
'spekz/javascript/SpecHelper.js',
|
46
|
+
]
|
47
|
+
|
48
|
+
@config.mappings.should == {
|
49
|
+
'/public' => @config.src_dir,
|
50
|
+
'/spekz' => @config.spec_dir
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'jasmine'
|
2
|
+
|
3
|
+
class JasmineSelfTestConfig < Jasmine::Config
|
4
|
+
def proj_root
|
5
|
+
File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
6
|
+
end
|
7
|
+
|
8
|
+
def src_dir
|
9
|
+
File.join(proj_root, 'src')
|
10
|
+
end
|
11
|
+
|
12
|
+
def spec_dir
|
13
|
+
File.join(proj_root, 'jasmine/spec')
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
+
|
3
|
+
require 'jasmine_self_test_config'
|
4
|
+
|
5
|
+
jasmine_config = JasmineSelfTestConfig.new
|
6
|
+
spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
|
7
|
+
|
8
|
+
should_stop = false
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
config.after(:suite) do
|
12
|
+
spec_builder.stop if should_stop
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
spec_builder.start
|
17
|
+
should_stop = true
|
18
|
+
spec_builder.declare_suites
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
+
|
3
|
+
def read(body)
|
4
|
+
return body if body.is_a?(String)
|
5
|
+
out = ""
|
6
|
+
body.each {|data| out += data }
|
7
|
+
out
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Jasmine::Server do
|
11
|
+
before(:each) do
|
12
|
+
config = Jasmine::Config.new
|
13
|
+
config.stub!(:mappings).and_return({
|
14
|
+
"/src" => File.join(Jasmine.root, "src"),
|
15
|
+
"/spec" => File.join(Jasmine.root, "spec")
|
16
|
+
})
|
17
|
+
|
18
|
+
config.stub!(:js_files).and_return(["/src/file1.js", "/spec/file2.js"])
|
19
|
+
|
20
|
+
@server = Jasmine::Server.new(0, config)
|
21
|
+
@thin_app = @server.thin.app
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
@server.thin.stop if @server && @server.thin.running?
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should serve static files" do
|
29
|
+
code, headers, body = @thin_app.call("PATH_INFO" => "/spec/suites/EnvSpec.js", "SCRIPT_NAME" => "xxx")
|
30
|
+
code.should == 200
|
31
|
+
headers["Content-Type"].should == "application/javascript"
|
32
|
+
read(body).should == File.read(File.join(Jasmine.root, "spec/suites/EnvSpec.js"))
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should serve Jasmine static files under /__JASMINE_ROOT__/" do
|
36
|
+
code, headers, body = @thin_app.call("PATH_INFO" => "/__JASMINE_ROOT__/lib/jasmine.css", "SCRIPT_NAME" => "xxx")
|
37
|
+
code.should == 200
|
38
|
+
headers["Content-Type"].should == "text/css"
|
39
|
+
read(body).should == File.read(File.join(Jasmine.root, "lib/jasmine.css"))
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should redirect /run.html to /" do
|
43
|
+
code, headers, body = @thin_app.call("PATH_INFO" => "/run.html", "SCRIPT_NAME" => "xxx")
|
44
|
+
code.should == 302
|
45
|
+
headers["Location"].should == "/"
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "/ page" do
|
49
|
+
it "should load each js file in order" do
|
50
|
+
code, headers, body = @thin_app.call("PATH_INFO" => "/", "SCRIPT_NAME" => "xxx")
|
51
|
+
code.should == 200
|
52
|
+
body = read(body)
|
53
|
+
body.should include("\"/src/file1.js")
|
54
|
+
body.should include("\"/spec/file2.js")
|
55
|
+
body.should satisfy {|s| s.index("/src/file1.js") < s.index("/spec/file2.js") }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should display an error using JS for 404's" do
|
60
|
+
code, headers, body = @thin_app.call("PATH_INFO" => "/spec/NonExistantFile.js", "SCRIPT_NAME" => "xxx")
|
61
|
+
code.should == 200 # todo: shouldn't this be 404? will that work with all browsers?
|
62
|
+
headers["Content-Type"].should == "application/javascript"
|
63
|
+
read(body).should == "document.write('<p>Couldn\\'t load /spec/NonExistantFile.js!</p>');"
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/templates/Rakefile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
namespace :jasmine do
|
2
|
-
require 'jasmine
|
2
|
+
require 'jasmine'
|
3
3
|
helper_overrides = File.expand_path(File.join(File.dirname(__FILE__), "spec/helpers/jasmine_helper.rb"))
|
4
4
|
if File.exist?(helper_overrides)
|
5
5
|
require helper_overrides
|
@@ -17,7 +17,7 @@ namespace :jasmine do
|
|
17
17
|
puts "your tests are here:"
|
18
18
|
puts " http://localhost:8888/run.html"
|
19
19
|
|
20
|
-
Jasmine::
|
20
|
+
Jasmine::Server.start(8888,
|
21
21
|
File.expand_path(Dir.pwd),
|
22
22
|
lambda { JasmineHelper.specs },
|
23
23
|
{ :spec_helpers => JasmineHelper.files + JasmineHelper.spec_helpers,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xian-test-jasmine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rajan Agaskar
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-28 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -65,40 +65,52 @@ dependencies:
|
|
65
65
|
description: Jasmine Ruby
|
66
66
|
email: ragaskar@gmail.com
|
67
67
|
executables:
|
68
|
+
- autospec
|
68
69
|
- edit_json.rb
|
70
|
+
- firefox
|
69
71
|
- git
|
70
72
|
- jasmine
|
71
73
|
- jeweler
|
72
74
|
- prettify_json.rb
|
75
|
+
- rackup
|
73
76
|
- rake
|
74
77
|
- rubyforge
|
78
|
+
- selenium-rc
|
79
|
+
- spec
|
80
|
+
- thin
|
75
81
|
extensions: []
|
76
82
|
|
77
83
|
extra_rdoc_files:
|
78
84
|
- README.markdown
|
79
85
|
files:
|
86
|
+
- bin/autospec
|
80
87
|
- bin/edit_json.rb
|
88
|
+
- bin/firefox
|
81
89
|
- bin/git
|
82
90
|
- bin/jasmine
|
83
91
|
- bin/jeweler
|
84
92
|
- bin/prettify_json.rb
|
93
|
+
- bin/rackup
|
85
94
|
- bin/rake
|
86
95
|
- bin/rubyforge
|
96
|
+
- bin/selenium-rc
|
97
|
+
- bin/spec
|
98
|
+
- bin/thin
|
87
99
|
- jasmine/lib/TrivialReporter.js
|
88
100
|
- jasmine/lib/consolex.js
|
89
101
|
- jasmine/lib/jasmine-0.10.0.js
|
90
102
|
- jasmine/lib/jasmine.css
|
91
103
|
- jasmine/lib/json2.js
|
92
|
-
- lib/jasmine
|
93
|
-
- lib/jasmine
|
94
|
-
- lib/jasmine
|
95
|
-
- lib/jasmine
|
96
|
-
- lib/jasmine
|
97
|
-
- lib/jasmine
|
104
|
+
- lib/jasmine.rb
|
105
|
+
- lib/jasmine/base.rb
|
106
|
+
- lib/jasmine/config.rb
|
107
|
+
- lib/jasmine/jasmine_helper.rb
|
108
|
+
- lib/jasmine/jasmine_meta_spec.rb
|
109
|
+
- lib/jasmine/run.html.erb
|
110
|
+
- lib/jasmine/selenium_driver.rb
|
111
|
+
- lib/jasmine/server.rb
|
112
|
+
- lib/jasmine/spec_builder.rb
|
98
113
|
- templates/Rakefile
|
99
|
-
- templates/example_spec.js
|
100
|
-
- templates/jasmine_helper.rb
|
101
|
-
- templates/spec_helper.js
|
102
114
|
- README.markdown
|
103
115
|
has_rdoc: true
|
104
116
|
homepage: http://github.com/ragaskar/jasmine-ruby
|
@@ -129,4 +141,8 @@ signing_key:
|
|
129
141
|
specification_version: 3
|
130
142
|
summary: Jasmine Ruby
|
131
143
|
test_files:
|
132
|
-
- spec/
|
144
|
+
- spec/config_spec.rb
|
145
|
+
- spec/jasmine_self_test_config.rb
|
146
|
+
- spec/jasmine_self_test_spec.rb
|
147
|
+
- spec/server_spec.rb
|
148
|
+
- spec/spec_helper.rb
|
data/lib/jasmine-ruby.rb
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
require 'erb'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module Jasmine
|
6
|
-
def self.root
|
7
|
-
File.expand_path(File.join(File.dirname(__FILE__), '../../jasmine'))
|
8
|
-
end
|
9
|
-
|
10
|
-
# this seemingly-over-complex method is necessary to get an open port on at least some of our Macs
|
11
|
-
def self.open_socket_on_unused_port
|
12
|
-
infos = Socket::getaddrinfo("localhost", nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
|
13
|
-
families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
|
14
|
-
|
15
|
-
return TCPServer.open('0.0.0.0', 0) if families.has_key?('AF_INET')
|
16
|
-
return TCPServer.open('::', 0) if families.has_key?('AF_INET6')
|
17
|
-
return TCPServer.open(0)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.find_unused_port
|
21
|
-
socket = open_socket_on_unused_port
|
22
|
-
port = socket.addr[1]
|
23
|
-
socket.close
|
24
|
-
port
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.server_is_listening_on(hostname, port)
|
28
|
-
require 'socket'
|
29
|
-
begin
|
30
|
-
socket = TCPSocket.open(hostname, port)
|
31
|
-
rescue Errno::ECONNREFUSED
|
32
|
-
return false
|
33
|
-
end
|
34
|
-
socket.close
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.wait_for_listener(port, name = "required process", seconds_to_wait = 10)
|
39
|
-
time_out_at = Time.now + seconds_to_wait
|
40
|
-
until server_is_listening_on "localhost", port
|
41
|
-
sleep 0.1
|
42
|
-
puts "Waiting for #{name} on #{port}..."
|
43
|
-
raise "#{name} didn't show up on port #{port} after #{seconds_to_wait} seconds." if Time.now > time_out_at
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.kill_process_group(process_group_id, signal="TERM")
|
48
|
-
Process.kill signal, -process_group_id # negative pid means kill process group. (see man 2 kill)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.cachebust(files, root_dir="", replace=nil, replace_with=nil)
|
52
|
-
require 'digest/md5'
|
53
|
-
files.collect do |file_name|
|
54
|
-
real_file_name = replace && replace_with ? file_name.sub(replace, replace_with) : file_name
|
55
|
-
begin
|
56
|
-
digest = Digest::MD5.hexdigest(File.read("#{root_dir}#{real_file_name}"))
|
57
|
-
rescue
|
58
|
-
digest = "MISSING-FILE"
|
59
|
-
end
|
60
|
-
"#{file_name}?cachebust=#{digest}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class RunAdapter
|
65
|
-
def initialize(spec_files_or_proc, options = {})
|
66
|
-
@spec_files_or_proc = Jasmine.files(spec_files_or_proc) || []
|
67
|
-
@jasmine_files = Jasmine.files(options[:jasmine_files]) || [
|
68
|
-
"/__JASMINE_ROOT__/lib/" + File.basename(Dir.glob("#{Jasmine.root}/lib/jasmine*.js").first),
|
69
|
-
"/__JASMINE_ROOT__/lib/TrivialReporter.js",
|
70
|
-
"/__JASMINE_ROOT__/lib/json2.js",
|
71
|
-
"/__JASMINE_ROOT__/lib/consolex.js",
|
72
|
-
]
|
73
|
-
@stylesheets = ["/__JASMINE_ROOT__/lib/jasmine.css"] + (Jasmine.files(options[:stylesheets]) || [])
|
74
|
-
@spec_helpers = Jasmine.files(options[:spec_helpers]) || []
|
75
|
-
end
|
76
|
-
|
77
|
-
def call(env)
|
78
|
-
run
|
79
|
-
end
|
80
|
-
|
81
|
-
def run
|
82
|
-
stylesheets = @stylesheets
|
83
|
-
spec_helpers = @spec_helpers
|
84
|
-
spec_files = @spec_files_or_proc
|
85
|
-
|
86
|
-
jasmine_files = @jasmine_files
|
87
|
-
jasmine_files = jasmine_files.call if jasmine_files.respond_to?(:call)
|
88
|
-
|
89
|
-
css_files = @stylesheets
|
90
|
-
|
91
|
-
|
92
|
-
body = ERB.new(File.read(File.join(File.dirname(__FILE__), "run.html"))).result(binding)
|
93
|
-
[
|
94
|
-
200,
|
95
|
-
{ 'Content-Type' => 'text/html' },
|
96
|
-
body
|
97
|
-
]
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
class Redirect
|
104
|
-
def initialize(url)
|
105
|
-
@url = url
|
106
|
-
end
|
107
|
-
|
108
|
-
def call(env)
|
109
|
-
[
|
110
|
-
302,
|
111
|
-
{ 'Location' => @url },
|
112
|
-
[]
|
113
|
-
]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
class JsAlert
|
118
|
-
def call(env)
|
119
|
-
[
|
120
|
-
200,
|
121
|
-
{ 'Content-Type' => 'application/javascript' },
|
122
|
-
"document.write('<p>Couldn\\'t load #{env["PATH_INFO"]}!</p>');"
|
123
|
-
]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
class FocusedSuite
|
128
|
-
def initialize(spec_files_or_proc, options)
|
129
|
-
@spec_files_or_proc = Jasmine.files(spec_files_or_proc) || []
|
130
|
-
@options = options
|
131
|
-
end
|
132
|
-
|
133
|
-
def call(env)
|
134
|
-
spec_files = @spec_files_or_proc
|
135
|
-
matching_specs = spec_files.select {|spec_file| spec_file =~ /#{Regexp.escape(env["PATH_INFO"])}/ }.compact
|
136
|
-
if !matching_specs.empty?
|
137
|
-
run_adapter = Jasmine::RunAdapter.new(matching_specs, @options)
|
138
|
-
run_adapter.run
|
139
|
-
else
|
140
|
-
[
|
141
|
-
200,
|
142
|
-
{ 'Content-Type' => 'application/javascript' },
|
143
|
-
"document.write('<p>Couldn\\'t find any specs matching #{env["PATH_INFO"]}!</p>');"
|
144
|
-
]
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
149
|
-
|
150
|
-
class SimpleServer
|
151
|
-
def self.start(port, root_path, spec_files_or_proc, options = {})
|
152
|
-
require 'thin'
|
153
|
-
config = {
|
154
|
-
'/__suite__' => Jasmine::FocusedSuite.new(spec_files_or_proc, options),
|
155
|
-
'/run.html' => Jasmine::Redirect.new('/'),
|
156
|
-
'/' => Jasmine::RunAdapter.new(spec_files_or_proc, options)
|
157
|
-
}
|
158
|
-
if (options[:mappings])
|
159
|
-
options[:mappings].each do |from, to|
|
160
|
-
config[from] = Rack::File.new(to)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
config["/__JASMINE_ROOT__"] = Rack::File.new(Jasmine.root)
|
165
|
-
|
166
|
-
file_serve_config = {
|
167
|
-
'/' => Rack::File.new(root_path)
|
168
|
-
}
|
169
|
-
|
170
|
-
app = Rack::Cascade.new([
|
171
|
-
Rack::URLMap.new(file_serve_config),
|
172
|
-
Rack::URLMap.new(config),
|
173
|
-
JsAlert.new
|
174
|
-
])
|
175
|
-
|
176
|
-
begin
|
177
|
-
Thin::Server.start('0.0.0.0', port, app)
|
178
|
-
rescue RuntimeError => e
|
179
|
-
raise e unless e.message == 'no acceptor'
|
180
|
-
raise RuntimeError.new("A server is already running on port #{port}")
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
class SimpleClient
|
186
|
-
def initialize(selenium_host, selenium_port, selenium_browser_start_command, http_address)
|
187
|
-
require 'selenium/client'
|
188
|
-
@driver = Selenium::Client::Driver.new(
|
189
|
-
selenium_host,
|
190
|
-
selenium_port,
|
191
|
-
selenium_browser_start_command,
|
192
|
-
http_address
|
193
|
-
)
|
194
|
-
@http_address = http_address
|
195
|
-
end
|
196
|
-
|
197
|
-
def tests_have_finished?
|
198
|
-
@driver.get_eval("window.jasmine.getEnv().currentRunner.finished") == "true"
|
199
|
-
end
|
200
|
-
|
201
|
-
def connect
|
202
|
-
@driver.start
|
203
|
-
@driver.open("/")
|
204
|
-
end
|
205
|
-
|
206
|
-
def disconnect
|
207
|
-
@driver.stop
|
208
|
-
end
|
209
|
-
|
210
|
-
def run
|
211
|
-
until tests_have_finished? do
|
212
|
-
sleep 0.1
|
213
|
-
end
|
214
|
-
|
215
|
-
puts @driver.get_eval("window.results()")
|
216
|
-
failed_count = @driver.get_eval("window.jasmine.getEnv().currentRunner.results().failedCount").to_i
|
217
|
-
failed_count == 0
|
218
|
-
end
|
219
|
-
|
220
|
-
def eval_js(script)
|
221
|
-
escaped_script = "'" + script.gsub(/(['\\])/) { '\\' + $1 } + "'"
|
222
|
-
|
223
|
-
result = @driver.get_eval(" try { eval(#{escaped_script}, window); } catch(err) { window.eval(#{escaped_script}); }")
|
224
|
-
JSON.parse("[#{result}]")[0]
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
class Runner
|
229
|
-
def initialize(selenium_jar_path, root_path, spec_files, options={})
|
230
|
-
@root_path = root_path
|
231
|
-
@selenium_jar_path = selenium_jar_path
|
232
|
-
@spec_files = spec_files
|
233
|
-
@options = options
|
234
|
-
|
235
|
-
@browser = options[:browser] ? options[:browser].delete(:browser) : 'firefox'
|
236
|
-
@selenium_pid = nil
|
237
|
-
@jasmine_server_pid = nil
|
238
|
-
end
|
239
|
-
|
240
|
-
def start
|
241
|
-
start_servers
|
242
|
-
@client = Jasmine::SimpleClient.new("localhost", @selenium_server_port, "*#{@browser}", "http://localhost:#{@jasmine_server_port}/")
|
243
|
-
@client.connect
|
244
|
-
end
|
245
|
-
|
246
|
-
def stop
|
247
|
-
@client.disconnect
|
248
|
-
stop_servers
|
249
|
-
end
|
250
|
-
|
251
|
-
def start_servers
|
252
|
-
@jasmine_server_port = Jasmine::find_unused_port
|
253
|
-
@selenium_server_port = Jasmine::find_unused_port
|
254
|
-
|
255
|
-
@selenium_pid = fork do
|
256
|
-
Process.setpgrp
|
257
|
-
exec "java -jar #{@selenium_jar_path} -port #{@selenium_server_port} > /dev/null 2>&1"
|
258
|
-
end
|
259
|
-
puts "selenium started. pid is #{@selenium_pid}"
|
260
|
-
|
261
|
-
@jasmine_server_pid = fork do
|
262
|
-
Process.setpgrp
|
263
|
-
Jasmine::SimpleServer.start(@jasmine_server_port, @root_path, @spec_files, @options)
|
264
|
-
exit! 0
|
265
|
-
end
|
266
|
-
puts "jasmine server started. pid is #{@jasmine_server_pid}"
|
267
|
-
|
268
|
-
Jasmine::wait_for_listener(@selenium_server_port, "selenium server")
|
269
|
-
Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
|
270
|
-
end
|
271
|
-
|
272
|
-
def stop_servers
|
273
|
-
puts "shutting down the servers..."
|
274
|
-
Jasmine::kill_process_group(@selenium_pid) if @selenium_pid
|
275
|
-
Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
|
276
|
-
end
|
277
|
-
|
278
|
-
def run
|
279
|
-
begin
|
280
|
-
start
|
281
|
-
puts "servers are listening on their ports -- running the test script..."
|
282
|
-
tests_passed = @client.run
|
283
|
-
ensure
|
284
|
-
stop
|
285
|
-
end
|
286
|
-
return tests_passed
|
287
|
-
end
|
288
|
-
|
289
|
-
def eval_js(script)
|
290
|
-
@client.eval_js(script)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
def self.files(f)
|
295
|
-
result = f
|
296
|
-
result = result.call if result.respond_to?(:call)
|
297
|
-
result
|
298
|
-
end
|
299
|
-
|
300
|
-
end
|
data/spec/jasmine_spec.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require "selenium_rc"
|
3
|
-
|
4
|
-
JASMINE_SPEC_DIR = File.join(File.dirname(__FILE__), "..", "jasmine", "spec")
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "jasmine-ruby", "jasmine_helper.rb"))
|
7
|
-
require File.expand_path(File.join(JasmineHelper.root, "contrib/ruby/jasmine_spec_builder"))
|
8
|
-
|
9
|
-
jasmine_runner = Jasmine::Runner.new(SeleniumRC::Server.new.jar_path,
|
10
|
-
JasmineHelper.spec_file_urls,
|
11
|
-
JasmineHelper.dir_mappings,
|
12
|
-
:spec_helpers => JasmineHelper.spec_helpers)
|
13
|
-
|
14
|
-
spec_builder = Jasmine::SpecBuilder.new(JasmineHelper.raw_spec_files, jasmine_runner)
|
15
|
-
|
16
|
-
should_stop = false
|
17
|
-
|
18
|
-
Spec::Runner.configure do |config|
|
19
|
-
config.after(:suite) do
|
20
|
-
spec_builder.stop if should_stop
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
spec_builder.start
|
25
|
-
should_stop = true
|
26
|
-
spec_builder.declare_suites
|
data/templates/example_spec.js
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
describe('ExampleSuite', function () {
|
2
|
-
it('should have a passing test', function() {
|
3
|
-
expect(true).toEqual(true);
|
4
|
-
});
|
5
|
-
|
6
|
-
describe('Nested Describe', function () {
|
7
|
-
it('should also have a passing test', function () {
|
8
|
-
expect(true).toEqual(true);
|
9
|
-
});
|
10
|
-
});
|
11
|
-
});
|
data/templates/jasmine_helper.rb
DELETED
data/templates/spec_helper.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
//You may load required files here, or create test-runner-wide environment settings.
|