antw-kin 0.3.2 → 0.3.3

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.
@@ -0,0 +1,34 @@
1
+ namespace :kin do
2
+
3
+ desc "Regenerates the sprite images. Any sprites which haven't been " \
4
+ "changed won't be regenerated."
5
+
6
+ task 'sprites' do
7
+ generate_sprites!(false)
8
+ end
9
+
10
+ desc "Regenerates the sprite images, even those which have not been " \
11
+ "changed."
12
+
13
+ task 'sprites:force' do
14
+ generate_sprites!(true)
15
+ end
16
+
17
+ ##
18
+ # Generates the sprites for the current Merb application.
19
+ #
20
+ # @param [Boolean] force
21
+ # Defines whether to regenerate sprites which haven't been changed.
22
+ #
23
+ def generate_sprites!(force)
24
+ require 'kin/sprites'
25
+ require 'kin/sprites/rake_runner'
26
+
27
+ Kin::Sprites::RakeRunner.new(
28
+ File.join(Merb.dir_for(:config), 'sprites.yml'),
29
+ File.join(Merb.dir_for(:image), 'sprites'),
30
+ File.join(Merb.dir_for(:stylesheet), 'sass', '_sprites.sass')
31
+ ).generate!(force)
32
+ end
33
+
34
+ end
@@ -0,0 +1,9 @@
1
+ :ruby
2
+ Kin::Nav.setup(:test, Kin::Nav::Formatters::HasRight(:right_one, :right_two)) do |nav|
3
+ # Items with titles.
4
+ nav.add(:left, 'Left')
5
+ nav.add(:right_one, 'Right one')
6
+ nav.add(:right_two, 'Right one')
7
+ end
8
+
9
+ = display_navigation(:test)
@@ -0,0 +1,7 @@
1
+ :ruby
2
+ Kin::Nav.setup(:test, Kin::Nav::Formatters::Subnav) do |nav|
3
+ nav.add(:one, 'One')
4
+ nav.add(:two, 'Two')
5
+ end
6
+
7
+ = display_navigation(:test)
@@ -0,0 +1,11 @@
1
+ ---
2
+ # Used in the RakeRunner specs to test
3
+ # a sprite definition being changed.
4
+
5
+ general:
6
+ - one
7
+ - three
8
+
9
+ more:
10
+ - two
11
+ - three
@@ -0,0 +1,9 @@
1
+ ---
2
+ general:
3
+ - one
4
+ - two
5
+ - three
6
+
7
+ more:
8
+ - two
9
+ - three
@@ -1,52 +1,10 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
2
 
3
- # Masthead::Builder Specs ======================================================
4
-
5
- describe 'masthead builder setter', :shared => true do
6
- it 'should set the attribute if a value is given' do
7
- @builder.send(@method, 'my_value').should == 'my_value'
8
- end
9
-
10
- it 'should not change the attribute value if nil is given' do
11
- @builder.send(@method, 'my_value')
12
- @builder.send(@method).should == 'my_value'
13
- @builder.send(@method, nil).should == 'my_value'
14
- end
15
-
16
- it 'should set the extra options' do
17
- @builder.send(@method, 'my_value', { :link => '/' })
18
- @builder.options[@method].should == { :link => '/' }
19
- end
20
- end
21
-
22
3
  describe Kin::Masthead::Builder do
23
4
  before(:each) do
24
5
  @builder = Kin::Masthead::Builder.new
25
6
  end
26
7
 
27
- # -------
28
- # Setters
29
-
30
- describe '#title' do
31
- before(:each) { @method = :title }
32
- it_should_behave_like 'masthead builder setter'
33
- end
34
-
35
- describe '#subtitle' do
36
- before(:each) { @method = :subtitle }
37
- it_should_behave_like 'masthead builder setter'
38
- end
39
-
40
- describe '#right_title' do
41
- before(:each) { @method = :right_title }
42
- it_should_behave_like 'masthead builder setter'
43
- end
44
-
45
- describe '#right_subtitle' do
46
- before(:each) { @method = :right_subtitle }
47
- it_should_behave_like 'masthead builder setter'
48
- end
49
-
50
8
  # -----
51
9
  # build
52
10
 
@@ -98,7 +56,7 @@ describe Kin::Masthead::Builder do
98
56
  it 'should render an empty right title when no right title is set, but ' +
99
57
  'a right subtitle is set' do
100
58
  @c.render(:right_subtitle).should have_selector('.extra .main') do |main|
101
- main.to_s.should =~ / /
59
+ main.to_xhtml.should include(' ') # Unicode non-breaking space.
102
60
  end
103
61
  end
104
62
 
@@ -130,16 +88,6 @@ describe Kin::Masthead::Builder do
130
88
  @c.render(:right_subtitle).should have_selector('.extra .subtitle')
131
89
  end
132
90
 
133
- # Border.
134
-
135
- it 'should not have a "no_border" class by default' do
136
- @c.render(:border).should_not have_selector('.no_border')
137
- end
138
-
139
- it 'should have a "no_border" class when no_border = true' do
140
- @c.render(:no_border).should have_selector('.no_border')
141
- end
142
-
143
91
  # Links.
144
92
 
145
93
  it 'should add links to fields when a :link option is present' do
@@ -202,27 +150,3 @@ describe Kin::Masthead::Builder do
202
150
  end
203
151
 
204
152
  end
205
-
206
- # Masthead::Helper Specs =====================================================
207
-
208
- describe 'Masthead helper mixin' do
209
- include Kin::Masthead::Helper
210
-
211
- describe '#masthead' do
212
- it 'should pass along the :no_border option' do
213
- masthead(:no_border => true) { |_| }
214
- masthead_builder.no_border.should be_true
215
- end
216
-
217
- it 'should pass the block along to #build' do
218
- masthead { |m| m.title('Title') }
219
- masthead_builder.title.should == 'Title'
220
- end
221
- end
222
-
223
- describe '#masthead_builder' do
224
- it 'should return the same instance each time' do
225
- masthead_builder.object_id.should == masthead_builder.object_id
226
- end
227
- end
228
- end
data/spec/nav_spec.rb CHANGED
@@ -145,6 +145,38 @@ describe Kin::Nav do
145
145
  end
146
146
  end
147
147
 
148
+ # ------------------
149
+ # HasRight formatter
150
+
151
+ describe 'with the HasRight formatter' do
152
+ before(:each) do
153
+ @html = @c.render(:has_right_formatter)
154
+ end
155
+
156
+ it 'should apply a custom style the right-aligned items' do
157
+ %w( right_one right_two ).each do |name|
158
+ @html.should have_selector("#nav_#{name} span.right_border")
159
+ end
160
+ end
161
+
162
+ it 'should use the default style for items not right-aligned' do
163
+ @html.should_not have_selector('#nav_left span.right_border')
164
+ end
165
+ end
166
+
167
+ # ----------------
168
+ # Subnav formatter
169
+
170
+ describe 'with the Subnav formatter' do
171
+ it 'should apply a custom style to all items' do
172
+ html = @c.render(:subnav_formatter)
173
+
174
+ %w( one two ).each do |name|
175
+ html.should have_selector("#nav_#{name} span.pill")
176
+ end
177
+ end
178
+ end
179
+
148
180
  # ------
149
181
  # titles
150
182
 
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,37 @@ Spec::Runner.configure do |config|
19
19
  config.include(Merb::Test::ViewHelper)
20
20
  config.include(Merb::Test::RouteHelper)
21
21
  config.include(Merb::Test::ControllerHelper)
22
+ config.include(Module.new do
23
+ ##
24
+ # Returns a path to the fixture directory. Any additional string
25
+ # parameters will be joined with the path.
26
+ #
27
+ def fixture_path(*dirs)
28
+ File.join(File.dirname(__FILE__), 'fixture', *dirs)
29
+ end
30
+
31
+ ##
32
+ # Returns a path to the tmp/spec folder. Any additional string
33
+ # parameters will be joined with the path.
34
+ #
35
+ def tmp_path(*dirs)
36
+ File.join(File.dirname(__FILE__), '..', 'tmp', 'spec', *dirs)
37
+ end
38
+
39
+ ##
40
+ # Does exactly what it says on the tin.
41
+ #
42
+ def capture_stdout
43
+ orig, $stdout = $stdout, StringIO.new
44
+
45
+ begin
46
+ yield
47
+ return $stdout.string
48
+ ensure
49
+ $stdout = orig
50
+ end
51
+ end
52
+ end)
22
53
  end
23
54
 
24
55
  ##
@@ -0,0 +1,349 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ sprites = File.join(File.dirname(__FILE__), '..', 'lib', 'kin', 'sprites')
4
+
5
+ require sprites
6
+ require File.join(sprites, 'rake_runner')
7
+
8
+ # IconSet ====================================================================
9
+
10
+ describe Kin::Sprites::IconSet do
11
+ it 'should include Enumerable' do
12
+ Kin::Sprites::IconSet.ancestors.should include(Enumerable)
13
+ end
14
+
15
+ describe '#each' do
16
+ it 'should yield each icon in turn' do
17
+ icons, yielded = %w(one two), []
18
+
19
+ Kin::Sprites::IconSet.new(icons).each do |icon|
20
+ yielded << icon
21
+ end
22
+
23
+ yielded.should == icons
24
+ end
25
+ end
26
+
27
+ describe '#location_of' do
28
+ before(:each) do
29
+ @set = Kin::Sprites::IconSet.new(%w(one two))
30
+ end
31
+
32
+ it 'should return 0 if the given icon is first' do
33
+ @set.location_of('one').should == 0
34
+ end
35
+
36
+ it 'should return 40 if the given icon is second' do
37
+ @set.location_of('two').should == 40
38
+ end
39
+ end
40
+
41
+ describe '#length' do
42
+ it 'should return the number of icons in the set' do
43
+ Kin::Sprites::IconSet.new([]).length.should == 0
44
+ Kin::Sprites::IconSet.new(['one']).length.should == 1
45
+ Kin::Sprites::IconSet.new(['one', 'two']).length.should == 2
46
+ end
47
+ end
48
+ end
49
+
50
+ # ImageGenerator =============================================================
51
+
52
+ # Requires:
53
+ #
54
+ # @gen (Kin::Sprites::ImageGenerator)
55
+ # An image generator instance.
56
+ # @sprite_path (String)
57
+ # A path to where a sprite should be saved.
58
+ #
59
+ describe 'saving a sprite', :shared => true do
60
+ it 'should save the image to the specified path' do
61
+ lambda { @gen.save(@sprite_path) }.should \
62
+ change(&lambda { File.exists?(@sprite_path) })
63
+ end
64
+
65
+ it 'should silently overwrite any existing file at the specified path' do
66
+ FileUtils.touch(@sprite_path)
67
+ orig_size = File.size(@sprite_path)
68
+ @gen.save(@sprite_path)
69
+
70
+ # Using touch should create a zero-byte file (as near as makes no
71
+ # difference, anyway). Saving the PNG should result in a larger file.
72
+ File.exists?(@sprite_path).should be_true
73
+ File.size(@sprite_path).should > orig_size
74
+ end
75
+
76
+ it 'should save a 32-bit PNG' do
77
+ @gen.save(@sprite_path)
78
+ image = Magick::Image.ping(@sprite_path).first
79
+ image.format.should == 'PNG'
80
+ image.quantum_depth.should == 8 # 8-bits per channel.
81
+ end
82
+
83
+ it 'should create a 16 pixel wide image' do
84
+ @gen.save(@sprite_path)
85
+ Magick::Image.ping(@sprite_path).first.columns.should == 16
86
+ end
87
+ end
88
+
89
+ describe Kin::Sprites::ImageGenerator, '#save' do
90
+ ##
91
+ # Creates an ImageGenerator instance suitable for use in specs.
92
+ #
93
+ # @param [Array<String>] An array of icons to use.
94
+ #
95
+ def create_image_generator(icons)
96
+ Kin::Sprites::ImageGenerator.new(
97
+ Kin::Sprites::IconSet.new(icons),
98
+ fixture_path('public', 'images', 'sprites', 'src')
99
+ )
100
+ end
101
+
102
+ before(:all) do
103
+ @dir = tmp_path('sprites')
104
+ @sprite_path = tmp_path('sprites', 'sprite.png')
105
+ FileUtils.mkdir_p(@dir)
106
+ end
107
+
108
+ after(:all) do
109
+ FileUtils.rmdir(@dir)
110
+ end
111
+
112
+ after(:each) do
113
+ FileUtils.rm(@sprite_path) if @sprite_path && File.exists?(@sprite_path)
114
+ end
115
+
116
+ # On with the specs...
117
+
118
+ describe 'when creating a sprite with a single icon' do
119
+ before(:each) do
120
+ @gen = create_image_generator(['one'])
121
+ end
122
+
123
+ it_should_behave_like 'saving a sprite'
124
+
125
+ it 'should create a 16 pixel high image' do
126
+ # 40 pixels with the top and bottom 12 (blank) cropped off
127
+ @gen.save(@sprite_path)
128
+ Magick::Image.ping(@sprite_path).first.rows.should == 16
129
+ end
130
+ end
131
+
132
+ describe 'when creating a sprite with a three icons' do
133
+ before(:each) do
134
+ @gen = create_image_generator(['one', 'two', 'three'])
135
+ end
136
+
137
+ it_should_behave_like 'saving a sprite'
138
+
139
+ it 'should create a 96 pixel high image' do
140
+ # 120 pixels with the top and bottom 12 (blank) cropped off
141
+ @gen.save(@sprite_path)
142
+ Magick::Image.ping(@sprite_path).first.rows.should == 96
143
+ end
144
+ end
145
+
146
+ it 'should raise IconNotReadable when one of the icons does not exist' do
147
+ block = lambda { create_image_generator(['not_here']).save(@sprite_path) }
148
+ block.should raise_error(
149
+ Kin::Sprites::ImageGenerator::IconNotReadable, /unable to open/)
150
+ end
151
+
152
+ it 'should raise TargetNotWriteable when the sprite path is not ' \
153
+ 'writeable' do
154
+ gen = create_image_generator(['one'])
155
+ orig_perms = File.stat(@dir).mode
156
+ File.chmod(0000, @dir)
157
+
158
+ begin
159
+ lambda { gen.save(@sprite_path) }.should raise_error(
160
+ Kin::Sprites::ImageGenerator::TargetNotWriteable, /Permission denied/)
161
+ ensure
162
+ File.chmod(orig_perms, @dir)
163
+ end
164
+ end
165
+ end
166
+
167
+ # SassGenerator ==============================================================
168
+
169
+ describe Kin::Sprites::SassGenerator, '#to_sass' do
170
+ before(:each) do
171
+ @set = Kin::Sprites::IconSet.new(%w(one two three))
172
+ @gen = Kin::Sprites::SassGenerator.new(@set, 'mysprites')
173
+ @sass = @gen.to_sass('/images/sprites')
174
+ end
175
+
176
+ it 'should not indent mixin definitions' do
177
+ @sass.each_line do |line|
178
+ line.should =~ /^=/ if line =~ /=\w+-icon/
179
+ end
180
+ end
181
+
182
+ it 'should indent if statements with two spaces' do
183
+ @sass.each_line do |line|
184
+ line.should =~ /^ @/ if line =~ /@(?:else|if)/
185
+ end
186
+ end
187
+
188
+ it 'should indent position assigments with four spaces' do
189
+ @sass.each_line do |line|
190
+ line.should =~ /^ !pos/ if line =~ /@pos = -\d+px/
191
+ end
192
+ end
193
+
194
+ it 'should indent background statements with two spaces' do
195
+ @sass.each_line do |line|
196
+ line.should =~ / :background/ if line =~ /:background/
197
+ end
198
+ end
199
+
200
+ it 'should include statements for all the icons' do
201
+ @sass.should include('!icon == "one"')
202
+ @sass.should include('!icon == "two"')
203
+ @sass.should include('!icon == "three"')
204
+ end
205
+
206
+ it 'should use an `@if` statement for the first icon' do
207
+ @sass.should include('@if !icon == "one"')
208
+ @sass.should_not include('@if !icon == "two"')
209
+ @sass.should_not include('@if !icon == "three"')
210
+ end
211
+
212
+ it 'should use an `@else if` statement for subsequence icons' do
213
+ @sass.should_not include('@else if !icon == "one"')
214
+ @sass.should include('@else if !icon == "two"')
215
+ @sass.should include('@else if !icon == "three"')
216
+ end
217
+
218
+ it 'should use the given base directory when creating the sprite path' do
219
+ @sass.should =~ %r{url\(/images/sprites}
220
+ end
221
+
222
+ it 'should use the generator name when creating the sprite path' do
223
+ @sass.should include('mysprites.png')
224
+ end
225
+ end
226
+
227
+ # RakeRunner =================================================================
228
+
229
+ ##
230
+ # Copies the icons source files from fixture/public/images/sprites/src to
231
+ # the tmp/spec/sprites/src directory. Removes tmp/spec/sprites when done.
232
+ #
233
+ describe Kin::Sprites::RakeRunner do
234
+ before(:each) do
235
+ FileUtils.mkdir_p(tmp_path('sprites'))
236
+ FileUtils.cp_r(fixture_path('public', 'images', 'sprites'), tmp_path)
237
+ end
238
+
239
+ after(:each) do
240
+ FileUtils.rm_r(tmp_path('sprites'))
241
+ end
242
+
243
+ def rake_runner(sprites_yml = 'sprites.yml')
244
+ Kin::Sprites::RakeRunner.new(
245
+ fixture_path('config', sprites_yml),
246
+ tmp_path('sprites'),
247
+ tmp_path('sprites', '_sprites.sass'))
248
+ end
249
+
250
+ it 'should raise an error when sprites.yml could not be found' do
251
+ lambda {
252
+ Kin::Sprites::RakeRunner.new(
253
+ 'not_here.yml',
254
+ fixture_path('public', 'images', 'sprites'),
255
+ fixture_path('public', 'stylesheets', 'sass', '_sprites.sass')
256
+ )
257
+ }.should raise_error(Kin::Sprites::SpriteError)
258
+ end
259
+
260
+ describe 'when no sprites have been previously generated' do
261
+ it 'should generate the sprite files' do
262
+ out = capture_stdout { rake_runner.generate! }
263
+ out.should =~ /Regenerated "general"/
264
+ out.should =~ /Regenerated "more"/
265
+ end
266
+
267
+ it 'should generate the SASS partial' do
268
+ out = capture_stdout { rake_runner.generate! }
269
+ out.should =~ /Saved SASS/
270
+ end
271
+ end
272
+
273
+ describe 'when the sprites have been previously generated,' do
274
+ describe 'and one has changed' do
275
+ before(:each) do
276
+ capture_stdout { rake_runner.generate! }
277
+ end
278
+
279
+ it 'should regenerate the changed sprite file' do
280
+ out = capture_stdout { rake_runner('sprites.different.yml').generate! }
281
+ out.should =~ /Regenerated "general"/
282
+ end
283
+
284
+ it 'should not regenerate the unchanged sprite file' do
285
+ out = capture_stdout { rake_runner('sprites.different.yml').generate! }
286
+ out.should =~ /Ignoring "more"/
287
+ end
288
+
289
+ it 'should regenerate the SASS partial' do
290
+ out = capture_stdout { rake_runner('sprites.different.yml').generate! }
291
+ out.should =~ /Saved SASS/
292
+ end
293
+ end
294
+
295
+ describe 'have not changed,' do
296
+ before(:each) do
297
+ capture_stdout { rake_runner.generate! }
298
+ end
299
+
300
+ describe 'and :force is false' do
301
+ it 'should not regenerate the sprite files' do
302
+ out = capture_stdout { rake_runner.generate! }
303
+ out.should =~ /Ignoring "general"/
304
+ out.should =~ /Ignoring "more"/
305
+ end
306
+
307
+ it 'should not regenerate the SASS partial' do
308
+ out = capture_stdout { rake_runner.generate! }
309
+ out.should_not =~ /Saved SASS/
310
+ end
311
+ end
312
+
313
+ describe 'and :force is true' do
314
+ it 'should regenerate the sprite files' do
315
+ out = capture_stdout { rake_runner.generate!(true) }
316
+ out.should =~ /Regenerated "general"/
317
+ out.should =~ /Regenerated "more"/
318
+ end
319
+
320
+ it 'should regenerate the SASS partial' do
321
+ out = capture_stdout { rake_runner.generate!(true) }
322
+ out.should =~ /Saved SASS/
323
+ end
324
+ end
325
+
326
+ describe 'and a sprite has been deleted' do
327
+ before(:each) do
328
+ FileUtils.rm(tmp_path('sprites', 'general.png'))
329
+ end
330
+
331
+ it 'should regenerate the deleted sprite' do
332
+ out = capture_stdout { rake_runner.generate! }
333
+ out.should =~ /Regenerated "general"/
334
+ end
335
+
336
+ it 'should not regenereate the unchanged sprite' do
337
+ out = capture_stdout { rake_runner.generate! }
338
+ out.should =~ /Ignoring "more"/
339
+ end
340
+
341
+ it 'should regenerate the SASS partial' do
342
+ out = capture_stdout { rake_runner.generate!(true) }
343
+ out.should =~ /Saved SASS/
344
+ end
345
+ end
346
+ end
347
+ end
348
+
349
+ end