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
@@ -24,8 +24,14 @@ class TestAxlsx < Test::Unit::TestCase
24
24
 
25
25
 
26
26
  def test_trust_input_can_be_set_to_true
27
+ # Class variables like this are not reset between test runs, so we have
28
+ # to save and restore the original value manually.
29
+ old = Axlsx.trust_input
30
+
27
31
  Axlsx.trust_input = true
28
32
  assert_equal true, Axlsx.trust_input
33
+
34
+ Axlsx.trust_input = old
29
35
  end
30
36
  def test_cell_range_relative
31
37
  p = Axlsx::Package.new
@@ -45,6 +51,16 @@ class TestAxlsx < Test::Unit::TestCase
45
51
  assert_equal(Axlsx.cell_range([c2, c1], true), "'Sheet &lt;''&gt;&quot; 1'!$A$1:$B$1")
46
52
  end
47
53
 
54
+ def test_cell_range_row
55
+ p = Axlsx::Package.new
56
+ ws = p.workbook.add_worksheet
57
+ row = ws.add_row
58
+ row.add_cell
59
+ row.add_cell
60
+ row.add_cell
61
+ assert_equal("A1:C1", Axlsx.cell_range(row, false))
62
+ end
63
+
48
64
  def test_name_to_indices
49
65
  setup_wide
50
66
  @wide_test_points.each do |key, value|
@@ -69,4 +85,25 @@ class TestAxlsx < Test::Unit::TestCase
69
85
  assert_equal([['Z5', 'AA5', 'AB5'], ['Z6', 'AA6', 'AB6']], Axlsx::range_to_a('Z5:AB6'))
70
86
  end
71
87
 
88
+ def test_sanitize_frozen_control_strippped
89
+ needs_sanitize = "legit\x08".freeze # Backspace control char
90
+
91
+ assert_equal(Axlsx.sanitize(needs_sanitize), 'legit', 'should strip control chars')
92
+ end
93
+
94
+ def test_sanitize_unfrozen_control_strippped
95
+ needs_sanitize = "legit\x08" # Backspace control char
96
+ sanitized_str = Axlsx.sanitize(needs_sanitize)
97
+
98
+ assert_equal(sanitized_str, 'legit', 'should strip control chars')
99
+ assert_equal(sanitized_str.object_id, sanitized_str.object_id, 'should preserve object')
100
+ end
101
+
102
+ def test_sanitize_unfrozen_no_sanitize
103
+ legit_str = 'legit'
104
+ sanitized_str = Axlsx.sanitize(legit_str)
105
+
106
+ assert_equal(sanitized_str, legit_str, 'should preserve value')
107
+ assert_equal(sanitized_str.object_id, legit_str.object_id, 'should preserve object')
108
+ end
72
109
  end
@@ -8,3 +8,5 @@ end
8
8
  require 'test/unit'
9
9
  require "timecop"
10
10
  require "axlsx.rb"
11
+ # MIME detection for Microsoft Office 2007+ formats
12
+ require 'mimemagic/overlay'
@@ -7,10 +7,17 @@ class TestPackage < Test::Unit::TestCase
7
7
  ws = @package.workbook.add_worksheet
8
8
  ws.add_row ['Can', 'we', 'build it?']
9
9
  ws.add_row ['Yes!', 'We', 'can!']
10
+ @rt = Axlsx::RichText.new
11
+ @rt.add_run "run 1", :b => true, :i => false
12
+ ws.add_row [@rt]
13
+
14
+ ws.rows.last.add_cell('b', :type => :text)
15
+
10
16
  ws.outline_level_rows 0, 1
11
17
  ws.outline_level_columns 0, 1
12
18
  ws.add_hyperlink :ref => ws.rows.first.cells.last, :location => 'https://github.com/randym'
13
19
  ws.workbook.add_defined_name("#{ws.name}!A1:C2", :name => '_xlnm.Print_Titles', :hidden => true)
20
+ ws.workbook.add_view active_tab: 1, first_sheet: 0
14
21
  ws.protect_range('A1:C1')
15
22
  ws.protect_range(ws.rows.last.cells)
16
23
  ws.add_comment :author => 'alice', :text => 'Hi Bob', :ref => 'A12'
@@ -52,8 +59,13 @@ class TestPackage < Test::Unit::TestCase
52
59
  chart.d_lbls.show_val = true
53
60
  end
54
61
 
62
+ ws.add_chart(Axlsx::BubbleChart, :title => 'bubble chart') do |chart|
63
+ chart.add_series :xData => [1,2,3,4], :yData => [1,3,2,4]
64
+ chart.d_lbls.show_val = true
65
+ end
66
+
55
67
  @fname = 'axlsx_test_serialization.xlsx'
56
- img = File.expand_path('../../examples/image1.jpeg', __FILE__)
68
+ img = File.expand_path('../fixtures/image1.jpeg', __FILE__)
57
69
  ws.add_image(:image_src => img, :noSelect => true, :noMove => true, :hyperlink=>"http://axlsx.blogspot.com") do |image|
58
70
  image.width=720
59
71
  image.height=666
@@ -61,12 +73,12 @@ class TestPackage < Test::Unit::TestCase
61
73
  image.start_at 5, 5
62
74
  image.end_at 10, 10
63
75
  end
64
- ws.add_image :image_src => File.expand_path('../../examples/image1.gif', __FILE__) do |image|
76
+ ws.add_image :image_src => File.expand_path('../fixtures/image1.gif', __FILE__) do |image|
65
77
  image.start_at 0, 20
66
78
  image.width=360
67
79
  image.height=333
68
80
  end
69
- ws.add_image :image_src => File.expand_path('../../examples/image1.png', __FILE__) do |image|
81
+ ws.add_image :image_src => File.expand_path('../fixtures/image1.png', __FILE__) do |image|
70
82
  image.start_at 9, 20
71
83
  image.width = 180
72
84
  image.height = 167
@@ -115,18 +127,35 @@ class TestPackage < Test::Unit::TestCase
115
127
  end
116
128
 
117
129
  def test_serialization
118
- assert_nothing_raised do
119
- begin
120
- @package.serialize(@fname)
121
- zf = Zip::File.open(@fname)
122
- @package.send(:parts).each{ |part| zf.get_entry(part[:entry]) }
123
- File.delete(@fname)
124
- rescue Errno::EACCES
125
- puts "WARNING:: test_serialization requires write access."
126
- end
130
+ @package.serialize(@fname)
131
+ assert_zip_file_matches_package(@fname, @package)
132
+ File.delete(@fname)
133
+ end
134
+
135
+ def test_serialization_with_zip_command
136
+ @package.serialize(@fname, false, zip_command: "zip")
137
+ assert_zip_file_matches_package(@fname, @package)
138
+ File.delete(@fname)
139
+ end
140
+
141
+ def test_serialization_with_zip_command_and_absolute_path
142
+ fname = "#{Dir.tmpdir}/#{@fname}"
143
+ @package.serialize(fname, false, zip_command: "zip")
144
+ assert_zip_file_matches_package(fname, @package)
145
+ File.delete(fname)
146
+ end
147
+
148
+ def test_serialization_with_invalid_zip_command
149
+ assert_raises Axlsx::ZipCommand::ZipError do
150
+ @package.serialize(@fname, false, zip_command: "invalid_zip")
127
151
  end
128
152
  end
129
153
 
154
+ def assert_zip_file_matches_package(fname, package)
155
+ zf = Zip::File.open(fname)
156
+ package.send(:parts).each{ |part| zf.get_entry(part[:entry]) }
157
+ end
158
+
130
159
  # See comment for Package#zip_entry_for_part
131
160
  def test_serialization_creates_identical_files_at_any_time_if_created_at_is_set
132
161
  @package.core.created = Time.now
@@ -148,6 +177,11 @@ class TestPackage < Test::Unit::TestCase
148
177
  assert package_1.to_stream.string == package_2.to_stream.string, "zip files are not identical"
149
178
  end
150
179
 
180
+ def test_serialization_creates_files_with_excel_mime_type
181
+ assert_equal(MimeMagic.by_magic(@package.to_stream).type,
182
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
183
+ end
184
+
151
185
  def test_validation
152
186
  assert_equal(@package.validate.size, 0, @package.validate)
153
187
  Axlsx::Workbook.send(:class_variable_set, :@@date1904, 9900)
@@ -176,12 +210,13 @@ class TestPackage < Test::Unit::TestCase
176
210
 
177
211
 
178
212
  #no mystery parts
179
- assert_equal(24, p.size)
213
+ assert_equal(25, p.size)
180
214
 
181
215
  end
182
216
 
183
217
  def test_shared_strings_requires_part
184
218
  @package.use_shared_strings = true
219
+ @package.to_stream #ensure all cell_serializer paths are hit
185
220
  p = @package.send(:parts)
186
221
  assert_equal(p.select{ |part| part[:entry] =~/xl\/sharedStrings.xml/}.size, 1, "shared strings table missing")
187
222
  end
@@ -218,6 +253,8 @@ class TestPackage < Test::Unit::TestCase
218
253
  # this is just a roundabout guess for a package as it is build now
219
254
  # in testing.
220
255
  assert(stream.size > 80000)
256
+ # Cached ids should be cleared
257
+ assert(Axlsx::Relationship.ids_cache.empty?)
221
258
  end
222
259
 
223
260
  def test_encrypt
@@ -0,0 +1,13 @@
1
+ require 'tc_helper.rb'
2
+ class TestMimeTypeUtils < Test::Unit::TestCase
3
+ def setup
4
+ @test_img = File.dirname(__FILE__) + "/../fixtures/image1.jpeg"
5
+ end
6
+
7
+ def teardown
8
+ end
9
+
10
+ def test_mime_type_utils
11
+ assert_equal(Axlsx::MimeTypeUtils::get_mime_type(@test_img), 'image/jpeg')
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
1
  require 'tc_helper.rb'
2
2
  class TestSimpleTypedList < Test::Unit::TestCase
3
3
  def setup
4
- @list = Axlsx::SimpleTypedList.new Fixnum
4
+ @list = Axlsx::SimpleTypedList.new Integer
5
5
  end
6
6
 
7
7
  def teardown
@@ -72,7 +72,6 @@ class TestSimpleTypedList < Test::Unit::TestCase
72
72
  def test_equality
73
73
  @list.push 1
74
74
  @list.push 2
75
- assert_equal(@list, [1,2])
76
-
75
+ assert_equal(@list.to_ary, [1,2])
77
76
  end
78
77
  end
@@ -91,7 +91,7 @@ class TestValidators < Test::Unit::TestCase
91
91
  assert_raise(ArgumentError) { Axlsx.validate_scale_10_400 10.0 }
92
92
  assert_raise(ArgumentError) { Axlsx.validate_scale_10_400 400.1 }
93
93
  assert_raise(ArgumentError) { Axlsx.validate_scale_10_400 "99" }
94
-
94
+
95
95
  #scale_0_10_400
96
96
  assert_nothing_raised { Axlsx.validate_scale_0_10_400 0 }
97
97
  assert_nothing_raised { Axlsx.validate_scale_0_10_400 10 }
@@ -101,7 +101,7 @@ class TestValidators < Test::Unit::TestCase
101
101
  assert_raise(ArgumentError) { Axlsx.validate_scale_0_10_400 10.0 }
102
102
  assert_raise(ArgumentError) { Axlsx.validate_scale_0_10_400 400.1 }
103
103
  assert_raise(ArgumentError) { Axlsx.validate_scale_0_10_400 "99" }
104
-
104
+
105
105
  #page_orientation
106
106
  assert_nothing_raised { Axlsx.validate_page_orientation :default }
107
107
  assert_nothing_raised { Axlsx.validate_page_orientation :landscape }
@@ -109,7 +109,7 @@ class TestValidators < Test::Unit::TestCase
109
109
  assert_raise(ArgumentError) { Axlsx.validate_page_orientation nil }
110
110
  assert_raise(ArgumentError) { Axlsx.validate_page_orientation 1 }
111
111
  assert_raise(ArgumentError) { Axlsx.validate_page_orientation "landscape" }
112
-
112
+
113
113
  #data_validation_error_style
114
114
  [:information, :stop, :warning].each do |sym|
115
115
  assert_nothing_raised { Axlsx.validate_data_validation_error_style sym }
@@ -117,7 +117,7 @@ class TestValidators < Test::Unit::TestCase
117
117
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style :other_symbol }
118
118
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 'warning' }
119
119
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 0 }
120
-
120
+
121
121
  #data_validation_operator
122
122
  [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween].each do |sym|
123
123
  assert_nothing_raised { Axlsx.validate_data_validation_operator sym }
@@ -125,15 +125,15 @@ class TestValidators < Test::Unit::TestCase
125
125
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style :other_symbol }
126
126
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 'lessThan' }
127
127
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 0 }
128
-
128
+
129
129
  #data_validation_type
130
- [:custom, :data, :decimal, :list, :none, :textLength, :time, :whole].each do |sym|
130
+ [:custom, :data, :decimal, :list, :none, :textLength, :date, :time, :whole].each do |sym|
131
131
  assert_nothing_raised { Axlsx.validate_data_validation_type sym }
132
132
  end
133
133
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style :other_symbol }
134
134
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 'decimal' }
135
135
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 0 }
136
-
136
+
137
137
  #sheet_view_type
138
138
  [:normal, :page_break_preview, :page_layout].each do |sym|
139
139
  assert_nothing_raised { Axlsx.validate_sheet_view_type sym }
@@ -141,7 +141,7 @@ class TestValidators < Test::Unit::TestCase
141
141
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style :other_symbol }
142
142
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 'page_layout' }
143
143
  assert_raise(ArgumentError) { Axlsx.validate_data_validation_error_style 0 }
144
-
144
+
145
145
  #active_pane_type
146
146
  [:bottom_left, :bottom_right, :top_left, :top_right].each do |sym|
147
147
  assert_nothing_raised { Axlsx.validate_pane_type sym }
@@ -149,7 +149,7 @@ class TestValidators < Test::Unit::TestCase
149
149
  assert_raise(ArgumentError) { Axlsx.validate_pane_type :other_symbol }
150
150
  assert_raise(ArgumentError) { Axlsx.validate_pane_type 'bottom_left' }
151
151
  assert_raise(ArgumentError) { Axlsx.validate_pane_type 0 }
152
-
152
+
153
153
  #split_state_type
154
154
  [:frozen, :frozen_split, :split].each do |sym|
155
155
  assert_nothing_raised { Axlsx.validate_split_state_type sym }
@@ -157,8 +157,32 @@ class TestValidators < Test::Unit::TestCase
157
157
  assert_raise(ArgumentError) { Axlsx.validate_split_state_type :other_symbol }
158
158
  assert_raise(ArgumentError) { Axlsx.validate_split_state_type 'frozen_split' }
159
159
  assert_raise(ArgumentError) { Axlsx.validate_split_state_type 0 }
160
+
161
+ #display_blanks_as
162
+ [:gap, :span, :zero].each do |sym|
163
+ assert_nothing_raised { Axlsx.validate_display_blanks_as sym }
164
+ end
165
+ assert_raise(ArgumentError) { Axlsx.validate_display_blanks_as :other_symbol }
166
+ assert_raise(ArgumentError) { Axlsx.validate_display_blanks_as 'other_blank' }
167
+ assert_raise(ArgumentError) { Axlsx.validate_display_blanks_as 0 }
168
+
169
+ #view_visibility
170
+ [:visible, :hidden, :very_hidden].each do |sym|
171
+ assert_nothing_raised { Axlsx.validate_view_visibility sym }
172
+ end
173
+ assert_raise(ArgumentError) { Axlsx.validate_view_visibility :other_symbol }
174
+ assert_raise(ArgumentError) { Axlsx.validate_view_visibility 'other_visibility' }
175
+ assert_raise(ArgumentError) { Axlsx.validate_view_visibility 0 }
176
+
177
+ #marker_symbol
178
+ [:default, :circle, :dash, :diamond, :dot, :picture, :plus, :square, :star, :triangle, :x].each do |sym|
179
+ assert_nothing_raised { Axlsx.validate_marker_symbol sym }
180
+ end
181
+ assert_raise(ArgumentError) { Axlsx.validate_marker_symbol :other_symbol }
182
+ assert_raise(ArgumentError) { Axlsx.validate_marker_symbol 'other_marker' }
183
+ assert_raise(ArgumentError) { Axlsx.validate_marker_symbol 0 }
160
184
  end
161
-
185
+
162
186
  def test_validate_integerish
163
187
  assert_raise(ArgumentError) { Axlsx.validate_integerish Axlsx }
164
188
  [1, 1.4, "a"].each { |test_value| assert_nothing_raised { Axlsx.validate_integerish test_value } }
@@ -179,7 +203,7 @@ class TestValidators < Test::Unit::TestCase
179
203
 
180
204
  def test_range_validation
181
205
  # exclusive
182
- assert_raise(ArgumentError) { Axlsx::RangeValidator.validate('foo', 1, 10, 10, false) }
206
+ assert_raise(ArgumentError) { Axlsx::RangeValidator.validate('foo', 1, 10, 10, false) }
183
207
  # inclusive by default
184
208
  assert_nothing_raised { Axlsx::RangeValidator.validate('foo', 1, 10, 10) }
185
209
  end
@@ -1,14 +1,14 @@
1
1
  require 'tc_helper'
2
2
 
3
3
  class TestDefinedNames < Test::Unit::TestCase
4
- def setup
4
+ def setup
5
5
  @dn = Axlsx::DefinedName.new('Sheet1!A1:A1')
6
6
  end
7
7
 
8
8
  def test_initialize
9
9
  assert_equal('Sheet1!A1:A1', @dn.formula)
10
10
  end
11
-
11
+
12
12
  def test_string_attributes
13
13
  %w(short_cut_key status_bar help description custom_menu comment).each do |attr|
14
14
  assert_raise(ArgumentError, 'only strings allowed in string attributes') { @dn.send("#{attr}=", 1) }
@@ -29,13 +29,21 @@ class TestDefinedNames < Test::Unit::TestCase
29
29
  assert_nothing_raised { @dn.local_sheet_id = 1 }
30
30
  end
31
31
 
32
+ def test_do_not_camelcase_value_for_name
33
+ @dn.name = '_xlnm._FilterDatabase'
34
+ doc = Nokogiri::XML(@dn.to_xml_string)
35
+ assert_equal(doc.xpath("//definedName[@name='_xlnm._FilterDatabase']").size, 1)
36
+ assert_equal('Sheet1!A1:A1', doc.xpath('//definedName').text)
37
+ end
38
+
32
39
  def test_to_xml_string
33
40
  assert_raise(ArgumentError, 'name is required for serialization') { @dn.to_xml_string }
34
41
  @dn.name = '_xlnm.Print_Titles'
35
42
  @dn.hidden = true
36
43
  doc = Nokogiri::XML(@dn.to_xml_string)
37
- assert(doc.xpath("//definedName[@name='_xlnm.Print_Titles']"))
38
- assert(doc.xpath("//definedName[@hidden='true']"))
44
+ assert_equal(doc.xpath("//definedName[@name='_xlnm.Print_Titles']").size, 1)
45
+ assert_equal(doc.xpath("//definedName[@hidden='1']").size, 1)
39
46
  assert_equal('Sheet1!A1:A1', doc.xpath('//definedName').text)
40
47
  end
48
+
41
49
  end
@@ -4,10 +4,12 @@ class TestSharedStringsTable < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  @p = Axlsx::Package.new :use_shared_strings=>true
7
+
7
8
  ws = @p.workbook.add_worksheet
8
9
  ws.add_row ['a', 1, 'b']
9
10
  ws.add_row ['b', 1, 'c']
10
11
  ws.add_row ['c', 1, 'd']
12
+ ws.rows.last.add_cell('b', :type => :text)
11
13
  end
12
14
 
13
15
  def test_workbook_has_shared_strings
@@ -16,7 +18,7 @@ class TestSharedStringsTable < Test::Unit::TestCase
16
18
 
17
19
  def test_count
18
20
  sst = @p.workbook.shared_strings
19
- assert_equal(sst.count, 6)
21
+ assert_equal(sst.count, 7)
20
22
  end
21
23
 
22
24
  def test_unique_count
@@ -41,4 +43,17 @@ class TestSharedStringsTable < Test::Unit::TestCase
41
43
  assert_equal(errors.size, 0, "sharedStirngs.xml Invalid" + errors.map{ |e| e.message }.to_s)
42
44
  end
43
45
 
46
+ def test_remove_control_characters_in_xml_serialization
47
+ nasties = "hello\x10\x00\x1C\x1Eworld"
48
+ @p.workbook.worksheets[0].add_row [nasties]
49
+
50
+ # test that the nasty string was added to the shared strings
51
+ assert @p.workbook.shared_strings.unique_cells.has_key?(nasties)
52
+
53
+ # test that none of the control characters are in the XML output for shared strings
54
+ assert_no_match(/#{Axlsx::CONTROL_CHARS}/, @p.workbook.shared_strings.to_xml_string)
55
+
56
+ # assert that the shared string was normalized to remove the control characters
57
+ assert_not_nil @p.workbook.shared_strings.to_xml_string.index("helloworld")
58
+ end
44
59
  end
@@ -33,12 +33,18 @@ class TestWorkbook < Test::Unit::TestCase
33
33
  assert_equal(@wb.use_autowidth, false)
34
34
  end
35
35
 
36
+ def test_is_reversed
37
+ assert_equal(@wb.is_reversed, nil)
38
+ assert_raise(ArgumentError) {@wb.is_reversed = 0.1}
39
+ assert_nothing_raised {@wb.is_reversed = true }
40
+ assert_equal(@wb.use_autowidth, true)
41
+ end
36
42
 
37
43
  def test_sheet_by_name_retrieval
38
44
  @wb.add_worksheet(:name=>'foo')
39
45
  @wb.add_worksheet(:name=>'bar')
40
46
  assert_equal('foo', @wb.sheet_by_name('foo').name)
41
-
47
+
42
48
  end
43
49
  def test_date1904
44
50
  assert_equal(Axlsx::Workbook.date1904, @wb.date1904)
@@ -53,6 +59,11 @@ class TestWorkbook < Test::Unit::TestCase
53
59
  assert_equal(1, @wb.defined_names.size)
54
60
  end
55
61
 
62
+ def test_add_view
63
+ @wb.add_view visibility: :hidden, window_width: 800
64
+ assert_equal(1, @wb.views.size)
65
+ end
66
+
56
67
  def test_shared_strings
57
68
  assert_equal(@wb.use_shared_strings, nil)
58
69
  assert_raise(ArgumentError) {@wb.use_shared_strings = 'bpb'}
@@ -66,7 +77,7 @@ class TestWorkbook < Test::Unit::TestCase
66
77
  assert_equal(@wb.worksheets.first, ws, "the worksheet returned is the worksheet added")
67
78
  assert_equal(ws.name, "bob", "name option gets passed to worksheet")
68
79
  end
69
-
80
+
70
81
  def test_insert_worksheet
71
82
  @wb.add_worksheet(:name => 'A')
72
83
  @wb.add_worksheet(:name => 'B')
@@ -93,7 +104,16 @@ class TestWorkbook < Test::Unit::TestCase
93
104
  end
94
105
  assert(errors.empty?, "error free validation")
95
106
  end
96
- def test_range_requires__valid_sheet
107
+
108
+ def test_to_xml_reversed
109
+ @wb.is_reversed = true
110
+ @wb.add_worksheet(:name => 'first')
111
+ second = @wb.add_worksheet(:name => 'second')
112
+ doc = Nokogiri::XML(@wb.to_xml_string)
113
+ assert_equal second.name, doc.xpath('//xmlns:workbook/xmlns:sheets/*[1]/@name').to_s
114
+ end
115
+
116
+ def test_range_requires_valid_sheet
97
117
  ws = @wb.add_worksheet :name=>'fish'
98
118
  ws.add_row [1,2,3]
99
119
  ws.add_row [4,5,6]
@@ -116,10 +136,25 @@ class TestWorkbook < Test::Unit::TestCase
116
136
  assert_equal(doc.xpath('//xmlns:workbook/xmlns:definedNames/xmlns:definedName').inner_text, @wb.worksheets[0].auto_filter.defined_name)
117
137
  end
118
138
 
139
+ def test_to_xml_string_book_views
140
+ @wb.add_worksheet do |sheet|
141
+ sheet.add_row [1, "two"]
142
+ end
143
+ @wb.add_view active_tab: 0, first_sheet: 0
144
+ doc = Nokogiri::XML(@wb.to_xml_string)
145
+ assert_equal(1, doc.xpath('//xmlns:workbook/xmlns:bookViews/xmlns:workbookView[@activeTab=0]').size)
146
+ end
147
+
119
148
  def test_to_xml_uses_correct_rIds_for_pivotCache
120
149
  ws = @wb.add_worksheet
121
150
  pivot_table = ws.add_pivot_table('G5:G6', 'A1:D5')
122
151
  doc = Nokogiri::XML(@wb.to_xml_string)
123
152
  assert_equal pivot_table.cache_definition.rId, doc.xpath("//xmlns:pivotCache").first["r:id"]
124
153
  end
154
+
155
+ def test_worksheet_name_is_intact_after_serialized_into_xml
156
+ sheet = @wb.add_worksheet(:name => '_Example')
157
+ wb_xml = Nokogiri::XML(@wb.to_xml_string)
158
+ assert_equal sheet.name, wb_xml.xpath('//xmlns:workbook/xmlns:sheets/*[1]/@name').to_s
159
+ end
125
160
  end