sinatra-assetpack 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +1 -0
  2. data/HISTORY.md +15 -0
  3. data/README.md +203 -112
  4. data/Rakefile +17 -0
  5. data/docsrc/style.css +32 -0
  6. data/{example → examples/basic}/.gitignore +0 -0
  7. data/{example → examples/basic}/Rakefile +0 -0
  8. data/{example → examples/basic}/app.rb +0 -0
  9. data/{example → examples/basic}/app/css/test.sass +0 -0
  10. data/{example → examples/basic}/app/images/icon.png +0 -0
  11. data/{example → examples/basic}/app/js/app.js +0 -0
  12. data/{example → examples/basic}/app/js/vendor/jquery.js +0 -0
  13. data/{example → examples/basic}/app/js/vendor/jquery.plugin.js +0 -0
  14. data/{example → examples/basic}/app/js/vendor/underscore.js +0 -0
  15. data/{example → examples/basic}/views/index.erb +0 -0
  16. data/examples/compass/.gitignore +1 -0
  17. data/examples/compass/Rakefile +7 -0
  18. data/examples/compass/app.rb +45 -0
  19. data/examples/compass/app/css/main.scss +64 -0
  20. data/examples/compass/app/images/icon-scfd8d7d404.png +0 -0
  21. data/examples/compass/app/images/icon/mail.png +0 -0
  22. data/examples/compass/app/images/icon/refresh.png +0 -0
  23. data/examples/compass/app/images/junk/mail.png +0 -0
  24. data/examples/compass/app/images/junk/refresh.png +0 -0
  25. data/examples/compass/app/js/app.js +3 -0
  26. data/examples/compass/app/js/vendor/jquery.js +2 -0
  27. data/examples/compass/app/js/vendor/jquery.plugin.js +2 -0
  28. data/examples/compass/app/js/vendor/underscore.js +2 -0
  29. data/examples/compass/config.ru +3 -0
  30. data/examples/compass/views/index.erb +15 -0
  31. data/lib/sinatra/assetpack.rb +1 -1
  32. data/lib/sinatra/assetpack/class_methods.rb +13 -7
  33. data/lib/sinatra/assetpack/options.rb +0 -8
  34. data/lib/sinatra/assetpack/package.rb +1 -1
  35. data/lib/sinatra/assetpack/rake.rb +7 -1
  36. data/lib/sinatra/assetpack/version.rb +1 -1
  37. data/test/app/app.rb +4 -0
  38. data/test/app/app/css/behavior.htc +1 -0
  39. data/test/app/app/js_glob/a/b/c1/hello.js +1 -0
  40. data/test/app/app/js_glob/a/b/c2/hi.js +1 -0
  41. data/test/app/app/js_glob/a/b/c2/hola.js +1 -0
  42. data/test/cache_test.rb +3 -4
  43. data/test/compressed_test.rb +30 -0
  44. data/test/glob_test.rb +42 -0
  45. data/test/local_file_test.rb +1 -2
  46. data/test/mime_type_test.rb +33 -0
  47. data/test/non_existent_test.rb +1 -2
  48. data/test/options_test.rb +1 -2
  49. data/test/order_test.rb +1 -2
  50. data/test/stylus_test.rb +1 -2
  51. data/test/template_cache_test.rb +29 -0
  52. data/test/test_helper.rb +6 -7
  53. data/test/yui_test.rb +1 -1
  54. metadata +59 -37
data/Rakefile CHANGED
@@ -12,3 +12,20 @@ task :test do
12
12
  end
13
13
 
14
14
  task :default => :test
15
+
16
+ gh = "rstacruz/sinatra-assetpack"
17
+ namespace :doc do
18
+ # http://github.com/rstacruz/reacco
19
+ desc "Builds the documentation into doc/"
20
+ task :build do
21
+ system "reacco -a --github #{gh} --css docsrc/style.css"
22
+ end
23
+
24
+ # http://github.com/rstacruz/git-update-ghpages
25
+ desc "Posts documentation to GitHub pages"
26
+ task :deploy => :build do
27
+ system "git update-ghpages #{gh} -i doc/"
28
+ end
29
+ end
30
+
31
+ task :doc => :'doc:build'
@@ -0,0 +1,32 @@
1
+ section.features {
2
+ background: #f6f6ff;
3
+ overflow: hidden; }
4
+
5
+ h2 {
6
+ font-size: 26pt; }
7
+
8
+ section.features h2 {
9
+ font-size: 32pt; }
10
+
11
+ section.features ul {
12
+ max-width: none;
13
+ margin-left: 0;
14
+ padding-left: 0;
15
+ width: 100%; }
16
+
17
+ section.features li {
18
+ list-style-type: none;
19
+ width: 420px;
20
+ float: left; margin-right: 40px; }
21
+
22
+ section.features li:nth-child(odd) {
23
+ clear: both; }
24
+
25
+ section.features li>p>strong {
26
+ font-family: shanti, sans-serif;
27
+ font-weight: normal;
28
+ font-size: 1.2em;
29
+ text-shadow: 2px 2px 0 rgba(255, 255, 255, 0.1);
30
+ display: block;
31
+ margin-bottom: 5px;
32
+ color: #88a; }
File without changes
File without changes
File without changes
@@ -0,0 +1 @@
1
+ public
@@ -0,0 +1,7 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ APP_FILE = 'app.rb'
4
+ APP_CLASS = 'App'
5
+
6
+ require 'sinatra/assetpack/rake'
7
+
@@ -0,0 +1,45 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'sinatra/base'
4
+ require 'sinatra/assetpack'
5
+ require 'compass'
6
+ require 'sinatra/support'
7
+
8
+ Encoding.default_external = 'utf-8' if defined?(::Encoding)
9
+
10
+ class App < Sinatra::Base
11
+ disable :show_exceptions
12
+ enable :raise_exceptions
13
+
14
+ set :root, File.dirname(__FILE__)
15
+
16
+ # This is a convenient way of setting up Compass in a Sinatra
17
+ # project without mucking around with load paths and such.
18
+ register Sinatra::CompassSupport
19
+
20
+ # ### Compass sprite configuration
21
+ # Skip this section if you don't need sprite images.
22
+ #
23
+ # Configure Compass so it knows where to look for sprites. This tells
24
+ # Compass to look for images in `app/images`, dump sprite images in the same
25
+ # folder, and link to it with HTTP images path.
26
+ #
27
+ c = Compass.configuration
28
+ c.project_path = root
29
+ c.images_dir = "app/images"
30
+ c.http_images_path = "/images"
31
+
32
+ # Asset Pack.
33
+ register Sinatra::AssetPack
34
+ assets do
35
+ css :main, ['/css/*.css']
36
+ end
37
+
38
+ get '/' do
39
+ erb :index
40
+ end
41
+ end
42
+
43
+ if __FILE__ == $0
44
+ App.run!
45
+ end
@@ -0,0 +1,64 @@
1
+ @import 'compass/css3';
2
+ @import 'compass/reset';
3
+
4
+ html, body {
5
+ font-family: sans-serif;
6
+ font-size: 11pt;
7
+ line-height: 1.5; }
8
+
9
+ body {
10
+ background: #c2c2cf; }
11
+
12
+ #all {
13
+ background: white;
14
+ color: #333;
15
+ padding: 10px;
16
+ width: 500px;
17
+ margin: 50px auto; }
18
+
19
+ // ### Optional sprite config
20
+ // You may put any of these before the `all-icon-sprites` line.
21
+ // These are completely optional.
22
+
23
+ // #### Sprite sets: (/icon/*.png)
24
+ $icon-spacing: 0; // How much blank space (in pixels) to put
25
+ $icon-dimensions: false; // Sets width/height in the classes
26
+ $icon-repeat: no-repeat;
27
+ $icon-position: 0;
28
+
29
+ // #### Individual images: (/icon/mail.png)
30
+ $icon-mail-spacing: 0;
31
+ $icon-mail-repeat: no-repeat;
32
+ $icon-mail-position: 0px;
33
+
34
+ // ### Sprite setup
35
+ // For "mail.png" and "refresh.png", this creates classes for .icon-mail and
36
+ // .icon-refresh that you can @extend from.
37
+ //
38
+ // See: http://compass-style.org/help/tutorials/configuration-reference/
39
+ //
40
+ @import "icon/*.png";
41
+ @include all-icon-sprites;
42
+
43
+ .image1, .image2 {
44
+ width: 16px; height: 16px;
45
+ display: inline-block; }
46
+
47
+ .image1 {
48
+ @extend .icon-mail; }
49
+
50
+ .image2 {
51
+ @extend .icon-refresh; }
52
+
53
+ // ### Advanced control
54
+ // The sprite map is available as $icon-sprites. You can then use
55
+ // `sprite()` on it.
56
+
57
+ .image3 {
58
+ background: sprite($icon-sprites, refresh); }
59
+ //background: url(...) 0 -16px;
60
+
61
+ .image3-with-offset {
62
+ background: sprite($icon-sprites, refresh, -2px, -9px); }
63
+ //background: url(...) -2px -19px;
64
+
@@ -0,0 +1,3 @@
1
+ ("App.js goes here.");
2
+
3
+
@@ -0,0 +1,2 @@
1
+ ("jQuery goes here.");
2
+
@@ -0,0 +1,2 @@
1
+ ("A jQuery plugin goes here.");
2
+
@@ -0,0 +1,2 @@
1
+ ("Underscore.js goes here.");
2
+
@@ -0,0 +1,3 @@
1
+ require './app'
2
+ App.set :run, false
3
+ run App
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title></title>
6
+ <%= css :main %>
7
+ </head>
8
+ <body>
9
+ <div id="all">
10
+ <h1>Here are some sprites:</h1>
11
+ <span class='image1'></span>
12
+ <span class='image2'></span>
13
+ </div>
14
+ </body>
15
+ </html>
@@ -14,7 +14,7 @@ module Sinatra
14
14
  # Returns a list of formats that can be served.
15
15
  # Anything not in this list will be rejected.
16
16
  def self.supported_formats
17
- @supported_formats ||= %w(css js png jpg gif otf eot ttf woff)
17
+ @supported_formats ||= %w(css js png jpg gif otf eot ttf woff htc)
18
18
  end
19
19
 
20
20
  # Returns a map of what MIME format each Tilt type returns.
@@ -19,10 +19,13 @@ module Sinatra
19
19
  def add_compressed_routes!
20
20
  assets.packages.each do |name, package|
21
21
  get package.route_regex do
22
- content_type package.type
23
- last_modified package.mtime if package.mtime
22
+ mtime, contents = @template_cache.fetch(package.path) {
23
+ [ package.mtime, package.minify ]
24
+ }
24
25
 
25
- settings.assets.cache[package.hash] ||= package.minify
26
+ content_type package.type
27
+ last_modified mtime
28
+ contents
26
29
  end
27
30
  end
28
31
  end
@@ -49,16 +52,19 @@ module Sinatra
49
52
  not_found unless format == fmt
50
53
 
51
54
  if fmt == 'css'
52
- asset_filter_css File.read(fn)
55
+ @template_cache.fetch(fn) { asset_filter_css File.read(fn) }
53
56
  else
54
57
  send_file fn
55
58
  end
56
59
  else
57
60
  # Dynamic file
58
61
  not_found unless AssetPack.tilt_formats[format] == fmt
59
- out = render format.to_sym, File.read(fn)
60
- out = asset_filter_css(out) if fmt == 'css'
61
- out
62
+
63
+ @template_cache.fetch(fn) {
64
+ out = render format.to_sym, File.read(fn)
65
+ out = asset_filter_css(out) if fmt == 'css'
66
+ out
67
+ }
62
68
  end
63
69
  end
64
70
  end
@@ -242,14 +242,6 @@ module Sinatra
242
242
  HashArray[*tuples.flatten]
243
243
  end
244
244
 
245
- def cache
246
- @cache ||= Hash.new
247
- end
248
-
249
- def reset_cache
250
- @cache = nil && cache
251
- end
252
-
253
245
  private
254
246
  # Returns a URI for a given file
255
247
  # path = '/projects/x/app/css'
@@ -55,7 +55,7 @@ module Sinatra
55
55
  # Returns the regex for the route, including cache buster crap.
56
56
  def route_regex
57
57
  re = @path.gsub(/(.[^.]+)$/) { |ext| "(?:\.[0-9]+)?#{ext}" }
58
- /#{re}/
58
+ /^#{re}$/
59
59
  end
60
60
 
61
61
  def to_development_html(options={})
@@ -8,9 +8,15 @@ unless defined?(APP_FILE) && defined?(APP_CLASS)
8
8
  exit
9
9
  end
10
10
 
11
+ def class_from_string(str)
12
+ str.split('::').inject(Object) do |mod, class_name|
13
+ mod.const_get(class_name)
14
+ end
15
+ end
16
+
11
17
  def app
12
18
  require File.expand_path(APP_FILE, Dir.pwd)
13
- Object.const_get(APP_CLASS.to_sym)
19
+ class_from_string(APP_CLASS)
14
20
  end
15
21
 
16
22
  namespace :assetpack do
@@ -1,7 +1,7 @@
1
1
  module Sinatra
2
2
  module AssetPack
3
3
  def self.version
4
- "0.0.8"
4
+ "0.0.9"
5
5
  end
6
6
  end
7
7
  end
@@ -18,6 +18,10 @@ class Main < Sinatra::Base
18
18
  serve '/css', :from => 'app/css'
19
19
  serve '/images', :from => 'app/images'
20
20
 
21
+ js :skitch, '/skitch.js', [
22
+ '/js/hi.js',
23
+ ]
24
+
21
25
  js :app, '/js/app.js', [
22
26
  '/js/vendor/**/*.js',
23
27
  '/js/assets/**/*.js',
@@ -0,0 +1 @@
1
+ ..
@@ -0,0 +1 @@
1
+ alert("Hello");
@@ -0,0 +1 @@
1
+ alert("Hi");
@@ -0,0 +1 @@
1
+ alert("Hola");
@@ -2,9 +2,8 @@ require File.expand_path('../test_helper', __FILE__)
2
2
 
3
3
  class CacheTest < UnitTest
4
4
  test "Compressed js caching" do
5
- app.assets.reset_cache
6
- # JSMin.expects(:minify).times(1) -- not working?
7
- get '/js/app.js'
8
- get '/js/app.js'
5
+ app.set :reload_templates, false
6
+ JSMin.expects(:minify).times(1)
7
+ 3.times { get '/js/app.js' }
9
8
  end
10
9
  end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class CompressedTest < UnitTest
4
+ class App < UnitTest::App
5
+ register Sinatra::AssetPack
6
+
7
+ assets {
8
+ js :app, '/app.js', [ '/js/*.js' ]
9
+ }
10
+ end
11
+
12
+ def app
13
+ App
14
+ end
15
+
16
+ test "ha" do
17
+ get '/x/y/z/app.js'
18
+ assert last_response.status == 404
19
+ end
20
+
21
+ test "right" do
22
+ get '/app.js'
23
+ assert last_response.status == 200
24
+ end
25
+
26
+ test "lol" do
27
+ get '/app.4872837.js'
28
+ assert last_response.status == 200
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class GlobTest < UnitTest
4
+ class App < UnitTest::App
5
+ register Sinatra::AssetPack
6
+
7
+ assets {
8
+ serve '/js', :from => 'app/js_glob'
9
+ js :a, '/a.js', [ '/js/**/*.js' ]
10
+ js :b, '/b.js', [ '/js/a/b/c2/*.js' ]
11
+ js :c, '/c.js', [ '/js/a/b/*/*.js' ]
12
+ }
13
+
14
+ get('/a') { js :a }
15
+ get('/b') { js :b }
16
+ get('/c') { js :c }
17
+ end
18
+
19
+ def app
20
+ App
21
+ end
22
+
23
+ should "match double-star globs recursively" do
24
+ get '/a'
25
+ assert body.include?("a/b/c1/hello.")
26
+ assert body.include?("a/b/c2/hi.")
27
+ assert body.include?("a/b/c2/hola.")
28
+ end
29
+
30
+ should "match single-star globs in filenames" do
31
+ get '/b'
32
+ assert body.include?("a/b/c2/hi.")
33
+ assert body.include?("a/b/c2/hola.")
34
+ end
35
+
36
+ should "match single-star globs in paths" do
37
+ get '/c'
38
+ assert body.include?("a/b/c1/hello.")
39
+ assert body.include?("a/b/c2/hi.")
40
+ assert body.include?("a/b/c2/hola.")
41
+ end
42
+ end