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.
Files changed (49) hide show
  1. data/README.rdoc +73 -26
  2. data/README_detail.rdoc +92 -27
  3. data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
  4. data/examples/edit_sheets/example_concating.rb +12 -12
  5. data/examples/edit_sheets/example_copying.rb +47 -0
  6. data/examples/edit_sheets/example_expanding.rb +17 -26
  7. data/examples/edit_sheets/example_naming.rb +13 -10
  8. data/examples/edit_sheets/example_ranges.rb +2 -2
  9. data/examples/edit_sheets/example_saving.rb +8 -14
  10. data/examples/open_save_close/example_control_to_excel.rb +1 -1
  11. data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
  12. data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
  13. data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
  14. data/examples/open_save_close/example_if_unsaved_forget.rb +4 -4
  15. data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
  16. data/examples/open_save_close/example_read_only.rb +1 -1
  17. data/examples/open_save_close/example_rename_cells.rb +1 -13
  18. data/examples/open_save_close/example_simple.rb +1 -1
  19. data/examples/open_save_close/example_unobtrusively.rb +3 -3
  20. data/lib/robust_excel_ole.rb +81 -2
  21. data/lib/robust_excel_ole/book.rb +171 -118
  22. data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
  23. data/lib/robust_excel_ole/excel.rb +153 -24
  24. data/lib/robust_excel_ole/range.rb +2 -2
  25. data/lib/robust_excel_ole/sheet.rb +84 -35
  26. data/lib/robust_excel_ole/version.rb +1 -1
  27. data/reo.bat +3 -0
  28. data/spec/book_close_spec.rb +179 -0
  29. data/spec/book_misc_spec.rb +365 -0
  30. data/spec/book_open_spec.rb +793 -0
  31. data/spec/book_save_spec.rb +257 -0
  32. data/spec/book_sheet_spec.rb +160 -0
  33. data/spec/book_spec.rb +145 -1533
  34. data/spec/book_subclass_spec.rb +50 -0
  35. data/spec/book_unobtr_spec.rb +950 -0
  36. data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
  37. data/spec/cell_spec.rb +6 -6
  38. data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
  39. data/spec/data/different_workbook.xls +0 -0
  40. data/spec/data/workbook.xls +0 -0
  41. data/spec/data/workbook.xlsm +0 -0
  42. data/spec/data/workbook.xlsx +0 -0
  43. data/spec/data/workbook_linked.xlsm +0 -0
  44. data/spec/data/workbook_linked_sub.xlsm +0 -0
  45. data/spec/excel_spec.rb +204 -5
  46. data/spec/range_spec.rb +6 -6
  47. data/spec/sheet_spec.rb +122 -34
  48. metadata +18 -8
  49. 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