vectory 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.github/workflows/release.yml +24 -0
  4. data/.gitignore +4 -0
  5. data/README.adoc +157 -1
  6. data/Rakefile +4 -0
  7. data/bin/vectory +9 -0
  8. data/emf.emf +1 -0
  9. data/lib/vectory/cli.rb +140 -0
  10. data/lib/vectory/datauri.rb +48 -0
  11. data/lib/vectory/emf.rb +31 -0
  12. data/lib/vectory/eps.rb +31 -0
  13. data/lib/vectory/file_magic.rb +53 -0
  14. data/lib/vectory/image.rb +23 -0
  15. data/lib/vectory/inkscape_converter.rb +72 -0
  16. data/lib/vectory/ps.rb +25 -0
  17. data/lib/vectory/svg.rb +27 -0
  18. data/lib/vectory/system_call.rb +49 -0
  19. data/lib/vectory/utils.rb +54 -0
  20. data/lib/vectory/vector.rb +74 -0
  21. data/lib/vectory/version.rb +1 -1
  22. data/lib/vectory.rb +34 -1
  23. data/spec/examples/emf2eps/img.emf +0 -0
  24. data/spec/examples/emf2eps/img.emf.datauri +1 -0
  25. data/spec/examples/emf2eps/img.eps +88 -0
  26. data/spec/examples/emf2ps/img.emf +0 -0
  27. data/spec/examples/emf2ps/img.ps +125 -0
  28. data/spec/examples/emf2svg/img.emf +0 -0
  29. data/spec/examples/emf2svg/img.svg +9 -0
  30. data/spec/examples/eps2emf/img.emf +0 -0
  31. data/spec/examples/eps2emf/img.eps +199 -0
  32. data/spec/examples/eps2emf/img.eps.datauri +1 -0
  33. data/spec/examples/eps2ps/img.eps +199 -0
  34. data/spec/examples/eps2ps/img.ps +549 -0
  35. data/spec/examples/eps2svg/img.eps +199 -0
  36. data/spec/examples/eps2svg/img.svg +173 -0
  37. data/spec/examples/eps_but_svg_extension.svg +199 -0
  38. data/spec/examples/img.jpg +0 -0
  39. data/spec/examples/ps2emf/img.emf +0 -0
  40. data/spec/examples/ps2emf/img.ps +549 -0
  41. data/spec/examples/ps2emf/img.ps.datauri +1 -0
  42. data/spec/examples/ps2eps/img.eps +844 -0
  43. data/spec/examples/ps2eps/img.ps +549 -0
  44. data/spec/examples/ps2svg/img.ps +549 -0
  45. data/spec/examples/ps2svg/img.svg +476 -0
  46. data/spec/examples/svg2emf/img.emf +0 -0
  47. data/spec/examples/svg2emf/img.svg +1 -0
  48. data/spec/examples/svg2emf/img.svg.datauri +1 -0
  49. data/spec/examples/svg2eps/img.eps +88 -0
  50. data/spec/examples/svg2eps/img.svg +1 -0
  51. data/spec/examples/svg2ps/img.ps +125 -0
  52. data/spec/examples/svg2ps/img.svg +1 -0
  53. data/spec/spec_helper.rb +7 -0
  54. data/spec/support/matchers.rb +39 -0
  55. data/spec/support/text_matcher.rb +63 -0
  56. data/spec/support/vectory_helper.rb +17 -0
  57. data/spec/vectory/cli_spec.rb +214 -0
  58. data/spec/vectory/datauri_spec.rb +101 -0
  59. data/spec/vectory/emf_spec.rb +38 -0
  60. data/spec/vectory/eps_spec.rb +40 -0
  61. data/spec/vectory/file_magic_spec.rb +24 -0
  62. data/spec/vectory/inkscape_converter_spec.rb +38 -0
  63. data/spec/vectory/ps_spec.rb +33 -0
  64. data/spec/vectory/svg_spec.rb +33 -0
  65. data/spec/vectory/vector_spec.rb +60 -0
  66. data/tmp/.keep +0 -0
  67. data/vectory.gemspec +10 -3
  68. metadata +163 -20
@@ -0,0 +1,125 @@
1
+ %!PS-Adobe-3.0
2
+ %%Creator: cairo 1.17.9 (https://cairographics.org)
3
+ %%CreationDate: Fri Oct 6 12:30:21 2023
4
+ %%Pages: 1
5
+ %%DocumentData: Clean7Bit
6
+ %%LanguageLevel: 2
7
+ %%DocumentMedia: 26x26mm 75 75 0 () ()
8
+ %%BoundingBox: 3 4 72 73
9
+ %%EndComments
10
+ %%BeginProlog
11
+ /languagelevel where
12
+ { pop languagelevel } { 1 } ifelse
13
+ 2 lt { /Helvetica findfont 12 scalefont setfont 50 500 moveto
14
+ (This print job requires a PostScript Language Level 2 printer.) show
15
+ showpage quit } if
16
+ /q { gsave } bind def
17
+ /Q { grestore } bind def
18
+ /cm { 6 array astore concat } bind def
19
+ /w { setlinewidth } bind def
20
+ /J { setlinecap } bind def
21
+ /j { setlinejoin } bind def
22
+ /M { setmiterlimit } bind def
23
+ /d { setdash } bind def
24
+ /m { moveto } bind def
25
+ /l { lineto } bind def
26
+ /c { curveto } bind def
27
+ /h { closepath } bind def
28
+ /re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
29
+ 0 exch rlineto 0 rlineto closepath } bind def
30
+ /S { stroke } bind def
31
+ /f { fill } bind def
32
+ /f* { eofill } bind def
33
+ /n { newpath } bind def
34
+ /W { clip } bind def
35
+ /W* { eoclip } bind def
36
+ /BT { } bind def
37
+ /ET { } bind def
38
+ /BDC { mark 3 1 roll /BDC pdfmark } bind def
39
+ /EMC { mark /EMC pdfmark } bind def
40
+ /cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
41
+ /Tj { show currentpoint cairo_store_point } bind def
42
+ /TJ {
43
+ {
44
+ dup
45
+ type /stringtype eq
46
+ { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
47
+ } forall
48
+ currentpoint cairo_store_point
49
+ } bind def
50
+ /cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
51
+ cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
52
+ /Tf { pop /cairo_font exch def /cairo_font_matrix where
53
+ { pop cairo_selectfont } if } bind def
54
+ /Td { matrix translate cairo_font_matrix matrix concatmatrix dup
55
+ /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
56
+ /cairo_font where { pop cairo_selectfont } if } bind def
57
+ /Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
58
+ cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
59
+ /g { setgray } bind def
60
+ /rg { setrgbcolor } bind def
61
+ /d1 { setcachedevice } bind def
62
+ /cairo_data_source {
63
+ CairoDataIndex CairoData length lt
64
+ { CairoData CairoDataIndex get /CairoDataIndex CairoDataIndex 1 add def }
65
+ { () } ifelse
66
+ } def
67
+ /cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def
68
+ /cairo_image { image cairo_flush_ascii85_file } def
69
+ /cairo_imagemask { imagemask cairo_flush_ascii85_file } def
70
+ /cairo_set_page_size {
71
+ % Change paper size, but only if different from previous paper size otherwise
72
+ % duplex fails. PLRM specifies a tolerance of 5 pts when matching paper size
73
+ % so we use the same when checking if the size changes.
74
+ /setpagedevice where {
75
+ pop currentpagedevice
76
+ /PageSize known {
77
+ 2 copy
78
+ currentpagedevice /PageSize get aload pop
79
+ exch 4 1 roll
80
+ sub abs 5 gt
81
+ 3 1 roll
82
+ sub abs 5 gt
83
+ or
84
+ } {
85
+ true
86
+ } ifelse
87
+ {
88
+ 2 array astore
89
+ 2 dict begin
90
+ /PageSize exch def
91
+ /ImagingBBox null def
92
+ currentdict end
93
+ setpagedevice
94
+ } {
95
+ pop pop
96
+ } ifelse
97
+ } {
98
+ pop
99
+ } ifelse
100
+ } def
101
+ %%EndProlog
102
+ %%BeginSetup
103
+ %%EndSetup
104
+ %%Page: 1 1
105
+ %%BeginPageSetup
106
+ %%PageMedia: 26x26mm
107
+ %%PageBoundingBox: 3 4 72 73
108
+ 76 76 cairo_set_page_size
109
+ %%EndPageSetup
110
+ q 3 4 69 69 rectclip
111
+ 1 0 0 -1 0 76 cm q
112
+ 0 0 0.6 rg
113
+ 71.25 37.5 m 71.25 56.141 56.141 71.25 37.5 71.25 c 18.859 71.25 3.75 56.141
114
+ 3.75 37.5 c 3.75 18.859 18.859 3.75 37.5 3.75 c 56.141 3.75 71.25 18.859
115
+ 71.25 37.5 c h
116
+ 71.25 37.5 m f
117
+ 1 g
118
+ 24.75 19.5 m 58.5 19.5 l 67.145 29.57 67.445 44.352 59.223 54.77 c 51 65.184
119
+ 36.551 68.32 24.75 62.25 c 24.75 42.75 l 44.25 42.75 l 44.25 32.25 l 24.75
120
+ 32.25 l h
121
+ 24.75 19.5 m f
122
+ Q Q
123
+ showpage
124
+ %%Trailer
125
+ %%EOF
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle fill="#009" r="45" cx="50" cy="50"/><path d="M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z" fill="#FFF"/></svg>
data/spec/spec_helper.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "vectory"
4
+ require "tmpdir"
5
+ require "rspec/matchers"
6
+ require "equivalent-xml"
7
+
8
+ Dir["./spec/support/**/*.rb"].sort.each { |file| require file }
4
9
 
5
10
  RSpec.configure do |config|
6
11
  # Enable flags like --only-failures and --next-failure
7
12
  config.example_status_persistence_file_path = ".rspec_status"
8
13
 
14
+ config.include Vectory::Helper
15
+
9
16
  # Disable RSpec exposing methods globally on `Module` and `main`
10
17
  config.disable_monkey_patching!
11
18
 
@@ -0,0 +1,39 @@
1
+ RSpec::Matchers.define :be_equivalent_eps_to do |expected|
2
+ match do |actual|
3
+ e = sub_time_and_version(expected)
4
+ a = sub_time_and_version(actual)
5
+
6
+ windows_pattern = /mswin|msys|mingw|cygwin|bccwin|wince|emc/
7
+ if RbConfig::CONFIG["host_os"].match?(windows_pattern)
8
+ Vectory.ui.debug("Using `TextMatcher`.")
9
+
10
+ Vectory::TextMatcher.new(allowed_changed_lines: 60,
11
+ allowed_changed_words_in_line: 5).match?(e, a)
12
+ else
13
+ Vectory.ui.debug("Using a default matcher.")
14
+
15
+ values_match?(e, a)
16
+ end
17
+ end
18
+
19
+ def sub_time_and_version(str)
20
+ str.sub(/%%CreationDate:(.+)$/, "%%CreationDate:")
21
+ .sub(/%%Creator: cairo(.+)$/, "%%Creator: cairo")
22
+ end
23
+
24
+ diffable
25
+ end
26
+
27
+ RSpec::Matchers.define :be_equivalent_svg_to do |expected|
28
+ match do |actual|
29
+ e = sub_unimportant(expected)
30
+ a = sub_unimportant(actual)
31
+ values_match?(e, a)
32
+ end
33
+
34
+ def sub_unimportant(str)
35
+ str.sub(/sodipodi:docname=(.+)$/, "sodipodi:docname=")
36
+ end
37
+
38
+ diffable
39
+ end
@@ -0,0 +1,63 @@
1
+ module Vectory
2
+ class TextMatcher
3
+ def initialize(allowed_changed_lines: 0,
4
+ allowed_changed_words_in_line: 0)
5
+ @allowed_changed_lines = allowed_changed_lines
6
+ @allowed_changed_words_in_line = allowed_changed_words_in_line
7
+ end
8
+
9
+ def match?(expected, actual)
10
+ expected_lines = expected.split("\n")
11
+ actual_lines = actual.split("\n")
12
+
13
+ if expected_lines.count < actual_lines.count
14
+ Vectory.ui.debug("Lines count differ.")
15
+ return false
16
+ end
17
+
18
+ lines_the_same?(expected_lines, actual_lines)
19
+ end
20
+
21
+ private
22
+
23
+ def lines_the_same?(expected_lines, actual_lines)
24
+ results = []
25
+ expected_lines
26
+ .zip(actual_lines)
27
+ .each_with_index do |(expected_line, actual_line), current_line|
28
+ results[current_line] = analyze_line(expected_line, actual_line)
29
+ end
30
+
31
+ print_results(results)
32
+
33
+ evaluate_results(results)
34
+ end
35
+
36
+ def analyze_line(expected, actual)
37
+ expected_words = expected.split
38
+ actual_words = actual.split
39
+
40
+ padded_expected_words = pad_ary(expected_words, actual_words.count)
41
+ padded_expected_words.zip(actual_words).count do |e, a|
42
+ e != a
43
+ end
44
+ end
45
+
46
+ def pad_ary(ary, target_length)
47
+ ary.fill(nil, ary.length...target_length)
48
+ end
49
+
50
+ def print_results(results)
51
+ results.each_with_index do |result, index|
52
+ unless result.zero?
53
+ Vectory.ui.debug("#{index}: #{result} different word(s).")
54
+ end
55
+ end
56
+ end
57
+
58
+ def evaluate_results(results)
59
+ results.none? { |changed| changed >= @allowed_changed_words_in_line } &&
60
+ results.count { |changed| changed > 0 } < @allowed_changed_lines
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,17 @@
1
+ require "htmlentities"
2
+ require "nokogiri"
3
+ require "tmpdir"
4
+
5
+ module Vectory
6
+ module Helper
7
+ def with_tmp_dir(&block)
8
+ Dir.mktmpdir(nil, Vectory.root_path.join("tmp/"), &block)
9
+ end
10
+
11
+ def in_tmp_dir(&block)
12
+ Dir.mktmpdir(nil, Vectory.root_path.join("tmp/")) do |dir|
13
+ Dir.chdir(dir, &block)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,214 @@
1
+ require "spec_helper"
2
+ require "vectory/cli"
3
+
4
+ RSpec.describe Vectory::CLI do
5
+ before do
6
+ # Vectory.ui.level = :debug
7
+ Vectory.ui.level = ENV["VECTORY_LOG"] || :fatal
8
+ end
9
+
10
+ describe "#convert" do
11
+ shared_examples "converter" do |format|
12
+ it "creates file of a chosen format" do
13
+ matcher = case format
14
+ when "eps", "ps" then "be_equivalent_eps_to"
15
+ when "svg" then "be_equivalent_svg_to"
16
+ else "be_equivalent_to"
17
+ end
18
+ with_tmp_dir do |dir|
19
+ output = File.join(dir, "output.#{format}")
20
+ status = described_class.start(["-f", format, "-o", output, input])
21
+ expect(status).to be Vectory::CLI::STATUS_SUCCESS
22
+ expect(File.read(output))
23
+ .to public_send(matcher, File.read(reference))
24
+ end
25
+ end
26
+ end
27
+
28
+ context "eps to ps" do
29
+ let(:input) { "spec/examples/eps2ps/img.eps" }
30
+ let(:reference) { "spec/examples/eps2ps/img.ps" }
31
+
32
+ it_behaves_like "converter", "ps"
33
+ end
34
+
35
+ context "eps to svg" do
36
+ let(:input) { "spec/examples/eps2svg/img.eps" }
37
+ let(:reference) { "spec/examples/eps2svg/img.svg" }
38
+
39
+ it_behaves_like "converter", "svg"
40
+ end
41
+
42
+ context "eps to emf" do
43
+ let(:input) { "spec/examples/eps2emf/img.eps" }
44
+ let(:reference) { "spec/examples/eps2emf/img.emf" }
45
+
46
+ it_behaves_like "converter", "emf"
47
+ end
48
+
49
+ context "ps to eps" do
50
+ let(:input) { "spec/examples/ps2eps/img.ps" }
51
+ let(:reference) { "spec/examples/ps2eps/img.eps" }
52
+
53
+ it_behaves_like "converter", "eps"
54
+ end
55
+
56
+ context "ps to emf" do
57
+ let(:input) { "spec/examples/ps2emf/img.ps" }
58
+ let(:reference) { "spec/examples/ps2emf/img.emf" }
59
+
60
+ it_behaves_like "converter", "emf"
61
+ end
62
+
63
+ context "ps to svg" do
64
+ let(:input) { "spec/examples/ps2svg/img.ps" }
65
+ let(:reference) { "spec/examples/ps2svg/img.svg" }
66
+
67
+ it_behaves_like "converter", "svg"
68
+ end
69
+
70
+ context "svg to emf" do
71
+ let(:input) { "spec/examples/svg2emf/img.svg" }
72
+ let(:reference) { "spec/examples/svg2emf/img.emf" }
73
+
74
+ it_behaves_like "converter", "emf"
75
+ end
76
+
77
+ context "svg to eps" do
78
+ let(:input) { "spec/examples/svg2eps/img.svg" }
79
+ let(:reference) { "spec/examples/svg2eps/img.eps" }
80
+
81
+ it_behaves_like "converter", "eps"
82
+ end
83
+
84
+ context "svg to ps" do
85
+ let(:input) { "spec/examples/svg2ps/img.svg" }
86
+ let(:reference) { "spec/examples/svg2ps/img.ps" }
87
+
88
+ it_behaves_like "converter", "ps"
89
+ end
90
+
91
+ context "emf to svg" do
92
+ let(:input) { "spec/examples/emf2svg/img.emf" }
93
+ let(:reference) { "spec/examples/emf2svg/img.svg" }
94
+
95
+ it_behaves_like "converter", "svg"
96
+ end
97
+
98
+ context "emf to eps" do
99
+ let(:input) { "spec/examples/emf2eps/img.emf" }
100
+ let(:reference) { "spec/examples/emf2eps/img.eps" }
101
+
102
+ it_behaves_like "converter", "eps"
103
+ end
104
+
105
+ context "emf to ps" do
106
+ let(:input) { "spec/examples/emf2ps/img.emf" }
107
+ let(:reference) { "spec/examples/emf2ps/img.ps" }
108
+
109
+ it_behaves_like "converter", "ps"
110
+ end
111
+
112
+ context "jpg to svg" do
113
+ let(:input) { "spec/examples/img.jpg" }
114
+ let(:format) { "svg" }
115
+
116
+ it "returns unsupported-input-format error" do
117
+ with_tmp_dir do |dir|
118
+ expect(Vectory.ui).to receive(:error)
119
+ .with(start_with("Could not detect input format. " \
120
+ "Please provide file of the following formats:"))
121
+
122
+ output = File.join(dir, "output.#{format}")
123
+ status = described_class.start(["-f", format, "-o", output, input])
124
+
125
+ expect(status)
126
+ .to be Vectory::CLI::STATUS_UNSUPPORTED_INPUT_FORMAT_ERROR
127
+ end
128
+ end
129
+ end
130
+
131
+ context "svg to jpg" do
132
+ let(:input) { "spec/examples/svg2emf/img.svg" }
133
+ let(:format) { "jpg" }
134
+
135
+ it "returns unsupported-output-format error" do
136
+ with_tmp_dir do |dir|
137
+ expect(Vectory.ui).to receive(:error)
138
+ .with(start_with("Unsupported output format '#{format}'. " \
139
+ "Please choose one of:"))
140
+
141
+ output = File.join(dir, "output.#{format}")
142
+ status = described_class.start(["-f", format, "-o", output, input])
143
+
144
+ expect(status)
145
+ .to be Vectory::CLI::STATUS_UNSUPPORTED_OUTPUT_FORMAT_ERROR
146
+ end
147
+ end
148
+ end
149
+
150
+ context "inkscape throws ConversionError" do
151
+ let(:input) { "spec/examples/eps2emf/img.eps" }
152
+ let(:format) { "emf" }
153
+
154
+ it "returns conversion error" do
155
+ with_tmp_dir do |dir|
156
+ expect(Vectory::InkscapeConverter.instance).to receive(:convert)
157
+ .and_raise(Vectory::ConversionError)
158
+
159
+ output = File.join(dir, "output.#{format}")
160
+ status = described_class.start(["-f", format, "-o", output, input])
161
+
162
+ expect(status).to be Vectory::CLI::STATUS_CONVERSION_ERROR
163
+ end
164
+ end
165
+ end
166
+
167
+ context "got SystemCallError" do
168
+ let(:input) { "spec/examples/eps2emf/img.eps" }
169
+ let(:format) { "emf" }
170
+
171
+ it "returns system-call error" do
172
+ with_tmp_dir do |dir|
173
+ expect_any_instance_of(Vectory::SystemCall).to receive(:call)
174
+ .and_raise(Vectory::SystemCallError)
175
+
176
+ output = File.join(dir, "output.#{format}")
177
+ status = described_class.start(["-f", format, "-o", output, input])
178
+
179
+ expect(status).to be Vectory::CLI::STATUS_SYSTEM_CALL_ERROR
180
+ end
181
+ end
182
+ end
183
+
184
+ context "got InkscapeNotFoundError" do
185
+ let(:input) { Vectory.root_path.join("spec/examples/eps2emf/img.eps") }
186
+ let(:format) { "emf" }
187
+
188
+ it "returns inkscape-not-found error" do
189
+ in_tmp_dir do
190
+ expect(Vectory::InkscapeConverter.instance)
191
+ .to receive(:convert).and_raise(Vectory::InkscapeNotFoundError)
192
+
193
+ status = described_class.start(["-f", format, input])
194
+
195
+ expect(status).to be Vectory::CLI::STATUS_INKSCAPE_NOT_FOUND_ERROR
196
+ end
197
+ end
198
+ end
199
+
200
+ context "no output option (it's not required)" do
201
+ let(:input) { Vectory.root_path.join("spec/examples/eps2emf/img.eps") }
202
+ let(:format) { "emf" }
203
+
204
+ it "uses input filename with a new extension and writes to current dir" do
205
+ in_tmp_dir do |dir|
206
+ status = described_class.start(["-f", format, input])
207
+
208
+ expect(Pathname.new(File.join(dir, "img.emf"))).to exist
209
+ expect(status).to be Vectory::CLI::STATUS_SUCCESS
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,101 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Vectory::Datauri do
4
+ describe "::from_vector" do
5
+ context "eps" do
6
+ let(:input) { "spec/examples/eps2emf/img.eps" }
7
+ let(:vector) { Vectory::Eps.from_path(input) }
8
+
9
+ it "returns datauri content" do
10
+ expect(Vectory::Datauri.from_vector(vector).content)
11
+ .to eq File.read("#{input}.datauri")
12
+ end
13
+ end
14
+
15
+ context "ps" do
16
+ let(:input) { "spec/examples/ps2emf/img.ps" }
17
+ let(:vector) { Vectory::Ps.from_path(input) }
18
+
19
+ it "returns datauri content" do
20
+ expect(Vectory::Datauri.from_vector(vector).content)
21
+ .to eq File.read("#{input}.datauri")
22
+ end
23
+ end
24
+
25
+ context "emf" do
26
+ let(:input) { "spec/examples/emf2eps/img.emf" }
27
+ let(:vector) { Vectory::Emf.from_path(input) }
28
+
29
+ it "returns datauri content" do
30
+ expect(Vectory::Datauri.from_vector(vector).content)
31
+ .to eq File.read("#{input}.datauri")
32
+ end
33
+ end
34
+
35
+ describe "svg" do
36
+ let(:input) { "spec/examples/svg2emf/img.svg" }
37
+ let(:vector) { Vectory::Svg.from_path(input) }
38
+
39
+ it "returns datauri content" do
40
+ expect(Vectory::Datauri.from_vector(vector).content)
41
+ .to eq File.read("#{input}.datauri")
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#to_vector" do
47
+ context "incorrect data" do
48
+ let(:not_a_datauri) { "123abc" }
49
+
50
+ it "raises conversion error" do
51
+ expect { Vectory::Datauri.new(not_a_datauri).to_vector }
52
+ .to raise_error(Vectory::ConversionError)
53
+ end
54
+ end
55
+
56
+ context "eps" do
57
+ let(:input) { "spec/examples/eps2emf/img.eps.datauri" }
58
+ let(:reference) { "spec/examples/eps2emf/img.eps" }
59
+
60
+ it "returns eps content" do
61
+ expect(Vectory::Datauri.from_path(input).to_vector.content)
62
+ .to eq File.read(reference)
63
+ end
64
+
65
+ it "returns Eps class" do
66
+ expect(Vectory::Datauri.from_path(input).to_vector)
67
+ .to be_kind_of(Vectory::Eps)
68
+ end
69
+ end
70
+
71
+ context "emf" do
72
+ let(:input) { "spec/examples/emf2eps/img.emf.datauri" }
73
+ let(:reference) { "spec/examples/emf2eps/img.emf" }
74
+
75
+ it "returns emf content" do
76
+ expect(Vectory::Datauri.from_path(input).to_vector.content)
77
+ .to eq File.binread(reference)
78
+ end
79
+
80
+ it "returns Emf class" do
81
+ expect(Vectory::Datauri.from_path(input).to_vector)
82
+ .to be_kind_of(Vectory::Emf)
83
+ end
84
+ end
85
+
86
+ context "svg" do
87
+ let(:input) { "spec/examples/svg2emf/img.svg.datauri" }
88
+ let(:reference) { "spec/examples/svg2emf/img.svg" }
89
+
90
+ it "returns svg content" do
91
+ expect(Vectory::Datauri.from_path(input).to_vector.content)
92
+ .to be_equivalent_to File.read(reference)
93
+ end
94
+
95
+ it "returns Svg class" do
96
+ expect(Vectory::Datauri.from_path(input).to_vector)
97
+ .to be_kind_of(Vectory::Svg)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Vectory::Emf do
4
+ describe "#to_svg" do
5
+ let(:input) { "spec/examples/emf2svg/img.emf" }
6
+ let(:reference) { "spec/examples/emf2svg/img.svg" }
7
+
8
+ it "returns svg content" do
9
+ expect(Vectory::Emf.from_path(input).to_svg.content)
10
+ .to be_equivalent_to File.read(reference)
11
+ end
12
+
13
+ it "strips the starting xml tag" do
14
+ expect(Vectory::Emf.from_path(input).to_svg.content)
15
+ .not_to start_with "<?xml"
16
+ end
17
+ end
18
+
19
+ describe "#to_eps" do
20
+ let(:input) { "spec/examples/emf2eps/img.emf" }
21
+ let(:reference) { "spec/examples/emf2eps/img.eps" }
22
+
23
+ it "returns eps content" do
24
+ expect(Vectory::Emf.from_path(input).to_eps.content)
25
+ .to be_equivalent_eps_to File.read(reference)
26
+ end
27
+ end
28
+
29
+ describe "#to_ps" do
30
+ let(:input) { "spec/examples/emf2ps/img.emf" }
31
+ let(:reference) { "spec/examples/emf2ps/img.ps" }
32
+
33
+ it "returns ps content" do
34
+ expect(Vectory::Emf.from_path(input).to_ps.content)
35
+ .to be_equivalent_eps_to File.read(reference)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Vectory::Eps do
4
+ shared_examples "converter" do |format|
5
+ it "returns content of a chosen format" do
6
+ matcher = case format
7
+ when "eps", "ps" then "be_equivalent_eps_to"
8
+ when "svg" then "be_equivalent_svg_to"
9
+ else "be_equivalent_to"
10
+ end
11
+
12
+ to_format_method = "to_#{format}"
13
+ expect(described_class.from_path(input)
14
+ .public_send(to_format_method)
15
+ .content)
16
+ .to public_send(matcher, File.read(reference))
17
+ end
18
+ end
19
+
20
+ describe "#to_ps" do
21
+ let(:input) { "spec/examples/eps2ps/img.eps" }
22
+ let(:reference) { "spec/examples/eps2ps/img.ps" }
23
+
24
+ it_behaves_like "converter", "ps"
25
+ end
26
+
27
+ describe "#to_svg" do
28
+ let(:input) { "spec/examples/eps2svg/img.eps" }
29
+ let(:reference) { "spec/examples/eps2svg/img.svg" }
30
+
31
+ it_behaves_like "converter", "svg"
32
+ end
33
+
34
+ describe "#to_emf" do
35
+ let(:input) { "spec/examples/eps2emf/img.eps" }
36
+ let(:reference) { "spec/examples/eps2emf/img.emf" }
37
+
38
+ it_behaves_like "converter", "emf"
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ require_relative "../../lib/vectory/file_magic"
4
+
5
+ RSpec.describe Vectory::FileMagic do
6
+ describe "#detect" do
7
+ references = {
8
+ "spec/examples/eps2svg/img.eps" => :eps,
9
+ "spec/examples/eps2emf/img.eps" => :eps,
10
+ "spec/examples/eps2svg/img.svg" => :svg,
11
+ "spec/examples/svg2emf/img.svg" => :svg,
12
+ "spec/examples/eps2emf/img.emf" => :emf,
13
+ "spec/examples/svg2emf/img.emf" => :emf,
14
+ }
15
+
16
+ references.each do |file, format|
17
+ context file do
18
+ it "returns #{format} format" do
19
+ expect(described_class.detect(file)).to eq format
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end