robust_excel_ole 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
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