patch-asset_library 0.5.0.1
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/README.rdoc +220 -0
- data/lib/asset_library.rb +121 -0
- data/lib/asset_library/asset.rb +35 -0
- data/lib/asset_library/asset_module.rb +94 -0
- data/lib/asset_library/compiler.rb +37 -0
- data/lib/asset_library/compiler/base.rb +20 -0
- data/lib/asset_library/compiler/closure.rb +41 -0
- data/lib/asset_library/compiler/default.rb +15 -0
- data/lib/asset_library/helpers.rb +98 -0
- data/lib/asset_library/rake_tasks.rb +22 -0
- data/lib/asset_library/util.rb +26 -0
- data/rails/init.rb +4 -0
- data/spec/asset_library/asset_module_spec.rb +183 -0
- data/spec/asset_library/asset_spec.rb +49 -0
- data/spec/asset_library/compiler/base_spec.rb +11 -0
- data/spec/asset_library/compiler/closure_spec.rb +104 -0
- data/spec/asset_library/compiler/default_spec.rb +27 -0
- data/spec/asset_library/compiler_spec.rb +35 -0
- data/spec/asset_library/helpers_spec.rb +210 -0
- data/spec/asset_library_spec.rb +120 -0
- data/spec/integration_spec.rb +90 -0
- data/spec/spec_helper.rb +70 -0
- metadata +98 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../../lib/asset_library/asset'
|
4
|
+
|
5
|
+
describe(AssetLibrary::Asset) do
|
6
|
+
it('should have eql? work for identical assets') do
|
7
|
+
a('/a/b.css').should eql(a('/a/b.css'))
|
8
|
+
end
|
9
|
+
|
10
|
+
it('should use absolute_path as its hash') do
|
11
|
+
a('/a/b.css').hash.should == '/a/b.css'.hash
|
12
|
+
end
|
13
|
+
|
14
|
+
context('#relative_path') do
|
15
|
+
it('should strip AssetLibrary.root') do
|
16
|
+
AssetLibrary.stub!(:root).and_return('/r')
|
17
|
+
a('/r/a/b.css').relative_path.should == '/a/b.css'
|
18
|
+
end
|
19
|
+
|
20
|
+
it('should strip nothing if root is "/"') do
|
21
|
+
AssetLibrary.stub!(:root).and_return('/')
|
22
|
+
a('/r/a/b.css').relative_path.should == '/r/a/b.css'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context('#timestamp') do
|
27
|
+
it('should return the file mtime') do
|
28
|
+
File.stub!(:mtime).with('/r/a/b.css').and_return(Time.at(123))
|
29
|
+
a('/r/a/b.css').timestamp.should == Time.at(123)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context('#relative_url') do
|
34
|
+
before(:each) do
|
35
|
+
AssetLibrary.stub!(:root).and_return('/r')
|
36
|
+
end
|
37
|
+
|
38
|
+
it('should use relative path and mtime') do
|
39
|
+
File.stub!(:mtime).with('/r/a/b.css').and_return(Time.at(123))
|
40
|
+
a('/r/a/b.css').relative_url.should == '/a/b.css?123'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def a(*args)
|
47
|
+
AssetLibrary::Asset.new(*args)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe(AssetLibrary::Compiler::Base) do
|
4
|
+
describe('#write_all_caches') do
|
5
|
+
it('should raise NotImplementedError') do
|
6
|
+
lambda do
|
7
|
+
AssetLibrary::Compiler::Base.new({}).write_all_caches
|
8
|
+
end.should raise_error(NotImplementedError)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe(AssetLibrary::Compiler::Closure) do
|
4
|
+
include TemporaryDirectory
|
5
|
+
include CompilerHelpers
|
6
|
+
|
7
|
+
before do
|
8
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
9
|
+
AssetLibrary.root = "#{tmp}/root"
|
10
|
+
end
|
11
|
+
|
12
|
+
def compiler(configuration = {})
|
13
|
+
configuration[:path] = '/PATH/TO/CLOSURE.jar' unless configuration.key?(:path)
|
14
|
+
compiler = AssetLibrary::Compiler::Closure.new(configuration)
|
15
|
+
compiler.stub!(:system)
|
16
|
+
compiler
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_one_compilation(compiler)
|
20
|
+
compiler.add_asset_module mock_asset_module('lib', :format, 'out.js', 'in.js')
|
21
|
+
end
|
22
|
+
|
23
|
+
describe('#initialize') do
|
24
|
+
it('should cry if the path to the compiler is not set') do
|
25
|
+
lambda{compiler(:path => nil)}.should raise_error(AssetLibrary::ConfigurationError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe('#write_all_caches') do
|
30
|
+
before do
|
31
|
+
@tmpdir = "#{tmp}/tmpdir"
|
32
|
+
FileUtils.mkdir_p @tmpdir
|
33
|
+
AssetLibrary::Util.stub!(:mktmpdir).and_yield(@tmpdir)
|
34
|
+
end
|
35
|
+
|
36
|
+
it("should run each module's files through closure compiler") do
|
37
|
+
compiler = self.compiler
|
38
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, 'LIB1.js', 'lib1-file1.js')
|
39
|
+
compiler.add_asset_module mock_asset_module('lib2', :format, 'LIB2.js', 'lib2-file1.js', 'lib2-file2.js')
|
40
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --js_output_file LIB1.js --js lib1-file1.js").and_return(true)
|
41
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --js_output_file LIB2.js --js lib2-file1.js --js lib2-file2.js").and_return(true)
|
42
|
+
compiler.write_all_caches(:format)
|
43
|
+
end
|
44
|
+
|
45
|
+
it('should take the java executable name from the :java configuration option') do
|
46
|
+
compiler = compiler(:java => '/PATH/TO/JAVA')
|
47
|
+
add_one_compilation(compiler)
|
48
|
+
compiler.should_receive(:system).with{ |*args| args.first == '/PATH/TO/JAVA' }.and_return(true)
|
49
|
+
compiler.write_all_caches(:format)
|
50
|
+
end
|
51
|
+
|
52
|
+
it('should take the path to closure compiler from the :path configuration option') do
|
53
|
+
compiler = compiler(:path => '/CLOSURE.jar')
|
54
|
+
add_one_compilation(compiler)
|
55
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-jar', '/CLOSURE.jar'] }.and_return(true)
|
56
|
+
compiler.write_all_caches(:format)
|
57
|
+
end
|
58
|
+
|
59
|
+
it('should interpret the path as relative to the application root') do
|
60
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
61
|
+
compiler = compiler(:path => 'CLOSURE')
|
62
|
+
add_one_compilation(compiler)
|
63
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-jar', "#{tmp}/app_root/CLOSURE"] }.and_return(true)
|
64
|
+
compiler.write_all_caches(:format)
|
65
|
+
end
|
66
|
+
|
67
|
+
it('should pass any configured java_flags to java') do
|
68
|
+
compiler = compiler(:java_flags => "-foo -bar")
|
69
|
+
add_one_compilation(compiler)
|
70
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-foo', '-bar'] }.and_return(true)
|
71
|
+
compiler.write_all_caches(:format)
|
72
|
+
end
|
73
|
+
|
74
|
+
it('should accept an Array for java_flags') do
|
75
|
+
compiler = compiler(:java_flags => %w"-foo -bar")
|
76
|
+
add_one_compilation(compiler)
|
77
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-foo', '-bar'] }.and_return(true)
|
78
|
+
compiler.write_all_caches(:format)
|
79
|
+
end
|
80
|
+
|
81
|
+
it('should pass any configured flags to the compiler') do
|
82
|
+
compiler = compiler(:flags => "--foo --bar")
|
83
|
+
add_one_compilation(compiler)
|
84
|
+
compiler.should_receive(:system).with{ |*args| args[3..4] == ['--foo', '--bar'] }.and_return(true)
|
85
|
+
compiler.write_all_caches(:format)
|
86
|
+
end
|
87
|
+
|
88
|
+
it('should add module compiler flags to the compiler command') do
|
89
|
+
compiler = self.compiler
|
90
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, 'LIB1.js', 'lib1-file1.js', :compiler_flags => ['--foo'])
|
91
|
+
compiler.add_asset_module mock_asset_module('lib2', :format, 'LIB2.js', 'lib2-file1.js', :compiler_flags => ['--bar'])
|
92
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --foo --js_output_file LIB1.js --js lib1-file1.js").and_return(true)
|
93
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --bar --js_output_file LIB2.js --js lib2-file1.js").and_return(true)
|
94
|
+
compiler.write_all_caches(:format)
|
95
|
+
end
|
96
|
+
|
97
|
+
it('should raise a Compiler::Error if the compiler fails') do
|
98
|
+
compiler = self.compiler
|
99
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, "lib1.js", "file1.js")
|
100
|
+
compiler.stub!(:system).and_return(false)
|
101
|
+
lambda{compiler.write_all_caches(:format)}.should raise_error(AssetLibrary::Compiler::Error)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe(AssetLibrary::Compiler::Default) do
|
4
|
+
include TemporaryDirectory
|
5
|
+
include CompilerHelpers
|
6
|
+
|
7
|
+
before do
|
8
|
+
@compiler = AssetLibrary::Compiler::Default.new(nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe('#write_all_caches') do
|
12
|
+
it('should concatenate each set of input files to produce the respective output files') do
|
13
|
+
write_file "lib1-file1.txt", "lib1-file1\n"
|
14
|
+
write_file "lib2-file1.txt", "lib2-file1\n"
|
15
|
+
write_file "lib2-file2.txt", "lib2-file2\n"
|
16
|
+
@compiler.add_asset_module mock_asset_module('lib1', :format, "#{tmp}/lib1.txt", "#{tmp}/lib1-file1.txt")
|
17
|
+
@compiler.add_asset_module mock_asset_module('lib2', :format, "#{tmp}/lib2.txt", "#{tmp}/lib2-file1.txt", "#{tmp}/lib2-file2.txt")
|
18
|
+
@compiler.write_all_caches(:format)
|
19
|
+
File.read("#{tmp}/lib1.txt").should == "lib1-file1\n"
|
20
|
+
File.read("#{tmp}/lib2.txt").should == "lib2-file1\nlib2-file2\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
def write_file(path, content)
|
24
|
+
open("#{tmp}/#{path}", 'w'){|f| f.print content}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe(AssetLibrary::Compiler) do
|
4
|
+
Compiler = AssetLibrary::Compiler
|
5
|
+
include TemporaryDirectory
|
6
|
+
|
7
|
+
before do
|
8
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
9
|
+
AssetLibrary.root = "#{tmp}/root"
|
10
|
+
end
|
11
|
+
|
12
|
+
describe('.create') do
|
13
|
+
it('should return a Default compiler for :default') do
|
14
|
+
Compiler.create(:default).should be_a(Compiler::Default)
|
15
|
+
end
|
16
|
+
|
17
|
+
it('should return a Closure compiler for :closure') do
|
18
|
+
Compiler.create(:closure, :path => '').should be_a(Compiler::Closure)
|
19
|
+
end
|
20
|
+
|
21
|
+
it('should pass the configuration to the compiler') do
|
22
|
+
Compiler.create(:default, {:param => 2}).config[:param].should == 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe('.register') do
|
27
|
+
TestCompiler = Class.new(Compiler::Base)
|
28
|
+
|
29
|
+
it('should register a custom compiler type') do
|
30
|
+
Compiler.register(:test, TestCompiler)
|
31
|
+
compiler = Compiler.create(:test)
|
32
|
+
compiler.should be_a(TestCompiler)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../../lib/asset_library/helpers'
|
4
|
+
|
5
|
+
describe(AssetLibrary::Helpers) do
|
6
|
+
before(:each) do
|
7
|
+
@h = nil
|
8
|
+
AssetLibrary.stub!(:root).and_return('/')
|
9
|
+
end
|
10
|
+
before(:each) do
|
11
|
+
@old_cache = AssetLibrary.cache # Empty globals
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:each) do
|
15
|
+
@h = nil
|
16
|
+
end
|
17
|
+
after(:each) do
|
18
|
+
AssetLibrary.cache = @old_cache
|
19
|
+
@old_cache = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
describe('#asset_library_javascript_tags') do
|
23
|
+
describe('when not caching') do
|
24
|
+
before(:each) do
|
25
|
+
AssetLibrary.stub!(:cache).and_return(false)
|
26
|
+
end
|
27
|
+
|
28
|
+
it('should fetch using asset_module') do
|
29
|
+
m = mock(:assets => [])
|
30
|
+
AssetLibrary.should_receive(:asset_module).with(:m).and_return(m)
|
31
|
+
h.asset_library_javascript_tags(:m)
|
32
|
+
end
|
33
|
+
|
34
|
+
it('should output nothing when a module is empty') do
|
35
|
+
m = mock(:assets => [])
|
36
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
37
|
+
h.asset_library_javascript_tags(:m).should == ''
|
38
|
+
end
|
39
|
+
|
40
|
+
it('should output a <script> tag for a file') do
|
41
|
+
m = mock(:assets => [a('/f.js')])
|
42
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
43
|
+
h.asset_library_javascript_tags(:m).should == '<script type="text/javascript" src="/f.js?123"></script>'
|
44
|
+
end
|
45
|
+
|
46
|
+
it('should join <script> tags with newlines') do
|
47
|
+
m = mock(:assets => [a('/f.js'), a('/f2.js')])
|
48
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
49
|
+
h.asset_library_javascript_tags(:m).should == '<script type="text/javascript" src="/f.js?123"></script>' + "\n" + '<script type="text/javascript" src="/f2.js?123"></script>'
|
50
|
+
end
|
51
|
+
|
52
|
+
it('should use compute_asset_host if available') do
|
53
|
+
m = mock(:assets => [a('/f.js')])
|
54
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
55
|
+
h.should_receive(:compute_asset_host).with('/f.js?123').and_return('http://assets.test')
|
56
|
+
h.asset_library_javascript_tags(:m).should =~ %r{"http://assets.test/f.js\?123"}
|
57
|
+
end
|
58
|
+
|
59
|
+
it('should not use compute_asset_host if it returns nil') do
|
60
|
+
m = mock(:assets => [a('/f.js')])
|
61
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
62
|
+
h.should_receive(:compute_asset_host).and_return(nil)
|
63
|
+
h.asset_library_javascript_tags(:m).should =~ %r{"/f.js\?123"}
|
64
|
+
end
|
65
|
+
|
66
|
+
it('should not use compute_asset_host if it returns ""') do
|
67
|
+
m = mock(:assets => [a('/f.js')])
|
68
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
69
|
+
h.should_receive(:compute_asset_host).and_return("")
|
70
|
+
h.asset_library_javascript_tags(:m).should =~ %r{"/f.js\?123"}
|
71
|
+
end
|
72
|
+
|
73
|
+
it('should add request protocol to compute_asset_host output if applicable') do
|
74
|
+
m = mock(:assets => [a('/f.js')])
|
75
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
76
|
+
h.stub!(:compute_asset_host).and_return('assets.test')
|
77
|
+
h.instance_variable_set(:@controller, mock(:request => mock(:protocol => 'http://')))
|
78
|
+
h.asset_library_javascript_tags(:m).should =~ %r{"http://assets.test/f.js\?123"}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe('when caching') do
|
83
|
+
before(:each) do
|
84
|
+
AssetLibrary.cache = true
|
85
|
+
end
|
86
|
+
|
87
|
+
it('should output a single <script> tag with the cache filename') do
|
88
|
+
m = mock(:cache_asset => a('/cache.js'))
|
89
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
90
|
+
h.asset_library_javascript_tags(:m).should == '<script type="text/javascript" src="/cache.js?123"></script>'
|
91
|
+
end
|
92
|
+
|
93
|
+
it('should use compute_asset_host if available') do
|
94
|
+
m = mock(:cache_asset => a('/cache.js'))
|
95
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
96
|
+
h.should_receive(:compute_asset_host).with('/cache.js?123').and_return('http://assets.test')
|
97
|
+
h.asset_library_javascript_tags(:m)
|
98
|
+
h.asset_library_javascript_tags(:m).should =~ %r{"http://assets.test/cache.js\?123"}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe('#asset_library_stylesheet_tags') do
|
104
|
+
describe('when not caching') do
|
105
|
+
before(:each) do
|
106
|
+
AssetLibrary.stub!(:cache).and_return(false)
|
107
|
+
end
|
108
|
+
|
109
|
+
it('should fetch using asset_module') do
|
110
|
+
m = mock(:assets => [])
|
111
|
+
AssetLibrary.should_receive(:asset_module).with(:m).and_return(m)
|
112
|
+
h.asset_library_stylesheet_tags(:m)
|
113
|
+
end
|
114
|
+
|
115
|
+
it('should output nothing when a module is empty') do
|
116
|
+
m = mock(:assets => [])
|
117
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
118
|
+
h.asset_library_stylesheet_tags(:m).should == ''
|
119
|
+
end
|
120
|
+
|
121
|
+
it('should output a single <script> with a single @import when there is one file') do
|
122
|
+
m = mock(:assets => [a('/f.css')])
|
123
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
124
|
+
h.asset_library_stylesheet_tags(:m).should == "<style type=\"text/css\">\n@import \"\/f.css?123\";\n</style>"
|
125
|
+
end
|
126
|
+
|
127
|
+
it('should use formats to find cache filename') do
|
128
|
+
m = mock
|
129
|
+
m.should_receive(:assets).with(:e).and_return([a('f.e.css')])
|
130
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
131
|
+
h.asset_library_stylesheet_tags(:m, :e).should == "<style type=\"text/css\">\n@import \"f.e.css?123\";\n</style>"
|
132
|
+
end
|
133
|
+
|
134
|
+
it('should output a single <script> tag with 30 @import') do
|
135
|
+
m = mock(:assets => (1..30).collect{|i| a("/f#{i}.css") })
|
136
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
137
|
+
h.asset_library_stylesheet_tags(:m).should =~ /\<style type=\"text\/css\"\>(\n@import \"\/f\d+.css\?123\";){30}\n\<\/style\>/
|
138
|
+
end
|
139
|
+
|
140
|
+
it('should output two <script> tags with 31 @imports') do
|
141
|
+
m = mock(:assets => (1..31).collect{|i| a("/f#{i}.css") })
|
142
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
143
|
+
h.asset_library_stylesheet_tags(:m).should =~ /\<style type="text\/css"\>(\n@import "\/f\d+.css\?123";){30}\n\<\/style\>\n<style type="text\/css"\>\n@import "\/f31.css\?123";\n\<\/style\>/
|
144
|
+
end
|
145
|
+
|
146
|
+
it('should output a final hash in the parameters as html attributes') do
|
147
|
+
m = mock(:assets => [a('/f.css')])
|
148
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
149
|
+
optional_hash = {:key1 => "val1", :key2 => "val2", :key3 => "val3"}
|
150
|
+
attributes_to_hash( h.asset_library_stylesheet_tags(:m, optional_hash), [:type] ).should == optional_hash
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe('when caching') do
|
155
|
+
before(:each) do
|
156
|
+
AssetLibrary.stub!(:cache).and_return(true)
|
157
|
+
end
|
158
|
+
|
159
|
+
it('should output a single <style> tag with the cache filename') do
|
160
|
+
m = mock(:cache_asset => a('/cache.css'))
|
161
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
162
|
+
h.asset_library_stylesheet_tags(:m).should == '<link rel="stylesheet" type="text/css" href="/cache.css?123" />'
|
163
|
+
end
|
164
|
+
|
165
|
+
it('should use format for the cache filename') do
|
166
|
+
m = mock
|
167
|
+
m.should_receive(:cache_asset).with(:e).and_return(a('/cache.e.css'))
|
168
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
169
|
+
h.asset_library_stylesheet_tags(:m, :e).should == '<link rel="stylesheet" type="text/css" href="/cache.e.css?123" />'
|
170
|
+
end
|
171
|
+
|
172
|
+
it('should output a final hash in the parameters as html attributes') do
|
173
|
+
m = mock(:cache_asset => a('/cache.css'))
|
174
|
+
AssetLibrary.stub!(:asset_module).and_return(m)
|
175
|
+
optional_hash = {:key1 => "val1", :key2 => "val2", :key3 => "val3"}
|
176
|
+
attributes_to_hash(h.asset_library_stylesheet_tags(:m, optional_hash), [:type, :rel, :href]).should == optional_hash
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def a(path)
|
184
|
+
File.stub!(:mtime).and_return(Time.at(123))
|
185
|
+
AssetLibrary::Asset.new(path)
|
186
|
+
end
|
187
|
+
|
188
|
+
def h
|
189
|
+
return @h if @h
|
190
|
+
c = Class.new do
|
191
|
+
include AssetLibrary::Helpers
|
192
|
+
end
|
193
|
+
@h = c.new
|
194
|
+
@h.stub!(:request).and_return(mock(:protocol => 'http://', :host_with_port => 'example.com'))
|
195
|
+
@h
|
196
|
+
end
|
197
|
+
|
198
|
+
def attributes_to_hash(string, without = [])
|
199
|
+
hash_from_tag_attributes = {}
|
200
|
+
|
201
|
+
string.scan(/\s([^\s=]+="[^"]*)"/).each do |attr|
|
202
|
+
a = attr[0].split("=\"")
|
203
|
+
hash_from_tag_attributes.merge!( a[0].to_sym => a[1] )
|
204
|
+
end
|
205
|
+
|
206
|
+
without.each{|k| hash_from_tag_attributes.delete k}
|
207
|
+
|
208
|
+
hash_from_tag_attributes
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe(AssetLibrary) do
|
4
|
+
def config_skeleton
|
5
|
+
{:modules => {}, :compilers => {}}
|
6
|
+
end
|
7
|
+
|
8
|
+
describe('#config') do
|
9
|
+
it('should YAML.load_file the config from config_path') do
|
10
|
+
AssetLibrary.config_path = '/config.yml'
|
11
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
12
|
+
YAML.should_receive(:load_file).with('/config.yml')
|
13
|
+
AssetLibrary.config
|
14
|
+
end
|
15
|
+
|
16
|
+
it('should return a skeletal configuration if config_path does not exist') do
|
17
|
+
AssetLibrary.config_path = '/config.yml'
|
18
|
+
File.stub!(:exist?).with('/config.yml').and_return(false)
|
19
|
+
AssetLibrary.config.should == config_skeleton
|
20
|
+
end
|
21
|
+
|
22
|
+
it('should cache config if cache is set') do
|
23
|
+
AssetLibrary.cache = true
|
24
|
+
AssetLibrary.config_path = '/config.yml'
|
25
|
+
|
26
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
27
|
+
YAML.should_receive(:load_file).with('/config.yml').once
|
28
|
+
|
29
|
+
AssetLibrary.config
|
30
|
+
AssetLibrary.config
|
31
|
+
end
|
32
|
+
|
33
|
+
it('should not cache config if cache is not set') do
|
34
|
+
AssetLibrary.cache = false
|
35
|
+
AssetLibrary.config_path = '/config.yml'
|
36
|
+
|
37
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
38
|
+
YAML.should_receive(:load_file).with('/config.yml').twice
|
39
|
+
|
40
|
+
AssetLibrary.config
|
41
|
+
AssetLibrary.config
|
42
|
+
end
|
43
|
+
|
44
|
+
it('should symbolize config hash keys') do
|
45
|
+
AssetLibrary.cache = false
|
46
|
+
AssetLibrary.config_path = '/config.yml'
|
47
|
+
|
48
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
49
|
+
YAML.should_receive(:load_file).with('/config.yml').and_return(
|
50
|
+
{ 'a' => { 'b' => 'c' } }
|
51
|
+
)
|
52
|
+
|
53
|
+
AssetLibrary.config.should == config_skeleton.merge(:a => {:b => 'c'})
|
54
|
+
end
|
55
|
+
|
56
|
+
it('should accept a v0.4 config file with a deprecation warning') do
|
57
|
+
AssetLibrary.cache = false
|
58
|
+
AssetLibrary.config_path = '/config.yml'
|
59
|
+
|
60
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
61
|
+
YAML.should_receive(:load_file).with('/config.yml').and_return(
|
62
|
+
{ 'a' => { 'files' => ['a.js'] } }
|
63
|
+
)
|
64
|
+
AssetLibrary.should_receive(:warn)
|
65
|
+
|
66
|
+
AssetLibrary.config.should == { :compilers => {}, :modules => { :a => { :files => ['a.js'] } } }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe('#asset_module') do
|
71
|
+
before(:each) do
|
72
|
+
@config = config_skeleton
|
73
|
+
AssetLibrary.stub!(:config).and_return(@config)
|
74
|
+
end
|
75
|
+
|
76
|
+
it('should return nil when given an invalid key') do
|
77
|
+
AssetLibrary.asset_module(:foo).should == nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it('should return an AssetModule when given a valid key') do
|
81
|
+
@config[:modules][:foo] = {}
|
82
|
+
AssetLibrary.asset_module(:foo).should(be_a(AssetLibrary::AssetModule))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe('#compiler') do
|
87
|
+
include TemporaryDirectory
|
88
|
+
|
89
|
+
before do
|
90
|
+
AssetLibrary.app_root = "#{tmp}/root"
|
91
|
+
end
|
92
|
+
|
93
|
+
it('should return a Default compiler if no compiler type has been configured for the given asset module') do
|
94
|
+
configure_compilers
|
95
|
+
asset_module = mock(:compiler_type => :default)
|
96
|
+
AssetLibrary.compiler(asset_module).should be_a(AssetLibrary::Compiler::Default)
|
97
|
+
end
|
98
|
+
|
99
|
+
it('should return a compiler of the configured type for the given asset module, if one is given') do
|
100
|
+
configure_compilers
|
101
|
+
asset_module = mock(:compiler_type => :closure)
|
102
|
+
AssetLibrary.compiler(asset_module).should be_a(AssetLibrary::Compiler::Closure)
|
103
|
+
end
|
104
|
+
|
105
|
+
it('should pass the right compiler configuration to the compiler') do
|
106
|
+
config = {:default => {:foo => 2}}
|
107
|
+
configure_compilers(config)
|
108
|
+
asset_module = mock(:compiler_type => :default)
|
109
|
+
AssetLibrary.compiler(asset_module).config[:foo].should == 2
|
110
|
+
end
|
111
|
+
|
112
|
+
def configure_compilers(config=nil)
|
113
|
+
config = {:compilers => config || {:closure => {:path => 'closure.jar'}}}
|
114
|
+
config_path = "#{tmp}/config.yml"
|
115
|
+
open(config_path, 'w'){|f| YAML.dump(config, f)}
|
116
|
+
AssetLibrary.config_path = config_path
|
117
|
+
AssetLibrary.config
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|