gkh-fontcustom 1.3.7

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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +20 -0
  4. data/CHANGELOG.md +137 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/Gemfile +4 -0
  7. data/LICENSES.txt +60 -0
  8. data/README.md +112 -0
  9. data/Rakefile +8 -0
  10. data/bin/fontcustom +5 -0
  11. data/fontcustom.gemspec +28 -0
  12. data/gemfiles/Gemfile.listen_1 +6 -0
  13. data/lib/fontcustom.rb +43 -0
  14. data/lib/fontcustom/base.rb +54 -0
  15. data/lib/fontcustom/cli.rb +110 -0
  16. data/lib/fontcustom/error.rb +4 -0
  17. data/lib/fontcustom/generator/font.rb +109 -0
  18. data/lib/fontcustom/generator/template.rb +222 -0
  19. data/lib/fontcustom/manifest.rb +75 -0
  20. data/lib/fontcustom/options.rb +192 -0
  21. data/lib/fontcustom/scripts/eotlitetool.py +466 -0
  22. data/lib/fontcustom/scripts/generate.py +128 -0
  23. data/lib/fontcustom/scripts/sfnt2woff +0 -0
  24. data/lib/fontcustom/templates/_fontcustom-rails.scss +14 -0
  25. data/lib/fontcustom/templates/_fontcustom.scss +16 -0
  26. data/lib/fontcustom/templates/fontcustom-preview.html +174 -0
  27. data/lib/fontcustom/templates/fontcustom.css +14 -0
  28. data/lib/fontcustom/templates/fontcustom.yml +96 -0
  29. data/lib/fontcustom/utility.rb +117 -0
  30. data/lib/fontcustom/version.rb +3 -0
  31. data/lib/fontcustom/watcher.rb +90 -0
  32. data/spec/fixtures/example/_example-rails.scss +50 -0
  33. data/spec/fixtures/example/example-preview.html +253 -0
  34. data/spec/fixtures/example/example.css +50 -0
  35. data/spec/fixtures/example/example.eot +0 -0
  36. data/spec/fixtures/example/example.svg +75 -0
  37. data/spec/fixtures/example/example.ttf +0 -0
  38. data/spec/fixtures/example/example.woff +0 -0
  39. data/spec/fixtures/generators/.fontcustom-manifest-corrupted.json +25 -0
  40. data/spec/fixtures/generators/.fontcustom-manifest-empty.json +0 -0
  41. data/spec/fixtures/generators/.fontcustom-manifest.json +52 -0
  42. data/spec/fixtures/generators/fontcustom.yml +1 -0
  43. data/spec/fixtures/generators/mixed-output/another-font.ttf +0 -0
  44. data/spec/fixtures/generators/mixed-output/dont-delete-me.bro +0 -0
  45. data/spec/fixtures/generators/mixed-output/fontcustom.css +108 -0
  46. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.eot +0 -0
  47. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.svg +56 -0
  48. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.ttf +0 -0
  49. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.woff +0 -0
  50. data/spec/fixtures/options/any-file-name.yml +1 -0
  51. data/spec/fixtures/options/config-is-in-dir/fontcustom.yml +1 -0
  52. data/spec/fixtures/options/fontcustom-empty.yml +1 -0
  53. data/spec/fixtures/options/fontcustom-malformed.yml +1 -0
  54. data/spec/fixtures/options/fontcustom.yml +1 -0
  55. data/spec/fixtures/options/no-config-here/.gitkeep +0 -0
  56. data/spec/fixtures/options/rails-like/config/fontcustom.yml +1 -0
  57. data/spec/fixtures/shared/not-a-dir +0 -0
  58. data/spec/fixtures/shared/templates/custom.css +4 -0
  59. data/spec/fixtures/shared/templates/regular.css +4 -0
  60. data/spec/fixtures/shared/vectors-empty/no_vectors_here.txt +0 -0
  61. data/spec/fixtures/shared/vectors/C.svg +14 -0
  62. data/spec/fixtures/shared/vectors/D.svg +15 -0
  63. data/spec/fixtures/shared/vectors/a_R3ally-eXotic f1Le Name.svg +6 -0
  64. data/spec/fontcustom/base_spec.rb +45 -0
  65. data/spec/fontcustom/cli_spec.rb +30 -0
  66. data/spec/fontcustom/generator/font_spec.rb +72 -0
  67. data/spec/fontcustom/generator/template_spec.rb +99 -0
  68. data/spec/fontcustom/manifest_spec.rb +17 -0
  69. data/spec/fontcustom/options_spec.rb +315 -0
  70. data/spec/fontcustom/utility_spec.rb +82 -0
  71. data/spec/fontcustom/watcher_spec.rb +121 -0
  72. data/spec/spec_helper.rb +103 -0
  73. metadata +252 -0
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:boxy="http://www.boxy-svg.com/boxyNS" version="1.1" id="Layer_1" x="0px" y="0px" width="100" height="100" enable-background="new -346 256 100 100" xml:space="preserve" boxy:zoom="278" boxy:scrollX="-153" boxy:scrollY="-70" viewBox="0 0 100 100">
3
+ <defs/>
4
+ <path d="M-263.363,311.56l-6.967-25.521l-19.562-12.246l19.148-3.609l0.413-5.213c0,0-14.309-6.192-25.391-8.708 c-2.433-0.553-4.653,8.025-6.731,7.853c-2.199-0.184-3.021-8.415-4.454-7.966c-8.955,2.807-14.775,15.64-14.775,15.64l13.432,5.213 l-19.7,16.04v42.107L-337.167,356h87.984L-263.363,311.56z M-296.575,337.709c-11.64,0-21.076-9.436-21.076-21.076 c0-11.639,9.436-21.075,21.076-21.075s21.076,9.436,21.076,21.075C-275.499,328.273-284.936,337.709-296.575,337.709z" transform="matrix(0.881719 0 0 0.881719 308.838 -224.858)"/>
5
+ <path d="M-297.026,313.592c-1.286-0.602-2.143-1.31-2.143-2.443c0-1.664,0.935-2.584,2.143-3.08V313.592L-297.026,313.592z M-295.195,319.575c1.323,0.602,2.258,1.416,2.258,2.727c0,1.31-0.973,2.194-2.258,2.69V319.575L-295.195,319.575z M-297.026,301.271v2.62c-4.167,0.46-7.828,2.621-7.828,7.471c0,4.921,4.323,6.195,7.828,7.435v6.621 c-0.273,0.07-0.506,0.07-0.74,0.07c-2.142,0-4.284-0.602-6.153-1.521l-0.507,4.461c2.688,0.601,4.011,0.956,6.971,0.956 c0.117,0,0.273,0,0.429-0.036v2.797h1.831v-2.902c4.478-0.496,7.944-2.69,7.944-7.33c0-5.098-4.519-6.372-7.944-7.611v-6.55 c0.117-0.035,0.194-0.035,0.311-0.035c1.908,0,3.816,0.39,5.53,1.062l0.507-4.071c-1.948-0.603-4.051-0.886-6.348-0.886v-2.548 H-297.026L-297.026,301.271z" transform="matrix(0.881719 0 0 0.881719 308.838 -224.858)"/>
6
+ </svg>
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Fontcustom::Base do
4
+ before(:each) { allow(Fontcustom::Manifest).to receive(:write_file) }
5
+
6
+ context "#compile" do
7
+ context "when [:checksum][:current] equals [:checksum][:previous]" do
8
+ it "should show 'no change' message" do
9
+ allow(Fontcustom::Base).to receive(:check_fontforge)
10
+ options = double("options")
11
+ allow(options).to receive(:options).and_return({})
12
+ allow(Fontcustom::Options).to receive(:new).and_return options
13
+
14
+ output = capture(:stdout) do
15
+ base = Fontcustom::Base.new({})
16
+ manifest = base.instance_variable_get :@manifest
17
+ expect(manifest).to receive(:get).and_return :previous => "abc"
18
+ expect(base).to receive(:checksum).and_return "abc"
19
+ base.compile
20
+ end
21
+ expect(output).to match(/No changes/)
22
+ end
23
+ end
24
+ end
25
+
26
+ context ".check_fontforge" do
27
+ it "should raise error if fontforge isn't installed" do
28
+ allow_any_instance_of(Fontcustom::Base).to receive(:"`").and_return("")
29
+ expect { Fontcustom::Base.new(:option => "foo") }.to raise_error Fontcustom::Error, /fontforge/
30
+ end
31
+ end
32
+
33
+ context ".checksum" do
34
+ it "should return hash of all vectors and templates" do
35
+ pending "SHA2 is different on CI servers. Why?"
36
+ allow(Fontcustom::Base).to receive(:check_fontforge)
37
+ base = Fontcustom::Base.new(:input => {:vectors => fixture("shared/vectors")})
38
+ base.instance_variable_set :@options, {
39
+ :templates => Dir.glob(File.join(fixture("shared/templates"), "*"))
40
+ }
41
+ hash = base.send :checksum
42
+ hash.should == "81ffd2f72877be02aad673fdf59c6f9dbfee4cc37ad0b121b9486bc2923b4b36"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+ require "fontcustom/cli"
3
+
4
+ describe Fontcustom::CLI do
5
+ context "#compile" do
6
+ it "should generate fonts and templates (integration)", :integration => true do
7
+ live_test do |testdir|
8
+ Fontcustom::CLI.start ["compile", "vectors", "--quiet"]
9
+ manifest = File.join testdir, ".fontcustom-manifest.json"
10
+ preview = File.join testdir, "fontcustom", "fontcustom-preview.html"
11
+
12
+ expect(Dir.glob(File.join(testdir, "fontcustom", "fontcustom_*\.{ttf,svg,woff,eot}")).length).to eq(4)
13
+ expect(File.read(manifest)).to match(/"fonts":.+fontcustom\/fontcustom_.+\.ttf"/m)
14
+ expect(File.exists?(preview)).to be_truthy
15
+ end
16
+ end
17
+
18
+ it "should generate fonts and templates according to passed options (integration)", :integration => true do
19
+ live_test do |testdir|
20
+ Fontcustom::CLI.start ["compile", "vectors", "--font-name", "example", "--preprocessor-path", "../foo/bar", "--templates", "css", "scss-rails", "preview", "--no-hash", "--base64", "--quiet"]
21
+ manifest = File.join testdir, ".fontcustom-manifest.json"
22
+ css = Dir.glob(File.join("example", "*.scss")).first
23
+
24
+ expect(File.read(manifest)).to match(/"fonts":.+example\/example\.ttf"/m)
25
+ expect(File.read(css)).to match("x-font-woff")
26
+ expect(File.read(css)).to match("../foo/bar/")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ describe Fontcustom::Generator::Font do
4
+ def generator
5
+ allow_any_instance_of(Fontcustom::Manifest).to receive(:write_file)
6
+ Fontcustom::Generator::Font.new("")
7
+ end
8
+
9
+ context "#generate" do
10
+ it "should set manifest[:glyphs] (integration)", :integration => true do
11
+ live_test do |testdir|
12
+ test_manifest
13
+ manifest = File.join Dir.pwd, ".fontcustom-manifest.json"
14
+ gen = Fontcustom::Generator::Font.new manifest
15
+ allow(gen).to receive(:create_fonts)
16
+ gen.generate
17
+ expect(File.read(manifest)).to match(/"glyphs":.+"C":/m)
18
+ end
19
+ end
20
+
21
+ it "should generate fonts (integration)", :integration => true do
22
+ live_test do |testdir|
23
+ test_manifest
24
+ manifest = File.join Dir.pwd, ".fontcustom-manifest.json"
25
+ Fontcustom::Generator::Font.new(manifest).generate
26
+ expect(Dir.glob(File.join(testdir, "fontcustom", "fontcustom_*\.{ttf,svg,woff,eot}")).length).to eq(4)
27
+ expect(File.read(manifest)).to match(/"fonts":.*fontcustom\/fontcustom_.+\.ttf"/m)
28
+ end
29
+ end
30
+ end
31
+
32
+ context ".create_output_dirs" do
33
+ it "should create empty dirs if they don't exist" do
34
+ gen = generator
35
+ options = {
36
+ :output => {:fonts => "path/fonts", :vectors => "path/vectors"},
37
+ :quiet => true
38
+ }
39
+ gen.instance_variable_set :@options, options
40
+ expect(gen).to receive(:empty_directory).with("path/fonts", :verbose => false)
41
+ expect(gen).to receive(:empty_directory).with("path/vectors", :verbose => false)
42
+ gen.send :create_output_dirs
43
+ end
44
+ end
45
+
46
+ context ".set_glyph_info" do
47
+ it "should set :glyphs in manifest" do
48
+ gen = generator
49
+ gen.instance_variable_set :@options, :input => {:vectors => fixture("shared/vectors")}
50
+ manifest = gen.instance_variable_get(:@manifest)
51
+
52
+ gen.send :set_glyph_info
53
+ data = manifest.instance_variable_get(:@data)
54
+ expect(data[:glyphs][:C]).to include(:codepoint => 61696)
55
+ expect(data[:glyphs][:D]).to include(:codepoint => 61697)
56
+ expect(data[:glyphs][:"a_R3ally-eXotic-f1Le-Name"]).to include(:codepoint => 61698)
57
+ end
58
+
59
+ it "should not change codepoints of existing glyphs" do
60
+ gen = generator
61
+ gen.instance_variable_set :@options, :input => {:vectors => fixture("shared/vectors")}
62
+ manifest = gen.instance_variable_get(:@manifest)
63
+ manifest.set :glyphs, {:C => {:source => "foo", :codepoint => 61699}}
64
+
65
+ gen.send :set_glyph_info
66
+ data = manifest.instance_variable_get(:@data)
67
+ expect(data[:glyphs][:C]).to include(:codepoint => 61699)
68
+ expect(data[:glyphs][:D]).to include(:codepoint => 61700)
69
+ expect(data[:glyphs][:"a_R3ally-eXotic-f1Le-Name"]).to include(:codepoint => 61701)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,99 @@
1
+ require "spec_helper"
2
+
3
+ describe Fontcustom::Generator::Template do
4
+ context "#generate" do
5
+ it "should generate templates (integration)", :integration => true do
6
+ live_test do |testdir|
7
+ FileUtils.cp_r fixture("generators/mixed-output"), "fontcustom"
8
+ test_manifest(
9
+ :input => "vectors",
10
+ :quiet => true,
11
+ :templates => %w|preview css scss scss-rails|
12
+ )
13
+ manifest = File.join testdir, ".fontcustom-manifest.json"
14
+ Fontcustom::Generator::Font.new(manifest).generate
15
+ Fontcustom::Generator::Template.new(manifest).generate
16
+
17
+ content = File.read manifest
18
+ expect(content).to match(/fontcustom\/fontcustom-preview.html/)
19
+ end
20
+ end
21
+ end
22
+
23
+ context ".set_relative_paths" do
24
+ it "should assign @font_path, @font_path_alt, and @font_path_preview" do
25
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
26
+ options = gen.instance_variable_get :@options
27
+ options[:output] = {:fonts => fixture("sandbox/test/fonts"), :css => fixture("sandbox/test/css"), :preview => fixture("sandbox/test")}
28
+
29
+ gen.send :set_relative_paths
30
+ expect(gen.instance_variable_get(:@font_path)).to match("../fonts")
31
+ expect(gen.instance_variable_get(:@font_path_alt)).to match("../fonts")
32
+ expect(gen.instance_variable_get(:@font_path_preview)).to match(".")
33
+ end
34
+
35
+ it "should assign @font_path_alt if :preprocessor_path is set" do
36
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
37
+ options = gen.instance_variable_get :@options
38
+ options[:preprocessor_path] = "fonts/fontcustom"
39
+ options[:output] = {:fonts => fixture("sandbox/test/fonts"), :css => fixture("sandbox/test/css"), :preview => fixture("sandbox/test")}
40
+
41
+ gen.send :set_relative_paths
42
+ expect(gen.instance_variable_get(:@font_path_alt)).to match("fonts/fontcustom")
43
+ end
44
+
45
+ it "should assign @font_path_alt as bare font name if :preprocessor_path is false" do
46
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
47
+ options = gen.instance_variable_get :@options
48
+ options[:preprocessor_path] = false
49
+ options[:output] = {:fonts => fixture("sandbox/test/fonts"), :css => fixture("sandbox/test/css"), :preview => fixture("sandbox/test")}
50
+
51
+ gen.send :set_relative_paths
52
+ expect(gen.instance_variable_get(:@font_path_alt)).to_not match("../fonts")
53
+ end
54
+
55
+ it "should assign '.' when paths are the same" do
56
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
57
+ options = gen.instance_variable_get :@options
58
+ options[:output] = {:fonts => fixture("sandbox/test/fonts"), :css => fixture("sandbox/test/fonts"), :preview => fixture("sandbox/test/fonts")}
59
+
60
+ gen.send :set_relative_paths
61
+ expect(gen.instance_variable_get(:@font_path)).to match("./")
62
+ end
63
+ end
64
+
65
+ context ".create_files" do
66
+ it "should not include the template path in custom output file paths" do
67
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
68
+
69
+ # Set options to specify a custom CSS template with a custom output location.
70
+ options = gen.instance_variable_get :@options
71
+ options[:input][:templates] = fixture("shared/templates")
72
+ options[:templates] = ['custom.css']
73
+ options[:output][:'custom.css'] = fixture("sandbox/test")
74
+
75
+ # Don't update the manifest based on these options.
76
+ manifest = gen.instance_variable_get :@manifest
77
+ expect(manifest).to receive(:set)
78
+
79
+ # Confirm that the output file doesn't include the template path.
80
+ expect(gen).to receive(:template).once do |source, target|
81
+ expect(source).to match("shared/templates")
82
+ expect(target).to_not match("shared/templates")
83
+ end
84
+
85
+ gen.send :create_files
86
+ end
87
+ end
88
+
89
+ context ".font_face" do
90
+ it "should return base64 when options are set" do
91
+ gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")
92
+ allow(gen).to receive(:woff_base64).and_return("3xampled4ta")
93
+ options = gen.instance_variable_get :@options
94
+ options[:base64] = true
95
+
96
+ expect(gen.send(:font_face)).to match("x-font-woff")
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe Fontcustom::Manifest do
4
+ context "#initialize" do
5
+ it "should create a manifest file and assign :options", :integration => true do
6
+ live_test do |testdir|
7
+ capture(:stdout) do
8
+ manifest = File.join testdir, ".fontcustom-manifest.json"
9
+ options = Fontcustom::Options.new(:manifest => manifest, :input => "vectors").options
10
+ Fontcustom::Manifest.new manifest, options
11
+ end
12
+ content = File.read File.join(testdir, ".fontcustom-manifest.json")
13
+ expect(content).to match(/"options":.+"input":/m)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,315 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Fontcustom::Options do
5
+ def options(args = {})
6
+ args[:manifest] = fixture(".fontcustom-manifest.json") if args[:manifest].nil?
7
+ Fontcustom::Options.new(args)
8
+ end
9
+
10
+ before(:each) do
11
+ allow_any_instance_of(Fontcustom::Options).to receive(:say_message)
12
+ allow_any_instance_of(Fontcustom::Options).to receive(:parse_options)
13
+ end
14
+
15
+ context ".overwrite_examples" do
16
+ it "should overwite example defaults with real defaults" do
17
+ o = options Fontcustom::EXAMPLE_OPTIONS.dup
18
+ o.send :overwrite_examples
19
+ cli = o.instance_variable_get(:@cli_options)
20
+ Fontcustom::EXAMPLE_OPTIONS.keys.each do |key|
21
+ expect(cli[key]).to eq(Fontcustom::DEFAULT_OPTIONS[key])
22
+ end
23
+ end
24
+ end
25
+
26
+ context ".set_config_path" do
27
+ context "when :config is set" do
28
+ it "should use options[:config] if it's a file" do
29
+ o = options :config => "options/any-file-name.yml"
30
+ o.send :set_config_path
31
+ expect(o.instance_variable_get(:@cli_options)[:config]).to eq("options/any-file-name.yml")
32
+ end
33
+
34
+ it "should search for fontcustom.yml if options[:config] is a dir" do
35
+ o = options :config => "options/config-is-in-dir"
36
+ o.send :set_config_path
37
+ expect(o.instance_variable_get(:@cli_options)[:config]).to eq("options/config-is-in-dir/fontcustom.yml")
38
+ end
39
+
40
+ it "should raise error if :config doesn't exist" do
41
+ o = options :config => "does-not-exist"
42
+ expect { o.send :set_config_path }.to raise_error Fontcustom::Error, /configuration file/
43
+ end
44
+ end
45
+
46
+ context "when :config is not set" do
47
+ it "should find fontcustom.yml in the same dir as the manifest" do
48
+ FileUtils.cd fixture("options") do
49
+ o = options
50
+ o.send :set_config_path
51
+ expect(o.instance_variable_get(:@cli_options)[:config]).to eq("fontcustom.yml")
52
+ end
53
+ end
54
+
55
+ it "should find fontcustom.yml at config/fontcustom.yml" do
56
+ FileUtils.cd fixture("options/rails-like") do
57
+ o = options
58
+ o.send :set_config_path
59
+ expect(o.instance_variable_get(:@cli_options)[:config]).to eq("config/fontcustom.yml")
60
+ end
61
+ end
62
+
63
+ it "should be false if nothing is found" do
64
+ o = options :manifest => "options/no-config-here/.fontcustom-manifest.json"
65
+ o.send :set_config_path
66
+ expect(o.instance_variable_get(:@cli_options)[:config]).to eq(false)
67
+ end
68
+ end
69
+ end
70
+
71
+ context ".load_config" do
72
+ it "should warn if fontcustom.yml is blank" do
73
+ o = options
74
+ o.instance_variable_set :@cli_options, {:config => fixture("options/fontcustom-empty.yml")}
75
+ expect(o).to receive(:say_message).with :warn, /was empty/
76
+ o.send :load_config
77
+ end
78
+
79
+ it "should raise error if fontcustom.yml isn't valid" do
80
+ o = options
81
+ o.instance_variable_set :@cli_options, {:config => fixture("options/fontcustom-malformed.yml")}
82
+ expect { o.send :load_config }.to raise_error Fontcustom::Error, /Error parsing/
83
+ end
84
+
85
+ it "should assign empty hash :config is false" do
86
+ o = options
87
+ o.instance_variable_set :@cli_options, {:config => false}
88
+ o.send :load_config
89
+ expect(o.instance_variable_get(:@config_options)).to eq({})
90
+ end
91
+
92
+ context "when :debug is true" do
93
+ it "should report which configuration file it's using" do
94
+ o = options
95
+ o.instance_variable_set :@cli_options, {
96
+ :config => fixture("options/any-file-name.yml"),
97
+ :debug => true
98
+ }
99
+ expect(o).to receive(:say_message).with :debug, /Using settings/
100
+ o.send :load_config
101
+ end
102
+ end
103
+ end
104
+
105
+ context ".merge_options" do
106
+ it "should overwrite defaults with config options" do
107
+ o = options
108
+ o.instance_variable_set :@config_options, { :input => "config" }
109
+ o.send :merge_options
110
+ expect(o.options[:input]).to eq("config")
111
+ end
112
+
113
+ it "should overwrite config file and defaults with CLI options" do
114
+ o = options
115
+ o.instance_variable_set :@config_options, { :input => "config", :output => "output" }
116
+ o.instance_variable_set :@cli_options, { :input => "cli" }
117
+ o.send :merge_options
118
+ expect(o.options[:input]).to eq("cli")
119
+ expect(o.options[:output]).to eq("output")
120
+ end
121
+ end
122
+
123
+ context ".clean_font_name" do
124
+ it "should normalize the font name" do
125
+ o = options
126
+ o.instance_variable_set :@options, { :font_name => " A_stR4nG3 nAm3 Ø& " }
127
+ o.send :clean_font_name
128
+ expect(o.options[:font_name]).to eq("A_stR4nG3--nAm3---")
129
+ end
130
+ end
131
+
132
+ context ".set_input_paths" do
133
+ it "should raise error if input[:vectors] doesn't contain SVGs" do
134
+ FileUtils.cd fixture("shared") do
135
+ o = options
136
+ o.instance_variable_set :@options, { :input => "vectors-empty" }
137
+ expect { o.send :set_input_paths }.to raise_error Fontcustom::Error, /doesn't contain any SVGs/
138
+ end
139
+ end
140
+
141
+ context "when :input is a hash" do
142
+ it "should set :templates as :vectors if :templates isn't set" do
143
+ FileUtils.cd fixture("shared") do
144
+ o = options
145
+ o.instance_variable_set :@options, { :input => { :vectors => "vectors" } }
146
+ o.send :set_input_paths
147
+ expect(o.options[:input][:templates]).to eq("vectors")
148
+ end
149
+ end
150
+
151
+ it "should preserve :templates if it's set" do
152
+ FileUtils.cd fixture("shared") do
153
+ o = options
154
+ o.instance_variable_set :@options, { :input => { :vectors => "vectors", :templates => "templates" } }
155
+ o.send :set_input_paths
156
+ expect(o.options[:input][:templates]).to eq("templates")
157
+ end
158
+ end
159
+
160
+ it "should raise an error if :vectors isn't set" do
161
+ FileUtils.cd fixture("shared") do
162
+ o = options
163
+ o.instance_variable_set :@options, { :input => { :templates => "templates" } }
164
+ expect { o.send :set_input_paths }.to raise_error Fontcustom::Error, /have a :vectors key/
165
+ end
166
+ end
167
+
168
+ it "should raise an error if :vectors doesn't point to an existing directory" do
169
+ FileUtils.cd fixture("shared") do
170
+ o = options
171
+ o.instance_variable_set :@options, {
172
+ :config => "fontcustom.yml",
173
+ :input => { :vectors => "not-a-dir" }
174
+ }
175
+ expect { o.send :set_input_paths }.to raise_error Fontcustom::Error, /isn't a directory/
176
+ end
177
+ end
178
+ end
179
+
180
+ context "when :input is a string" do
181
+ it "should return a hash of locations" do
182
+ FileUtils.cd fixture("shared") do
183
+ o = options
184
+ o.instance_variable_set :@options, { :input => "vectors" }
185
+ o.send :set_input_paths
186
+ expect(o.options[:input]).to have_key(:vectors)
187
+ expect(o.options[:input]).to have_key(:templates)
188
+ end
189
+ end
190
+
191
+ it "should set :templates to match :vectors" do
192
+ FileUtils.cd fixture("shared") do
193
+ o = options
194
+ o.instance_variable_set :@options, { :input => "vectors" }
195
+ o.send :set_input_paths
196
+ expect(o.options[:input][:templates]).to eq("vectors")
197
+ end
198
+ end
199
+
200
+ it "should raise an error if :vectors doesn't point to a directory" do
201
+ FileUtils.cd fixture("shared") do
202
+ o = options
203
+ o.instance_variable_set :@options, {
204
+ :config => "fontcustom.yml",
205
+ :input => "not-a-dir"
206
+ }
207
+ expect { o.send :set_input_paths }.to raise_error Fontcustom::Error, /isn't a directory/
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ context ".set_output_paths" do
214
+ context "when :output is nil" do
215
+ context "when :debug is true" do
216
+ it "should print a warning" do
217
+ o = options
218
+ o.instance_variable_set :@options, {
219
+ :debug => true,
220
+ :font_name => "Test-Font"
221
+ }
222
+ expect(o).to receive(:say_message).with :debug, /Test-Font/
223
+ o.send :set_output_paths
224
+ end
225
+ end
226
+ end
227
+
228
+ context "when :output is a hash" do
229
+ it "should set :css and :preview to match :fonts if either aren't set" do
230
+ o = options
231
+ o.instance_variable_set :@options, { :output => { :fonts => "output/fonts" } }
232
+ o.send :set_output_paths
233
+ expect(o.options[:output][:css]).to eq("output/fonts")
234
+ expect(o.options[:output][:preview]).to eq("output/fonts")
235
+ end
236
+
237
+ it "should preserve :css and :preview if they do exist" do
238
+ o = options
239
+ o.instance_variable_set :@options, {
240
+ :output => {
241
+ :fonts => "output/fonts",
242
+ :css => "output/styles",
243
+ :preview => "output/preview"
244
+ }
245
+ }
246
+ o.send :set_output_paths
247
+ expect(o.options[:output][:css]).to eq("output/styles")
248
+ expect(o.options[:output][:preview]).to eq("output/preview")
249
+ end
250
+
251
+ it "should create additional paths if they are given" do
252
+ o = options
253
+ o.instance_variable_set :@options, {
254
+ :output => {
255
+ :fonts => "output/fonts",
256
+ "special.js" => "assets/javascripts"
257
+ }
258
+ }
259
+ o.send :set_output_paths
260
+ expect(o.options[:output][:"special.js"]).to eq("assets/javascripts")
261
+ end
262
+
263
+ it "should raise an error if :fonts isn't set" do
264
+ o = options
265
+ o.instance_variable_set :@options, {
266
+ :config => "fontcustom.yml",
267
+ :output => { :css => "output/styles" }
268
+ }
269
+ expect { o.send :set_output_paths }.to raise_error Fontcustom::Error, /have a :fonts key/
270
+ end
271
+ end
272
+
273
+ context "when :output is a string" do
274
+ it "should return a hash of output locations" do
275
+ o = options
276
+ o.instance_variable_set :@options, { :output => "output/fonts" }
277
+ o.send :set_output_paths
278
+ expect(o.options[:output]).to be_a(Hash)
279
+ expect(o.options[:output]).to have_key(:fonts)
280
+ expect(o.options[:output]).to have_key(:css)
281
+ expect(o.options[:output]).to have_key(:preview)
282
+ end
283
+
284
+ it "should set :css and :preview to match :fonts" do
285
+ o = options
286
+ o.instance_variable_set :@options, { :output => "output/fonts" }
287
+ o.send :set_output_paths
288
+ expect(o.options[:output][:css]).to eq("output/fonts")
289
+ expect(o.options[:output][:preview]).to eq("output/fonts")
290
+ end
291
+
292
+ it "should raise an error if :fonts exists but isn't a directory" do
293
+ FileUtils.cd fixture("shared") do
294
+ o = options
295
+ o.instance_variable_set :@options, {
296
+ :config => "fontcustom.yml",
297
+ :output => "not-a-dir"
298
+ }
299
+ expect { o.send :set_output_paths }.to raise_error Fontcustom::Error, /isn't a directory/
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ context ".check_template_paths" do
306
+ it "should raise an error if a template does not exist" do
307
+ o = options
308
+ o.instance_variable_set :@options, {
309
+ :input => { :templates => fixture("shared/templates") },
310
+ :templates => %w|fake-template.txt|
311
+ }
312
+ expect { o.send :check_template_paths }.to raise_error Fontcustom::Error, /wasn't found/
313
+ end
314
+ end
315
+ end