paste 0.2.1 → 0.2.2
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.
- data/lib/paste/capistrano.rb +6 -0
- data/lib/paste/js/cache.rb +21 -12
- data/lib/paste/rails/helper.rb +3 -2
- data/lib/paste/tasks/paste.rake +6 -1
- data/lib/paste/version.rb +1 -1
- data/spec/paste/css/provides_spec.rb +29 -0
- data/spec/paste/js/cache_spec.rb +47 -0
- data/spec/paste/js/chain_spec.rb +133 -0
- data/spec/paste/js/compress_spec.rb +43 -0
- data/spec/paste/js/config_spec.rb +35 -0
- data/spec/paste/js/erb_spec.rb +106 -0
- data/spec/paste/js/unify_spec.rb +90 -0
- data/spec/paste/rails/helper_spec.rb +117 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/helpers.rb +74 -0
- data/spec/support/matchers.rb +45 -0
- metadata +32 -81
- data/VERSION +0 -1
data/lib/paste/capistrano.rb
CHANGED
@@ -13,6 +13,12 @@ Capistrano::Configuration.instance(true).load do
|
|
13
13
|
"rake RAILS_ENV=#{env} paste:rebuild; echo ''"
|
14
14
|
end
|
15
15
|
|
16
|
+
task :compress do
|
17
|
+
env = exists?(:rails_env) ? rails_env : 'production'
|
18
|
+
run "cd #{latest_release} && " +
|
19
|
+
"rake RAILS_ENV=#{env} paste:compress"
|
20
|
+
end
|
21
|
+
|
16
22
|
desc "Create a directory for caching javascript and such"
|
17
23
|
task :create_cache do
|
18
24
|
run "mkdir -p #{shared_path}/paste-cache"
|
data/lib/paste/js/cache.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/module/synchronization'
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
|
3
5
|
module Paste
|
@@ -28,14 +30,16 @@ module Paste
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
def register sources
|
32
|
-
|
33
|
-
|
33
|
+
def register sources, into_hash = nil
|
34
|
+
into_hash ||= results
|
35
|
+
|
36
|
+
if into_hash[result_name(sources)][:sources] != sources
|
37
|
+
into_hash[result_name(sources)] = {
|
34
38
|
:sources => sources,
|
35
39
|
:parser => config.parser.new(self, sources)
|
36
40
|
}
|
37
41
|
|
38
|
-
write_cache_to_disk
|
42
|
+
write_cache_to_disk into_hash
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -57,23 +61,28 @@ module Paste
|
|
57
61
|
|
58
62
|
def results
|
59
63
|
return @results if defined?(@results)
|
64
|
+
|
60
65
|
@results = Hash.new { {} }
|
61
66
|
|
62
67
|
begin
|
63
68
|
cached = YAML.load_file tmp_path(config.cache_file)
|
64
|
-
rescue
|
65
|
-
cached = []
|
66
|
-
end
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
+
if cached
|
71
|
+
cached.each do |sources|
|
72
|
+
register sources, @results
|
73
|
+
end
|
74
|
+
end
|
75
|
+
rescue
|
70
76
|
end
|
71
77
|
|
72
78
|
@results
|
73
79
|
end
|
74
80
|
|
81
|
+
@@results_lock = Mutex.new
|
82
|
+
synchronize :results, :with => :@@results_lock
|
83
|
+
|
75
84
|
protected
|
76
|
-
|
85
|
+
|
77
86
|
def needs_update_relative_to_sources result
|
78
87
|
path = destination result
|
79
88
|
return true unless File.exists?(path) && results.key?(result)
|
@@ -83,12 +92,12 @@ module Paste
|
|
83
92
|
end
|
84
93
|
end
|
85
94
|
|
86
|
-
def write_cache_to_disk
|
95
|
+
def write_cache_to_disk cache
|
87
96
|
file = tmp_path config.cache_file
|
88
97
|
FileUtils.mkdir_p File.dirname(file)
|
89
98
|
|
90
99
|
to_write = []
|
91
|
-
|
100
|
+
cache.each do |result, hash|
|
92
101
|
to_write << hash[:sources]
|
93
102
|
end
|
94
103
|
|
data/lib/paste/rails/helper.rb
CHANGED
@@ -18,9 +18,10 @@ module Paste
|
|
18
18
|
|
19
19
|
results = Paste::Rails.glue.paste *(@javascripts ||= [])
|
20
20
|
all_css = (results[:css] + @css).uniq
|
21
|
-
|
21
|
+
|
22
22
|
cache = Digest::SHA1.hexdigest(all_css.sort.join)[0..12]
|
23
|
-
all_css << {:cache => cache}
|
23
|
+
all_css << {:cache => cache} unless Paste::CSS.config.no_cache
|
24
|
+
|
24
25
|
stylesheet_link_tag *all_css
|
25
26
|
end
|
26
27
|
|
data/lib/paste/tasks/paste.rake
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
namespace :paste do
|
2
|
-
desc 'Rebuild all cached javascripts
|
2
|
+
desc 'Rebuild all cached javascripts'
|
3
3
|
task :rebuild => :environment do
|
4
|
+
Paste::Rails.glue.rebuild!
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Compress all cached javascripts'
|
8
|
+
task :compress => :environment do
|
4
9
|
Paste::Rails.glue.rebuild! :compress => 'google'
|
5
10
|
end
|
6
11
|
end
|
data/lib/paste/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'a css provider' do
|
4
|
+
before :each do
|
5
|
+
Paste::JS::Test.write 'foo', '//= require_css <foo>'
|
6
|
+
Paste::CSS::Test.write 'foo', ''
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should require the css" do
|
10
|
+
result = subject.paste 'foo'
|
11
|
+
result[:css].should == ['foo']
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should not require multiple css twice" do
|
15
|
+
Paste::JS::Test.write 'bar', '//= require_css <foo>'
|
16
|
+
|
17
|
+
subject.paste('foo', 'bar')[:css].should == ['foo']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'Providing CSS from javascript' do
|
22
|
+
describe Paste::JS::Unify do
|
23
|
+
it_should_behave_like 'a css provider'
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Paste::JS::Chain do
|
27
|
+
it_should_behave_like 'a css provider'
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::JS::Unify, 'building cached concatenations' do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
Paste::JS::Test.write 'foo', 'foo()'
|
7
|
+
Paste::JS::Test.write 'bar', 'bar()'
|
8
|
+
Paste::JS::Test.write 'foo/baz', 'baz()'
|
9
|
+
|
10
|
+
@result = subject.paste('foo', 'bar', 'foo/baz')[:javascript].first
|
11
|
+
Paste::JS::Test.delete @result
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should rebuild within the same instance of the unifier" do
|
15
|
+
subject.rebuild!
|
16
|
+
|
17
|
+
subject.should have_in_result(@result, "foo()\nbar()\nbaz()")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow another watcher to rebuild it" do
|
21
|
+
subject = Paste::JS::Unify.new
|
22
|
+
subject.rebuild!
|
23
|
+
|
24
|
+
subject.should have_in_result(@result, "foo()\nbar()\nbaz()")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should rebuild pre-existing results despite modification times" do
|
28
|
+
# Make the file exist and have the last modified time of the sources
|
29
|
+
# to be previous to now
|
30
|
+
subject.paste('foo', 'bar', 'foo/baz')
|
31
|
+
Paste::JS::Test.write 'foo', 'foo2()', Time.now - 42
|
32
|
+
Paste::JS::Test.write 'bar', 'bar2()', Time.now - 42
|
33
|
+
Paste::JS::Test.write 'foo/baz', 'baz2()', Time.now - 42
|
34
|
+
|
35
|
+
subject.rebuild!
|
36
|
+
|
37
|
+
subject.should have_in_result(@result, "foo2()\nbar2()\nbaz2()")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should ignore cached results which no longer exist" do
|
41
|
+
Paste::JS::Test.delete_source 'foo'
|
42
|
+
Paste::JS::Test.delete_source 'bar'
|
43
|
+
|
44
|
+
subject.rebuild!
|
45
|
+
subject.destination(@result).should_not exist
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::JS::Chain do
|
4
|
+
before :each do
|
5
|
+
Paste::JS::Test.write 'foo', 'foo()'
|
6
|
+
Paste::JS::Test.write 'bar', 'bar()'
|
7
|
+
Paste::JS::Test.write 'foo/baz', 'baz()'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return the sources given" do
|
11
|
+
results = subject.paste('foo', 'bar', 'foo/baz')[:javascript]
|
12
|
+
|
13
|
+
results.sort.should == ['bar.js', 'foo.js', 'foo/baz.js']
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate the concatenation when the destination doesn't exist" do
|
17
|
+
subject.paste('foo', 'bar', 'foo/baz')
|
18
|
+
|
19
|
+
subject.should have_in_result('foo', 'foo()')
|
20
|
+
subject.should have_in_result('bar', 'bar()')
|
21
|
+
subject.should have_in_result('foo/baz', 'baz()')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return the sources with dependencies satisfied" do
|
25
|
+
Paste::JS::Test.write 'foo', "//= require <foo/bar>\n//= require <bar>"
|
26
|
+
Paste::JS::Test.write 'bar', '//= require <foo/bar>'
|
27
|
+
Paste::JS::Test.write 'foo/bar', 'foobar()'
|
28
|
+
|
29
|
+
subject.paste('foo', 'bar', 'foo/bar')[:javascript].should == ['foo/bar.js', 'bar.js', 'foo.js']
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise an exception on circular dependencies" do
|
33
|
+
Paste::JS::Test.write 'foo', '//= require <bar>'
|
34
|
+
Paste::JS::Test.write 'bar', '//= require <foo>'
|
35
|
+
|
36
|
+
lambda {
|
37
|
+
subject.paste('foo', 'bar')
|
38
|
+
}.should raise_exception(/circular dependency/i)
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "regenerating files" do
|
42
|
+
it "should only regenerate modified files" do
|
43
|
+
subject.paste('foo', 'bar', 'foo/baz')
|
44
|
+
|
45
|
+
Paste::JS::Test.write 'foo', 'foo(foo)', Time.now - 42
|
46
|
+
Paste::JS::Test.write 'bar', 'bar(bar)', Time.now + 42
|
47
|
+
|
48
|
+
subject.paste('foo', 'bar', 'foo/baz')
|
49
|
+
|
50
|
+
subject.should have_in_result('foo', 'foo()')
|
51
|
+
subject.should have_in_result('bar', 'bar(bar)')
|
52
|
+
subject.should have_in_result('foo/baz', 'baz()')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should update the results only if the sources have changed" do
|
56
|
+
subject = described_class.new
|
57
|
+
|
58
|
+
subject.paste('foo')
|
59
|
+
subject.paste('bar')
|
60
|
+
Paste::JS::Test.write 'foo', 'foobar()', Time.now - 42
|
61
|
+
Paste::JS::Test.write 'bar', 'barbar()', Time.now + 42
|
62
|
+
|
63
|
+
subject.rebuild
|
64
|
+
|
65
|
+
subject.should have_in_result('foo', 'foo()')
|
66
|
+
subject.should have_in_result('bar', 'barbar()')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should watch for changes in dependencies as well" do
|
70
|
+
Paste::JS::Test.write 'foo', '//= require <bar>'
|
71
|
+
Paste::JS::Test.write 'bar', ''
|
72
|
+
Paste::JS::Test.write 'baz', ''
|
73
|
+
subject.paste('foo')
|
74
|
+
|
75
|
+
Paste::JS::Test.write 'bar', '//= require <baz>', Time.now + 42
|
76
|
+
|
77
|
+
subject.paste('foo')[:javascript].should == ['baz.js', 'bar.js', 'foo.js']
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should watch for changes in dependencies as well" do
|
81
|
+
Paste::JS::Test.write 'foo', '//= require <bar>'
|
82
|
+
Paste::JS::Test.write 'bar', ''
|
83
|
+
Paste::JS::Test.write 'baz', ''
|
84
|
+
subject.paste('foo')
|
85
|
+
|
86
|
+
Paste::JS::Test.write 'bar', '//= require <baz>', Time.now + 42
|
87
|
+
|
88
|
+
subject.paste('foo')[:javascript].should == ['baz.js', 'bar.js', 'foo.js']
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should watch for changes in very deep dependencies" do
|
92
|
+
Paste::JS::Test.write 'foo', ''
|
93
|
+
Paste::JS::Test.write 'bar', ''
|
94
|
+
subject.paste('foo')
|
95
|
+
|
96
|
+
Paste::JS::Test.write 'foo', '//= require <bar>', Time.now + 42
|
97
|
+
|
98
|
+
subject.paste('foo')[:javascript].should == ['bar.js', 'foo.js']
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should update dependencies when they've been rewritten using rebuild" do
|
102
|
+
Paste::JS::Test.write 'foo', ''
|
103
|
+
Paste::JS::Test.write 'baz', 'foobar'
|
104
|
+
|
105
|
+
subject.paste('foo')
|
106
|
+
Paste::JS::Test.write 'foo', '//= require <baz>', Time.now + 42
|
107
|
+
subject.rebuild
|
108
|
+
Paste::JS::Test.touch 'foo', Time.now - 1
|
109
|
+
|
110
|
+
@result = subject.paste('foo')[:javascript].should == ['baz.js', 'foo.js']
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "implicit dependencies" do
|
115
|
+
before :each do
|
116
|
+
Paste::JS::Test.write 'foo', ''
|
117
|
+
Paste::JS::Test.write 'bar', '//= require <foo>'
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be included when pasting" do
|
121
|
+
subject.paste('bar')[:javascript].should == ['foo.js', 'bar.js']
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should be regenerated" do
|
125
|
+
result = subject.paste('bar')[:javascript].first
|
126
|
+
|
127
|
+
Paste::JS::Test.write 'foo', 'foobar()', Time.now + 42
|
128
|
+
|
129
|
+
subject.paste('bar')
|
130
|
+
subject.should have_in_result(result, 'foobar()')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::JS::Unify, 'compression' do
|
4
|
+
before :each do
|
5
|
+
Paste::JS::Test.write 'foo', "function foo() {};\n foo()"
|
6
|
+
Paste::JS::Test.write 'bar', "function bar() {};\n bar()"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should not compress the files when pasting" do
|
10
|
+
result = subject.paste('foo')[:javascript].first
|
11
|
+
|
12
|
+
subject.should have_in_result(result, "function foo() {};\n foo()")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should compress the previously generated result" do
|
16
|
+
result = subject.paste('foo', 'bar')[:javascript].first
|
17
|
+
|
18
|
+
begin
|
19
|
+
subject.rebuild! :compress => 'google'
|
20
|
+
rescue SocketError
|
21
|
+
pending 'Error connecting to google'
|
22
|
+
end
|
23
|
+
|
24
|
+
contents = File.read subject.destination(result)
|
25
|
+
contents.should_not contain("\n")
|
26
|
+
contents.should =~ /function/
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow the compilation level to be specified" do
|
30
|
+
result = subject.paste('foo', 'bar')[:javascript].first
|
31
|
+
|
32
|
+
begin
|
33
|
+
subject.rebuild! :compress => 'google',
|
34
|
+
:compilation_level => 'ADVANCED_OPTIMIZATIONS'
|
35
|
+
rescue SocketError
|
36
|
+
pending 'Error connecting to google'
|
37
|
+
end
|
38
|
+
|
39
|
+
# Everything should be optimized out
|
40
|
+
subject.should have_in_result(result, '')
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::Glue, 'configuration' do
|
4
|
+
it "should resolve absolute paths correctly" do
|
5
|
+
absolute = File.expand_path(__FILE__)
|
6
|
+
subject.resolve(absolute).should == absolute
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should resolve a non-absolute path relative to the specified root" do
|
10
|
+
subject.config.root = '/foo/bar'
|
11
|
+
subject.resolve('nonexistent').should == '/foo/bar/nonexistent'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should allow relative paths to the root to be set for configuration" do
|
15
|
+
subject.config.root = '/foo/bar'
|
16
|
+
subject.config.tmp_path = 'tmp'
|
17
|
+
subject.config.erb_path = 'erb'
|
18
|
+
subject.config.destination = 'dst'
|
19
|
+
|
20
|
+
subject.tmp_path.should == '/foo/bar/tmp'
|
21
|
+
subject.erb_path.should == '/foo/bar/erb'
|
22
|
+
subject.destination.should == '/foo/bar/dst'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow absolute paths to the root to be set for configuration" do
|
26
|
+
subject.config.root = '/foo/bar'
|
27
|
+
subject.config.tmp_path = '/tmp'
|
28
|
+
subject.config.erb_path = '/erb'
|
29
|
+
subject.config.destination = '/dst'
|
30
|
+
|
31
|
+
subject.tmp_path.should == '/tmp'
|
32
|
+
subject.erb_path.should == '/erb'
|
33
|
+
subject.destination.should == '/dst'
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::JS::Base do
|
4
|
+
|
5
|
+
it "should render an erb file into a temporary location" do
|
6
|
+
Paste::JS::Test.write 'foo.js.erb', ''
|
7
|
+
subject.render_all_erb
|
8
|
+
|
9
|
+
subject.erb_path('foo.js').should exist
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should execute the ERB in the file" do
|
13
|
+
Paste::JS::Test.write 'foo.js.erb', '<%= "foo" %><%= "bar" %>'
|
14
|
+
subject.render_all_erb
|
15
|
+
|
16
|
+
subject.erb_path('foo.js').should have_contents('foobar')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should handle deeply nested erb files alright" do
|
20
|
+
Paste::JS::Test.write 'foo/bar/baz.js.erb', '<%= "foo" %><%= "bar" %>'
|
21
|
+
subject.render_all_erb
|
22
|
+
|
23
|
+
subject.erb_path('foo/bar/baz.js').should have_contents('foobar')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "shouldn't try to render regular js files" do
|
27
|
+
Paste::JS::Test.write 'foo', 'foo()'
|
28
|
+
subject.render_all_erb
|
29
|
+
|
30
|
+
subject.erb_path('foo.js').should_not exist
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should render when being rebuilt" do
|
34
|
+
Paste::JS::Test.write 'foo.js.erb', 'foobar'
|
35
|
+
subject.rebuild!
|
36
|
+
|
37
|
+
subject.erb_path('foo.js').should have_contents('foobar')
|
38
|
+
end
|
39
|
+
|
40
|
+
context "pasting a variety of regular/erb files" do
|
41
|
+
shared_examples_for 'an erb paster' do
|
42
|
+
it "should use the generated ERB file when pasting" do
|
43
|
+
Paste::JS::Test.write 'foo.js.erb', '<%= "foo" %><%= "bar" %>'
|
44
|
+
Paste::JS::Test.write 'bar', "//= require <foo>\nbar()"
|
45
|
+
subject.render_all_erb
|
46
|
+
|
47
|
+
subject.paste('bar')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should watch for a file to be changed to an ERB file" do
|
51
|
+
Paste::JS::Test.write 'foo', 'foo'
|
52
|
+
result = subject.paste('foo')[:javascript]
|
53
|
+
result.each{ |p| Paste::JS::Test.delete p }
|
54
|
+
Paste::JS::Test.delete_source 'foo'
|
55
|
+
|
56
|
+
Paste::JS::Test.write 'foo.js.erb', '<%= "foo" %><%= "bar" %>'
|
57
|
+
subject.render_all_erb
|
58
|
+
|
59
|
+
subject.paste('foo')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Paste::JS::Chain do
|
64
|
+
it_should_behave_like 'an erb paster'
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Paste::JS::Unify do
|
68
|
+
it_should_behave_like 'an erb paster'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "modifying existing files" do
|
73
|
+
before :each do
|
74
|
+
Paste::JS::Test.write subject.erb_path('foo.js'), 'foo'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should regenerate the file if the source was modified" do
|
78
|
+
# File is modified after the original one
|
79
|
+
Paste::JS::Test.write 'foo.js.erb', 'foobar', Time.now + 42
|
80
|
+
|
81
|
+
subject.render_all_erb
|
82
|
+
|
83
|
+
subject.erb_path('foo.js').should have_contents('foobar')
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not regenerate the file if the source was not modified" do
|
87
|
+
Paste::JS::Test.write 'foo.js.erb', 'foobar', Time.now - 42
|
88
|
+
subject.render_all_erb
|
89
|
+
|
90
|
+
subject.erb_path('foo.js').should have_contents('foo')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "rails" do
|
95
|
+
before :each do
|
96
|
+
Rails = {:foo => 'bar'}
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should allow templates to use Rails instead of ::Rails" do
|
100
|
+
Paste::JS::Test.write 'foo.js.erb', '<%= Rails[:foo] %>'
|
101
|
+
subject.render_all_erb
|
102
|
+
|
103
|
+
subject.erb_path('foo.js').should have_contents('bar')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::JS::Unify do
|
4
|
+
before :each do
|
5
|
+
Paste::JS::Test.write 'foo', 'foo()'
|
6
|
+
Paste::JS::Test.write 'bar', 'bar()'
|
7
|
+
Paste::JS::Test.write 'foo/baz', 'baz()'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should generate only one result" do
|
11
|
+
results = subject.paste('foo', 'bar', 'foo/baz')[:javascript]
|
12
|
+
|
13
|
+
results.size.should == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate the same results for different forms of the input" do
|
17
|
+
results = subject.paste('foo', 'bar', 'foo/baz')
|
18
|
+
|
19
|
+
results.should == subject.paste('foo', 'foo/baz.js', 'bar.js')
|
20
|
+
results.should == subject.paste('bar', 'foo.js', 'foo/baz')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate the concatenation when the destination doesn't exist" do
|
24
|
+
result = subject.paste('foo', 'bar', 'foo/baz')[:javascript].first
|
25
|
+
|
26
|
+
subject.should have_in_result(result, "foo()\nbar()\nbaz()")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should rebuild the results after the file has been removed" do
|
30
|
+
result = subject.paste('foo', 'bar', 'foo/baz')[:javascript].first
|
31
|
+
|
32
|
+
Paste::JS::Test.delete result
|
33
|
+
subject.paste('foo', 'bar', 'foo/baz')
|
34
|
+
|
35
|
+
subject.should have_in_result(result, "foo()\nbar()\nbaz()")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise a descriptive exception when the source doesn't exist" do
|
39
|
+
lambda {
|
40
|
+
subject.paste 'random'
|
41
|
+
}.should raise_error(/source random/i)
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "regenerating files" do
|
45
|
+
it "should occur if any file is changed" do
|
46
|
+
result = subject.paste('foo', 'bar')[:javascript].first
|
47
|
+
|
48
|
+
Paste::JS::Test.write 'foo', 'foobar()', Time.now + 42
|
49
|
+
subject.paste('foo', 'bar')
|
50
|
+
|
51
|
+
subject.should have_in_result(result, "foobar()\nbar()")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not occur if no files have changed" do
|
55
|
+
result = subject.paste('foo', 'bar')[:javascript].first
|
56
|
+
|
57
|
+
Paste::JS::Test.write 'foo', 'foobar', Time.now - 42
|
58
|
+
subject.paste('foo', 'bar')
|
59
|
+
|
60
|
+
subject.should have_in_result(result, "foo()\nbar()")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should update the results only if the sources have changed" do
|
64
|
+
subject = described_class.new
|
65
|
+
|
66
|
+
result1 = subject.paste('foo')[:javascript].first
|
67
|
+
result2 = subject.paste('bar', 'foo/baz')[:javascript].first
|
68
|
+
Paste::JS::Test.write 'foo', 'foobar()', Time.now - 42
|
69
|
+
Paste::JS::Test.write 'bar', 'barbar()', Time.now + 42
|
70
|
+
|
71
|
+
subject.rebuild
|
72
|
+
|
73
|
+
subject.should have_in_result(result1, 'foo()')
|
74
|
+
subject.should have_in_result(result2, "barbar()\nbaz()")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should watch for changes in dependencies as well" do
|
78
|
+
Paste::JS::Test.write 'foo', "//= require <bar>\nfoo"
|
79
|
+
Paste::JS::Test.write 'bar', 'bar'
|
80
|
+
Paste::JS::Test.write 'baz', 'baz'
|
81
|
+
result = subject.paste('foo')[:javascript].first
|
82
|
+
|
83
|
+
Paste::JS::Test.write 'bar', "//= require <baz>\nbar", Time.now + 42
|
84
|
+
|
85
|
+
subject.paste('foo')
|
86
|
+
|
87
|
+
subject.should have_in_result(result, "baz\nbar\nfoo")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Paste::Rails::Helper do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@helper = Object.new
|
7
|
+
@helper.class.send :include, subject
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "working with javascript" do
|
11
|
+
it "should register the include_javascript method" do
|
12
|
+
@helper.include_javascript 'foobar'
|
13
|
+
|
14
|
+
@helper.included_javascripts.should == ['foobar']
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow multiple sources to be included at once" do
|
18
|
+
@helper.include_javascripts 'foo', 'bar'
|
19
|
+
|
20
|
+
@helper.included_javascripts.should == ['foo', 'bar']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "shouldn't allow multiple sources to be in the list" do
|
24
|
+
@helper.include_javascripts 'foo', 'bar'
|
25
|
+
@helper.include_javascript 'foo'
|
26
|
+
|
27
|
+
@helper.included_javascripts.should == ['foo', 'bar']
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should paste the sources when asked for" do
|
31
|
+
@helper.stub(:javascript_include_tag).and_return ''
|
32
|
+
@glue = mock(Paste::Glue)
|
33
|
+
Paste::Rails.stub(:glue).and_return(@glue)
|
34
|
+
|
35
|
+
@glue.should_receive(:paste).with('foo', 'bar').and_return(
|
36
|
+
:javascripts => [],
|
37
|
+
:css => []
|
38
|
+
)
|
39
|
+
|
40
|
+
@helper.include_javascript 'foo'
|
41
|
+
@helper.paste_js_tags 'bar'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return the javascript include tags" do
|
45
|
+
@helper.should_receive(:javascript_include_tag).with(
|
46
|
+
'foo', 'bar').and_return 'foo.js'
|
47
|
+
Paste::Rails.stub(:glue).and_return(
|
48
|
+
mock(Paste::Glue, :paste => {
|
49
|
+
:javascript => ['foo', 'bar'],
|
50
|
+
:css => ['bar/baz']
|
51
|
+
})
|
52
|
+
)
|
53
|
+
|
54
|
+
@helper.paste_js_tags('foo').should == 'foo.js'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "working with css" do
|
59
|
+
it "should register the include_css method" do
|
60
|
+
@helper.include_css 'foobar'
|
61
|
+
|
62
|
+
@helper.included_css.should == ['foobar']
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should allow multiple sources to be included at once" do
|
66
|
+
@helper.include_css 'foo', 'bar'
|
67
|
+
|
68
|
+
@helper.included_css.should == ['foo', 'bar']
|
69
|
+
end
|
70
|
+
|
71
|
+
it "shouldn't allow multiple sources to be in the list" do
|
72
|
+
@helper.include_css 'foo', 'bar'
|
73
|
+
@helper.include_css 'foo'
|
74
|
+
|
75
|
+
@helper.included_css.should == ['foo', 'bar']
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return the stylesheet link tags for what was included" do
|
79
|
+
@helper.include_css 'foo', 'bar'
|
80
|
+
@helper.should_receive(:stylesheet_link_tag).with(
|
81
|
+
'foo', 'bar', instance_of(Hash)).and_return 'foo.css'
|
82
|
+
Paste::Rails.stub(:glue).and_return(Paste::JS::Chain.new)
|
83
|
+
|
84
|
+
@helper.paste_css_tags.should == 'foo.css'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return the stylesheet link tags for what is specified" do
|
88
|
+
@helper.should_receive(:stylesheet_link_tag).with(
|
89
|
+
'foo', 'bar', instance_of(Hash)).and_return 'foo.css'
|
90
|
+
Paste::Rails.stub(:glue).and_return(Paste::JS::Chain.new)
|
91
|
+
|
92
|
+
@helper.paste_css_tags('foo', 'bar').should == 'foo.css'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should include css required by the javascript" do
|
96
|
+
Paste::JS::Test.write 'foo.js', '//= require_css <bar>'
|
97
|
+
@helper.include_javascript 'foo'
|
98
|
+
@helper.should_receive(:stylesheet_link_tag).with(
|
99
|
+
'bar', instance_of(Hash)).and_return 'bar.css'
|
100
|
+
|
101
|
+
@helper.paste_css_tags.should == 'bar.css'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "the default glue value" do
|
106
|
+
it "should be a unifier by default" do
|
107
|
+
Paste::Rails.glue.should be_a(Paste::JS::Unify)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should be swappable" do
|
111
|
+
@chain = Paste::JS::Chain
|
112
|
+
Paste::Rails.glue = @chain
|
113
|
+
|
114
|
+
Paste::Rails.glue.should == @chain
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'paste'
|
7
|
+
|
8
|
+
Paste::Glue.configure do |config|
|
9
|
+
config.root = File.expand_path('../tmp', __FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
Paste::JS.config.load_path = ['js_sources']
|
13
|
+
Paste::JS.config.destination = 'destination'
|
14
|
+
|
15
|
+
RSpec.configure do |c|
|
16
|
+
c.color_enabled = true
|
17
|
+
|
18
|
+
c.after(:each) do
|
19
|
+
FileUtils.rm_rf Paste::Glue.config.root
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Dir[File.dirname(__FILE__) + '/support/*.rb'].each { |f| load f }
|
@@ -0,0 +1,74 @@
|
|
1
|
+
def dump_tree
|
2
|
+
raise Dir[Paste::JS::Base.root + '/**/*'].map { |f|
|
3
|
+
unless File.directory?(f)
|
4
|
+
out = f
|
5
|
+
out += "\n\t- " + File.read(f).gsub("\n", "\n\t- ")
|
6
|
+
out += "\n\t\t(#{File.mtime(f)})"
|
7
|
+
f = out
|
8
|
+
end
|
9
|
+
f
|
10
|
+
}.join("\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
module Paste
|
14
|
+
module TestBase
|
15
|
+
def write source, contents, last_modified = Time.now
|
16
|
+
file = path source
|
17
|
+
FileUtils.mkdir_p File.dirname(file)
|
18
|
+
File.open(file, 'w') { |f| f << contents }
|
19
|
+
|
20
|
+
touch source, last_modified
|
21
|
+
end
|
22
|
+
|
23
|
+
def touch source, modified_time = Time.now
|
24
|
+
File.utime Time.now, modified_time, path(source)
|
25
|
+
end
|
26
|
+
|
27
|
+
def path source
|
28
|
+
return source if source.to_s[0...1] == '/'
|
29
|
+
|
30
|
+
file = File.join(base.load_path.first, source)
|
31
|
+
file += '.' + extension unless file.end_with?('.' + extension) ||
|
32
|
+
file.end_with?('.erb')
|
33
|
+
file
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete result
|
37
|
+
delete_file File.join(base.destination, result)
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete_source source
|
41
|
+
delete_file File.join(base.load_path.first, source)
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def delete_file file
|
47
|
+
file += '.' + extension unless file.end_with?('.' + extension)
|
48
|
+
|
49
|
+
File.delete(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
def base
|
53
|
+
Paste.const_get(extension.upcase).const_get('Base')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module JS::Test
|
58
|
+
extend TestBase
|
59
|
+
|
60
|
+
def self.extension
|
61
|
+
'js'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module CSS
|
66
|
+
module Test
|
67
|
+
extend TestBase
|
68
|
+
|
69
|
+
def self.extension
|
70
|
+
'css'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
def failed_not_contains_message file, contents
|
2
|
+
msg = "Expected #{file} to contain:\n\t#{contents.gsub("\n", "\n\t")}\nWhen"
|
3
|
+
|
4
|
+
if File.file?(file)
|
5
|
+
msg += " it contained:\n#{File.read(file)}".gsub("\n", "\n\t")
|
6
|
+
else
|
7
|
+
msg += ' it did not exist.'
|
8
|
+
end
|
9
|
+
|
10
|
+
msg
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Matchers.define :have_in_result do |result, contents|
|
14
|
+
result += '.js' unless result.end_with?('.js')
|
15
|
+
|
16
|
+
match do |glue|
|
17
|
+
File.join(glue.destination, result).should have_contents(contents)
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message do |glue|
|
21
|
+
failed_not_contains_message File.join(glue.destination, result), contents
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec::Matchers.define :have_contents do |contents|
|
26
|
+
match do |file|
|
27
|
+
File.file?(file) && File.read(file).chomp.should == contents.chomp
|
28
|
+
end
|
29
|
+
|
30
|
+
failure_message do |file|
|
31
|
+
failed_not_contains_message file, contents
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Matchers.define :exist do
|
36
|
+
match do |file|
|
37
|
+
File.exists?(file)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
RSpec::Matchers.define :contain do |substr|
|
42
|
+
match do |str|
|
43
|
+
!str.index(substr).nil?
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 2
|
9
|
+
version: 0.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alex Crichton
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-09-05 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -43,22 +43,9 @@ dependencies:
|
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: *id002
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: paste
|
48
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
segments:
|
54
|
-
- 0
|
55
|
-
version: "0"
|
56
|
-
type: :runtime
|
57
|
-
prerelease: false
|
58
|
-
version_requirements: *id003
|
59
46
|
- !ruby/object:Gem::Dependency
|
60
47
|
name: activesupport
|
61
|
-
requirement: &
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
62
49
|
none: false
|
63
50
|
requirements:
|
64
51
|
- - ">="
|
@@ -71,66 +58,9 @@ dependencies:
|
|
71
58
|
version: 3.0.0.beta4
|
72
59
|
type: :runtime
|
73
60
|
prerelease: false
|
74
|
-
version_requirements: *
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: jeweler
|
77
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
segments:
|
83
|
-
- 0
|
84
|
-
version: "0"
|
85
|
-
type: :development
|
86
|
-
prerelease: false
|
87
|
-
version_requirements: *id005
|
88
|
-
- !ruby/object:Gem::Dependency
|
89
|
-
name: rake
|
90
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
|
-
requirements:
|
93
|
-
- - ">="
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
segments:
|
96
|
-
- 0
|
97
|
-
version: "0"
|
98
|
-
type: :development
|
99
|
-
prerelease: false
|
100
|
-
version_requirements: *id006
|
101
|
-
- !ruby/object:Gem::Dependency
|
102
|
-
name: rcov
|
103
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
104
|
-
none: false
|
105
|
-
requirements:
|
106
|
-
- - ">="
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
segments:
|
109
|
-
- 0
|
110
|
-
version: "0"
|
111
|
-
type: :development
|
112
|
-
prerelease: false
|
113
|
-
version_requirements: *id007
|
114
|
-
- !ruby/object:Gem::Dependency
|
115
|
-
name: rspec
|
116
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
117
|
-
none: false
|
118
|
-
requirements:
|
119
|
-
- - ">="
|
120
|
-
- !ruby/object:Gem::Version
|
121
|
-
segments:
|
122
|
-
- 2
|
123
|
-
- 0
|
124
|
-
- 0
|
125
|
-
- beta
|
126
|
-
- 19
|
127
|
-
version: 2.0.0.beta.19
|
128
|
-
type: :development
|
129
|
-
prerelease: false
|
130
|
-
version_requirements: *id008
|
61
|
+
version_requirements: *id003
|
131
62
|
description: Asset Management for Rails
|
132
|
-
email:
|
133
|
-
- alex@alexcrichton.com
|
63
|
+
email: alex@alexcrichton.com
|
134
64
|
executables: []
|
135
65
|
|
136
66
|
extensions: []
|
@@ -138,8 +68,6 @@ extensions: []
|
|
138
68
|
extra_rdoc_files:
|
139
69
|
- README.rdoc
|
140
70
|
files:
|
141
|
-
- README.rdoc
|
142
|
-
- VERSION
|
143
71
|
- lib/paste.rb
|
144
72
|
- lib/paste/capistrano.rb
|
145
73
|
- lib/paste/css/base.rb
|
@@ -158,6 +86,18 @@ files:
|
|
158
86
|
- lib/paste/resolver.rb
|
159
87
|
- lib/paste/tasks/paste.rake
|
160
88
|
- lib/paste/version.rb
|
89
|
+
- README.rdoc
|
90
|
+
- spec/paste/css/provides_spec.rb
|
91
|
+
- spec/paste/js/cache_spec.rb
|
92
|
+
- spec/paste/js/chain_spec.rb
|
93
|
+
- spec/paste/js/compress_spec.rb
|
94
|
+
- spec/paste/js/config_spec.rb
|
95
|
+
- spec/paste/js/erb_spec.rb
|
96
|
+
- spec/paste/js/unify_spec.rb
|
97
|
+
- spec/paste/rails/helper_spec.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/support/helpers.rb
|
100
|
+
- spec/support/matchers.rb
|
161
101
|
has_rdoc: true
|
162
102
|
homepage: http://github.com/alexcrichton/paste
|
163
103
|
licenses: []
|
@@ -172,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
112
|
requirements:
|
173
113
|
- - ">="
|
174
114
|
- !ruby/object:Gem::Version
|
175
|
-
hash: -
|
115
|
+
hash: -1981454484605526525
|
176
116
|
segments:
|
177
117
|
- 0
|
178
118
|
version: "0"
|
@@ -181,6 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
121
|
requirements:
|
182
122
|
- - ">="
|
183
123
|
- !ruby/object:Gem::Version
|
124
|
+
hash: -1981454484605526525
|
184
125
|
segments:
|
185
126
|
- 0
|
186
127
|
version: "0"
|
@@ -191,5 +132,15 @@ rubygems_version: 1.3.7
|
|
191
132
|
signing_key:
|
192
133
|
specification_version: 3
|
193
134
|
summary: JS and CSS dependency management
|
194
|
-
test_files:
|
195
|
-
|
135
|
+
test_files:
|
136
|
+
- spec/paste/css/provides_spec.rb
|
137
|
+
- spec/paste/js/cache_spec.rb
|
138
|
+
- spec/paste/js/chain_spec.rb
|
139
|
+
- spec/paste/js/compress_spec.rb
|
140
|
+
- spec/paste/js/config_spec.rb
|
141
|
+
- spec/paste/js/erb_spec.rb
|
142
|
+
- spec/paste/js/unify_spec.rb
|
143
|
+
- spec/paste/rails/helper_spec.rb
|
144
|
+
- spec/spec_helper.rb
|
145
|
+
- spec/support/helpers.rb
|
146
|
+
- spec/support/matchers.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.2.1
|