css_image_embedder 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +5 -0
- data/Gemfile +2 -0
- data/LICENCE +20 -0
- data/Manifest +23 -0
- data/README.md +57 -0
- data/Rakefile +12 -0
- data/css_image_embedder.gemspec +37 -0
- data/init.rb +1 -0
- data/lib/css_image_embedder/converter.rb +119 -0
- data/lib/css_image_embedder/exception.rb +9 -0
- data/lib/css_image_embedder/helper.rb +45 -0
- data/lib/css_image_embedder.rb +5 -0
- data/spec/css_image_embedder_spec.rb +140 -0
- data/spec/files/bg.png +0 -0
- data/spec/files/bg_base64.png +1 -0
- data/spec/files/big_converted.css +6 -0
- data/spec/files/file_sources_invalid.css +6 -0
- data/spec/files/oneliner.css +1 -0
- data/spec/files/oneliner_converted.css +1 -0
- data/spec/files/std.css +6 -0
- data/spec/files/std_converted.css +6 -0
- data/spec/files/too_big.css +6 -0
- data/spec/files/too_big.jpg +0 -0
- data/spec/spec_helper.rb +9 -0
- data.tar.gz.sig +1 -0
- metadata +131 -0
- metadata.gz.sig +0 -0
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
data/LICENCE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Maciej Mensfeld
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
CHANGELOG.rdoc
|
2
|
+
Gemfile
|
3
|
+
LICENCE
|
4
|
+
README.md
|
5
|
+
Rakefile
|
6
|
+
init.rb
|
7
|
+
lib/css_image_embedder.rb
|
8
|
+
lib/css_image_embedder/converter.rb
|
9
|
+
lib/css_image_embedder/exception.rb
|
10
|
+
lib/css_image_embedder/helper.rb
|
11
|
+
spec/css_image_embedder_spec.rb
|
12
|
+
spec/files/bg.png
|
13
|
+
spec/files/bg_base64.png
|
14
|
+
spec/files/big_converted.css
|
15
|
+
spec/files/file_sources_invalid.css
|
16
|
+
spec/files/oneliner.css
|
17
|
+
spec/files/oneliner_converted.css
|
18
|
+
spec/files/std.css
|
19
|
+
spec/files/std_converted.css
|
20
|
+
spec/files/too_big.css
|
21
|
+
spec/files/too_big.jpg
|
22
|
+
spec/spec_helper.rb
|
23
|
+
Manifest
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# CSS Image Embedder
|
2
|
+
|
3
|
+
Css Image Embedder puts your background files directly into corresponding CSS file. Thanks to that - your server needs to handle fewer requests and the page layout renders smoothly (whole stylesheet at once).
|
4
|
+
|
5
|
+
## INSTALL
|
6
|
+
|
7
|
+
gem install css_image_embedder
|
8
|
+
|
9
|
+
# USAGE
|
10
|
+
|
11
|
+
Add gem to your gemfile:
|
12
|
+
|
13
|
+
gem 'css_image_embedder'
|
14
|
+
|
15
|
+
and then you will gain a helper method called `image_embed_stylesheet_link_tag`. Use it instead of `stylesheet_link_tag` (params are the same). This helper method will not destroy (or modify) your original CSS files. It only changes cached CSS file, so if you do not use:
|
16
|
+
|
17
|
+
:cache => "/path/cached_stylesheets.css"
|
18
|
+
|
19
|
+
method will act the same way as `stylesheet_link_tag`. Also - you will not see any effect in development environment (except when you turn caching on).
|
20
|
+
|
21
|
+
## Disadvantages
|
22
|
+
|
23
|
+
Css Image Embedder has one major disadvantage. Files converted into base64 are approximately 30% bigger then normal, so when you embed them into CSS file, the total size of CSS with backgrounds will not be equal to sum of CSS file and backgrounds files. However, if you use gzip compression on your server - it will compress CSS file and the total size will be approximately equal. So just turn gzip compression on :)
|
24
|
+
## Example
|
25
|
+
|
26
|
+
Suppose we have two backgrounds: `bg1.png` and `bg2.jpg` and two CSS files (each for background declaration): `first.css` and `second.css`.
|
27
|
+
|
28
|
+
The background declarations will be normal. You don't need to do anything special in your CSS files. So lets take `first.css`:
|
29
|
+
|
30
|
+
#first { background: #fff url(/images/bg1.png) no-repeat;}
|
31
|
+
|
32
|
+
and second stylesheet:
|
33
|
+
|
34
|
+
#second { background: #fff url(/images/bg2.png) no-repeat;}
|
35
|
+
|
36
|
+
Now lets just use them in our layout:
|
37
|
+
|
38
|
+
image_embed_stylesheet_link_tag(
|
39
|
+
"first", "second",
|
40
|
+
:cache => "cached_stylesheet"
|
41
|
+
)
|
42
|
+
|
43
|
+
This will produce nice `cached_stylesheet` with both background images embedded directly into cached CSS file.
|
44
|
+
|
45
|
+
|
46
|
+
## Note on Patches/Pull Requests
|
47
|
+
|
48
|
+
* Fork the project.
|
49
|
+
* Make your feature addition or bug fix.
|
50
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
51
|
+
* Commit, do not mess with Rakefile, version, or history.
|
52
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
53
|
+
* Send me a pull request. Bonus points for topic branches.
|
54
|
+
|
55
|
+
## Copyright
|
56
|
+
|
57
|
+
Copyright (c) 2011 Maciej Mensfeld. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('css_image_embedder', '0.1.1') do |p|
|
6
|
+
p.description = "Css Image Embedder puts your background files directly into corresponding CSS file. Thanks to that - your server needs to handle fewer requests and the page layout renders smoothly (whole stylesheet at once)."
|
7
|
+
p.url = "http://github.com/mensfeld/css_image_embedder"
|
8
|
+
p.author = "Maciej Mensfeld"
|
9
|
+
p.email = "maciej@mensfeld.pl"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = ["rspec >=2.0.0", "rails"]
|
12
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{css_image_embedder}
|
5
|
+
s.version = "0.1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Maciej Mensfeld"]
|
9
|
+
s.cert_chain = ["/home/mencio/.cert_keys/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2011-04-09}
|
11
|
+
s.description = %q{Css Image Embedder puts your background files directly into corresponding CSS file. Thanks to that - your server needs to handle fewer requests and the page layout renders smoothly (whole stylesheet at once).}
|
12
|
+
s.email = %q{maciej@mensfeld.pl}
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.md", "lib/css_image_embedder.rb", "lib/css_image_embedder/converter.rb", "lib/css_image_embedder/exception.rb", "lib/css_image_embedder/helper.rb"]
|
14
|
+
s.files = ["CHANGELOG.rdoc", "Gemfile", "LICENCE", "README.md", "Rakefile", "init.rb", "lib/css_image_embedder.rb", "lib/css_image_embedder/converter.rb", "lib/css_image_embedder/exception.rb", "lib/css_image_embedder/helper.rb", "spec/css_image_embedder_spec.rb", "spec/files/bg.png", "spec/files/bg_base64.png", "spec/files/big_converted.css", "spec/files/file_sources_invalid.css", "spec/files/oneliner.css", "spec/files/oneliner_converted.css", "spec/files/std.css", "spec/files/std_converted.css", "spec/files/too_big.css", "spec/files/too_big.jpg", "spec/spec_helper.rb", "Manifest", "css_image_embedder.gemspec"]
|
15
|
+
s.homepage = %q{http://github.com/mensfeld/css_image_embedder}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Css_image_embedder", "--main", "README.md"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{css_image_embedder}
|
19
|
+
s.rubygems_version = %q{1.5.2}
|
20
|
+
s.signing_key = %q{/home/mencio/.cert_keys/gem-private_key.pem}
|
21
|
+
s.summary = %q{Css Image Embedder puts your background files directly into corresponding CSS file. Thanks to that - your server needs to handle fewer requests and the page layout renders smoothly (whole stylesheet at once).}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
28
|
+
s.add_development_dependency(%q<rails>, [">= 0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
31
|
+
s.add_dependency(%q<rails>, [">= 0"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
35
|
+
s.add_dependency(%q<rails>, [">= 0"])
|
36
|
+
end
|
37
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'css_image_embedder'
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Converts CSS files - it will embed any img file attached as background
|
4
|
+
# background: url(...)... --> (base64) --> url(data:image/png;base64,...)
|
5
|
+
# Domyślnie osadza w CSSie tylko pliki mniejsze niz 32kb
|
6
|
+
|
7
|
+
require 'base64'
|
8
|
+
module CssImageEmbedder
|
9
|
+
class Converter
|
10
|
+
# IE does not accept embed files bigger then 32kb
|
11
|
+
DEFAULT_MAX_IMG_SIZE = 32*1024
|
12
|
+
|
13
|
+
attr_reader :result
|
14
|
+
|
15
|
+
def initialize(*sources)
|
16
|
+
options = sources.extract_options!.stringify_keys
|
17
|
+
source = options.delete("source")
|
18
|
+
@file_path = options.delete("path")
|
19
|
+
@root_path = options.delete("root")
|
20
|
+
@overwrite = options.delete("overwrite") || false
|
21
|
+
@result = nil
|
22
|
+
|
23
|
+
@img_max_size = options.delete("img_max_size") || DEFAULT_MAX_IMG_SIZE
|
24
|
+
|
25
|
+
if @file_path
|
26
|
+
raise CssNotFound unless File.exists?(@file_path)
|
27
|
+
@source = File.open(@file_path, 'r') { |file| file.read }
|
28
|
+
else
|
29
|
+
raise CssStringNotProvided unless source
|
30
|
+
@source = source
|
31
|
+
@overwrite = false
|
32
|
+
end
|
33
|
+
|
34
|
+
raise RootPathNotProvided unless @root_path
|
35
|
+
end
|
36
|
+
|
37
|
+
# Performe converting
|
38
|
+
def convert
|
39
|
+
if elements = pull
|
40
|
+
source = @source
|
41
|
+
elements.each do |el|
|
42
|
+
file_base64 = File.join(@root_path, el[:converted_path])
|
43
|
+
file_ext = el[:converted_path].split('.').last
|
44
|
+
begin
|
45
|
+
next if File.size?(file_base64) > @img_max_size
|
46
|
+
file_base64 = self.class.file_to_base64(file_base64)
|
47
|
+
source.gsub!(el[:original_url], "url(data:image/#{file_ext.downcase};base64,#{file_base64})")
|
48
|
+
rescue
|
49
|
+
next
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@result = source
|
53
|
+
else
|
54
|
+
@result = @source
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Saves converted result to file
|
59
|
+
def save(filename = nil)
|
60
|
+
if @file_path && @overwrite && filename.nil?
|
61
|
+
p = @file_path
|
62
|
+
else
|
63
|
+
p = filename
|
64
|
+
end
|
65
|
+
f = File.new(p, "w")
|
66
|
+
f.write(@result)
|
67
|
+
f.close
|
68
|
+
end
|
69
|
+
|
70
|
+
# Force overwrite
|
71
|
+
def save!(filename = nil)
|
72
|
+
@overwrite = true
|
73
|
+
save(filename)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Convert to base64 without new lines
|
77
|
+
def self.file_to_base64(path)
|
78
|
+
str = File.open(path, 'r') { |file| file.read }
|
79
|
+
Base64.encode64(str).gsub("\n", '')
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Pulls out files paths from url(smthng)
|
85
|
+
# Returns an array containing:
|
86
|
+
# - original path (./images/smthng.png)
|
87
|
+
# - converted path (/images/smthng.png)
|
88
|
+
# - original url (url(./images/smthng.png))
|
89
|
+
def pull
|
90
|
+
# Whole urls including stuff around (url('/images/smthng.png') )
|
91
|
+
whole_urls = @source.scan(/url\(.+?\)/i)
|
92
|
+
return nil if whole_urls.count == 0
|
93
|
+
|
94
|
+
img_bg_paths = []
|
95
|
+
whole_urls.each do |url|
|
96
|
+
img_bg_paths << url.scan(/url\(\s*["']?([^"']+)["']?\s*\)/i)[0][0]
|
97
|
+
end
|
98
|
+
img_bg_paths_original = img_bg_paths.clone
|
99
|
+
|
100
|
+
img_bg_paths.collect! do |img|
|
101
|
+
img = img.gsub('./', '/')
|
102
|
+
img = "/#{img}" if img[0] != '/'
|
103
|
+
img
|
104
|
+
end
|
105
|
+
|
106
|
+
result = []
|
107
|
+
img_bg_paths.each_with_index do |el, i|
|
108
|
+
result <<
|
109
|
+
{:original_path =>img_bg_paths_original[i],
|
110
|
+
:converted_path => el,
|
111
|
+
:original_url => whole_urls[i]
|
112
|
+
}
|
113
|
+
end
|
114
|
+
result.uniq!
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Helper methods for ActionView::Base in Rails
|
2
|
+
module CssImageEmbedder
|
3
|
+
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
# Basicly it's just stylesheet_link_tag with one small difference ;)
|
7
|
+
# Will not test it - Rails guys already did it
|
8
|
+
def image_embed_stylesheet_link_tag(*sources)
|
9
|
+
options = sources.extract_options!.stringify_keys
|
10
|
+
concat = options.delete("concat")
|
11
|
+
cache = concat || options.delete("cache")
|
12
|
+
recursive = options.delete("recursive")
|
13
|
+
root = options.delete("root") || File.join(Rails.root, 'public')
|
14
|
+
env = options.delete("env") || Rails.env
|
15
|
+
|
16
|
+
if concat || (config.perform_caching && cache)
|
17
|
+
joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
|
18
|
+
joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.stylesheets_dir, joined_stylesheet_name)
|
19
|
+
|
20
|
+
unless config.perform_caching && File.exists?(joined_stylesheet_path)
|
21
|
+
write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
|
22
|
+
# here's the magic ;)
|
23
|
+
css = CssImageEmbedder::Converter.new(
|
24
|
+
:path => joined_stylesheet_path,
|
25
|
+
:overwrite => true,
|
26
|
+
:root => root)
|
27
|
+
css.convert
|
28
|
+
css.save!
|
29
|
+
end
|
30
|
+
stylesheet_tag(joined_stylesheet_name, options)
|
31
|
+
else
|
32
|
+
sources = expand_stylesheet_sources(sources, recursive)
|
33
|
+
# When we use SASS and test env - will not work - and will raise
|
34
|
+
# exception - that css files does not exist. We make a workaround
|
35
|
+
# by not checking sources in test env
|
36
|
+
ensure_stylesheet_sources!(sources) if cache && env != 'test'
|
37
|
+
sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end # Helper
|
42
|
+
|
43
|
+
end # Base64CssEmbedder
|
44
|
+
|
45
|
+
ActionView::Base.send :include, CssImageEmbedder::Helper
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
4
|
+
FILES_ROOT = File.join(ROOT, 'files')
|
5
|
+
|
6
|
+
def file_content(f)
|
7
|
+
file = File.new("#{f}", "r")
|
8
|
+
content = ''
|
9
|
+
while (line = file.gets)
|
10
|
+
content+=line
|
11
|
+
end
|
12
|
+
content
|
13
|
+
end
|
14
|
+
|
15
|
+
def files_equal?(f1, f2)
|
16
|
+
file_content(f1) == file_content(f2)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe CssImageEmbedder::Converter do
|
20
|
+
subject { CssImageEmbedder::Converter }
|
21
|
+
|
22
|
+
# Should clear all css files created in test
|
23
|
+
after(:all) do
|
24
|
+
FileUtils.rm("#{ROOT}/std.css")
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when we have CSS file without any strange stuff" do
|
28
|
+
it "should convert std css file and embed pictures into it" do
|
29
|
+
converter = subject.new(
|
30
|
+
:path => "#{FILES_ROOT}/std.css",
|
31
|
+
:overwrite => true,
|
32
|
+
:root => ROOT
|
33
|
+
)
|
34
|
+
converter.convert
|
35
|
+
converter.result.should === file_content("#{FILES_ROOT}/std_converted.css")
|
36
|
+
end
|
37
|
+
|
38
|
+
context "and allow to overwrite" do
|
39
|
+
it "should embed backgrounds and overwrite source file" do
|
40
|
+
# Copy std.css to check if it will be overwritten
|
41
|
+
FileUtils.cp("#{FILES_ROOT}/std.css", "#{ROOT}/std.css")
|
42
|
+
converter = subject.new(
|
43
|
+
:path => "#{ROOT}/std.css",
|
44
|
+
:overwrite => true,
|
45
|
+
:root => ROOT
|
46
|
+
)
|
47
|
+
converter.convert
|
48
|
+
converter.save
|
49
|
+
converter.result.should == file_content("#{ROOT}/std.css")
|
50
|
+
converter.result.should == file_content("#{FILES_ROOT}/std_converted.css")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when we provide too big background" do
|
57
|
+
it "should not embed it by default" do
|
58
|
+
converter = subject.new(
|
59
|
+
:path => "#{FILES_ROOT}/too_big.css",
|
60
|
+
:overwrite => true,
|
61
|
+
:root => ROOT
|
62
|
+
)
|
63
|
+
converter.convert
|
64
|
+
converter.result.should === file_content("#{FILES_ROOT}/too_big.css")
|
65
|
+
end
|
66
|
+
|
67
|
+
context "but limit is bigger" do
|
68
|
+
it "should embed it" do
|
69
|
+
converter = subject.new(
|
70
|
+
:path => "#{FILES_ROOT}/too_big.css",
|
71
|
+
:overwrite => true,
|
72
|
+
:root => ROOT,
|
73
|
+
:img_max_size => 100*1024
|
74
|
+
)
|
75
|
+
converter.convert
|
76
|
+
converter.result.should === file_content("#{FILES_ROOT}/big_converted.css")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when we provide css file where paths don't point to valid files" do
|
82
|
+
it "should leave original css file structure" do
|
83
|
+
converter = subject.new(
|
84
|
+
:path => "#{FILES_ROOT}/file_sources_invalid.css",
|
85
|
+
:root => ROOT
|
86
|
+
)
|
87
|
+
converter.convert
|
88
|
+
converter.result.should == file_content("#{FILES_ROOT}/file_sources_invalid.css")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when we don't provide root path" do
|
93
|
+
it "should raise RootPathNotProvided" do
|
94
|
+
lambda {
|
95
|
+
subject.new(
|
96
|
+
:path => "#{FILES_ROOT}/std_converted.css"
|
97
|
+
)
|
98
|
+
}.should raise_exception(RootPathNotProvided)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when we provide invalid source css file" do
|
103
|
+
it "should raise Exceptions::CssNotFound" do
|
104
|
+
lambda {
|
105
|
+
subject.new(
|
106
|
+
:path => "#{FILES_ROOT}no_file.css"
|
107
|
+
)
|
108
|
+
}.should raise_exception(CssNotFound)
|
109
|
+
end
|
110
|
+
|
111
|
+
context "but we provide string containing css" do
|
112
|
+
it "should convert it from string" do
|
113
|
+
converter = subject.new(
|
114
|
+
:source => file_content("#{FILES_ROOT}/std.css"),
|
115
|
+
:root => ROOT
|
116
|
+
)
|
117
|
+
converter.convert
|
118
|
+
converter.result.should == file_content("#{FILES_ROOT}/std_converted.css")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when we try to convert file to base64" do
|
123
|
+
it "should convert it" do
|
124
|
+
subject.file_to_base64("#{FILES_ROOT}/bg.png").should == file_content("#{FILES_ROOT}/bg_base64.png").gsub("\n", '')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "when we provide huge one liner" do
|
129
|
+
it "should convert it without hesitation" do
|
130
|
+
converter = subject.new(
|
131
|
+
:path => "#{FILES_ROOT}/oneliner.css",
|
132
|
+
:root => ROOT
|
133
|
+
)
|
134
|
+
converter.convert
|
135
|
+
converter.result.should == file_content("#{FILES_ROOT}/oneliner_converted.css")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/spec/files/bg.png
ADDED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
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
|