perfectline-smurf 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,59 @@
1
+ # Smurf
2
+
3
+ Smurf is a Rails plugin that does Javascript and CSS minification the way you would expect. See, with Rails `2.x` we got this cool new `:cache` option on `javascript_include_tag` and `stylesheet_link_tag`, but no option for minifying the cached file(s).
4
+
5
+ Smurf ends that. Smurf - if installed and when caching is enabled for the environment - will nab the concatenated file content from Rails just before it saves it and minifies the content using either JSmin or a custom CSS compressor.
6
+
7
+ Some cool things about Smurf, which also allude to the reasons I wrote it:
8
+
9
+ * Smurf will only run when Rails needs to cache new files
10
+ * It will never run on its own
11
+ * It requires absolutely no configuration
12
+ * Other than installing it, you don't need to do anything
13
+ * It just gets out of your way
14
+
15
+ Smurf will work with any version of Rails `2.x`; including Rails `2.2.2`.
16
+
17
+ ### JSmin
18
+
19
+ It's really an adaptation of Uladzislau Latynski's [jsmin.rb](http://javascript.crockford.com/jsmin.rb) port of Douglas Crockford's [jsmin.c](http://javascript.crockford.com/jsmin.c) library.
20
+
21
+ ### Smurf CSS Compressor
22
+
23
+ The following are the rules I applied, gathered from various perusals around the Internet*s*
24
+
25
+ 1. Replace consecutive whitespace characters with a single space
26
+ 2. Remove whitespace around opening brackets
27
+ 3. Remove whitespace in front of closing brackets
28
+ 4. Remove the semi-colon just before the closing bracket
29
+ 5. Remove comments between `/* ... */` - this could be a problem (esp. for CSS hacks)
30
+ 6. Remove spaces around `;`, `:`, and `,` characters
31
+ 7. Ensure whitespace between closing brackets and periods
32
+
33
+ ## Installation
34
+
35
+ ./script/plugin install git://github.com/thumblemonks/smurf.git
36
+
37
+ Then, wherever you define `javascript_include_tag` or `stylesheet_link_tag`, make sure to add the standard `:cache => true` or `:cache => 'some_bundle'` options.
38
+
39
+ Also make sure to at least have this setting in your production.rb:
40
+
41
+ config.action_controller.perform_caching = true
42
+
43
+ ## Testing and Other Stuff
44
+
45
+ If you want to test Smurf and you don't want to test with the latest version of Rails as of this writing (2.2.2), then do something like the following:
46
+
47
+ rake RAILS_GEM_VERSION=2.1.2
48
+
49
+ This is the mechanism I used for testing that Smurf works for all versions:
50
+
51
+ rake && rake RAILS_GEM_VERSION=2.1.2
52
+
53
+ ## Meta
54
+
55
+ Author: Justin Knowlden <gus@thumblemonks.com>
56
+
57
+ Contributions from: Lance Ivy, Scott White, Daniel Schierbeck
58
+
59
+ See MIT-LICENSE for licensing information
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |jewel|
8
+ jewel.name = 'smurf'
9
+ jewel.summary = 'Rails plugin to automatically minify JS and CSS when their bundles get cached'
10
+ jewel.email = 'gus@thumblemonks.com'
11
+ jewel.homepage = 'http://github.com/thumblemonks/smurf'
12
+ jewel.description = 'Rails plugin to automatically minify JS and CSS when their bundles get cached. Send in those patches!'
13
+ jewel.authors = ["Justin Knowlden"]
14
+ jewel.files.exclude 'test/**'
15
+ jewel.test_files.exclude 'test/log/**'
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
21
+ desc 'Default: run unit tests.'
22
+ task :default => :test
23
+
24
+ desc 'Test the load_model plugin.'
25
+ Rake::TestTask.new(:test) do |t|
26
+ t.libs << 'lib'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ desc 'Generate documentation for the smurf plugin.'
32
+ Rake::RDocTask.new(:rdoc) do |rdoc|
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = 'Smurf'
35
+ rdoc.options << '--line-numbers' << '--inline-source'
36
+ rdoc.rdoc_files.include('README')
37
+ rdoc.rdoc_files.include('lib/**/*.rb')
38
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 1
4
+ :minor: 1
data/lib/smurf.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'smurf/javascript'
2
+ require 'smurf/stylesheet'
3
+
4
+ if Rails.version =~ /^2\.2\./
5
+ # Support for Rails >= 2.2.x
6
+ module Smurf
7
+
8
+ module JavaScriptSources
9
+ private
10
+ def joined_contents; Smurf::Javascript.new(super).minified; end
11
+ end # JavaScriptSources
12
+
13
+ module StylesheetSources
14
+ private
15
+ def joined_contents; Smurf::Stylesheet.new(super).minified; end
16
+ end # StylesheetSources
17
+
18
+ end # ActionView::Helpers::AssetTagHelper::AssetTag
19
+ ActionView::Helpers::AssetTagHelper::JavaScriptSources.send(
20
+ :include, Smurf::JavaScriptSources)
21
+ ActionView::Helpers::AssetTagHelper::StylesheetSources.send(
22
+ :include, Smurf::StylesheetSources)
23
+ else
24
+ # Support for Rails <= 2.1.x
25
+ module ActionView::Helpers::AssetTagHelper
26
+ private
27
+ def join_asset_file_contents_with_minification(files)
28
+ content = join_asset_file_contents_without_minification(files)
29
+ if !files.grep(%r[/javascripts]).empty?
30
+ content = Smurf::Javascript.new(content).minified
31
+ elsif !files.grep(%r[/stylesheets]).empty?
32
+ content = Smurf::Stylesheet.new(content).minified
33
+ end
34
+ content
35
+ end
36
+ alias_method_chain :join_asset_file_contents, :minification
37
+ end # ActionView::Helpers::AssetTagHelper
38
+ end
@@ -0,0 +1,225 @@
1
+ # Author: Justin Knowlden
2
+ # Adaption of jsmin.rb published by Uladzislau Latynski
3
+ #
4
+ # -------------------
5
+ # jsmin.rb 2007-07-20
6
+ # Author: Uladzislau Latynski
7
+ # This work is a translation from C to Ruby of jsmin.c published by
8
+ # Douglas Crockford. Permission is hereby granted to use the Ruby
9
+ # version under the same conditions as the jsmin.c on which it is
10
+ # based.
11
+ #
12
+ # /* jsmin.c
13
+ # 2003-04-21
14
+ #
15
+ # Copyright (c) 2002 Douglas Crockford (www.crockford.com)
16
+ #
17
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
18
+ # this software and associated documentation files (the "Software"), to deal in
19
+ # the Software without restriction, including without limitation the rights to
20
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
21
+ # of the Software, and to permit persons to whom the Software is furnished to do
22
+ # so, subject to the following conditions:
23
+ #
24
+ # The above copyright notice and this permission notice shall be included in all
25
+ # copies or substantial portions of the Software.
26
+ #
27
+ # The Software shall be used for Good, not Evil.
28
+ #
29
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
+ # SOFTWARE.
36
+
37
+ require 'stringio'
38
+
39
+ module Smurf
40
+ class Javascript
41
+ EOF = -1
42
+
43
+ @theA = ""
44
+ @theB = ""
45
+
46
+ def initialize(content)
47
+ @input = StringIO.new(content)
48
+ @output = StringIO.new
49
+ jsmin
50
+ end
51
+
52
+ def minified
53
+ @output.rewind
54
+ @output.read
55
+ end
56
+
57
+ # isAlphanum -- return true if the character is a letter, digit,
58
+ # underscore, # dollar sign, or non-ASCII character
59
+ def isAlphanum(c)
60
+ return false if !c || c == EOF
61
+ return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
62
+ (c >= 'A' && c <= 'Z') || c == '_' || c == '$' ||
63
+ c == '\\' || Array(c[0].bytes).first > 126)
64
+ end
65
+
66
+ # get -- return the next character from stdin. Watch out for lookahead. If
67
+ # the character is a control character, translate it to a space or linefeed.
68
+ def get()
69
+ c = @input.getc
70
+ return EOF if(!c)
71
+ c = c.chr
72
+ return c if (c >= " " || c == "\n" || c.unpack("c") == EOF)
73
+ return "\n" if (c == "\r")
74
+ return " "
75
+ end
76
+
77
+ # Get the next character without getting it.
78
+ def peek()
79
+ lookaheadChar = @input.getc
80
+ @input.ungetc(lookaheadChar)
81
+ return lookaheadChar.chr
82
+ end
83
+
84
+ # mynext -- get the next character, excluding comments.
85
+ # peek() is used to see if a '/' is followed by a '/' or '*'.
86
+ def mynext()
87
+ c = get
88
+ if (c == "/")
89
+ if(peek == "/")
90
+ while(true)
91
+ c = get
92
+ if (c <= "\n")
93
+ return c
94
+ end
95
+ end
96
+ end
97
+ if(peek == "*")
98
+ get
99
+ while(true)
100
+ case get
101
+ when "*"
102
+ if (peek == "/")
103
+ get
104
+ return " "
105
+ end
106
+ when EOF
107
+ raise "Unterminated comment"
108
+ end
109
+ end
110
+ end
111
+ end
112
+ return c
113
+ end
114
+
115
+ # action -- do something! What you do is determined by the argument: 1
116
+ # Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B.
117
+ # (Delete A). 3 Get the next B. (Delete B). action treats a string as a
118
+ # single character. Wow! action recognizes a regular expression if it is
119
+ # preceded by ( or , or =.
120
+ def action(a)
121
+ if(a==1)
122
+ @output.write @theA
123
+ end
124
+ if(a==1 || a==2)
125
+ @theA = @theB
126
+ if (@theA == "\'" || @theA == "\"")
127
+ while (true)
128
+ @output.write @theA
129
+ @theA = get
130
+ break if (@theA == @theB)
131
+ raise "Unterminated string literal" if (@theA <= "\n")
132
+ if (@theA == "\\")
133
+ # allow multi-line strings if each line is terminated by \\n (or \\r\n)
134
+ if ["\r", "\n"].include? peek
135
+ get # throw away the line ending
136
+ get if ["\r", "\n"].include? peek
137
+ else
138
+ @output.write @theA
139
+ end
140
+ @theA = get
141
+ end
142
+ end
143
+ end
144
+ end
145
+ if(a==1 || a==2 || a==3)
146
+ @theB = mynext
147
+ if (@theB == "/" && (@theA == "(" || @theA == "," || @theA == "=" ||
148
+ @theA == ":" || @theA == "[" || @theA == "!" ||
149
+ @theA == "&" || @theA == "|" || @theA == "?" ||
150
+ @theA == "{" || @theA == "}" || @theA == ";" ||
151
+ @theA == "\n"))
152
+ @output.write @theA
153
+ @output.write @theB
154
+ while (true)
155
+ @theA = get
156
+ if (@theA == "/")
157
+ break
158
+ elsif (@theA == "\\")
159
+ @output.write @theA
160
+ @theA = get
161
+ elsif (@theA <= "\n")
162
+ raise "Unterminated RegExp Literal"
163
+ end
164
+ @output.write @theA
165
+ end
166
+ @theB = mynext
167
+ end
168
+ end
169
+ end
170
+
171
+ # jsmin -- Copy the input to the output, deleting the characters which are
172
+ # insignificant to JavaScript. Comments will be removed. Tabs will be
173
+ # replaced with spaces. Carriage returns will be replaced with linefeeds.
174
+ # Most spaces and linefeeds will be removed.
175
+ def jsmin
176
+ @theA = "\n"
177
+ action(3)
178
+ while (@theA != EOF)
179
+ case @theA
180
+ when " "
181
+ if (isAlphanum(@theB))
182
+ action(1)
183
+ else
184
+ action(2)
185
+ end
186
+ when "\n"
187
+ case (@theB)
188
+ when "{","[","(","+","-"
189
+ action(1)
190
+ when " "
191
+ action(3)
192
+ else
193
+ if (isAlphanum(@theB))
194
+ action(1)
195
+ else
196
+ action(2)
197
+ end
198
+ end
199
+ else
200
+ case (@theB)
201
+ when " "
202
+ if (isAlphanum(@theA))
203
+ action(1)
204
+ else
205
+ action(3)
206
+ end
207
+ when "\n"
208
+ case (@theA)
209
+ when "}","]",")","+","-","\"","\\", "'", '"'
210
+ action(1)
211
+ else
212
+ if (isAlphanum(@theA))
213
+ action(1)
214
+ else
215
+ action(3)
216
+ end
217
+ end
218
+ else
219
+ action(1)
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end # Javascript
225
+ end # Smurf
@@ -0,0 +1,34 @@
1
+ module Smurf
2
+ class Stylesheet
3
+ def initialize(content)
4
+ @content = content.nil? ? nil : minify(content)
5
+ end
6
+
7
+ def minified; @content; end
8
+
9
+ # TODO: deal with string values better (urls, content blocks, etc.)
10
+ def minify(content)
11
+ class << content; include Minifier; end
12
+ content.compress_whitespace.remove_comments.remove_spaces_outside_block.
13
+ remove_spaces_inside_block.trim_last_semicolon.strip
14
+ end
15
+
16
+ module Minifier
17
+ # .*? is a non-greedy match on anything
18
+ def compress_whitespace; compress!(/\s+/, ' '); end
19
+ def remove_comments; compress!(/\/\*.*?\*\/\s?/, ''); end
20
+ def remove_spaces_outside_block
21
+ compress!(/(\A|\})(.*?)\{/) { |m| m.gsub(/\s?([}{,])\s?/, '\1') }
22
+ end
23
+ def remove_spaces_inside_block
24
+ compress!(/\{(.*?)(?=\})/) do |m|
25
+ # remove spaces in the labels/attributes
26
+ m.gsub(/(?:\A|\s*;)(.*?)(?::\s*|\z)/) { |n| n.gsub(/\s/, '') }.strip
27
+ end
28
+ end
29
+ def trim_last_semicolon; compress!(/;(?=\})/, ''); end
30
+ private
31
+ def compress!(*args, &block) gsub!(*args, &block) || self; end
32
+ end
33
+ end # Stylesheet
34
+ end # Smurf
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'smurf'
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,109 @@
1
+ # Don't change this file!
2
+ # Configure your app in config/environment.rb and config/environments/*.rb
3
+
4
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
+
6
+ module Rails
7
+ class << self
8
+ def boot!
9
+ unless booted?
10
+ preinitialize
11
+ pick_boot.run
12
+ end
13
+ end
14
+
15
+ def booted?
16
+ defined? Rails::Initializer
17
+ end
18
+
19
+ def pick_boot
20
+ (vendor_rails? ? VendorBoot : GemBoot).new
21
+ end
22
+
23
+ def vendor_rails?
24
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
25
+ end
26
+
27
+ def preinitialize
28
+ load(preinitializer_path) if File.exist?(preinitializer_path)
29
+ end
30
+
31
+ def preinitializer_path
32
+ "#{RAILS_ROOT}/config/preinitializer.rb"
33
+ end
34
+ end
35
+
36
+ class Boot
37
+ def run
38
+ load_initializer
39
+ Rails::Initializer.run(:set_load_path)
40
+ end
41
+ end
42
+
43
+ class VendorBoot < Boot
44
+ def load_initializer
45
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
+ Rails::Initializer.run(:install_gem_spec_stubs)
47
+ end
48
+ end
49
+
50
+ class GemBoot < Boot
51
+ def load_initializer
52
+ self.class.load_rubygems
53
+ load_rails_gem
54
+ require 'initializer'
55
+ end
56
+
57
+ def load_rails_gem
58
+ if version = self.class.gem_version
59
+ gem 'rails', version
60
+ else
61
+ gem 'rails'
62
+ end
63
+ rescue Gem::LoadError => load_error
64
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
65
+ exit 1
66
+ end
67
+
68
+ class << self
69
+ def rubygems_version
70
+ Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
71
+ end
72
+
73
+ def gem_version
74
+ if defined? RAILS_GEM_VERSION
75
+ RAILS_GEM_VERSION
76
+ elsif ENV.include?('RAILS_GEM_VERSION')
77
+ ENV['RAILS_GEM_VERSION']
78
+ else
79
+ parse_gem_version(read_environment_rb)
80
+ end
81
+ end
82
+
83
+ def load_rubygems
84
+ require 'rubygems'
85
+ min_version = '1.1.1'
86
+ unless rubygems_version >= min_version
87
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
88
+ exit 1
89
+ end
90
+
91
+ rescue LoadError
92
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93
+ exit 1
94
+ end
95
+
96
+ def parse_gem_version(text)
97
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
98
+ end
99
+
100
+ private
101
+ def read_environment_rb
102
+ File.read("#{RAILS_ROOT}/config/environment.rb")
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ # All that for this:
109
+ Rails.boot!
@@ -0,0 +1,24 @@
1
+ # Be sure to restart your server when you modify this file
2
+
3
+ # Uncomment below to force Rails into production mode when
4
+ # you don't control web/app server and can't set it the proper way
5
+ # ENV['RAILS_ENV'] ||= 'production'
6
+
7
+ # Specifies gem version of Rails to use when vendor/rails is not present
8
+ unless defined? RAILS_GEM_VERSION
9
+ RAILS_GEM_VERSION = (ENV['RAILS_GEM_VERSION'] || '2.3.2')
10
+ end
11
+
12
+ # Bootstrap the Rails environment, frameworks, and default configuration
13
+ require File.join(File.dirname(__FILE__), 'boot')
14
+
15
+ Rails::Initializer.run do |config|
16
+ config.gem 'thoughtbot-shoulda', :lib => 'shoulda/rails',
17
+ :source => 'http://gems.github.com'
18
+ config.gem 'sqlite3-ruby', :lib => 'sqlite3'
19
+
20
+ config.action_controller.session = {
21
+ :session_key => '_smurf_session',
22
+ :secret => '731d6426b731d6426b731d6426b731d6426b731d6426b731d6426b731d6426b'
23
+ }
24
+ end
@@ -0,0 +1,19 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Tell ActionMailer not to deliver emails to the real world.
17
+ # The :test delivery method accumulates sent emails in the
18
+ # ActionMailer::Base.deliveries array.
19
+ config.action_mailer.delivery_method = :test
@@ -0,0 +1,5 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.connect ':controller/service.wsdl', :action => 'wsdl'
3
+ map.connect ':controller/:action/:id.:format'
4
+ map.connect ':controller/:action/:id'
5
+ end
@@ -0,0 +1,82 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class SmurfTest < Test::Unit::TestCase
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Helpers::AssetTagHelper
6
+
7
+ # Javascript
8
+
9
+ context "when caching on for javascript" do
10
+ setup do
11
+ ActionController::Base.stubs(:perform_caching).returns(true)
12
+ javascript_include_tag('testing.js', :cache => 'cache/actual')
13
+ end
14
+
15
+ should_have_same_contents('javascripts/cache/expected.js',
16
+ 'javascripts/cache/actual.js')
17
+ end # when caching on for javascript
18
+
19
+ context "minifying multi-line strings in javascript" do
20
+ setup do
21
+ input = StringIO.new()
22
+ input.puts("var foo='bar \\")
23
+ input.puts(" bar \\")
24
+ input.puts(" baz';")
25
+ input.rewind
26
+ @content = input.read
27
+ end
28
+
29
+ should "not affect the string" do
30
+ expected = "\n" + @content.gsub(/\\?\r?\n/, '')
31
+ assert_equal expected, Smurf::Javascript.new(@content).minified
32
+ end
33
+ end
34
+
35
+ # Stylesheet
36
+
37
+ context "when caching on for stylesheets" do
38
+ setup do
39
+ ActionController::Base.stubs(:perform_caching).returns(true)
40
+ stylesheet_link_tag('foo', 'bar', :cache => 'cache/actual')
41
+ end
42
+
43
+ should_have_same_contents('stylesheets/cache/expected.css',
44
+ 'stylesheets/cache/actual.css')
45
+ end # when caching on for stylesheets
46
+
47
+ context "minifying a non-existent pattern in a stylesheet" do
48
+ setup {@himom = "hi{mom:super-awesome}"}
49
+
50
+ # Thanks to someone named Niko for finding this
51
+ should "succeed for removing comments" do
52
+ actual = "hi { mom: super-awesome; } "
53
+ assert_equal @himom, Smurf::Stylesheet.new(actual).minified
54
+ end
55
+
56
+ should "succeed when no spaces to compress" do
57
+ actual = @himom
58
+ assert_equal @himom, Smurf::Stylesheet.new(actual).minified
59
+ end
60
+
61
+ should "succeed when no outside or inside blocks" do
62
+ # nothing outside, means nothing inside. they are complementary
63
+ actual = "how-did: this-happen; typo: maybe;}"
64
+ expected = "how-did: this-happen; typo: maybe}"
65
+ assert_equal expected, Smurf::Stylesheet.new(actual).minified
66
+ end
67
+
68
+ should "succeed when no last semi-colon in block" do
69
+ actual = "hi { mom: super-awesome } "
70
+ assert_equal @himom, Smurf::Stylesheet.new(actual).minified
71
+ end
72
+
73
+ should "succeed across all parsers when no content provided" do
74
+ actual = ""
75
+ assert_equal "", Smurf::Stylesheet.new(actual).minified
76
+ end
77
+
78
+ should "succeed if nil provided" do
79
+ assert_nil Smurf::Stylesheet.new(nil).minified
80
+ end
81
+ end # minifying a non-existent pattern
82
+ end
@@ -0,0 +1,32 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ ENV["RAILS_ROOT"] = File.expand_path(File.join(File.dirname(__FILE__), 'rails'))
3
+ require File.expand_path(File.join(ENV["RAILS_ROOT"], 'config', 'environment'))
4
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'init'))
5
+
6
+ require 'test_help'
7
+ require 'ruby-debug'
8
+
9
+ class Test::Unit::TestCase
10
+
11
+ def teardown
12
+ artifacts = Dir.glob(File.join(asset_path, '**', 'cache', 'actual.*'))
13
+ FileUtils.rm(artifacts)
14
+ end
15
+
16
+ def self.should_have_same_contents(expected_path, actual_path)
17
+ should "have the same file contents as #{expected_path}" do
18
+ expected = read_asset_file(expected_path)
19
+ actual = read_asset_file(actual_path)
20
+ assert_equal expected, actual
21
+ end
22
+ end
23
+
24
+ private
25
+ def asset_path
26
+ File.join(File.join(ENV["RAILS_ROOT"], 'public'))
27
+ end
28
+
29
+ def read_asset_file(relative_path)
30
+ File.read(File.join(asset_path, relative_path))
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: perfectline-smurf
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Justin Knowlden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-24 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Rails plugin to automatically minify JS and CSS when their bundles get cached. Send in those patches!
17
+ email: gus@thumblemonks.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - README.markdown
26
+ - Rakefile
27
+ - VERSION.yml
28
+ - lib/smurf.rb
29
+ - lib/smurf/javascript.rb
30
+ - lib/smurf/stylesheet.rb
31
+ - rails/init.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/thumblemonks/smurf
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Rails plugin to automatically minify JS and CSS when their bundles get cached
58
+ test_files:
59
+ - test/rails/app/controllers/application.rb
60
+ - test/rails/config/boot.rb
61
+ - test/rails/config/environment.rb
62
+ - test/rails/config/environments/test.rb
63
+ - test/rails/config/routes.rb
64
+ - test/smurf_test.rb
65
+ - test/test_helper.rb