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