spritely 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/spritely/cache.rb +41 -0
- data/lib/spritely/collection.rb +4 -4
- data/lib/spritely/generators/chunky_png.rb +1 -0
- data/lib/spritely/image_set.rb +8 -0
- data/lib/spritely/options.rb +30 -8
- data/lib/spritely/sass_functions.rb +20 -14
- data/lib/spritely/sprite_map.rb +9 -7
- data/lib/spritely/version.rb +1 -1
- data/lib/spritely.rb +0 -6
- data/spec/fixtures/correct-sprite.png +0 -0
- data/spec/fixtures/rails-app/app/assets/stylesheets/sprites.css.scss +12 -7
- data/spec/fixtures/test/foo.png +0 -0
- data/spec/integration/stylesheet_spec.rb +2 -2
- data/spec/spritely/cache_spec.rb +22 -0
- data/spec/spritely/collection_spec.rb +6 -6
- data/spec/spritely/generators/chunky_png_spec.rb +2 -1
- data/spec/spritely/image_set_spec.rb +3 -1
- data/spec/spritely/options_spec.rb +15 -4
- data/spec/spritely/sass_functions_spec.rb +82 -0
- data/spec/spritely/sprite_map_spec.rb +15 -8
- data/spec/spritely_spec.rb +0 -8
- data/spec/support/rails_app_helpers.rb +11 -1
- data/spec/support/shared_examples.rb +1 -1
- metadata +8 -5
- data/spec/integration/application.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8713d85420999dd80091c7851846907da9bf01d7
|
4
|
+
data.tar.gz: 255c099a89c000d9102a68791695ccdab45b5b52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec919488acf8b9c8718f3309031eed246f063b35848aa6695c2b08b4b7c83645fbdaaf0f4151574335c23da137c82643724aa479db994bba35a9e88edf1279e4
|
7
|
+
data.tar.gz: ceecec6dd9287f29c9dd9847deec20c6c625ce39532069f560c2b5b84199871e22e764e0d2a79dac745ae08293b6a585c8860f5d57bcb74c8ec8bc089a3ae12c
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Spritely
|
4
|
+
class Cache < Struct.new(:filename)
|
5
|
+
PNG_SIGNATURE_LENGTH = 8 # http://www.w3.org/TR/PNG/#5PNG-file-signature
|
6
|
+
PNG_INFO_LENGTH = 8 # http://www.w3.org/TR/PNG/#5DataRep
|
7
|
+
PNG_CRC_LENGTH = 4 # Cyclic Redundancy Check (CRC) byte-length; http://www.w3.org/TR/PNG/#5Chunk-layout
|
8
|
+
|
9
|
+
def self.generate(*objects)
|
10
|
+
Digest::MD5.hexdigest(objects.collect(&:cache_key).join)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.busted?(filename, expected_cache_key)
|
14
|
+
new(filename).key != expected_cache_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def key
|
18
|
+
return @key if @key
|
19
|
+
|
20
|
+
File.open(filename) do |file|
|
21
|
+
file.read(PNG_SIGNATURE_LENGTH) # we first have to read the signature to fast-forward the IO#pos
|
22
|
+
until file.eof?
|
23
|
+
each_chunk(file) do |keyword, value|
|
24
|
+
if keyword == 'cache_key'
|
25
|
+
return @key = value
|
26
|
+
break
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def each_chunk(file, &block)
|
36
|
+
length = file.read(PNG_INFO_LENGTH).unpack('Na4').first
|
37
|
+
yield *file.read(length).unpack('Z*a*')
|
38
|
+
file.read(PNG_CRC_LENGTH)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/spritely/collection.rb
CHANGED
@@ -16,8 +16,8 @@ module Spritely
|
|
16
16
|
image_sets.find { |image_set| image_set.name == name }
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
files.collect { |file|
|
19
|
+
def cache_key
|
20
|
+
files.collect { |file| File.mtime(file) }.join
|
21
21
|
end
|
22
22
|
|
23
23
|
def width
|
@@ -40,7 +40,7 @@ module Spritely
|
|
40
40
|
|
41
41
|
def position!
|
42
42
|
image_sets.each_with_index do |image_set, index|
|
43
|
-
image_set.top = heights[0..index].reduce(:+) - image_set.
|
43
|
+
image_set.top = heights[0..index].reduce(:+) - image_set.outer_height
|
44
44
|
image_set.position_in!(width)
|
45
45
|
end
|
46
46
|
end
|
@@ -52,7 +52,7 @@ module Spritely
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def heights
|
55
|
-
image_sets.collect(&:
|
55
|
+
image_sets.collect(&:outer_height)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
data/lib/spritely/image_set.rb
CHANGED
data/lib/spritely/options.rb
CHANGED
@@ -1,19 +1,41 @@
|
|
1
1
|
require 'active_support/core_ext/hash/deep_merge'
|
2
|
+
require 'active_support/core_ext/hash/except'
|
3
|
+
require 'active_support/core_ext/hash/slice'
|
2
4
|
|
3
5
|
module Spritely
|
4
|
-
class Options
|
5
|
-
|
6
|
+
class Options < Struct.new(:hash)
|
7
|
+
GLOBAL_OPTIONS = [:spacing]
|
6
8
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def cache_key
|
10
|
+
stripped_hash.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def inspect
|
14
|
+
"#<Spritely::Options global_options=#{global_options} options=#{options}>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
options[key] || global_options
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def options
|
24
|
+
@options ||= stripped_hash.except(*GLOBAL_OPTIONS).inject({}) do |h, (key, value)|
|
25
|
+
split_key = key.to_s.split('_')
|
26
|
+
option = global_options.merge(split_key.pop.to_sym => value)
|
11
27
|
h.deep_merge!(split_key.join('-') => option)
|
12
28
|
end
|
13
29
|
end
|
14
30
|
|
15
|
-
def
|
16
|
-
|
31
|
+
def global_options
|
32
|
+
@global_options ||= stripped_hash.slice(*GLOBAL_OPTIONS)
|
33
|
+
end
|
34
|
+
|
35
|
+
def stripped_hash
|
36
|
+
@stripped_hash ||= hash.inject({}) do |h, (key, sass_object)|
|
37
|
+
h.merge!(key.to_sym => sass_object.value)
|
38
|
+
end
|
17
39
|
end
|
18
40
|
end
|
19
41
|
end
|
@@ -2,20 +2,20 @@ require 'spritely/sprite_map'
|
|
2
2
|
|
3
3
|
module Spritely
|
4
4
|
module SassFunctions
|
5
|
-
def
|
6
|
-
SpriteMap.create(glob, kwargs)
|
5
|
+
def spritely_map(glob, kwargs = {})
|
6
|
+
SpriteMap.create(glob.value, kwargs)
|
7
7
|
end
|
8
8
|
|
9
|
-
::Sass::Script::Functions.declare :
|
9
|
+
::Sass::Script::Functions.declare :spritely_map, [:glob], var_kwargs: true
|
10
10
|
|
11
|
-
def
|
11
|
+
def spritely_url(sprite_map)
|
12
12
|
asset_url(Sass::Script::String.new("sprites/#{sprite_map.name}.png"))
|
13
13
|
end
|
14
14
|
|
15
|
-
::Sass::Script::Functions.declare :
|
15
|
+
::Sass::Script::Functions.declare :spritely_url, [:sprite_map]
|
16
16
|
|
17
|
-
def
|
18
|
-
image = sprite_map
|
17
|
+
def spritely_position(sprite_map, image_name)
|
18
|
+
image = find_image(sprite_map, image_name)
|
19
19
|
|
20
20
|
x = Sass::Script::Number.new(image.left, image.left == 0 ? [] : ['px'])
|
21
21
|
y = Sass::Script::Number.new(-image.top, image.top == 0 ? [] : ['px'])
|
@@ -23,23 +23,29 @@ module Spritely
|
|
23
23
|
Sass::Script::List.new([x, y], :space)
|
24
24
|
end
|
25
25
|
|
26
|
-
::Sass::Script::Functions.declare :
|
26
|
+
::Sass::Script::Functions.declare :spritely_position, [:sprite_map, :image_name]
|
27
27
|
|
28
|
-
def
|
29
|
-
image = sprite_map
|
28
|
+
def spritely_width(sprite_map, image_name)
|
29
|
+
image = find_image(sprite_map, image_name)
|
30
30
|
|
31
31
|
Sass::Script::Number.new(image.width, ['px'])
|
32
32
|
end
|
33
33
|
|
34
|
-
::Sass::Script::Functions.declare :
|
34
|
+
::Sass::Script::Functions.declare :spritely_width, [:sprite_map, :image_name]
|
35
35
|
|
36
|
-
def
|
37
|
-
image = sprite_map
|
36
|
+
def spritely_height(sprite_map, image_name)
|
37
|
+
image = find_image(sprite_map, image_name)
|
38
38
|
|
39
39
|
Sass::Script::Number.new(image.height, ['px'])
|
40
40
|
end
|
41
41
|
|
42
|
-
::Sass::Script::Functions.declare :
|
42
|
+
::Sass::Script::Functions.declare :spritely_height, [:sprite_map, :image_name]
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def find_image(sprite_map, image_name)
|
47
|
+
sprite_map.find(image_name.value) || raise(Sass::SyntaxError, "No image '#{image_name.value}' found in sprite map '#{sprite_map.name}'.")
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
data/lib/spritely/sprite_map.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
require 'spritely/options'
|
3
|
+
require 'spritely/cache'
|
2
4
|
require 'spritely/collection'
|
3
5
|
require 'spritely/generators/chunky_png'
|
4
6
|
|
@@ -17,12 +19,16 @@ module Spritely
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def initialize(glob, options = {})
|
20
|
-
@glob = glob
|
22
|
+
@glob = glob
|
21
23
|
@options = Options.new(options)
|
22
24
|
end
|
23
25
|
|
26
|
+
def cache_key
|
27
|
+
@cache_key ||= Cache.generate(options, collection)
|
28
|
+
end
|
29
|
+
|
24
30
|
def inspect
|
25
|
-
"#<Spritely::SpriteMap name=#{name}
|
31
|
+
"#<Spritely::SpriteMap name=#{name} options=#{options}>"
|
26
32
|
end
|
27
33
|
|
28
34
|
def collection
|
@@ -42,7 +48,7 @@ module Spritely
|
|
42
48
|
end
|
43
49
|
|
44
50
|
def needs_generation?
|
45
|
-
!File.exist?(filename) ||
|
51
|
+
!File.exist?(filename) || Cache.busted?(filename, cache_key)
|
46
52
|
end
|
47
53
|
|
48
54
|
private
|
@@ -50,9 +56,5 @@ module Spritely
|
|
50
56
|
def files
|
51
57
|
Spritely.environment.paths.flat_map { |path| Dir.glob(File.join(path, glob)) }
|
52
58
|
end
|
53
|
-
|
54
|
-
def outdated?
|
55
|
-
collection.last_modification_time > Spritely.modification_time(filename)
|
56
|
-
end
|
57
59
|
end
|
58
60
|
end
|
data/lib/spritely/version.rb
CHANGED
data/lib/spritely.rb
CHANGED
@@ -2,8 +2,6 @@ require 'sass'
|
|
2
2
|
require 'spritely/sass_functions'
|
3
3
|
require 'spritely/sprockets/manifest'
|
4
4
|
|
5
|
-
raise LoadError, "Spritely cannot be used in conjunction with Compass. Hope you choose Spritely!" if defined?(::Compass)
|
6
|
-
|
7
5
|
module Spritely
|
8
6
|
def self.environment
|
9
7
|
::Rails.application.assets
|
@@ -12,8 +10,4 @@ module Spritely
|
|
12
10
|
def self.directory
|
13
11
|
::Rails.root.join('app', 'assets', 'images', 'sprites')
|
14
12
|
end
|
15
|
-
|
16
|
-
def self.modification_time(filename)
|
17
|
-
File.mtime(filename).to_i
|
18
|
-
end
|
19
13
|
end
|
Binary file
|
@@ -1,13 +1,18 @@
|
|
1
|
-
$application-sprite:
|
1
|
+
$application-sprite: spritely-map("application/*.png",
|
2
|
+
$background-repeat: true,
|
3
|
+
$football-spacing: 100px,
|
4
|
+
$mario-spacing: 10px,
|
5
|
+
$spacing: 5px
|
6
|
+
);
|
2
7
|
|
3
8
|
body {
|
4
|
-
background-image:
|
5
|
-
background-position:
|
9
|
+
background-image: spritely-url($application-sprite);
|
10
|
+
background-position: spritely-position($application-sprite, "background");
|
6
11
|
}
|
7
12
|
|
8
13
|
#mario {
|
9
|
-
background-image:
|
10
|
-
background-position:
|
11
|
-
width:
|
12
|
-
height:
|
14
|
+
background-image: spritely-url($application-sprite);
|
15
|
+
background-position: spritely-position($application-sprite, "mario");
|
16
|
+
width: spritely-width($application-sprite, "mario");
|
17
|
+
height: spritely-height($application-sprite, "mario");
|
13
18
|
}
|
data/spec/fixtures/test/foo.png
CHANGED
Binary file
|
@@ -8,7 +8,7 @@ describe 'Stylesheet generation', :integration do
|
|
8
8
|
it { should include(<<-CSS.strip_heredoc
|
9
9
|
body {
|
10
10
|
background-image: url(/assets/sprites/application.png);
|
11
|
-
background-position: 0 -
|
11
|
+
background-position: 0 -952px;
|
12
12
|
}
|
13
13
|
CSS
|
14
14
|
) }
|
@@ -18,7 +18,7 @@ describe 'Stylesheet generation', :integration do
|
|
18
18
|
it { should include(<<-CSS.strip_heredoc
|
19
19
|
#mario {
|
20
20
|
background-image: url(/assets/sprites/application.png);
|
21
|
-
background-position: 0 -
|
21
|
+
background-position: 0 -728px;
|
22
22
|
width: 200px;
|
23
23
|
height: 214px;
|
24
24
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spritely::Cache do
|
4
|
+
let(:filename) { File.join(__dir__, '..', 'fixtures', 'test', 'foo.png') }
|
5
|
+
|
6
|
+
subject { Spritely::Cache.new(filename) }
|
7
|
+
|
8
|
+
its(:filename) { should eq(filename) }
|
9
|
+
its(:key) { should eq('527272411fe99a8b5e9da254ac0aae88') }
|
10
|
+
|
11
|
+
describe '.generate' do
|
12
|
+
it 'should collect the cache_key values and digest them' do
|
13
|
+
expect(Spritely::Cache.generate(double(cache_key: 'asdf'), double(cache_key: 'hjkl'))).to eq('527272411fe99a8b5e9da254ac0aae88')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.busted?' do
|
18
|
+
it 'should check the expected value against the real value' do
|
19
|
+
expect(Spritely::Cache).to be_busted(filename, 'asdf')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Spritely::Collection do
|
4
|
-
let(:first_set) { double(repeated?: true, name: 'foo', width: 1,
|
5
|
-
let(:second_set) { double(repeated?: false, name: 'bar', width: 100,
|
4
|
+
let(:first_set) { double(repeated?: true, name: 'foo', width: 1, outer_height: 10, images: [1]) }
|
5
|
+
let(:second_set) { double(repeated?: false, name: 'bar', width: 100, outer_height: 100, images: [2, 3]) }
|
6
6
|
|
7
7
|
subject { Spritely::Collection.new(['file-1.png', 'file-2.png'], {'file-1' => {repeat: true}}) }
|
8
8
|
|
@@ -70,13 +70,13 @@ describe Spritely::Collection do
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
describe '#
|
73
|
+
describe '#cache_key' do
|
74
74
|
before do
|
75
|
-
allow(
|
76
|
-
allow(
|
75
|
+
allow(File).to receive(:mtime).with('file-1.png').and_return(10)
|
76
|
+
allow(File).to receive(:mtime).with('file-2.png').and_return(100)
|
77
77
|
end
|
78
78
|
|
79
|
-
its(:
|
79
|
+
its(:cache_key) { should eq('10100') }
|
80
80
|
end
|
81
81
|
|
82
82
|
describe '#position!' do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Spritely::Generators::ChunkyPng do
|
4
|
-
let(:png_canvas) { double }
|
4
|
+
let(:png_canvas) { double(metadata: {}) }
|
5
5
|
|
6
6
|
subject { Spritely::Generators::ChunkyPng.new(sprite_map) }
|
7
7
|
|
@@ -26,6 +26,7 @@ describe Spritely::Generators::ChunkyPng do
|
|
26
26
|
it 'should save the PNG canvas' do
|
27
27
|
expect(png_canvas).to receive(:save).with('blah.png', :fast_rgba)
|
28
28
|
subject.save!
|
29
|
+
expect(png_canvas.metadata).to include('cache_key' => 'cachevalue')
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -3,7 +3,7 @@ require 'ostruct'
|
|
3
3
|
|
4
4
|
describe Spritely::ImageSet do
|
5
5
|
let(:path) { "#{__dir__}/../fixtures/test/foo.png" }
|
6
|
-
let(:options) { {repeat: true} }
|
6
|
+
let(:options) { {repeat: true, spacing: 10} }
|
7
7
|
|
8
8
|
subject { Spritely::ImageSet.new(path, options) }
|
9
9
|
|
@@ -14,6 +14,8 @@ describe Spritely::ImageSet do
|
|
14
14
|
its(:height) { should eq(1) }
|
15
15
|
its(:name) { should eq('foo') }
|
16
16
|
its(:left) { should eq(0) }
|
17
|
+
its(:spacing) { should eq(10) }
|
18
|
+
its(:outer_height) { should eq(11) }
|
17
19
|
|
18
20
|
describe '#top' do
|
19
21
|
before { subject.top = 123 }
|
@@ -1,16 +1,27 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Spritely::Options do
|
4
|
-
let(:hash) { {
|
4
|
+
let(:hash) { {
|
5
|
+
'some_new_image_x' => Sass::Script::Number.new(123),
|
6
|
+
'some_new_image_y' => Sass::Script::Number.new(456),
|
7
|
+
'some_new_image_spacing' => Sass::Script::Number.new(789),
|
8
|
+
'another_image_repeat' => Sass::Script::Bool.new(true),
|
9
|
+
'yet_another_image_repeat' => Sass::Script::Bool.new(false),
|
10
|
+
'spacing' => Sass::Script::Number.new(901)
|
11
|
+
} }
|
5
12
|
|
6
13
|
subject(:options) { Spritely::Options.new(hash) }
|
7
14
|
|
8
|
-
its(
|
9
|
-
its(
|
15
|
+
its(:inspect) { should eq("#<Spritely::Options global_options=#{{spacing: 901}} options=#{{'some-new-image' => {spacing: 789, x: 123, y: 456}, 'another-image' => {spacing: 901, repeat: true}, 'yet-another-image' => {spacing: 901, repeat: false}}}>") }
|
16
|
+
its(:cache_key) { should eq({some_new_image_x: 123, some_new_image_y: 456, some_new_image_spacing: 789, another_image_repeat: true, yet_another_image_repeat: false, spacing: 901}.to_s) }
|
17
|
+
|
18
|
+
its(['some-new-image']) { should eq({spacing: 789, x: 123, y: 456}) }
|
19
|
+
its(['another-image']) { should eq({spacing: 901, repeat: true}) }
|
20
|
+
its(['yet-another-image']) { should eq({spacing: 901, repeat: false}) }
|
10
21
|
|
11
22
|
describe '#[]' do
|
12
23
|
it 'should fall back to an empty hash' do
|
13
|
-
expect(options[:unknown]).to eq({})
|
24
|
+
expect(options[:unknown]).to eq({spacing: 901})
|
14
25
|
end
|
15
26
|
end
|
16
27
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spritely::SassFunctions do
|
4
|
+
class SpriteMapDouble < Sass::Script::Literal
|
5
|
+
def name; 'test'; end
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:sprite_map) { SpriteMapDouble.new }
|
9
|
+
|
10
|
+
before { allow(Spritely::SpriteMap).to receive(:create).and_return(sprite_map) }
|
11
|
+
|
12
|
+
shared_examples "a sprite function that checks image existence" do
|
13
|
+
before { allow(sprite_map).to receive(:find).with('bar').and_return(image) }
|
14
|
+
|
15
|
+
context 'the image does not exist' do
|
16
|
+
let(:image) { nil }
|
17
|
+
|
18
|
+
it 'should raise a nice exception' do
|
19
|
+
expect { subject }.to raise_error(Sass::SyntaxError, "No image 'bar' found in sprite map 'test'.")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#spritely_url' do
|
25
|
+
before do
|
26
|
+
asset_url_module = Module.new do
|
27
|
+
def asset_url(path)
|
28
|
+
path
|
29
|
+
end
|
30
|
+
end
|
31
|
+
::Sass::Script::Functions.send(:include, asset_url_module)
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
::Sass::Script::Functions.send(:undef_method, :asset_url)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should use Rails' built-in asset_url function" do
|
39
|
+
expect(evaluate("spritely-url(spritely-map('test/*.png'))")).to eq('sprites/test.png')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#spritely_position' do
|
44
|
+
let(:image) { double(left: 0, top: 12) }
|
45
|
+
|
46
|
+
subject { evaluate("spritely-position(spritely-map('test/*.png'), 'bar')") }
|
47
|
+
|
48
|
+
include_examples "a sprite function that checks image existence"
|
49
|
+
|
50
|
+
it { should eq('0 -12px') }
|
51
|
+
|
52
|
+
context 'the left is not 0' do
|
53
|
+
let(:image) { double(left: 10, top: 12) }
|
54
|
+
|
55
|
+
it { should eq('10px -12px') }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#spritely_width' do
|
60
|
+
let(:image) { double(width: 25) }
|
61
|
+
|
62
|
+
subject { evaluate("spritely-width(spritely-map('test/*.png'), 'bar')") }
|
63
|
+
|
64
|
+
include_examples "a sprite function that checks image existence"
|
65
|
+
|
66
|
+
it { should eq('25px') }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#spritely_height' do
|
70
|
+
let(:image) { double(height: 50) }
|
71
|
+
|
72
|
+
subject { evaluate("spritely-height(spritely-map('test/*.png'), 'bar')") }
|
73
|
+
|
74
|
+
include_examples "a sprite function that checks image existence"
|
75
|
+
|
76
|
+
it { should eq('50px') }
|
77
|
+
end
|
78
|
+
|
79
|
+
def evaluate(value)
|
80
|
+
Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s
|
81
|
+
end
|
82
|
+
end
|
@@ -1,22 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Spritely::SpriteMap do
|
4
|
-
let(:
|
4
|
+
let(:options_hash) { {'some_new_image_x' => 123, 'some_new_image_y' => 456, 'another_image_repeat' => true} }
|
5
|
+
let(:options_object) { double(options: 'options', cache_key: 'options') }
|
5
6
|
|
6
|
-
subject { Spritely::SpriteMap.new(
|
7
|
+
subject { Spritely::SpriteMap.new('test/*.png', options_hash) }
|
7
8
|
|
8
9
|
before do
|
9
10
|
Spritely.stub(:directory).and_return(File)
|
10
|
-
allow(Spritely::Options).to receive(:new).with(
|
11
|
+
allow(Spritely::Options).to receive(:new).with(options_hash).and_return(options_object)
|
11
12
|
end
|
12
13
|
|
13
14
|
it { should be_a(Sass::Script::Literal) }
|
14
15
|
|
15
16
|
its(:glob) { should eq('test/*.png') }
|
16
|
-
its(:options) { should eq(
|
17
|
+
its(:options) { should eq(options_object) }
|
17
18
|
its(:name) { should eq('test') }
|
18
19
|
its(:filename) { should eq('test.png') }
|
19
|
-
its(:inspect) { should eq(
|
20
|
+
its(:inspect) { should eq("#<Spritely::SpriteMap name=test options=#{options_object}>") }
|
20
21
|
|
21
22
|
describe '.create' do
|
22
23
|
let(:sprite_map) { double(needs_generation?: true) }
|
@@ -28,12 +29,18 @@ describe Spritely::SpriteMap do
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
describe '#cache_key' do
|
33
|
+
before { allow(subject).to receive(:collection).and_return(double(cache_key: 'collection value')) }
|
34
|
+
|
35
|
+
its(:cache_key) { should eq('dfc047d12e4c6404e9dae98bc2851e5c') }
|
36
|
+
end
|
37
|
+
|
31
38
|
describe '#collection' do
|
32
39
|
let(:collection) { double(find: 'find value', width: 'width value', height: 'height value', images: 'images value') }
|
33
40
|
|
34
41
|
before do
|
35
42
|
Spritely.stub_chain(:environment, :paths).and_return(["#{__dir__}/../fixtures"])
|
36
|
-
allow(Spritely::Collection).to receive(:create).with(["#{__dir__}/../fixtures/test/foo.png"],
|
43
|
+
allow(Spritely::Collection).to receive(:create).with(["#{__dir__}/../fixtures/test/foo.png"], options_object).and_return(collection)
|
37
44
|
end
|
38
45
|
|
39
46
|
its(:collection) { should eq(collection) }
|
@@ -64,8 +71,8 @@ describe Spritely::SpriteMap do
|
|
64
71
|
let(:file_exists) { true }
|
65
72
|
|
66
73
|
before do
|
67
|
-
subject.
|
68
|
-
allow(Spritely).to receive(:
|
74
|
+
allow(subject).to receive(:cache_key).and_return('value')
|
75
|
+
allow(Spritely::Cache).to receive(:busted?).with('test.png', 'value').and_return(true)
|
69
76
|
end
|
70
77
|
|
71
78
|
its(:needs_generation?) { should be_true }
|
data/spec/spritely_spec.rb
CHANGED
@@ -12,12 +12,4 @@ describe Spritely do
|
|
12
12
|
|
13
13
|
its(:directory) { should eq('app/assets/images/sprites') }
|
14
14
|
end
|
15
|
-
|
16
|
-
describe '.modification_time' do
|
17
|
-
before { allow(File).to receive(:mtime).with('foo').and_return('123') }
|
18
|
-
|
19
|
-
it 'should give us the modification time' do
|
20
|
-
expect(Spritely.modification_time('foo')).to eq(123)
|
21
|
-
end
|
22
|
-
end
|
23
15
|
end
|
@@ -1,8 +1,18 @@
|
|
1
1
|
module RailsAppHelpers
|
2
|
+
GENERATOR_FLAGS = [
|
3
|
+
'--skip-active-record',
|
4
|
+
'--skip-test-unit',
|
5
|
+
'--skip-javascript',
|
6
|
+
'--skip-spring',
|
7
|
+
'--skip-git'
|
8
|
+
]
|
9
|
+
|
2
10
|
def within_rails_app(&block)
|
3
11
|
Dir.mktmpdir do |tmpdir|
|
4
12
|
Dir.chdir(tmpdir) do
|
5
|
-
|
13
|
+
flags = GENERATOR_FLAGS
|
14
|
+
flags << '--edge' if ENV['BUNDLE_GEMFILE'] =~ /rails_edge\.gemfile$/
|
15
|
+
%x(rails new dummy #{flags.join(' ')})
|
6
16
|
Dir.chdir('dummy') do
|
7
17
|
Bundler.with_clean_env do
|
8
18
|
File.open('Gemfile', 'a') do |f|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
shared_examples "a generator" do
|
2
2
|
let(:images) { [OpenStruct.new(data: 'first image data', left: 1, top: 10), OpenStruct.new(data: 'second image data', left: 2, top: 20)] }
|
3
|
-
let(:sprite_map) { double(images: images, width: 100, height: 200, filename: 'blah.png') }
|
3
|
+
let(:sprite_map) { double(images: images, width: 100, height: 200, filename: 'blah.png', cache_key: 'cachevalue') }
|
4
4
|
|
5
5
|
its(:sprite_map) { should eq(sprite_map) }
|
6
6
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spritely
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Robbin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chunky_png
|
@@ -136,6 +136,7 @@ extensions: []
|
|
136
136
|
extra_rdoc_files: []
|
137
137
|
files:
|
138
138
|
- lib/spritely.rb
|
139
|
+
- lib/spritely/cache.rb
|
139
140
|
- lib/spritely/collection.rb
|
140
141
|
- lib/spritely/generators/base.rb
|
141
142
|
- lib/spritely/generators/chunky_png.rb
|
@@ -153,20 +154,21 @@ files:
|
|
153
154
|
- spec/fixtures/rails-app/app/assets/images/application/mario.png
|
154
155
|
- spec/fixtures/rails-app/app/assets/stylesheets/sprites.css.scss
|
155
156
|
- spec/fixtures/test/foo.png
|
156
|
-
- spec/integration/application.png
|
157
157
|
- spec/integration/precompilation_spec.rb
|
158
158
|
- spec/integration/stylesheet_spec.rb
|
159
159
|
- spec/spec_helper.rb
|
160
|
+
- spec/spritely/cache_spec.rb
|
160
161
|
- spec/spritely/collection_spec.rb
|
161
162
|
- spec/spritely/generators/chunky_png_spec.rb
|
162
163
|
- spec/spritely/image_set_spec.rb
|
163
164
|
- spec/spritely/image_spec.rb
|
164
165
|
- spec/spritely/options_spec.rb
|
166
|
+
- spec/spritely/sass_functions_spec.rb
|
165
167
|
- spec/spritely/sprite_map_spec.rb
|
166
168
|
- spec/spritely_spec.rb
|
167
169
|
- spec/support/rails_app_helpers.rb
|
168
170
|
- spec/support/shared_examples.rb
|
169
|
-
homepage:
|
171
|
+
homepage: https://github.com/agrobbin/spritely
|
170
172
|
licenses:
|
171
173
|
- MIT
|
172
174
|
metadata: {}
|
@@ -199,15 +201,16 @@ test_files:
|
|
199
201
|
- spec/fixtures/rails-app/app/assets/images/application/mario.png
|
200
202
|
- spec/fixtures/rails-app/app/assets/stylesheets/sprites.css.scss
|
201
203
|
- spec/fixtures/test/foo.png
|
202
|
-
- spec/integration/application.png
|
203
204
|
- spec/integration/precompilation_spec.rb
|
204
205
|
- spec/integration/stylesheet_spec.rb
|
205
206
|
- spec/spec_helper.rb
|
207
|
+
- spec/spritely/cache_spec.rb
|
206
208
|
- spec/spritely/collection_spec.rb
|
207
209
|
- spec/spritely/generators/chunky_png_spec.rb
|
208
210
|
- spec/spritely/image_set_spec.rb
|
209
211
|
- spec/spritely/image_spec.rb
|
210
212
|
- spec/spritely/options_spec.rb
|
213
|
+
- spec/spritely/sass_functions_spec.rb
|
211
214
|
- spec/spritely/sprite_map_spec.rb
|
212
215
|
- spec/spritely_spec.rb
|
213
216
|
- spec/support/rails_app_helpers.rb
|
Binary file
|