fontcustom 1.0.1 → 1.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +1 -1
  4. data/TODO.md +6 -0
  5. data/lib/fontcustom.rb +1 -1
  6. data/lib/fontcustom/actions.rb +28 -0
  7. data/lib/fontcustom/cli.rb +16 -15
  8. data/lib/fontcustom/generator/font.rb +31 -35
  9. data/lib/fontcustom/generator/template.rb +49 -34
  10. data/lib/fontcustom/options.rb +17 -11
  11. data/lib/fontcustom/scripts/generate.py +1 -1
  12. data/lib/fontcustom/templates/_fontcustom-bootstrap-ie7.scss +4 -3
  13. data/lib/fontcustom/templates/_fontcustom-bootstrap.scss +9 -14
  14. data/lib/fontcustom/templates/_fontcustom.scss +8 -14
  15. data/lib/fontcustom/templates/fontcustom-bootstrap-ie7.css +3 -2
  16. data/lib/fontcustom/templates/fontcustom-bootstrap.css +9 -8
  17. data/lib/fontcustom/templates/fontcustom-preview.html +2 -3
  18. data/lib/fontcustom/templates/fontcustom.css +7 -7
  19. data/lib/fontcustom/templates/fontcustom.yml +25 -66
  20. data/lib/fontcustom/util.rb +108 -31
  21. data/lib/fontcustom/version.rb +1 -1
  22. data/lib/fontcustom/watcher.rb +24 -8
  23. data/spec/fixtures/{mixed-output → generators}/.fontcustom-data +0 -0
  24. data/spec/fixtures/{mixed-output → generators/mixed-output}/another-font.ttf +0 -0
  25. data/spec/fixtures/{mixed-output → generators/mixed-output}/dont-delete-me.bro +0 -0
  26. data/spec/fixtures/{mixed-output → generators/mixed-output}/fontcustom.css +0 -0
  27. data/spec/fixtures/{mixed-output → generators/mixed-output}/fontcustom_cc5ce52f2ae4f9ce2e7ee8131bbfee1e.eot +0 -0
  28. data/spec/fixtures/{mixed-output → generators/mixed-output}/fontcustom_cc5ce52f2ae4f9ce2e7ee8131bbfee1e.svg +0 -0
  29. data/spec/fixtures/{mixed-output → generators/mixed-output}/fontcustom_cc5ce52f2ae4f9ce2e7ee8131bbfee1e.ttf +0 -0
  30. data/spec/fixtures/{mixed-output → generators/mixed-output}/fontcustom_cc5ce52f2ae4f9ce2e7ee8131bbfee1e.woff +0 -0
  31. data/spec/fixtures/{not-a-dir → shared/not-a-dir} +0 -0
  32. data/spec/fixtures/shared/templates/custom.css +1 -0
  33. data/spec/fixtures/shared/templates/regular.css +1 -0
  34. data/spec/fixtures/{empty → shared/vectors-empty}/no_vectors_here.txt +0 -0
  35. data/spec/fixtures/{vectors → shared/vectors}/C.svg +0 -0
  36. data/spec/fixtures/{vectors → shared/vectors}/D.svg +0 -0
  37. data/spec/fixtures/vectors/a_R3ally-eXotic f1Le Name.svg b/data/spec/fixtures/shared/vectors/a_R3ally-eXotic f1Le → Name.svg +0 -0
  38. data/spec/fixtures/util/config-is-in-dir/fontcustom.yml +1 -0
  39. data/spec/fixtures/util/fontcustom-malformed.yml +1 -0
  40. data/spec/fixtures/{fontcustom.yml → util/fontcustom.yml} +0 -0
  41. data/spec/fixtures/util/rails-like/config/fontcustom.yml +1 -0
  42. data/spec/fontcustom/actions_spec.rb +22 -0
  43. data/spec/fontcustom/generator/font_spec.rb +107 -62
  44. data/spec/fontcustom/generator/template_spec.rb +124 -29
  45. data/spec/fontcustom/util_spec.rb +299 -53
  46. data/spec/fontcustom/watcher_spec.rb +56 -10
  47. data/spec/spec_helper.rb +8 -3
  48. metadata +46 -34
  49. data/spec/fixtures/empty-data/.fontcustom-data +0 -0
@@ -13,101 +13,347 @@ describe Fontcustom::Util do
13
13
  end
14
14
 
15
15
  context ".collect_options" do
16
- it "should return defaults when called without arguments" do
17
- options = util.collect_options
18
- defaults = Fontcustom::DEFAULT_OPTIONS.dup
19
-
20
- # ignore :templates and :output since they're generated
21
- options.delete(:templates)
22
- defaults.delete(:templates)
23
- options.delete(:output)
24
- defaults.delete(:output)
25
-
26
- options.should == defaults
16
+ it "should raise error if fontcustom.yml isn't valid" do
17
+ options = {
18
+ :project_root => fixture,
19
+ :input => "shared/vectors",
20
+ :config => "util/fontcustom-malformed.yml"
21
+ }
22
+ expect { util.collect_options(options) }.to raise_error Fontcustom::Error, /couldn't read your configuration/
27
23
  end
28
24
 
29
25
  it "should overwrite defaults with config file" do
30
- options = util.collect_options :config => fixture("fontcustom.yml")
31
- options[:font_name].should == "custom-name-from-config"
26
+ options = {
27
+ :project_root => fixture,
28
+ :input => "shared/vectors",
29
+ :config => "util/fontcustom.yml"
30
+ }
31
+ options = util.collect_options options
32
+ options[:font_name].should == "Custom-Name-From-Config"
32
33
  end
33
34
 
34
35
  it "should overwrite config file and defaults with CLI options" do
35
- options = util.collect_options :config => fixture("fontcustom.yml"), :font_name => "custom-name-from-cli"
36
+ options = {
37
+ :project_root => fixture,
38
+ :input => "shared/vectors",
39
+ :font_name => "custom-name-from-cli",
40
+ :config => "util/fontcustom.yml"
41
+ }
42
+ options = util.collect_options options
36
43
  options[:font_name].should == "custom-name-from-cli"
37
44
  end
38
45
 
39
46
  it "should normalize file name" do
40
- options = util.collect_options :font_name => " A_stR4nG3 nAm3 "
41
- options[:font_name].should == "a_str4ng3-nam3"
47
+ options = {
48
+ :project_root => fixture,
49
+ :input => "shared/vectors",
50
+ :font_name => " A_stR4nG3 nAm3 Ø& "
51
+ }
52
+ options = util.collect_options options
53
+ options[:font_name].should == "A_stR4nG3--nAm3---"
42
54
  end
43
55
  end
44
56
 
45
57
  context ".get_config_path" do
46
58
  it "should search for fontcustom.yml if options[:config] is a dir" do
47
- options = { :config => fixture("") }
48
- util.get_config_path(options).should == fixture("fontcustom.yml")
59
+ options = {
60
+ :project_root => fixture,
61
+ :config => "util/config-is-in-dir"
62
+ }
63
+ util.get_config_path(options).should == fixture("util/config-is-in-dir/fontcustom.yml")
64
+ end
65
+
66
+ it "should use options[:config] if it's a file" do
67
+ options = {
68
+ :project_root => fixture,
69
+ :config => "util/fontcustom.yml"
70
+ }
71
+ util.get_config_path(options).should == fixture("util/fontcustom.yml")
72
+ end
73
+
74
+ it "should find fontcustom.yml in :project_root/config" do
75
+ options = { :project_root => fixture("util/rails-like") }
76
+ util.get_config_path(options).should == fixture("util/rails-like/config/fontcustom.yml")
77
+ end
78
+
79
+ it "should follow ../../ paths" do
80
+ options = {
81
+ :project_root => fixture("shared"),
82
+ :input => "vectors",
83
+ :config => "../util"
84
+ }
85
+ util.get_config_path(options).should == fixture("util/fontcustom.yml")
86
+ end
87
+
88
+ it "should print out which fontcustom.yml it's using"
89
+
90
+ it "should raise error if fontcustom.yml was specified but doesn't exist" do
91
+ options = {
92
+ :project_root => fixture,
93
+ :input => "shared/vectors",
94
+ :config => "does-not-exist"
95
+ }
96
+ expect { util.get_config_path(options) }.to raise_error Fontcustom::Error, /couldn't find/
97
+ end
98
+
99
+ it "should print a warning if fontcustom.yml was NOT specified and doesn't exist"
100
+ end
101
+
102
+ context ".get_input_paths" do
103
+ it "should raise error if input[:vectors] doesn't contain vectors" do
104
+ options = {
105
+ :project_root => fixture,
106
+ :input => "shared/vectors-empty"
107
+ }
108
+ expect { util.get_input_paths(options) }.to raise_error Fontcustom::Error, /doesn't contain any vectors/
109
+ end
110
+
111
+ it "should follow ../../ paths" do
112
+ options = {
113
+ :project_root => fixture("util"),
114
+ :input => {:vectors => "../shared/vectors", :templates => "../shared/templates"}
115
+ }
116
+ paths = util.get_input_paths(options)
117
+ paths[:vectors].should eq(fixture("shared/vectors"))
118
+ paths[:templates].should eq(fixture("shared/templates"))
119
+ end
120
+
121
+ context "when passed a hash" do
122
+ it "should return a hash of input locations" do
123
+ options = {
124
+ :input => { :vectors => "shared/vectors" },
125
+ :project_root => fixture
126
+ }
127
+ paths = util.get_input_paths(options)
128
+ paths.should have_key("vectors")
129
+ paths.should have_key("templates")
130
+ end
131
+
132
+ it "should set :templates as :vectors if :templates isn't passed" do
133
+ options = {
134
+ :input => { :vectors => "shared/vectors" },
135
+ :project_root => fixture
136
+ }
137
+ paths = util.get_input_paths(options)
138
+ paths[:vectors].should equal(paths[:templates])
139
+ end
140
+
141
+ it "should preserve :templates if it is passed" do
142
+ options = {
143
+ :input => { :vectors => "shared/vectors", :templates => "shared/templates" },
144
+ :project_root => fixture
145
+ }
146
+ paths = util.get_input_paths(options)
147
+ paths[:templates].should_not equal(paths[:vectors])
148
+ end
149
+
150
+ it "should raise an error if :vectors isn't included" do
151
+ options = {
152
+ :input => { :templates => "shared/templates" },
153
+ :project_root => fixture
154
+ }
155
+ expect { util.get_input_paths(options) }.to raise_error Fontcustom::Error, /should be a string or a hash/
156
+ end
157
+
158
+ it "should raise an error if :vectors doesn't point to an existing directory" do
159
+ options = {
160
+ :input => { :vectors => "shared/not-a-dir" },
161
+ :project_root => fixture
162
+ }
163
+ expect { util.get_input_paths(options) }.to raise_error Fontcustom::Error, /should be a directory/
164
+ end
49
165
  end
50
166
 
51
- it "should search use options[:config] if it's a file" do
52
- options = { :config => fixture("fontcustom.yml") }
53
- util.get_config_path(options).should == fixture("fontcustom.yml")
167
+ context "when passed a string" do
168
+ it "should return a hash of input locations" do
169
+ options = {
170
+ :input => "shared/vectors",
171
+ :project_root => fixture
172
+ }
173
+ paths = util.get_input_paths(options)
174
+ paths.should have_key("vectors")
175
+ paths.should have_key("templates")
176
+ end
177
+
178
+ it "should set :templates to match :vectors" do
179
+ options = {
180
+ :input => "shared/vectors",
181
+ :project_root => fixture
182
+ }
183
+ paths = util.get_input_paths(options)
184
+ paths[:vectors].should equal(paths[:templates])
185
+ end
186
+
187
+ it "should raise an error if :vectors doesn't point to a directory" do
188
+ options = {
189
+ :input => "shared/not-a-dir",
190
+ :project_root => fixture
191
+ }
192
+ expect { util.collect_options options }.to raise_error Fontcustom::Error, /should be a directory/
193
+ end
54
194
  end
195
+ end
55
196
 
56
- it "should search in input dir if no options[:config] is given" do
57
- options = { :input => fixture("") }
58
- util.get_config_path(options).should == fixture("fontcustom.yml")
197
+ context ".get_output_paths" do
198
+ it "should default to :project_root/:font_name if no output is specified" do
199
+ options = { :project_root => fixture, :font_name => "test" }
200
+ paths = util.get_output_paths(options)
201
+ paths[:fonts].should eq(fixture("test"))
59
202
  end
60
203
 
61
- it "should return false if neither exist" do
62
- options = { :input => fixture("vectors") }
63
- util.get_config_path(options).should be_false
204
+ it "should print a warning when defaulting to :project_root/:font_name"
205
+
206
+ it "should follow ../../ paths" do
207
+ options = {
208
+ :project_root => fixture("shared"),
209
+ :input => "vectors",
210
+ :output => {
211
+ :fonts => "../output/fonts",
212
+ :css => "../output/css",
213
+ :preview => "../output/views"
214
+ }
215
+ }
216
+ paths = util.get_output_paths(options)
217
+ paths[:fonts].should eq(fixture("output/fonts"))
218
+ paths[:css].should eq(fixture("output/css"))
219
+ paths[:preview].should eq(fixture("output/views"))
220
+ end
221
+
222
+ context "when passed a hash" do
223
+ it "should return a hash of output locations" do
224
+ options = {
225
+ :output => { :fonts => "output/fonts" },
226
+ :project_root => fixture
227
+ }
228
+ paths = util.get_output_paths(options)
229
+ paths.should have_key("fonts")
230
+ paths.should have_key("css")
231
+ paths.should have_key("preview")
232
+ end
233
+
234
+ it "should set :css and :preview to match :fonts if either aren't passed" do
235
+ options = {
236
+ :output => { :fonts => "output/fonts" },
237
+ :project_root => fixture
238
+ }
239
+ paths = util.get_output_paths(options)
240
+ paths[:css].should equal(paths[:fonts])
241
+ paths[:preview].should equal(paths[:fonts])
242
+ end
243
+
244
+ it "should preserve :css and :preview if they do exist" do
245
+ options = {
246
+ :output => {
247
+ :fonts => "output/fonts",
248
+ :css => "output/styles",
249
+ :preview => "output/preview"
250
+ },
251
+ :project_root => fixture
252
+ }
253
+ paths = util.get_output_paths(options)
254
+ paths[:css].should_not equal(paths[:fonts])
255
+ paths[:preview].should_not equal(paths[:fonts])
256
+ end
257
+
258
+ it "should create additional paths if they are given" do
259
+ options = {
260
+ :output => {
261
+ :fonts => "output/fonts",
262
+ "special.js" => "assets/javascripts"
263
+ },
264
+ :project_root => fixture
265
+ }
266
+ paths = util.get_output_paths(options)
267
+ paths["special.js"].should eq(File.join(options[:project_root], "assets/javascripts"))
268
+ end
269
+
270
+ it "should raise an error if :fonts isn't included" do
271
+ options = {
272
+ :output => { :css => "output/styles" },
273
+ :project_root => fixture
274
+ }
275
+ expect { util.get_output_paths(options) }.to raise_error Fontcustom::Error, /containing a "fonts" key/
276
+ end
277
+ end
278
+
279
+ context "when passed a string" do
280
+ it "should return a hash of output locations" do
281
+ options = {
282
+ :output => "output/fonts",
283
+ :project_root => fixture
284
+ }
285
+ paths = util.get_output_paths(options)
286
+ paths.should have_key("fonts")
287
+ paths.should have_key("css")
288
+ paths.should have_key("preview")
289
+ end
290
+
291
+ it "should set :css and :preview to match :fonts" do
292
+ options = {
293
+ :output => "output/fonts",
294
+ :project_root => fixture
295
+ }
296
+ paths = util.get_output_paths(options)
297
+ paths[:css].should equal(paths[:fonts])
298
+ paths[:preview].should equal(paths[:fonts])
299
+ end
300
+
301
+ it "should raise an error if :fonts exists but isn't a directory" do
302
+ options = {
303
+ :output => "shared/not-a-dir",
304
+ :project_root => fixture
305
+ }
306
+ expect { util.get_output_paths(options) }.to raise_error Fontcustom::Error, /directory, not a file/
307
+ end
64
308
  end
65
309
  end
66
310
 
67
- context ".get_template_paths" do
311
+ context ".get_templates" do
68
312
  it "should ensure that 'css' is included with 'preview'" do
69
313
  lib = util.gem_lib_path
70
- options = { :input => fixture("vectors"), :templates => %W|preview| }
71
- templates = util.get_template_paths options
314
+ options = { :input => fixture("shared/vectors"), :templates => %W|preview| }
315
+ templates = util.get_templates options
72
316
  templates.should =~ [
73
- File.join(lib, "templates", "fontcustom.css"),
317
+ File.join(lib, "templates", "fontcustom.css"),
74
318
  File.join(lib, "templates", "fontcustom-preview.html")
75
319
  ]
76
320
  end
77
321
 
78
322
  it "should expand shorthand for packaged templates" do
79
323
  lib = util.gem_lib_path
80
- options = { :input => fixture("vectors"), :templates => %W|preview css scss bootstrap bootstrap-scss bootstrap-ie7 bootstrap-ie7-scss| }
81
- templates = util.get_template_paths options
324
+ options = { :input => fixture("shared/vectors"), :templates => %W|preview css scss bootstrap bootstrap-scss bootstrap-ie7 bootstrap-ie7-scss| }
325
+ templates = util.get_templates options
82
326
  templates.should =~ [
83
327
  File.join(lib, "templates", "fontcustom-preview.html"),
84
- File.join(lib, "templates", "fontcustom.css"),
328
+ File.join(lib, "templates", "fontcustom.css"),
85
329
  File.join(lib, "templates", "_fontcustom.scss"),
86
- File.join(lib, "templates", "fontcustom-bootstrap.css"),
87
- File.join(lib, "templates", "_fontcustom-bootstrap.scss"),
88
- File.join(lib, "templates", "fontcustom-bootstrap-ie7.css"),
89
- File.join(lib, "templates", "_fontcustom-bootstrap-ie7.scss")
330
+ File.join(lib, "templates", "fontcustom-bootstrap.css"),
331
+ File.join(lib, "templates", "_fontcustom-bootstrap.scss"),
332
+ File.join(lib, "templates", "fontcustom-bootstrap-ie7.css"),
333
+ File.join(lib, "templates", "_fontcustom-bootstrap-ie7.scss")
90
334
  ]
91
335
  end
92
336
 
93
- it "should search in Dir.pwd first" do
94
- Dir.chdir fixture("")
95
- options = { :templates => %W|not-a-dir| }
96
- templates = util.get_template_paths options
97
- templates.should =~ ["not-a-dir"]
98
- end
99
-
100
- it "should search in options[:input] second" do
101
- options = { :input => fixture("empty"), :templates => %W|no_vectors_here.txt| }
102
- templates = util.get_template_paths options
103
- templates.should =~ [fixture("empty/no_vectors_here.txt")]
337
+ it "should find custom templates in :template_path" do
338
+ options = {
339
+ :project_root => fixture,
340
+ :input => {
341
+ :vectors => fixture("shared/vectors"),
342
+ :templates => fixture("shared/templates")
343
+ },
344
+ :templates => %W|custom.css|
345
+ }
346
+ templates = util.get_templates options
347
+ templates.should eq([ fixture("shared/templates/custom.css") ])
104
348
  end
105
349
 
106
350
  it "should raise an error if a template does not exist" do
107
- options = { :input => fixture("vectors"), :templates => %W|css #{fixture("fake-template")}| }
108
- expect { util.get_template_paths options }.to raise_error(
109
- Fontcustom::Error, /couldn't find.+#{fixture("fake-template")}/
110
- )
351
+ options = {
352
+ :project_root => fixture,
353
+ :input => { :templates => "shared/templates" },
354
+ :templates => %W|css fake-template|
355
+ }
356
+ expect { util.get_templates options }.to raise_error Fontcustom::Error, /couldn't find.+fake-template/
111
357
  end
112
358
  end
113
359
  end
@@ -7,7 +7,7 @@ describe Fontcustom::Watcher do
7
7
  Fontcustom::Generator::Font.stub :start
8
8
  Fontcustom::Generator::Template.stub :start
9
9
  opts = Fontcustom::Util.collect_options options
10
- opts[:blocking] = false # undocumented — non-blocking use of watcher
10
+ opts[:blocking] = false # undocumented — non-blocking use of watcher for testing
11
11
  Fontcustom::Watcher.new opts
12
12
  end
13
13
 
@@ -15,7 +15,11 @@ describe Fontcustom::Watcher do
15
15
  it "should call generators on init" do
16
16
  Fontcustom::Generator::Font.should_receive(:start).once
17
17
  Fontcustom::Generator::Template.should_receive(:start).once
18
- w = watcher :input => fixture("vectors"), :output => fixture("watcher-test")
18
+ w = watcher(
19
+ :project_root => fixture,
20
+ :input => "shared/vectors",
21
+ :output => "output"
22
+ )
19
23
  # silence output
20
24
  capture(:stdout) do
21
25
  w.watch
@@ -26,7 +30,12 @@ describe Fontcustom::Watcher do
26
30
  it "should not call generators on init if options[:skip_first] is passed" do
27
31
  Fontcustom::Generator::Font.should_not_receive(:start)
28
32
  Fontcustom::Generator::Template.should_not_receive(:start)
29
- w = watcher :input => fixture("vectors"), :output => fixture("watcher-test"), :skip_first => true
33
+ w = watcher(
34
+ :project_root => fixture,
35
+ :input => "shared/vectors",
36
+ :output => "output",
37
+ :skip_first => true
38
+ )
30
39
  capture(:stdout) do
31
40
  w.watch
32
41
  w.stop
@@ -36,31 +45,68 @@ describe Fontcustom::Watcher do
36
45
  it "should call generators when vectors change" do
37
46
  Fontcustom::Generator::Font.should_receive(:start).once
38
47
  Fontcustom::Generator::Template.should_receive(:start).once
39
- w = watcher :input => fixture("vectors"), :output => fixture("watcher-test"), :skip_first => true
48
+ w = watcher(
49
+ :project_root => fixture,
50
+ :input => "shared/vectors",
51
+ :output => "output",
52
+ :skip_first => true
53
+ )
40
54
  capture(:stdout) do
41
55
  begin
42
56
  w.watch
43
- FileUtils.cp fixture("vectors/C.svg"), fixture("vectors/test.svg")
44
- sleep 2
57
+ FileUtils.cp fixture("shared/vectors/C.svg"), fixture("shared/vectors/test.svg")
58
+ sleep 1
45
59
  ensure
46
60
  w.stop
47
- new = fixture("vectors/test.svg")
61
+ new = fixture("shared/vectors/test.svg")
48
62
  FileUtils.rm(new) if File.exists?(new)
49
63
  end
50
64
  end
51
65
  end
52
66
 
67
+ it "should call generators when watched templates change" do
68
+ Fontcustom::Generator::Font.should_receive(:start).once
69
+ Fontcustom::Generator::Template.should_receive(:start).once
70
+ w = watcher(
71
+ :project_root => fixture,
72
+ :input => {:vectors => "shared/vectors", :templates => "shared/templates"},
73
+ :templates => %w|css preview custom.css|,
74
+ :output => "output",
75
+ :skip_first => true
76
+ )
77
+ capture(:stdout) do
78
+ begin
79
+ template = fixture "shared/templates/custom.css"
80
+ content = File.read template
81
+ new = content + "\n.bar { color: red; }"
82
+
83
+ w.watch
84
+ File.open(template, "w") { |file| file.write(new) }
85
+ sleep 1
86
+ ensure
87
+ w.stop
88
+ File.open(template, "w") { |file| file.write(content) }
89
+ end
90
+ end
91
+
92
+ end
93
+
53
94
  it "should do nothing when non-vectors change" do
54
95
  Fontcustom::Generator::Font.should_not_receive(:start)
55
96
  Fontcustom::Generator::Template.should_not_receive(:start)
56
- w = watcher :input => fixture("vectors"), :output => fixture("watcher-test"), :skip_first => true
97
+ w = watcher(
98
+ :project_root => fixture,
99
+ :input => "shared/vectors",
100
+ :output => "output",
101
+ :skip_first => true
102
+ )
57
103
  capture(:stdout) do
58
104
  begin
59
105
  w.watch
60
- FileUtils.touch fixture("vectors/non-vector-file")
106
+ FileUtils.touch fixture("shared/vectors/non-vector-file")
61
107
  ensure
62
108
  w.stop
63
- new = fixture("vectors/non-vector-file")
109
+ new = fixture("shared/vectors/non-vector-file")
64
110
  FileUtils.rm(new) if File.exists?(new)
65
111
  end
66
112
  end