paste 0.0.2 → 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg
2
+ .bundle
3
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sprockets'
4
+ gem 'paste', :path => '.'
5
+ gem 'activesupport', '>= 3.0.0.beta4'
6
+
7
+ group 'development' do
8
+ gem 'jeweler'
9
+ gem 'rake'
10
+ gem 'rspec', '>= 2.0.0.beta.19'
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ paste (0.1.0)
5
+ activesupport (>= 3.0.0.beta4)
6
+ paste
7
+ sprockets
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (3.0.0.rc)
13
+ diff-lcs (1.1.2)
14
+ gemcutter (0.6.1)
15
+ git (1.2.5)
16
+ jeweler (1.4.0)
17
+ gemcutter (>= 0.1.0)
18
+ git (>= 1.2.5)
19
+ rubyforge (>= 2.0.0)
20
+ json_pure (1.4.3)
21
+ rake (0.8.7)
22
+ rspec (2.0.0.beta.19)
23
+ rspec-core (= 2.0.0.beta.19)
24
+ rspec-expectations (= 2.0.0.beta.19)
25
+ rspec-mocks (= 2.0.0.beta.19)
26
+ rspec-core (2.0.0.beta.19)
27
+ rspec-expectations (2.0.0.beta.19)
28
+ diff-lcs (>= 1.1.2)
29
+ rspec-mocks (2.0.0.beta.19)
30
+ rubyforge (2.0.4)
31
+ json_pure (>= 1.1.7)
32
+ sprockets (1.0.2)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ activesupport (>= 3.0.0.beta4)
39
+ jeweler
40
+ paste!
41
+ rake
42
+ rspec (>= 2.0.0.beta.19)
43
+ sprockets
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'paste/version'
5
+ require 'jeweler'
6
+
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = 'paste'
9
+ gem.authors = ['Alex Crichton']
10
+ gem.description = 'Asset Management for Rails'
11
+ gem.summary = 'JS and CSS dependency management'
12
+ gem.email = ['alex@alexcrichton.com']
13
+ gem.homepage = 'http://github.com/alexcrichton/paste'
14
+
15
+ gem.add_bundler_dependencies
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+
19
+ namespace :gem do
20
+ desc "Push the gem to rubygems.org"
21
+ task :push do
22
+ system "gem push pkg/paste-#{Paste::VERSION}.gem"
23
+ end
24
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -52,11 +52,17 @@ module Paste
52
52
  def results
53
53
  return @results if defined?(@results)
54
54
  @results = Hash.new { {} }
55
-
56
- (YAML.load_file tmp_path(config.cache_file) rescue []).each do |sources|
55
+
56
+ begin
57
+ cached = YAML.load_file tmp_path(config.cache_file)
58
+ rescue
59
+ cached = []
60
+ end
61
+
62
+ cached.each do |sources|
57
63
  register sources
58
64
  end
59
-
65
+
60
66
  @results
61
67
  end
62
68
 
@@ -7,9 +7,15 @@ module Paste
7
7
  css_dependencies = []
8
8
 
9
9
  sources.each do |source|
10
- register [source] unless registered? [source]
11
- source_deps = results[result_name([source])][:parser].js_dependencies
12
- js_dependencies = js_dependencies | source_deps
10
+ name = result_name [source]
11
+ if registered? [source]
12
+ results[name][:parser].reset! if needs_update? name
13
+ else
14
+ register [source] unless registered? [source]
15
+ end
16
+
17
+ source_deps = results[name][:parser].js_dependencies
18
+ js_dependencies = source_deps | js_dependencies# | source_deps
13
19
  end
14
20
 
15
21
  js_dependencies = js_dependencies.map do |d|
@@ -5,7 +5,7 @@ module Paste
5
5
  module Resolver
6
6
 
7
7
  def resolve path
8
- if File.exists?(path) || path.bytes.first == '/'.bytes.first
8
+ if Pathname.new(path).absolute?
9
9
  File.expand_path path
10
10
  else
11
11
  File.join config.root, path
data/lib/paste/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Paste
2
- VERSION = '0.0.2'
2
+ VERSION = File.read(File.expand_path('../../../VERSION', __FILE__))
3
3
  end
data/paste.gemspec ADDED
@@ -0,0 +1,104 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{paste}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Alex Crichton"]
12
+ s.date = %q{2010-08-12}
13
+ s.description = %q{Asset Management for Rails}
14
+ s.email = ["alex@alexcrichton.com"]
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/paste.rb",
26
+ "lib/paste/capistrano.rb",
27
+ "lib/paste/css/base.rb",
28
+ "lib/paste/glue.rb",
29
+ "lib/paste/js/base.rb",
30
+ "lib/paste/js/cache.rb",
31
+ "lib/paste/js/chain.rb",
32
+ "lib/paste/js/compress.rb",
33
+ "lib/paste/js/erb_renderer.rb",
34
+ "lib/paste/js/unify.rb",
35
+ "lib/paste/parser/sprockets.rb",
36
+ "lib/paste/rails.rb",
37
+ "lib/paste/rails/helper.rb",
38
+ "lib/paste/rails/railtie.rb",
39
+ "lib/paste/rails/updater.rb",
40
+ "lib/paste/resolver.rb",
41
+ "lib/paste/tasks/paste.rake",
42
+ "lib/paste/version.rb",
43
+ "paste.gemspec",
44
+ "script/test",
45
+ "spec/paste/css/provides_spec.rb",
46
+ "spec/paste/js/cache_spec.rb",
47
+ "spec/paste/js/chain_spec.rb",
48
+ "spec/paste/js/compress_spec.rb",
49
+ "spec/paste/js/config_spec.rb",
50
+ "spec/paste/js/erb_spec.rb",
51
+ "spec/paste/js/unify_spec.rb",
52
+ "spec/paste/rails/helper_spec.rb",
53
+ "spec/spec_helper.rb",
54
+ "spec/support/helpers.rb",
55
+ "spec/support/matchers.rb"
56
+ ]
57
+ s.homepage = %q{http://github.com/alexcrichton/paste}
58
+ s.rdoc_options = ["--charset=UTF-8"]
59
+ s.require_paths = ["lib"]
60
+ s.rubygems_version = %q{1.3.7}
61
+ s.summary = %q{JS and CSS dependency management}
62
+ s.test_files = [
63
+ "spec/paste/css/provides_spec.rb",
64
+ "spec/paste/js/cache_spec.rb",
65
+ "spec/paste/js/chain_spec.rb",
66
+ "spec/paste/js/compress_spec.rb",
67
+ "spec/paste/js/config_spec.rb",
68
+ "spec/paste/js/erb_spec.rb",
69
+ "spec/paste/js/unify_spec.rb",
70
+ "spec/paste/rails/helper_spec.rb",
71
+ "spec/spec_helper.rb",
72
+ "spec/support/helpers.rb",
73
+ "spec/support/matchers.rb"
74
+ ]
75
+
76
+ if s.respond_to? :specification_version then
77
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
78
+ s.specification_version = 3
79
+
80
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
81
+ s.add_runtime_dependency(%q<sprockets>, [">= 0"])
82
+ s.add_runtime_dependency(%q<paste>, [">= 0"])
83
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0.beta4"])
84
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
85
+ s.add_development_dependency(%q<rake>, [">= 0"])
86
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
87
+ else
88
+ s.add_dependency(%q<sprockets>, [">= 0"])
89
+ s.add_dependency(%q<paste>, [">= 0"])
90
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta4"])
91
+ s.add_dependency(%q<jeweler>, [">= 0"])
92
+ s.add_dependency(%q<rake>, [">= 0"])
93
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
94
+ end
95
+ else
96
+ s.add_dependency(%q<sprockets>, [">= 0"])
97
+ s.add_dependency(%q<paste>, [">= 0"])
98
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta4"])
99
+ s.add_dependency(%q<jeweler>, [">= 0"])
100
+ s.add_dependency(%q<rake>, [">= 0"])
101
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
102
+ end
103
+ end
104
+
data/script/test ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'bundler/cli'
5
+
6
+ root = File.expand_path('../..', __FILE__)
7
+ destination = root + '/tmp'
8
+
9
+ ENV.delete 'BUNDLE_GEMFILE'
10
+ ENV['GEM_HOME'] = destination
11
+ ENV['GEM_PATH'] = destination
12
+ ENV['BUNDLE_PATH'] = destination
13
+
14
+ Bundler::CLI.start ['install', "--gemfile=#{root}/Gemfile", '--path', destination]
15
+
16
+ Bundler.setup :default, :test
17
+
18
+ require 'rspec/core'
19
+ success = RSpec::Core::Runner.run(['--color', root + '/spec'], $stderr, $stdout)
20
+
21
+ exit! success ? 0 : 1
@@ -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,100 @@
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', 'bar', 'baz'
74
+
75
+ Paste::JS::Test.write 'bar', '//= require <baz>', Time.now + 42
76
+
77
+ subject.paste('foo', 'bar', 'baz')[:javascript].should == ['baz.js', 'bar.js', 'foo.js']
78
+ end
79
+ end
80
+
81
+ describe "implicit dependencies" do
82
+ before :each do
83
+ Paste::JS::Test.write 'foo', ''
84
+ Paste::JS::Test.write 'bar', '//= require <foo>'
85
+ end
86
+
87
+ it "should be included when pasting" do
88
+ subject.paste('bar')[:javascript].should == ['foo.js', 'bar.js']
89
+ end
90
+
91
+ it "should be regenerated" do
92
+ result = subject.paste('bar')[:javascript].first
93
+
94
+ Paste::JS::Test.write 'foo', 'foobar()', Time.now + 42
95
+
96
+ subject.paste('bar')
97
+ subject.should have_in_result(result, 'foobar()')
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,42 @@
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', :level => 'ADVANCED_OPTIMIZATIONS'
34
+ rescue SocketError
35
+ pending 'Error connecting to google'
36
+ end
37
+
38
+ # Everything should be optimized out
39
+ subject.should have_in_result(result, '')
40
+ end
41
+
42
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paste::Glue, 'configuration' do
4
+ it "should resolve absolute paths correctly" do
5
+ subject.resolve(__FILE__).should == __FILE__
6
+ end
7
+
8
+ it "should resolve a non-absolute path relative to the specified root" do
9
+ subject.config.root = '/foo/bar'
10
+ subject.resolve('nonexistent').should == '/foo/bar/nonexistent'
11
+ end
12
+
13
+ it "should allow relative paths to the root to be set for configuration" do
14
+ subject.config.root = '/foo/bar'
15
+ subject.config.tmp_path = 'tmp'
16
+ subject.config.erb_path = 'erb'
17
+ subject.config.destination = 'dst'
18
+
19
+ subject.tmp_path.should == '/foo/bar/tmp'
20
+ subject.erb_path.should == '/foo/bar/erb'
21
+ subject.destination.should == '/foo/bar/dst'
22
+ end
23
+
24
+ it "should allow absolute paths to the root to be set for configuration" do
25
+ subject.config.root = '/foo/bar'
26
+ subject.config.tmp_path = '/tmp'
27
+ subject.config.erb_path = '/erb'
28
+ subject.config.destination = '/dst'
29
+
30
+ subject.tmp_path.should == '/tmp'
31
+ subject.erb_path.should == '/erb'
32
+ subject.destination.should == '/dst'
33
+ end
34
+ end
@@ -0,0 +1,94 @@
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', 'bar()'
45
+ subject.render_all_erb
46
+
47
+ subject.paste('foo', 'bar')
48
+ end
49
+ end
50
+
51
+ describe Paste::JS::Chain do
52
+ it_should_behave_like 'an erb paster'
53
+ end
54
+
55
+ describe Paste::JS::Unify do
56
+ it_should_behave_like 'an erb paster'
57
+ end
58
+ end
59
+
60
+ describe "modifying existing files" do
61
+ before :each do
62
+ Paste::JS::Test.write subject.erb_path('foo.js'), 'foo'
63
+ end
64
+
65
+ it "should regenerate the file if the source was modified" do
66
+ # File is modified after the original one
67
+ Paste::JS::Test.write 'foo.js.erb', 'foobar', Time.now + 42
68
+
69
+ subject.render_all_erb
70
+
71
+ subject.erb_path('foo.js').should have_contents('foobar')
72
+ end
73
+
74
+ it "should not regenerate the file if the source was not modified" do
75
+ Paste::JS::Test.write 'foo.js.erb', 'foobar', Time.now - 42
76
+ subject.render_all_erb
77
+
78
+ subject.erb_path('foo.js').should have_contents('foo')
79
+ end
80
+ end
81
+
82
+ context "rails" do
83
+ before :each do
84
+ Rails = {:foo => 'bar'}
85
+ end
86
+
87
+ it "should allow templates to use Rails instead of ::Rails" do
88
+ Paste::JS::Test.write 'foo.js.erb', '<%= Rails[:foo] %>'
89
+ subject.render_all_erb
90
+
91
+ subject.erb_path('foo.js').should have_contents('bar')
92
+ end
93
+ end
94
+ 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', 'bar', 'baz')[:javascript].first
82
+
83
+ Paste::JS::Test.write 'bar', "//= require <baz>\nbar", Time.now + 42
84
+
85
+ subject.paste('foo', 'bar', 'baz')
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,26 @@
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.dirname(__FILE__) + '/tmp'
10
+ end
11
+
12
+ Paste::JS.config.load_path = ['js_sources']
13
+ Paste::JS.config.destination = 'destination'
14
+ Paste::CSS.config.load_path = ['css_sources']
15
+ Paste::CSS.config.destination = 'destination'
16
+
17
+
18
+ RSpec.configure do |c|
19
+ c.color_enabled = true
20
+
21
+ c.after(:each) do
22
+ FileUtils.rm_rf Paste::Glue.config.root
23
+ end
24
+ end
25
+
26
+ Dir[File.dirname(__FILE__) + '/support/*.rb'].each { |f| load f }
@@ -0,0 +1,72 @@
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::Test
66
+ extend TestBase
67
+
68
+ def self.extension
69
+ 'css'
70
+ end
71
+ end
72
+ 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,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 0.0.2
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Crichton
@@ -15,27 +15,27 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-09 00:00:00 -05:00
18
+ date: 2010-08-12 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
+ type: :runtime
23
+ prerelease: false
24
+ name: sprockets
22
25
  version_requirements: &id001 !ruby/object:Gem::Requirement
23
26
  none: false
24
27
  requirements:
25
28
  - - ">="
26
29
  - !ruby/object:Gem::Version
27
- hash: -1848230024
30
+ hash: 3
28
31
  segments:
29
- - 3
30
- - 0
31
32
  - 0
32
- - beta4
33
- version: 3.0.0.beta4
33
+ version: "0"
34
34
  requirement: *id001
35
+ - !ruby/object:Gem::Dependency
35
36
  type: :runtime
36
- name: activesupport
37
37
  prerelease: false
38
- - !ruby/object:Gem::Dependency
38
+ name: paste
39
39
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
@@ -46,11 +46,56 @@ dependencies:
46
46
  - 0
47
47
  version: "0"
48
48
  requirement: *id002
49
+ - !ruby/object:Gem::Dependency
49
50
  type: :runtime
50
- name: sprockets
51
51
  prerelease: false
52
- - !ruby/object:Gem::Dependency
52
+ name: activesupport
53
53
  version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: -1848230024
59
+ segments:
60
+ - 3
61
+ - 0
62
+ - 0
63
+ - beta4
64
+ version: 3.0.0.beta4
65
+ requirement: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ type: :development
68
+ prerelease: false
69
+ name: jeweler
70
+ version_requirements: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirement: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ type: :development
82
+ prerelease: false
83
+ name: rake
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirement: *id005
94
+ - !ruby/object:Gem::Dependency
95
+ type: :development
96
+ prerelease: false
97
+ name: rspec
98
+ version_requirements: &id006 !ruby/object:Gem::Requirement
54
99
  none: false
55
100
  requirements:
56
101
  - - ">="
@@ -63,10 +108,7 @@ dependencies:
63
108
  - beta
64
109
  - 19
65
110
  version: 2.0.0.beta.19
66
- requirement: *id003
67
- type: :development
68
- name: rspec
69
- prerelease: false
111
+ requirement: *id006
70
112
  description: Asset Management for Rails
71
113
  email:
72
114
  - alex@alexcrichton.com
@@ -77,6 +119,13 @@ extensions: []
77
119
  extra_rdoc_files:
78
120
  - README.rdoc
79
121
  files:
122
+ - .gitignore
123
+ - Gemfile
124
+ - Gemfile.lock
125
+ - README.rdoc
126
+ - Rakefile
127
+ - VERSION
128
+ - lib/paste.rb
80
129
  - lib/paste/capistrano.rb
81
130
  - lib/paste/css/base.rb
82
131
  - lib/paste/glue.rb
@@ -87,23 +136,33 @@ files:
87
136
  - lib/paste/js/erb_renderer.rb
88
137
  - lib/paste/js/unify.rb
89
138
  - lib/paste/parser/sprockets.rb
139
+ - lib/paste/rails.rb
90
140
  - lib/paste/rails/helper.rb
91
141
  - lib/paste/rails/railtie.rb
92
142
  - lib/paste/rails/updater.rb
93
- - lib/paste/rails.rb
94
143
  - lib/paste/resolver.rb
95
144
  - lib/paste/tasks/paste.rake
96
145
  - lib/paste/version.rb
97
- - lib/paste.rb
98
- - README.rdoc
146
+ - paste.gemspec
147
+ - script/test
148
+ - spec/paste/css/provides_spec.rb
149
+ - spec/paste/js/cache_spec.rb
150
+ - spec/paste/js/chain_spec.rb
151
+ - spec/paste/js/compress_spec.rb
152
+ - spec/paste/js/config_spec.rb
153
+ - spec/paste/js/erb_spec.rb
154
+ - spec/paste/js/unify_spec.rb
155
+ - spec/paste/rails/helper_spec.rb
156
+ - spec/spec_helper.rb
157
+ - spec/support/helpers.rb
158
+ - spec/support/matchers.rb
99
159
  has_rdoc: true
100
160
  homepage: http://github.com/alexcrichton/paste
101
161
  licenses: []
102
162
 
103
163
  post_install_message:
104
164
  rdoc_options:
105
- - --main
106
- - README.rdoc
165
+ - --charset=UTF-8
107
166
  require_paths:
108
167
  - lib
109
168
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -131,5 +190,15 @@ rubygems_version: 1.3.7
131
190
  signing_key:
132
191
  specification_version: 3
133
192
  summary: JS and CSS dependency management
134
- test_files: []
135
-
193
+ test_files:
194
+ - spec/paste/css/provides_spec.rb
195
+ - spec/paste/js/cache_spec.rb
196
+ - spec/paste/js/chain_spec.rb
197
+ - spec/paste/js/compress_spec.rb
198
+ - spec/paste/js/config_spec.rb
199
+ - spec/paste/js/erb_spec.rb
200
+ - spec/paste/js/unify_spec.rb
201
+ - spec/paste/rails/helper_spec.rb
202
+ - spec/spec_helper.rb
203
+ - spec/support/helpers.rb
204
+ - spec/support/matchers.rb