rack-sprockets 1.0.4 → 1.1.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 (38) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +47 -0
  4. data/README.rdoc +2 -2
  5. data/Rakefile +5 -60
  6. data/demos/yui_compressed/Gemfile +5 -0
  7. data/demos/yui_compressed/Gemfile.lock +19 -0
  8. data/demos/yui_compressed/REAME.rdoc +13 -0
  9. data/demos/yui_compressed/app.rb +17 -0
  10. data/demos/yui_compressed/app/javascripts/alert_one.js +4 -0
  11. data/demos/yui_compressed/app/javascripts/alert_two.js +4 -0
  12. data/demos/yui_compressed/app/javascripts/app.js +16 -0
  13. data/demos/yui_compressed/public/javascripts/app.js +1 -0
  14. data/demos/yui_compressed/public/javascripts/uncompressed_app.js +12 -0
  15. data/lib/rack/.rb +1 -0
  16. data/lib/rack/sprockets/request.rb +42 -24
  17. data/lib/rack/sprockets/source.rb +27 -27
  18. data/lib/rack/sprockets/version.rb +4 -12
  19. data/rack-sprockets.gemspec +29 -0
  20. data/test/app_helper.rb +25 -0
  21. data/test/config_test.rb +80 -0
  22. data/test/env.rb +9 -0
  23. data/test/fixtures/mock_options.rb +9 -0
  24. data/test/fixtures/sinatra/app.rb +9 -0
  25. data/test/fixtures/sinatra/app/javascripts/alert_one.js +2 -0
  26. data/test/fixtures/sinatra/app/javascripts/alert_two.js +2 -0
  27. data/test/fixtures/sinatra/app/javascripts/app.js +10 -0
  28. data/test/fixtures/sinatra/app/javascripts/app_compiled.js +12 -0
  29. data/test/fixtures/sinatra/app/javascripts/nested/dependency.js +2 -0
  30. data/test/fixtures/sinatra/app/javascripts/nested/thing.js +11 -0
  31. data/test/fixtures/sinatra/app/javascripts/nested/thing_compiled.js +14 -0
  32. data/test/helper.rb +80 -0
  33. data/test/options_test.rb +78 -0
  34. data/test/request_test.rb +141 -0
  35. data/test/response_test.rb +41 -0
  36. data/test/sinatra_test.rb +42 -0
  37. data/test/source_test.rb +163 -0
  38. metadata +103 -40
@@ -0,0 +1,5 @@
1
+ /pkg/
2
+ /doc/
3
+ /coverage/
4
+ *.log
5
+ *.bundle/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rack-sprockets.gemspec
4
+ gemspec
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-sprockets (1.0.4)
5
+ rack (~> 1.0)
6
+ sprockets (~> 1.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ json (1.5.1)
12
+ kelredd-useful (0.4.1)
13
+ json
14
+ leftright (0.9.0)
15
+ nokogiri (1.4.4)
16
+ rack (1.2.2)
17
+ rack-test (0.5.7)
18
+ rack (>= 1.0)
19
+ shoulda (2.11.3)
20
+ sinatra (1.2.1)
21
+ rack (~> 1.1)
22
+ tilt (>= 1.2.2, < 2.0)
23
+ sprockets (1.0.2)
24
+ test-belt (0.2.1)
25
+ kelredd-useful (~> 0.4.0)
26
+ leftright (~> 0.9.0)
27
+ shoulda (~> 2.11)
28
+ tilt (1.2.2)
29
+ webrat (0.7.3)
30
+ nokogiri (>= 1.2.0)
31
+ rack (>= 1.0)
32
+ rack-test (>= 0.5.3)
33
+ yui-compressor (0.9.4)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ bundler (~> 1.0)
40
+ rack (~> 1.0)
41
+ rack-sprockets!
42
+ rack-test (>= 0.5.3)
43
+ sinatra (>= 0.9.4)
44
+ sprockets (~> 1.0)
45
+ test-belt (= 0.2.1)
46
+ webrat (>= 0.6.0)
47
+ yui-compressor (>= 0.9.1)
@@ -60,10 +60,10 @@ These are similar to sprockets options and, where applicable, map directly to a
60
60
  - The path where static files are located. Maps to the `:asset_root` Sprockets option.
61
61
 
62
62
  * :*source* ["app/javascripts"]
63
- - The path where Sprockets source files are located. Notice this does not map to the `:source_files` Sprockets option. It is assumed that any requested resource found in `:source` be treated as a Sprockets source file.
63
+ - The root path where Sprockets source resources are located. Notice this does not map to the `:source_files` Sprockets option. It is assumed that any requested resource found in `:source` be treated as a Sprockets source file.
64
64
 
65
65
  * :*hosted_at* ["/javascripts"]
66
- - The public hosted HTTP path for static javascripts files.
66
+ - The public hosted HTTP path for static javascript files.
67
67
 
68
68
  * :*load_path* [["app/javascripts/", "vendor/javascripts/"]]
69
69
  - An ordered array of directory names to search for dependencies in. Maps to the `:load_path` Sprockets option.
data/Rakefile CHANGED
@@ -1,62 +1,7 @@
1
- require 'rubygems'
2
- require 'rake/gempackagetask'
3
- require 'rake/testtask'
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
4
3
 
5
- require File.expand_path('../lib/rack/sprockets/version', __FILE__)
4
+ require 'test_belt/rake_tasks'
5
+ TestBelt::RakeTasks.for :test
6
6
 
7
- spec = Gem::Specification.new do |s|
8
- s.name = 'rack-sprockets'
9
- s.version = RackSprockets::Version.to_s
10
- s.has_rdoc = true
11
- s.extra_rdoc_files = %w(README.rdoc)
12
- s.rdoc_options = %w(--main README.rdoc)
13
- s.summary = "Sprockets javascript preprocessing for Rack apps."
14
- s.author = 'Kelly Redding'
15
- s.email = 'kelly@kelredd.com'
16
- s.homepage = 'http://github.com/kelredd/rack-sprockets'
17
- s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib}/**/*")
18
- # s.executables = ['rack-sprockets']
19
-
20
- s.add_development_dependency("shoulda", [">= 2.10.0"])
21
- s.add_development_dependency("sinatra", [">= 0.9.4"])
22
- s.add_development_dependency("rack-test", [">= 0.5.3"])
23
- s.add_development_dependency("webrat", [">= 0.6.0"])
24
- s.add_development_dependency("yui-compressor", [">=0.9.1"])
25
-
26
- s.add_dependency("rack", [">= 0.4"])
27
- s.add_dependency("sprockets", [">= 1.0.0"])
28
- end
29
-
30
- Rake::GemPackageTask.new(spec) do |pkg|
31
- pkg.gem_spec = spec
32
- end
33
-
34
- Rake::TestTask.new do |t|
35
- t.libs << 'test'
36
- t.test_files = FileList["test/**/*_test.rb"]
37
- t.verbose = true
38
- end
39
-
40
- begin
41
- require 'rcov/rcovtask'
42
-
43
- Rcov::RcovTask.new(:coverage) do |t|
44
- t.libs = ['test']
45
- t.test_files = FileList["test/**/*_test.rb"]
46
- t.verbose = true
47
- t.rcov_opts = ['--text-report', "-x #{Gem.path}", '-x /Library/Ruby', '-x /usr/lib/ruby']
48
- end
49
-
50
- task :default => :coverage
51
-
52
- rescue LoadError
53
- warn "\n**** Install rcov (sudo gem install relevance-rcov) to get coverage stats ****\n"
54
- task :default => :test
55
- end
56
-
57
- desc 'Generate the gemspec to serve this gem'
58
- task :gemspec do
59
- file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
60
- File.open(file, 'w') {|f| f << spec.to_ruby }
61
- puts "Created gemspec: #{file}"
62
- end
7
+ task :default => :build
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'sinatra'
4
+ gem 'rack-sprockets', '~>1.0.4', :require => "rack/sprockets"
5
+ gem 'yui-compressor'
@@ -0,0 +1,19 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ rack (1.2.1)
5
+ rack-sprockets (1.0.4)
6
+ rack (>= 0.4)
7
+ sprockets (>= 1.0.0)
8
+ sinatra (1.0)
9
+ rack (>= 1.0)
10
+ sprockets (1.0.2)
11
+ yui-compressor (0.9.1)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ rack-sprockets (~> 1.0.4)
18
+ sinatra
19
+ yui-compressor
@@ -0,0 +1,13 @@
1
+ == YUI Compressor Rack Sprockets demo
2
+
3
+ This demo will use rack sprockets to define an /javascripts/app.js resource. To run and test this demo, do the following:
4
+
5
+ 1. Pull the latest rack-sprockets repo
6
+ 2. cd demos/yui_compressed
7
+ 3. bundle install
8
+ 4. ruby app.rb #starts up sinatra app on localhost:4567
9
+ 5. Browse to http://localhost:4567/javascripts/app.rb
10
+ 6. see a compressed js resource
11
+ 7. see a new cached file named app.js written to demos/yui-compressed/public/javascripts
12
+
13
+ Hope this helps as a working usage demo. This was written to help resolve issue #2: http://github.com/kelredd/rack-sprockets/issues/#issue/2
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+ require 'sinatra'
6
+ Bundler.require(:default)
7
+
8
+ # use the rack-sprockets middleware with default options:
9
+ # => http://github.com/kelredd/rack-sprockets --> README --> "Available Options" for details
10
+ use Rack::Sprockets
11
+
12
+ # configure rack-sprockets with custom configuration settings
13
+ # => http://github.com/kelredd/rack-sprockets --> README --> "Available Configurations" for details
14
+ Rack::Sprockets.configure do |config|
15
+ config.cache = true
16
+ config.compress = :yui
17
+ end
@@ -0,0 +1,4 @@
1
+ function one_message() {
2
+ var one_msg = 'alert one';
3
+ alert(one_msg);
4
+ }
@@ -0,0 +1,4 @@
1
+ function two_message() {
2
+ var two_msg = 'alert 2';
3
+ alert(two_msg);
4
+ }
@@ -0,0 +1,16 @@
1
+ //= require <alert_one>
2
+ //= require <alert_two>
3
+
4
+ function app_message() {
5
+ var app_msg = 'full app';
6
+ alert(app_msg);
7
+ }
8
+
9
+ function () {
10
+ var foo = {};
11
+ foo["bar"] = "baz";
12
+ }
13
+
14
+ one_message();
15
+ two_message();
16
+ app_message();
@@ -0,0 +1 @@
1
+ function one_message(){var a="alert one";alert(a)}function two_message(){var a="alert 2";alert(a)}function app_message(){var a="full app";alert(a)}function(){var a={};a.bar="baz"}one_message();two_message();app_message();
@@ -0,0 +1,12 @@
1
+ var one_message = 'alert one';
2
+ alert(one_message);
3
+ var two_message = 'alert 2';
4
+ alert(two_message);
5
+
6
+ var app_message = 'full app';
7
+ alert(app_message);
8
+
9
+ function () {
10
+ var foo = {};
11
+ foo["bar"] = "baz";
12
+ }
@@ -0,0 +1 @@
1
+ # require 'rack_sprockets//...'
@@ -11,7 +11,7 @@ module Rack::Sprockets
11
11
 
12
12
  class Request < Rack::Request
13
13
  include Rack::Sprockets::Options
14
-
14
+
15
15
  JS_PATH_FORMATS = ['.js']
16
16
 
17
17
  # The HTTP request method. This is the standard implementation of this
@@ -21,25 +21,43 @@ module Rack::Sprockets
21
21
  def request_method
22
22
  @env['REQUEST_METHOD']
23
23
  end
24
-
24
+
25
+ def http_accept
26
+ @env['HTTP_ACCEPT']
27
+ end
28
+
25
29
  def path_info
26
30
  @env['PATH_INFO']
27
31
  end
28
-
29
- def http_accept
30
- @env['HTTP_ACCEPT']
32
+
33
+ def hosted_at_option
34
+ # sanitized :hosted_at option
35
+ # remove any trailing '/'
36
+ # ensure single leading '/'
37
+ @hosted_at_option ||= options(:hosted_at).sub(/\/+$/, '').sub(/^\/*/, '/')
31
38
  end
32
-
33
- def path_resource_name
34
- File.basename(path_info, path_resource_format)
39
+
40
+ def path_info_resource
41
+ # sanitized path to the resource being requested
42
+ # ensure single leading '/'
43
+ # remove any resource format
44
+ # ex:
45
+ # '/something.js' => '/something'
46
+ # '/nested/something.js' => '/nested/something'
47
+ # '///something.js' => '/something'
48
+ # '/nested///something.js' => '/nested/something'
49
+ @path_info_resource ||= File.join(
50
+ File.dirname(path_info.gsub(/\/+/, '/')).sub(/^#{hosted_at_option}/, ''),
51
+ File.basename(path_info.gsub(/\/+/, '/'), path_info_format)
52
+ ).sub(/^\/*/, '/')
35
53
  end
36
-
37
- def path_resource_format
38
- File.extname(path_info)
54
+
55
+ def path_info_format
56
+ @path_info_format ||= File.extname(path_info.gsub(/\/+/, '/'))
39
57
  end
40
58
 
41
59
  def cache
42
- File.join(options(:root), options(:public), options(:hosted_at))
60
+ File.join(options(:root), options(:public), hosted_at_option)
43
61
  end
44
62
 
45
63
  # The Rack::Sprockets::Source that the request is for
@@ -55,36 +73,36 @@ module Rack::Sprockets
55
73
  :expand_paths => options(:expand_paths)
56
74
  }
57
75
  }
58
- Source.new(path_resource_name, source_opts)
76
+ Source.new(path_info_resource, source_opts)
59
77
  end
60
78
  end
61
79
 
62
80
  def for_js?
63
81
  (http_accept && http_accept.include?(Rack::Sprockets::MIME_TYPE)) ||
64
82
  (media_type && media_type.include?(Rack::Sprockets::MIME_TYPE )) ||
65
- JS_PATH_FORMATS.include?(path_resource_format)
83
+ JS_PATH_FORMATS.include?(path_info_format)
66
84
  end
67
85
 
68
86
  def hosted_at?
69
- File.basename(File.dirname(path_info)) == File.basename(options(:hosted_at))
87
+ path_info =~ /^#{hosted_at_option}/
70
88
  end
71
-
72
- def exists?
73
- File.exists?(File.join(cache, "#{path_resource_name}#{path_resource_format}"))
89
+
90
+ def cached?
91
+ File.exists?(File.join(cache, "#{path_info_resource}#{path_info_format}"))
74
92
  end
75
93
 
76
- # Determine if the request is for an existing Sprockets source file
94
+ # Determine if the request is for a non-cached existing Sprockets source file
77
95
  # This will be called on every request so speed is an issue
78
96
  # => first check if the request is a GET on a js resource in :hosted_at (fast)
79
- # => don't process if a file already exists in :hosted_at
97
+ # => don't process if a file has already been cached
80
98
  # => otherwise, check for sprockets source files that match the request (slow)
81
99
  def for_sprockets?
82
- get? &&
100
+ get? && # GET on js resource in :hosted_at (fast, check first)
83
101
  for_js? &&
84
102
  hosted_at? &&
85
- !exists? &&
86
- !source.files.empty?
103
+ !cached? && # resource not cached (little slower)
104
+ !source.files.empty? # there is source for the resource (slow, check last)
87
105
  end
88
-
106
+
89
107
  end
90
108
  end
@@ -10,7 +10,7 @@ end
10
10
  module Rack::Sprockets
11
11
 
12
12
  class Source
13
-
13
+
14
14
  PREFERRED_EXTENSIONS = [:js]
15
15
  SECRETARY_DEFAULTS = {
16
16
  :expand_paths => true
@@ -18,18 +18,18 @@ module Rack::Sprockets
18
18
  YUI_OPTS = {
19
19
  :munge => true
20
20
  }
21
-
22
- attr_reader :js_name
23
-
24
- def initialize(js_name, options={})
25
- @js_name = js_name
21
+
22
+ attr_reader :js_resource
23
+
24
+ def initialize(js_resource, options={})
25
+ @js_resource = js_resource.gsub(/^\/+/, '')
26
26
  @compress = options[:compress]
27
27
  @cache = options[:cache]
28
28
 
29
29
  @folder = get_required_path(options, :folder)
30
30
  @secretary = SECRETARY_DEFAULTS.merge(options[:secretary] || {})
31
31
  end
32
-
32
+
33
33
  def compress?
34
34
  !!@compress
35
35
  end
@@ -39,11 +39,11 @@ module Rack::Sprockets
39
39
  def cache
40
40
  @cache
41
41
  end
42
-
42
+
43
43
  def files
44
44
  @files ||= js_sources
45
- end
46
-
45
+ end
46
+
47
47
  def secretary
48
48
  @secretary_obj ||= Sprockets::Secretary.new(@secretary.merge({
49
49
  :source_files => files
@@ -53,7 +53,7 @@ module Rack::Sprockets
53
53
  def compiled
54
54
  @compiled ||= begin
55
55
  compiled_js = secretary.concatenation.to_s
56
-
56
+
57
57
  compiled_js = case @compress
58
58
  when :whitespace, true
59
59
  compiled_js.delete("\n")
@@ -67,52 +67,52 @@ module Rack::Sprockets
67
67
  compiled_js
68
68
  end
69
69
 
70
- if cache? && !File.exists?(cf = File.join(@cache, "#{@js_name}.js"))
71
- FileUtils.mkdir_p(@cache)
70
+ if cache? && !File.exists?(cf = File.join(@cache, "#{@js_resource}.js"))
71
+ FileUtils.mkdir_p(File.dirname(cf))
72
72
  File.open(cf, "w") do |file|
73
73
  file.write(compiled_js)
74
74
  end
75
75
  end
76
-
76
+
77
77
  compiled_js
78
78
  end
79
79
  end
80
80
  alias_method :to_js, :compiled
81
81
  alias_method :js, :compiled
82
-
82
+
83
83
  protected
84
-
84
+
85
85
  # Source files matching the js name
86
86
  def js_sources
87
- @js_sources ||= preferred_sources([*@js_name])
87
+ @js_sources ||= preferred_source_files([*@js_resource])
88
88
  end
89
-
89
+
90
90
  private
91
-
92
- # Given a list of file names, return a list of
93
- # existing source files with the corresponding names
91
+
92
+ # Given a list of file resources, return a list of
93
+ # existing source files with the corresponding resource names
94
94
  # honoring the preferred extension list
95
- def preferred_sources(file_names)
96
- file_names.collect do |name|
95
+ def preferred_source_files(file_resources)
96
+ file_resources.collect do |resource|
97
97
  PREFERRED_EXTENSIONS.inject(nil) do |source_file, extension|
98
98
  source_file || begin
99
- path = File.join(@folder, "#{name}.#{extension}")
99
+ path = File.join(@folder, "#{resource}.#{extension}")
100
100
  File.exists?(path) ? path : nil
101
101
  end
102
102
  end
103
103
  end.compact
104
104
  end
105
-
105
+
106
106
  def get_required_path(options, path_key)
107
107
  unless options.has_key?(path_key)
108
108
  raise(ArgumentError, "no :#{path_key} option specified")
109
109
  end
110
110
  unless File.exists?(options[path_key])
111
- raise(ArgumentError, "the :#{path_key} ('#{options[path_key]}') does not exist")
111
+ raise(ArgumentError, "the :#{path_key} ('#{options[path_key]}') does not exist")
112
112
  end
113
113
  options[path_key]
114
114
  end
115
115
 
116
116
  end
117
-
117
+
118
118
  end