js_spec 0.1.0 → 0.2.0

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.
Files changed (48) hide show
  1. data/CHANGES +6 -0
  2. data/README +23 -1
  3. data/Rakefile +5 -3
  4. data/bin/js_spec +1 -5
  5. data/bin/js_spec_server +0 -0
  6. data/core/JSSpecExtensions.js +70 -25
  7. data/core/jquery.js +2992 -0
  8. data/init.rb +0 -0
  9. data/lib/js_spec/client.rb +50 -0
  10. data/lib/js_spec/rack/response.rb +5 -0
  11. data/lib/js_spec/rails_server.rb +3 -3
  12. data/lib/js_spec/resources/dir.rb +43 -43
  13. data/lib/js_spec/resources/file.rb +16 -16
  14. data/lib/js_spec/resources/runners/firefox1_runner.rb +8 -0
  15. data/lib/js_spec/resources/runners/firefox_runner.rb +49 -72
  16. data/lib/js_spec/resources/runners.rb +6 -7
  17. data/lib/js_spec/resources/spec_dir_runner.rb +7 -7
  18. data/lib/js_spec/resources/spec_file_runner.rb +7 -7
  19. data/lib/js_spec/resources/spec_runner.rb +16 -11
  20. data/lib/js_spec/resources/suite.rb +14 -14
  21. data/lib/js_spec/resources/suite_finish.rb +12 -12
  22. data/lib/js_spec/server.rb +29 -17
  23. data/lib/js_spec/thin/backends/js_spec_server.rb +9 -0
  24. data/lib/js_spec/thin/js_spec_connection.rb +43 -0
  25. data/lib/js_spec.rb +14 -2
  26. data/spec/integration/integration_spec.rb +14 -0
  27. data/spec/integration/integration_spec_helper.rb +52 -0
  28. data/spec/integration_suite.rb +10 -0
  29. data/spec/spec_suite.rb +1 -0
  30. data/spec/unit/js_spec/client_spec.rb +137 -0
  31. data/spec/unit/{rails_server_spec.rb → js_spec/rails_server_spec.rb} +8 -7
  32. data/spec/unit/{resources → js_spec/resources}/dir_spec.rb +1 -1
  33. data/spec/unit/{resources → js_spec/resources}/file_spec.rb +9 -6
  34. data/spec/unit/js_spec/resources/runner_spec.rb +24 -0
  35. data/spec/unit/js_spec/resources/runners/firefox_runner_spec.rb +152 -0
  36. data/spec/unit/js_spec/resources/spec_dir_runner_spec.rb +48 -0
  37. data/spec/unit/{resources → js_spec/resources}/spec_file_runner_spec.rb +1 -1
  38. data/spec/unit/{resources → js_spec/resources}/suite_finish_spec.rb +5 -5
  39. data/spec/unit/{resources → js_spec/resources}/suite_spec.rb +1 -1
  40. data/spec/unit/{resources → js_spec/resources}/web_root_spec.rb +1 -1
  41. data/spec/unit/{server_spec.rb → js_spec/server_spec.rb} +29 -92
  42. data/spec/unit/rack/response_spec.rb +30 -0
  43. data/spec/unit/thin/js_spec_connection_spec.rb +50 -0
  44. data/spec/unit/unit_spec_helper.rb +40 -5
  45. metadata +107 -60
  46. data/spec/unit/resources/runner_spec.rb +0 -24
  47. data/spec/unit/resources/runners/firefox_runner_spec.rb +0 -87
  48. data/spec/unit/resources/spec_dir_runner_spec.rb +0 -43
data/init.rb ADDED
File without changes
@@ -0,0 +1,50 @@
1
+ module JsSpec
2
+ class Client
3
+ class << self
4
+ def run(params={})
5
+ data = []
6
+ data << "selenium_host=#{CGI.escape(params[:selenium_host] || 'localhost')}"
7
+ data << "selenium_port=#{CGI.escape((params[:selenium_port] || 4444).to_s)}"
8
+ data << "spec_url=#{CGI.escape(params[:spec_url])}" if params[:spec_url]
9
+ response = Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) do |http|
10
+ http.post('/runners/firefox', data.join("&"))
11
+ end
12
+
13
+ body = response.body
14
+ if body.empty?
15
+ puts "SUCCESS"
16
+ return true
17
+ else
18
+ puts "FAILURE"
19
+ puts body
20
+ return false
21
+ end
22
+ end
23
+
24
+ def run_argv(argv)
25
+ params = {}
26
+ parser = OptionParser.new do |o|
27
+ o.banner = "JsSpec Runner"
28
+ o.banner << "\nUsage: #{$0} [options] [-- untouched arguments]"
29
+
30
+ o.on
31
+ o.on('-h', '--selenium_host=SELENIUM_HOST', "The host name of the Selenium Server relative to where this file is executed") do |host|
32
+ params[:selenium_host] = host
33
+ end
34
+
35
+ o.on('-p', '--selenium_port=SELENIUM_PORT', "The port of the Selenium Server relative to where this file is executed") do |port|
36
+ params[:selenium_port] = port
37
+ end
38
+
39
+ o.on('-u', '--spec_url=SPEC_URL', "The url of the js spec server, relative to the browsers running via the Selenium Server") do |spec_url|
40
+ params[:spec_url] = spec_url
41
+ end
42
+
43
+ o.on_tail
44
+ end
45
+ parser.order!(argv)
46
+ run params
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ Rack::Response.class_eval do
2
+ def ready?
3
+ status ? true : false
4
+ end
5
+ end
@@ -2,10 +2,10 @@ module JsSpec
2
2
  class RailsServer < Server
3
3
  class << self
4
4
  def run(rails_root, server_options = {})
5
- server_options[:Host] ||= Server::DEFAULT_HOST
6
- server_options[:Port] ||= Server::DEFAULT_PORT
5
+ server_options[:Host] ||= DEFAULT_HOST
6
+ server_options[:Port] ||= DEFAULT_PORT
7
7
  Server.instance = new(rails_root, server_options[:Host], server_options[:Port])
8
- Rack::Handler::Mongrel.run(Server.instance, server_options)
8
+ Server.instance.run server_options
9
9
  end
10
10
  end
11
11
 
@@ -1,60 +1,60 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class Dir < File
4
- def locate(name)
5
- if file = file(name)
6
- file
7
- else
8
- locate_spec_runner(name)
4
+ def locate(name)
5
+ if file = file(name)
6
+ file
7
+ else
8
+ locate_spec_runner(name)
9
+ end
9
10
  end
10
- end
11
11
 
12
- def get
13
- SpecDirRunner.new(self).get
14
- end
12
+ def get(request, response)
13
+ SpecDirRunner.new(self).get(request, response)
14
+ end
15
15
 
16
- def glob(pattern)
17
- expanded_pattern = absolute_path + pattern
18
- ::Dir.glob(expanded_pattern).map do |absolute_globbed_path|
19
- relative_globbed_path = absolute_globbed_path.gsub(absolute_path, relative_path)
20
- File.new(absolute_globbed_path, relative_globbed_path)
16
+ def glob(pattern)
17
+ expanded_pattern = absolute_path + pattern
18
+ ::Dir.glob(expanded_pattern).map do |absolute_globbed_path|
19
+ relative_globbed_path = absolute_globbed_path.gsub(absolute_path, relative_path)
20
+ File.new(absolute_globbed_path, relative_globbed_path)
21
+ end
21
22
  end
22
- end
23
23
 
24
- protected
25
- def determine_child_paths(name)
26
- absolute_child_path = "#{absolute_path}/#{name}"
27
- relative_child_path = "#{relative_path}/#{name}"
28
- [absolute_child_path, relative_child_path]
29
- end
24
+ protected
25
+ def determine_child_paths(name)
26
+ absolute_child_path = "#{absolute_path}/#{name}"
27
+ relative_child_path = "#{relative_path}/#{name}"
28
+ [absolute_child_path, relative_child_path]
29
+ end
30
30
 
31
- def locate_spec_runner(name)
32
- if subdir = subdir(name)
33
- subdir
34
- elsif file = file(name + '.js')
35
- SpecFileRunner.new(file)
36
- else
37
- raise "No specs found at #{relative_path}/#{name}."
31
+ def locate_spec_runner(name)
32
+ if subdir = subdir(name)
33
+ subdir
34
+ elsif file = file(name + '.js')
35
+ SpecFileRunner.new(file)
36
+ else
37
+ raise "No specs found at #{relative_path}/#{name}."
38
+ end
38
39
  end
39
- end
40
40
 
41
- def file(name)
42
- absolute_file_path, relative_file_path = determine_child_paths(name)
43
- if ::File.exists?(absolute_file_path) && !::File.directory?(absolute_file_path)
44
- Resources::File.new(absolute_file_path, relative_file_path)
45
- else
46
- nil
41
+ def file(name)
42
+ absolute_file_path, relative_file_path = determine_child_paths(name)
43
+ if ::File.exists?(absolute_file_path) && !::File.directory?(absolute_file_path)
44
+ Resources::File.new(absolute_file_path, relative_file_path)
45
+ else
46
+ nil
47
+ end
47
48
  end
48
- end
49
49
 
50
- def subdir(name)
51
- absolute_dir_path, relative_dir_path = determine_child_paths(name)
52
- if ::File.directory?(absolute_dir_path)
53
- Resources::Dir.new(absolute_dir_path, relative_dir_path)
54
- else
55
- nil
50
+ def subdir(name)
51
+ absolute_dir_path, relative_dir_path = determine_child_paths(name)
52
+ if ::File.directory?(absolute_dir_path)
53
+ Resources::Dir.new(absolute_dir_path, relative_dir_path)
54
+ else
55
+ nil
56
+ end
56
57
  end
57
58
  end
58
59
  end
59
- end
60
60
  end
@@ -1,32 +1,32 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class File
4
- MIME_TYPES = {
4
+ MIME_TYPES = {
5
5
  '.js' => 'text/javascript',
6
6
  '.css' => 'text/css',
7
7
  '.png' => 'image/png',
8
8
  '.jpg' => 'image/jpeg',
9
9
  '.jpeg' => 'image/jpeg',
10
10
  '.gif' => 'image/gif',
11
- }
11
+ }
12
12
 
13
- attr_reader :absolute_path, :relative_path
13
+ attr_reader :absolute_path, :relative_path
14
14
 
15
- def initialize(absolute_path, relative_path)
16
- @absolute_path = absolute_path
17
- @relative_path = relative_path
18
- end
15
+ def initialize(absolute_path, relative_path)
16
+ @absolute_path = absolute_path
17
+ @relative_path = relative_path
18
+ end
19
19
 
20
- def get
21
- extension = ::File.extname(absolute_path)
22
- Server.response.headers['Content-Type'] = MIME_TYPES[extension] || 'text/html'
23
- ::File.read(absolute_path)
24
- end
20
+ def get(request, response)
21
+ extension = ::File.extname(absolute_path)
22
+ response.headers['Content-Type'] = MIME_TYPES[extension] || 'text/html'
23
+ response.body = ::File.read(absolute_path)
24
+ end
25
25
 
26
- def ==(other)
27
- return false unless other.class == self.class
28
- absolute_path == other.absolute_path && relative_path == other.relative_path
26
+ def ==(other)
27
+ return false unless other.class == self.class
28
+ absolute_path == other.absolute_path && relative_path == other.relative_path
29
+ end
29
30
  end
30
31
  end
31
- end
32
32
  end
@@ -0,0 +1,8 @@
1
+ module JsSpec
2
+ module Resources
3
+ class Runners
4
+ class Firefox1Runner < FirefoxRunner
5
+ end
6
+ end
7
+ end
8
+ end
@@ -1,90 +1,67 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class Runners
4
- class FirefoxRunner
5
- class << self
6
- def resume(guid, text)
7
- responses[guid] = text
8
- threads[guid].kill
9
- end
10
-
11
- def threads
12
- @threads ||= {}
13
- end
4
+ class FirefoxRunner
5
+ class << self
6
+ def resume(guid, text)
7
+ runner = instances.delete(guid)
8
+ runner.finalize(text)
9
+ end
14
10
 
15
- def response_value(guid)
16
- responses[guid]
17
- ensure
18
- responses.delete guid
19
- end
11
+ def register_instance(runner)
12
+ instances[runner.guid] = runner
13
+ end
20
14
 
21
- protected
22
- def responses
23
- @responses ||= {}
15
+ protected
16
+ def instances
17
+ @instances ||= {}
18
+ end
24
19
  end
25
- end
26
20
 
27
- include FileUtils
28
- attr_reader :profile_dir
29
-
30
- def initialize
31
- profile_base = "#{::Dir.tmpdir}/js_spec/firefox"
32
- mkdir_p profile_base
33
- @profile_dir = "#{profile_base}/#{Time.now.to_i}"
34
- end
35
-
36
- def post
37
- copy_profile_files
38
- create_profile
39
- wait_for_full_profile_to_be_created
40
-
41
- guid = UUID.new
42
- start_browser guid
43
- thread = Thread.start {sleep}
44
- self.class.threads[guid] = thread
45
- thread.join
46
-
47
- self.class.response_value guid
48
- end
21
+ include FileUtils
22
+ attr_reader :guid, :profile_dir, :request, :response, :connection, :driver
49
23
 
50
- protected
51
- def copy_profile_files
52
- dir = ::File.dirname(__FILE__)
53
- firefox_profile_path = ::File.expand_path("#{dir}/../../../../resources/firefox")
54
- system("cp -R #{firefox_profile_path} #{profile_dir}") || raise("Copying Firefox profile failed")
55
- end
56
-
57
- def create_profile
58
- system("firefox -profile #{profile_dir} -chrome chrome://killff/content/kill.html") || raise("Initializing profile failed")
59
- end
60
-
61
- def wait_for_full_profile_to_be_created
62
- Timeout.timeout(5) do
63
- wait_for_file_lock_to_go_away
24
+ def initialize(request, response)
25
+ profile_base = "#{::Dir.tmpdir}/js_spec/firefox"
26
+ mkdir_p profile_base
27
+ @profile_dir = "#{profile_base}/#{Time.now.to_i}"
28
+ @guid = UUID.new
29
+ @request = request
30
+ @response = response
31
+ @connection = Server.connection
64
32
  end
65
- end
66
33
 
67
- def start_browser(guid)
68
- Thread.start do
69
- system("firefox -profile #{profile_dir} http://localhost:8080/specs?guid=#{guid}") || raise("Starting Firefox failed")
34
+ def post(request, response)
35
+ FirefoxRunner.register_instance self
36
+ spec_url = (request && request['spec_url']) ? request['spec_url'] : spec_suite_url
37
+ parsed_spec_url = URI.parse(spec_url)
38
+ @driver = Selenium::SeleniumDriver.new(
39
+ request['selenium_host'] || 'localhost',
40
+ (request['selenium_port'] || 4444).to_i,
41
+ '*firefox',
42
+ "#{parsed_spec_url.scheme}://#{parsed_spec_url.host}:#{parsed_spec_url.port}"
43
+ )
44
+ driver.start
45
+ Thread.start do
46
+ url = "#{spec_url}?guid=#{guid}"
47
+ driver.open(url)
48
+ end
49
+ response.status = nil
70
50
  end
71
- end
72
51
 
73
- def wait_for_file_lock_to_go_away
74
- loop do
75
- return if lock_is_gone? && lock_remains_gone?
52
+ def finalize(text)
53
+ driver.stop
54
+ response.status = 200
55
+ response.body = text
56
+ connection.send_response(*response.finish)
76
57
  end
77
- end
78
58
 
79
- def lock_is_gone?
80
- !::File.exists?("#{profile_dir}/parent.lock")
81
- end
59
+ protected
82
60
 
83
- def lock_remains_gone?
84
- sleep 0.5
85
- lock_is_gone?
61
+ def spec_suite_url
62
+ "#{Server.root_url}/specs"
63
+ end
86
64
  end
87
65
  end
88
66
  end
89
- end
90
- end
67
+ end
@@ -1,16 +1,15 @@
1
1
  dir = File.dirname(__FILE__)
2
- require File.expand_path("#{dir}/runners/firefox_runner")
3
2
 
4
3
  module JsSpec
5
4
  module Resources
6
5
  class Runners
7
- def locate(name)
8
- if name == 'firefox'
9
- FirefoxRunner.new
10
- else
11
- raise "Invalid path #{name}"
6
+ def locate(name)
7
+ if name == 'firefox'
8
+ FirefoxRunner.new(Server.request, Server.response)
9
+ else
10
+ raise "Invalid path #{name}"
11
+ end
12
12
  end
13
13
  end
14
14
  end
15
- end
16
15
  end
@@ -1,15 +1,15 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class SpecDirRunner < SpecRunner
4
- attr_reader :dir
4
+ attr_reader :dir
5
5
 
6
- def initialize(dir)
7
- @dir = dir
8
- end
6
+ def initialize(dir)
7
+ @dir = dir
8
+ end
9
9
 
10
- def spec_files
11
- dir.glob("/**/*_spec.js")
10
+ def spec_files
11
+ dir.glob("/**/*_spec.js")
12
+ end
12
13
  end
13
14
  end
14
- end
15
15
  end
@@ -1,15 +1,15 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class SpecFileRunner < SpecRunner
4
- attr_reader :file
4
+ attr_reader :file
5
5
 
6
- def initialize(file)
7
- @file = file
8
- end
6
+ def initialize(file)
7
+ @file = file
8
+ end
9
9
 
10
- def spec_files
11
- [file]
10
+ def spec_files
11
+ [file]
12
+ end
12
13
  end
13
14
  end
14
- end
15
15
  end
@@ -1,8 +1,9 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class SpecRunner
4
- def get
5
- html = <<-HTML
4
+ def get(request, response)
5
+ guid = (request && request['guid']) || 'null';
6
+ html = <<-HTML
6
7
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
7
8
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko">
8
9
  <head>
@@ -11,19 +12,23 @@ module JsSpec
11
12
  <link rel="stylesheet" type="text/css" href="/core/JSSpec.css" />
12
13
  <script type="text/javascript" src="/core/diff_match_patch.js"></script>
13
14
  <script type="text/javascript" src="/core/JSSpec.js"></script>
15
+ <script type="text/javascript" src="/core/jquery.js"></script>
14
16
  <script type="text/javascript" src="/core/JSSpecExtensions.js"></script>
15
- HTML
16
- spec_files.each do |file|
17
- html << %{<script type="text/javascript" src="#{file.relative_path}"></script>\n}
18
- end
17
+ HTML
18
+ spec_files.each do |file|
19
+ html << %{<script type="text/javascript" src="#{file.relative_path}"></script>\n}
20
+ end
19
21
 
20
- html << <<-HTML
22
+ html << <<-HTML
23
+ <script type="text/javascript">
24
+ JSSpec.guid = '#{guid}';
25
+ </script>
21
26
  </head>
22
27
  <body></body>
23
28
  </html>
24
- HTML
25
- html.gsub(/^ /, "")
29
+ HTML
30
+ response.body = html.gsub(/^ /, "")
31
+ end
26
32
  end
27
33
  end
28
- end
29
- end
34
+ end
@@ -1,24 +1,24 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class Suite
4
- class << self
5
- def locate(id)
6
- new id
4
+ class << self
5
+ def locate(id)
6
+ new id
7
+ end
7
8
  end
8
- end
9
9
 
10
- attr_reader :id
11
- def initialize(id)
12
- @id = id
13
- end
10
+ attr_reader :id
11
+ def initialize(id)
12
+ @id = id
13
+ end
14
14
 
15
- def locate(name)
16
- if name == 'finish'
17
- SuiteFinish.new self
18
- else
19
- raise ArgumentError, "Invalid path: #{name}"
15
+ def locate(name)
16
+ if name == 'finish'
17
+ SuiteFinish.new self
18
+ else
19
+ raise ArgumentError, "Invalid path: #{name}"
20
+ end
20
21
  end
21
22
  end
22
23
  end
23
- end
24
24
  end
@@ -1,20 +1,20 @@
1
1
  module JsSpec
2
2
  module Resources
3
3
  class SuiteFinish
4
- attr_reader :suite
5
- def initialize(suite)
6
- @suite = suite
7
- end
4
+ attr_reader :suite
5
+ def initialize(suite)
6
+ @suite = suite
7
+ end
8
8
 
9
- def post
10
- guid = Server.request['guid']
11
- if guid
12
- Runners::FirefoxRunner.resume(guid, Server.request['text'])
13
- else
14
- STDOUT.puts Server.request['text']
9
+ def post(request, response)
10
+ guid = request['guid']
11
+ if guid
12
+ Runners::FirefoxRunner.resume(guid, request['text'])
13
+ else
14
+ STDOUT.puts request['text']
15
+ end
16
+ ""
15
17
  end
16
- ""
17
18
  end
18
19
  end
19
- end
20
20
  end
@@ -1,8 +1,5 @@
1
1
  module JsSpec
2
2
  class Server
3
- DEFAULT_HOST = "127.0.0.1"
4
- DEFAULT_PORT = 8080
5
-
6
3
  class << self
7
4
  attr_accessor :instance
8
5
 
@@ -10,19 +7,17 @@ module JsSpec
10
7
  server_options[:Host] ||= DEFAULT_HOST
11
8
  server_options[:Port] ||= DEFAULT_PORT
12
9
  @instance = new(spec_root_path, implementation_root_path, public_path, server_options[:Host], server_options[:Port])
13
- Rack::Handler::Mongrel.run(instance, server_options)
14
- end
15
-
16
- def default_url
17
- "http://#{DEFAULT_HOST}:#{DEFAULT_PORT}"
10
+ instance.run server_options
18
11
  end
19
12
 
20
13
  def spec_root_path; instance.spec_root_path; end
21
14
  def implementation_root_path; instance.implementation_root_path; end
22
15
  def public_path; instance.public_path; end
23
16
  def core_path; instance.core_path; end
17
+ def connection; instance.connection; end
24
18
  def request; instance.request; end
25
19
  def response; instance.response; end
20
+ def root_url; instance.root_url; end
26
21
  end
27
22
 
28
23
  attr_reader :host, :port, :spec_root_path, :implementation_root_path, :core_path, :public_path
@@ -36,21 +31,30 @@ module JsSpec
36
31
  @host = host
37
32
  @port = port
38
33
  end
39
-
34
+
35
+ def run(options)
36
+ ::Thin::Server.start(
37
+ ::Thin::Backends::JsSpecServer.new(options[:Host], options[:Port]),
38
+ options[:Port],
39
+ self
40
+ )
41
+ end
42
+
40
43
  def call(env)
44
+ self.connection = env['js_spec.connection']
41
45
  self.request = Rack::Request.new(env)
42
46
  self.response = Rack::Response.new
43
47
  method = request.request_method.downcase.to_sym
44
- response.body = get_resource.send(method)
48
+ get_resource(request).send(method, request, response)
45
49
  response.finish
46
50
  ensure
51
+ self.connection = nil
47
52
  self.request = nil
48
53
  self.response = nil
49
54
  end
50
-
51
- def run(path)
52
- system(%{firefox "http://#{host}:#{port}/#{path}"})
53
- Suite.new
55
+
56
+ def connection
57
+ Thread.current[:connection]
54
58
  end
55
59
 
56
60
  def request
@@ -60,8 +64,16 @@ module JsSpec
60
64
  def response
61
65
  Thread.current[:response]
62
66
  end
67
+
68
+ def root_url
69
+ "http://#{host}:#{port}"
70
+ end
63
71
 
64
72
  protected
73
+ def connection=(connection)
74
+ Thread.current[:connection] = connection
75
+ end
76
+
65
77
  def request=(request)
66
78
  Thread.current[:request] = request
67
79
  end
@@ -70,12 +82,12 @@ module JsSpec
70
82
  Thread.current[:response] = response
71
83
  end
72
84
 
73
- def path_parts
85
+ def path_parts(req)
74
86
  request.path_info.split('/').reject { |part| part == "" }
75
87
  end
76
88
 
77
- def get_resource
78
- path_parts.inject(Resources::WebRoot.new(public_path)) do |resource, child_resource_name|
89
+ def get_resource(request)
90
+ path_parts(request).inject(Resources::WebRoot.new(public_path)) do |resource, child_resource_name|
79
91
  resource.locate(child_resource_name)
80
92
  end
81
93
  rescue Exception => e