robust_excel_ole 0.3.4 → 0.3.5
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.
- data/README.rdoc +73 -26
- data/README_detail.rdoc +92 -27
- data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
- data/examples/edit_sheets/example_concating.rb +12 -12
- data/examples/edit_sheets/example_copying.rb +47 -0
- data/examples/edit_sheets/example_expanding.rb +17 -26
- data/examples/edit_sheets/example_naming.rb +13 -10
- data/examples/edit_sheets/example_ranges.rb +2 -2
- data/examples/edit_sheets/example_saving.rb +8 -14
- data/examples/open_save_close/example_control_to_excel.rb +1 -1
- data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
- data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
- data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
- data/examples/open_save_close/example_if_unsaved_forget.rb +4 -4
- data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
- data/examples/open_save_close/example_read_only.rb +1 -1
- data/examples/open_save_close/example_rename_cells.rb +1 -13
- data/examples/open_save_close/example_simple.rb +1 -1
- data/examples/open_save_close/example_unobtrusively.rb +3 -3
- data/lib/robust_excel_ole.rb +81 -2
- data/lib/robust_excel_ole/book.rb +171 -118
- data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
- data/lib/robust_excel_ole/excel.rb +153 -24
- data/lib/robust_excel_ole/range.rb +2 -2
- data/lib/robust_excel_ole/sheet.rb +84 -35
- data/lib/robust_excel_ole/version.rb +1 -1
- data/reo.bat +3 -0
- data/spec/book_close_spec.rb +179 -0
- data/spec/book_misc_spec.rb +365 -0
- data/spec/book_open_spec.rb +793 -0
- data/spec/book_save_spec.rb +257 -0
- data/spec/book_sheet_spec.rb +160 -0
- data/spec/book_spec.rb +145 -1533
- data/spec/book_subclass_spec.rb +50 -0
- data/spec/book_unobtr_spec.rb +950 -0
- data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
- data/spec/cell_spec.rb +6 -6
- data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
- data/spec/data/different_workbook.xls +0 -0
- data/spec/data/workbook.xls +0 -0
- data/spec/data/workbook.xlsm +0 -0
- data/spec/data/workbook.xlsx +0 -0
- data/spec/data/workbook_linked.xlsm +0 -0
- data/spec/data/workbook_linked_sub.xlsm +0 -0
- data/spec/excel_spec.rb +204 -5
- data/spec/range_spec.rb +6 -6
- data/spec/sheet_spec.rb +122 -34
- metadata +18 -8
- data/spec/data/workbook_connected_sub.xlsm +0 -0
@@ -0,0 +1,793 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), './spec_helper')
|
4
|
+
|
5
|
+
|
6
|
+
$VERBOSE = nil
|
7
|
+
|
8
|
+
include RobustExcelOle
|
9
|
+
|
10
|
+
describe Book do
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
excel = Excel.new(:reuse => true)
|
14
|
+
open_books = excel == nil ? 0 : excel.Workbooks.Count
|
15
|
+
puts "*** open books *** : #{open_books}" if open_books > 0
|
16
|
+
Excel.close_all
|
17
|
+
end
|
18
|
+
|
19
|
+
before do
|
20
|
+
@dir = create_tmpdir
|
21
|
+
@simple_file = @dir + '/workbook.xls'
|
22
|
+
@simple_save_file = @dir + '/workbook_save.xls'
|
23
|
+
@different_file = @dir + '/different_workbook.xls'
|
24
|
+
@simple_file_other_path = @dir + '/more_data/workbook.xls'
|
25
|
+
@another_simple_file = @dir + '/another_workbook.xls'
|
26
|
+
@linked_file = @dir + '/workbook_linked.xlsm'
|
27
|
+
@simple_file_xlsm = @dir + '/workbook.xls'
|
28
|
+
@simple_file_xlsx = @dir + '/workbook.xlsx'
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
Excel.close_all
|
33
|
+
rm_tmp(@dir)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "open" do
|
37
|
+
|
38
|
+
context "with standard options" do
|
39
|
+
before do
|
40
|
+
@book = Book.open(@simple_file)
|
41
|
+
end
|
42
|
+
|
43
|
+
after do
|
44
|
+
@book.close
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should say that it lives" do
|
48
|
+
@book.should be_alive
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with identity transperence" do
|
53
|
+
|
54
|
+
before do
|
55
|
+
@book = Book.open(@simple_file)
|
56
|
+
end
|
57
|
+
|
58
|
+
after do
|
59
|
+
@book.close
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should yield identical Book objects for identical Excel books" do
|
63
|
+
book2 = Book.open(@simple_file)
|
64
|
+
book2.should === @book
|
65
|
+
book2.close
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should yield different Book objects for different Excel books" do
|
69
|
+
book2 = Book.open(@different_file)
|
70
|
+
book2.should_not === @book
|
71
|
+
book2.close
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should yield different Book objects when opened the same file in different Excel instances" do
|
75
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
76
|
+
book2.should_not === @book
|
77
|
+
book2.close
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should yield identical Book objects for identical Excel books when reopening" do
|
81
|
+
@book.should be_alive
|
82
|
+
@book.close
|
83
|
+
@book.should_not be_alive
|
84
|
+
book2 = Book.open(@simple_file)
|
85
|
+
book2.should === @book
|
86
|
+
book2.should be_alive
|
87
|
+
book2.close
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should yield identical Book objects when reopening and the Excel is closed" do
|
91
|
+
@book.should be_alive
|
92
|
+
@book.close
|
93
|
+
Excel.close_all
|
94
|
+
book2 = Book.open(@simple_file)
|
95
|
+
book2.should be_alive
|
96
|
+
book2.should === @book
|
97
|
+
book2.close
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should yield different Book objects when reopening in a new Excel" do
|
101
|
+
@book.should be_alive
|
102
|
+
old_excel = @book.excel
|
103
|
+
@book.close
|
104
|
+
@book.should_not be_alive
|
105
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
106
|
+
book2.should_not === @book
|
107
|
+
book2.should be_alive
|
108
|
+
book2.excel.should_not == old_excel
|
109
|
+
book2.close
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should yield different Book objects when reopening in a new given Excel instance" do
|
113
|
+
old_excel = @book.excel
|
114
|
+
new_excel = Excel.new(:reuse => false)
|
115
|
+
@book.close
|
116
|
+
@book.should_not be_alive
|
117
|
+
book2 = Book.open(@simple_file, :force_excel => new_excel)
|
118
|
+
book2.should_not === @book
|
119
|
+
book2.should be_alive
|
120
|
+
book2.excel.should == new_excel
|
121
|
+
book2.excel.should_not == old_excel
|
122
|
+
book2.close
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should yield identical Book objects when reopening in the old excel" do
|
126
|
+
old_excel = @book.excel
|
127
|
+
new_excel = Excel.new(:reuse => false)
|
128
|
+
@book.close
|
129
|
+
@book.should_not be_alive
|
130
|
+
book2 = Book.open(@simple_file, :force_excel => old_excel)
|
131
|
+
book2.should === @book
|
132
|
+
book2.should be_alive
|
133
|
+
book2.excel.should == old_excel
|
134
|
+
@book.should be_alive
|
135
|
+
book2.close
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with :force_excel" do
|
141
|
+
|
142
|
+
before do
|
143
|
+
@book = Book.open(@simple_file)
|
144
|
+
end
|
145
|
+
|
146
|
+
after do
|
147
|
+
@book.close rescue nil
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should open in a new Excel" do
|
151
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
152
|
+
book2.should be_alive
|
153
|
+
book2.should be_a Book
|
154
|
+
book2.excel.should_not == @book.excel
|
155
|
+
book2.should_not == @book
|
156
|
+
@book.Readonly.should be_false
|
157
|
+
book2.Readonly.should be_true
|
158
|
+
book2.close
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should open in a given Excel, not provide identity transparency, because old book readonly, new book writable" do
|
162
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
163
|
+
book2.excel.should_not == @book.excel
|
164
|
+
book3 = Book.open(@simple_file, :force_excel => :new)
|
165
|
+
book3.excel.should_not == book2.excel
|
166
|
+
book3.excel.should_not == @book.excel
|
167
|
+
book2.close
|
168
|
+
book4 = Book.open(@simple_file, :force_excel => book2.excel)
|
169
|
+
book4.should be_alive
|
170
|
+
book4.should be_a Book
|
171
|
+
book4.excel.should == book2.excel
|
172
|
+
book4.Readonly.should == true
|
173
|
+
book4.should_not == book2
|
174
|
+
book4.close
|
175
|
+
book5 = Book.open(@simple_file, :force_excel => book2)
|
176
|
+
book5.should be_alive
|
177
|
+
book5.should be_a Book
|
178
|
+
book5.excel.should == book2.excel
|
179
|
+
book5.Readonly.should == true
|
180
|
+
book5.should_not == book2
|
181
|
+
book5.close
|
182
|
+
book3.close
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should open in a given Excel, provide identity transparency, because book can be readonly, such that the old and the new book are readonly" do
|
186
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
187
|
+
book2.excel.should_not == @book.excel
|
188
|
+
book3 = Book.open(@simple_file, :force_excel => :new)
|
189
|
+
book3.excel.should_not == book2.excel
|
190
|
+
book3.excel.should_not == @book.excel
|
191
|
+
book2.close
|
192
|
+
book3.close
|
193
|
+
@book.close
|
194
|
+
book4 = Book.open(@simple_file, :force_excel => book2.excel, :read_only => true)
|
195
|
+
book4.should be_alive
|
196
|
+
book4.should be_a Book
|
197
|
+
book4.excel.should == book2.excel
|
198
|
+
book4.ReadOnly.should be_true
|
199
|
+
book4.should == book2
|
200
|
+
book4.close
|
201
|
+
book5 = Book.open(@simple_file, :force_excel => book2, :read_only => true)
|
202
|
+
book5.should be_alive
|
203
|
+
book5.should be_a Book
|
204
|
+
book5.excel.should == book2.excel
|
205
|
+
book5.ReadOnly.should be_true
|
206
|
+
book5.should == book2
|
207
|
+
book5.close
|
208
|
+
book3.close
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should open in a given Excel, provide identity transparency, because book can be readonly, such that the old and the new book are readonly" do
|
212
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
213
|
+
book2.excel.should_not == @book.excel
|
214
|
+
book2.close
|
215
|
+
@book.close
|
216
|
+
book4 = Book.open(@simple_file, :force_excel => book2, :read_only => true)
|
217
|
+
book4.should be_alive
|
218
|
+
book4.should be_a Book
|
219
|
+
book4.excel.should == book2.excel
|
220
|
+
book4.ReadOnly.should be_true
|
221
|
+
book4.should == book2
|
222
|
+
book4.close
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should raise an error if no Excel or Book is given" do
|
226
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
227
|
+
book2.excel.should_not == @book.excel
|
228
|
+
book2.close
|
229
|
+
@book.close
|
230
|
+
expect{
|
231
|
+
Book.open(@simple_file, :force_excel => :book)
|
232
|
+
}.to raise_error(ExcelErrorOpen, "provided instance is neither an Excel nor a Book")
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should do force_excel even if both force_ and default_excel is given" do
|
236
|
+
book2 = Book.open(@simple_file, :default_excel => @book.excel, :force_excel => :new)
|
237
|
+
book2.should be_alive
|
238
|
+
book2.should be_a Book
|
239
|
+
book2.excel.should_not == @book.excel
|
240
|
+
book2.should_not == @book
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "with another :force_excel" do
|
245
|
+
it "should do force_excel even if both force_ and default_excel is given" do
|
246
|
+
book2 = Book.open(@simple_file, :force_excel => nil)
|
247
|
+
book2.should be_alive
|
248
|
+
book2.should be_a Book
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "with :default_excel" do
|
253
|
+
|
254
|
+
before do
|
255
|
+
excel = Excel.new(:reuse => false)
|
256
|
+
@book = Book.open(@simple_file)
|
257
|
+
end
|
258
|
+
|
259
|
+
after do
|
260
|
+
@book.close rescue nil
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should use the open book" do
|
264
|
+
book2 = Book.open(@simple_file, :default_excel => :reuse)
|
265
|
+
book2.excel.should == @book.excel
|
266
|
+
book2.should be_alive
|
267
|
+
book2.should be_a Book
|
268
|
+
book2.should == @book
|
269
|
+
book2.close
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should reopen the book in the excel instance where it was opened before" do
|
273
|
+
excel = Excel.new(:reuse => false)
|
274
|
+
@book.close
|
275
|
+
book2 = Book.open(@simple_file)
|
276
|
+
book2.should be_alive
|
277
|
+
book2.should be_a Book
|
278
|
+
book2.excel.should == @book.excel
|
279
|
+
book2.excel.should_not == excel
|
280
|
+
book2.filename.should == @book.filename
|
281
|
+
@book.should be_alive
|
282
|
+
book2.should == @book
|
283
|
+
book2.close
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should reopen a book in a new Excel if all Excel instances are closed" do
|
287
|
+
excel = Excel.new(:reuse => false)
|
288
|
+
excel2 = @book.excel
|
289
|
+
fn = @book.filename
|
290
|
+
@book.close
|
291
|
+
Excel.close_all
|
292
|
+
book2 = Book.open(@simple_file, :default_excel => :reuse)
|
293
|
+
book2.should be_alive
|
294
|
+
book2.should be_a Book
|
295
|
+
book2.filename.should == fn
|
296
|
+
@book.should be_alive
|
297
|
+
book2.should == @book
|
298
|
+
book2.close
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should reopen a book in the first opened Excel if the old Excel is closed" do
|
302
|
+
excel = @book.excel
|
303
|
+
Excel.close_all
|
304
|
+
new_excel = Excel.new(:reuse => false)
|
305
|
+
new_excel2 = Excel.new(:reuse => false)
|
306
|
+
book2 = Book.open(@simple_file, :default_excel => :reuse)
|
307
|
+
book2.should be_alive
|
308
|
+
book2.should be_a Book
|
309
|
+
book2.excel.should_not == excel
|
310
|
+
book2.excel.should_not == new_excel2
|
311
|
+
book2.excel.should == new_excel
|
312
|
+
@book.should be_alive
|
313
|
+
book2.should == @book
|
314
|
+
book2.close
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should reopen a book in the first opened excel, if the book cannot be reopened" do
|
318
|
+
@book.close
|
319
|
+
Excel.close_all
|
320
|
+
excel1 = Excel.new(:reuse => false)
|
321
|
+
excel2 = Excel.new(:reuse => false)
|
322
|
+
book2 = Book.open(@different_file, :default_excel => :reuse)
|
323
|
+
book2.should be_alive
|
324
|
+
book2.should be_a Book
|
325
|
+
book2.excel.should == excel1
|
326
|
+
book2.excel.should_not == excel2
|
327
|
+
book2.close
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should reopen a book in the excel instance where it was opened most recently" do
|
331
|
+
book2 = Book.open(@simple_file, :force_excel => :new)
|
332
|
+
@book.close
|
333
|
+
book2.close
|
334
|
+
book3 = Book.open(@simple_file)
|
335
|
+
book2.should be_alive
|
336
|
+
book2.should be_a Book
|
337
|
+
book3.excel.should == book2.excel
|
338
|
+
book3.excel.should_not == @book.excel
|
339
|
+
book3.should == book2
|
340
|
+
book3.should_not == @book
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should open a new excel, if the book cannot be reopened" do
|
344
|
+
@book.close
|
345
|
+
new_excel = Excel.new(:reuse => false)
|
346
|
+
book2 = Book.open(@different_file, :default_excel => :new)
|
347
|
+
book2.should be_alive
|
348
|
+
book2.should be_a Book
|
349
|
+
book2.excel.should_not == new_excel
|
350
|
+
book2.excel.should_not == @book.excel
|
351
|
+
book2.close
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should open a given excel, if the book cannot be reopened" do
|
355
|
+
@book.close
|
356
|
+
new_excel = Excel.new(:reuse => false)
|
357
|
+
book2 = Book.open(@different_file, :default_excel => @book.excel)
|
358
|
+
book2.should be_alive
|
359
|
+
book2.should be_a Book
|
360
|
+
book2.excel.should_not == new_excel
|
361
|
+
book2.excel.should == @book.excel
|
362
|
+
book2.close
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should open a given excel, if the book cannot be reopened" do
|
366
|
+
@book.close
|
367
|
+
new_excel = Excel.new(:reuse => false)
|
368
|
+
book2 = Book.open(@different_file, :default_excel => @book)
|
369
|
+
book2.should be_alive
|
370
|
+
book2.should be_a Book
|
371
|
+
book2.excel.should_not == new_excel
|
372
|
+
book2.excel.should == @book.excel
|
373
|
+
book2.close
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should reuse an open book by default" do
|
377
|
+
book2 = Book.open(@simple_file)
|
378
|
+
book2.excel.should == @book.excel
|
379
|
+
book2.should == @book
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
context "with :if_unsaved" do
|
384
|
+
|
385
|
+
before do
|
386
|
+
@book = Book.open(@simple_file)
|
387
|
+
@sheet = @book[0]
|
388
|
+
@book.add_sheet(@sheet, :as => 'a_name')
|
389
|
+
end
|
390
|
+
|
391
|
+
after do
|
392
|
+
@book.close(:if_unsaved => :forget)
|
393
|
+
@new_book.close rescue nil
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should raise an error, if :if_unsaved is :raise" do
|
397
|
+
expect {
|
398
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :raise)
|
399
|
+
}.to raise_error(ExcelErrorOpen, "book is already open but not saved (#{File.basename(@simple_file)})")
|
400
|
+
end
|
401
|
+
|
402
|
+
it "should let the book open, if :if_unsaved is :accept" do
|
403
|
+
expect {
|
404
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :accept)
|
405
|
+
}.to_not raise_error
|
406
|
+
@book.should be_alive
|
407
|
+
@new_book.should be_alive
|
408
|
+
@new_book.should == @book
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should open book and close old book, if :if_unsaved is :forget" do
|
412
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :forget)
|
413
|
+
@book.should_not be_alive
|
414
|
+
@new_book.should be_alive
|
415
|
+
@new_book.filename.downcase.should == @simple_file.downcase
|
416
|
+
end
|
417
|
+
|
418
|
+
context "with :if_unsaved => :alert" do
|
419
|
+
before do
|
420
|
+
@key_sender = IO.popen 'ruby "' + File.join(File.dirname(__FILE__), '/helpers/key_sender.rb') + '" "Microsoft Office Excel" ' , "w"
|
421
|
+
end
|
422
|
+
|
423
|
+
after do
|
424
|
+
@key_sender.close
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should open the new book and close the unsaved book, if user answers 'yes'" do
|
428
|
+
# "Yes" is the default. --> language independent
|
429
|
+
@key_sender.puts "{enter}"
|
430
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :alert)
|
431
|
+
@new_book.should be_alive
|
432
|
+
@new_book.filename.downcase.should == @simple_file.downcase
|
433
|
+
@book.should_not be_alive
|
434
|
+
end
|
435
|
+
|
436
|
+
it "should not open the new book and not close the unsaved book, if user answers 'no'" do
|
437
|
+
# "No" is right to "Yes" (the default). --> language independent
|
438
|
+
# strangely, in the "no" case, the question will sometimes be repeated three times
|
439
|
+
#@book.excel.Visible = true
|
440
|
+
@key_sender.puts "{right}{enter}"
|
441
|
+
@key_sender.puts "{right}{enter}"
|
442
|
+
@key_sender.puts "{right}{enter}"
|
443
|
+
expect{
|
444
|
+
Book.open(@simple_file, :if_unsaved => :alert)
|
445
|
+
}.to raise_error(ExcelErrorOpen, "open: user canceled or open error")
|
446
|
+
@book.should be_alive
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should open the book in a new excel instance, if :if_unsaved is :new_excel" do
|
451
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :new_excel)
|
452
|
+
@book.should be_alive
|
453
|
+
@new_book.should be_alive
|
454
|
+
@new_book.filename.should == @book.filename
|
455
|
+
@new_book.excel.should_not == @book.excel
|
456
|
+
@new_book.close
|
457
|
+
end
|
458
|
+
|
459
|
+
it "should raise an error, if :if_unsaved is default" do
|
460
|
+
expect {
|
461
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :raise)
|
462
|
+
}.to raise_error(ExcelErrorOpen, "book is already open but not saved (#{File.basename(@simple_file)})")
|
463
|
+
end
|
464
|
+
|
465
|
+
it "should raise an error, if :if_unsaved is invalid option" do
|
466
|
+
expect {
|
467
|
+
@new_book = Book.open(@simple_file, :if_unsaved => :invalid_option)
|
468
|
+
}.to raise_error(ExcelErrorOpen, ":if_unsaved: invalid option: invalid_option")
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
context "with :if_obstructed" do
|
473
|
+
|
474
|
+
for i in 1..2 do
|
475
|
+
|
476
|
+
context "with and without reopen" do
|
477
|
+
|
478
|
+
before do
|
479
|
+
if i == 1 then
|
480
|
+
book_before = Book.open(@simple_file)
|
481
|
+
book_before.close
|
482
|
+
end
|
483
|
+
@book = Book.open(@simple_file_other_path)
|
484
|
+
@sheet_count = @book.workbook.Worksheets.Count
|
485
|
+
@sheet = @book[0]
|
486
|
+
@book.add_sheet(@sheet, :as => 'a_name')
|
487
|
+
end
|
488
|
+
|
489
|
+
after do
|
490
|
+
@book.close(:if_unsaved => :forget)
|
491
|
+
@new_book.close rescue nil
|
492
|
+
end
|
493
|
+
|
494
|
+
it "should raise an error, if :if_obstructed is :raise" do
|
495
|
+
expect {
|
496
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :raise)
|
497
|
+
}.to raise_error(ExcelErrorOpen, "blocked by a book with the same name in a different path: workbook.xls")
|
498
|
+
end
|
499
|
+
|
500
|
+
it "should close the other book and open the new book, if :if_obstructed is :forget" do
|
501
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :forget)
|
502
|
+
@book.should_not be_alive
|
503
|
+
@new_book.should be_alive
|
504
|
+
@new_book.filename.downcase.should == @simple_file.downcase
|
505
|
+
end
|
506
|
+
|
507
|
+
it "should save the old book, close it, and open the new book, if :if_obstructed is :save" do
|
508
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :save)
|
509
|
+
@book.should_not be_alive
|
510
|
+
@new_book.should be_alive
|
511
|
+
@new_book.filename.downcase.should == @simple_file.downcase
|
512
|
+
old_book = Book.open(@simple_file_other_path, :if_obstructed => :forget)
|
513
|
+
old_book.workbook.Worksheets.Count.should == @sheet_count + 1
|
514
|
+
old_book.close
|
515
|
+
end
|
516
|
+
|
517
|
+
it "should raise an error, if the old book is unsaved, and close the old book and open the new book,
|
518
|
+
if :if_obstructed is :close_if_saved" do
|
519
|
+
expect{
|
520
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :close_if_saved)
|
521
|
+
}.to raise_error(ExcelErrorOpen, "book with the same name in a different path is unsaved: workbook.xls")
|
522
|
+
@book.save
|
523
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :close_if_saved)
|
524
|
+
@book.should_not be_alive
|
525
|
+
@new_book.should be_alive
|
526
|
+
@new_book.filename.downcase.should == @simple_file.downcase
|
527
|
+
old_book = Book.open(@simple_file_other_path, :if_obstructed => :forget)
|
528
|
+
old_book.workbook.Worksheets.Count.should == @sheet_count + 1
|
529
|
+
old_book.close
|
530
|
+
end
|
531
|
+
|
532
|
+
it "should open the book in a new excel instance, if :if_obstructed is :new_excel" do
|
533
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :new_excel)
|
534
|
+
@book.should be_alive
|
535
|
+
@new_book.should be_alive
|
536
|
+
@new_book.filename.should_not == @book.filename
|
537
|
+
@new_book.excel.should_not == @book.excel
|
538
|
+
end
|
539
|
+
|
540
|
+
it "should raise an error, if :if_obstructed is default" do
|
541
|
+
expect {
|
542
|
+
@new_book = Book.open(@simple_file)
|
543
|
+
}.to raise_error(ExcelErrorOpen, "blocked by a book with the same name in a different path: workbook.xls")
|
544
|
+
end
|
545
|
+
|
546
|
+
it "should raise an error, if :if_obstructed is invalid option" do
|
547
|
+
expect {
|
548
|
+
@new_book = Book.open(@simple_file, :if_obstructed => :invalid_option)
|
549
|
+
}.to raise_error(ExcelErrorOpen, ":if_obstructed: invalid option: invalid_option")
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
context "with an already saved book" do
|
556
|
+
before do
|
557
|
+
@book = Book.open(@simple_file)
|
558
|
+
end
|
559
|
+
|
560
|
+
after do
|
561
|
+
@book.close
|
562
|
+
end
|
563
|
+
|
564
|
+
possible_options = [:read_only, :raise, :accept, :forget, nil]
|
565
|
+
possible_options.each do |options_value|
|
566
|
+
context "with :if_unsaved => #{options_value} and in the same and different path" do
|
567
|
+
before do
|
568
|
+
@new_book = Book.open(@simple_file, :reuse=> true, :if_unsaved => options_value)
|
569
|
+
@different_book = Book.new(@different_file, :reuse=> true, :if_unsaved => options_value)
|
570
|
+
end
|
571
|
+
after do
|
572
|
+
@new_book.close
|
573
|
+
@different_book.close
|
574
|
+
end
|
575
|
+
it "should open without problems " do
|
576
|
+
@new_book.should be_a Book
|
577
|
+
@different_book.should be_a Book
|
578
|
+
end
|
579
|
+
it "should belong to the same Excel instance" do
|
580
|
+
@new_book.excel.should == @book.excel
|
581
|
+
@different_book.excel.should == @book.excel
|
582
|
+
end
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
context "with non-existing file" do
|
588
|
+
|
589
|
+
it "should raise an exception" do
|
590
|
+
File.delete @simple_save_file rescue nil
|
591
|
+
expect {
|
592
|
+
Book.open(@simple_save_file, :if_absent => :raise)
|
593
|
+
}.to raise_error(ExcelErrorOpen, "file #{@simple_save_file} not found")
|
594
|
+
end
|
595
|
+
|
596
|
+
it "should create a workbook" do
|
597
|
+
File.delete @simple_save_file rescue nil
|
598
|
+
book = Book.open(@simple_save_file, :if_absent => :create)
|
599
|
+
book.should be_a Book
|
600
|
+
book.close
|
601
|
+
File.exist?(@simple_save_file).should be_true
|
602
|
+
end
|
603
|
+
|
604
|
+
it "should raise an exception by default" do
|
605
|
+
File.delete @simple_save_file rescue nil
|
606
|
+
expect {
|
607
|
+
Book.open(@simple_save_file)
|
608
|
+
}.to raise_error(ExcelErrorOpen, "file #{@simple_save_file} not found")
|
609
|
+
end
|
610
|
+
|
611
|
+
end
|
612
|
+
|
613
|
+
context "with attr_reader excel" do
|
614
|
+
|
615
|
+
before do
|
616
|
+
@new_book = Book.open(@simple_file)
|
617
|
+
end
|
618
|
+
after do
|
619
|
+
@new_book.close
|
620
|
+
end
|
621
|
+
it "should provide the excel instance of the book" do
|
622
|
+
excel = @new_book.excel
|
623
|
+
excel.class.should == Excel
|
624
|
+
excel.should be_a Excel
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
context "with :read_only" do
|
629
|
+
|
630
|
+
it "should reopen the book with writable (unsaved changes from readonly will not be saved)" do
|
631
|
+
book = Book.open(@simple_file, :read_only => true)
|
632
|
+
book.ReadOnly.should be_true
|
633
|
+
book.should be_alive
|
634
|
+
sheet = book[0]
|
635
|
+
old_cell_value = sheet[1,1].value
|
636
|
+
sheet[1,1] = sheet[1,1].value == "foo" ? "bar" : "foo"
|
637
|
+
book.Saved.should be_false
|
638
|
+
new_book = Book.open(@simple_file, :read_only => false, :if_unsaved => :accept)
|
639
|
+
new_book.ReadOnly.should be_false
|
640
|
+
new_book.should be_alive
|
641
|
+
book.should be_alive
|
642
|
+
new_book.should == book
|
643
|
+
new_sheet = new_book[0]
|
644
|
+
new_cell_value = new_sheet[1,1].value
|
645
|
+
new_cell_value.should == old_cell_value
|
646
|
+
end
|
647
|
+
|
648
|
+
it "should not raise an error when trying to reopen the book as read_only while the writable book had unsaved changes" do
|
649
|
+
book = Book.open(@simple_file, :read_only => false)
|
650
|
+
book.ReadOnly.should be_false
|
651
|
+
book.should be_alive
|
652
|
+
sheet = book[0]
|
653
|
+
old_cell_value = sheet[1,1].value
|
654
|
+
sheet[1,1] = sheet[1,1].value == "foo" ? "bar" : "foo"
|
655
|
+
book.Saved.should be_false
|
656
|
+
new_book = Book.open(@simple_file, :read_only => true, :if_unsaved => :accept)
|
657
|
+
new_book.ReadOnly.should be_false
|
658
|
+
new_book.Saved.should be_false
|
659
|
+
new_book.should == book
|
660
|
+
end
|
661
|
+
|
662
|
+
it "should reopen the book with writable in the same Excel instance (unsaved changes from readonly will not be saved)" do
|
663
|
+
book = Book.open(@simple_file, :read_only => true)
|
664
|
+
book.ReadOnly.should be_true
|
665
|
+
book.should be_alive
|
666
|
+
sheet = book[0]
|
667
|
+
old_cell_value = sheet[1,1].value
|
668
|
+
sheet[1,1] = sheet[1,1].value == "foo" ? "bar" : "foo"
|
669
|
+
book.Saved.should be_false
|
670
|
+
new_book = Book.open(@simple_file, :if_unsaved => :accept, :force_excel => book.excel, :read_only => false)
|
671
|
+
new_book.ReadOnly.should be_false
|
672
|
+
new_book.should be_alive
|
673
|
+
book.should be_alive
|
674
|
+
new_book.should == book
|
675
|
+
new_sheet = new_book[0]
|
676
|
+
new_cell_value = new_sheet[1,1].value
|
677
|
+
new_cell_value.should == old_cell_value
|
678
|
+
end
|
679
|
+
|
680
|
+
it "should reopen the book with readonly (unsaved changes of the writable should be saved)" do
|
681
|
+
book = Book.open(@simple_file, :force_excel => :new, :read_only => false)
|
682
|
+
book.ReadOnly.should be_false
|
683
|
+
book.should be_alive
|
684
|
+
sheet = book[0]
|
685
|
+
old_cell_value = sheet[1,1].value
|
686
|
+
sheet[1,1] = sheet[1,1].value == "foo" ? "bar" : "foo"
|
687
|
+
book.Saved.should be_false
|
688
|
+
new_book = Book.open(@simple_file, :force_excel => book.excel, :read_only => true, :if_unsaved => :accept)
|
689
|
+
new_book.ReadOnly.should be_false
|
690
|
+
new_book.Saved.should be_false
|
691
|
+
new_book.should == book
|
692
|
+
end
|
693
|
+
|
694
|
+
it "should open the second book in another Excel as writable" do
|
695
|
+
book = Book.open(@simple_file, :read_only => true)
|
696
|
+
book.ReadOnly.should be_true
|
697
|
+
new_book = Book.open(@simple_file, :force_excel => :new, :read_only => false)
|
698
|
+
new_book.ReadOnly.should be_false
|
699
|
+
new_book.close
|
700
|
+
book.close
|
701
|
+
end
|
702
|
+
|
703
|
+
it "should be able to save, if :read_only => false" do
|
704
|
+
book = Book.open(@simple_file, :read_only => false)
|
705
|
+
book.should be_a Book
|
706
|
+
expect {
|
707
|
+
book.save_as(@simple_save_file, :if_exists => :overwrite)
|
708
|
+
}.to_not raise_error
|
709
|
+
book.close
|
710
|
+
end
|
711
|
+
|
712
|
+
it "should be able to save, if :read_only is default" do
|
713
|
+
book = Book.open(@simple_file)
|
714
|
+
book.should be_a Book
|
715
|
+
expect {
|
716
|
+
book.save_as(@simple_save_file, :if_exists => :overwrite)
|
717
|
+
}.to_not raise_error
|
718
|
+
book.close
|
719
|
+
end
|
720
|
+
|
721
|
+
it "should raise an error, if :read_only => true" do
|
722
|
+
book = Book.open(@simple_file, :read_only => true)
|
723
|
+
book.should be_a Book
|
724
|
+
expect {
|
725
|
+
book.save_as(@simple_save_file, :if_exists => :overwrite)
|
726
|
+
}.to raise_error
|
727
|
+
book.close
|
728
|
+
end
|
729
|
+
end
|
730
|
+
|
731
|
+
context "with various file formats" do
|
732
|
+
|
733
|
+
it "should open linked workbook" do
|
734
|
+
book = Book.open(@linked_file, :visible => true)
|
735
|
+
book.close
|
736
|
+
end
|
737
|
+
|
738
|
+
it "should open xlsm file" do
|
739
|
+
book = Book.open(@simple_file_xlsm, :visible => true)
|
740
|
+
book.close
|
741
|
+
end
|
742
|
+
|
743
|
+
it "should open xlsx file" do
|
744
|
+
book = Book.open(@simple_file_xlsx, :visible => true)
|
745
|
+
book.close
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
|
750
|
+
context "with block" do
|
751
|
+
it 'block parameter should be instance of Book' do
|
752
|
+
Book.open(@simple_file) do |book|
|
753
|
+
book.should be_a Book
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
context "with WIN32OLE#GetAbsolutePathName" do
|
759
|
+
it "'~' should be HOME directory" do
|
760
|
+
path = '~/Abrakadabra.xlsx'
|
761
|
+
expected_path = Regexp.new(File.expand_path(path).gsub(/\//, "."))
|
762
|
+
expect {
|
763
|
+
Book.open(path)
|
764
|
+
}.to raise_error(ExcelErrorOpen, "file #{path} not found")
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
describe "reopen" do
|
770
|
+
|
771
|
+
context "with standard" do
|
772
|
+
|
773
|
+
before do
|
774
|
+
@book = Book.open(@simple_file)
|
775
|
+
end
|
776
|
+
|
777
|
+
after do
|
778
|
+
@book.close
|
779
|
+
end
|
780
|
+
|
781
|
+
it "should reopen the closed book" do
|
782
|
+
@book.should be_alive
|
783
|
+
book1 = @book
|
784
|
+
@book.close
|
785
|
+
@book.should_not be_alive
|
786
|
+
@book.reopen
|
787
|
+
@book.should be_a Book
|
788
|
+
@book.should be_alive
|
789
|
+
@book.should === book1
|
790
|
+
end
|
791
|
+
end
|
792
|
+
end
|
793
|
+
end
|