axlsx 1.0.16 → 1.0.18
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.
- data/.yardopts +1 -0
- data/CHANGELOG.md +7 -0
- data/README.md +105 -46
- data/examples/example.rb +172 -142
- data/lib/axlsx/content_type/content_type.rb +4 -3
- data/lib/axlsx/content_type/default.rb +1 -0
- data/lib/axlsx/content_type/override.rb +1 -0
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +1 -0
- data/lib/axlsx/drawing/axis.rb +1 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +1 -0
- data/lib/axlsx/drawing/bar_series.rb +1 -0
- data/lib/axlsx/drawing/cat_axis.rb +1 -0
- data/lib/axlsx/drawing/cat_axis_data.rb +1 -0
- data/lib/axlsx/drawing/chart.rb +4 -4
- data/lib/axlsx/drawing/drawing.rb +1 -0
- data/lib/axlsx/drawing/graphic_frame.rb +1 -0
- data/lib/axlsx/drawing/hyperlink.rb +1 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +1 -0
- data/lib/axlsx/drawing/line_series.rb +1 -0
- data/lib/axlsx/drawing/marker.rb +1 -0
- data/lib/axlsx/drawing/one_cell_anchor.rb +1 -0
- data/lib/axlsx/drawing/pic.rb +2 -1
- data/lib/axlsx/drawing/picture_locking.rb +1 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +1 -0
- data/lib/axlsx/drawing/pie_series.rb +1 -0
- data/lib/axlsx/drawing/scaling.rb +1 -0
- data/lib/axlsx/drawing/ser_axis.rb +1 -0
- data/lib/axlsx/drawing/series.rb +1 -0
- data/lib/axlsx/drawing/series_title.rb +1 -0
- data/lib/axlsx/drawing/title.rb +1 -0
- data/lib/axlsx/drawing/two_cell_anchor.rb +1 -0
- data/lib/axlsx/drawing/val_axis.rb +1 -0
- data/lib/axlsx/drawing/val_axis_data.rb +1 -0
- data/lib/axlsx/drawing/view_3D.rb +1 -0
- data/lib/axlsx/package.rb +86 -38
- data/lib/axlsx/rels/relationship.rb +4 -3
- data/lib/axlsx/rels/relationships.rb +1 -0
- data/lib/axlsx/stylesheet/border.rb +1 -0
- data/lib/axlsx/stylesheet/border_pr.rb +1 -0
- data/lib/axlsx/stylesheet/cell_alignment.rb +1 -0
- data/lib/axlsx/stylesheet/cell_protection.rb +1 -0
- data/lib/axlsx/stylesheet/cell_style.rb +1 -0
- data/lib/axlsx/stylesheet/color.rb +1 -0
- data/lib/axlsx/stylesheet/fill.rb +1 -0
- data/lib/axlsx/stylesheet/font.rb +8 -0
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +1 -0
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -0
- data/lib/axlsx/stylesheet/styles.rb +12 -9
- data/lib/axlsx/stylesheet/table_style.rb +1 -0
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -0
- data/lib/axlsx/stylesheet/table_styles.rb +1 -0
- data/lib/axlsx/stylesheet/xf.rb +1 -0
- data/lib/axlsx/util/cbf.rb +1 -0
- data/lib/axlsx/util/constants.rb +23 -14
- data/lib/axlsx/util/ms_off_crypto.rb +1 -1
- data/lib/axlsx/util/parser.rb +1 -0
- data/lib/axlsx/util/simple_typed_list.rb +2 -1
- data/lib/axlsx/util/storage.rb +1 -0
- data/lib/axlsx/util/validators.rb +11 -2
- data/lib/axlsx/version.rb +2 -1
- data/lib/axlsx/workbook/shared_strings_table.rb +71 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +69 -0
- data/lib/axlsx/workbook/workbook.rb +47 -25
- data/lib/axlsx/workbook/worksheet/cell.rb +131 -78
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +29 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +94 -0
- data/lib/axlsx/workbook/worksheet/row.rb +44 -12
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +158 -44
- data/lib/axlsx.rb +16 -10
- data/test/content_type/tc_content_type.rb +2 -0
- data/test/content_type/tc_default.rb +2 -0
- data/test/content_type/tc_override.rb +1 -0
- data/test/drawing/tc_chart.rb +2 -2
- data/test/stylesheet/tc_cell_alignment.rb +8 -3
- data/test/stylesheet/tc_font.rb +8 -0
- data/test/stylesheet/tc_styles.rb +6 -2
- data/test/tc_package.rb +31 -0
- data/test/workbook/tc_shared_strings_table.rb +39 -0
- data/test/workbook/tc_shared_strings_table.rb~ +8 -0
- data/test/workbook/tc_workbook.rb +8 -0
- data/test/workbook/worksheet/tc_cell.rb +52 -9
- data/test/workbook/worksheet/tc_date_time_converter.rb +127 -0
- data/test/workbook/worksheet/tc_date_time_converter.rb~ +69 -0
- data/test/workbook/worksheet/tc_page_margins.rb +100 -0
- data/test/workbook/worksheet/tc_row.rb +36 -0
- data/test/workbook/worksheet/tc_worksheet.rb +97 -3
- metadata +33 -40
|
@@ -10,7 +10,7 @@ class TestCell < Test::Unit::TestCase
|
|
|
10
10
|
@row = @ws.add_row
|
|
11
11
|
@c = @row.add_cell 1, :type=>:float, :style=>1
|
|
12
12
|
end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def test_initialize
|
|
15
15
|
assert_equal(@row.cells.last, @c, "the cell was added to the row")
|
|
16
16
|
assert_equal(@c.type, :float, "type option is applied")
|
|
@@ -18,11 +18,16 @@ class TestCell < Test::Unit::TestCase
|
|
|
18
18
|
assert_equal(@c.value, 1.0, "type option is applied and value is casted")
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
def test_style_date_data
|
|
22
23
|
c = Axlsx::Cell.new(@c.row, Time.now)
|
|
23
24
|
assert_equal(Axlsx::STYLE_DATE, c.style)
|
|
24
25
|
end
|
|
25
26
|
|
|
27
|
+
def test_row
|
|
28
|
+
assert_equal(@c.row, @row)
|
|
29
|
+
end
|
|
30
|
+
|
|
26
31
|
def test_index
|
|
27
32
|
assert_equal(@c.index, @row.cells.index(@c))
|
|
28
33
|
end
|
|
@@ -41,20 +46,22 @@ class TestCell < Test::Unit::TestCase
|
|
|
41
46
|
|
|
42
47
|
def test_style
|
|
43
48
|
assert_raise(ArgumentError, "must reject invalid style indexes") { @c.style=@c.row.worksheet.workbook.styles.cellXfs.size }
|
|
44
|
-
assert_nothing_raised("must allow valid style index changes") {@c.style=1}
|
|
49
|
+
assert_nothing_raised("must allow valid style index changes") {@c.style=1}
|
|
45
50
|
assert_equal(@c.style, 1)
|
|
46
51
|
end
|
|
47
52
|
|
|
48
53
|
def test_type
|
|
49
|
-
assert_raise(ArgumentError, "type must be :string, :integer, :float, :time") { @c.type = :array }
|
|
54
|
+
assert_raise(ArgumentError, "type must be :string, :integer, :float, :date, :time, :boolean") { @c.type = :array }
|
|
50
55
|
assert_nothing_raised("type can be changed") { @c.type = :string }
|
|
51
56
|
assert_equal(@c.value, "1.0", "changing type casts the value")
|
|
52
|
-
|
|
57
|
+
|
|
53
58
|
assert_equal(@row.add_cell(Time.now).type, :time, 'time should be time')
|
|
59
|
+
assert_equal(@row.add_cell(Date.today).type, :date, 'date should be date')
|
|
60
|
+
assert_equal(@row.add_cell(true).type, :boolean, 'boolean should be boolean')
|
|
54
61
|
end
|
|
55
62
|
|
|
56
63
|
def test_value
|
|
57
|
-
assert_raise(ArgumentError, "type must be :string, :integer, :float, :time") { @c.type = :array }
|
|
64
|
+
assert_raise(ArgumentError, "type must be :string, :integer, :float, :date, :time, :boolean") { @c.type = :array }
|
|
58
65
|
assert_nothing_raised("type can be changed") { @c.type = :string }
|
|
59
66
|
assert_equal(@c.value, "1.0", "changing type casts the value")
|
|
60
67
|
end
|
|
@@ -66,14 +73,17 @@ class TestCell < Test::Unit::TestCase
|
|
|
66
73
|
def test_cell_type_from_value
|
|
67
74
|
assert_equal(@c.send(:cell_type_from_value, 1.0), :float)
|
|
68
75
|
assert_equal(@c.send(:cell_type_from_value, 1), :integer)
|
|
76
|
+
assert_equal(@c.send(:cell_type_from_value, Date.today), :date)
|
|
69
77
|
assert_equal(@c.send(:cell_type_from_value, Time.now), :time)
|
|
70
78
|
assert_equal(@c.send(:cell_type_from_value, []), :string)
|
|
71
79
|
assert_equal(@c.send(:cell_type_from_value, "d"), :string)
|
|
72
80
|
assert_equal(@c.send(:cell_type_from_value, nil), :string)
|
|
73
81
|
assert_equal(@c.send(:cell_type_from_value, -1), :integer)
|
|
82
|
+
assert_equal(@c.send(:cell_type_from_value, true), :boolean)
|
|
83
|
+
assert_equal(@c.send(:cell_type_from_value, false), :boolean)
|
|
74
84
|
end
|
|
75
85
|
|
|
76
|
-
def test_cast_value
|
|
86
|
+
def test_cast_value
|
|
77
87
|
@c.type = :string
|
|
78
88
|
assert_equal(@c.send(:cast_value, 1.0), "1.0")
|
|
79
89
|
@c.type = :integer
|
|
@@ -82,7 +92,9 @@ class TestCell < Test::Unit::TestCase
|
|
|
82
92
|
assert_equal(@c.send(:cast_value, "1.0"), 1.0)
|
|
83
93
|
@c.type = :string
|
|
84
94
|
assert_equal(@c.send(:cast_value, nil), "")
|
|
85
|
-
|
|
95
|
+
@c.type = :boolean
|
|
96
|
+
assert_equal(@c.send(:cast_value, true), 1)
|
|
97
|
+
assert_equal(@c.send(:cast_value, false), 0)
|
|
86
98
|
end
|
|
87
99
|
|
|
88
100
|
def test_color
|
|
@@ -180,7 +192,7 @@ class TestCell < Test::Unit::TestCase
|
|
|
180
192
|
@c.row.add_cell 2
|
|
181
193
|
@c.row.add_cell 3
|
|
182
194
|
@c.merge "A2"
|
|
183
|
-
assert_equal(@c.row.worksheet.merged_cells.last, "A1:A2")
|
|
195
|
+
assert_equal(@c.row.worksheet.merged_cells.last, "A1:A2")
|
|
184
196
|
end
|
|
185
197
|
|
|
186
198
|
def test_merge_with_cell
|
|
@@ -188,7 +200,38 @@ class TestCell < Test::Unit::TestCase
|
|
|
188
200
|
@c.row.add_cell 2
|
|
189
201
|
@c.row.add_cell 3
|
|
190
202
|
@c.merge @row.cells.last
|
|
191
|
-
assert_equal(@c.row.worksheet.merged_cells.last, "A1:C1")
|
|
203
|
+
assert_equal(@c.row.worksheet.merged_cells.last, "A1:C1")
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_equality
|
|
207
|
+
c2 = @row.add_cell 1, :type=>:float, :style=>1
|
|
208
|
+
assert(c2.shareable(@c))
|
|
209
|
+
c3 = @row.add_cell 2, :type=>:float, :style=>1
|
|
210
|
+
c4 = @row.add_cell 1, :type=>:float, :style=>1, :color => "#FFFFFFFF"
|
|
211
|
+
assert_equal(c4.shareable(c2) ,false)
|
|
212
|
+
c5 = @row.add_cell 1, :type=>:float, :style=>1, :color => "#FFFFFFFF"
|
|
213
|
+
assert(c5.shareable(c4))
|
|
214
|
+
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_ssti
|
|
218
|
+
assert_raise(ArgumentError, "ssti must be an unsigned integer!") { @c.send(:ssti=, -1) }
|
|
219
|
+
@c.send :ssti=, 1
|
|
220
|
+
assert_equal(@c.ssti, 1)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def test_to_xml
|
|
224
|
+
# TODO This could use some much more stringent testing related to the xml content generated!
|
|
225
|
+
row = @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)"]
|
|
226
|
+
schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
|
|
227
|
+
doc = Nokogiri::XML(@ws.to_xml)
|
|
228
|
+
errors = []
|
|
229
|
+
schema.validate(doc).each do |error|
|
|
230
|
+
errors.push error
|
|
231
|
+
puts error.message
|
|
232
|
+
end
|
|
233
|
+
assert(errors.empty?, "error free validation")
|
|
234
|
+
|
|
192
235
|
end
|
|
193
236
|
|
|
194
237
|
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'axlsx.rb'
|
|
4
|
+
|
|
5
|
+
class TestDateTimeConverter < Test::Unit::TestCase
|
|
6
|
+
def setup
|
|
7
|
+
@margin_of_error = 0.000_001
|
|
8
|
+
@extended_time_range = begin
|
|
9
|
+
Time.parse "1893-08-05"
|
|
10
|
+
Time.parse "9999-12-31T23:59:59Z"
|
|
11
|
+
true
|
|
12
|
+
rescue
|
|
13
|
+
false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_date_to_serial_1900
|
|
18
|
+
Axlsx::Workbook.date1904 = false
|
|
19
|
+
tests = if @extended_time_range
|
|
20
|
+
{ # examples taken straight from the spec
|
|
21
|
+
"1893-08-05" => -2338.0,
|
|
22
|
+
"1900-01-01" => 2.0,
|
|
23
|
+
"1910-02-03" => 3687.0,
|
|
24
|
+
"2006-02-01" => 38749.0,
|
|
25
|
+
"9999-12-31" => 2958465.0
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
{ # examples taken inside the possible values
|
|
29
|
+
"1970-01-01" => 25569.0, # Unix epoch
|
|
30
|
+
"1970-01-02" => 25570.0,
|
|
31
|
+
"2006-02-01" => 38749.0,
|
|
32
|
+
"2038-01-19" => 50424.0, # max date using signed timestamp in 32bit
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
tests.each do |date_string, expected|
|
|
36
|
+
serial = Axlsx::DateTimeConverter::date_to_serial Date.parse(date_string)
|
|
37
|
+
assert_equal expected, serial
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_date_to_serial_1904
|
|
42
|
+
Axlsx::Workbook.date1904 = true
|
|
43
|
+
tests = if @extended_time_range
|
|
44
|
+
{ # examples taken straight from the spec
|
|
45
|
+
"1893-08-05" => -3800.0,
|
|
46
|
+
"1904-01-01" => 0.0,
|
|
47
|
+
"1910-02-03" => 2225.0,
|
|
48
|
+
"2006-02-01" => 37287.0,
|
|
49
|
+
"9999-12-31" => 2957003.0
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
{ # examples taken inside the possible values
|
|
53
|
+
"1970-01-01" => 24107.0, # Unix epoch
|
|
54
|
+
"1970-01-02" => 24108.0,
|
|
55
|
+
"2006-02-01" => 37287.0,
|
|
56
|
+
"2038-01-19" => 48962.0, # max date using signed timestamp in 32bit
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
tests.each do |date_string, expected|
|
|
60
|
+
serial = Axlsx::DateTimeConverter::date_to_serial Date.parse(date_string)
|
|
61
|
+
assert_equal expected, serial
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_time_to_serial_1900
|
|
66
|
+
Axlsx::Workbook.date1904 = false
|
|
67
|
+
tests = if @extended_time_range
|
|
68
|
+
{ # examples taken straight from the spec
|
|
69
|
+
"1893-08-05T00:00:01Z" => -2337.999989,
|
|
70
|
+
"1899-12-28T18:00:00Z" => -1.25,
|
|
71
|
+
"1910-02-03T10:05:54Z" => 3687.4207639,
|
|
72
|
+
"1900-01-01T12:00:00Z" => 2.5, # wrongly indicated as 1.5 in the spec!
|
|
73
|
+
"9999-12-31T23:59:59Z" => 2958465.9999884
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
{ # examples taken inside the possible values
|
|
77
|
+
"1970-01-01T00:00:00Z" => 25569.0, # Unix epoch
|
|
78
|
+
"1970-01-01T12:00:00Z" => 25569.5,
|
|
79
|
+
"2000-01-01T00:00:00Z" => 36526.0,
|
|
80
|
+
"2038-01-19T03:14:07Z" => 50424.134803, # max signed timestamp in 32bit
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
tests.each do |time_string, expected|
|
|
84
|
+
serial = Axlsx::DateTimeConverter::time_to_serial Time.parse(time_string)
|
|
85
|
+
assert_in_delta expected, serial, @margin_of_error
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_time_to_serial_1904
|
|
90
|
+
Axlsx::Workbook.date1904 = true
|
|
91
|
+
# ruby 1.8.7 cannot parse dates prior to epoch. see http://ruby-doc.org/core-1.8.7/Time.html
|
|
92
|
+
|
|
93
|
+
tests = if @extended_time_range
|
|
94
|
+
{ # examples taken straight from the spec
|
|
95
|
+
"1893-08-05T00:00:01Z" => -3799.999989,
|
|
96
|
+
"1910-02-03T10:05:54Z" => 2225.4207639,
|
|
97
|
+
"1904-01-01T12:00:00Z" => 0.5000000,
|
|
98
|
+
"9999-12-31T23:59:59Z" => 2957003.9999884
|
|
99
|
+
}
|
|
100
|
+
else
|
|
101
|
+
{ # examples taken inside the possible values
|
|
102
|
+
"1970-01-01T00:00:00Z" => 24107.0, # Unix epoch
|
|
103
|
+
"1970-01-01T12:00:00Z" => 24107.5,
|
|
104
|
+
"2000-01-01T00:00:00Z" => 35064.0,
|
|
105
|
+
"2038-01-19T03:14:07Z" => 48962.134803, # max signed timestamp in 32bit
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
tests.each do |time_string, expected|
|
|
109
|
+
serial = Axlsx::DateTimeConverter::time_to_serial Time.parse(time_string)
|
|
110
|
+
assert_in_delta expected, serial, @margin_of_error
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_timezone
|
|
115
|
+
utc = Time.utc 2012 # January 1st, 2012 at 0:00 UTC
|
|
116
|
+
local = begin
|
|
117
|
+
Time.new 2012, 1, 1, 1, 0, 0, 3600 # January 1st, 2012 at 1:00 GMT+1
|
|
118
|
+
rescue ArgumentError
|
|
119
|
+
Time.parse "2012-01-01 01:00:00 +0100"
|
|
120
|
+
end
|
|
121
|
+
assert_equal local, utc
|
|
122
|
+
assert_equal Axlsx::DateTimeConverter::time_to_serial(local), Axlsx::DateTimeConverter::time_to_serial(utc)
|
|
123
|
+
Axlsx::Workbook.date1904 = true
|
|
124
|
+
assert_equal Axlsx::DateTimeConverter::time_to_serial(local), Axlsx::DateTimeConverter::time_to_serial(utc)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'axlsx.rb'
|
|
3
|
+
|
|
4
|
+
class TestConverter < Test::Unit::TestCase
|
|
5
|
+
def setup
|
|
6
|
+
@converter = Axlsx::Converter.new
|
|
7
|
+
@margin_of_error = 0.000_001
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_date_to_serial_1900
|
|
11
|
+
{ # examples taken straight from the spec
|
|
12
|
+
"1893-08-05" => -2338.0,
|
|
13
|
+
"1900-01-01" => 2.0,
|
|
14
|
+
"1910-02-03" => 3687.0,
|
|
15
|
+
"2006-02-01" => 38749.0,
|
|
16
|
+
"9999-12-31" => 2958465.0,
|
|
17
|
+
}.each do |date_string, expected|
|
|
18
|
+
serial = @converter.date_to_serial Date.parse(date_string)
|
|
19
|
+
assert_equal serial, expected
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_date_to_serial_1904
|
|
24
|
+
{ # examples taken straight from the spec
|
|
25
|
+
"1893-08-05" => -3800.0,
|
|
26
|
+
"1904-01-01" => 0.0,
|
|
27
|
+
"1910-02-03" => 2225.0,
|
|
28
|
+
"2006-02-01" => 37287.0,
|
|
29
|
+
"9999-12-31" => 2957003.0,
|
|
30
|
+
}.each do |date_string, expected|
|
|
31
|
+
serial = @converter.date_to_serial Date.parse(date_string), true
|
|
32
|
+
assert_equal serial, expected
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_time_to_serial_1900
|
|
37
|
+
{ # examples taken straight from the spec
|
|
38
|
+
"1893-08-05T00:00:01Z" => -2337.999989,
|
|
39
|
+
"1899-12-28T18:00:00Z" => -1.25,
|
|
40
|
+
"1910-02-03T10:05:54Z" => 3687.4207639,
|
|
41
|
+
"1900-01-01T12:00:00Z" => 2.5, # wrongly indicated as 1.5 in the spec!
|
|
42
|
+
"9999-12-31T23:59:59Z" => 2958465.9999884,
|
|
43
|
+
}.each do |time_string, expected|
|
|
44
|
+
serial = @converter.time_to_serial Time.parse(time_string)
|
|
45
|
+
assert_in_delta serial, expected, @margin_of_error
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_time_to_serial_1904
|
|
50
|
+
{ # examples taken straight from the spec
|
|
51
|
+
"1893-08-05T00:00:01Z" => -3799.999989,
|
|
52
|
+
"1910-02-03T10:05:54Z" => 2225.4207639,
|
|
53
|
+
"1904-01-01T12:00:00Z" => 0.5000000,
|
|
54
|
+
"9999-12-31T23:59:59Z" => 2957003.9999884,
|
|
55
|
+
}.each do |time_string, expected|
|
|
56
|
+
serial = @converter.time_to_serial Time.parse(time_string), true
|
|
57
|
+
assert_in_delta serial, expected, @margin_of_error
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_timezone
|
|
62
|
+
utc = Time.utc 2012 # January 1st, 2012 at 0:00 UTC
|
|
63
|
+
local = Time.new 2012, 1, 1, 1, 0, 0, 3600 # January 1st, 2012 at 1:00 GMT+1
|
|
64
|
+
assert_equal local, utc
|
|
65
|
+
assert_equal @converter.time_to_serial(local), @converter.time_to_serial(utc)
|
|
66
|
+
assert_equal @converter.time_to_serial(local, true), @converter.time_to_serial(utc, true)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'axlsx.rb'
|
|
3
|
+
|
|
4
|
+
class TestPageMargins < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
p = Axlsx::Package.new
|
|
8
|
+
ws = p.workbook.add_worksheet :name=>"hmmm"
|
|
9
|
+
@pm = ws.page_margins
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_initialize
|
|
13
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_LEFT_RIGHT, @pm.left)
|
|
14
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_LEFT_RIGHT, @pm.right)
|
|
15
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_TOP_BOTTOM, @pm.top)
|
|
16
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_TOP_BOTTOM, @pm.bottom)
|
|
17
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_HEADER_FOOTER, @pm.header)
|
|
18
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_HEADER_FOOTER, @pm.footer)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_initialize_with_options
|
|
22
|
+
optioned = Axlsx::PageMargins.new(:left => 2, :right => 3, :top => 2, :bottom => 1, :header => 0.1, :footer => 0.1)
|
|
23
|
+
assert_equal(2, optioned.left)
|
|
24
|
+
assert_equal(3, optioned.right)
|
|
25
|
+
assert_equal(2, optioned.top)
|
|
26
|
+
assert_equal(1, optioned.bottom)
|
|
27
|
+
assert_equal(0.1, optioned.header)
|
|
28
|
+
assert_equal(0.1, optioned.footer)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_set_all_values
|
|
33
|
+
@pm.set(:left => 1.1, :right => 1.2, :top => 1.3, :bottom => 1.4, :header => 0.8, :footer => 0.9)
|
|
34
|
+
assert_equal(1.1, @pm.left)
|
|
35
|
+
assert_equal(1.2, @pm.right)
|
|
36
|
+
assert_equal(1.3, @pm.top)
|
|
37
|
+
assert_equal(1.4, @pm.bottom)
|
|
38
|
+
assert_equal(0.8, @pm.header)
|
|
39
|
+
assert_equal(0.9, @pm.footer)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_set_some_values
|
|
43
|
+
@pm.set(:left => 1.1, :right => 1.2)
|
|
44
|
+
assert_equal(1.1, @pm.left)
|
|
45
|
+
assert_equal(1.2, @pm.right)
|
|
46
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_TOP_BOTTOM, @pm.top)
|
|
47
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_TOP_BOTTOM, @pm.bottom)
|
|
48
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_HEADER_FOOTER, @pm.header)
|
|
49
|
+
assert_equal(Axlsx::PageMargins::DEFAULT_HEADER_FOOTER, @pm.footer)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_to_xml
|
|
53
|
+
@pm.left = 1.1
|
|
54
|
+
@pm.right = 1.2
|
|
55
|
+
@pm.top = 1.3
|
|
56
|
+
@pm.bottom = 1.4
|
|
57
|
+
@pm.header = 0.8
|
|
58
|
+
@pm.footer = 0.9
|
|
59
|
+
xml = Nokogiri::XML::Builder.new
|
|
60
|
+
@pm.to_xml(xml)
|
|
61
|
+
doc = Nokogiri::XML.parse(xml.to_xml)
|
|
62
|
+
assert_equal(1, doc.xpath(".//pageMargins[@left=1.1][@right=1.2][@top=1.3][@bottom=1.4][@header=0.8][@footer=0.9]").size)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_left
|
|
66
|
+
assert_raise(ArgumentError) { @pm.left = -1.2 }
|
|
67
|
+
assert_nothing_raised { @pm.left = 1.5 }
|
|
68
|
+
assert_equal(@pm.left, 1.5)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_right
|
|
72
|
+
assert_raise(ArgumentError) { @pm.right = -1.2 }
|
|
73
|
+
assert_nothing_raised { @pm.right = 1.5 }
|
|
74
|
+
assert_equal(@pm.right, 1.5)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_top
|
|
78
|
+
assert_raise(ArgumentError) { @pm.top = -1.2 }
|
|
79
|
+
assert_nothing_raised { @pm.top = 1.5 }
|
|
80
|
+
assert_equal(@pm.top, 1.5)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_bottom
|
|
84
|
+
assert_raise(ArgumentError) { @pm.bottom = -1.2 }
|
|
85
|
+
assert_nothing_raised { @pm.bottom = 1.5 }
|
|
86
|
+
assert_equal(@pm.bottom, 1.5)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_header
|
|
90
|
+
assert_raise(ArgumentError) { @pm.header = -1.2 }
|
|
91
|
+
assert_nothing_raised { @pm.header = 1.5 }
|
|
92
|
+
assert_equal(@pm.header, 1.5)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_footer
|
|
96
|
+
assert_raise(ArgumentError) { @pm.footer = -1.2 }
|
|
97
|
+
assert_nothing_raised { @pm.footer = 1.5 }
|
|
98
|
+
assert_equal(@pm.footer, 1.5)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -12,6 +12,14 @@ class TestRow < Test::Unit::TestCase
|
|
|
12
12
|
def test_initialize
|
|
13
13
|
assert(@row.cells.empty?, "no cells by default")
|
|
14
14
|
assert_equal(@row.worksheet, @ws, "has a reference to the worksheet")
|
|
15
|
+
assert_nil(@row.height, "height defaults to nil")
|
|
16
|
+
assert(!@row.custom_height?, "no custom height by default")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_initialize_with_fixed_height
|
|
20
|
+
row = @ws.add_row([1,2,3,4,5], :height=>40)
|
|
21
|
+
assert_equal(40, row.height)
|
|
22
|
+
assert(row.custom_height?)
|
|
15
23
|
end
|
|
16
24
|
|
|
17
25
|
def test_style
|
|
@@ -33,4 +41,32 @@ class TestRow < Test::Unit::TestCase
|
|
|
33
41
|
r = @ws.add_row [1,2,3], :style=>0, :types=>:integer
|
|
34
42
|
assert_equal(r.cells.size, 3)
|
|
35
43
|
end
|
|
44
|
+
|
|
45
|
+
def test_custom_height
|
|
46
|
+
@row.height = 20
|
|
47
|
+
assert(@row.custom_height?)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_height
|
|
51
|
+
assert_raise(ArgumentError) { @row.height = -3 }
|
|
52
|
+
assert_nothing_raised { @row.height = 15 }
|
|
53
|
+
assert_equal(15, @row.height)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_to_xml_without_custom_height
|
|
57
|
+
xml = Nokogiri::XML::Builder.new
|
|
58
|
+
@row.to_xml(xml)
|
|
59
|
+
doc = Nokogiri::XML.parse(xml.to_xml)
|
|
60
|
+
assert_equal(0, doc.xpath(".//row[@ht]").size)
|
|
61
|
+
assert_equal(0, doc.xpath(".//row[@customHeight]").size)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_to_xml_with_custom_height
|
|
65
|
+
@row.height = 20
|
|
66
|
+
xml = Nokogiri::XML::Builder.new
|
|
67
|
+
@row.to_xml(xml)
|
|
68
|
+
doc = Nokogiri::XML.parse(xml.to_xml)
|
|
69
|
+
assert_equal(1, doc.xpath(".//row[@ht=20][@customHeight=1]").size)
|
|
70
|
+
end
|
|
71
|
+
|
|
36
72
|
end
|
|
@@ -13,6 +13,29 @@ class TestWorksheet < Test::Unit::TestCase
|
|
|
13
13
|
assert_equal(ws.pn, "worksheets/sheet2.xml")
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def test_page_margins
|
|
17
|
+
assert(@ws.page_margins.is_a? Axlsx::PageMargins)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_page_margins_yeild
|
|
21
|
+
@ws.page_margins do |pm|
|
|
22
|
+
assert(pm.is_a? Axlsx::PageMargins)
|
|
23
|
+
assert(@ws.page_margins == pm)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_initialization_options
|
|
28
|
+
page_margins = {:left => 2, :right => 2, :bottom => 2, :top => 2, :header => 2, :footer => 2}
|
|
29
|
+
optioned = @ws.workbook.add_worksheet(:name => 'bob', :page_margins => page_margins)
|
|
30
|
+
assert_equal(optioned.page_margins.left, page_margins[:left])
|
|
31
|
+
assert_equal(optioned.page_margins.right, page_margins[:right])
|
|
32
|
+
assert_equal(optioned.page_margins.top, page_margins[:top])
|
|
33
|
+
assert_equal(optioned.page_margins.bottom, page_margins[:bottom])
|
|
34
|
+
assert_equal(optioned.page_margins.header, page_margins[:header])
|
|
35
|
+
assert_equal(optioned.page_margins.footer, page_margins[:footer])
|
|
36
|
+
assert_equal(optioned.name, 'bob')
|
|
37
|
+
end
|
|
38
|
+
|
|
16
39
|
def test_rels_pn
|
|
17
40
|
assert_equal(@ws.rels_pn, "worksheets/_rels/sheet1.xml.rels")
|
|
18
41
|
ws = @ws.workbook.add_worksheet
|
|
@@ -28,11 +51,21 @@ class TestWorksheet < Test::Unit::TestCase
|
|
|
28
51
|
def test_index
|
|
29
52
|
assert_equal(@ws.index, @ws.workbook.worksheets.index(@ws))
|
|
30
53
|
end
|
|
31
|
-
|
|
54
|
+
|
|
55
|
+
def test_dimension
|
|
56
|
+
@ws.add_row [1, 2, 3]
|
|
57
|
+
@ws.add_row [4, 5, 6]
|
|
58
|
+
assert_equal @ws.dimension, "A1:C2"
|
|
59
|
+
end
|
|
60
|
+
|
|
32
61
|
def test_referencing
|
|
33
62
|
@ws.add_row [1, 2, 3]
|
|
34
63
|
@ws.add_row [4, 5, 6]
|
|
35
64
|
range = @ws["A1:C2"]
|
|
65
|
+
first_row = @ws[1]
|
|
66
|
+
last_row = @ws[2]
|
|
67
|
+
assert_equal(@ws.rows[0],first_row)
|
|
68
|
+
assert_equal(@ws.rows[1],last_row)
|
|
36
69
|
assert_equal(range.size, 6)
|
|
37
70
|
assert_equal(range.first, @ws.rows.first.cells.first)
|
|
38
71
|
assert_equal(range.last, @ws.rows.last.cells.last)
|
|
@@ -110,6 +143,19 @@ class TestWorksheet < Test::Unit::TestCase
|
|
|
110
143
|
assert(errors.empty?, "error free validation")
|
|
111
144
|
end
|
|
112
145
|
|
|
146
|
+
def test_valid_with_page_margins
|
|
147
|
+
@ws.page_margins.set :left => 9
|
|
148
|
+
schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
|
|
149
|
+
doc = Nokogiri::XML(@ws.to_xml)
|
|
150
|
+
errors = []
|
|
151
|
+
schema.validate(doc).each do |error|
|
|
152
|
+
errors.push error
|
|
153
|
+
puts error.message
|
|
154
|
+
end
|
|
155
|
+
assert(errors.empty?, "error free validation")
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
|
|
113
159
|
def test_relationships
|
|
114
160
|
assert(@ws.relationships.empty?, "No Drawing relationship until you add a chart")
|
|
115
161
|
c = @ws.add_chart Axlsx::Pie3DChart
|
|
@@ -123,6 +169,11 @@ class TestWorksheet < Test::Unit::TestCase
|
|
|
123
169
|
assert_raise(ArgumentError, "worksheet name must be unique") { n = @ws.name; @ws.workbook.add_worksheet(:name=> @ws) }
|
|
124
170
|
end
|
|
125
171
|
|
|
172
|
+
def test_name_size
|
|
173
|
+
assert_raise(ArgumentError, "name too long!") { @ws.name = Array.new(32, "A").join('') }
|
|
174
|
+
assert_nothing_raised { @ws.name = Array.new(31, "A").join('') }
|
|
175
|
+
end
|
|
176
|
+
|
|
126
177
|
def test_update_auto_with_data
|
|
127
178
|
small = @ws.workbook.styles.add_style(:sz=>2)
|
|
128
179
|
big = @ws.workbook.styles.add_style(:sz=>10)
|
|
@@ -130,18 +181,61 @@ class TestWorksheet < Test::Unit::TestCase
|
|
|
130
181
|
@ws.add_row ["chasing windmills", "penut"], :style=>small
|
|
131
182
|
assert(@ws.auto_fit_data.size == 2, "a data item for each column")
|
|
132
183
|
|
|
133
|
-
assert_equal(@ws.auto_fit_data[0], {:sz=>2
|
|
184
|
+
assert_equal(@ws.auto_fit_data[0], {:sz => 2, :longest => "chasing windmills", :fixed=>nil}, "adding a row updates auto_fit_data if the product of the string length and font is greater for the column")
|
|
134
185
|
|
|
135
186
|
|
|
136
187
|
@ws.add_row ["mule"], :style=>big
|
|
137
|
-
assert_equal(@ws.auto_fit_data[0], {:sz=>10,:longest=>"mule"}, "adding a row updates auto_fit_data if the product of the string length and font is greater for the column")
|
|
188
|
+
assert_equal(@ws.auto_fit_data[0], {:sz=>10,:longest=>"mule", :fixed=>nil}, "adding a row updates auto_fit_data if the product of the string length and font is greater for the column")
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_set_fixed_width_column
|
|
192
|
+
@ws.add_row ["mule", "donkey", "horse"], :widths => [20, :ignore, nil]
|
|
193
|
+
assert(@ws.auto_fit_data.size == 3, "a data item for each column")
|
|
194
|
+
assert_equal({:sz=>11, :longest=>"mule", :fixed=>20 }, @ws.auto_fit_data[0], "adding a row with fixed width updates :fixed attribute")
|
|
195
|
+
assert_equal({:sz=>11, :longest=>"", :fixed=>nil}, @ws.auto_fit_data[1], ":ignore does not set any data")
|
|
196
|
+
assert_equal({:sz=>11, :longest=>"horse", :fixed=>nil}, @ws.auto_fit_data[2], "nil, well really anything else just works as normal")
|
|
197
|
+
@ws.add_row ["mule", "donkey", "horse"]
|
|
198
|
+
assert_equal({:sz=>11, :longest=>"donkey", :fixed=>nil}, @ws.auto_fit_data[1])
|
|
199
|
+
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_fixed_widths_with_merged_cells
|
|
203
|
+
@ws.add_row ["hey, I'm like really long and stuff so I think you will merge me."]
|
|
204
|
+
@ws.merge_cells "A1:C1"
|
|
205
|
+
@ws.add_row ["but Im Short!"], :widths=> [14.8]
|
|
206
|
+
assert_equal(@ws.send(:auto_width, @ws.auto_fit_data[0]), 14.8)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def test_fixed_width_to_auto
|
|
210
|
+
@ws.add_row ["hey, I'm like really long and stuff so I think you will merge me."]
|
|
211
|
+
@ws.merge_cells "A1:C1"
|
|
212
|
+
@ws.add_row ["but Im Short!"], :widths=> [14.8]
|
|
213
|
+
assert_equal(@ws.send(:auto_width, @ws.auto_fit_data[0]), 14.8)
|
|
214
|
+
@ws.add_row ["no, I like auto!"], :widths=>[:auto]
|
|
215
|
+
assert_equal(@ws.auto_fit_data[0][:fixed], nil)
|
|
138
216
|
end
|
|
139
217
|
|
|
140
218
|
def test_auto_width
|
|
141
219
|
assert(@ws.send(:auto_width, {:sz=>11, :longest=>"fisheries"}) > @ws.send(:auto_width, {:sz=>11, :longest=>"fish"}), "longer strings get a longer auto_width at the same font size")
|
|
142
220
|
|
|
143
221
|
assert(@ws.send(:auto_width, {:sz=>11, :longest=>"fish"}) < @ws.send(:auto_width, {:sz=>12, :longest=>"fish"}), "larger fonts produce longer with with same string")
|
|
222
|
+
assert_equal(@ws.send(:auto_width, {:sz=>11, :longest => "This is a really long string", :fixed=>0.2}), 0.2, "fixed rules!")
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_fixed_height
|
|
226
|
+
@ws.add_row [1, 2, 3], :height => 40
|
|
227
|
+
assert_equal(40, @ws.rows[-1].height)
|
|
228
|
+
end
|
|
229
|
+
|
|
144
230
|
|
|
231
|
+
def test_set_column_width
|
|
232
|
+
@ws.add_row ["chasing windmills", "penut"]
|
|
233
|
+
assert_equal(@ws.auto_fit_data[0][:fixed], nil, 'no fixed by default')
|
|
234
|
+
@ws.column_widths nil, 0.5
|
|
235
|
+
assert_equal(@ws.auto_fit_data[1][:fixed], 0.5, 'eat my width')
|
|
236
|
+
assert_raise(ArgumentError, 'reject invalid columns') { @ws.column_widths 2, 7, nil }
|
|
237
|
+
assert_raise(ArgumentError, 'only accept unsigned ints') { @ws.column_widths 2, 7, -1 }
|
|
238
|
+
assert_raise(ArgumentError, 'only accept Integer, Float or Fixnum') { @ws.column_widths 2, 7, "-1" }
|
|
145
239
|
end
|
|
146
240
|
|
|
147
241
|
def test_merge_cells
|