oddb2xml 1.8.9 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDkwNTVmNTM3ZWRmMzAzODBjNjRiZDE2YzFjNTQxZGM1NTgzYTBlNA==
5
+ data.tar.gz: !binary |-
6
+ Yzk0NWQ0ZWJhZWRmMmQ0ODZhMDQxMWQzNWY2NGYxZjliZWFhNGVlYg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmY5MmMzYWRjNDc3OTFlM2E4ZmVhYjVkZmExYTVjOGM2NDM3YTBlNTU1MGQz
10
+ MGQ2Zjk3MDgyMDJhMmFlNDViMDI0NGNmYTI0ZTE4NzNiMDE4N2ViMWEyZjZk
11
+ NGNmYmVlYzcwZTMwOGQ3NWY0NjBjYjI4NDVkMGFkMzFmZjFmNGU=
12
+ data.tar.gz: !binary |-
13
+ MDAzMzVjODcxZjY2NGU1YjYyMGVkZDI4MjI5NzhlZjY5YzQzOTViMTQ1Mjc4
14
+ MTM4NTEzOTY3ZmIwMzgzZmQzNDQyNTY0YzlmNzUzYTVlMDBiNGFiODc1MjA3
15
+ YzMzZmQ5NjY2ZTQ3YTg5NzE2MDA5NDc4YjQ4YjNjOWMzZTExMGQ=
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oddb2xml (1.8.9)
4
+ oddb2xml (1.9.0)
5
5
  archive-tar-minitar (~> 0.5.2)
6
6
  mechanize (~> 2.5.1)
7
7
  nokogiri (~> 1.5.10)
@@ -1,4 +1,10 @@
1
- === 1.8.9 / upcoming
1
+ === 1.9.0 / 12.01.2015
2
+
3
+ * Fixed adding prices from ZurRose if -f dat -p zurrose given
4
+ * Reorganized switches
5
+ * Added option -I x to add x percent to public prices for non-SL items
6
+
7
+ === 1.8.9 / 05.01.2015
2
8
 
3
9
  * Added option -e x to add x percent to public prices for non-SL items
4
10
 
@@ -7,77 +7,21 @@ $:.unshift root.join('lib') if $0 == __FILE__
7
7
 
8
8
  require 'optparse'
9
9
  require 'oddb2xml'
10
+ require 'oddb2xml/options'
10
11
 
11
- def help
12
- <<EOS
13
- #$0 ver.#{Oddb2xml::VERSION}
14
- Usage:
15
- oddb2xml [option]
16
- produced files are found under data
17
- -a T, --append=T Additional target. T, only 'nonpharma' is available.
18
- -c F, --compress=F Compress format F. {tar.gz|zip}
19
- -e --extended pharma, non-pharma plus prices and non-pharma from zurrose. Products without EAN-Code will also be listed.
20
- -f F, --format=F File format F, default is xml. {xml|dat}
21
- If F is given, -o option is ignored.
22
- -i I, --include=I Include target option for 'dat' format. only 'ean14' is available.
23
- 'xml' format includes always ean14 records.
24
- -o O, --option=O Optional output. O, only 'fi' is available.
25
- -p P, --price=P Price source (transfer.dat). P, only 'zurrose' is available.
26
- -t S, --tag-suffix=S XML tag suffix S. Default is none. [A-z0-9]
27
- If S is given, it is also used as prefix of filename.
28
- -x N, --context=N context N {product|address}. product is default.
29
-
30
- For debugging purposes
31
- --skip-download skips downloading files it the file is already under downloads.
32
- Downloaded files are saved under downloads
33
- --log log important actions
34
- -h, --help Show this help message.
35
- EOS
36
- end
37
-
38
- parser = OptionParser.new
39
- opts = {
40
- :fi => false,
41
- :adr => false,
42
- :nonpharma => false,
43
- :extended => false,
44
- :compress_ext => nil,
45
- :format => :xml,
46
- :tag_suffix => nil,
47
- :debug => false,
48
- :ean14 => false,
49
- :skip_download=> false,
50
- :log => false,
51
- :percent => 0,
52
- }
53
-
54
- parser.on('-a v', '--append v', /^nonpharma$/) {|v| opts[:nonpharma] = true }
55
- parser.on('-c v', '--compress v', /^tar\.gz|zip$/){|v| opts[:compress_ext] = v }
56
- parser.on('-e [x]', '--extended [x]') {|v| opts[:extended] = true
57
- opts[:nonpharma] = :true
58
- opts[:price] = :zurrose
59
- opts[:percent] = v ? v.to_i : 0
60
- }
61
- parser.on('-f v', '--format v', /^xml|dat$/) {|v| opts[:format] = v.intern }
62
- parser.on('-o v', '--option v', /^fi$/) {|v| opts[:fi] = true }
63
- parser.on('-i v', '--include v', /^ean14$/) {|v| opts[:ean14] = true }
64
- parser.on('-t v', '--tag-suffix v', /^[A-z0-9]*$/i) {|v| opts[:tag_suffix] = v.upcase }
65
- parser.on('-x v', '--context v', /^addr(ess)*$/i){|v| opts[:address] = true }
66
- parser.on('-p v', '--price v', /^zurrose$/) {|v| opts[:price] = v.intern }
67
- parser.on('--skip-download') {|v| opts[:skip_download] = true }
68
- parser.on('--log') {|v| opts[:log] = :true }
69
- parser.on_tail('-h', '--help') { puts help; exit }
12
+ options = Oddb2xml::Options.new
70
13
 
71
14
  args = ARGV.dup
72
15
  begin
73
- parser.parse!(args)
16
+ options.parser.parse!(args)
74
17
  rescue OptionParser::MissingArgument,
75
18
  OptionParser::InvalidArgument,
76
19
  OptionParser::InvalidOption
77
- puts help
20
+ puts Oddb2xml::Options.help
78
21
  exit
79
22
  end
80
23
 
24
+ opts = options.opts
81
25
  # TEMP
82
26
  if path = args.first
83
27
  opts[:transfer_dat] = path
@@ -736,17 +736,14 @@ module Oddb2xml
736
736
  xml.ARTPRI {
737
737
  xml.VDAT Time.parse(datetime).strftime("%d.%m.%Y")
738
738
  xml.PTYP "ZURROSE"
739
- xml.PRICE info_zur_rose[:price]
739
+ price = info_zur_rose[:price]
740
+ price = (price.to_f*(1 + (@options[:percent].to_f/100))).round_by(0.05).round(2) if @options[:percent] != nil
741
+ xml.PRICE price
740
742
  }
741
743
  xml.ARTPRI {
742
744
  xml.VDAT Time.parse(datetime).strftime("%d.%m.%Y")
743
745
  xml.PTYP "ZURROSEPUB"
744
- price = info_zur_rose[:pub_price]
745
- if @options[:percent] != nil
746
- price = (price.to_f*(1 + (@options[:percent].to_f/100))).round_by(0.05).round(2)
747
- else
748
- end
749
- xml.PRICE price
746
+ xml.PRICE info_zur_rose[:pub_price]
750
747
  }
751
748
  end
752
749
  #xml.ARTMIG {
@@ -1033,9 +1030,20 @@ module Oddb2xml
1033
1030
  (pac ? pac[:name_de].to_s : '') +
1034
1031
  (idx[:additional_desc] ? idx[:additional_desc] : '')
1035
1032
  ).gsub(/"/, '')
1033
+ price_doctor = pac ? format_price(pac[:prices][:exf_price][:price]).to_s : nil
1034
+ price_public = pac ? format_price(pac[:prices][:pub_price][:price]).to_s : nil
1035
+ if @infos_zur_rose[ean]
1036
+ price_public ||= sprintf('%06i', ((@infos_zur_rose[ean][:pub_price].to_f)*100).to_i)
1037
+ if @infos_zur_rose[ean][:pub_price]
1038
+ price_doctor ||= sprintf('%06i', ((@infos_zur_rose[ean][:price].to_f)*100).to_i) if @infos_zur_rose[ean][:price]
1039
+ if @options[:percent] != nil
1040
+ price_doctor = sprintf('%06i', (price_doctor.to_f*(1 + (@options[:percent].to_f/100))).round_by(0.05).round(2))
1041
+ end
1042
+ end
1043
+ end
1036
1044
  row << format_name(abez)
1037
- row << "%#{DAT_LEN[:PRMO]}s" % (pac ? format_price(pac[:prices][:exf_price][:price].to_s) : ('0' * DAT_LEN[:PRMO]))
1038
- row << "%#{DAT_LEN[:PRPU]}s" % (pac ? format_price(pac[:prices][:pub_price][:price].to_s) : ('0' * DAT_LEN[:PRPU]))
1045
+ row << "%#{DAT_LEN[:PRMO]}s" % (price_doctor ? price_doctor.to_s : ('0' * DAT_LEN[:PRMO]))
1046
+ row << "%#{DAT_LEN[:PRPU]}s" % (price_public ? price_public.to_s : ('0' * DAT_LEN[:PRPU]))
1039
1047
  row << "%#{DAT_LEN[:CKZL]}s" % if (@lppvs[ean])
1040
1048
  '2'
1041
1049
  elsif pac # sl_entry
@@ -5,6 +5,7 @@ require 'oddb2xml/builder'
5
5
  require 'oddb2xml/downloader'
6
6
  require 'oddb2xml/extractor'
7
7
  require 'oddb2xml/compressor'
8
+ require 'oddb2xml/options'
8
9
  require 'oddb2xml/util'
9
10
  require 'rubyXL'
10
11
 
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ require 'optparse'
3
+
4
+ module Oddb2xml
5
+
6
+ class Options
7
+ attr_reader :parser, :opts
8
+ def Options.default_opts
9
+ {
10
+ :fi => false,
11
+ :adr => false,
12
+ :address => false,
13
+ :nonpharma => false,
14
+ :extended => false,
15
+ :compress_ext => nil,
16
+ :format => :xml,
17
+ :tag_suffix => nil,
18
+ :debug => false,
19
+ :ean14 => false,
20
+ :skip_download=> false,
21
+ :log => false,
22
+ :percent => 0,
23
+ }
24
+ end
25
+ def Options.help
26
+ <<EOS
27
+ #$0 ver.#{Oddb2xml::VERSION}
28
+ Usage:
29
+ oddb2xml [option]
30
+ produced files are found under data
31
+ -a, --append Additional target nonpharma
32
+ -c F, --compress=F Compress format F. {tar.gz|zip}
33
+ -e --extended pharma, non-pharma plus prices and non-pharma from zurrose. Products without EAN-Code will also be listed.
34
+ -f F, --format=F File format F, default is xml. {xml|dat}
35
+ If F is given, -o option is ignored.
36
+ -I x, --increment=x Increment price by x percent. Forces -f dat -p zurrose.
37
+ -i, --include Include target option for ean14 for 'dat' format.
38
+ 'xml' format includes always ean14 records.
39
+ -o, --option Optional fachinfo output.
40
+ -p, --price Price source (transfer.dat) from ZurRose
41
+ -t S, --tag-suffix=S XML tag suffix S. Default is none. [A-z0-9]
42
+ If S is given, it is also used as prefix of filename.
43
+ -x N, --context=N context N {product|address}. product is default.
44
+
45
+ For debugging purposes
46
+ --skip-download skips downloading files it the file is already under downloads.
47
+ Downloaded files are saved under downloads
48
+ --log log important actions
49
+ -h, --help Show this help message.
50
+ EOS
51
+ end
52
+ def initialize
53
+ @parser = OptionParser.new
54
+ @opts = Options.default_opts
55
+ @parser.on('-a', '--append') {|v| @opts[:nonpharma] = true }
56
+ @parser.on('-c v', '--compress v', /^tar\.gz|zip$/){|v| @opts[:compress_ext] = v }
57
+ @parser.on('-e', '--extended') {|v| @opts[:extended] = true
58
+ @opts[:nonpharma] = true
59
+ @opts[:price] = :zurrose
60
+ }
61
+ @parser.on('-f v', '--format v', /^xml|dat$/) {|v| @opts[:format] = v.intern }
62
+ @parser.on('-o', '--option') {|v| @opts[:fi] = true }
63
+ @parser.on('-I v', '--increment v', /^[0-9]+$/) {|v| @opts[:percent] = v ? v.to_i : 0
64
+ @opts[:price] = :zurrose
65
+ }
66
+ @parser.on('-i', '--include') {|v| @opts[:ean14] = true }
67
+ @parser.on('-t v', '--tag-suffix v', /^[A-z0-9]*$/i) {|v| @opts[:tag_suffix] = v.upcase }
68
+ @parser.on('-x v', '--context v', /^addr(ess)*$/i){|v| @opts[:address] = true }
69
+ @parser.on('-p', '--price') {|v| @opts[:price] = :zurrose }
70
+ @parser.on('--skip-download') {|v| @opts[:skip_download] = true }
71
+ @parser.on('--log') {|v| @opts[:log] = true }
72
+ @parser.on_tail('-h', '--help') { puts Options.help; exit }
73
+ end
74
+ end
75
+ end
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "1.8.9"
2
+ VERSION = "1.9.0"
3
3
  end
@@ -44,14 +44,16 @@ describe Oddb2xml::Builder do
44
44
  after(:each) do
45
45
  Dir.chdir @savedDir if @savedDir and File.directory?(@savedDir)
46
46
  end
47
- if false
47
+
48
48
  context 'XSD-generation: ' do
49
49
  let(:cli) do
50
50
  opts = {}
51
51
  @oddb2xml_xsd = File.expand_path(File.join(File.dirname(__FILE__), '..', 'oddb2xml.xsd'))
52
52
  @article_xml = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_article.xml'))
53
53
  @product_xml = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_product.xml'))
54
- Oddb2xml::Cli.new(opts)
54
+ options = Oddb2xml::Options.new
55
+ options.parser.parse!([])
56
+ Oddb2xml::Cli.new(options.opts)
55
57
  end
56
58
 
57
59
  it 'should return true when validating xml against oddb2xml.xsd' do
@@ -74,8 +76,9 @@ if false
74
76
 
75
77
  context 'when no option is given' do
76
78
  let(:cli) do
77
- opts = {}
78
- Oddb2xml::Cli.new(opts)
79
+ options = Oddb2xml::Options.new
80
+ options.parser.parse!([])
81
+ Oddb2xml::Cli.new(options.opts)
79
82
  end
80
83
 
81
84
  it 'should pass validating via oddb2xml.xsd' do
@@ -121,10 +124,9 @@ if false
121
124
 
122
125
  context 'when -f dat is given' do
123
126
  let(:cli) do
124
- opts = {
125
- :format => :dat,
126
- }
127
- Oddb2xml::Cli.new(opts)
127
+ options = Oddb2xml::Options.new
128
+ options.parser.parse!('-f dat'.split(' '))
129
+ Oddb2xml::Cli.new(options.opts)
128
130
  end
129
131
 
130
132
  it 'should contain the correct values fo CMUT from zurrose_transfer.dat' do
@@ -136,17 +138,16 @@ if false
136
138
  oddb_dat.should match(/^..2/), "should have a record with '2' in CMUT field"
137
139
  oddb_dat.should match(/^..3/), "should have a record with '3' in CMUT field"
138
140
  oddb_dat.should match(/1115819012LEVETIRACETAM DESITIN Filmtabl 250 mg 30 Stk/), "should have Desitin"
141
+ IO.readlines(dat_filename).each{ |line| check_article(line, false, false) }
139
142
  # oddb_dat.should match(/^..1/), "should have a record with '1' in CMUT field" # we have no
140
143
  end
141
144
  end
142
145
 
143
- context 'when -a nonpharma -f dat is given' do
146
+ context 'when --append -f dat is given' do
144
147
  let(:cli) do
145
- opts = {
146
- :nonpharma => 'true',
147
- :format => :dat,
148
- }
149
- Oddb2xml::Cli.new(opts)
148
+ options = Oddb2xml::Options.new
149
+ options.parser.parse!('--append -f dat'.split(' '))
150
+ Oddb2xml::Cli.new(options.opts)
150
151
  end
151
152
 
152
153
  it 'should generate a valid oddb_with_migel.dat' do
@@ -168,18 +169,57 @@ if false
168
169
  oddb_dat.should match(/76806206900842/), "should match EAN of Desitin"
169
170
  end
170
171
  end
172
+
173
+ context 'when --append -I 80 -e is given' do
174
+ let(:cli) do
175
+ options = Oddb2xml::Options.new
176
+ options.parser.parse!('--append -I 80 -e'.split(' '))
177
+ Oddb2xml::Cli.new(options.opts)
178
+ end
179
+
180
+ it 'should contain the correct prices' do
181
+ cleanup_directories_before_run
182
+ res = buildr_capture(:stdout){ cli.run }
183
+ @article_xml = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_article.xml'))
184
+ File.exists?(@article_xml).should eq true
185
+ article_xml = IO.read(@article_xml)
186
+ product_filename = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_product.xml'))
187
+ File.exists?(product_filename).should eq true
188
+ doc = REXML::Document.new File.new(@article_xml)
189
+ unless /1\.8\.7/.match(RUBY_VERSION)
190
+ price_zur_rose = XPath.match( doc, "//ART[DSCRD='SOFRADEX Gtt Auric']/ARTPRI[PTYP='ZURROSE']/PRICE").first.text
191
+ price_zur_rose.should eq '12.9'
192
+ price_zur_rose_pub = XPath.match( doc, "//ART[DSCRD='SOFRADEX Gtt Auric']/ARTPRI[PTYP='ZURROSEPUB']/PRICE").first.text
193
+ price_zur_rose_pub.should eq '15.45'
194
+ end
195
+ end
196
+ end
197
+
171
198
  context 'when option -e is given' do
172
199
  let(:cli) do
173
- opts = {
174
- :extended => :true,
175
- :nonpharma => :true,
176
- :price => :zurrose,
177
- :log => true,
178
- :skip_download => true,
179
- }
180
- Oddb2xml::Cli.new(opts)
200
+ options = Oddb2xml::Options.new
201
+ options.parser.parse!('-e'.split(' '))
202
+ Oddb2xml::Cli.new(options.opts)
181
203
  end
182
204
 
205
+ it 'should contain the correct prices' do
206
+ cleanup_directories_before_run
207
+ res = buildr_capture(:stdout){ cli.run }
208
+ @article_xml = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_article.xml'))
209
+ File.exists?(@article_xml).should eq true
210
+ article_xml = IO.read(@article_xml)
211
+ product_filename = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_product.xml'))
212
+ File.exists?(product_filename).should eq true
213
+ doc = REXML::Document.new File.new(@article_xml)
214
+ unless /1\.8\.7/.match(RUBY_VERSION)
215
+ price_zur_rose = XPath.match( doc, "//ART[DSCRD='SOFRADEX Gtt Auric']/ARTPRI[PTYP='ZURROSE']/PRICE").first.text
216
+ price_zur_rose.should eq '7.2'
217
+ price_zur_rose_pub = XPath.match( doc, "//ART[DSCRD='SOFRADEX Gtt Auric']/ARTPRI[PTYP='ZURROSEPUB']/PRICE").first.text
218
+ price_zur_rose_pub.should eq '15.45'
219
+ end
220
+ end
221
+
222
+
183
223
  def checkItemForRefdata(doc, pharmacode, isRefdata)
184
224
  article = XPath.match( doc, "//ART[PHAR=#{pharmacode.to_s}]").first
185
225
  name = article.elements['DSCRD'].text
@@ -378,23 +418,18 @@ if false
378
418
  checkItemForSALECD(doc, "0598003", 'I') # SOFRADEX
379
419
  end
380
420
  end
381
- end
421
+
382
422
  context 'testing -e option' do
383
423
  let(:cli) do
384
- opts = {
385
- :extended => :true,
386
- :skip_download => true,
387
- }
388
- Oddb2xml::Cli.new(opts)
424
+ options = Oddb2xml::Options.new
425
+ options.parser.parse!('-e --skip-download'.split(' '))
426
+ Oddb2xml::Cli.new(options.opts)
389
427
  end
390
428
 
391
- let(:cli_e80) do
392
- opts = {
393
- :extended => :true,
394
- :percent => 80,
395
- :skip_download => true,
396
- }
397
- Oddb2xml::Cli.new(opts)
429
+ let(:cli_I80) do
430
+ options = Oddb2xml::Options.new
431
+ options.parser.parse!('-e -I 80 --skip-download'.split(' '))
432
+ Oddb2xml::Cli.new(options.opts)
398
433
  end
399
434
  search_path_rose = "//ART[PHAR=0023722]/ARTPRI[PTYP='ZURROSE']/PRICE"
400
435
  search_path_pub = "//ART[PHAR=0023722]/ARTPRI[PTYP='ZURROSEPUB']/PRICE"
@@ -420,8 +455,8 @@ end
420
455
  XPath.match( doc, search_path_desitin).first.text.should eq '27.8'
421
456
  end
422
457
 
423
- it 'should add 80 percent to zur_rose pubbprice if -e 80' do
424
- res = buildr_capture(:stdout){ cli_e80.run }
458
+ it 'should add 80 percent to zur_rose pubbprice if -I 80' do
459
+ res = buildr_capture(:stdout){ cli_I80.run }
425
460
  @article_xml = File.expand_path(File.join(Oddb2xml::WorkDir, 'oddb_article.xml'))
426
461
  File.exists?(@article_xml).should eq true
427
462
  FileUtils.cp(@article_xml, File.join(Oddb2xml::WorkDir, 'tst-e80.xml'))
@@ -432,15 +467,82 @@ end
432
467
  refdata = article.elements['REF_DATA'].text
433
468
  smno = article.elements['SMNO'] ? article.elements['SMNO'].text : 'nil'
434
469
  XPath.match( doc, search_path_rose).size.should eq 1
435
- XPath.match( doc, search_path_rose).first.text.should eq '9.85'
436
- price = 15.20 # This is the zurrose pub price.
437
- price2 = (price*1.8).round_by(0.05).round(2) # Our price should be now 80% higher
470
+ XPath.match( doc, search_path_rose).first.text.should eq '17.75'
438
471
  XPath.match( doc, search_path_pub).first.text
439
- XPath.match( doc, search_path_pub).first.text.to_f.should eq price2
472
+ XPath.match( doc, search_path_pub).first.text.should eq '15.20'
440
473
  XPath.match( doc, search_path_desitin).first.text.should eq '27.8'
441
474
  # sl-entries have a PPUB price, but no ZURROSEPUB, and vice versa
442
475
  XPath.match( doc, "//ART[PHAR=0023722]/ARTPRI[PTYP='PPUB']").size.should eq 0
443
476
  XPath.match( doc, "//ART[SMNO='62069008']/ARTPRI[PTYP='ZURROSEPUB']").size.should eq 0
444
477
  end
445
478
  end
479
+
480
+ def check_article(line, check_prices = false, add_80_percents=0)
481
+ name = line[10..59]
482
+ ckzl = line[72]
483
+ ciks = line[75]
484
+ price_doctor = line[60..65].to_i
485
+ price_public = line[66..71].to_i
486
+ puts "check_article: #{price_doctor} #{price_public} CKZL is #{ckzl} CIKS is #{ciks} name #{name} " if $VERBOSE
487
+ return unless check_prices
488
+ if /11116999473TC/.match(line)
489
+ price_doctor.should eq 16455
490
+ line[60..65].should eq '016455'
491
+ ckzl.should eq '1'
492
+ price_public.should eq 20530 # this is a SL-product. Therefore we may not have a price increase
493
+ line[66..71].should eq '020530' # the dat format requires leading zeroes and not point
494
+ end
495
+ if /1130598003SOFRADEX/.match(line)
496
+ price_public.should eq 1545 # this is a non SL-product, but no price increase was requested
497
+ line[66..71].should eq '001545' # the dat format requires leading zeroes and not point
498
+
499
+ ckzl.should eq '3'
500
+ if add_80_percents
501
+ price_doctor.should eq 1292 # = 1545*1.8 this is a non SL-product. Therefore we must increase its price as requsted
502
+ line[60..65].should eq '001292' # dat format requires leading zeroes and not poin
503
+ else
504
+ price_doctor.should eq 718 # this is a non SL-product, but no price increase was requested
505
+ line[60..65].should eq '000718' # the dat format requires leading zeroes and not point
506
+ end
507
+ end
508
+ end
509
+
510
+ context 'when -f dat -p is given' do
511
+ let(:cli) do
512
+ options = Oddb2xml::Options.new
513
+ options.parser.parse!('-f dat -p'.split(' '))
514
+ Oddb2xml::Cli.new(options.opts)
515
+ end
516
+
517
+ it 'should contain the correct values fo CMUT from zurrose_transfer.dat' do
518
+ res = buildr_capture(:stdout){ cli.run }
519
+ res.should match(/products/)
520
+ dat_filename = File.join(Oddb2xml::WorkDir, 'oddb.dat')
521
+ File.exists?(dat_filename).should eq true
522
+ oddb_dat = IO.read(dat_filename)
523
+ oddb_dat.should match(/^..2/), "should have a record with '2' in CMUT field"
524
+ oddb_dat.should match(/^..3/), "should have a record with '3' in CMUT field"
525
+ oddb_dat.should match(/1115819012LEVETIRACETAM DESITIN Filmtabl 250 mg 30 Stk/), "should have Desitin"
526
+ IO.readlines(dat_filename).each{ |line| check_article(line, true, false) }
527
+ # oddb_dat.should match(/^..1/), "should have a record with '1' in CMUT field" # we have no
528
+ end
529
+ end
530
+
531
+ context 'when -f dat -I 80 is given' do
532
+ let(:cli) do
533
+ options = Oddb2xml::Options.new
534
+ options.parser.parse!('-f dat -I 80'.split(' '))
535
+ Oddb2xml::Cli.new(options.opts)
536
+ end
537
+ it 'should contain the corect prices' do
538
+ res = buildr_capture(:stdout){ cli.run }
539
+ res.should match(/products/)
540
+ dat_filename = File.join(Oddb2xml::WorkDir, 'oddb.dat')
541
+ File.exists?(dat_filename).should eq true
542
+ oddb_dat = IO.read(dat_filename)
543
+ oddb_dat_lines = IO.readlines(dat_filename)
544
+ IO.readlines(dat_filename).each{ |line| check_article(line, true, true) }
545
+ end
546
+ end
547
+
446
548
  end
@@ -58,14 +58,9 @@ describe Oddb2xml::Cli do
58
58
  end
59
59
  context 'when -c tar.gz option is given' do
60
60
  let(:cli) do
61
- opts = {
62
- :compress_ext => 'tar.gz',
63
- :nonpharma => false,
64
- :fi => false,
65
- :address => false,
66
- :tag_suffix => nil,
67
- }
68
- Oddb2xml::Cli.new(opts)
61
+ options = Oddb2xml::Options.new
62
+ options.parser.parse!('-c tar.gz'.split(' '))
63
+ Oddb2xml::Cli.new(options.opts)
69
64
  end
70
65
  it_behaves_like 'any interface for product'
71
66
  it 'should have compress option' do
@@ -85,14 +80,9 @@ describe Oddb2xml::Cli do
85
80
  end
86
81
  context 'when -c zip option is given' do
87
82
  let(:cli) do
88
- opts = {
89
- :compress_ext => 'zip',
90
- :nonpharma => false,
91
- :fi => false,
92
- :address => false,
93
- :tag_suffix => nil,
94
- }
95
- Oddb2xml::Cli.new(opts)
83
+ options = Oddb2xml::Options.new
84
+ options.parser.parse!('-c zip'.split(' '))
85
+ Oddb2xml::Cli.new(options.opts)
96
86
  end
97
87
  it_behaves_like 'any interface for product'
98
88
  it 'should have compress option' do
@@ -113,14 +103,9 @@ describe Oddb2xml::Cli do
113
103
  end
114
104
  context 'when -a nonpharma option is given' do
115
105
  let(:cli) do
116
- opts = {
117
- :compress_ext => nil,
118
- :nonpharma => true,
119
- :fi => false,
120
- :address => false,
121
- :tag_suffix => nil,
122
- }
123
- Oddb2xml::Cli.new(opts)
106
+ options = Oddb2xml::Options.new
107
+ options.parser.parse!('-a nonpharma'.split(' '))
108
+ Oddb2xml::Cli.new(options.opts)
124
109
  end
125
110
  it_behaves_like 'any interface for product'
126
111
  it 'should have nonpharma option' do
@@ -148,14 +133,9 @@ describe Oddb2xml::Cli do
148
133
  end
149
134
  context 'when -t _swiss option is given' do
150
135
  let(:cli) do
151
- opts = {
152
- :compress_ext => nil,
153
- :nonpharma => false,
154
- :fi => false,
155
- :address => false,
156
- :tag_suffix => '_swiss'.upcase,
157
- }
158
- Oddb2xml::Cli.new(opts)
136
+ options = Oddb2xml::Options.new
137
+ options.parser.parse!('-t _swiss'.split(' '))
138
+ Oddb2xml::Cli.new(options.opts)
159
139
  end
160
140
  it_behaves_like 'any interface for product'
161
141
  it 'should have tag_suffix option' do
@@ -183,14 +163,9 @@ describe Oddb2xml::Cli do
183
163
  end
184
164
  context 'when -o fi option is given' do
185
165
  let(:cli) do
186
- opts = {
187
- :compress_ext => nil,
188
- :nonpharma => false,
189
- :fi => true,
190
- :address => false,
191
- :tag_suffix => nil,
192
- }
193
- Oddb2xml::Cli.new(opts)
166
+ options = Oddb2xml::Options.new
167
+ options.parser.parse!('-o fi'.split(' '))
168
+ Oddb2xml::Cli.new(options.opts)
194
169
  end
195
170
  it_behaves_like 'any interface for product'
196
171
  it 'should have nonpharma option' do
@@ -220,14 +195,9 @@ describe Oddb2xml::Cli do
220
195
  end
221
196
  context 'when -x address option is given' do
222
197
  let(:cli) do
223
- opts = {
224
- :compress_ext => nil,
225
- :nonpharma => false,
226
- :fi => false,
227
- :address => true,
228
- :tag_suffix => nil,
229
- }
230
- Oddb2xml::Cli.new(opts)
198
+ options = Oddb2xml::Options.new
199
+ options.parser.parse!('-x address'.split(' '))
200
+ Oddb2xml::Cli.new(options.opts)
231
201
  end
232
202
  it_behaves_like 'any interface for address'
233
203
  it 'should have address option' do
@@ -0,0 +1,187 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "#{Dir.pwd}/lib/oddb2xml/options"
5
+ module Kernel
6
+ def cli_capture(stream)
7
+ begin
8
+ stream = stream.to_s
9
+ eval "$#{stream} = StringIO.new"
10
+ yield
11
+ result = eval("$#{stream}").string
12
+ ensure
13
+ eval "$#{stream} = #{stream.upcase}"
14
+ end
15
+ result
16
+ end
17
+ end
18
+
19
+ describe Oddb2xml::Options do
20
+ include ServerMockHelper
21
+ Default_opts = {
22
+ :fi => false,
23
+ :adr => false,
24
+ :address => false,
25
+ :nonpharma => false,
26
+ :extended => false,
27
+ :compress_ext => nil,
28
+ :format => :xml,
29
+ :tag_suffix => nil,
30
+ :debug => false,
31
+ :ean14 => false,
32
+ :skip_download=> false,
33
+ :log => false,
34
+ :percent => 0,
35
+ }
36
+ context 'when default_opts' do
37
+ specify { expect(Oddb2xml::Options.default_opts).to eq Default_opts }
38
+ end
39
+
40
+ context 'when no options is passed' do
41
+ options = Oddb2xml::Options.new
42
+ specify { expect(options.opts).to eq Default_opts }
43
+ end
44
+
45
+ context 'when -c tar.gz option is given' do
46
+ options = Oddb2xml::Options.new
47
+ options.parser.parse!('-c tar.gz'.split(' '))
48
+ specify { expect(options.opts[:compress_ext]).to eq('tar.gz') }
49
+ expected = Default_opts.clone
50
+ expected[:compress_ext] = 'tar.gz'
51
+ specify { expect(options.opts).to eq expected }
52
+ end
53
+
54
+ context 'when -c tar.gz option --skip-download is given' do
55
+ options = Oddb2xml::Options.new
56
+ options.parser.parse!('-c tar.gz --skip-download'.split(' '))
57
+ expected = Default_opts.clone
58
+ expected[:compress_ext] = 'tar.gz'
59
+ expected[:skip_download] = true
60
+ specify { expect(options.opts).to eq expected }
61
+ end
62
+
63
+ context 'when -c tar.gz option --skip-download is given' do
64
+ options = Oddb2xml::Options.new
65
+ options.parser.parse!('-c tar.gz --skip-download'.split(' '))
66
+ expected = Default_opts.clone
67
+ expected[:compress_ext] = 'tar.gz'
68
+ expected[:skip_download] = true
69
+ specify { expect(options.opts).to eq expected }
70
+ end
71
+
72
+ context 'when -a is given' do
73
+ options = Oddb2xml::Options.new
74
+ options.parser.parse!('-a'.split(' '))
75
+ expected = Default_opts.clone
76
+ expected[:nonpharma] = true
77
+ specify { expect(options.opts).to eq expected }
78
+ end
79
+
80
+ context 'when --append is given' do
81
+ options = Oddb2xml::Options.new
82
+ options.parser.parse!('--append '.split(' '))
83
+ expected = Default_opts.clone
84
+ expected[:nonpharma] = true
85
+ specify { expect(options.opts).to eq expected }
86
+ end
87
+
88
+ context 'when -e is given' do
89
+ options = Oddb2xml::Options.new
90
+ options.parser.parse!('-e'.split(' '))
91
+ expected = Default_opts.clone
92
+ expected[:extended] = true
93
+ expected[:nonpharma] = true
94
+ expected[:price] = :zurrose
95
+ specify { expect(options.opts).to eq expected }
96
+ end
97
+
98
+ context 'when -e is given' do
99
+ options = Oddb2xml::Options.new
100
+ options.parser.parse!('-e'.split(' '))
101
+ expected = Default_opts.clone
102
+ expected[:extended] = true
103
+ expected[:nonpharma] = true
104
+ expected[:price] = :zurrose
105
+ specify { expect(options.opts).to eq expected }
106
+ end
107
+
108
+ context 'when -e -I 80 is given' do
109
+ options = Oddb2xml::Options.new
110
+ options.parser.parse!('-e -I 80'.split(' '))
111
+ expected = Default_opts.clone
112
+ expected[:extended] = true
113
+ expected[:nonpharma] = true
114
+ expected[:price] = :zurrose
115
+ expected[:percent] = 80
116
+ specify { expect(options.opts).to eq expected }
117
+ end
118
+
119
+ context 'when -f dat is given' do
120
+ options = Oddb2xml::Options.new
121
+ options.parser.parse!('-f dat'.split(' '))
122
+ expected = Default_opts.clone
123
+ expected[:format] = :dat
124
+ specify { expect(options.opts).to eq expected }
125
+ end
126
+
127
+ context 'when -f dat -I 80 is given' do
128
+ options = Oddb2xml::Options.new
129
+ options.parser.parse!('-f dat -I 80'.split(' '))
130
+ expected = Default_opts.clone
131
+ expected[:format] = :dat
132
+ expected[:percent] = 80
133
+ expected[:price] = :zurrose
134
+ specify { expect(options.opts).to eq expected }
135
+ end
136
+
137
+ context 'when -I 80 is given' do
138
+ options = Oddb2xml::Options.new
139
+ options.parser.parse!('-I 80'.split(' '))
140
+ expected = Default_opts.clone
141
+ expected[:percent] = 80
142
+ expected[:price] = :zurrose
143
+ specify { expect(options.opts).to eq expected }
144
+ end
145
+
146
+ context 'when -o is given' do
147
+ options = Oddb2xml::Options.new
148
+ options.parser.parse!('-o'.split(' '))
149
+ expected = Default_opts.clone
150
+ expected[:fi] = true
151
+ specify { expect(options.opts).to eq expected }
152
+ end
153
+
154
+ context 'when -i ean14 is given' do
155
+ options = Oddb2xml::Options.new
156
+ options.parser.parse!('-i ean14'.split(' '))
157
+ expected = Default_opts.clone
158
+ expected[:ean14] = true
159
+ specify { expect(options.opts).to eq expected }
160
+ end
161
+
162
+ context 'when -x addr is given' do
163
+ options = Oddb2xml::Options.new
164
+ options.parser.parse!('-x addr'.split(' '))
165
+ expected = Default_opts.clone
166
+ expected[:address] = true
167
+ specify { expect(options.opts).to eq expected }
168
+ end
169
+
170
+ context 'when -p zurrose is given' do
171
+ options = Oddb2xml::Options.new
172
+ options.parser.parse!('-p zurrose'.split(' '))
173
+ expected = Default_opts.clone
174
+ expected[:price] = :zurrose
175
+ specify { expect(options.opts).to eq expected }
176
+ end
177
+
178
+ context 'when -o fi --log is given' do
179
+ options = Oddb2xml::Options.new
180
+ options.parser.parse!('-o fi --log'.split(' '))
181
+ expected = Default_opts.clone
182
+ expected[:fi] = true
183
+ expected[:log] = true
184
+ specify { expect(options.opts).to eq expected }
185
+ end
186
+ end
187
+
@@ -49,9 +49,10 @@ prepare_for_gem_test
49
49
  # unfortunately it returns a very common name
50
50
  unless 'localhost.localdomain'.eql?(Socket.gethostbyname(Socket.gethostname).first)
51
51
  test_one_call('oddb2xml -e')
52
- test_one_call('oddb2xml -e80')
53
- test_one_call('oddb2xml -f dat -a nonpharma')
54
- test_one_call('oddb2xml -a nonpharma')
52
+ test_one_call('oddb2xml -e -I80')
53
+ test_one_call('oddb2xml -f dat --append -I 80')
54
+ test_one_call('oddb2xml -f dat --append')
55
+ test_one_call('oddb2xml --append')
55
56
  end
56
57
  test_one_call('oddb2xml -t md -c tar.gz')
57
58
  test_one_call('oddb2xml -f xml')
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oddb2xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.9
5
- prerelease:
4
+ version: 1.9.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Yasuhiro Asaka, Zeno R.R. Davatz
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rubyzip
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: archive-tar-minitar
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: mechanize
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: nokogiri
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: savon
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ~>
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ~>
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: spreadsheet
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ~>
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ~>
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: rubyXL
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ~>
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ~>
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: sax-machine
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ~>
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :runtime
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ~>
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: bundler
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -158,7 +139,6 @@ dependencies:
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: rake
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
143
  - - ! '>='
164
144
  - !ruby/object:Gem::Version
@@ -166,7 +146,6 @@ dependencies:
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
150
  - - ! '>='
172
151
  - !ruby/object:Gem::Version
@@ -174,7 +153,6 @@ dependencies:
174
153
  - !ruby/object:Gem::Dependency
175
154
  name: rspec
176
155
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
156
  requirements:
179
157
  - - ! '>='
180
158
  - !ruby/object:Gem::Version
@@ -182,7 +160,6 @@ dependencies:
182
160
  type: :development
183
161
  prerelease: false
184
162
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
163
  requirements:
187
164
  - - ! '>='
188
165
  - !ruby/object:Gem::Version
@@ -190,7 +167,6 @@ dependencies:
190
167
  - !ruby/object:Gem::Dependency
191
168
  name: webmock
192
169
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
170
  requirements:
195
171
  - - ! '>='
196
172
  - !ruby/object:Gem::Version
@@ -198,7 +174,6 @@ dependencies:
198
174
  type: :development
199
175
  prerelease: false
200
176
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
177
  requirements:
203
178
  - - ! '>='
204
179
  - !ruby/object:Gem::Version
@@ -206,7 +181,6 @@ dependencies:
206
181
  - !ruby/object:Gem::Dependency
207
182
  name: rdoc
208
183
  requirement: !ruby/object:Gem::Requirement
209
- none: false
210
184
  requirements:
211
185
  - - ! '>='
212
186
  - !ruby/object:Gem::Version
@@ -214,7 +188,6 @@ dependencies:
214
188
  type: :development
215
189
  prerelease: false
216
190
  version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
191
  requirements:
219
192
  - - ! '>='
220
193
  - !ruby/object:Gem::Version
@@ -244,6 +217,7 @@ files:
244
217
  - lib/oddb2xml/compressor.rb
245
218
  - lib/oddb2xml/downloader.rb
246
219
  - lib/oddb2xml/extractor.rb
220
+ - lib/oddb2xml/options.rb
247
221
  - lib/oddb2xml/util.rb
248
222
  - lib/oddb2xml/version.rb
249
223
  - lib/oddb2xml/xml_definitions.rb
@@ -295,6 +269,7 @@ files:
295
269
  - spec/data/zurrose_transfer.dat
296
270
  - spec/downloader_spec.rb
297
271
  - spec/extractor_spec.rb
272
+ - spec/options_spec.rb
298
273
  - spec/spec_helper.rb
299
274
  - test_options.rb
300
275
  - tools/cacert.pem
@@ -303,27 +278,26 @@ files:
303
278
  homepage: https://github.com/zdavatz/oddb2xml
304
279
  licenses:
305
280
  - GPL-v2
281
+ metadata: {}
306
282
  post_install_message:
307
283
  rdoc_options: []
308
284
  require_paths:
309
285
  - lib
310
286
  required_ruby_version: !ruby/object:Gem::Requirement
311
- none: false
312
287
  requirements:
313
288
  - - ! '>='
314
289
  - !ruby/object:Gem::Version
315
290
  version: '0'
316
291
  required_rubygems_version: !ruby/object:Gem::Requirement
317
- none: false
318
292
  requirements:
319
293
  - - ! '>='
320
294
  - !ruby/object:Gem::Version
321
295
  version: '0'
322
296
  requirements: []
323
297
  rubyforge_project:
324
- rubygems_version: 1.8.25
298
+ rubygems_version: 2.3.0
325
299
  signing_key:
326
- specification_version: 3
300
+ specification_version: 4
327
301
  summary: oddb2xml creates xml files.
328
302
  test_files:
329
303
  - spec/builder_spec.rb
@@ -372,4 +346,5 @@ test_files:
372
346
  - spec/data/zurrose_transfer.dat
373
347
  - spec/downloader_spec.rb
374
348
  - spec/extractor_spec.rb
349
+ - spec/options_spec.rb
375
350
  - spec/spec_helper.rb