xian-test-jasmine 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/bin/autospec ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/environment"))
3
+ load File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/gems/rspec-1.2.9/bin/autospec"))
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
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/environment"))
3
+ load File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/gems/rack-1.0.1/bin/rackup"))
data/bin/selenium-rc ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/environment"))
3
+ load File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/gems/selenium-rc-2.1.0/bin/selenium-rc"))
data/bin/spec ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/environment"))
3
+ load File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/gems/rspec-1.2.9/bin/spec"))
data/bin/thin ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/environment"))
3
+ load File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/gems/thin-1.2.5/bin/thin"))
data/lib/jasmine.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'jasmine/base'
2
+ require 'jasmine/config'
3
+ require 'jasmine/server'
4
+ require 'jasmine/selenium_driver'
5
+
6
+ require 'jasmine/jasmine_helper'
7
+ require 'jasmine/spec_builder'
@@ -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-ruby', 'jasmine_meta_spec.rb'))
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__), "jasmine_spec_builder"))
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
- <% spec_files.each do |spec_file| %>
40
- <script src="<%= spec_file %>" type="text/javascript"></script>
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(spec_files, runner)
8
- @spec_files = spec_files
9
- @runner = runner
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
- @spec_files.each do |filename|
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|
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ require 'spec'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "../lib/jasmine"))
data/templates/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  namespace :jasmine do
2
- require 'jasmine-ruby'
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::SimpleServer.start(8888,
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.2
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-27 00:00:00 -06:00
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-ruby.rb
93
- - lib/jasmine-ruby/jasmine_helper.rb
94
- - lib/jasmine-ruby/jasmine_meta_spec.rb
95
- - lib/jasmine-ruby/jasmine_runner.rb
96
- - lib/jasmine-ruby/jasmine_spec_builder.rb
97
- - lib/jasmine-ruby/run.html
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/jasmine_spec.rb
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,3 +0,0 @@
1
- require 'jasmine-ruby/jasmine_helper'
2
- require 'jasmine-ruby/jasmine_runner'
3
- require 'jasmine-ruby/jasmine_spec_builder'
@@ -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
@@ -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
- });
@@ -1,12 +0,0 @@
1
- class JasmineHelper
2
- def self.files
3
- #return a list of files you want to load before your spec defintions load
4
- []
5
- end
6
-
7
- def self.stylesheets
8
- #return a list of stylesheets you want to load in the runner
9
- []
10
- end
11
-
12
- end
@@ -1 +0,0 @@
1
- //You may load required files here, or create test-runner-wide environment settings.