workbook 0.4.6.0 → 0.4.7

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +14 -15
  4. data/lib/workbook.rb +22 -11
  5. data/lib/workbook/book.rb +47 -25
  6. data/lib/workbook/cell.rb +20 -26
  7. data/lib/workbook/generatetypes.rb +14 -0
  8. data/lib/workbook/modules/cache.rb +52 -0
  9. data/lib/workbook/modules/{table_diff_sort.rb → diff_sort.rb} +64 -16
  10. data/lib/workbook/modules/raw_objects_storage.rb +7 -2
  11. data/lib/workbook/readers/ods_reader.rb +1 -1
  12. data/lib/workbook/readers/xls_reader.rb +55 -55
  13. data/lib/workbook/readers/xls_shared.rb +47 -0
  14. data/lib/workbook/readers/xlsx_reader.rb +34 -153
  15. data/lib/workbook/row.rb +47 -4
  16. data/lib/workbook/sheet.rb +4 -0
  17. data/lib/workbook/table.rb +36 -16
  18. data/lib/workbook/types/Date.rb +9 -0
  19. data/lib/workbook/types/False.rb +0 -0
  20. data/lib/workbook/types/FalseClass.rb +9 -0
  21. data/lib/workbook/types/Nil.rb +0 -0
  22. data/lib/workbook/types/NilClass.rb +9 -0
  23. data/lib/workbook/types/Numeric.rb +9 -0
  24. data/lib/workbook/types/String.rb +9 -0
  25. data/lib/workbook/types/Time.rb +9 -0
  26. data/lib/workbook/types/True.rb +0 -0
  27. data/lib/workbook/types/TrueClass.rb +9 -0
  28. data/lib/workbook/version.rb +1 -1
  29. data/lib/workbook/writers/html_writer.rb +40 -18
  30. data/lib/workbook/writers/xls_writer.rb +47 -5
  31. data/lib/workbook/writers/xlsx_writer.rb +123 -0
  32. data/test/artifacts/bigtable.xls +0 -0
  33. data/test/artifacts/bigtable.xlsx +0 -0
  34. data/test/artifacts/simple_sheet.xlsx +0 -0
  35. data/test/artifacts/simple_sheet_many_sheets.xls +0 -0
  36. data/test/test_book.rb +50 -2
  37. data/test/test_cell.rb +1 -1
  38. data/test/test_format.rb +8 -0
  39. data/test/test_modules_cache.rb +68 -0
  40. data/test/test_modules_table_diff_sort.rb +12 -1
  41. data/test/test_readers_xls_reader.rb +6 -0
  42. data/test/test_readers_xlsx_reader.rb +10 -9
  43. data/test/test_row.rb +65 -8
  44. data/test/test_sheet.rb +8 -0
  45. data/test/test_table.rb +48 -0
  46. data/test/test_writers_html_writer.rb +18 -8
  47. data/test/test_writers_xls_writer.rb +90 -0
  48. data/test/test_writers_xlsx_writer.rb +153 -0
  49. data/workbook.gemspec +9 -7
  50. metadata +71 -31
Binary file
Binary file
Binary file
data/test/test_book.rb CHANGED
@@ -10,16 +10,18 @@ class TestWorkbook < Test::Unit::TestCase
10
10
 
11
11
  def test_push
12
12
  w = Workbook::Book.new nil
13
+ assert_equal(w.count,1)
13
14
  assert_equal([[[]]],w)
14
15
  w = Workbook::Book.new
15
- assert_equal(w.count,1)
16
-
17
16
  w.push
18
17
  assert_equal(w.first.class,Workbook::Sheet)
19
18
  w.push
19
+ assert_equal(w,w.last.book)
20
20
  assert_equal(w.count,3)
21
21
  s = Workbook::Sheet.new
22
22
  w.push s
23
+ assert_equal(w,w.last.book)
24
+
23
25
  assert_equal(w.last,s)
24
26
  w = Workbook::Book.new
25
27
  assert_equal(w.sheet.table.class,Workbook::Table)
@@ -34,6 +36,8 @@ class TestWorkbook < Test::Unit::TestCase
34
36
  assert_equal(w.sheet, s)
35
37
  end
36
38
 
39
+
40
+
37
41
  def test_template
38
42
  b = Workbook::Book.new
39
43
  raw = "asdf"
@@ -44,6 +48,15 @@ class TestWorkbook < Test::Unit::TestCase
44
48
  assert_equal(raw,b.template)
45
49
  end
46
50
 
51
+ def test_file_extension
52
+ b = Workbook::Book.new
53
+ assert_equal("aaa",b.file_extension("aaa.aaa"))
54
+ b = Workbook::Book.new
55
+ assert_equal("xlsx",b.file_extension(File.join(File.dirname(__FILE__), 'artifacts/book_with_tabs_and_colours.xlsx')))
56
+ b = Workbook::Book.new
57
+ assert_equal("xlsx",b.file_extension(File.new(File.join(File.dirname(__FILE__), 'artifacts/book_with_tabs_and_colours.xlsx'))))
58
+ end
59
+
47
60
  def test_parent_child
48
61
  b = Workbook::Book.new [[1,2,3],[1,2,3]]
49
62
  assert_equal(Workbook::Sheet, b.first.class)
@@ -67,4 +80,39 @@ class TestWorkbook < Test::Unit::TestCase
67
80
  assert_raises(ArgumentError) { Workbook::Book.read("test string here", :ods) }
68
81
  assert_raises(ArgumentError) { Workbook::Book.read("test string here", :xlsx) }
69
82
  end
83
+
84
+ def test_push_and_ltlt
85
+ b = Workbook::Book.new [["a","b"],[1,2]]
86
+ b.push Workbook::Sheet.new([["a","b"],[2,2]])
87
+ b.push Workbook::Sheet.new([["a","b"],[3,2]])
88
+ b << Workbook::Sheet.new([["a","b"],[4,2]])
89
+ b.push Workbook::Sheet.new([["a","b"],[5,2]])
90
+ b << Workbook::Sheet.new([["a","b"],[6,2]])
91
+ b.push Workbook::Sheet.new([["a","b"],[7,2]])
92
+
93
+ # puts b.index b.last
94
+ 7.times { |time| assert_equal(b,b[0].book) }
95
+ end
96
+
97
+ def test_removal_of_sheets_pop_and_delete_at_works_as_expected
98
+ b = Workbook::Book.new [["a","b"],[1,2]]
99
+ b.push Workbook::Sheet.new([["a","b"],[2,2]])
100
+ b.push Workbook::Sheet.new([["a","b"],[3,2]])
101
+ b << Workbook::Sheet.new([["a","b"],[4,2]])
102
+ b.push Workbook::Sheet.new([["a","b"],[5,2]])
103
+ b << Workbook::Sheet.new([["a","b"],[6,2]])
104
+ b.push Workbook::Sheet.new([["a","b"],[7,2]])
105
+
106
+ assert_equal(7, b.count)
107
+ assert_equal(5,b[4][0][1][0].value)
108
+ b.delete_at(4)
109
+ assert_equal(6, b.count)
110
+ assert_equal(6,b[4][0][1][0].value)
111
+ b.pop(3)
112
+ assert_equal(3, b.count)
113
+ end
114
+
115
+ def test_supported_mime_types
116
+ assert_equal true, Workbook::SUPPORTED_MIME_TYPES.include?('text/csv')
117
+ end
70
118
  end
data/test/test_cell.rb CHANGED
@@ -10,7 +10,7 @@ class TestCell < Test::Unit::TestCase
10
10
  w = Workbook::Cell.new "asdf"
11
11
  assert_equal("asdf",w.value)
12
12
 
13
- assert_raise(ArgumentError) { w = Workbook::Cell.new :asdf }
13
+ assert_raise(ArgumentError) { w = Workbook::Cell.new Workbook::Row }
14
14
 
15
15
  t = Time.now
16
16
  w = Workbook::Cell.new t
data/test/test_format.rb CHANGED
@@ -19,6 +19,14 @@ class TestFormat < Test::Unit::TestCase
19
19
 
20
20
  end
21
21
 
22
+ def test_available_raws
23
+ deet = Time.now
24
+ f = Workbook::Format.new {}
25
+ assert_equal([], f.available_raws)
26
+ f.add_raw deet
27
+ assert_equal([Time], f.available_raws)
28
+ end
29
+
22
30
  def test_merge
23
31
  a = Workbook::Format.new({:background=>:red})
24
32
  b = Workbook::Format.new({:background=>:yellow, :color=>:green})
@@ -0,0 +1,68 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), 'helper')
3
+
4
+ class TestToCacheClass
5
+ include Workbook::Modules::Cache
6
+ def basic_fetch
7
+ fetch_cache(:a){
8
+ sleep(0.5)
9
+ "return"
10
+ }
11
+ end
12
+ def expiring_fetch
13
+ fetch_cache(:a,Time.now+0.6){
14
+ sleep(0.5)
15
+ "return"
16
+ }
17
+ end
18
+ end
19
+
20
+ module Modules
21
+ class TestTableDiffSort < Test::Unit::TestCase
22
+ def test_basic_fetch
23
+ c = TestToCacheClass.new
24
+ c.debug_cache = false
25
+ start_time = Time.now
26
+ c.basic_fetch
27
+ diff_time = Time.now-start_time
28
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
29
+ c.basic_fetch
30
+ diff_time = Time.now-start_time
31
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
32
+ c.basic_fetch
33
+ diff_time = Time.now-start_time
34
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
35
+ end
36
+ def test_basic_fetch_invalidate_cache!
37
+ c = TestToCacheClass.new
38
+ start_time = Time.now
39
+ c.basic_fetch
40
+ diff_time = Time.now-start_time
41
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
42
+ c.basic_fetch
43
+ diff_time = Time.now-start_time
44
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
45
+ c.invalidate_cache!
46
+ c.basic_fetch
47
+ diff_time = Time.now-start_time
48
+ assert_equal(true,(diff_time > 1 and diff_time < 1.01))
49
+ end
50
+ def test_basic_fetch_invalidate_by_expiration
51
+ c = TestToCacheClass.new
52
+ start_time = Time.now
53
+ c.expiring_fetch
54
+ diff_time = Time.now-start_time
55
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
56
+ c.expiring_fetch
57
+ diff_time = Time.now-start_time
58
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
59
+ c.expiring_fetch
60
+ diff_time = Time.now-start_time
61
+ assert_equal(true,(diff_time > 0.5 and diff_time < 0.51))
62
+ sleep(0.5)
63
+ diff_time = Time.now-start_time
64
+ assert_equal(true,(diff_time > 1 and diff_time < 1.01))
65
+ end
66
+
67
+ end
68
+ end
@@ -106,7 +106,6 @@ module Modules
106
106
  # ba = [['a','b','c','d'],[1,2,3,4],[3,2,3,4],[3,3,3,4],[4,2,3,4],[]]
107
107
  # bb = [['a','b','c','d'],[1,2,3,4],[3,2,3,4],[3,2,3,4],[],[5,2,3,4]]
108
108
  # hence,
109
- expected = [['a','b','c','d'],[1,2,3,4],[3,2,3,4],[3,'3 (was: 2)',3,4],[4,2,3,4],['(was: 5)','(was: 2)','(was: 3)','(was: 4)']]
110
109
 
111
110
  tself = ba.sheet.table
112
111
  tother = bb.sheet.table
@@ -115,5 +114,17 @@ module Modules
115
114
  assert_equal("a,b,c,d\n1,2,3,4\n3,2,3,4\n3,3 (was: 2),3,4\n4,2,3,4\n(was: 5),(was: 2),(was: 3),(was: 4)\n",diff_result.to_csv)
116
115
  diff_result.sheet.book.write_to_xls
117
116
  end
117
+
118
+ def test_workbook_diff
119
+ ba = Workbook::Book.new [['a','b','c','d'],[1,2,3,4],[4,2,3,4],[3,2,3,4],[3,3,3,4]]
120
+ bb = Workbook::Book.new [['a','b','c','d'],[1,2,3,4],[3,2,3,4],[5,2,3,4],[3,2,3,4]]
121
+ ba << [['e','f','g','h'],[1,2,3,4],[4,2,3,4],[3,2,3,4],[3,3,3,4]]
122
+ bb << [['e','f','g','h'],[1,2,2,2],[4,2,3,4],[3,2,3,4],[3,3,3,6]]
123
+ diff_result = ba.diff bb
124
+
125
+ assert_equal("a,b,c,d\n1,2,3,4\n3,2,3,4\n3,3 (was: 2),3,4\n4,2,3,4\n(was: 5),(was: 2),(was: 3),(was: 4)\n",diff_result[0][0].to_csv)
126
+ assert_equal("e,f,g,h\n1,2,3 (was: 2),4 (was: 2)\n3,2,3,4\n3,3,3,4 (was: 6)\n4,2,3,4\n",diff_result[1][0].to_csv)
127
+
128
+ end
118
129
  end
119
130
  end
@@ -58,5 +58,11 @@ module Readers
58
58
  end
59
59
  assert_equal(true,failed_properly)
60
60
  end
61
+ def test_multi_sheet_opening
62
+ b = Workbook::Book.open(File.join(File.dirname(__FILE__), 'artifacts/simple_sheet_many_sheets.xls'))
63
+ raw_xls = b.template.raws[Spreadsheet::Excel::Workbook]
64
+ assert_equal(["Diff_10", "Diff_9", "Diff_8", "Diff_7", "Diff_6", "Diff_5", "Diff_4", "Diff_3", "Diff_2", "Diff_1"], b.collect{|a| a.name})
65
+ assert_equal([10, 9, 8, 7, 6, 5, 4, 3, 2, 1], b.collect{|a| a.table[1][0].value})
66
+ end
61
67
  end
62
68
  end
@@ -9,9 +9,9 @@ module Readers
9
9
  assert_equal(90588,w.sheet.table[2][:b].value)
10
10
  assert_equal(DateTime.new(2011,11,15),w.sheet.table[3][:d].value)
11
11
  # assert_equal("#CCFFCC",w.sheet.table[3][:c].format[:background_color]) #colour compatibility turned off for now...
12
- assert_equal(8,w.sheet.table.first[:b].format[:width].round)
13
- assert_equal(4,w.sheet.table.first[:a].format[:width].round)
14
- assert_equal(25,w.sheet.table.first[:c].format[:width].round)
12
+ # assert_equal(8,w.sheet.table.first[:b].format[:width].round)
13
+ # assert_equal(4,w.sheet.table.first[:a].format[:width].round)
14
+ # assert_equal(25,w.sheet.table.first[:c].format[:width].round)
15
15
  end
16
16
  def test_open_native_xlsx
17
17
  w = Workbook::Book.new
@@ -29,11 +29,12 @@ module Readers
29
29
  assert_equal(nil,w.ms_formatting_to_strftime(nil));
30
30
  assert_equal(nil,w.ms_formatting_to_strftime(""));
31
31
  end
32
- def test_monkey_patched_ruby_xl_is_date_format?
33
- w = RubyXL::Workbook.new
34
- assert_equal(false, w.is_date_format?(nil))
35
- assert_equal(false, w.is_date_format?(""))
36
- assert_equal(true, w.is_date_format?("D-M-YYY"))
37
- end
32
+
33
+ # def test_monkey_patched_ruby_xl_is_date_format?
34
+ # w = RubyXL::Workbook.new
35
+ # assert_equal(false, w.is_date_format?(nil))
36
+ # assert_equal(false, w.is_date_format?(""))
37
+ # assert_equal(true, w.is_date_format?("D-M-YYY"))
38
+ # end
38
39
  end
39
40
  end
data/test/test_row.rb CHANGED
@@ -104,7 +104,7 @@ class TestRow < Test::Unit::TestCase
104
104
  assert_equal(date, r2[:asdfasd].value)
105
105
  assert_equal(date, r2[1].value)
106
106
  end
107
-
107
+
108
108
 
109
109
  def test_to_hash_with_values
110
110
  t = Workbook::Table.new
@@ -118,7 +118,7 @@ class TestRow < Test::Unit::TestCase
118
118
  expected = {:test=>2, :asdfasd=>date}
119
119
  assert_equal(expected, r2.to_hash_with_values)
120
120
  end
121
-
121
+
122
122
  def test_to_hash_cache
123
123
  t = Workbook::Table.new
124
124
  t << ["test", "asdf-asd"]
@@ -129,9 +129,9 @@ class TestRow < Test::Unit::TestCase
129
129
  assert_equal(3, r[:test].value)
130
130
  assert_equal(3, r[:test].value)
131
131
  t.last[:test] = nil
132
- assert_equal(nil, r[:test].value)
132
+ assert_equal(nil, r[:test].value)
133
133
  r[:test] = 5
134
- assert_equal(5, r[:test].value)
134
+ assert_equal(5, r[:test].value)
135
135
  end
136
136
 
137
137
  def test_compare
@@ -217,14 +217,14 @@ class TestRow < Test::Unit::TestCase
217
217
  table.push Workbook::Row.new(["a","b"])
218
218
  table[1] = Workbook::Row.new([1,2])
219
219
  assert_equal(1,table[1][:a].value)
220
- assert_equal(2,table[1][:b].value)
221
-
220
+ assert_equal(2,table[1][:b].value)
221
+
222
222
  b = Workbook::Book.new
223
223
  table = b.sheet.table
224
224
  table.push Workbook::Row.new(["a","b"])
225
225
  table[1] = [1,2]
226
226
  assert_equal(1,table[1][:a].value)
227
- assert_equal(2,table[1][:b].value)
227
+ assert_equal(2,table[1][:b].value)
228
228
  end
229
229
 
230
230
  def test_preservation_of_format_on_assign
@@ -236,7 +236,18 @@ class TestRow < Test::Unit::TestCase
236
236
  assert_equal("#f00",row[0].format["background"])
237
237
  end
238
238
 
239
- def test_row_hash_index_assignment
239
+ def test_find_by_string
240
+ b = Workbook::Book.new
241
+ table = b.sheet.table
242
+ table << Workbook::Row.new(["a","b"])
243
+ row = Workbook::Row.new([],table)
244
+ row[1]= 12
245
+ assert_equal(12, table.last["b"])
246
+ assert_equal(nil, table.last["a"])
247
+
248
+ end
249
+
250
+ def test_row_hash_index_string_assignment
240
251
  b = Workbook::Book.new
241
252
  table = b.sheet.table
242
253
  table << Workbook::Row.new(["a","b"])
@@ -245,6 +256,8 @@ class TestRow < Test::Unit::TestCase
245
256
  assert_equal(12, table.last.last.value)
246
257
  row[:b]= 15
247
258
  assert_equal(15, table.last.last.value)
259
+ row["b"]= 18
260
+ assert_equal(18, table.last.last.value)
248
261
  end
249
262
 
250
263
  def test_trim!
@@ -316,4 +329,48 @@ class TestRow < Test::Unit::TestCase
316
329
  assert_equal(c, d)
317
330
 
318
331
  end
332
+
333
+ def test_add
334
+ a = Workbook::Row.new
335
+ a << 1
336
+ a << 2
337
+ a << "asdf"
338
+ a << 2.2
339
+ a.push(5)
340
+ assert_equal(1,a[0].value)
341
+ assert_equal(2,a[1].value)
342
+ assert_equal("asdf",a[2].value)
343
+ assert_equal(2.2,a[3].value)
344
+ assert_equal(5,a[4].value)
345
+ end
346
+
347
+ def test_plus
348
+ header = Workbook::Row.new([:a,:b])
349
+ a = Workbook::Row.new
350
+ table = Workbook::Table.new
351
+ table << header
352
+ table << a
353
+ assert_equal(table, a.table)
354
+ assert_equal(Workbook::Row, (a + [1,1]).class )
355
+ assert_equal([1,1],(a + [1,1]).to_a )
356
+ assert_equal(Workbook::Cell,(a + [1,1])[0].class )
357
+ a += [1,1]
358
+ assert_equal([1,1],a.to_a )
359
+ assert_equal(Workbook::Row, a.class )
360
+ assert_equal(nil, a.table)
361
+ assert_equal(Workbook::Cell,a[0].class)
362
+ end
363
+
364
+ def test_concat
365
+ header = Workbook::Row.new([:a,:b])
366
+ a = Workbook::Row.new
367
+ table = Workbook::Table.new
368
+ table << header
369
+ table << a
370
+ a.concat [1,1]
371
+ assert_equal([1,1],a.to_a )
372
+ assert_equal(Workbook::Row, a.class )
373
+ assert_equal(table, a.table)
374
+ assert_equal(Workbook::Cell,a[0].class)
375
+ end
319
376
  end
data/test/test_sheet.rb CHANGED
@@ -74,4 +74,12 @@ class TestWorkbook < Test::Unit::TestCase
74
74
  printer.print(:path => ".", :profile => "profile")
75
75
 
76
76
  end
77
+ def test_name
78
+ b = Workbook::Book.new [["a","b"],[1,2]]
79
+ b.push Workbook::Sheet.new([["a","b"],[2,2]])
80
+ b.push Workbook::Sheet.new([["a","b"],[3,2]])
81
+
82
+ # puts b.index b.last
83
+ assert_equal(["Sheet 1", "Sheet 2", "Sheet 3"], b.collect{|a| a.name})
84
+ end
77
85
  end
data/test/test_table.rb CHANGED
@@ -121,8 +121,37 @@ class TestTable< Test::Unit::TestCase
121
121
  assert_equal(27,t.alpha_index_to_number_index("AB"))
122
122
  assert_equal(51,t.alpha_index_to_number_index("AZ"))
123
123
  assert_equal(52,t.alpha_index_to_number_index("BA"))
124
+ assert_equal((27*26)-1,t.alpha_index_to_number_index("ZZ"))
124
125
  end
125
126
 
127
+ def test_multirowselect_through_collections
128
+ w = Workbook::Book.new [["a","b"],[1,2],[3,4]]
129
+ t = w.sheet.table
130
+ assert_equal(Workbook::Table,t[0..2].class)
131
+ assert_equal(2,t[0..2][1][1])
132
+ end
133
+
134
+ def test_table
135
+ w = Workbook::Book.new [[nil,nil],["a","b"],[1,2],[3,4]]
136
+ t = w.sheet.table
137
+ w2 = Workbook::Book.new
138
+ w2.sheet.table = t[2..3]
139
+ assert_equal("1,2\n3,4\n", w2.sheet.table.to_csv)
140
+ end
141
+ def test_array_style_assignment
142
+ w = Workbook::Book.new [["a","b"],[1,2],[3,4]]
143
+ t = w.sheet.table
144
+ r = t[1].clone
145
+ assert_equal(nil, r.table)
146
+ t[2] = r
147
+ assert_equal(t, r.table)
148
+ end
149
+ def test_delete_at
150
+ w = Workbook::Book.new [["a","b"],[1,2],[3,4]]
151
+ t = w.sheet.table
152
+ t.delete_at 2
153
+ assert_equal(1, t.last.first.value)
154
+ end
126
155
  def test_trim!
127
156
  t = Workbook::Table.new
128
157
  t << [1,2,3]
@@ -138,4 +167,23 @@ class TestTable< Test::Unit::TestCase
138
167
  t.trim!
139
168
  assert_equal("1,2,3\n,,\n1,2,\n",t.to_csv)
140
169
  end
170
+ def test_performance
171
+ table = Workbook::Table.new
172
+ headers = 1000.times.collect{|a| "header#{a}"}
173
+ first_row = 1000.times.collect{|a| Time.now}
174
+ table << headers.shuffle
175
+ table << first_row
176
+ 100.times do |times|
177
+ row = table[1].clone
178
+ table << row
179
+ headers.each do |a|
180
+ row[a.to_sym]=Time.now
181
+ end
182
+ end
183
+ last_line = table.count-1
184
+ first_few_lines = table[12][0].value - table[2][0].value
185
+ last_few_lines = table[last_line][0].value - table[last_line-10][0].value
186
+ # puts [first_few_lines,last_few_lines].join(" vs ")
187
+ assert_equal(true, first_few_lines*1.10 > last_few_lines) # 10% slower is acceptable
188
+ end
141
189
  end