vectory 0.1.0 → 0.2.0

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 (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