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
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
data/reo.bat ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ irb -r lib/robust_excel_ole
@@ -0,0 +1,179 @@
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 "close" do
37
+
38
+ context "with saved book" do
39
+ before do
40
+ @book = Book.open(@simple_file)
41
+ end
42
+
43
+ it "should close book" do
44
+ expect{
45
+ @book.close
46
+ }.to_not raise_error
47
+ @book.should_not be_alive
48
+ end
49
+ end
50
+
51
+ context "with unsaved read_only book" do
52
+ before do
53
+ @book = Book.open(@simple_file, :read_only => true)
54
+ @sheet_count = @book.workbook.Worksheets.Count
55
+ @book.add_sheet(@sheet, :as => 'a_name')
56
+ end
57
+
58
+ it "should close the unsaved book without error and without saving" do
59
+ expect{
60
+ @book.close
61
+ }.to_not raise_error
62
+ new_book = Book.open(@simple_file)
63
+ new_book.workbook.Worksheets.Count.should == @sheet_count
64
+ new_book.close
65
+ end
66
+ end
67
+
68
+ context "with unsaved book" do
69
+ before do
70
+ @book = Book.open(@simple_file)
71
+ @sheet_count = @book.workbook.Worksheets.Count
72
+ @book.add_sheet(@sheet, :as => 'a_name')
73
+ @sheet = @book[0]
74
+ end
75
+
76
+ after do
77
+ @book.close(:if_unsaved => :forget) rescue nil
78
+ end
79
+
80
+ it "should raise error with option :raise" do
81
+ expect{
82
+ @book.close(:if_unsaved => :raise)
83
+ }.to raise_error(ExcelErrorClose, "book is unsaved (#{File.basename(@simple_file)})")
84
+ end
85
+
86
+ it "should raise error by default" do
87
+ expect{
88
+ @book.close(:if_unsaved => :raise)
89
+ }.to raise_error(ExcelErrorClose, "book is unsaved (#{File.basename(@simple_file)})")
90
+ end
91
+
92
+ it "should close the book and leave its file untouched with option :forget" do
93
+ ole_workbook = @book.workbook
94
+ excel = @book.excel
95
+ expect {
96
+ @book.close(:if_unsaved => :forget)
97
+ }.to change {excel.Workbooks.Count }.by(-1)
98
+ @book.workbook.should == nil
99
+ @book.should_not be_alive
100
+ expect{
101
+ ole_workbook.Name}.to raise_error(WIN32OLERuntimeError)
102
+ new_book = Book.open(@simple_file)
103
+ begin
104
+ new_book.workbook.Worksheets.Count.should == @sheet_count
105
+ ensure
106
+ new_book.close
107
+ end
108
+ end
109
+
110
+ it "should raise an error for invalid option" do
111
+ expect {
112
+ @book.close(:if_unsaved => :invalid_option)
113
+ }.to raise_error(ExcelErrorClose, ":if_unsaved: invalid option: invalid_option")
114
+ end
115
+
116
+
117
+ it "should save the book before close with option :save" do
118
+ ole_workbook = @book.workbook
119
+ excel = @book.excel
120
+ expect {
121
+ @book.close(:if_unsaved => :save)
122
+ }.to change {excel.Workbooks.Count }.by(-1)
123
+ @book.workbook.should == nil
124
+ @book.should_not be_alive
125
+ expect{
126
+ ole_workbook.Name}.to raise_error(WIN32OLERuntimeError)
127
+ new_book = Book.open(@simple_file)
128
+ begin
129
+ new_book.workbook.Worksheets.Count.should == @sheet_count + 1
130
+ ensure
131
+ new_book.close
132
+ end
133
+ end
134
+
135
+ context "with :if_unsaved => :alert" do
136
+ before do
137
+ @key_sender = IO.popen 'ruby "' + File.join(File.dirname(__FILE__), '/helpers/key_sender.rb') + '" "Microsoft Excel" ' , "w"
138
+ end
139
+
140
+ after do
141
+ @key_sender.close
142
+ end
143
+
144
+ possible_answers = [:yes, :no, :cancel]
145
+ possible_answers.each_with_index do |answer, position|
146
+ it "should" + (answer == :yes ? "" : " not") + " the unsaved book and" + (answer == :cancel ? " not" : "") + " close it" + "if user answers '#{answer}'" do
147
+ # "Yes" is the default. "No" is right of "Yes", "Cancel" is right of "No" --> language independent
148
+ @key_sender.puts "{right}" * position + "{enter}"
149
+ ole_workbook = @book.workbook
150
+ excel = @book.excel
151
+ displayalert_value = @book.excel.DisplayAlerts
152
+ if answer == :cancel then
153
+ expect {
154
+ @book.close(:if_unsaved => :alert)
155
+ }.to raise_error(ExcelUserCanceled, "close: canceled by user")
156
+ @book.workbook.Saved.should be_false
157
+ @book.workbook.should_not == nil
158
+ @book.should be_alive
159
+ else
160
+ expect {
161
+ @book.close(:if_unsaved => :alert)
162
+ }.to change {@book.excel.Workbooks.Count }.by(-1)
163
+ @book.workbook.should == nil
164
+ @book.should_not be_alive
165
+ expect{ole_workbook.Name}.to raise_error(WIN32OLERuntimeError)
166
+ end
167
+ new_book = Book.open(@simple_file, :if_unsaved => :forget)
168
+ begin
169
+ new_book.workbook.Worksheets.Count.should == @sheet_count + (answer==:yes ? 1 : 0)
170
+ new_book.excel.DisplayAlerts.should == displayalert_value
171
+ ensure
172
+ new_book.close
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,365 @@
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 "create file" do
37
+ context "with standard" do
38
+ it "open an existing file" do
39
+ expect {
40
+ @book = Book.new(@simple_file)
41
+ }.to_not raise_error
42
+ @book.should be_a Book
43
+ @book.close
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "send methods to workbook" do
49
+
50
+ context "with standard" do
51
+ before do
52
+ @book = Book.open(@simple_file)
53
+ end
54
+
55
+ after do
56
+ @book.close
57
+ end
58
+
59
+ it "should send Saved to workbook" do
60
+ @book.Saved.should be_true
61
+ end
62
+
63
+ it "should send Fullname to workbook" do
64
+ @book.Fullname.tr('\\','/').should == @simple_file
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "hidden_excel" do
70
+
71
+ context "with some open book" do
72
+
73
+ before do
74
+ @book = Book.open(@simple_file)
75
+ end
76
+
77
+ after do
78
+ @book.close
79
+ end
80
+
81
+ it "should create and use a hidden Excel instance" do
82
+ book2 = Book.open(@simple_file, :force_excel => @book.bookstore.hidden_excel)
83
+ book2.excel.should_not == @book.excel
84
+ book2.excel.visible.should be_false
85
+ book2.excel.displayalerts.should be_false
86
+ book2.close
87
+ end
88
+ end
89
+ end
90
+
91
+ describe "nvalue, set_nvalue, rename_range" do
92
+
93
+ context "nvalue, book[<name>]" do
94
+
95
+ before do
96
+ @book1 = Book.open(@another_simple_file)
97
+ end
98
+
99
+ after do
100
+ @book1.close(:if_unsaved => :forget)
101
+ end
102
+
103
+ it "should return value of a range" do
104
+ @book1.nvalue("new").should == "foo"
105
+ @book1.nvalue("one").should == 1
106
+ @book1.nvalue("firstrow").should == [[1,2]]
107
+ @book1.nvalue("four").should == [[1,2],[3,4]]
108
+ @book1.nvalue("firstrow").should_not == "12"
109
+ @book1.nvalue("firstcell").should == "foo"
110
+ @book1["new"].should == "foo"
111
+ @book1["one"].should == 1
112
+ @book1["firstrow"].should == [[1,2]]
113
+ @book1["four"].should == [[1,2],[3,4]]
114
+ @book1["firstcell"].should == "foo"
115
+ end
116
+
117
+ it "should raise an error if name not defined" do
118
+ expect {
119
+ @book1.nvalue("foo")
120
+ }.to raise_error(ExcelErrorNValue, "name foo not in another_workbook.xls")
121
+ expect {
122
+ @book1["foo"]
123
+ }.to raise_error(ExcelErrorNValue, "name foo not in another_workbook.xls")
124
+ end
125
+
126
+ it "should raise an error if name was defined but contents is calcuated" do
127
+ expect {
128
+ @book1.nvalue("named_formula")
129
+ }.to raise_error(ExcelErrorNValue, "RefersToRange error of name named_formula in another_workbook.xls")
130
+ expect {
131
+ @book1["named_formula"]
132
+ }.to raise_error(ExcelErrorNValue, "RefersToRange error of name named_formula in another_workbook.xls")
133
+ end
134
+
135
+ it "should return default value if name not defined" do
136
+ @book1.nvalue("foo", :default => 2).should == 2
137
+ @book1.nvalue("named_formula", :default => 4).should == 4
138
+ end
139
+ end
140
+
141
+ context "set_nvalue, book[<name>]=" do
142
+
143
+ before do
144
+ @book1 = Book.open(@another_simple_file)
145
+ end
146
+
147
+ after do
148
+ @book1.close(:if_unsaved => :forget)
149
+ end
150
+
151
+ it "should set value of a range" do
152
+ @book1.nvalue("new").should == "foo"
153
+ @book1.set_nvalue("new","bar")
154
+ @book1.nvalue("new").should == "bar"
155
+ end
156
+
157
+ it "should raise an error if name not defined" do
158
+ expect {
159
+ @book1.set_nvalue("foo","bar")
160
+ }.to raise_error(ExcelErrorNValue, "name foo not in another_workbook.xls")
161
+ expect {
162
+ @book1["foo"] = "bar"
163
+ }.to raise_error(ExcelErrorNValue, "name foo not in another_workbook.xls")
164
+ end
165
+
166
+ it "should raise an error if name was defined but contents is calcuated" do
167
+ expect {
168
+ @book1.set_nvalue("named_formula","bar")
169
+ }.to raise_error(ExcelErrorNValue, "RefersToRange error of name named_formula in another_workbook.xls")
170
+ expect {
171
+ @book1["named_formula"] = "bar"
172
+ }.to raise_error(ExcelErrorNValue, "RefersToRange error of name named_formula in another_workbook.xls")
173
+ end
174
+
175
+ it "should set value of a range" do
176
+ @book1.nvalue("new").should == "foo"
177
+ @book1["new"] = "bar"
178
+ @book1.nvalue("new").should == "bar"
179
+ end
180
+ end
181
+
182
+ context "rename_range" do
183
+
184
+ before do
185
+ @book1 = Book.open(@another_simple_file)
186
+ end
187
+
188
+ after do
189
+ @book1.close(:if_unsaved => :forget)
190
+ end
191
+
192
+ it "should rename a range" do
193
+ @book1.rename_range("four","five")
194
+ @book1.nvalue("five").should == [[1,2],[3,4]]
195
+ expect {
196
+ @book1.rename_range("four","five")
197
+ }.to raise_error(ExcelError, "name four not in another_workbook.xls")
198
+ end
199
+ end
200
+ end
201
+
202
+ describe "alive?, filename, ==, visible, displayalerts, activate, saved" do
203
+
204
+ context "with alive?" do
205
+
206
+ before do
207
+ @book = Book.open(@simple_file)
208
+ end
209
+
210
+ after do
211
+ @book.close
212
+ end
213
+
214
+ it "should return true, if book is alive" do
215
+ @book.should be_alive
216
+ end
217
+
218
+ it "should return false, if book is dead" do
219
+ @book.close
220
+ @book.should_not be_alive
221
+ end
222
+
223
+ end
224
+
225
+ context "with filename" do
226
+
227
+ before do
228
+ @book = Book.open(@simple_file)
229
+ end
230
+
231
+ after do
232
+ @book.close
233
+ end
234
+
235
+ it "should return full file name" do
236
+ @book.filename.should == @simple_file
237
+ end
238
+
239
+ it "should return nil for dead book" do
240
+ @book.close
241
+ @book.filename.should == nil
242
+ end
243
+
244
+ end
245
+
246
+ context "with ==" do
247
+
248
+ before do
249
+ @book = Book.open(@simple_file)
250
+ end
251
+
252
+ after do
253
+ @book.close
254
+ @new_book.close rescue nil
255
+ end
256
+
257
+ it "should be true with two identical books" do
258
+ @new_book = Book.open(@simple_file)
259
+ @new_book.should == @book
260
+ end
261
+
262
+ it "should be false with two different books" do
263
+ @new_book = Book.new(@different_file)
264
+ @new_book.should_not == @book
265
+ end
266
+
267
+ it "should be false with same book names but different paths" do
268
+ @new_book = Book.new(@simple_file_other_path, :excel => :new)
269
+ @new_book.should_not == @book
270
+ end
271
+
272
+ it "should be false with same book names but different excel instances" do
273
+ @new_book = Book.new(@simple_file, :excel => :new)
274
+ @new_book.should_not == @book
275
+ end
276
+
277
+ it "should be false with non-Books" do
278
+ @book.should_not == "hallo"
279
+ @book.should_not == 7
280
+ @book.should_not == nil
281
+ end
282
+ end
283
+
284
+ context "with saved" do
285
+
286
+ before do
287
+ @book = Book.open(@simple_file)
288
+ end
289
+
290
+ after do
291
+ @book.close(:if_unsaved => :forget)
292
+ end
293
+
294
+ it "should yield true for a saved book" do
295
+ @book.saved.should be_true
296
+ end
297
+
298
+ it "should yield false for an unsaved book" do
299
+ sheet = @book[0]
300
+ sheet[1,1] = sheet[1,1].value == "foo" ? "bar" : "foo"
301
+ @book.saved.should be_false
302
+ end
303
+ end
304
+
305
+ context "with visible and displayalerts" do
306
+
307
+ before do
308
+ @book = Book.open(@simple_file)
309
+ end
310
+
311
+ after do
312
+ @book.close
313
+ end
314
+
315
+ it "should make Excel visible" do
316
+ @book.excel.visible = false
317
+ @book.excel.visible.should be_false
318
+ @book.excel.visible = true
319
+ @book.excel.visible.should be_true
320
+ end
321
+
322
+ it "should enable DisplayAlerts in Excel" do
323
+ @book.excel.displayalerts = false
324
+ @book.excel.displayalerts.should be_false
325
+ @book.excel.displayalerts = true
326
+ @book.excel.displayalerts.should be_true
327
+ end
328
+ end
329
+
330
+ context "with activate" do
331
+
332
+ before do
333
+ @key_sender = IO.popen 'ruby "' + File.join(File.dirname(__FILE__), '/helpers/key_sender.rb') + '" "Microsoft Office Excel" ' , "w"
334
+ @book = Book.open(@simple_file, :visible => true)
335
+ @book2 = Book.open(@another_simple_file, :force_excel => :new, :visible => true)
336
+ end
337
+
338
+ after do
339
+ @book.close(:if_unsaved => :forget)
340
+ @book2.close(:if_unsaved => :forget)
341
+ @key_sender.close
342
+ end
343
+
344
+ it "should activate a book" do
345
+ sheet = @book[1]
346
+ sheet.Activate
347
+ sheet[2,3].Activate
348
+ sheet2 = @book2[2]
349
+ sheet2.Activate
350
+ sheet2[3,2].Activate
351
+ Excel.current.should == @book.excel
352
+ @book2.activate
353
+ @key_sender.puts "{a}{enter}"
354
+ sleep 1
355
+ sheet2[3,2].Value.should == "a"
356
+ #Excel.current.should == @book2.excel
357
+ @book.activate
358
+ @key_sender.puts "{a}{enter}"
359
+ sleep 1
360
+ sheet[2,3].Value.should == "a"
361
+ Excel.current.should == @book.excel
362
+ end
363
+ end
364
+ end
365
+ end