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 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.