vectory 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -1
- data/.github/workflows/release.yml +24 -0
- data/.gitignore +4 -0
- data/README.adoc +157 -1
- data/Rakefile +4 -0
- data/bin/vectory +9 -0
- data/emf.emf +1 -0
- data/lib/vectory/cli.rb +140 -0
- data/lib/vectory/datauri.rb +48 -0
- data/lib/vectory/emf.rb +31 -0
- data/lib/vectory/eps.rb +31 -0
- data/lib/vectory/file_magic.rb +53 -0
- data/lib/vectory/image.rb +23 -0
- data/lib/vectory/inkscape_converter.rb +72 -0
- data/lib/vectory/ps.rb +25 -0
- data/lib/vectory/svg.rb +27 -0
- data/lib/vectory/system_call.rb +49 -0
- data/lib/vectory/utils.rb +54 -0
- data/lib/vectory/vector.rb +74 -0
- data/lib/vectory/version.rb +1 -1
- data/lib/vectory.rb +34 -1
- data/spec/examples/emf2eps/img.emf +0 -0
- data/spec/examples/emf2eps/img.emf.datauri +1 -0
- data/spec/examples/emf2eps/img.eps +88 -0
- data/spec/examples/emf2ps/img.emf +0 -0
- data/spec/examples/emf2ps/img.ps +125 -0
- data/spec/examples/emf2svg/img.emf +0 -0
- data/spec/examples/emf2svg/img.svg +9 -0
- data/spec/examples/eps2emf/img.emf +0 -0
- data/spec/examples/eps2emf/img.eps +199 -0
- data/spec/examples/eps2emf/img.eps.datauri +1 -0
- data/spec/examples/eps2ps/img.eps +199 -0
- data/spec/examples/eps2ps/img.ps +549 -0
- data/spec/examples/eps2svg/img.eps +199 -0
- data/spec/examples/eps2svg/img.svg +173 -0
- data/spec/examples/eps_but_svg_extension.svg +199 -0
- data/spec/examples/img.jpg +0 -0
- data/spec/examples/ps2emf/img.emf +0 -0
- data/spec/examples/ps2emf/img.ps +549 -0
- data/spec/examples/ps2emf/img.ps.datauri +1 -0
- data/spec/examples/ps2eps/img.eps +844 -0
- data/spec/examples/ps2eps/img.ps +549 -0
- data/spec/examples/ps2svg/img.ps +549 -0
- data/spec/examples/ps2svg/img.svg +476 -0
- data/spec/examples/svg2emf/img.emf +0 -0
- data/spec/examples/svg2emf/img.svg +1 -0
- data/spec/examples/svg2emf/img.svg.datauri +1 -0
- data/spec/examples/svg2eps/img.eps +88 -0
- data/spec/examples/svg2eps/img.svg +1 -0
- data/spec/examples/svg2ps/img.ps +125 -0
- data/spec/examples/svg2ps/img.svg +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/matchers.rb +39 -0
- data/spec/support/text_matcher.rb +63 -0
- data/spec/support/vectory_helper.rb +17 -0
- data/spec/vectory/cli_spec.rb +214 -0
- data/spec/vectory/datauri_spec.rb +101 -0
- data/spec/vectory/emf_spec.rb +38 -0
- data/spec/vectory/eps_spec.rb +40 -0
- data/spec/vectory/file_magic_spec.rb +24 -0
- data/spec/vectory/inkscape_converter_spec.rb +38 -0
- data/spec/vectory/ps_spec.rb +33 -0
- data/spec/vectory/svg_spec.rb +33 -0
- data/spec/vectory/vector_spec.rb +60 -0
- data/tmp/.keep +0 -0
- data/vectory.gemspec +10 -3
- 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
|