paste 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"
@@ -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
- if results[result_name(sources)][:sources] != sources
33
- results[result_name(sources)] = {
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
- cached.each do |sources|
69
- register sources
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
- results.each do |result, hash|
100
+ cache.each do |result, hash|
92
101
  to_write << hash[:sources]
93
102
  end
94
103
 
@@ -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
 
@@ -1,6 +1,11 @@
1
1
  namespace :paste do
2
- desc 'Rebuild all cached javascripts with compression'
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
@@ -1,3 +1,3 @@
1
1
  module Paste
2
- VERSION = File.read(File.expand_path('../../../VERSION', __FILE__))
2
+ VERSION = '0.2.2'
3
3
  end
@@ -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
@@ -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
- - 1
9
- version: 0.2.1
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-08-18 00:00:00 -05:00
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: &id004 !ruby/object:Gem::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: *id004
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: -772280203830109166
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