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
@@ -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