juicer 0.2.6 → 1.0.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.
Files changed (122) hide show
  1. data/History.txt +28 -0
  2. data/Rakefile +84 -36
  3. data/Readme.rdoc +192 -23
  4. data/VERSION +1 -0
  5. data/bin/juicer +2 -4
  6. data/lib/juicer.rb +9 -10
  7. data/lib/juicer/asset/path.rb +275 -0
  8. data/lib/juicer/asset/path_resolver.rb +79 -0
  9. data/lib/juicer/binary.rb +3 -5
  10. data/lib/juicer/cache_buster.rb +112 -27
  11. data/lib/juicer/command/install.rb +4 -2
  12. data/lib/juicer/command/list.rb +16 -9
  13. data/lib/juicer/command/merge.rb +30 -14
  14. data/lib/juicer/command/verify.rb +1 -1
  15. data/lib/juicer/css_cache_buster.rb +31 -47
  16. data/lib/juicer/datafy/datafy.rb +20 -0
  17. data/lib/juicer/dependency_resolver/css_dependency_resolver.rb +29 -0
  18. data/lib/juicer/dependency_resolver/dependency_resolver.rb +101 -0
  19. data/lib/juicer/dependency_resolver/javascript_dependency_resolver.rb +23 -0
  20. data/lib/juicer/ext/logger.rb +5 -0
  21. data/lib/juicer/ext/string.rb +47 -0
  22. data/lib/juicer/ext/symbol.rb +15 -0
  23. data/lib/juicer/image_embed.rb +129 -0
  24. data/lib/juicer/install/base.rb +2 -2
  25. data/lib/juicer/install/closure_compiler_installer.rb +69 -0
  26. data/lib/juicer/install/jslint_installer.rb +3 -3
  27. data/lib/juicer/install/rhino_installer.rb +3 -2
  28. data/lib/juicer/install/yui_compressor_installer.rb +3 -2
  29. data/lib/juicer/jslint.rb +1 -1
  30. data/lib/juicer/merger/base.rb +1 -1
  31. data/lib/juicer/merger/javascript_merger.rb +3 -4
  32. data/lib/juicer/merger/stylesheet_merger.rb +13 -15
  33. data/lib/juicer/minifyer/closure_compiler.rb +90 -0
  34. data/lib/juicer/minifyer/java_base.rb +77 -0
  35. data/lib/juicer/minifyer/yui_compressor.rb +15 -48
  36. data/test/bin/jslint-1.0.js +523 -0
  37. data/test/bin/jslint.js +523 -0
  38. data/test/bin/rhino1_7R1.zip +0 -0
  39. data/test/bin/rhino1_7R2-RC1.jar +0 -0
  40. data/test/bin/rhino1_7R2-RC1.zip +0 -0
  41. data/test/bin/yuicompressor +0 -0
  42. data/test/bin/yuicompressor-2.3.5.zip +0 -0
  43. data/test/bin/yuicompressor-2.4.2.jar +0 -0
  44. data/test/bin/yuicompressor-2.4.2.zip +0 -0
  45. data/test/data/Changelog.txt +10 -0
  46. data/test/data/a.css +3 -0
  47. data/test/data/a.js +5 -0
  48. data/test/data/a1.css +5 -0
  49. data/test/data/b.css +1 -0
  50. data/test/data/b.js +5 -0
  51. data/test/data/b1.css +5 -0
  52. data/test/data/c1.css +3 -0
  53. data/test/data/css/2.gif +1 -0
  54. data/test/data/css/test.css +11 -0
  55. data/test/data/css/test2.css +1 -0
  56. data/test/data/d1.css +3 -0
  57. data/test/data/images/1.png +1 -0
  58. data/test/data/my_app.js +2 -0
  59. data/test/data/not-ok.js +2 -0
  60. data/test/data/ok.js +3 -0
  61. data/test/data/path_test.css +5 -0
  62. data/test/data/path_test2.css +14 -0
  63. data/test/data/pkg/module/moda.js +2 -0
  64. data/test/data/pkg/module/modb.js +3 -0
  65. data/test/data/pkg/pkg.js +1 -0
  66. data/test/fixtures/yui-download.html +425 -0
  67. data/test/test_helper.rb +36 -7
  68. data/test/unit/juicer/asset/path_resolver_test.rb +76 -0
  69. data/test/unit/juicer/asset/path_test.rb +370 -0
  70. data/test/unit/juicer/cache_buster_test.rb +104 -0
  71. data/test/{juicer/test_chainable.rb → unit/juicer/chainable_test.rb} +1 -1
  72. data/test/unit/juicer/command/install_test.rb +58 -0
  73. data/test/{juicer/command/test_list.rb → unit/juicer/command/list_test.rb} +26 -14
  74. data/test/unit/juicer/command/merge_test.rb +162 -0
  75. data/test/{juicer/command/test_util.rb → unit/juicer/command/util_test.rb} +10 -6
  76. data/test/unit/juicer/command/verify_test.rb +48 -0
  77. data/test/{juicer/test_css_cache_buster.rb → unit/juicer/css_cache_buster_test.rb} +10 -30
  78. data/test/unit/juicer/datafy_test.rb +37 -0
  79. data/test/{juicer/merger/test_css_dependency_resolver.rb → unit/juicer/dependency_resolver/css_dependency_resolver_test.rb} +2 -2
  80. data/test/{juicer/merger/test_javascript_dependency_resolver.rb → unit/juicer/dependency_resolver/javascript_dependency_resolver_test.rb} +13 -2
  81. data/test/unit/juicer/ext/{#string_test.rb# → string_test.rb} +0 -7
  82. data/test/unit/juicer/ext/symbol_test.rb +27 -0
  83. data/test/unit/juicer/image_embed_test.rb +271 -0
  84. data/test/unit/juicer/install/installer_base_test.rb +214 -0
  85. data/test/{juicer/install/test_jslint_installer.rb → unit/juicer/install/jslint_installer_test.rb} +1 -1
  86. data/test/{juicer/install/test_rhino_installer.rb → unit/juicer/install/rhino_installer_test.rb} +1 -1
  87. data/test/{juicer/install/test_yui_compressor_installer.rb → unit/juicer/install/yui_compressor_test.rb} +16 -16
  88. data/test/unit/juicer/jslint_test.rb +60 -0
  89. data/test/{juicer/merger/test_base.rb → unit/juicer/merger/base_test.rb} +1 -1
  90. data/test/{juicer/merger/test_javascript_merger.rb → unit/juicer/merger/javascript_merger_test.rb} +2 -2
  91. data/test/{juicer/merger/test_stylesheet_merger.rb → unit/juicer/merger/stylesheet_merger_test.rb} +15 -13
  92. data/test/unit/juicer/minifyer/closure_compressor_test.rb +107 -0
  93. data/test/{integration → unit}/juicer/minifyer/yui_compressor_test.rb +30 -47
  94. data/test/unit/juicer_test.rb +1 -0
  95. metadata +207 -113
  96. data/lib/juicer/core.rb +0 -61
  97. data/lib/juicer/merger/css_dependency_resolver.rb +0 -25
  98. data/lib/juicer/merger/dependency_resolver.rb +0 -82
  99. data/lib/juicer/merger/javascript_dependency_resolver.rb +0 -21
  100. data/tasks/ann.rake +0 -80
  101. data/tasks/bones.rake +0 -20
  102. data/tasks/gem.rake +0 -201
  103. data/tasks/git.rake +0 -40
  104. data/tasks/notes.rake +0 -27
  105. data/tasks/post_load.rake +0 -34
  106. data/tasks/rdoc.rake +0 -51
  107. data/tasks/rubyforge.rake +0 -55
  108. data/tasks/setup.rb +0 -292
  109. data/tasks/spec.rake +0 -54
  110. data/tasks/svn.rake +0 -47
  111. data/tasks/test.rake +0 -40
  112. data/tasks/test/setup.rake +0 -35
  113. data/tasks/zentest.rake +0 -36
  114. data/test/juicer/command/test_install.rb +0 -53
  115. data/test/juicer/command/test_merge.rb +0 -160
  116. data/test/juicer/command/test_verify.rb +0 -33
  117. data/test/juicer/install/test_installer_base.rb +0 -195
  118. data/test/juicer/minifyer/test_yui_compressor.rb +0 -159
  119. data/test/juicer/test_cache_buster.rb +0 -58
  120. data/test/juicer/test_core.rb +0 -47
  121. data/test/juicer/test_jslint.rb +0 -33
  122. data/test/test_juicer.rb +0 -4
@@ -0,0 +1,48 @@
1
+ require "test_helper"
2
+
3
+ class TestVerifyCommand < Test::Unit::TestCase
4
+ def setup
5
+ @io = StringIO.new
6
+ @command = Juicer::Command::Verify.new(Logger.new(@io))
7
+ @path = Dir.pwd
8
+ @juicer = Juicer.home
9
+ end
10
+
11
+ def teardown
12
+ Dir.chdir(@path)
13
+ Juicer.home = @juicer
14
+ end
15
+
16
+ context "executing command" do
17
+ should "fail with no files" do
18
+ assert_raise ArgumentError do
19
+ @command.execute []
20
+ end
21
+ end
22
+
23
+ should "fail if installer is not found" do
24
+ Juicer.home = path("somewhere")
25
+ Dir.chdir("lib")
26
+ command = Juicer::Command::Verify.new(Logger.new(@io))
27
+
28
+ assert_raise FileNotFoundError do
29
+ command.execute path("a.js")
30
+ end
31
+ end
32
+
33
+ should "verify several files" do
34
+ files = %w[file1.js file2.js file3.js]
35
+ ok = "OK!\njslint: No problems"
36
+
37
+ Juicer::Command::Verify.any_instance.expects(:files).with(files).returns(files)
38
+ Juicer::JsLint.any_instance.expects(:check).with(files[0]).returns(Juicer::JsLint::Report.new)
39
+ Juicer::JsLint.any_instance.expects(:check).with(files[1]).returns(Juicer::JsLint::Report.new(["Oops"]))
40
+ Juicer::JsLint.any_instance.expects(:check).with(files[2]).returns(Juicer::JsLint::Report.new)
41
+
42
+ @command.execute(files)
43
+
44
+ assert_match(/OK!/, @io.string)
45
+ assert_match(/Problems detected/, @io.string)
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. test_helper])) unless defined?(Juicer)
1
+ require "test_helper"
2
2
 
3
3
  class TestCssCacheBuster < Test::Unit::TestCase
4
4
  def setup
@@ -8,34 +8,13 @@ class TestCssCacheBuster < Test::Unit::TestCase
8
8
 
9
9
  def teardown
10
10
  Juicer::Test::FileSetup.new.delete
11
- end
12
-
13
- def test_resolve_full_url
14
- assert_equal "http://localhost/images/1.png", @buster.resolve("http://localhost/images/1.png", "")
15
- end
16
-
17
- def test_resolve_relative_url
18
- file = path("images/1.png")
19
- assert_equal(file, @buster.resolve("../images/1.png", path("css/test.css")))
20
- end
21
-
22
- def test_resolve_absolute_url_without_web_root_should_fail
23
- file = path("images/1.png")
24
- assert_raise FileNotFoundError do
25
- @buster.resolve("/images/1.png", path("css/test.css"))
26
- end
27
- end
28
-
29
- def test_resolve_absolute_url_with_web_root
30
- buster = Juicer::CssCacheBuster.new :web_root => path("")
31
- file = path("images/1.png")
32
- assert_equal(file, buster.resolve("/images/1.png", path("css/test.css")))
11
+ Juicer::Test::FileSetup.new.create
33
12
  end
34
13
 
35
14
  def test_find_urls
36
15
  urls = @buster.urls(path("css/test.css"))
37
16
  assert_equal 3, urls.length
38
- assert_equal "../a1.css../images/1.png2.gif", urls.sort.join.gsub(path("/"), "")
17
+ assert_equal "../a1.css../images/1.png2.gif", urls.collect { |a| a.path }.sort.join.gsub(path("/"), "")
39
18
  end
40
19
 
41
20
  def test_image_references_should_be_updated
@@ -48,7 +27,7 @@ class TestCssCacheBuster < Test::Unit::TestCase
48
27
  end
49
28
  end
50
29
 
51
- def test_absolute_path_without_web_root_should_fail
30
+ def test_absolute_path_without_document_root_should_fail
52
31
  file = path("css/test2.css")
53
32
  buster = Juicer::CssCacheBuster.new
54
33
 
@@ -57,9 +36,9 @@ class TestCssCacheBuster < Test::Unit::TestCase
57
36
  end
58
37
  end
59
38
 
60
- def test_absolute_path_should_be_resolved_when_web_root_known
39
+ def test_absolute_path_should_be_resolved_when_document_root_known
61
40
  file = path("css/test.css")
62
- buster = Juicer::CssCacheBuster.new :web_root => path("")
41
+ buster = Juicer::CssCacheBuster.new :document_root => path("")
63
42
 
64
43
  assert_nothing_raised do
65
44
  buster.save file
@@ -74,7 +53,7 @@ class TestCssCacheBuster < Test::Unit::TestCase
74
53
  File.open(path("a2.css"), "w") { |f| f.puts "" }
75
54
  file = path("path_test2.css")
76
55
  output = path("path_test3.css")
77
- buster = Juicer::CssCacheBuster.new :web_root => path("")
56
+ buster = Juicer::CssCacheBuster.new :document_root => path("")
78
57
  buster.save file, output
79
58
 
80
59
  buster.urls(output).each { |url| assert url !~ /(jcb=\d+).*(jcb=\d+)/, url }
@@ -84,8 +63,9 @@ class TestCssCacheBuster < Test::Unit::TestCase
84
63
  File.open(path("a2.css"), "w") { |f| f.puts "" }
85
64
  file = path("path_test2.css")
86
65
  output = path("path_test3.css")
87
- buster = Juicer::CssCacheBuster.new :web_root => path(""), :type => :hard
66
+ buster = Juicer::CssCacheBuster.new :document_root => path(""), :type => :hard
88
67
  buster.save file, output
89
- buster.urls(output).each { |url| assert url =~ /-\d+\.[a-z]{3}/, url }
68
+
69
+ buster.urls(output).each { |asset| assert_match /-jcb\d+\.[a-z]{3}$/, asset.path }
90
70
  end
91
71
  end
@@ -0,0 +1,37 @@
1
+ require 'test/unit'
2
+ require "test_helper"
3
+
4
+ class TC_Datafy < Test::Unit::TestCase
5
+
6
+ def test_make_data_uri_text_plain
7
+ assert_equal(SHORT_TEXT_PLAIN_URI, Datafy::make_data_uri(SHORT_STRING, TEXT_PLAIN))
8
+ assert_equal(LONG_TEXT_PLAIN_URI, Datafy::make_data_uri(LONG_STRING, TEXT_PLAIN))
9
+ end
10
+
11
+ def test_make_data_uri_octet_stream
12
+ assert_equal(SHORT_APPLICATION_OCTET_STREAM_URI, Datafy::make_data_uri(SHORT_STRING, APPLICATION_OCTET_STREAM))
13
+ assert_equal(LONG_APPLICATION_OCTET_STREAM_URI, Datafy::make_data_uri(LONG_STRING, APPLICATION_OCTET_STREAM))
14
+ end
15
+
16
+ # mime types
17
+ TEXT_PLAIN = 'text/plain'
18
+ APPLICATION_OCTET_STREAM = 'application/octet-stream'
19
+
20
+ # string versions
21
+ SHORT_STRING = 'this is some text'
22
+ SHORT_BASE64 = 'dGhpcyBpcyBzb21lIHRleHQ='
23
+ SHORT_URLENCODED = 'this+is+some+text'
24
+
25
+ LONG_STRING = 'this is a really long string. this is a really long string. this is a really long string. this is a really long string. this is a really long string. this is a really long string. this is a really long string. this is a really long string.'
26
+ LONG_BASE64 = 'dGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4gdGhpcyBpcyBhIHJlYWxseSBsb25nIHN0cmluZy4='
27
+ LONG_URLENCODED = 'this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.+this+is+a+really+long+string.'
28
+
29
+ # data: uris
30
+ SHORT_APPLICATION_OCTET_STREAM_URI = "data:#{APPLICATION_OCTET_STREAM};base64,#{SHORT_BASE64}"
31
+ SHORT_TEXT_PLAIN_URI = "data:#{TEXT_PLAIN},#{SHORT_URLENCODED}"
32
+
33
+ LONG_APPLICATION_OCTET_STREAM_URI = "data:#{APPLICATION_OCTET_STREAM};base64,#{LONG_BASE64}"
34
+ LONG_TEXT_PLAIN_URI = "data:#{TEXT_PLAIN},#{LONG_URLENCODED}"
35
+
36
+
37
+ end
@@ -1,8 +1,8 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. test_helper])) unless defined?(Juicer)
1
+ require "test_helper"
2
2
 
3
3
  class TestCssDependencyResolver < Test::Unit::TestCase
4
4
  def setup
5
- @resolver = Juicer::Merger::CssDependencyResolver.new
5
+ @resolver = Juicer::CssDependencyResolver.new
6
6
  Juicer::Test::FileSetup.new.create
7
7
  end
8
8
 
@@ -1,9 +1,9 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. test_helper])) unless defined?(Juicer)
1
+ require "test_helper"
2
2
 
3
3
  class TestJavaScriptDependencyResolver < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- @resolver = Juicer::Merger::JavaScriptDependencyResolver.new
6
+ @resolver = Juicer::JavaScriptDependencyResolver.new
7
7
  Juicer::Test::FileSetup.new.create
8
8
  end
9
9
 
@@ -36,4 +36,15 @@ class TestJavaScriptDependencyResolver < Test::Unit::TestCase
36
36
 
37
37
  assert_equal [a_file, b_file], files.sort
38
38
  end
39
+
40
+ def test_directory_resolve
41
+ my_app = path("my_app.js")
42
+ expected_files = %w(pkg/pkg.js
43
+ pkg/module/moda.js
44
+ pkg/module/modb.js
45
+ my_app.js).map{|file| path(file)}
46
+
47
+ actual_files = @resolver.resolve(my_app)
48
+ assert_equal expected_files, actual_files
49
+ end
39
50
  end
@@ -1,6 +1,5 @@
1
1
  require "test_helper"
2
2
 
3
-
4
3
  class TestStringExtensions < Test::Unit::TestCase
5
4
  context "camel case method" do
6
5
  should "convert underscored string" do
@@ -25,12 +24,6 @@ class TestStringExtensions < Test::Unit::TestCase
25
24
  assert_equal String, "String".to_class
26
25
  end
27
26
 
28
- should "raise error when loading String class from array class" do
29
- assert_raise RuntimeError do
30
- "String".to_class(Array)
31
- end
32
- end
33
-
34
27
  should "return String class from Object" do
35
28
  assert_equal String, "String".to_class(Object)
36
29
  end
@@ -0,0 +1,27 @@
1
+ require "test_helper"
2
+
3
+ class TestSymbolExtensions < Test::Unit::TestCase
4
+ context "camel case method" do
5
+ should "return camel cased string from underscored symbol" do
6
+ assert_equal "CamelCase", :camel_case.camel_case
7
+ end
8
+
9
+ should "return camel cased string from upper cased underscored symbol" do
10
+ assert_equal "CamelCase", :CAMEL_CASE.camel_case
11
+ end
12
+
13
+ should "return camel cased string from 'camel cased' underscored symbol" do
14
+ assert_equal "CamelCase", :Camel_Case.camel_case
15
+ end
16
+ end
17
+
18
+ context "classify method" do
19
+ should "return nested class" do
20
+ assert_equal Juicer::DependencyResolver, :dependency_resolver.classify(Juicer)
21
+ end
22
+
23
+ should "return top level class from underscored symbol" do
24
+ assert_equal FileUtils, :file_utils.classify
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,271 @@
1
+ require "test_helper"
2
+ require 'fakefs/safe'
3
+
4
+ class TestImageEmbed < Test::Unit::TestCase
5
+ include FakeFS
6
+
7
+ context "ImageEmbed instance using data_uri," do
8
+ setup do
9
+ FakeFS.activate!
10
+ FileSystem.clear
11
+ FileUtils.mkdir_p("/stylesheets")
12
+ FileUtils.mkdir_p("/images")
13
+
14
+ @supported_assets = [
15
+ { :path => '/images/test.png', :content => 'hello png!' },
16
+ { :path => '/images/test.gif', :content => 'hello gif!' },
17
+ { :path => '/images/test.jpg', :content => 'hello jpg!' },
18
+ { :path => '/images/test.jpeg', :content => 'hello jpeg!' },
19
+ ]
20
+ create_files(@supported_assets)
21
+
22
+ @unsupported_assets = [
23
+ { :path => '/images/test.bmp', :content => 'hello bmp!' },
24
+ { :path => '/images/test.js', :content => 'hello js!' },
25
+ { :path => '/images/test.txt', :content => 'hello txt!' },
26
+ { :path => '/images/test.swf', :content => 'hello swf!' },
27
+ { :path => '/images/test.swf', :content => 'hello swf!' },
28
+ { :path => '/images/test.ico', :content => 'hello ico!' },
29
+ { :path => '/images/test.tif', :content => 'hello tif!' },
30
+ { :path => '/images/test.tiff', :content => 'hello tiff!' },
31
+ { :path => '/images/test.applet', :content => 'hello applet!' },
32
+ { :path => '/images/test.jar', :content => 'hello jar!' }
33
+ ]
34
+ create_files(@unsupported_assets)
35
+ @embedder = Juicer::ImageEmbed.new(:type => :data_uri, :document_root => '')
36
+ end
37
+
38
+ teardown do
39
+ FakeFS.deactivate!
40
+ end
41
+
42
+ context "save method" do
43
+ context "with files exceeding SIZE_LIMIT" do
44
+ setup do
45
+ @large_files = [{ :path => '/images/large-file.png',
46
+ :content => "hello png!" + (" " * @embedder.size_limit) }]
47
+ create_files(@large_files)
48
+
49
+ @stylesheets = [{
50
+ :path => '/stylesheets/test_embed_duplicates.css',
51
+ :content => "body: { background: url(#{@large_files.first[:path]}?embed=true); }"
52
+ }]
53
+ create_files(@stylesheets)
54
+ end
55
+
56
+ should "not embed images that exceeds size limit" do
57
+ # make sure there are no errors
58
+ assert_nothing_raised do
59
+ @embedder.save @stylesheets.first[:path]
60
+ end
61
+
62
+ css_contents = File.read(@stylesheets.first[:path])
63
+
64
+ # encode the image
65
+ image_contents = File.read( @large_files.first[:path] )
66
+ data_uri = Datafy::make_data_uri(image_contents, 'image/png')
67
+
68
+ # make sure the encoded data_uri is not present in the stylesheet
69
+ assert !css_contents.include?(data_uri)
70
+
71
+ # make sure the original url still exist in the stylesheet
72
+ assert_match Regexp.new(@large_files.first[:path]), css_contents
73
+ end
74
+ end
75
+
76
+ context "with duplicated urls" do
77
+ setup do
78
+ @stylesheets = [{
79
+ :path => '/stylesheets/test_embed_duplicates.css',
80
+ :content => <<-EOF
81
+ body: { background: url(#{@supported_assets.first[:path]}?embed=true); }
82
+ div.section: { background: url(#{@supported_assets.first[:path]}?embed=true); }
83
+ div.article: { background: url(#{@supported_assets.last[:path]}?embed=true); }
84
+ EOF
85
+ }]
86
+ create_files(@stylesheets)
87
+ end
88
+
89
+ should_eventually "provide warnings for duplicate urls"
90
+
91
+ should "not embed duplicates" do
92
+ # make sure there are no errors
93
+ assert_nothing_raised do
94
+ @embedder.save @stylesheets.first[:path]
95
+ end
96
+
97
+ css_contents = File.read(@stylesheets.first[:path])
98
+
99
+ # encode the image
100
+ image_contents = File.read(@supported_assets.first[:path])
101
+ data_uri = Datafy::make_data_uri(image_contents, 'image/png')
102
+
103
+ # make sure the encoded data_uri is not present in the stylesheet
104
+ assert !css_contents.include?(data_uri)
105
+ end
106
+
107
+ should "embed distinct urls" do
108
+ # make sure there are no errors
109
+ assert_nothing_raised do
110
+ @embedder.save @stylesheets.first[:path]
111
+ end
112
+
113
+ css_contents = File.read(@stylesheets.first[:path])
114
+
115
+ # encode the image
116
+ image_contents = File.read(@supported_assets.last[:path])
117
+ data_uri = Datafy::make_data_uri(image_contents, 'image/jpeg')
118
+
119
+ # make sure the encoded data_uri is not present in the stylesheet
120
+ assert css_contents.include?(data_uri)
121
+
122
+ assert_no_match Regexp.new(@supported_assets.last[:path]), css_contents
123
+ end
124
+
125
+ end
126
+
127
+ should "embed images into css file" do
128
+ @stylesheets = [
129
+ {
130
+ :path => '/stylesheets/test_embed_true.css',
131
+ :content => "body: { background: url(#{@supported_assets.first[:path]}?embed=true); }"
132
+ }
133
+ ]
134
+ create_files( @stylesheets )
135
+
136
+ @stylesheets.each do |stylesheet|
137
+ old_contents = File.read( stylesheet[:path] )
138
+
139
+ # make sure there are no errors
140
+ assert_nothing_raised do
141
+ @embedder.save stylesheet[:path]
142
+ end
143
+
144
+ css_contents = File.read( stylesheet[:path] )
145
+
146
+ # make sure the original url does not exist anymore
147
+ assert_no_match( Regexp.new( @supported_assets.first[:path] ), css_contents )
148
+
149
+ # make sure the url has been converted into a data uri
150
+ image_contents = File.read( @supported_assets.first[:path] )
151
+
152
+ # # create the data uri from the image contents
153
+ data_uri = Datafy::make_data_uri( image_contents, 'image/png' )
154
+
155
+ # let's see if the data uri exists in the file
156
+ assert css_contents.include?( data_uri )
157
+ end
158
+ end
159
+
160
+ should "not embed unflagged images" do
161
+ @stylesheets = [
162
+ {
163
+ :path => '/stylesheets/test_embed_true.css',
164
+ :content => "
165
+ body: { background: url(#{@supported_assets.first[:path]}); }
166
+ h1: { background: url(#{@supported_assets.last[:path]}?embed=false); }
167
+ "
168
+ }
169
+ ]
170
+ create_files( @stylesheets )
171
+
172
+ @stylesheets.each do |stylesheet|
173
+ old_contents = File.read( stylesheet[:path] )
174
+
175
+ # make sure there are no errors
176
+ assert_nothing_raised do
177
+ @embedder.save stylesheet[:path]
178
+ end
179
+
180
+ css_contents = File.read( stylesheet[:path] )
181
+
182
+ # make sure the original url still exists
183
+ assert_match( Regexp.new( @supported_assets.first[:path] ), css_contents )
184
+ assert_match( Regexp.new( @supported_assets.last[:path] ), css_contents )
185
+ end
186
+ end
187
+
188
+
189
+ should "not embed unsupported images" do
190
+ @stylesheets = [
191
+ {
192
+ :path => '/stylesheets/test_embed_true.css',
193
+ :content => "
194
+ body: { background: url(#{@unsupported_assets.first[:path]}?embed=true); }
195
+ h1: { background: url(#{@unsupported_assets.last[:path]}?embed=true); }
196
+ "
197
+ }
198
+ ]
199
+ create_files( @stylesheets )
200
+
201
+ @stylesheets.each do |stylesheet|
202
+ old_contents = File.read( stylesheet[:path] )
203
+
204
+ # make sure there are no errors
205
+ assert_nothing_raised do
206
+ @embedder.save stylesheet[:path]
207
+ end
208
+
209
+ css_contents = File.read( stylesheet[:path] )
210
+
211
+ # make sure the original url still exists
212
+ assert_match( Regexp.new( @unsupported_assets.first[:path] ), css_contents )
213
+ assert_match( Regexp.new( @unsupported_assets.last[:path] ), css_contents )
214
+ end
215
+ end
216
+
217
+
218
+ end # context
219
+
220
+ context "embed method" do
221
+ should "not modify regular paths" do
222
+ path = @supported_assets.first[:path]
223
+ assert_equal( path, @embedder.embed_data_uri( path ) )
224
+ end
225
+
226
+ should "not modify paths flagged as not embeddable" do
227
+ path = "#{@supported_assets.first[:path]}?embed=false"
228
+ assert_equal( path, @embedder.embed_data_uri( path ) )
229
+ end
230
+
231
+ should "embed image when path flagged as embeddable" do
232
+ path = "#{@supported_assets.first[:path]}?embed=true"
233
+ assert_not_equal( path, @embedder.embed_data_uri( path ) )
234
+ end
235
+
236
+ should "encode all supported asset types" do
237
+ @supported_assets.each do |asset|
238
+ path = "#{asset[:path]}?embed=true"
239
+ assert_not_equal( path, @embedder.embed_data_uri( path ) )
240
+ end
241
+ end
242
+
243
+ should "not encod unsupported asset types" do
244
+ @unsupported_assets.each do |asset|
245
+ path = "#{asset[:path]}?embed=true"
246
+ assert_equal( path, @embedder.embed_data_uri( path ) )
247
+ end
248
+ end
249
+
250
+ should "set correct mimetype for supported extensions" do
251
+ @supported_assets.each do |asset|
252
+ path = "#{asset[:path]}?embed=true"
253
+ extension = /(png|gif|jpg|jpeg)/.match( asset[:path] )
254
+ assert_match(/image\/#{extension}/, @embedder.embed_data_uri( path ) )
255
+ end
256
+ end
257
+ end # context
258
+ end
259
+
260
+ private
261
+ # expects the containing path to have been created already
262
+ def create_files( files = [] )
263
+ files.each do |file|
264
+ path = file[:path]
265
+ File.open(path, 'w') do |f|
266
+ f.write file[:content]
267
+ assert File.exists?( file[:path] )
268
+ end
269
+ end
270
+ end
271
+ end