spreadsheet 1.2.6 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c8aa45d407cf5aeadbf8af753a674fdf12dab84c
4
- data.tar.gz: 32a18ad8a2d79f9eb5df62f435560502c05bfbb8
2
+ SHA256:
3
+ metadata.gz: a831e5c252775858cbdba547a3ac3228028cb6c9a56a92a77ab8fdc393de0658
4
+ data.tar.gz: 1240cd6a3b8362fa9c807c26d36fd6f8df19872e195ce09e98583597f73fa8cc
5
5
  SHA512:
6
- metadata.gz: 97f97bf780ece2ac6f25906106b1f62c1cb681cb91740620321875de8fcd2489dc97c592a4d143c52f1cd78c6f737e2b12a33fe3d6a0715ecd4f390461ffa713
7
- data.tar.gz: ddb5ee3babe8492581be775a760db74dd4f392f75773386c6a204682e051f20b56d004091741653691eba09f7e8433588945b266784747d95b5cfae4f0836180
6
+ metadata.gz: 35dd4c09f32c793bf85f4290a497eb25a298b2f59e107eb4ecebf3c37e1e6a1ee505eaec3409057c0914754ca9036fb8a4c173c8d251e448ef932e38489d0c04
7
+ data.tar.gz: b20106050e1370ced689559af16e97efc4b19abde21165091d9f4a1ebea02758625713f09e20be0ccf7b8be2075fc59567c5bf581e583a2250ccc81ee04b2e5f
data/bin/bundle ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../../Gemfile", __FILE__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_version
64
+ @bundler_version ||=
65
+ env_var_version || cli_arg_version ||
66
+ lockfile_version
67
+ end
68
+
69
+ def bundler_requirement
70
+ return "#{Gem::Requirement.default}.a" unless bundler_version
71
+
72
+ bundler_gem_version = Gem::Version.new(bundler_version)
73
+
74
+ requirement = bundler_gem_version.approximate_recommendation
75
+
76
+ return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
77
+
78
+ requirement += ".a" if bundler_gem_version.prerelease?
79
+
80
+ requirement
81
+ end
82
+
83
+ def load_bundler!
84
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
85
+
86
+ activate_bundler
87
+ end
88
+
89
+ def activate_bundler
90
+ gem_error = activation_error_handling do
91
+ gem "bundler", bundler_requirement
92
+ end
93
+ return if gem_error.nil?
94
+ require_error = activation_error_handling do
95
+ require "bundler/version"
96
+ end
97
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
98
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
99
+ exit 42
100
+ end
101
+
102
+ def activation_error_handling
103
+ yield
104
+ nil
105
+ rescue StandardError, LoadError => e
106
+ e
107
+ end
108
+ end
109
+
110
+ m.load_bundler!
111
+
112
+ if m.invoked_as_script?
113
+ load Gem.bin_path("bundler", "bundle")
114
+ end
data/bin/bundler ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'bundler' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("bundler", "bundler")
data/bin/oletool ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'oletool' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("ruby-ole", "oletool")
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/sow ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'sow' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("hoe", "sow")
data/bin/xlsopcodes CHANGED
@@ -1,18 +1,29 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'spreadsheet'
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'xlsopcodes' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
4
10
 
5
- source, target = ARGV
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
6
14
 
7
- if source.nil?
8
- puts "Usage: #{$0} <source> [<target>]"
9
- exit -1
10
- end
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
11
16
 
12
- target = target ? File.open(target, 'w') : STDOUT
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
13
25
 
14
- reader = Spreadsheet::Excel::Reader.new :print_opcodes => target
15
- reader.setup File.open(source)
26
+ require "rubygems"
27
+ require "bundler/setup"
16
28
 
17
- while tuple = reader.get_next_chunk
18
- end
29
+ load Gem.bin_path("spreadsheet", "xlsopcodes")
@@ -241,81 +241,6 @@ class Worksheet
241
241
  end
242
242
  write_multiples row, first_idx, multiples if multiples
243
243
  end
244
- def write_changes reader, endpos, sst_status
245
-
246
- ## FIXME this is not smart solution to update outline_level.
247
- # without this process, outlines in row disappear in MS Excel.
248
- @worksheet.row_count.times do |i|
249
- if @worksheet.row(i).outline_level > 0
250
- @worksheet.row(i).outline_level = @worksheet.row(i).outline_level
251
- end
252
- end
253
-
254
- reader.seek @worksheet.offset
255
- blocks = row_blocks
256
- lastpos = reader.pos
257
- offsets = {}
258
- row_offsets = []
259
- changes = @worksheet.changes
260
- @worksheet.offsets.each do |key, pair|
261
- if changes.include?(key) \
262
- || (sst_status == :complete_update && key.is_a?(Integer))
263
- offsets.store pair, key
264
- end
265
- end
266
- ## FIXME it may be smarter to simply write all rowblocks, instead of doing a
267
- # song-and-dance routine for every row...
268
- work = offsets.invert
269
- work.each do |key, (pos, len)|
270
- case key
271
- when Integer
272
- row_offsets.push [key, [pos, len]]
273
- when :dimensions
274
- row_offsets.push [-1, [pos, len]]
275
- end
276
- end
277
- row_offsets.sort!
278
- row_offsets.reverse!
279
- control = changes.size
280
- @worksheet.each do |row|
281
- key = row.idx
282
- if changes.include?(key) && !work.include?(key)
283
- row, pair = row_offsets.find do |idx, _| idx <= key end
284
- work.store key, pair
285
- end
286
- end
287
- if changes.size > control
288
- warn <<-EOS
289
- Your Worksheet was modified while it was being written. This should not happen.
290
- Please contact the author (hannes dot wyss at gmail dot com) with a sample file
291
- and minimal code that generates this warning. Thanks!
292
- EOS
293
- end
294
- work = work.sort_by do |key, (pos, len)|
295
- [pos, key.is_a?(Integer) ? key : -1]
296
- end
297
- work.each do |key, (pos, len)|
298
- @io.write reader.read(pos - lastpos) if pos > lastpos
299
- if key.is_a?(Integer)
300
- if block = blocks.find do |rows| rows.any? do |row| row.idx == key end end
301
- write_rowblock block
302
- blocks.delete block
303
- end
304
- else
305
- send "write_#{key}"
306
- end
307
- lastpos = pos + len
308
- reader.seek lastpos
309
- end
310
-
311
- # Necessary for outline (grouping) and hiding functions
312
- # but these below are not necessary to run
313
- # if [Row|Column]#hidden? = false and [Row|Column]#outline_level == 0
314
- write_colinfos
315
- write_guts
316
-
317
- @io.write reader.read(endpos - lastpos)
318
- end
319
244
  def write_colinfo bunch
320
245
  col = bunch.first
321
246
  width = col.width.to_f * 256
@@ -164,93 +164,6 @@ class Workbook < Spreadsheet::Writer
164
164
  end
165
165
  end
166
166
  ##
167
- # Copy unchanged data verbatim, adjust offsets and write new records for
168
- # changed data.
169
- def write_changes workbook, io
170
- sanitize_worksheets workbook.worksheets
171
- collect_formats workbook, :existing_document => true
172
- reader = workbook.ole
173
- sheet_data = {}
174
- sst_status, sst_total, sst_strings = complete_sst_update? workbook
175
- sst = {}
176
- sst_strings.each_with_index do |str, idx| sst.store str, idx end
177
- sheets = worksheets(workbook)
178
- positions = []
179
- newsheets = []
180
- sheets.each do |sheet|
181
- @sst[sheet] = sst
182
- pos, len = workbook.offsets[sheet.worksheet]
183
- if pos
184
- positions.push pos
185
- sheet.write_changes reader, pos + len, sst_status
186
- else
187
- newsheets.push sheet
188
- sheet.write_from_scratch
189
- end
190
- sheet_data[sheet.worksheet] = sheet.data
191
- end
192
- Ole::Storage.open io do |ole|
193
- ole.file.open 'Workbook', 'w' do |writer|
194
- reader.seek lastpos = 0
195
- workbook.offsets.select do |key, pair|
196
- workbook.changes.include? key
197
- end.sort_by do |key, (pos, _)|
198
- pos
199
- end.each do |key, (pos, len)|
200
- data = reader.read(pos - lastpos)
201
- writer.write data
202
- case key
203
- when Spreadsheet::Worksheet
204
- writer.write sheet_data[key]
205
- when :boundsheets
206
- ## boundsheets are hard to calculate. The offset below is only
207
- # correct if there are no more changes in the workbook globals
208
- # string after this.
209
- oldoffset = positions.min - len
210
- lastpos = pos + len
211
- bytechange = 0
212
- buffer = StringIO.new ''.dup
213
- if tuple = workbook.offsets[:sst]
214
- write_sst_changes workbook, buffer, writer.pos,
215
- sst_total, sst_strings
216
- pos, len = tuple
217
- if offset = workbook.offsets[:extsst]
218
- len += offset[1].to_i
219
- end
220
- bytechange = buffer.size - len
221
- write_boundsheets workbook, writer, oldoffset + bytechange
222
- reader.seek lastpos
223
- writer.write reader.read(pos - lastpos)
224
- buffer.rewind
225
- writer.write buffer.read
226
- elsif sst.empty? || workbook.biff_version < 8
227
- write_boundsheets workbook, writer, oldoffset + bytechange
228
- else
229
- write_sst workbook, buffer, writer.pos
230
- write_boundsheets workbook, writer, oldoffset + buffer.size
231
- pos = lastpos
232
- len = positions.min - lastpos
233
- if len > OPCODE_SIZE
234
- reader.seek pos
235
- writer.write reader.read(len - OPCODE_SIZE)
236
- end
237
- buffer.rewind
238
- writer.write buffer.read
239
- write_eof workbook, writer
240
- end
241
- else
242
- send "write_#{key}", workbook, writer
243
- end
244
- lastpos = [pos + len, reader.size - 1].min
245
- reader.seek lastpos
246
- end
247
- writer.write reader.read
248
- newsheets.each do |sheet|
249
- writer.write sheet.data
250
- end
251
- end
252
- end
253
- end
254
167
  def write_datemode workbook, writer
255
168
  mode = @date_base.year == 1899 ? 0x00 : 0x01
256
169
  data = [
@@ -639,8 +552,7 @@ class Workbook < Spreadsheet::Writer
639
552
  write_op writer, 0x003d, data.pack('v*')
640
553
  end
641
554
  ##
642
- # The main writer method. Calls #write_from_scratch or #write_changes
643
- # depending on the class and state of _workbook_.
555
+ # The main writer method. Calls #write_from_scratch.
644
556
  def write_workbook workbook, io
645
557
  unless workbook.is_a?(Excel::Workbook) && workbook.io
646
558
  @date_base = Date.new 1899, 12, 31
@@ -650,7 +562,8 @@ class Workbook < Spreadsheet::Writer
650
562
  if workbook.changes.empty?
651
563
  super
652
564
  else
653
- write_changes workbook, io
565
+ @date_base = Date.new 1899, 12, 31
566
+ write_from_scratch workbook, io
654
567
  end
655
568
  end
656
569
  ensure
@@ -243,84 +243,6 @@ class Worksheet
243
243
  end
244
244
  write_multiples row, first_idx, multiples if multiples
245
245
  end
246
- def write_changes reader, endpos, sst_status
247
-
248
- ## FIXME this is not smart solution to update outline_level.
249
- # without this process, outlines in row disappear in MS Excel.
250
- @worksheet.row_count.times do |i|
251
- if @worksheet.row(i).outline_level > 0
252
- @worksheet.row(i).outline_level = @worksheet.row(i).outline_level
253
- end
254
- end
255
-
256
- reader.seek @worksheet.offset
257
- blocks = row_blocks
258
- lastpos = reader.pos
259
- offsets = {}
260
- row_offsets = []
261
- changes = @worksheet.changes
262
- @worksheet.offsets.each do |key, pair|
263
- if changes.include?(key) \
264
- || (sst_status == :complete_update && key.is_a?(Integer))
265
- offsets.store pair, key
266
- end
267
- end
268
- ## FIXME it may be smarter to simply write all rowblocks, instead of doing a
269
- # song-and-dance routine for every row...
270
- work = offsets.invert
271
- work.each do |key, (pos, len)|
272
- case key
273
- when Integer
274
- row_offsets.push [key, [pos, len]]
275
- when :dimensions
276
- row_offsets.push [-1, [pos, len]]
277
- end
278
- end
279
- row_offsets.sort!
280
- row_offsets.reverse!
281
- control = changes.size
282
- @worksheet.each do |row|
283
- key = row.idx
284
- if changes.include?(key) && !work.include?(key)
285
- row, pair = row_offsets.find do |idx, _| idx <= key end
286
- work.store key, pair
287
- end
288
- end
289
- if changes.size > control
290
- warn <<-EOS
291
- Your Worksheet was modified while it was being written. This should not happen.
292
- Please contact the author (hannes dot wyss at gmail dot com) with a sample file
293
- and minimal code that generates this warning. Thanks!
294
- EOS
295
- end
296
- work = work.sort_by do |key, (pos, _)|
297
- [pos, key.is_a?(Integer) ? key : -1]
298
- end
299
- work.each do |key, (pos, len)|
300
- @io.write reader.read(pos - lastpos) if pos > lastpos
301
- if key.is_a?(Integer)
302
- if block = blocks.find do |rows| rows.any? do |row| row.idx == key end end
303
- write_rowblock block
304
- blocks.delete block
305
- end
306
- else
307
- send "write_#{key}"
308
- end
309
- lastpos = pos + len
310
- reader.seek lastpos
311
- end
312
-
313
- # Necessary for outline (grouping) and hiding functions
314
- # but these below are not necessary to run
315
- # if [Row|Column]#hidden? = false and [Row|Column]#outline_level == 0
316
- write_merged_cells
317
- write_pagesetup
318
- write_margins
319
- write_colinfos
320
- write_guts
321
-
322
- @io.write reader.read(endpos - lastpos)
323
- end
324
246
  def write_colinfo bunch
325
247
  col = bunch.first
326
248
  width = col.width.to_f * 256
@@ -1,11 +1,5 @@
1
1
  require 'spreadsheet'
2
2
 
3
- warn <<-EOS
4
- [DEPRECATED] By requiring 'spreadsheet/excel' you are loading a Compatibility
5
- layer which provides a drop-in replacement for Spreadsheet::Excel
6
- versions <= 0.3.5.1. This code will be removed in Spreadsheet
7
- version 1.0.0
8
- EOS
9
3
  ##
10
4
  # Spreadsheet::Excel Compatibility Layer.
11
5
  # Drop-in replacement for Spreadsheet::Excel version <= 0.3.5.1
@@ -3,5 +3,5 @@
3
3
  module Spreadsheet
4
4
  ##
5
5
  # The version of Spreadsheet you are using.
6
- VERSION = '1.2.6'
6
+ VERSION = '1.3.0'
7
7
  end
@@ -49,7 +49,7 @@ module Spreadsheet
49
49
  :right => 0.75,
50
50
  :bottom => 1
51
51
  }
52
- @name = opts[:name] || 'Worksheet'
52
+ @name = sanitize_invalid_characters(opts[:name] || 'Worksheet')
53
53
  @workbook = opts[:workbook]
54
54
  @rows = []
55
55
  @columns = []
@@ -233,7 +233,7 @@ module Spreadsheet
233
233
  res
234
234
  end
235
235
  def << cells=[]
236
- insert_row last_row_index + 1, cells
236
+ insert_row @rows.size, cells
237
237
  end
238
238
  def inspect
239
239
  names = instance_variables
@@ -366,6 +366,9 @@ module Spreadsheet
366
366
  end
367
367
 
368
368
  private
369
+ def sanitize_invalid_characters(name) # :nodoc:
370
+ name.gsub(Regexp.new('[\\\/\*\?\:\[\]]'.encode(Spreadsheet.client_encoding)), '_')
371
+ end
369
372
  def index_of_first ary # :nodoc:
370
373
  return unless ary
371
374
  ary.index(ary.find do |elm| elm end)
Binary file
Binary file
data/test/integration.rb CHANGED
@@ -1401,6 +1401,30 @@ module Spreadsheet
1401
1401
  assert_equal(:visible, book2.worksheet(1).visibility)
1402
1402
  end
1403
1403
 
1404
+ def test_append_and_reopen
1405
+ filename = path = File.join @var, 'test.xls'
1406
+ sheet_name = 'Test Sheet'
1407
+
1408
+ # Create excel
1409
+ excel = Spreadsheet::Workbook.new(filename)
1410
+ sheet = excel.create_worksheet(name: sheet_name)
1411
+ sheet.row(1).replace ['Data']
1412
+ excel.write(filename)
1413
+
1414
+ # Append something
1415
+ excel = Spreadsheet.open(filename, 'a+')
1416
+ sheet = excel.worksheet(sheet_name)
1417
+ sheet.row(2).replace ['Data2']
1418
+ filename = "test2.xls"
1419
+ excel.write(filename)
1420
+
1421
+ # Reopen
1422
+ excel = Spreadsheet.open filename
1423
+ sheet = excel.worksheet sheet_name
1424
+ ensure
1425
+ File.delete filename if File.exist? filename
1426
+ end
1427
+
1404
1428
  def test_text_drawing
1405
1429
  path = File.join @data, 'test_text_drawing.xls'
1406
1430
  book = Spreadsheet.open path
data/test/suite.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require 'rubygems'
4
4
  require 'bundler'
5
5
  require 'find'
6
+ require 'simplecov'
7
+ SimpleCov.start
6
8
 
7
9
  $VERBOSE = true
8
10
 
data/test/worksheet.rb CHANGED
@@ -138,5 +138,10 @@ module Spreadsheet
138
138
  end
139
139
  end
140
140
 
141
+ def test_name
142
+ worksheet = Worksheet.new(name: '\a/b*c?d:e[f]')
143
+ assert_equal '_a_b_c_d_e_f_', worksheet.name
144
+ end
145
+
141
146
  end
142
147
  end