vitrine 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e36b0ef37b91224c1fe39ea53768011abbfb150d
4
- data.tar.gz: 89ab96905bdfd081a1322417d351e8d60431688d
3
+ metadata.gz: 6ee018a5ccd0dc9855944a5383d88ea37bde9b68
4
+ data.tar.gz: 318885cc0cdb952a5e0da8374493ad73df9919f2
5
5
  SHA512:
6
- metadata.gz: 612af9879a6fc35d9c55bd2600db4ee35768ae7ff4c78d9b1c5e37bd9553a09f45aa7076d1282211a2f53283b38196e5628e5b7818988d4d37237309bb6636f0
7
- data.tar.gz: b473bcc793ba500cace85af74e6dd5a0070e133c926f17ffb48b7fdf7aa898bcc826d5ab6a50beb1a17c6e5102072f422e13d9058a931a93ba9b77d16dbaf6e2
6
+ metadata.gz: b3ffd8d9dc3d901e9f05c8b5abfd9ff0a94f860f910934918015b55eaf82382876baca2610b31e233f854377812c0ff181c3de74e9ef21b4b802f7ac4145403d
7
+ data.tar.gz: 87fd5a399ecd9d46ce855ff408361f7d226d6f1571ac3fad59ab82052e25c32ef105c5cc364381427878237aadd5db47282251a4f4d652552ce0f887a4b3b510
data/README.md CHANGED
@@ -23,24 +23,16 @@ Vitrine assumes that there are two directories under the current tree:
23
23
 
24
24
  Vitrine is for **development**. It takes runtime compilation to 11 and beyound. Running tasks
25
25
  is all fine and good when you build out the app for production, but when iterating on UI it's essential
26
- to be able to just yank the file 3in there and carry on.
26
+ to be able to just yank the file in there and carry on. THe compilation perks include:
27
27
 
28
- ### For SCSS/SASS
28
+ * Any `.scss` file you shove into the `public` directory can be referenced as `.css` from your HTML.
29
+ Ask for `foo.css` and `foo.scss` will be compiled on the fly.
30
+ * Any `.coffee` file you shove into the `public` directory can be references as `.js` from your HTML.
31
+ Ask for `bar.js` and `bar.coffee` will be compiled on the fly.
32
+ * CoffeeScript files will have source-maps out of the box for pleasant browser debugging.
33
+ * Decent error messages will be shown for both invalid SCSS and invalid CoffeeScript.
29
34
 
30
- Any .scss file you shove into the "public" directory can be referenced as ".css" from your HTML code.
31
- Vitrine will automatically compile it via SASS.
32
-
33
- ### For CoffeeScript, with source maps
34
-
35
- Same thing applies to CoffeeScript - put `.coffee` files in "public", and reference them as `.js` files.
36
- Vitrine will generate you source maps on the fly for pleasant browser debugging.
37
-
38
- ## Sensible error messages when automatic compilation fails
39
-
40
- Vitrine will try to show you sensible errors if your SCSS or CoffeeScript fail to compile due to syntax errors and
41
- the like. CoffeeScript errors go to the browser console, and Sass errors go in a generated element on top of your page.
42
-
43
- ## Do not recompile on every request
35
+ ## Asset caching
44
36
 
45
37
  Succesfully compiled assets will be cached to save time on next reload, and ETagged based on their
46
38
  mtime.
@@ -51,8 +43,8 @@ If you have the "views" directory available, Vitrine will try to pick up any usa
51
43
  From there on, it's going to try to render it with the automatically picked template engine using the
52
44
  standard Sinatra facilities. You can use HAML, LESS, Slim, ERB, Builder or anything else you like.
53
45
 
54
- If you are writing an SPA, you can make a file called "catch_all.erb" which is going to be the fall-through template
55
- for all missing URLs without extension.
46
+ If you are writing an SPA, you can make a file called "catch_all.erb" which is going to be
47
+ the fall-through template for all missing URLs without extension.
56
48
 
57
49
  ## Automatic reload via Guard
58
50
 
@@ -80,6 +72,15 @@ forget to set `:root` - like so:
80
72
  vitrine.settings.set :root => File.dirname(__FILE__)
81
73
  end
82
74
 
75
+ You can also only opt-in to the asset compilation system of Vitrine only once you have migrated your app from
76
+ the prototype stage into, say, a Sinatra application.
77
+
78
+ Note that you _need_ to have an `ExecJS` environment on your server for this:
79
+
80
+ use Vitrine::AssetCompiler.new do | ac |
81
+ vitrine.settings.set :root => File.dirname(__FILE__)
82
+ end
83
+
83
84
  ## Contributing to vitrine
84
85
 
85
86
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
@@ -0,0 +1,148 @@
1
+ # The part of Vitrine responsible for SASS and CoffeeScript
2
+ # compilation and caching. By default it will assume your
3
+ # public directory is set on the inner app in the Rack stack,
4
+ # and can be retreived using the standard Sinatra settings
5
+ # protocol, like so:
6
+ #
7
+ # @app.settings.public_folder
8
+ #
9
+ # However, you can also set this setting on the app object using the
10
+ # AssetCompiler#public_dir accessor.
11
+ #
12
+ # use Vitrine::AssetCompiler do | compiler |
13
+ # compiler.public_dir = File.dirname(__FILE__) + '/public'
14
+ # end
15
+ #
16
+ # This allows you to use the asset compiler when the inner app
17
+ # is not a Sinatra application.
18
+ #
19
+ # Obviously, the usual limitation apply for this kind of workflow -
20
+ # you pretty much have to have an ExecJS env on yourserver, or else...
21
+ class Vitrine::AssetCompiler < Sinatra::Base
22
+ set :show_exceptions, false
23
+ set :raise_errors, true
24
+
25
+ # An explicit override for +public_folder+ setting,
26
+ # if set will take precedence over the setting
27
+ attr_accessor :public_dir
28
+
29
+ # Try to find SCSS replacement for missing CSS
30
+ get /(.+)\.css/ do | basename |
31
+ begin
32
+ content_type 'text/css', :charset => 'utf-8'
33
+ # TODO: has no handling for .sass
34
+ scss_source_path = File.join(get_public, "#{basename}.scss")
35
+ mtime_cache(scss_source_path) do
36
+ # TODO: Examine http://sass-lang.com/documentation/file.SASS_REFERENCE.html
37
+ # It already has provisions for error display, among other things
38
+ Sass.compile_file(scss_source_path, cache_location: '/tmp/vitrine/sass-cache')
39
+ end
40
+ rescue Errno::ENOENT # Missing SCSS
41
+ forward_or_halt "No such CSS or SCSS file found"
42
+ rescue Exception => e # CSS syntax error or something alike
43
+ # Add a generated DOM element before <body/> to inject
44
+ # a visible error message
45
+ error_tpl = 'body:before {
46
+ background: white; padding: 3px; font-family: monospaced; color: red;
47
+ font-size: 14px; content: %s }'
48
+ css_message = error_tpl % [e.class, "\n", "--> ", e.message].join.inspect
49
+ # If we halt with 500 this will not be shown as CSS
50
+ halt 200, css_message
51
+ end
52
+ end
53
+
54
+ # Generate a sourcemap for CoffeeScript files
55
+ get /(.+)\.js\.map$/ do | basename |
56
+ begin
57
+ coffee_source = File.join(get_public, "#{basename}.coffee")
58
+ content_type 'application/json', :charset => 'utf-8'
59
+ mtime_cache(coffee_source) do
60
+ Vitrine.build_coffeescript_source_map_body(coffee_source, get_public)
61
+ end
62
+ rescue Errno::ENOENT # Missing CoffeeScript
63
+ forward_or_halt "No coffeescript file found to generate the map for"
64
+ rescue Exception => e # CS syntax error or something alike
65
+ halt 400, 'Compliation of the related CoffeeScript file failed'
66
+ end
67
+ end
68
+
69
+ # Try to find CoffeeScript replacement for missing JS
70
+ get /(.+)\.js$/ do | basename |
71
+ # If this file is not found resort back to a coffeescript
72
+ begin
73
+ coffee_source = File.join(get_public, "#{basename}.coffee")
74
+ content_type 'text/javascript'
75
+ mtime_cache(coffee_source) do
76
+ source_body = File.read(coffee_source)
77
+ # We could have sent a header, but it's a nice idea to have the
78
+ # sourcemap header saved if we write out the compiled JS,
79
+ # whereas otherwise it would have been discarded
80
+ [
81
+ "//# sourceMappingURL=#{basename}.js.map",
82
+ CoffeeScript.compile(source_body)
83
+ ].join("\n")
84
+ end
85
+ rescue Errno::ENOENT # Missing CoffeeScript
86
+ forward_or_halt "No such JS file and could not find a .coffee replacement"
87
+ rescue Exception => e # CS syntax error or something alike
88
+ # Inject the syntax error into the browser console
89
+ console_message = 'console.error(%s)' % [e.class, "\n", "--> ", e.message].join.inspect
90
+ # Avoid 500 because it plays bad with LiveReload
91
+ halt 200, console_message
92
+ end
93
+ end
94
+
95
+ def mtime_cache(path, &blk)
96
+ # Mix in the request URL into the cache key so that we can hash
97
+ # .map sourcemaps and .js compiles based off of the same file path
98
+ # and mtime
99
+ key = [File.expand_path(path), File.mtime(path), request.path_info, get_public]
100
+ cache_sha = Digest::SHA1.hexdigest(Marshal.dump(key))
101
+
102
+ # Store in a temp dir
103
+ FileUtils.mkdir_p '/tmp/vitrine'
104
+ p = '/tmp/vitrine/%s' % cache_sha
105
+
106
+ # Only write it out unless a file with the same SHA does not exist
107
+ unless File.exist?(p)
108
+ Vitrine.atomic_write(p) do |f|
109
+ log "---> Recompiling #{path} for #{request.path_info}"
110
+ f.write(yield)
111
+ end
112
+ end
113
+
114
+ # And send out the file that's been written
115
+ last_modified(File.mtime(p))
116
+ etag File.mtime(p).to_i.to_s
117
+ File.read(p)
118
+ end
119
+
120
+
121
+ # Get path to the public directory, trying (in order:)
122
+ # self.public_dir reader
123
+ # the inner app's public_folder setting
124
+ # my own public_folder setting
125
+ def get_public
126
+ inner_public = if @app && @app.respond_to?(:settings)
127
+ @app.settings.public_folder
128
+ else
129
+ nil
130
+ end
131
+ choices = [@public_dir, inner_public, settings.public_dir]
132
+ choices.compact.shift
133
+ end
134
+
135
+ def forward_or_halt msg
136
+ if @app
137
+ log "Forwarding, #{msg} -> pub #{get_public.inspect}"
138
+ forward
139
+ else
140
+ halt 404, msg
141
+ end
142
+ end
143
+
144
+ def log(mgs)
145
+ env['captivity.logger'].debug(msg) if env['captivity.logger']
146
+ end
147
+ end
148
+
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vitrine
2
- VERSION = '0.0.13'
2
+ VERSION = '0.0.14'
3
3
  end
data/lib/vitrine.rb CHANGED
@@ -3,10 +3,12 @@ require 'coffee-script'
3
3
  require 'rack/contrib/try_static'
4
4
  require 'sass'
5
5
  require 'pathname'
6
+ require 'fileutils'
6
7
 
7
8
  require_relative 'version'
8
9
  require_relative 'atomic_write'
9
10
  require_relative 'sourcemaps'
11
+ require_relative 'asset_compiler'
10
12
 
11
13
  # A little idiosyncrastic asset server.
12
14
  # Does very simple things:
@@ -14,14 +16,15 @@ require_relative 'sourcemaps'
14
16
  # * automatic compilation of CoffeeScript and SASS assets - just request them with .js and .css
15
17
  # and Vitrine will find them and compile them for you on the spot
16
18
  class Vitrine::App < Sinatra::Base
17
- set :static, true
18
19
 
19
20
  set :show_exceptions, false
20
21
  set :raise_errors, true
21
22
 
22
23
  # Sets whether Vitrine will output messages about dynamic assets
23
24
  set :silent, true
24
- set :public_folder, ->{ File.join(settings.root, 'public') }
25
+ set :public_folder, ->{ File.join(settings.root, 'public') }
26
+
27
+ use Vitrine::AssetCompiler
25
28
 
26
29
  # For extensionless things try to pick out the related templates
27
30
  # from the views directory, and render them with a default layout.
@@ -88,88 +91,8 @@ class Vitrine::App < Sinatra::Base
88
91
  template_engine = File.extname(template_path).gsub(/^\./, '')
89
92
  render(template_engine, File.read(template_path), :layout => get_layout, :locals => locals)
90
93
  end
91
-
92
-
93
- # Try to find SCSS replacement for missing CSS
94
- get /(.+)\.css/ do | basename |
95
- begin
96
- content_type 'text/css', :charset => 'utf-8'
97
- # TODO: has no handling for .sass
98
- scss_source_path = File.join(settings.root, 'public', "#{basename}.scss")
99
- mtime_cache(scss_source_path) do
100
- # TODO: Examine http://sass-lang.com/documentation/file.SASS_REFERENCE.html
101
- Sass.compile_file(scss_source_path, cache_location: '/tmp/vitrine/sass-cache')
102
- end
103
- rescue Errno::ENOENT # Missing SCSS
104
- halt 404, "No such CSS or SCSS file found"
105
- rescue Exception => e # CSS syntax error or something alike
106
- # Add a generated DOM element before <body/> to inject
107
- # a visible error message
108
- error_tpl = 'body:before { background: white; font-family: sans-serif; color: red; font-size: 14px; content: %s }'
109
- css_message = error_tpl % [e.class, "\n", "--> ", e.message].join.inspect
110
- # If we halt with 500 this will not be shown as CSS
111
- halt 200, css_message
112
- end
113
- end
114
94
 
115
- # Generate a sourcemap for CoffeeScript files
116
- get /(.+)\.js\.map$/ do | basename |
117
- begin
118
- coffee_source = File.join(settings.root, 'public', "#{basename}.coffee")
119
- content_type 'application/json', :charset => 'utf-8'
120
- mtime_cache(coffee_source) do
121
- Vitrine.build_coffeescript_source_map_body(coffee_source, File.join(settings.root, 'public'))
122
- end
123
- rescue Errno::ENOENT # Missing CoffeeScript
124
- halt 404, "No coffeescript file found to generate the map for"
125
- rescue Exception => e # CS syntax error or something alike
126
- halt 400, 'Compliation of the related CoffeeScript file failed'
127
- end
128
- end
129
95
 
130
- # Try to find CoffeeScript replacement for missing JS
131
- get /(.+)\.js$/ do | basename |
132
- # If this file is not found resort back to a coffeescript
133
- begin
134
- coffee_source = File.join(settings.root, 'public', "#{basename}.coffee")
135
- content_type 'text/javascript'
136
- mtime_cache(coffee_source) do
137
- ["//# sourceMappingURL=#{basename}.js.map", CoffeeScript.compile(File.read(coffee_source))].join("\n")
138
- end
139
- rescue Errno::ENOENT # Missing CoffeeScript
140
- halt 404, "No such JS file and could not find a .coffee replacement"
141
- rescue Exception => e # CS syntax error or something alike
142
- # Inject the syntax error into the browser console
143
- console_message = 'console.error(%s)' % [e.class, "\n", "--> ", e.message].join.inspect
144
- halt 500, console_message
145
- end
146
- end
147
-
148
- require 'fileutils'
149
-
150
- def mtime_cache(path, &blk)
151
- # Mix in the request URL into the cache key so that we can hash
152
- # .map sourcemaps and .js compiles based off of the same file path
153
- # and mtime
154
- key = [File.expand_path(path), File.mtime(path), request.path_info, settings.root]
155
- cache_sha = Digest::SHA1.hexdigest(Marshal.dump(key))
156
-
157
- # Store in a temp dir
158
- FileUtils.mkdir_p '/tmp/vitrine'
159
- p = '/tmp/vitrine/%s' % cache_sha
160
- if File.exist?(p)
161
- etag File.mtime(p)
162
- File.read(p)
163
- else
164
- yield.tap do | body |
165
- Vitrine.atomic_write(p) do |f|
166
- log "---> Recompiling #{path} for #{request.path_info}"
167
- f.write body
168
- end
169
- etag File.mtime(p)
170
- end
171
- end
172
- end
173
96
 
174
97
  def get_layout
175
98
  layouts = Dir.glob(File.join(settings.views, 'layout.*'))
data/test/test_vitrine.rb CHANGED
@@ -77,70 +77,9 @@ class TestVitrine < Test::Unit::TestCase
77
77
  end
78
78
 
79
79
  get '/nice.js'
80
-
81
- assert_not_nil last_response.headers['ETag'], 'Should set ETag for the compiled version'
82
- assert_equal 200, last_response.status
83
- assert_equal 'text/javascript;charset=utf-8', last_response.content_type
84
-
85
- assert last_response.body.include?( 'alert("rockage!")'), 'Should include the compiled function'
86
- assert last_response.body.include?( '//# sourceMappingURL=/nice.js.map'),
87
- 'Should include the reference to the source map'
88
- end
89
-
90
- def test_compiles_coffeescript_sourcemap
91
-
92
- FileUtils.mkdir_p File.join(@tempdir, 'public', 'js')
93
-
94
- write_public 'js/nice.coffee' do | f |
95
- f.puts 'alert "rockage!"'
96
- end
97
-
98
- # Sourcemap will only ever get requested AFTER the corresponding JS file
99
- get '/js/nice.js'
100
- assert last_response.ok?
101
-
102
- get '/js/nice.js.map'
103
- ref = {"version"=>3, "file"=>"", "sourceRoot"=>"", "sources"=>["/js/nice.coffee"],
104
- "names"=>[], "mappings"=>"AAAA;CAAA,CAAA,GAAA,KAAA;CAAA"}
105
- assert_equal ref, JSON.parse(last_response.body)
106
- end
107
-
108
- def test_sends_vanilla_js_if_its_present
109
- write_public 'vanilla.js' do | f |
110
- f.puts 'vanilla();'
111
- end
112
-
113
- get '/vanilla.js'
114
- assert_equal 200, last_response.status
115
- assert_equal "vanilla();\n", last_response.body
116
- end
117
-
118
- def test_invalid_coffeescript_creates_decent_error_alerts
119
- write_public 'faulty.coffee' do | f |
120
- f.puts 'function() { junked up }'
121
- end
122
-
123
- get '/faulty.js'
124
-
125
- assert_equal 500, last_response.status
126
- assert_equal 'text/javascript;charset=utf-8', last_response.content_type
127
- err = 'console.error("ExecJS::RuntimeError\n--> SyntaxError: reserved word \"function\"")'
128
- assert_equal err, last_response.body
80
+ assert_include last_response.body, 'alert("rockage!")', 'Should include the compiled function'
129
81
  end
130
82
 
131
- def test_caches_compiled_js_by_etag_and_responds_with_304_when_requested_again
132
- write_public 'nice.coffee' do | f |
133
- f.puts 'alert "rockage!"'
134
- end
135
-
136
- get '/nice.js'
137
- assert_equal 200, last_response.status
138
- assert_not_nil last_response.headers['ETag']
139
-
140
- etag = last_response.headers['ETag']
141
- get '/nice.js', {}, rack_env = {'HTTP_IF_NONE_MATCH' => etag}
142
- assert_equal 304, last_response.status
143
- end
144
83
 
145
84
  def test_sends_vanilla_css_if_present
146
85
  write_public 'vanilla.css' do | f |
@@ -153,29 +92,14 @@ class TestVitrine < Test::Unit::TestCase
153
92
  assert_equal '/* vanilla CSS kode */', last_response.body
154
93
  end
155
94
 
156
- def test_compiles_scss_when_requested_as_css
157
- write_public 'styles.scss' do | f |
158
- f.puts '.foo {'
159
- f.puts '.bar { font-size: 10px; }'
160
- f.puts '}'
161
- end
162
-
163
- get '/styles.css'
164
-
165
- assert last_response.ok?
166
- assert_not_nil last_response.headers['ETag'], 'Should set ETag for the compiled version'
167
- assert last_response.body.include?('.foo .bar {'), 'Should have compiled the CSS rule'
168
- end
169
95
 
170
- def test_displays_decent_alerts_for_scss_errors
171
- write_public 'faulty.scss' do | f |
172
- f.puts '.foo {{ junkiness-factor: 24pem; }'
96
+ def test_sends_vanilla_js_if_its_present
97
+ write_public 'vanilla.js' do | f |
98
+ f.puts 'vanilla();'
173
99
  end
174
100
 
175
- get '/faulty.css'
176
-
101
+ get '/vanilla.js'
177
102
  assert_equal 200, last_response.status
178
- assert last_response.body.include?('body:before {'), 'Should include the generated element selector'
179
- assert last_response.body.include?('Sass::SyntaxError'), 'Should include the syntax error class'
103
+ assert_equal "vanilla();\n", last_response.body
180
104
  end
181
105
  end
@@ -0,0 +1,96 @@
1
+ require_relative 'helper'
2
+
3
+ class TestVitrineAssetCompiler < Test::Unit::TestCase
4
+ include Rack::Test::Methods, VitrineTesting
5
+
6
+ def app # overridden
7
+ Vitrine::AssetCompiler.new.tap { |a| a.settings.set :root, @tempdir }
8
+ end
9
+
10
+ def test_compiles_coffeescript_to_js_when_addressed_by_js_extension
11
+ write_public 'nice.coffee' do | f |
12
+ f.puts 'alert "rockage!"'
13
+ end
14
+
15
+ get '/nice.js'
16
+
17
+ assert_not_nil last_response.headers['ETag'], 'Should set ETag for the compiled version'
18
+ assert_equal 200, last_response.status
19
+ assert_equal 'text/javascript;charset=utf-8', last_response.content_type
20
+
21
+ assert last_response.body.include?( 'alert("rockage!")'), 'Should include the compiled function'
22
+ assert last_response.body.include?( '//# sourceMappingURL=/nice.js.map'),
23
+ 'Should include the reference to the source map'
24
+ end
25
+
26
+ def test_compiles_coffeescript_sourcemap
27
+
28
+ FileUtils.mkdir_p File.join(@tempdir, 'public', 'js')
29
+
30
+ write_public 'js/nice.coffee' do | f |
31
+ f.puts 'alert "rockage!"'
32
+ end
33
+
34
+ # Sourcemap will only ever get requested AFTER the corresponding JS file
35
+ get '/js/nice.js'
36
+ assert last_response.ok?
37
+
38
+ get '/js/nice.js.map'
39
+ ref = {"version"=>3, "file"=>"", "sourceRoot"=>"", "sources"=>["/js/nice.coffee"],
40
+ "names"=>[], "mappings"=>"AAAA;CAAA,CAAA,GAAA,KAAA;CAAA"}
41
+ assert_equal ref, JSON.parse(last_response.body)
42
+ end
43
+
44
+ def test_invalid_coffeescript_creates_decent_error_alerts
45
+ write_public 'faulty.coffee' do | f |
46
+ f.puts 'function() { junked up }'
47
+ end
48
+
49
+ get '/faulty.js'
50
+
51
+ assert_equal 200, last_response.status
52
+ assert_equal 'text/javascript;charset=utf-8', last_response.content_type
53
+ err = 'console.error("ExecJS::RuntimeError\n--> SyntaxError: reserved word \"function\"")'
54
+ assert_equal err, last_response.body
55
+ end
56
+
57
+ def test_caches_compiled_js_by_etag_and_responds_with_304_when_requested_again
58
+ write_public 'nice.coffee' do | f |
59
+ f.puts 'alert "rockage!"'
60
+ end
61
+
62
+ get '/nice.js'
63
+ assert_equal 200, last_response.status
64
+ assert_not_nil last_response.headers['ETag']
65
+
66
+ etag = last_response.headers['ETag']
67
+ get '/nice.js', {}, rack_env = {'HTTP_IF_NONE_MATCH' => etag}
68
+ assert_equal 304, last_response.status
69
+ end
70
+
71
+ def test_compiles_scss_when_requested_as_css
72
+ write_public 'styles.scss' do | f |
73
+ f.puts '.foo {'
74
+ f.puts '.bar { font-size: 10px; }'
75
+ f.puts '}'
76
+ end
77
+
78
+ get '/styles.css'
79
+
80
+ assert last_response.ok?
81
+ assert_not_nil last_response.headers['ETag'], 'Should set ETag for the compiled version'
82
+ assert last_response.body.include?('.foo .bar {'), 'Should have compiled the CSS rule'
83
+ end
84
+
85
+ def test_displays_decent_alerts_for_scss_errors
86
+ write_public 'faulty.scss' do | f |
87
+ f.puts '.foo {{ junkiness-factor: 24pem; }'
88
+ end
89
+
90
+ get '/faulty.css'
91
+
92
+ assert_equal 200, last_response.status
93
+ assert last_response.body.include?('body:before {'), 'Should include the generated element selector'
94
+ assert last_response.body.include?('Sass::SyntaxError'), 'Should include the syntax error class'
95
+ end
96
+ end
@@ -7,9 +7,12 @@ class TestVitrineInRackStack < Test::Unit::TestCase
7
7
  def app
8
8
  td = temporary_app_dir
9
9
  outer = Rack::Builder.new do
10
- use Vitrine::App do | v |
11
- v.settings.set root: td
10
+ # The outer app
11
+ use Vitrine::App do |v|
12
+ v.settings.set root: td
12
13
  end
14
+
15
+ # And a lobster downstream
13
16
  map "/lobster" do
14
17
  run Rack::Lobster.new
15
18
  end
@@ -25,7 +28,7 @@ class TestVitrineInRackStack < Test::Unit::TestCase
25
28
 
26
29
  def test_fetch_js
27
30
  write_public('hello.coffee') do | f |
28
- f << 'window.alert("Hello Coffee")'
31
+ f << 'window.alert "Hello Coffee"'
29
32
  end
30
33
 
31
34
  get '/hello.js'
data/vitrine.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "vitrine"
8
- s.version = "0.0.13"
8
+ s.version = "0.0.14"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik Tarkhanov"]
12
- s.date = "2013-12-20"
12
+ s.date = "2013-12-23"
13
13
  s.description = " Serves ERB templates with live CoffeeScript and SASS "
14
14
  s.email = "me@julik.nl"
15
15
  s.executables = ["vitrine"]
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "README.md",
26
26
  "Rakefile",
27
27
  "bin/vitrine",
28
+ "lib/asset_compiler.rb",
28
29
  "lib/atomic_write.rb",
29
30
  "lib/server.rb",
30
31
  "lib/sourcemaps.rb",
@@ -32,6 +33,7 @@ Gem::Specification.new do |s|
32
33
  "lib/vitrine.rb",
33
34
  "test/helper.rb",
34
35
  "test/test_vitrine.rb",
36
+ "test/test_vitrine_asset_compiler.rb",
35
37
  "test/test_vitrine_in_rack_stack.rb",
36
38
  "vitrine.gemspec"
37
39
  ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vitrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-20 00:00:00.000000000 Z
11
+ date: 2013-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -222,6 +222,7 @@ files:
222
222
  - README.md
223
223
  - Rakefile
224
224
  - bin/vitrine
225
+ - lib/asset_compiler.rb
225
226
  - lib/atomic_write.rb
226
227
  - lib/server.rb
227
228
  - lib/sourcemaps.rb
@@ -229,6 +230,7 @@ files:
229
230
  - lib/vitrine.rb
230
231
  - test/helper.rb
231
232
  - test/test_vitrine.rb
233
+ - test/test_vitrine_asset_compiler.rb
232
234
  - test/test_vitrine_in_rack_stack.rb
233
235
  - vitrine.gemspec
234
236
  homepage: http://github.com/julik/vitrine