caxlsx 2.0.2 → 3.0.4

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 (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -30
  3. data/README.md +65 -151
  4. data/Rakefile +9 -11
  5. data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
  6. data/examples/generate.rb +15 -0
  7. data/lib/axlsx.rb +35 -17
  8. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  9. data/lib/axlsx/content_type/content_type.rb +1 -1
  10. data/lib/axlsx/doc_props/app.rb +1 -1
  11. data/lib/axlsx/doc_props/core.rb +5 -5
  12. data/lib/axlsx/drawing/area_chart.rb +99 -0
  13. data/lib/axlsx/drawing/area_series.rb +110 -0
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +12 -9
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  17. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  18. data/lib/axlsx/drawing/bar_series.rb +12 -14
  19. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  20. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  21. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  22. data/lib/axlsx/drawing/chart.rb +52 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +4 -4
  24. data/lib/axlsx/drawing/drawing.rb +6 -1
  25. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  26. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  27. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  28. data/lib/axlsx/drawing/line_chart.rb +10 -10
  29. data/lib/axlsx/drawing/line_series.rb +32 -3
  30. data/lib/axlsx/drawing/marker.rb +1 -1
  31. data/lib/axlsx/drawing/num_data.rb +4 -4
  32. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  33. data/lib/axlsx/drawing/num_val.rb +3 -1
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  35. data/lib/axlsx/drawing/pic.rb +25 -19
  36. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  38. data/lib/axlsx/drawing/pie_series.rb +6 -6
  39. data/lib/axlsx/drawing/scaling.rb +6 -6
  40. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  41. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  42. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  43. data/lib/axlsx/drawing/series.rb +3 -3
  44. data/lib/axlsx/drawing/series_title.rb +4 -2
  45. data/lib/axlsx/drawing/str_data.rb +3 -3
  46. data/lib/axlsx/drawing/str_val.rb +3 -1
  47. data/lib/axlsx/drawing/title.rb +23 -4
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/view_3D.rb +2 -2
  51. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  52. data/lib/axlsx/package.rb +58 -47
  53. data/lib/axlsx/rels/relationship.rb +27 -26
  54. data/lib/axlsx/rels/relationships.rb +7 -4
  55. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  56. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  58. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  59. data/lib/axlsx/stylesheet/color.rb +1 -3
  60. data/lib/axlsx/stylesheet/font.rb +11 -3
  61. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  62. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  63. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  64. data/lib/axlsx/stylesheet/styles.rb +7 -7
  65. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  66. data/lib/axlsx/util/accessors.rb +6 -6
  67. data/lib/axlsx/util/constants.rb +108 -99
  68. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  69. data/lib/axlsx/util/options_parser.rb +2 -1
  70. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  71. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  72. data/lib/axlsx/util/storage.rb +4 -4
  73. data/lib/axlsx/util/validators.rb +31 -19
  74. data/lib/axlsx/util/zip_command.rb +73 -0
  75. data/lib/axlsx/version.rb +1 -1
  76. data/lib/axlsx/workbook/defined_name.rb +11 -12
  77. data/lib/axlsx/workbook/defined_names.rb +2 -2
  78. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  79. data/lib/axlsx/workbook/workbook.rb +36 -20
  80. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  81. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  82. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  83. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  85. data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
  86. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  87. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  88. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  89. data/lib/axlsx/workbook/worksheet/col.rb +14 -13
  90. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  91. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  92. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  93. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  94. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  96. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  97. data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
  98. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  99. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  100. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  101. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  102. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  103. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  106. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  108. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  109. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  110. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  111. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  112. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  113. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  114. data/lib/axlsx/workbook/worksheet/row.rb +42 -52
  115. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  116. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  117. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  118. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  119. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  120. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  122. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  123. data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
  124. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  125. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  126. data/lib/caxlsx.rb +2 -0
  127. data/test/drawing/tc_area_chart.rb +39 -0
  128. data/test/drawing/tc_area_series.rb +71 -0
  129. data/test/drawing/tc_axis.rb +27 -0
  130. data/test/drawing/tc_bar_chart.rb +71 -0
  131. data/test/drawing/tc_bubble_chart.rb +44 -0
  132. data/test/drawing/tc_bubble_series.rb +21 -0
  133. data/test/drawing/tc_chart.rb +23 -10
  134. data/test/drawing/tc_data_source.rb +6 -0
  135. data/test/drawing/tc_drawing.rb +4 -4
  136. data/test/drawing/tc_hyperlink.rb +1 -1
  137. data/test/drawing/tc_line_chart.rb +5 -5
  138. data/test/drawing/tc_line_series.rb +47 -6
  139. data/test/drawing/tc_one_cell_anchor.rb +1 -1
  140. data/test/drawing/tc_pic.rb +11 -15
  141. data/test/drawing/tc_pie_series.rb +2 -1
  142. data/test/drawing/tc_scatter_series.rb +36 -1
  143. data/test/drawing/tc_series_title.rb +21 -0
  144. data/test/drawing/tc_str_val.rb +9 -0
  145. data/test/drawing/tc_title.rb +21 -0
  146. data/test/fixtures/image1.gif +0 -0
  147. data/test/fixtures/image1.jpeg +0 -0
  148. data/test/fixtures/image1.jpg +0 -0
  149. data/test/fixtures/image1.png +0 -0
  150. data/test/fixtures/image1_fake.jpg +0 -0
  151. data/test/rels/tc_relationship.rb +8 -0
  152. data/test/stylesheet/tc_font.rb +14 -2
  153. data/test/stylesheet/tc_styles.rb +29 -3
  154. data/test/tc_axlsx.rb +37 -0
  155. data/test/tc_helper.rb +2 -0
  156. data/test/tc_package.rb +50 -13
  157. data/test/util/tc_mime_type_utils.rb +13 -0
  158. data/test/util/tc_simple_typed_list.rb +2 -3
  159. data/test/util/tc_validators.rb +35 -11
  160. data/test/workbook/tc_defined_name.rb +12 -4
  161. data/test/workbook/tc_shared_strings_table.rb +16 -1
  162. data/test/workbook/tc_workbook.rb +38 -3
  163. data/test/workbook/tc_workbook_view.rb +50 -0
  164. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  165. data/test/workbook/worksheet/tc_break.rb +1 -1
  166. data/test/workbook/worksheet/tc_cell.rb +143 -9
  167. data/test/workbook/worksheet/tc_col.rb +18 -3
  168. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  169. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  170. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  171. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  172. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  173. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  174. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  175. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  176. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  177. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  178. data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
  179. data/test/workbook/worksheet/tc_row.rb +24 -2
  180. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  181. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  182. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  183. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  184. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  185. data/test/workbook/worksheet/tc_table.rb +2 -3
  186. data/test/workbook/worksheet/tc_worksheet.rb +123 -60
  187. metadata +180 -128
  188. data/examples/2010_comments.rb +0 -17
  189. data/examples/anchor_swapping.rb +0 -28
  190. data/examples/auto_filter.rb +0 -16
  191. data/examples/basic_charts.rb +0 -58
  192. data/examples/chart_colors.rb +0 -88
  193. data/examples/colored_links.rb +0 -59
  194. data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
  195. data/examples/conditional_formatting/getting_barred.rb +0 -37
  196. data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
  197. data/examples/conditional_formatting/scaled_colors.rb +0 -39
  198. data/examples/conditional_formatting/stop_and_go.rb +0 -37
  199. data/examples/data_validation.rb +0 -50
  200. data/examples/example.rb +0 -777
  201. data/examples/extractive.rb +0 -45
  202. data/examples/ios_preview.rb +0 -14
  203. data/examples/page_setup.rb +0 -11
  204. data/examples/pivot_table.rb +0 -39
  205. data/examples/sheet_protection.rb +0 -10
  206. data/examples/skydrive/real_example.rb +0 -63
  207. data/examples/styles.rb +0 -66
  208. data/examples/underline.rb +0 -13
  209. data/examples/wrap_text.rb +0 -21
  210. data/lib/axlsx/util/parser.rb +0 -44
@@ -0,0 +1,50 @@
1
+ require 'tc_helper'
2
+
3
+ class TestWorkbookView < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @options = { visibility: :hidden, minimized: true, show_horizontal_scroll: true, show_vertical_scroll: true,
7
+ show_sheet_tabs: true, tab_ratio: 750, first_sheet: 0, active_tab: 1, x_window: 500, y_window: 400,
8
+ window_width: 800, window_height: 600, auto_filter_date_grouping: true }
9
+ @book_view = Axlsx::WorkbookView.new @options
10
+ end
11
+
12
+ def test_options_assignation
13
+ @options.each do |key, value|
14
+ assert_equal(value, @book_view.send(key))
15
+ end
16
+ end
17
+
18
+ def test_boolean_attribute_validation
19
+ %w(minimized show_horizontal_scroll show_vertical_scroll show_sheet_tabs auto_filter_date_grouping).each do |attr|
20
+ assert_raise(ArgumentError, 'only booleanish allowed in boolean attributes') { @book_view.send("#{attr}=", "banana") }
21
+ assert_nothing_raised { @book_view.send("#{attr}=", false )}
22
+ end
23
+ end
24
+
25
+ def test_integer_attribute_validation
26
+ %w(tab_ratio first_sheet active_tab x_window y_window window_width window_height).each do |attr|
27
+ assert_raise(ArgumentError, 'only integer allowed in integer attributes') { @book_view.send("#{attr}=", "b") }
28
+ assert_nothing_raised { @book_view.send("#{attr}=", 7 )}
29
+ end
30
+ end
31
+
32
+ def test_visibility_attribute_validation
33
+ assert_raise(ArgumentError) { @book_view.visibility = :foobar }
34
+ assert_nothing_raised { @book_view.visibility = :hidden }
35
+ assert_nothing_raised { @book_view.visibility = :very_hidden }
36
+ assert_nothing_raised { @book_view.visibility = :visible }
37
+ end
38
+
39
+ def test_to_xml_string
40
+ xml = @book_view.to_xml_string
41
+ doc = Nokogiri::XML(xml)
42
+ @options.each do |key, value|
43
+ if value == true || value == false
44
+ value = value ? 1 : 0
45
+ end
46
+ path = "workbookView[@#{Axlsx.camel(key, false)}='#{value}']"
47
+ assert_equal(1, doc.xpath(path).size)
48
+ end
49
+ end
50
+ end
@@ -44,7 +44,7 @@ class TestFilters < Test::Unit::TestCase
44
44
 
45
45
  def test_to_xml_string
46
46
  doc = Nokogiri::XML(@filters.to_xml_string)
47
- assert_equal(1, doc.xpath('//filters[@blank="true"]').size)
47
+ assert_equal(1, doc.xpath('//filters[@blank=1]').size)
48
48
  end
49
49
  end
50
50
 
@@ -44,6 +44,6 @@ class TestBreak < Test::Unit::TestCase
44
44
 
45
45
  def test_to_xml_string
46
46
  doc = Nokogiri::XML(@break.to_xml_string)
47
- assert_equal(doc.xpath('//brk[@id="1"][@min="1"][@max="10"][@pt="false"][@man="true"]').size, 1)
47
+ assert_equal(doc.xpath('//brk[@id="1"][@min="1"][@max="10"][@pt=0][@man=1]').size, 1)
48
48
  end
49
49
  end
@@ -4,10 +4,11 @@ class TestCell < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  p = Axlsx::Package.new
7
+ p.use_shared_strings = true
7
8
  @ws = p.workbook.add_worksheet :name=>"hmmm"
8
9
  p.workbook.styles.add_style :sz=>20
9
10
  @row = @ws.add_row
10
- @c = @row.add_cell 1, :type=>:float, :style=>1
11
+ @c = @row.add_cell 1, :type=>:float, :style=>1, :escape_formulas=>true
11
12
  data = (0..26).map { |index| index }
12
13
  @ws.add_row data
13
14
  @cAA = @ws["AA2"]
@@ -18,6 +19,7 @@ class TestCell < Test::Unit::TestCase
18
19
  assert_equal(@c.type, :float, "type option is applied")
19
20
  assert_equal(@c.style, 1, "style option is applied")
20
21
  assert_equal(@c.value, 1.0, "type option is applied and value is casted")
22
+ assert_equal(@c.escape_formulas, true, "escape formulas option is applied")
21
23
  end
22
24
 
23
25
  def test_style_date_data
@@ -34,7 +36,7 @@ class TestCell < Test::Unit::TestCase
34
36
  end
35
37
 
36
38
  def test_pos
37
- assert_equal(@c.pos, [@c.index, @c.row.index])
39
+ assert_equal(@c.pos, [@c.index, @c.row.index(@c)])
38
40
  end
39
41
 
40
42
  def test_r
@@ -50,6 +52,32 @@ class TestCell < Test::Unit::TestCase
50
52
  assert_equal(@cAA.r_abs,"$AA$2", "needs to accept multi-digit columns")
51
53
  end
52
54
 
55
+ def test_name
56
+ @c.name = 'foo'
57
+ assert_equal(1, @ws.workbook.defined_names.size)
58
+ assert_equal('foo', @ws.workbook.defined_names.last.name)
59
+ end
60
+
61
+ def test_autowidth
62
+ style = @c.row.worksheet.workbook.styles.add_style({:alignment => {:horizontal => :center, :vertical => :center, :wrap_text => true}} )
63
+ @c.style = style
64
+ assert_in_delta(6.6, @c.autowidth, 0.01)
65
+ end
66
+
67
+ def test_time
68
+ @c.type = :time
69
+ now = DateTime.now
70
+ @c.value = now
71
+ assert_equal(@c.value, now.to_time)
72
+ end
73
+
74
+ def test_date
75
+ @c.type = :date
76
+ now = Time.now
77
+ @c.value = now
78
+ assert_equal(@c.value, now.to_date)
79
+ end
80
+
53
81
  def test_style
54
82
  assert_raise(ArgumentError, "must reject invalid style indexes") { @c.style=@c.row.worksheet.workbook.styles.cellXfs.size }
55
83
  assert_nothing_raised("must allow valid style index changes") {@c.style=1}
@@ -79,6 +107,12 @@ class TestCell < Test::Unit::TestCase
79
107
 
80
108
  def test_cell_type_from_value
81
109
  assert_equal(@c.send(:cell_type_from_value, 1.0), :float)
110
+ assert_equal(@c.send(:cell_type_from_value, "1e1"), :float)
111
+ assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MAX_10_EXP}"), :float)
112
+ assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MAX_10_EXP + 1}"), :string)
113
+ assert_equal(@c.send(:cell_type_from_value, "1e-1"), :float)
114
+ assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MIN_10_EXP}"), :float)
115
+ assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MIN_10_EXP - 1}"), :string)
82
116
  assert_equal(@c.send(:cell_type_from_value, 1), :integer)
83
117
  assert_equal(@c.send(:cell_type_from_value, Date.today), :date)
84
118
  assert_equal(@c.send(:cell_type_from_value, Time.now), :time)
@@ -89,9 +123,35 @@ class TestCell < Test::Unit::TestCase
89
123
  assert_equal(@c.send(:cell_type_from_value, true), :boolean)
90
124
  assert_equal(@c.send(:cell_type_from_value, false), :boolean)
91
125
  assert_equal(@c.send(:cell_type_from_value, 1.0/10**6), :float)
126
+ assert_equal(@c.send(:cell_type_from_value, Axlsx::RichText.new), :richtext)
92
127
  assert_equal(:iso_8601, @c.send(:cell_type_from_value, '2008-08-30T01:45:36.123+09:00'))
93
128
  end
94
129
 
130
+ def test_cell_type_from_value_looks_like_number_but_is_not
131
+ mimic_number = Class.new do
132
+ def initialize(to_s_value)
133
+ @to_s_value = to_s_value
134
+ end
135
+
136
+ def to_s
137
+ @to_s_value
138
+ end
139
+ end
140
+
141
+ number_strings = [
142
+ '1',
143
+ '1234567890',
144
+ '1.0',
145
+ '1e1',
146
+ '0',
147
+ "1e#{Float::MIN_10_EXP}"
148
+ ]
149
+
150
+ number_strings.each do |number_string|
151
+ assert_equal(@c.send(:cell_type_from_value, mimic_number.new(number_string)), :string)
152
+ end
153
+ end
154
+
95
155
  def test_cast_value
96
156
  @c.type = :string
97
157
  assert_equal(@c.send(:cast_value, 1.0), "1.0")
@@ -101,6 +161,8 @@ class TestCell < Test::Unit::TestCase
101
161
  assert_equal(@c.send(:cast_value, "1.0"), 1.0)
102
162
  @c.type = :string
103
163
  assert_equal(@c.send(:cast_value, nil), nil)
164
+ @c.type = :richtext
165
+ assert_equal(@c.send(:cast_value, nil), nil)
104
166
  @c.type = :float
105
167
  assert_equal(@c.send(:cast_value, nil), nil)
106
168
  @c.type = :boolean
@@ -110,6 +172,19 @@ class TestCell < Test::Unit::TestCase
110
172
  assert_equal("2012-10-10T12:24", @c.send(:cast_value, "2012-10-10T12:24"))
111
173
  end
112
174
 
175
+ def test_cast_time_subclass
176
+ subtime = Class.new(Time) do
177
+ def to_time
178
+ raise "#to_time of Time subclass should not be called"
179
+ end
180
+ end
181
+
182
+ time = subtime.now
183
+
184
+ @c.type = :time
185
+ assert_equal(time, @c.send(:cast_value, time))
186
+ end
187
+
113
188
  def test_color
114
189
  assert_raise(ArgumentError) { @c.color = -1.1 }
115
190
  assert_nothing_raised { @c.color = "FF00FF00" }
@@ -217,6 +292,13 @@ class TestCell < Test::Unit::TestCase
217
292
  assert_equal(@c.row.worksheet.send(:merged_cells).last, "A1:C1")
218
293
  end
219
294
 
295
+ def test_reverse_merge_with_cell
296
+ @c.row.add_cell 2
297
+ @c.row.add_cell 3
298
+ @row.cells.last.merge @c
299
+ assert_equal(@c.row.worksheet.send(:merged_cells).last, "A1:C1")
300
+ end
301
+
220
302
  def test_ssti
221
303
  assert_raise(ArgumentError, "ssti must be an unsigned integer!") { @c.send(:ssti=, -1) }
222
304
  @c.send :ssti=, 1
@@ -255,7 +337,7 @@ class TestCell < Test::Unit::TestCase
255
337
  c_xml = Nokogiri::XML(@c.to_xml_string(1,1))
256
338
  assert_equal(c_xml.xpath("/c[@s=1]").size, 1)
257
339
  end
258
-
340
+
259
341
  def test_to_xml_string_with_run
260
342
  # Actually quite a number of similar run styles
261
343
  # but the processing should be the same
@@ -265,7 +347,7 @@ class TestCell < Test::Unit::TestCase
265
347
  @c.font_name = 'arial'
266
348
  @c.color = 'FF0000'
267
349
  c_xml = Nokogiri::XML(@c.to_xml_string(1,1))
268
- assert(c_xml.xpath("//b"))
350
+ assert(c_xml.xpath("//b").any?)
269
351
  end
270
352
 
271
353
  def test_to_xml_string_formula
@@ -274,8 +356,62 @@ class TestCell < Test::Unit::TestCase
274
356
  sheet.add_row ["=IF(2+2=4,4,5)"]
275
357
  end
276
358
  doc = Nokogiri::XML(ws.to_xml_string)
277
- assert(doc.xpath("//f[@text()='IF(2+2=4,4,5)']"))
359
+ doc.remove_namespaces!
360
+ assert(doc.xpath("//f[text()='IF(2+2=4,4,5)']").any?)
361
+ end
362
+
363
+ def test_to_xml_string_formula_escaped
364
+ p = Axlsx::Package.new
365
+ ws = p.workbook.add_worksheet do |sheet|
366
+ sheet.add_row ["=IF(2+2=4,4,5)"], escape_formulas: true
367
+ end
368
+ doc = Nokogiri::XML(ws.to_xml_string)
369
+ doc.remove_namespaces!
370
+ assert(doc.xpath("//t[text()='=IF(2+2=4,4,5)']").any?)
371
+ end
372
+
373
+ def test_to_xml_string_formula_escape_array_parameter
374
+ p = Axlsx::Package.new
375
+ ws = p.workbook.add_worksheet do |sheet|
376
+ sheet.add_row [
377
+ "=IF(2+2=4,4,5)",
378
+ "=IF(13+13=4,4,5)",
379
+ "=IF(99+99=4,4,5)"
380
+ ], escape_formulas: [true, false, true]
381
+ end
382
+ doc = Nokogiri::XML(ws.to_xml_string)
383
+ doc.remove_namespaces!
384
+
385
+ assert(doc.xpath("//t[text()='=IF(2+2=4,4,5)']").any?)
386
+ assert(doc.xpath("//f[text()='IF(13+13=4,4,5)']").any?)
387
+ assert(doc.xpath("//t[text()='=IF(99+99=4,4,5)']").any?)
388
+ end
389
+
390
+ def test_to_xml_string_array_formula
391
+ p = Axlsx::Package.new
392
+ ws = p.workbook.add_worksheet do |sheet|
393
+ sheet.add_row ["{=SUM(C2:C11*D2:D11)}"]
394
+ end
395
+ doc = Nokogiri::XML(ws.to_xml_string)
396
+ doc.remove_namespaces!
397
+ assert(doc.xpath("//f[text()='SUM(C2:C11*D2:D11)']").any?)
398
+ assert(doc.xpath("//f[@t='array']").any?)
399
+ assert(doc.xpath("//f[@ref='A1']").any?)
400
+ end
401
+
402
+ def test_to_xml_string_text_formula
403
+ p = Axlsx::Package.new
404
+ ws = p.workbook.add_worksheet do |sheet|
405
+ sheet.add_row ["=1+1", "-1+1"], type: :text
406
+ end
407
+ doc = Nokogiri::XML(ws.to_xml_string)
408
+ doc.remove_namespaces!
278
409
 
410
+ assert(doc.xpath("//f[text()='1+1']").empty?)
411
+ assert(doc.xpath("//t[text()='=1+1']").any?)
412
+
413
+ assert(doc.xpath("//f[text()='1+1']").empty?)
414
+ assert(doc.xpath("//t[text()='-1+1']").any?)
279
415
  end
280
416
 
281
417
  def test_font_size_with_custom_style_and_no_sz
@@ -294,17 +430,17 @@ class TestCell < Test::Unit::TestCase
294
430
  sz = @c.send(:font_size)
295
431
  assert_equal(sz, 52)
296
432
  end
297
-
298
433
 
299
434
  def test_cell_with_sz
300
435
  @c.sz = 25
301
436
  assert_equal(25, @c.send(:font_size))
302
437
  end
438
+
303
439
  def test_to_xml
304
440
  # TODO This could use some much more stringent testing related to the xml content generated!
305
441
  @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)", "2013-01-13T13:31:25.123"]
306
442
  @ws.rows.last.cells[5].u = true
307
-
443
+
308
444
  schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
309
445
  doc = Nokogiri::XML(@ws.to_xml_string)
310
446
  errors = []
@@ -313,7 +449,5 @@ class TestCell < Test::Unit::TestCase
313
449
  puts error.message
314
450
  end
315
451
  assert(errors.empty?, "error free validation")
316
-
317
452
  end
318
-
319
453
  end
@@ -7,7 +7,7 @@ class TestCol < Test::Unit::TestCase
7
7
  end
8
8
 
9
9
  def test_initialize
10
- options = { :width => 12, :collapsed => true, :hidden => true, :outline_level => 1, :phonetic => true, :style => 1}
10
+ options = { :width => 12, :collapsed => true, :hidden => true, :outline_level => 1, :phonetic => true, :style => 1}
11
11
 
12
12
  col = Axlsx::Col.new 0, 0, options
13
13
  options.each{ |key, value| assert_equal(col.send(key.to_sym), value) }
@@ -39,6 +39,21 @@ class TestCol < Test::Unit::TestCase
39
39
  assert_equal(@col.customWidth, true, 'customWidth is true when width is set')
40
40
  end
41
41
 
42
+ def test_widthUnderLimit
43
+ @col.width = 3
44
+ assert_equal(@col.width, 3, 'width is set to exact value')
45
+ end
46
+
47
+ def test_widthOverLimit
48
+ @col.width = 31337
49
+ assert_equal(@col.width, 255, 'width is set to maximum allowed value')
50
+ end
51
+
52
+ def test_widthSetToNil
53
+ @col.width = nil
54
+ assert_equal(@col.width, nil, 'width is set to unspecified value')
55
+ end
56
+
42
57
  def test_hidden
43
58
  assert_equal(@col.hidden, nil)
44
59
  assert_raise(ArgumentError, 'hidden must be boolean(ish)') { @col.hidden = 'bob' }
@@ -61,11 +76,11 @@ class TestCol < Test::Unit::TestCase
61
76
  def test_to_xml_string
62
77
  @col.width = 100
63
78
  doc = Nokogiri::XML(@col.to_xml_string)
64
- assert_equal(1, doc.xpath("//col [@bestFit='#{@col.best_fit}']").size)
79
+ assert_equal(1, doc.xpath("//col [@bestFit='#{@col.best_fit ? 1 : 0}']").size)
65
80
  assert_equal(1, doc.xpath("//col [@max=#{@col.max}]").size)
66
81
  assert_equal(1, doc.xpath("//col [@min=#{@col.min}]").size)
67
82
  assert_equal(1, doc.xpath("//col [@width=#{@col.width}]").size)
68
- assert_equal(1, doc.xpath("//col [@customWidth='#{@col.custom_width}']").size)
83
+ assert_equal(1, doc.xpath("//col [@customWidth='#{@col.custom_width ? 1 : 0}']").size)
69
84
  end
70
85
 
71
86
  def test_style
@@ -113,8 +113,8 @@ class TestConditionalFormatting < Test::Unit::TestCase
113
113
  :percent => false, :rank => 0, :stdDev => 1, :stopIfTrue => true, :timePeriod => :today,
114
114
  :formula => "0.0"})
115
115
  doc = Nokogiri::XML.parse(cf.to_xml_string)
116
- assert_equal(1, doc.xpath(".//conditionalFormatting//cfRule[@type='cellIs'][@aboveAverage='false'][@bottom='false'][@dxfId=0][@equalAverage='false'][@priority=2][@operator='lessThan'][@text=''][@percent='false'][@rank=0][@stdDev=1][@stopIfTrue='true'][@timePeriod='today']").size)
117
- assert doc.xpath(".//conditionalFormatting//cfRule[@type='cellIs'][@aboveAverage='false'][@bottom='false'][@dxfId=0][@equalAverage='false'][@priority=2][@operator='lessThan'][@text=''][@percent='false'][@rank=0][@stdDev=1][@stopIfTrue='true'][@timePeriod='today']//formula=0.0")
116
+ assert_equal(1, doc.xpath(".//conditionalFormatting//cfRule[@type='cellIs'][@aboveAverage=0][@bottom=0][@dxfId=0][@equalAverage=0][@priority=2][@operator='lessThan'][@text=''][@percent=0][@rank=0][@stdDev=1][@stopIfTrue=1][@timePeriod='today']").size)
117
+ assert doc.xpath(".//conditionalFormatting//cfRule[@type='cellIs'][@aboveAverage=0][@bottom=0][@dxfId=0][@equalAverage=0][@priority=2][@operator='lessThan'][@text=''][@percent=0][@rank=0][@stdDev=1][@stopIfTrue=1][@timePeriod='today']//formula=0.0")
118
118
  end
119
119
 
120
120
  def test_to_xml
@@ -38,7 +38,7 @@ class TestDataBar < Test::Unit::TestCase
38
38
 
39
39
  def test_to_xml_string
40
40
  doc = Nokogiri::XML.parse(@data_bar.to_xml_string)
41
- assert_equal(doc.xpath(".//dataBar[@minLength=10][@maxLength=90][@showValue='true']").size, 1)
41
+ assert_equal(doc.xpath(".//dataBar[@minLength=10][@maxLength=90][@showValue=1]").size, 1)
42
42
  assert_equal(doc.xpath(".//dataBar//cfvo").size, 2)
43
43
  assert_equal(doc.xpath(".//dataBar//color").size, 1)
44
44
  end
@@ -160,11 +160,11 @@ class TestDataValidation < Test::Unit::TestCase
160
160
  #test attributes
161
161
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1']
162
162
  [@promptTitle='Be carful!'][@prompt='Only values between 5 and 10'][@operator='between'][@errorTitle='Wrong input']
163
- [@error='Only values between 5 and 10'][@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@type='whole']
163
+ [@error='Only values between 5 and 10'][@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@type='whole']
164
164
  [@errorStyle='information']").size)
165
165
  assert doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1']
166
166
  [@promptTitle='Be carful!'][@prompt='Only values between 5 and 10'][@operator='between'][@errorTitle='Wrong input']
167
- [@error='Only values between 5 and 10'][@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true']
167
+ [@error='Only values between 5 and 10'][@showErrorMessage=1][@allowBlank=1][@showInputMessage=1]
168
168
  [@type='whole'][@errorStyle='information']")
169
169
 
170
170
  #test forumula1
@@ -189,11 +189,11 @@ class TestDataValidation < Test::Unit::TestCase
189
189
  #test attributes
190
190
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1']
191
191
  [@promptTitle='Be carful!'][@prompt='Only values from list'][@errorTitle='Wrong input'][@error='Only values from list']
192
- [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@showDropDown='true'][@type='list']
192
+ [@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@showDropDown=1][@type='list']
193
193
  [@errorStyle='stop']").size)
194
194
  assert doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1']
195
195
  [@promptTitle='Be carful!'][@prompt='Only values from list'][@errorTitle='Wrong input'][@error='Only values from list']
196
- [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@showDropDown='true'][@type='list'][@errorStyle='stop']")
196
+ [@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@showDropDown=1][@type='list'][@errorStyle='stop']")
197
197
 
198
198
  #test forumula1
199
199
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations/xmlns:dataValidation/xmlns:formula1").size)
@@ -212,11 +212,11 @@ class TestDataValidation < Test::Unit::TestCase
212
212
 
213
213
  #test attributes
214
214
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1'][@promptTitle='Be carful!']
215
- [@prompt='Only values corresponding formula'][@errorTitle='Wrong input'][@error='Only values corresponding formula'][@showErrorMessage='true']
216
- [@allowBlank='true'][@showInputMessage='true'][@type='custom'][@errorStyle='stop']").size)
215
+ [@prompt='Only values corresponding formula'][@errorTitle='Wrong input'][@error='Only values corresponding formula'][@showErrorMessage=1]
216
+ [@allowBlank=1][@showInputMessage=1][@type='custom'][@errorStyle='stop']").size)
217
217
  assert doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='1']/xmlns:dataValidation[@sqref='A1'][@promptTitle='Be carful!']
218
218
  [@prompt='Only values corresponding formula'][@errorTitle='Wrong input'][@error='Only values corresponding formula']
219
- [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@type='custom'][@errorStyle='stop']")
219
+ [@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@type='custom'][@errorStyle='stop']")
220
220
 
221
221
  #test forumula1
222
222
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations/xmlns:dataValidation/xmlns:formula1").size)
@@ -240,21 +240,21 @@ class TestDataValidation < Test::Unit::TestCase
240
240
  #test attributes
241
241
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='2']/xmlns:dataValidation[@sqref='A1']
242
242
  [@promptTitle='Be carful!'][@prompt='Only values between 5 and 10'][@operator='between'][@errorTitle='Wrong input']
243
- [@error='Only values between 5 and 10'][@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@type='whole']
243
+ [@error='Only values between 5 and 10'][@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@type='whole']
244
244
  [@errorStyle='information']").size)
245
245
  assert doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='2']/xmlns:dataValidation[@sqref='A1']
246
246
  [@promptTitle='Be carful!'][@prompt='Only values between 5 and 10'][@operator='between'][@errorTitle='Wrong input']
247
- [@error='Only values between 5 and 10'][@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true']
247
+ [@error='Only values between 5 and 10'][@showErrorMessage=1][@allowBlank=1][@showInputMessage=1]
248
248
  [@type='whole'][@errorStyle='information']")
249
249
 
250
250
  #test attributes
251
251
  assert_equal(1, doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='2']/xmlns:dataValidation[@sqref='B1']
252
252
  [@promptTitle='Be carful!'][@prompt='Only values from list'][@errorTitle='Wrong input'][@error='Only values from list']
253
- [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@showDropDown='true'][@type='list']
253
+ [@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@showDropDown=1][@type='list']
254
254
  [@errorStyle='stop']").size)
255
255
  assert doc.xpath("//xmlns:worksheet/xmlns:dataValidations[@count='2']/xmlns:dataValidation[@sqref='B1']
256
256
  [@promptTitle='Be carful!'][@prompt='Only values from list'][@errorTitle='Wrong input'][@error='Only values from list']
257
- [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@showDropDown='true'][@type='list'][@errorStyle='stop']")
257
+ [@showErrorMessage=1][@allowBlank=1][@showInputMessage=1][@showDropDown=1][@type='list'][@errorStyle='stop']")
258
258
  end
259
259
 
260
260
  def test_empty_attributes