js_spec 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGES +5 -1
  2. data/Rakefile +3 -3
  3. data/bin/js_spec +10 -0
  4. data/bin/js_spec_server +2 -1
  5. data/core/JSSpec.js +11 -5
  6. data/core/JSSpecExtensions.js +127 -8
  7. data/core/demo.html +8 -1
  8. data/lib/js_spec/rails_server.rb +22 -0
  9. data/lib/js_spec/{dir.rb → resources/dir.rb} +7 -5
  10. data/lib/js_spec/{file.rb → resources/file.rb} +9 -3
  11. data/lib/js_spec/resources/runners/firefox_runner.rb +90 -0
  12. data/lib/js_spec/resources/runners.rb +16 -0
  13. data/lib/js_spec/{spec_dir_runner.rb → resources/spec_dir_runner.rb} +5 -3
  14. data/lib/js_spec/{spec_file_runner.rb → resources/spec_file_runner.rb} +4 -2
  15. data/lib/js_spec/{spec_runner.rb → resources/spec_runner.rb} +3 -1
  16. data/lib/js_spec/resources/suite.rb +24 -0
  17. data/lib/js_spec/resources/suite_finish.rb +20 -0
  18. data/lib/js_spec/resources/web_root.rb +34 -0
  19. data/lib/js_spec/server.rb +16 -6
  20. data/lib/js_spec.rb +16 -7
  21. data/spec/{functional_spec_suite.rb → functional_suite.rb} +2 -2
  22. data/spec/spec_suite.rb +2 -2
  23. data/spec/unit/rails_server_spec.rb +44 -0
  24. data/spec/unit/{dir_spec.rb → resources/dir_spec.rb} +10 -8
  25. data/spec/unit/{file_spec.rb → resources/file_spec.rb} +12 -6
  26. data/spec/unit/resources/runner_spec.rb +24 -0
  27. data/spec/unit/resources/runners/firefox_runner_spec.rb +87 -0
  28. data/spec/unit/{spec_dir_runner_spec.rb → resources/spec_dir_runner_spec.rb} +5 -3
  29. data/spec/unit/resources/spec_file_runner_spec.rb +20 -0
  30. data/spec/unit/resources/suite_finish_spec.rb +42 -0
  31. data/spec/unit/resources/suite_spec.rb +44 -0
  32. data/spec/unit/resources/web_root_spec.rb +55 -0
  33. data/spec/unit/server_spec.rb +75 -14
  34. data/spec/unit/unit_spec_helper.rb +9 -8
  35. data/spec/{unit_spec_suite.rb → unit_suite.rb} +2 -2
  36. metadata +37 -28
  37. data/lib/js_spec/suite_result.rb +0 -11
  38. data/lib/js_spec/web_root.rb +0 -18
  39. data/spec/unit/spec_file_runner_spec.rb +0 -18
  40. data/spec/unit/suite_result_spec.rb +0 -31
  41. data/spec/unit/web_root_spec.rb +0 -39
data/lib/js_spec.rb CHANGED
@@ -1,13 +1,22 @@
1
1
  require "rubygems"
2
2
  require "rack"
3
3
  require "mongrel"
4
+ require "fileutils"
5
+ require "tmpdir"
6
+ require "timeout"
7
+ require "uuid"
4
8
 
5
9
  dir = File.dirname(__FILE__)
10
+ require "#{dir}/js_spec/resources/runners"
11
+ require "#{dir}/js_spec/resources/runners/firefox_runner"
12
+
6
13
  require "#{dir}/js_spec/server"
7
- require "#{dir}/js_spec/spec_runner"
8
- require "#{dir}/js_spec/spec_file_runner"
9
- require "#{dir}/js_spec/spec_dir_runner"
10
- require "#{dir}/js_spec/file"
11
- require "#{dir}/js_spec/dir"
12
- require "#{dir}/js_spec/web_root"
13
- require "#{dir}/js_spec/suite_result"
14
+ require "#{dir}/js_spec/rails_server"
15
+ require "#{dir}/js_spec/resources/spec_runner"
16
+ require "#{dir}/js_spec/resources/spec_file_runner"
17
+ require "#{dir}/js_spec/resources/spec_dir_runner"
18
+ require "#{dir}/js_spec/resources/file"
19
+ require "#{dir}/js_spec/resources/dir"
20
+ require "#{dir}/js_spec/resources/web_root"
21
+ require "#{dir}/js_spec/resources/suite"
22
+ require "#{dir}/js_spec/resources/suite_finish"
@@ -1,4 +1,4 @@
1
- class JsSpecFunctionalSuite
1
+ class FunctionalSuite
2
2
  def run
3
3
  dir = File.dirname(__FILE__)
4
4
  Dir["#{dir}/functional/**/*_spec.rb"].each do |file|
@@ -7,4 +7,4 @@ class JsSpecFunctionalSuite
7
7
  end
8
8
  end
9
9
 
10
- JsSpecFunctionalSuite.new.run
10
+ FunctionalSuite.new.run
data/spec/spec_suite.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  dir = File.dirname(__FILE__)
2
- raise "Failure" unless system(%Q|ruby #{dir}/unit_spec_suite.rb|)
3
- raise "Failure" unless system(%Q|ruby #{dir}/functional_spec_suite.rb|)
2
+ raise "Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
3
+ raise "Failure" unless system(%Q|ruby #{dir}/functional_suite.rb|)
@@ -0,0 +1,44 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/unit_spec_helper")
2
+
3
+ module JsSpec
4
+ describe RailsServer do
5
+ it "subclasses Server" do
6
+ RailsServer.superclass.should == Server
7
+ end
8
+
9
+ describe ".run" do
10
+ attr_reader :rails_root
11
+ before do
12
+ @rails_root = "/rails/root"
13
+ Server.instance = nil
14
+ end
15
+
16
+ it "initializes the RailsServer and runs the Mongrel Handler and sets Server.instance to the RailsServer instance" do
17
+ host = Server::DEFAULT_HOST
18
+ port = Server::DEFAULT_PORT
19
+ server_instance = Object.new
20
+ mock.proxy(RailsServer).new(
21
+ rails_root,
22
+ host,
23
+ port
24
+ ) do |new_instance|
25
+ server_instance
26
+ end
27
+ mock(Rack::Handler::Mongrel).run(server_instance, {:Host => host, :Port => port})
28
+
29
+ RailsServer.run(rails_root)
30
+ Server.instance.should == server_instance
31
+ end
32
+ end
33
+
34
+ describe "#initialize" do
35
+ it "sets the server paths based on the passed in rails root" do
36
+ rails_root = "/rails/root"
37
+ server = RailsServer.new(rails_root)
38
+ server.spec_root_path.should == "#{rails_root}/spec/javascripts"
39
+ server.implementation_root_path.should == "#{rails_root}/public/javascripts"
40
+ server.public_path.should == "#{rails_root}/public"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,18 +1,19 @@
1
- require File.expand_path("#{File.dirname(__FILE__)}/unit_spec_helper")
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
2
 
3
3
  module JsSpec
4
- describe Dir do
4
+ module Resources
5
+ describe Dir do
5
6
  attr_reader :dir, :absolute_path, :relative_path
6
7
 
7
8
  describe "in core dir" do
8
9
  before do
9
10
  @absolute_path = core_path
10
11
  @relative_path = "/core"
11
- @dir = JsSpec::Dir.new(absolute_path, relative_path)
12
+ @dir = Resources::Dir.new(absolute_path, relative_path)
12
13
  end
13
14
 
14
15
  describe "#locate when passed a name of a real file" do
15
- it "returns a JsSpec::File representing it" do
16
+ it "returns a Resources::File representing it" do
16
17
  file = dir.locate("JSSpec.css")
17
18
  file.relative_path.should == "/core/JSSpec.css"
18
19
  file.absolute_path.should == "#{core_path}/JSSpec.css"
@@ -24,7 +25,7 @@ module JsSpec
24
25
  before do
25
26
  @absolute_path = spec_root_path
26
27
  @relative_path = "/specs"
27
- @dir = JsSpec::Dir.new(absolute_path, relative_path)
28
+ @dir = Resources::Dir.new(absolute_path, relative_path)
28
29
  end
29
30
 
30
31
  it "has an absolute path" do
@@ -36,7 +37,7 @@ module JsSpec
36
37
  end
37
38
 
38
39
  describe "#locate when passed the name with an extension" do
39
- it "when file exists, returns a JsSpec::File representing it" do
40
+ it "when file exists, returns a Resources::File representing it" do
40
41
  file = dir.locate("failing_spec.js")
41
42
  file.relative_path.should == "/specs/failing_spec.js"
42
43
  file.absolute_path.should == "#{spec_root_path}/failing_spec.js"
@@ -56,7 +57,7 @@ module JsSpec
56
57
 
57
58
  it "when name corresponds to a subdirectory, returns a DirectoryRunner for the directory" do
58
59
  subdir = dir.locate("foo")
59
- subdir.should be_an_instance_of(JsSpec::Dir)
60
+ subdir.should be_an_instance_of(Resources::Dir)
60
61
  subdir.should == spec_dir("/foo")
61
62
  end
62
63
 
@@ -76,7 +77,8 @@ module JsSpec
76
77
  globbed_files.should contain_spec_file_with_correct_paths("/foo/failing_spec.js")
77
78
  globbed_files.should contain_spec_file_with_correct_paths("/foo/passing_spec.js")
78
79
  end
79
- end
80
+ end
80
81
  end
81
82
  end
83
+ end
82
84
  end
@@ -1,11 +1,12 @@
1
- require File.expand_path("#{File.dirname(__FILE__)}/unit_spec_helper")
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
2
 
3
3
  module JsSpec
4
- describe File do
4
+ module Resources
5
+ describe File do
5
6
  attr_reader :file
6
7
 
7
8
  before do
8
- @file = JsSpec::File.new(absolute_path, relative_path)
9
+ @file = Resources::File.new(absolute_path, relative_path)
9
10
  end
10
11
 
11
12
  def absolute_path
@@ -66,13 +67,18 @@ module JsSpec
66
67
 
67
68
  describe "==" do
68
69
  it "returns true when passed a file with the same absolute and relative paths" do
69
- file.should == JsSpec::File.new(absolute_path, relative_path)
70
+ file.should == Resources::File.new(absolute_path, relative_path)
70
71
  end
71
72
 
72
73
  it "returns false when passed a file with a different absolute or relative path" do
73
- file.should_not == JsSpec::File.new(absolute_path, "bogus")
74
- file.should_not == JsSpec::File.new("bogus", relative_path)
74
+ file.should_not == Resources::File.new(absolute_path, "bogus")
75
+ file.should_not == Resources::File.new("bogus", relative_path)
76
+ end
77
+
78
+ it "when passed a Dir, returns false because File is not a Dir" do
79
+ file.should_not == Resources::Dir.new(absolute_path, relative_path)
75
80
  end
76
81
  end
77
82
  end
83
+ end
78
84
  end
@@ -0,0 +1,24 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe Runners do
6
+ attr_reader :runner
7
+ before do
8
+ @runner = Runners.new
9
+ end
10
+
11
+ describe "#locate" do
12
+ it "when passed 'firefox', returns a FirefoxRunner" do
13
+ runner.locate('firefox').should be_instance_of(Runners::FirefoxRunner)
14
+ end
15
+
16
+ it "when not passed 'firefox', raises an error" do
17
+ lambda do
18
+ runner.locate('invalid')
19
+ end.should raise_error
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,87 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe Runners::FirefoxRunner do
6
+ attr_reader :runner
7
+ before do
8
+ @runner = Runners::FirefoxRunner.new
9
+ end
10
+
11
+ describe "#post" do
12
+ attr_reader :firefox_profile_path
13
+ before do
14
+ dir = ::File.dirname(__FILE__)
15
+ @firefox_profile_path = ::File.expand_path("#{dir}/../../../../resources/firefox")
16
+ ::File.should be_directory(firefox_profile_path)
17
+ end
18
+
19
+ it "returns ''" do
20
+ guid = nil
21
+ stub.proxy(UUID).new {|guid| guid = guid}
22
+ stub(runner).system {true}
23
+ stub(runner).sleep(0.5)
24
+ stub(runner).sleep {Kernel.sleep}
25
+
26
+ post_return_value = nil
27
+ Thread.start do
28
+ post_return_value = runner.post
29
+ end
30
+ wait_for do
31
+ Runners::FirefoxRunner.threads[guid]
32
+ end
33
+ Runners::FirefoxRunner.resume(guid, 'foobar')
34
+
35
+ wait_for do
36
+ post_return_value == 'foobar'
37
+ end
38
+ end
39
+
40
+ def wait_for(timeout=5)
41
+ Timeout.timeout(timeout) do
42
+ loop do
43
+ break if yield
44
+ end
45
+ end
46
+ end
47
+
48
+ it "copies the firefox profile files to a tmp directory " <<
49
+ "and creates a profile " <<
50
+ "and waits for profile to be created " <<
51
+ "and starts firefox" do
52
+ stub(runner).sleep
53
+
54
+ mock(runner).system("cp -R #{firefox_profile_path} #{runner.profile_dir}").ordered {true}
55
+ mock(runner).system("firefox -profile #{runner.profile_dir} -chrome chrome://killff/content/kill.html").ordered {true}
56
+ mock(::File).exists?("#{runner.profile_dir}/parent.lock").ordered {false}
57
+ mock(runner).sleep(0.5).ordered
58
+ mock(::File).exists?("#{runner.profile_dir}/parent.lock").ordered {false}
59
+ mock(runner).system(Regexp.new("firefox -profile #{runner.profile_dir} http://localhost:8080/specs")).ordered {true}
60
+ stub(runner).callcc
61
+ runner.post
62
+ end
63
+
64
+ it "calls #copy_profile_files, #create_profile, #wait_for_full_profile_to_be_created, and #start_browser" do
65
+ stub(runner).system {true}
66
+ stub(runner).sleep
67
+ stub(runner).callcc
68
+
69
+ mock.proxy(runner).copy_profile_files.ordered
70
+ mock.proxy(runner).create_profile.ordered
71
+ mock.proxy(runner).wait_for_full_profile_to_be_created.ordered
72
+ mock.proxy(runner).start_browser(is_a(String)).ordered
73
+
74
+ runner.post
75
+ end
76
+ end
77
+
78
+ describe "#start_browser" do
79
+ it "starts a firefox browser in a thread" do
80
+ mock(Thread).start.yields
81
+ mock(runner).system("firefox -profile #{runner.profile_dir} http://localhost:8080/specs?guid=foobar").ordered {true}
82
+ runner.__send__(:start_browser, "foobar")
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,14 +1,15 @@
1
- require File.expand_path("#{File.dirname(__FILE__)}/unit_spec_helper")
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
2
 
3
3
  module JsSpec
4
- describe SpecDirRunner do
4
+ module Resources
5
+ describe SpecDirRunner do
5
6
  attr_reader :dir, :runner
6
7
 
7
8
  before do
8
9
  @dir = Dir.new(spec_root_path, '/specs')
9
10
  @runner = SpecDirRunner.new(dir)
10
11
  end
11
-
12
+
12
13
  describe "#spec_files" do
13
14
  it "returns a File for each *_spec.js file in the directory" do
14
15
  spec_files = runner.spec_files
@@ -38,4 +39,5 @@ module JsSpec
38
39
  end
39
40
  end
40
41
  end
42
+ end
41
43
  end
@@ -0,0 +1,20 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe SpecFileRunner, "#spec_files" do
6
+ attr_reader :absolute_path, :relative_path, :file, :runner
7
+
8
+ before do
9
+ @absolute_path = "#{spec_root_path}/failing_spec.js"
10
+ @relative_path = "/specs/failing_spec.js"
11
+ @file = File.new(absolute_path, relative_path)
12
+ @runner = SpecFileRunner.new(file)
13
+ end
14
+
15
+ it "returns the single File to run in an Array" do
16
+ runner.spec_files.should == [file]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe SuiteFinish do
6
+ attr_reader :stdout, :suite_finish, :suite
7
+ before do
8
+ @stdout = StringIO.new
9
+ SuiteFinish.const_set(:STDOUT, stdout)
10
+ @suite = Suite.new('foobar')
11
+ @suite_finish = SuiteFinish.new(suite)
12
+ end
13
+
14
+ after do
15
+ SuiteFinish.__send__(:remove_const, :STDOUT)
16
+ end
17
+
18
+ describe ".post" do
19
+ describe "when the request has no guid" do
20
+ it "writes the body of the request to stdout" do
21
+ body = "The text in the POST body"
22
+ request = Rack::Request.new({'rack.input' => StringIO.new("text=#{body}")})
23
+ request.body.string.should == "text=#{body}"
24
+ stub.proxy(Server).request {request}
25
+
26
+ suite_finish.post
27
+ stdout.string.should == "#{body}\n"
28
+ end
29
+
30
+ it "returns an empty string" do
31
+ body = "The text in the POST body"
32
+ request = Rack::Request.new({'rack.input' => StringIO.new("text=#{body}")})
33
+ request.body.string.should == "text=#{body}"
34
+ stub.proxy(Server).request {request}
35
+
36
+ suite_finish.post.should == ""
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe Suite do
6
+ attr_reader :stdout
7
+ before do
8
+ @stdout = StringIO.new
9
+ Suite.const_set(:STDOUT, stdout)
10
+ end
11
+
12
+ after do
13
+ Suite.__send__(:remove_const, :STDOUT)
14
+ end
15
+
16
+ describe ".locate" do
17
+ it "when passed an identifier, returns an instance of Suite with the identifier" do
18
+ instance = Suite.locate('foobar')
19
+ instance.class.should == Suite
20
+ instance.id.should == 'foobar'
21
+ end
22
+ end
23
+
24
+ describe "#locate" do
25
+ attr_reader :suite
26
+ before do
27
+ @suite = Suite.new('foobar')
28
+ end
29
+
30
+ it "when passed 'finish', returns a SuiteFinish that has access to the suite" do
31
+ suite_finish = suite.locate('finish')
32
+ suite_finish.class.should == SuiteFinish
33
+ suite_finish.suite.should == suite
34
+ end
35
+
36
+ it "when not passed 'finish', raises ArgumentError" do
37
+ lambda do
38
+ suite.locate('invalid')
39
+ end.should raise_error(ArgumentError, "Invalid path: invalid")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsSpec
4
+ module Resources
5
+ describe WebRoot do
6
+ attr_reader :web_root
7
+ before(:each) do
8
+ @web_root = WebRoot.new(public_path)
9
+ end
10
+
11
+ describe "#locate" do
12
+ it "when passed 'specs', returns a SpecDirRunner representing the specs" do
13
+ runner = web_root.locate('specs')
14
+ runner.should == spec_dir
15
+ end
16
+
17
+ it "when passed 'core', returns a Dir representing the JsSpec core directory" do
18
+ runner = web_root.locate('core')
19
+ runner.should == Resources::Dir.new(JsSpec::Server.core_path, '/core')
20
+ end
21
+
22
+ it "when passed 'implementations', returns a Dir representing the javascript implementations directory" do
23
+ runner = web_root.locate('implementations')
24
+ runner.should == Resources::Dir.new(JsSpec::Server.implementation_root_path, '/implementations')
25
+ end
26
+
27
+ it "when passed 'results', returns a Suite" do
28
+ runner = web_root.locate('suites')
29
+ runner.should == Resources::Suite
30
+ end
31
+
32
+ it "when passed 'runners', returns a Runner" do
33
+ runner = web_root.locate('runners')
34
+ runner.should be_instance_of(Resources::Runners)
35
+ end
36
+
37
+ it "when passed a directory that is in the public_path, returns a Dir representing that directory" do
38
+ runner = web_root.locate('stylesheets')
39
+ runner.should == Resources::Dir.new("#{JsSpec::Server.public_path}/stylesheets", '/stylesheets')
40
+ end
41
+
42
+ it "when passed a file that is in the public_path, returns a File representing that file" do
43
+ runner = web_root.locate('robots.txt')
44
+ runner.should == Resources::File.new("#{JsSpec::Server.public_path}/robots.txt", '/robots.txt')
45
+ end
46
+
47
+ it "when not passed 'core' or 'specs', raises an error" do
48
+ lambda do
49
+ web_root.locate('invalid')
50
+ end.should raise_error
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -29,6 +29,17 @@ module JsSpec
29
29
  result = get("/core/JSSpec.js").body
30
30
  result.should == ::File.read("#{Server.core_path}/JSSpec.js")
31
31
  end
32
+
33
+ specify "'/stylesheets/example.css', returns the contents of the file" do
34
+ result = get("/stylesheets/example.css").body
35
+ result.should == ::File.read("#{Server.public_path}/stylesheets/example.css")
36
+ end
37
+
38
+ specify "'/invalid/path', shows the full invalid path in the error message" do
39
+ lambda do
40
+ get("/invalid/path")
41
+ end.should raise_error(Exception, Regexp.new("/invalid/path"))
42
+ end
32
43
  end
33
44
 
34
45
  describe ".run" do
@@ -42,36 +53,48 @@ module JsSpec
42
53
  host = Server::DEFAULT_HOST
43
54
  port = Server::DEFAULT_PORT
44
55
 
45
- mock.proxy(Server).new(spec_root_path, implementation_root_path, host, port) do
56
+ mock.proxy(Server).new(spec_root_path, implementation_root_path, public_path, host, port) do
46
57
  server_instance
47
58
  end
48
59
  mock(Rack::Handler::Mongrel).run(server_instance, {:Host => host, :Port => port})
49
60
 
50
- Server.run(spec_root_path, implementation_root_path)
61
+ Server.run(spec_root_path, implementation_root_path, public_path)
51
62
  end
52
63
 
53
64
  it "when passed a custom host and port, sets the host and port to the passed in value" do
54
65
  host = 'foobar.com'
55
66
  port = 80
56
67
 
57
- mock.proxy(Server).new(spec_root_path, implementation_root_path, host, port) do
68
+ mock.proxy(Server).new(spec_root_path, implementation_root_path, public_path, host, port) do
58
69
  server_instance
59
70
  end
60
71
  mock(Rack::Handler::Mongrel).run(server_instance, {:Host => host, :Port => port})
61
72
 
62
- Server.run(spec_root_path, implementation_root_path, {:Host => host, :Port => port})
73
+ Server.run(spec_root_path, implementation_root_path, public_path, {:Host => host, :Port => port})
74
+ end
75
+ end
76
+
77
+ describe ".default_url" do
78
+ it "returns the default host and port" do
79
+ Server.default_url.should == "http://#{Server::DEFAULT_HOST}:#{Server::DEFAULT_PORT}"
63
80
  end
64
81
  end
65
82
 
66
83
  describe ".spec_root" do
67
84
  it "returns the Dir " do
68
- Server.spec_root_path.should == ::File.expand_path(spec_root_path)
85
+ Server.spec_root_path.should == spec_root_path
69
86
  end
70
87
  end
71
88
 
72
89
  describe ".spec_root_path" do
73
90
  it "returns the absolute path of the specs root directory" do
74
- Server.spec_root_path.should == ::File.expand_path(spec_root_path)
91
+ Server.spec_root_path.should == spec_root_path
92
+ end
93
+ end
94
+
95
+ describe ".public_path" do
96
+ it "returns the expanded path of the public path" do
97
+ Server.public_path.should == public_path
75
98
  end
76
99
  end
77
100
 
@@ -85,14 +108,14 @@ module JsSpec
85
108
  describe ".implementation_root_path" do
86
109
  it "returns the expanded path to the JsSpec implementations directory" do
87
110
  dir = ::File.dirname(__FILE__)
88
- Server.implementation_root_path.should == ::File.expand_path(implementation_root_path)
111
+ Server.implementation_root_path.should == implementation_root_path
89
112
  end
90
113
  end
91
114
 
92
115
  describe ".request" do
93
116
  it "returns request in progress for the thread" do
94
117
  the_request = nil
95
- stub.instance_of(WebRoot).locate('somedir') do
118
+ stub.instance_of(Resources::WebRoot).locate('somedir') do
96
119
  the_request = JsSpec::Server.request
97
120
  Thread.current[:request].should == the_request
98
121
  thread2 = Thread.new do
@@ -120,7 +143,7 @@ module JsSpec
120
143
  describe ".response" do
121
144
  it "returns response in progress" do
122
145
  the_response = nil
123
- stub.instance_of(WebRoot).locate('somedir') do
146
+ stub.instance_of(Resources::WebRoot).locate('somedir') do
124
147
  the_response = JsSpec::Server.response
125
148
  Thread.current[:response].should == the_response
126
149
  thread2 = Thread.new do
@@ -145,11 +168,49 @@ module JsSpec
145
168
  end
146
169
  end
147
170
 
148
- describe "#initialize" do
149
- it "expands relative paths for #spec_root_path and #implementation_root_path" do
150
- server = Server.new("foo", "bar")
151
- server.spec_root_path.should == ::File.expand_path("foo")
152
- server.implementation_root_path.should == ::File.expand_path("bar")
171
+ describe "#call" do
172
+ it "when resource responds with a string, sets the string as the response.body" do
173
+ somedir_resource = Object.new
174
+ stub.instance_of(Resources::WebRoot).locate('somedir') do
175
+ somedir_resource
176
+ end
177
+
178
+ def somedir_resource.get
179
+ "Somedir String"
180
+ end
181
+ response = get('/somedir')
182
+ response.body.should == "Somedir String"
183
+ end
184
+
185
+ describe "when there is an error" do
186
+ attr_reader :top_line_of_backtrace
187
+ before do
188
+ @top_line_of_backtrace = __LINE__ + 2
189
+ stub.instance_of(Resources::WebRoot).locate('somedir') do
190
+ raise "Foobar"
191
+ end
192
+ end
193
+
194
+ it "shows the full request path in the error message" do
195
+ lambda do
196
+ get('/somedir')
197
+ end.should raise_error(Exception, Regexp.new("/somedir"))
198
+ end
199
+
200
+ it "uses the backtrace from where the original error was raised" do
201
+ no_error = true
202
+ begin
203
+ get('/somedir')
204
+ rescue Exception => e
205
+ no_error = false
206
+ top_of_backtrace = e.backtrace.first.split(":")
207
+ backtrace_file = ::File.expand_path(top_of_backtrace[0])
208
+ backtrace_line = Integer(top_of_backtrace[1])
209
+ backtrace_file.should == __FILE__
210
+ backtrace_line.should == top_line_of_backtrace
211
+ end
212
+ raise "There should have been an error" if no_error
213
+ end
153
214
  end
154
215
  end
155
216
  end