ktheory-juicer 1.0.0.ktheory1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +30 -0
- data/Manifest.txt +58 -0
- data/Rakefile +96 -0
- data/Readme.rdoc +312 -0
- data/VERSION +1 -0
- data/bin/juicer +8 -0
- data/lib/juicer.rb +70 -0
- data/lib/juicer/asset/path.rb +275 -0
- data/lib/juicer/asset/path_resolver.rb +79 -0
- data/lib/juicer/binary.rb +171 -0
- data/lib/juicer/cache_buster.rb +130 -0
- data/lib/juicer/chainable.rb +106 -0
- data/lib/juicer/cli.rb +56 -0
- data/lib/juicer/command/install.rb +61 -0
- data/lib/juicer/command/list.rb +57 -0
- data/lib/juicer/command/merge.rb +205 -0
- data/lib/juicer/command/util.rb +32 -0
- data/lib/juicer/command/verify.rb +60 -0
- data/lib/juicer/css_cache_buster.rb +80 -0
- data/lib/juicer/datafy/datafy.rb +20 -0
- data/lib/juicer/dependency_resolver/css_dependency_resolver.rb +29 -0
- data/lib/juicer/dependency_resolver/dependency_resolver.rb +101 -0
- data/lib/juicer/dependency_resolver/javascript_dependency_resolver.rb +23 -0
- data/lib/juicer/ext/logger.rb +5 -0
- data/lib/juicer/ext/string.rb +47 -0
- data/lib/juicer/ext/symbol.rb +15 -0
- data/lib/juicer/image_embed.rb +136 -0
- data/lib/juicer/install/base.rb +186 -0
- data/lib/juicer/install/closure_compiler_installer.rb +69 -0
- data/lib/juicer/install/jslint_installer.rb +51 -0
- data/lib/juicer/install/rhino_installer.rb +53 -0
- data/lib/juicer/install/yui_compressor_installer.rb +67 -0
- data/lib/juicer/jslint.rb +90 -0
- data/lib/juicer/merger/base.rb +74 -0
- data/lib/juicer/merger/javascript_merger.rb +29 -0
- data/lib/juicer/merger/stylesheet_merger.rb +110 -0
- data/lib/juicer/minifyer/closure_compiler.rb +90 -0
- data/lib/juicer/minifyer/java_base.rb +77 -0
- data/lib/juicer/minifyer/yui_compressor.rb +96 -0
- data/test/bin/jslint-1.0.js +523 -0
- data/test/bin/jslint.js +523 -0
- data/test/bin/rhino1_7R1.zip +0 -0
- data/test/bin/rhino1_7R2-RC1.jar +0 -0
- data/test/bin/rhino1_7R2-RC1.zip +0 -0
- data/test/bin/yuicompressor +0 -0
- data/test/bin/yuicompressor-2.3.5.zip +0 -0
- data/test/bin/yuicompressor-2.4.2.jar +0 -0
- data/test/bin/yuicompressor-2.4.2.zip +0 -0
- data/test/data/Changelog.txt +10 -0
- data/test/data/a.css +3 -0
- data/test/data/a.js +5 -0
- data/test/data/a1.css +5 -0
- data/test/data/b.css +1 -0
- data/test/data/b.js +5 -0
- data/test/data/b1.css +5 -0
- data/test/data/c1.css +3 -0
- data/test/data/css/2.gif +1 -0
- data/test/data/css/test.css +11 -0
- data/test/data/css/test2.css +1 -0
- data/test/data/d1.css +3 -0
- data/test/data/images/1.png +1 -0
- data/test/data/my_app.js +2 -0
- data/test/data/not-ok.js +2 -0
- data/test/data/ok.js +3 -0
- data/test/data/path_test.css +5 -0
- data/test/data/path_test2.css +14 -0
- data/test/data/pkg/module/moda.js +2 -0
- data/test/data/pkg/module/modb.js +3 -0
- data/test/data/pkg/pkg.js +1 -0
- data/test/test_helper.rb +169 -0
- data/test/unit/juicer/asset/path_resolver_test.rb +76 -0
- data/test/unit/juicer/asset/path_test.rb +370 -0
- data/test/unit/juicer/cache_buster_test.rb +104 -0
- data/test/unit/juicer/chainable_test.rb +94 -0
- data/test/unit/juicer/command/install_test.rb +58 -0
- data/test/unit/juicer/command/list_test.rb +81 -0
- data/test/unit/juicer/command/merge_test.rb +162 -0
- data/test/unit/juicer/command/util_test.rb +58 -0
- data/test/unit/juicer/command/verify_test.rb +48 -0
- data/test/unit/juicer/css_cache_buster_test.rb +71 -0
- data/test/unit/juicer/datafy_test.rb +37 -0
- data/test/unit/juicer/dependency_resolver/css_dependency_resolver_test.rb +36 -0
- data/test/unit/juicer/dependency_resolver/javascript_dependency_resolver_test.rb +50 -0
- data/test/unit/juicer/ext/string_test.rb +59 -0
- data/test/unit/juicer/ext/symbol_test.rb +27 -0
- data/test/unit/juicer/image_embed_test.rb +271 -0
- data/test/unit/juicer/install/installer_base_test.rb +214 -0
- data/test/unit/juicer/install/jslint_installer_test.rb +54 -0
- data/test/unit/juicer/install/rhino_installer_test.rb +57 -0
- data/test/unit/juicer/install/yui_compressor_test.rb +56 -0
- data/test/unit/juicer/jslint_test.rb +60 -0
- data/test/unit/juicer/merger/base_test.rb +122 -0
- data/test/unit/juicer/merger/javascript_merger_test.rb +74 -0
- data/test/unit/juicer/merger/stylesheet_merger_test.rb +180 -0
- data/test/unit/juicer/minifyer/closure_compressor_test.rb +107 -0
- data/test/unit/juicer/minifyer/yui_compressor_test.rb +116 -0
- data/test/unit/juicer_test.rb +1 -0
- metadata +265 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Dummy
|
4
|
+
include Juicer::Command::Util
|
5
|
+
end
|
6
|
+
|
7
|
+
class TestCommandUtil < Test::Unit::TestCase
|
8
|
+
|
9
|
+
CSS_FILES = %w{a.css a1.css b.css b1.css c1.css d1.css path_test.css path_test2.css}
|
10
|
+
JS_FILES = %w{a.js}
|
11
|
+
ALL_FILES = (CSS_FILES + JS_FILES).sort
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@impl = Dummy.new
|
15
|
+
Juicer::Test::FileSetup.new.create
|
16
|
+
Dir.glob("test/data/*.min.css").each { |file| File.delete(file) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_files_from_single_file
|
20
|
+
files = @impl.files("test/data/a.css")
|
21
|
+
assert files.is_a?(Array)
|
22
|
+
assert_equal "test/data/a.css", files.sort.join
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_files_from_single_glob_pattern
|
26
|
+
files = @impl.files("test/data/*.css")
|
27
|
+
assert files.is_a?(Array)
|
28
|
+
assert_equal CSS_FILES.collect { |f| "test/data/#{f}" }.join, files.sort.join
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_files_from_mixed_arguments
|
32
|
+
files = @impl.files("test/data/*.css", "test/data/a.js")
|
33
|
+
assert files.is_a?(Array)
|
34
|
+
assert_equal ALL_FILES.collect { |f| "test/data/#{f}" }.join, files.sort.join
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_files_from_array
|
38
|
+
files = @impl.files(["test/data/*.css", "test/data/a.js"])
|
39
|
+
assert files.is_a?(Array)
|
40
|
+
assert_equal ALL_FILES.collect { |f| "test/data/#{f}" }.join, files.sort.join
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_relative_path_single_file
|
44
|
+
assert_equal "test/data/a.css", @impl.relative("test/data/a.css")
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_relative_path_many_files
|
48
|
+
files = @impl.relative(Dir.glob("test/data/*.css"))
|
49
|
+
assert files.is_a?(Array)
|
50
|
+
assert_equal CSS_FILES.collect { |f| "test/data/#{f}" }.join, files.sort.join
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_relative_path_many_files_explicit_reference
|
54
|
+
files = @impl.relative(Dir.glob("test/data/*.css"), "lib")
|
55
|
+
assert files.is_a?(Array)
|
56
|
+
assert_equal CSS_FILES.collect { |f| "../test/data/#{f}" }.join, files.sort.join
|
57
|
+
end
|
58
|
+
end
|
@@ -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
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestCssCacheBuster < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Juicer::Test::FileSetup.new.create
|
6
|
+
@buster = Juicer::CssCacheBuster.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
Juicer::Test::FileSetup.new.delete
|
11
|
+
Juicer::Test::FileSetup.new.create
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_find_urls
|
15
|
+
urls = @buster.urls(path("css/test.css"))
|
16
|
+
assert_equal 3, urls.length
|
17
|
+
assert_equal "../a1.css../images/1.png2.gif", urls.collect { |a| a.path }.sort.join.gsub(path("/"), "")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_image_references_should_be_updated
|
21
|
+
file = path("css/test.css")
|
22
|
+
buster = Juicer::CssCacheBuster.new
|
23
|
+
buster.save file
|
24
|
+
|
25
|
+
File.read(file).scan(/url\(([^\)]*)\)/m).each do |path|
|
26
|
+
assert_match(/[^\?]*\?jcb=\d+/, path.first)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_absolute_path_without_web_root_should_fail
|
31
|
+
file = path("css/test2.css")
|
32
|
+
buster = Juicer::CssCacheBuster.new
|
33
|
+
|
34
|
+
assert_raise FileNotFoundError do
|
35
|
+
buster.save file
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_absolute_path_should_be_resolved_when_web_root_known
|
40
|
+
file = path("css/test.css")
|
41
|
+
buster = Juicer::CssCacheBuster.new :web_root => path("")
|
42
|
+
|
43
|
+
assert_nothing_raised do
|
44
|
+
buster.save file
|
45
|
+
end
|
46
|
+
|
47
|
+
File.read(file).scan(/url\(([^\)]*)\)/m).each do |path|
|
48
|
+
assert_match(/[^\?]*\?jcb=\d+/, path.first)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_urls_should_only_have_mtime_appended_once
|
53
|
+
File.open(path("a2.css"), "w") { |f| f.puts "" }
|
54
|
+
file = path("path_test2.css")
|
55
|
+
output = path("path_test3.css")
|
56
|
+
buster = Juicer::CssCacheBuster.new :web_root => path("")
|
57
|
+
buster.save file, output
|
58
|
+
|
59
|
+
buster.urls(output).each { |url| assert url !~ /(jcb=\d+).*(jcb=\d+)/, url }
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_type_hard_should_produce_hard_buster_urls
|
63
|
+
File.open(path("a2.css"), "w") { |f| f.puts "" }
|
64
|
+
file = path("path_test2.css")
|
65
|
+
output = path("path_test3.css")
|
66
|
+
buster = Juicer::CssCacheBuster.new :web_root => path(""), :type => :hard
|
67
|
+
buster.save file, output
|
68
|
+
|
69
|
+
buster.urls(output).each { |asset| assert_match /-jcb\d+\.[a-z]{3}$/, asset.path }
|
70
|
+
end
|
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
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestCssDependencyResolver < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@resolver = Juicer::CssDependencyResolver.new
|
6
|
+
Juicer::Test::FileSetup.new.create
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_init
|
10
|
+
assert_equal [], @resolver.files
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_resolve
|
14
|
+
b_file = path('b.css')
|
15
|
+
a_file = path('a.css')
|
16
|
+
|
17
|
+
files = @resolver.resolve(path('a.css')) do |file|
|
18
|
+
assert b_file == file || a_file == file
|
19
|
+
b_file != file
|
20
|
+
end
|
21
|
+
|
22
|
+
assert_equal [a_file], files
|
23
|
+
|
24
|
+
files = @resolver.resolve(path('a.css')) do |file|
|
25
|
+
assert b_file == file || a_file == file
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_equal [a_file, b_file], files.sort
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_load_order
|
33
|
+
files = @resolver.resolve(path("a1.css")).collect { |file| file.split("/").pop }
|
34
|
+
assert_equal "d1.cssb1.cssc1.cssa1.css", files.join
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestJavaScriptDependencyResolver < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@resolver = Juicer::JavaScriptDependencyResolver.new
|
7
|
+
Juicer::Test::FileSetup.new.create
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_init
|
11
|
+
assert_equal [], @resolver.files
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_resolve
|
15
|
+
b_file = path('b.js')
|
16
|
+
a_file = path('a.js')
|
17
|
+
|
18
|
+
files = @resolver.resolve(a_file) do |file|
|
19
|
+
assert b_file == file || a_file == file, file
|
20
|
+
b_file != file
|
21
|
+
end
|
22
|
+
|
23
|
+
assert_equal [a_file], files
|
24
|
+
|
25
|
+
files = @resolver.resolve(a_file) do |file|
|
26
|
+
assert b_file == file || a_file == file
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
assert_equal [a_file, b_file], files.sort
|
31
|
+
|
32
|
+
files = @resolver.resolve(b_file) do |file|
|
33
|
+
assert b_file == file || a_file == file
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
assert_equal [a_file, b_file], files.sort
|
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
|
50
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestStringExtensions < Test::Unit::TestCase
|
4
|
+
context "camel case method" do
|
5
|
+
should "convert underscored string" do
|
6
|
+
assert_equal "CamelCase", "camel_case".camel_case
|
7
|
+
end
|
8
|
+
|
9
|
+
should "convert spaced string" do
|
10
|
+
assert_equal "Camel case", "camel case".camel_case
|
11
|
+
end
|
12
|
+
|
13
|
+
should "convert upper-case underscored string" do
|
14
|
+
assert_equal "CamelCase", "CAMEL_CASE".camel_case
|
15
|
+
end
|
16
|
+
|
17
|
+
should "convert 'camel cased' underscored string" do
|
18
|
+
assert_equal "CamelCase", "Camel_Case".camel_case
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "to_class method" do
|
23
|
+
should "return String class" do
|
24
|
+
assert_equal String, "String".to_class
|
25
|
+
end
|
26
|
+
|
27
|
+
should "return String class from Object" do
|
28
|
+
assert_equal String, "String".to_class(Object)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return nested class" do
|
32
|
+
assert_equal Juicer::DependencyResolver, "Juicer::DependencyResolver".to_class
|
33
|
+
end
|
34
|
+
|
35
|
+
should "return class from module" do
|
36
|
+
assert_equal Juicer::DependencyResolver, "DependencyResolver".to_class(Juicer)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return class from nested module" do
|
40
|
+
assert_equal Juicer::Install::YuiCompressorInstaller, "YuiCompressorInstaller".to_class(Juicer::Install)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "classify method" do
|
45
|
+
should "return class from underscored string" do
|
46
|
+
assert_equal Juicer::DependencyResolver, "dependency_resolver".classify(Juicer)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "return top level class from underscored string" do
|
50
|
+
assert_equal FileUtils, "file_utils".classify
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "underscore method" do
|
55
|
+
should "return underscored string from camel cased string" do
|
56
|
+
assert_equal "stylesheet_merger", "StylesheetMerger".underscore
|
57
|
+
end
|
58
|
+
end
|
59
|
+
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, :web_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
|