spreadsheet_architect 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +17 -2
  3. data/README.md +149 -129
  4. data/lib/spreadsheet_architect/class_methods/csv.rb +2 -2
  5. data/lib/spreadsheet_architect/class_methods/ods.rb +2 -2
  6. data/lib/spreadsheet_architect/class_methods/xlsx.rb +26 -30
  7. data/lib/spreadsheet_architect/exceptions.rb +32 -30
  8. data/lib/spreadsheet_architect/utils/xlsx.rb +46 -25
  9. data/lib/spreadsheet_architect/utils.rb +116 -121
  10. data/lib/spreadsheet_architect/version.rb +1 -1
  11. data/lib/spreadsheet_architect.rb +5 -1
  12. data/test/dummy_app/app/models/active_model_object.rb +1 -0
  13. data/test/dummy_app/app/models/custom_post.rb +1 -0
  14. data/test/dummy_app/app/models/legacy_plain_ruby_object.rb +14 -0
  15. data/test/dummy_app/app/models/plain_ruby_object.rb +2 -9
  16. data/test/dummy_app/app/models/post.rb +3 -0
  17. data/test/dummy_app/config/routes.rb +4 -5
  18. data/test/dummy_app/db/test.sqlite3 +0 -0
  19. data/test/dummy_app/log/test.log +26911 -21739
  20. data/test/dummy_app/tmp/2.0.1/integration/alt_xlsx.xlsx +0 -0
  21. data/test/dummy_app/tmp/2.0.1/integration/csv.csv +6 -0
  22. data/test/dummy_app/tmp/2.0.1/integration/ods.ods +0 -0
  23. data/test/dummy_app/tmp/2.0.1/integration/xlsx.xlsx +0 -0
  24. data/test/dummy_app/tmp/2.0.1/kitchen_sink.ods +0 -0
  25. data/test/dummy_app/tmp/2.0.1/kitchen_sink.xlsx +0 -0
  26. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.csv +3 -0
  27. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.ods +0 -0
  28. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.xlsx +0 -0
  29. data/test/dummy_app/tmp/{empty_sa.csv → 2.0.1/models/ActiveModelObject/empty.csv} +0 -0
  30. data/test/dummy_app/tmp/{ods/empty_model.ods → 2.0.1/models/ActiveModelObject/empty.ods} +0 -0
  31. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.xlsx +0 -0
  32. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.csv +6 -0
  33. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.ods +0 -0
  34. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.xlsx +0 -0
  35. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.csv +3 -0
  36. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.ods +0 -0
  37. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.xlsx +0 -0
  38. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.csv +1 -0
  39. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.ods +0 -0
  40. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.xlsx +0 -0
  41. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.csv +6 -0
  42. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.ods +0 -0
  43. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.xlsx +0 -0
  44. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.csv +3 -0
  45. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.ods +0 -0
  46. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.xlsx +0 -0
  47. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.csv +1 -0
  48. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.ods +0 -0
  49. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  50. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.csv +6 -0
  51. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.ods +0 -0
  52. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  53. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.csv +3 -0
  54. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.ods +0 -0
  55. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.xlsx +0 -0
  56. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.csv +0 -0
  57. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.ods +0 -0
  58. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.xlsx +0 -0
  59. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.csv +6 -0
  60. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.ods +0 -0
  61. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.xlsx +0 -0
  62. data/test/dummy_app/tmp/2.0.1/models/Post/data.csv +3 -0
  63. data/test/dummy_app/tmp/2.0.1/models/Post/data.ods +0 -0
  64. data/test/dummy_app/tmp/2.0.1/models/Post/data.xlsx +0 -0
  65. data/test/dummy_app/tmp/2.0.1/models/Post/empty.csv +0 -0
  66. data/test/dummy_app/tmp/2.0.1/models/Post/empty.ods +0 -0
  67. data/test/dummy_app/tmp/2.0.1/models/Post/empty.xlsx +0 -0
  68. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/data.csv +3 -0
  69. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/data.ods +0 -0
  70. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/data.xlsx +0 -0
  71. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/empty.csv +0 -0
  72. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/empty.ods +0 -0
  73. data/test/dummy_app/tmp/2.0.1/models/SpreadsheetArchitect/empty.xlsx +0 -0
  74. data/test/dummy_app/tmp/2.0.1/multi_sheet.ods +0 -0
  75. data/test/dummy_app/tmp/2.0.1/multi_sheet.xlsx +0 -0
  76. data/test/dummy_app/tmp/3.0.0.pre/integration/alt_xlsx.xlsx +0 -0
  77. data/test/dummy_app/tmp/3.0.0.pre/integration/csv.csv +6 -0
  78. data/test/dummy_app/tmp/3.0.0.pre/integration/ods.ods +0 -0
  79. data/test/dummy_app/tmp/3.0.0.pre/integration/xlsx.xlsx +0 -0
  80. data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.ods +0 -0
  81. data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.xlsx +0 -0
  82. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.csv +3 -0
  83. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.ods +0 -0
  84. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.xlsx +0 -0
  85. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.csv +0 -0
  86. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.ods +0 -0
  87. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.xlsx +0 -0
  88. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.csv +6 -0
  89. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.ods +0 -0
  90. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.xlsx +0 -0
  91. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.csv +3 -0
  92. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.ods +0 -0
  93. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.xlsx +0 -0
  94. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.csv +1 -0
  95. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.ods +0 -0
  96. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.xlsx +0 -0
  97. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.csv +6 -0
  98. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.ods +0 -0
  99. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.xlsx +0 -0
  100. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.csv +3 -0
  101. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.ods +0 -0
  102. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.xlsx +0 -0
  103. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.csv +0 -0
  104. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.ods +0 -0
  105. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  106. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.csv +6 -0
  107. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.ods +0 -0
  108. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  109. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.csv +3 -0
  110. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.ods +0 -0
  111. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.xlsx +0 -0
  112. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.csv +1 -0
  113. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.ods +0 -0
  114. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.xlsx +0 -0
  115. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.csv +6 -0
  116. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.ods +0 -0
  117. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.xlsx +0 -0
  118. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.csv +3 -0
  119. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.ods +0 -0
  120. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.xlsx +0 -0
  121. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.csv +0 -0
  122. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.ods +0 -0
  123. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.xlsx +0 -0
  124. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/data.csv +3 -0
  125. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/data.ods +0 -0
  126. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/data.xlsx +0 -0
  127. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/empty.csv +0 -0
  128. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/empty.ods +0 -0
  129. data/test/dummy_app/tmp/3.0.0.pre/models/SpreadsheetArchitect/empty.xlsx +0 -0
  130. data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.ods +0 -0
  131. data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.xlsx +0 -0
  132. data/test/dummy_app/tmp/axlsx-master/integration/alt_xlsx.xlsx +0 -0
  133. data/test/dummy_app/tmp/axlsx-master/integration/csv.csv +6 -0
  134. data/test/dummy_app/tmp/axlsx-master/integration/ods.ods +0 -0
  135. data/test/dummy_app/tmp/axlsx-master/integration/xlsx.xlsx +0 -0
  136. data/test/dummy_app/tmp/axlsx-master/kitchen_sink.ods +0 -0
  137. data/test/dummy_app/tmp/axlsx-master/kitchen_sink.xlsx +0 -0
  138. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.csv +3 -0
  139. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.ods +0 -0
  140. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.xlsx +0 -0
  141. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.csv +0 -0
  142. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.ods +0 -0
  143. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.xlsx +0 -0
  144. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.csv +6 -0
  145. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.ods +0 -0
  146. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.xlsx +0 -0
  147. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.csv +3 -0
  148. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.ods +0 -0
  149. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.xlsx +0 -0
  150. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.csv +0 -0
  151. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.ods +0 -0
  152. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.xlsx +0 -0
  153. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.csv +6 -0
  154. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.ods +0 -0
  155. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.xlsx +0 -0
  156. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.csv +3 -0
  157. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.ods +0 -0
  158. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.xlsx +0 -0
  159. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.csv +1 -0
  160. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.ods +0 -0
  161. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  162. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.csv +6 -0
  163. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.ods +0 -0
  164. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  165. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.csv +3 -0
  166. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.ods +0 -0
  167. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.xlsx +0 -0
  168. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.csv +1 -0
  169. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.ods +0 -0
  170. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.xlsx +0 -0
  171. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.csv +6 -0
  172. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.ods +0 -0
  173. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.xlsx +0 -0
  174. data/test/dummy_app/tmp/axlsx-master/models/Post/data.csv +3 -0
  175. data/test/dummy_app/tmp/axlsx-master/models/Post/data.ods +0 -0
  176. data/test/dummy_app/tmp/axlsx-master/models/Post/data.xlsx +0 -0
  177. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.csv +0 -0
  178. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.ods +0 -0
  179. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.xlsx +0 -0
  180. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/data.csv +3 -0
  181. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/data.ods +0 -0
  182. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/data.xlsx +0 -0
  183. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/empty.csv +0 -0
  184. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/empty.ods +0 -0
  185. data/test/dummy_app/tmp/axlsx-master/models/SpreadsheetArchitect/empty.xlsx +0 -0
  186. data/test/dummy_app/tmp/axlsx-master/multi_sheet.ods +0 -0
  187. data/test/dummy_app/tmp/axlsx-master/multi_sheet.xlsx +0 -0
  188. data/test/integration/application_test.rb +8 -11
  189. data/test/models/all_models_test.rb +107 -0
  190. data/test/test_helper.rb +13 -4
  191. data/test/unit/exceptions_test.rb +168 -0
  192. data/test/unit/formats_test.rb +15 -0
  193. data/test/unit/general_test.rb +15 -0
  194. data/test/unit/kitchen_sink_test.rb +87 -0
  195. data/test/unit/multi_sheet_test.rb +29 -0
  196. data/test/unit/utils_test.rb +179 -0
  197. data/test/unit/xlsx_utils_test.rb +143 -0
  198. metadata +409 -116
  199. data/lib/generators/spreadsheet_architect/add_project_defaults_generator.rb +0 -20
  200. data/test/dummy_app/app/models/bad_plain_ruby_object.rb +0 -3
  201. data/test/dummy_app/app/views/reports/sample.html.erb +0 -1
  202. data/test/dummy_app/log/development.log +0 -28
  203. data/test/dummy_app/tmp/active_model_object/csv.csv +0 -21
  204. data/test/dummy_app/tmp/active_model_object/ods.ods +0 -0
  205. data/test/dummy_app/tmp/active_model_object/xlsx.xlsx +0 -0
  206. data/test/dummy_app/tmp/custom_posts/csv.csv +0 -6
  207. data/test/dummy_app/tmp/custom_posts/empty.xlsx +0 -0
  208. data/test/dummy_app/tmp/custom_posts/ods.ods +0 -0
  209. data/test/dummy_app/tmp/custom_posts/xlsx.xlsx +0 -0
  210. data/test/dummy_app/tmp/empty_model.csv +0 -1
  211. data/test/dummy_app/tmp/empty_model.xlsx +0 -0
  212. data/test/dummy_app/tmp/empty_sa.xlsx +0 -0
  213. data/test/dummy_app/tmp/extreme.xlsx +0 -0
  214. data/test/dummy_app/tmp/integration_tests/alt_xlsx.xlsx +0 -0
  215. data/test/dummy_app/tmp/integration_tests/csv.csv +0 -6
  216. data/test/dummy_app/tmp/integration_tests/ods.ods +0 -0
  217. data/test/dummy_app/tmp/integration_tests/xlsx.xlsx +0 -0
  218. data/test/dummy_app/tmp/model.csv +0 -6
  219. data/test/dummy_app/tmp/model.xlsx +0 -0
  220. data/test/dummy_app/tmp/ods/empty_sa.ods +0 -0
  221. data/test/dummy_app/tmp/ods/model.ods +0 -0
  222. data/test/dummy_app/tmp/ods/model_options.ods +0 -0
  223. data/test/dummy_app/tmp/ods/sa.ods +0 -0
  224. data/test/dummy_app/tmp/options.csv +0 -6
  225. data/test/dummy_app/tmp/plain_ruby_object/csv.csv +0 -4
  226. data/test/dummy_app/tmp/plain_ruby_object/ods.ods +0 -0
  227. data/test/dummy_app/tmp/plain_ruby_object/xlsx.xlsx +0 -0
  228. data/test/dummy_app/tmp/posts/csv.csv +0 -6
  229. data/test/dummy_app/tmp/posts/empty.xlsx +0 -0
  230. data/test/dummy_app/tmp/posts/ods.ods +0 -0
  231. data/test/dummy_app/tmp/posts/xlsx.xlsx +0 -0
  232. data/test/dummy_app/tmp/sa.csv +0 -4
  233. data/test/dummy_app/tmp/sa.xlsx +0 -0
  234. data/test/models/active_model_object_test.rb +0 -51
  235. data/test/models/bad_plain_ruby_object_test.rb +0 -28
  236. data/test/models/csv_test.rb +0 -59
  237. data/test/models/custom_post_test.rb +0 -51
  238. data/test/models/ods_test.rb +0 -65
  239. data/test/models/plain_ruby_object_test.rb +0 -51
  240. data/test/models/post_test.rb +0 -44
  241. data/test/models/spreadsheet_architect_utils_test.rb +0 -73
  242. data/test/models/xlsx_test.rb +0 -98
  243. data/test/spreadsheet_architect_test.rb +0 -11
@@ -4,26 +4,21 @@ require 'test_helper'
4
4
 
5
5
  class ApplicationTest < ActionDispatch::IntegrationTest
6
6
  def setup
7
- @path = Rails.root.join('tmp/integration_tests')
7
+ @path = VERSIONED_BASE_PATH.join("integration")
8
8
  FileUtils.mkdir_p(@path)
9
9
  end
10
10
 
11
- test "Renders sample xlsx action" do
12
- get '/spreadsheet/xlsx', params: {format: :xlsx}
13
- assert_response :success
14
- assert_not @response.body.include?("<h1>Hello World!</h1>")
15
- end
16
-
17
11
  def test_csv
18
- get '/spreadsheet/csv'
12
+ get '/spreadsheets/csv', params: {format: :csv}
19
13
  assert_response :success
14
+
20
15
  File.open(File.join(@path, 'csv.csv'), 'w+b') do |f|
21
16
  f.write @response.body
22
17
  end
23
18
  end
24
19
 
25
20
  def test_ods
26
- get '/spreadsheet/ods'
21
+ get '/spreadsheets/ods'
27
22
  assert_response :success
28
23
 
29
24
  File.open(File.join(@path, 'ods.ods'), 'w+b') do |f|
@@ -32,16 +27,18 @@ class ApplicationTest < ActionDispatch::IntegrationTest
32
27
  end
33
28
 
34
29
  def test_xlsx
35
- get '/spreadsheet/xlsx'
30
+ get '/spreadsheets/xlsx'
36
31
  assert_response :success
32
+
37
33
  File.open(File.join(@path, 'xlsx.xlsx'), 'w+b') do |f|
38
34
  f.write @response.body
39
35
  end
40
36
  end
41
37
 
42
38
  def test_alt_xlsx
43
- get '/spreadsheet/alt_xlsx', params: {format: :xlsx}
39
+ get '/spreadsheets/alt_xlsx', params: {format: :xlsx}
44
40
  assert_response :success
41
+
45
42
  File.open(File.join(@path, 'alt_xlsx.xlsx'), 'w+b') do |f|
46
43
  f.write @response.body
47
44
  end
@@ -0,0 +1,107 @@
1
+ require "test_helper"
2
+
3
+ class AllModelsTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @data = [
7
+ ['row1', 'test1'],
8
+ [123.456, nil, '123'],
9
+ [123, Date.today, Time.now]
10
+ ]
11
+ end
12
+
13
+ def teardown
14
+ end
15
+
16
+ def set_path(klass)
17
+ @path = VERSIONED_BASE_PATH.join("models/#{klass}")
18
+ FileUtils.mkdir_p(@path)
19
+ end
20
+
21
+ models = [SpreadsheetArchitect, ActiveModelObject, PlainRubyObject, LegacyPlainRubyObject, Post, CustomPost]
22
+
23
+ models.each do |klass|
24
+ instances = 5.times.map{|i|
25
+ x = (klass == SpreadsheetArchitect ? Post : klass).new
26
+ x.name = i
27
+ x.content = i+2
28
+ x.created_at = Time.now
29
+ x
30
+ }
31
+
32
+ ['csv', 'ods', 'xlsx'].each do |format|
33
+
34
+ if klass.instance_methods.include?(:spreadsheet_columns) || klass.instance_methods.include?(:column_names)
35
+
36
+ test ":instances #{klass} #{format}" do
37
+ set_path(klass)
38
+
39
+ method = "to_#{format}"
40
+ which = klass.respond_to?(method) ? klass : SpreadsheetArchitect
41
+
42
+ data = which.send(method, instances: instances)
43
+
44
+ File.open(File.join(@path, "instances.#{format}"), 'w+b') do |f|
45
+ f.write data
46
+ end
47
+ end
48
+
49
+ test "Empty :instances #{klass} #{format}" do
50
+ set_path(klass)
51
+
52
+ method = "to_#{format}"
53
+ which = klass.respond_to?(method) ? klass : SpreadsheetArchitect
54
+
55
+ File.open(File.join(@path, "empty.#{format}"),'w+b') do |f|
56
+ f.write which.send(method, instances: [])
57
+ end
58
+ end
59
+ end
60
+
61
+ test ":data #{klass} #{format}" do
62
+ set_path(klass)
63
+
64
+ method = "to_#{format}"
65
+ which = klass.respond_to?(method) ? klass : SpreadsheetArchitect
66
+
67
+ data = which.send(method, data: @data)
68
+
69
+ File.open(File.join(@path, "data.#{format}"), 'w+b') do |f|
70
+ f.write data
71
+ end
72
+ end
73
+
74
+ test "Empty :data #{klass} #{format}" do
75
+ set_path(klass)
76
+
77
+ method = "to_#{format}"
78
+ which = klass.respond_to?(method) ? klass : SpreadsheetArchitect
79
+
80
+ File.open(File.join(@path, "empty.#{format}"),'w+b') do |f|
81
+ f.write which.send(method, data: [])
82
+ end
83
+ end
84
+
85
+ if klass.is_a?(ActiveRecord::Base)
86
+ test "ActiveRecord::Relation" do
87
+ method = "to_#{format}"
88
+
89
+ File.open(File.join(@path, "active_record_relation.#{format}"),'w+b') do |f|
90
+ f.write klass.all.send(method)
91
+ end
92
+ end
93
+
94
+ test "Empty ActiveRecord::Relation" do
95
+ method = "to_#{format}"
96
+
97
+ File.open(File.join(@path, "empty_active_record_relation.#{format}"),'w+b') do |f|
98
+ f.write klass.limit(0).send(method)
99
+ end
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+
107
+ end
data/test/test_helper.rb CHANGED
@@ -23,13 +23,22 @@ Minitest::Reporters.use!
23
23
 
24
24
  require 'custom_assertions'
25
25
 
26
- ### Cleanup old test spreadsheets
27
- FileUtils.remove_dir(Rails.root.join('tmp/'), true)
28
- FileUtils.mkdir(Rails.root.join('tmp/'))
29
-
30
26
  post_count = Post.count
31
27
  if post_count < 5
32
28
  (5 - post_count).times do |i|
33
29
  Post.create!(name: "foo #{i}", content: "bar #{i}", age: i)
34
30
  end
35
31
  end
32
+
33
+ axlsx_spec = Gem.loaded_specs['axlsx']
34
+ if !axlsx_spec.source.is_a?(Bundler::Source::Rubygems)
35
+ axlsx_version = 'axlsx-master'
36
+ else
37
+ axlsx_version = axlsx_spec.version.to_s
38
+ end
39
+
40
+ VERSIONED_BASE_PATH = Rails.root.join("tmp/#{axlsx_version}")
41
+
42
+ ### Cleanup old test spreadsheets
43
+ FileUtils.remove_dir(VERSIONED_BASE_PATH, true)
44
+ FileUtils.mkdir_p(VERSIONED_BASE_PATH)
@@ -0,0 +1,168 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionsTest < ActiveSupport::TestCase
4
+
5
+ test "NoDataError" do
6
+ error = SpreadsheetArchitect::Exceptions::NoDataError
7
+
8
+ assert error.new
9
+
10
+ assert_raise error do
11
+ SpreadsheetArchitect.to_csv(foo: :bar)
12
+ end
13
+ end
14
+
15
+ test "MultipleDataSourcesError" do
16
+ error = SpreadsheetArchitect::Exceptions::MultipleDataSourcesError
17
+
18
+ assert error.new
19
+
20
+ assert_raise error do
21
+ SpreadsheetArchitect.to_csv(data: [], instances: [])
22
+ end
23
+ end
24
+
25
+ test "InvalidTypeError" do
26
+ error = SpreadsheetArchitect::Exceptions::InvalidTypeError
27
+
28
+ assert error.new(:foobar_option).message
29
+
30
+ assert_raise error do
31
+ SpreadsheetArchitect.to_csv(spreadsheet_columns: :foo)
32
+ end
33
+ assert_raise error do
34
+ SpreadsheetArchitect.to_csv(data: :foo)
35
+ end
36
+ assert_raise error do
37
+ SpreadsheetArchitect.to_csv(instances: :foo)
38
+ end
39
+ assert_raise error do
40
+ SpreadsheetArchitect.to_csv(headers: :foo)
41
+ end
42
+ assert_raise error do
43
+ SpreadsheetArchitect.to_csv(header_style: :foo)
44
+ end
45
+ assert_raise error do
46
+ SpreadsheetArchitect.to_csv(row_style: :foo)
47
+ end
48
+ assert_raise error do
49
+ SpreadsheetArchitect.to_csv(column_styles: :foo)
50
+ end
51
+ assert_raise error do
52
+ SpreadsheetArchitect.to_csv(range_styles: :foo)
53
+ end
54
+ assert_raise error do
55
+ SpreadsheetArchitect.to_csv(merges: :foo)
56
+ end
57
+ assert_raise error do
58
+ SpreadsheetArchitect.to_csv(borders: :foo)
59
+ end
60
+ assert_raise error do
61
+ SpreadsheetArchitect.to_csv(column_widths: :foo)
62
+ end
63
+ end
64
+
65
+ test "SpreadsheetColumnsNotDefinedError" do
66
+ error = SpreadsheetArchitect::Exceptions::SpreadsheetColumnsNotDefinedError
67
+
68
+ assert_raise ArgumentError do
69
+ error.new
70
+ end
71
+
72
+ assert error.new(SpreadsheetArchitect)
73
+
74
+ class QuickBadClass
75
+ include SpreadsheetArchitect
76
+ end
77
+
78
+ assert_raise error do
79
+ QuickBadClass.to_csv(instances: [])
80
+ end
81
+ end
82
+
83
+ test "InvalidColumnError" do
84
+ error = SpreadsheetArchitect::Exceptions::InvalidColumnError
85
+
86
+ assert_raise ArgumentError do
87
+ error.new
88
+ end
89
+
90
+ assert error.new(:foobar_column)
91
+
92
+ assert_raise error do
93
+ SpreadsheetArchitect.to_xlsx(data: [[1]], column_styles: [{columns: 999}])
94
+ end
95
+
96
+ assert_raise error do
97
+ SpreadsheetArchitect.to_xlsx(data: [[1]], column_styles: [{columns: 'ZZZ'}])
98
+ end
99
+
100
+ assert_raise error do
101
+ SpreadsheetArchitect.to_xlsx(data: [[1]], column_styles: [{columns: [999]}])
102
+ end
103
+
104
+ assert_raise error do
105
+ SpreadsheetArchitect.to_xlsx(data: [[1]], column_styles: [{columns: ('ZZX'..'ZZZ')}])
106
+ end
107
+ end
108
+
109
+ test "InvalidRangeStylesOptionError" do
110
+ error = SpreadsheetArchitect::Exceptions::InvalidRangeStylesOptionError
111
+
112
+ assert_raise ArgumentError do
113
+ error.new
114
+ end
115
+
116
+ assert error.new(:columns, :bar_opt)
117
+ assert error.new(:row, :bar_opt)
118
+ assert error.new(:foo, :bar_opt)
119
+
120
+ assert_raise error do
121
+ SpreadsheetArchitect::Utils::XLSX.range_hash_to_str({columns: :foo}, 1, 1)
122
+ end
123
+
124
+ assert_raise error do
125
+ SpreadsheetArchitect::Utils::XLSX.range_hash_to_str({rows: :foo}, 1, 1)
126
+ end
127
+ end
128
+
129
+ test "InvalidRangeError" do
130
+ error = SpreadsheetArchitect::Exceptions::InvalidRangeError
131
+
132
+ assert_raise ArgumentError do
133
+ error.new
134
+ end
135
+
136
+ errors = []
137
+ errors.push error.new(:foo_type, :bar_opt)
138
+ errors.push error.new(:columns, :bar_opt)
139
+ errors.push error.new(:rows, :bar_opt)
140
+ errors.push error.new(:format, :bar_opt)
141
+ errors.push error.new(:type, :bar_opt)
142
+ errors.push error.new(:foo_type, :bar_opt)
143
+
144
+ assert_equal errors.count, errors.uniq.count
145
+ assert error.new(:foo_type, :bar_opt)
146
+
147
+ assert_raise error do
148
+ SpreadsheetArchitect::Utils::XLSX.verify_range(:foo, 1)
149
+ end
150
+
151
+ assert_raise error do
152
+ SpreadsheetArchitect::Utils::XLSX.verify_range("foo", 1)
153
+ end
154
+
155
+ assert_raise error do
156
+ SpreadsheetArchitect::Utils::XLSX.verify_range("foo:foo", 1)
157
+ end
158
+
159
+ assert_raise error do
160
+ SpreadsheetArchitect::Utils::XLSX.verify_range("A1:A2", 1)
161
+ end
162
+
163
+ assert_raise error do
164
+ SpreadsheetArchitect::Utils::XLSX.verify_range("@1:A2", 1)
165
+ end
166
+ end
167
+
168
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class FormatsTest < ActiveSupport::TestCase
4
+
5
+ [:xlsx, :ods, :csv].each do |format|
6
+ test "Registers :#{format} mime type" do
7
+ assert Mime::Type.lookup_by_extension(format)
8
+ end
9
+
10
+ test "Registers :#{format} template handler" do
11
+ assert ActionController::Renderers::RENDERERS.include?(format.to_sym)
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class GeneralTest < ActiveSupport::TestCase
4
+
5
+ test "Version accessible by default" do
6
+ assert_not_nil SpreadsheetArchitect::VERSION
7
+ end
8
+
9
+ test "Constants dont change" do
10
+ x = SpreadsheetArchitect.default_options.to_s
11
+ SpreadsheetArchitect.to_xlsx(headers: [[1]], data: [[1]], header_style: {b: false}, row_style: {background_color: '000000'})
12
+ assert_equal(x, SpreadsheetArchitect.default_options.to_s)
13
+ end
14
+
15
+ end
@@ -0,0 +1,87 @@
1
+ require "test_helper"
2
+
3
+ class KitchenSinkTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @options = {
7
+ headers: [
8
+ ['Latest Posts'],
9
+ ['Title','Category','Author','Posted on','Earnings']
10
+ ],
11
+ data: 50.times.map{|i| [i, i*2, i*3, i*4, i*5, i*6, i*7, i*8]},
12
+ header_style: {background_color: "000000", color: "FFFFFF", align: :center, font_size: 12, bold: true, italic: true},
13
+ row_style: {background_color: nil, color: "000000", align: :left, font_size: 12},
14
+ sheet_name: 'Kitchen Sink'
15
+ }
16
+ end
17
+
18
+ def teardown
19
+ end
20
+
21
+ def test_xlsx
22
+ @options.merge!({
23
+ column_styles: [
24
+ {columns: 0, styles: {bold: true}},
25
+ {columns: (1..3), styles: {format_code: "$#,##0.00"}},
26
+ {columns: [4], include_header: true, styles: {italic: true}}
27
+ ],
28
+
29
+ range_styles: [
30
+ {range: "B2:C4", styles: {background_color: "CCCCCC"}},
31
+ {range: {rows: 1, columns: :all}, styles: {bold: true}},
32
+ {range: {rows: (0..5), columns: (1..4)}, styles: {italic: true}},
33
+ {range: {rows: :all, columns: (3..4)}, styles: {color: "999999"}}
34
+ ],
35
+
36
+ borders: [
37
+ {range: "B2:C4"},
38
+ {range: "D6:D7", border_styles: {style: :dashDot, color: "333333"}},
39
+ {range: {rows: (2..11), columns: :all}, border_styles: {edges: [:top,:bottom]}},
40
+ {range: {rows: 3, columns: 4}, border_styles: {edges: [:top,:bottom]}}
41
+ ],
42
+
43
+ merges: [
44
+ {range: "A1:C1"},
45
+ {range: {rows: 2, columns: :all}},
46
+ {range: {rows: (3..4), columns: (0..3)}}
47
+ ],
48
+
49
+ column_types: [
50
+ :string,
51
+ :integer,
52
+ :float,
53
+ :boolean,
54
+ nil,
55
+ ],
56
+ })
57
+
58
+ # Using Array Data
59
+ file_data = SpreadsheetArchitect.to_xlsx(@options)
60
+
61
+ File.open(VERSIONED_BASE_PATH.join("kitchen_sink.xlsx"),'w+b') do |f|
62
+ f.write file_data
63
+ end
64
+ end
65
+
66
+ def test_ods
67
+ @options.merge!({
68
+ column_types: [
69
+ :string,
70
+ :float,
71
+ :percent,
72
+ :currency,
73
+ :date,
74
+ :time,
75
+ nil
76
+ ],
77
+ })
78
+
79
+ # Using Array Data
80
+ file_data = SpreadsheetArchitect.to_ods(@options)
81
+
82
+ File.open(VERSIONED_BASE_PATH.join("kitchen_sink.ods"),'w+b') do |f|
83
+ f.write file_data
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+ class MultiSheetTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @test_data = [[1,2,3], [4,5,6], [7,8,9]]
7
+ end
8
+
9
+ test "xlsx" do
10
+ package = Post.to_axlsx_package
11
+ package = CustomPost.to_axlsx_package({sheet_name: 'Latest Projects'}, package)
12
+ package = SpreadsheetArchitect.to_axlsx_package({data: @test_data, sheet_name: 'Another Sheet'}, package)
13
+
14
+ File.open(VERSIONED_BASE_PATH.join("multi_sheet.xlsx"),'w+b') do |f|
15
+ f.write package.to_stream.read
16
+ end
17
+ end
18
+
19
+ test "ods" do
20
+ spreadsheet = Post.to_rodf_spreadsheet
21
+ spreadsheet = CustomPost.to_rodf_spreadsheet({sheet_name: 'Latest Projects'}, spreadsheet)
22
+ spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet({data: @test_data, sheet_name: 'Another Sheet'}, spreadsheet)
23
+
24
+ File.open(VERSIONED_BASE_PATH.join("multi_sheet.ods"),'w+b') do |f|
25
+ f.write spreadsheet.bytes
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,179 @@
1
+ require 'test_helper'
2
+
3
+ class UtilsTest < ActiveSupport::TestCase
4
+ klass = SpreadsheetArchitect::Utils
5
+
6
+ def setup
7
+ @options = {
8
+ header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
9
+ row_style: {background_color: nil, color: '000000', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
10
+ sheet_name: 'My Project Export',
11
+ column_styles: [],
12
+ range_styles: [],
13
+ merges: [],
14
+ borders: [],
15
+ column_types: [],
16
+ column_widths: [],
17
+
18
+ headers: ['test1', 'test2','test3'],
19
+ data: [
20
+ ['row1'],
21
+ ['row2 c1', 'row2 c2'],
22
+ ['the','data']
23
+ ]
24
+ }
25
+ end
26
+
27
+ def teardown
28
+ end
29
+
30
+ test "get_cell_data" do
31
+ assert klass.get_cell_data(@options, SpreadsheetArchitect)
32
+
33
+ assert klass.get_cell_data(@options, Post)
34
+
35
+ assert klass.get_options({}, SpreadsheetArchitect)
36
+
37
+ assert_raise SpreadsheetArchitect::Exceptions::MultipleDataSourcesError do
38
+ klass.get_cell_data(@options.merge(instances: []), SpreadsheetArchitect)
39
+ end
40
+
41
+ ### using Data option
42
+ output = klass.get_cell_data(@options.merge(headers: true), SpreadsheetArchitect)
43
+ assert_equal false, output[:headers]
44
+
45
+ output = klass.get_cell_data(@options.merge(column_types: nil), SpreadsheetArchitect)
46
+ assert_nil output[:column_types]
47
+
48
+ output = klass.get_cell_data(@options.merge(column_types: []), SpreadsheetArchitect)
49
+ assert_nil output[:column_types]
50
+
51
+ output = klass.get_cell_data(@options.merge(column_types: [:string]), SpreadsheetArchitect)
52
+ assert_equal output[:column_types], [:string]
53
+
54
+ headers = [[1,2,3], [3,4,5]]
55
+ output = klass.get_cell_data(@options.merge(headers: headers), SpreadsheetArchitect)
56
+ assert_equal headers, output[:headers]
57
+
58
+ ### Using instances option
59
+ output = klass.get_cell_data(@options.merge(data: nil), Post.all)
60
+ assert output[:instances].is_a?(Array)
61
+
62
+ output = klass.get_cell_data(@options.merge(data: nil), Post.limit(0))
63
+ assert output[:instances].is_a?(Array)
64
+
65
+ assert_raise SpreadsheetArchitect::Exceptions::NoDataError do
66
+ klass.get_cell_data(@options.merge(data: nil, instances: nil), SpreadsheetArchitect)
67
+ end
68
+
69
+ output = klass.get_cell_data(@options.merge(data: nil, instances: [PlainRubyObject.new]), SpreadsheetArchitect)
70
+ assert output[:instances].count == 1
71
+ end
72
+
73
+ test "get_options" do
74
+ ### Empty
75
+ assert_not_empty klass.get_options({}, SpreadsheetArchitect)
76
+
77
+ ### using SpreadsheetArchitect
78
+ assert_not_empty klass.get_options(@options, SpreadsheetArchitect)
79
+
80
+ ### with model defaults via SPREADSHEET_OPTIONS
81
+ assert defined?(CustomPost::SPREADSHEET_OPTIONS)
82
+ assert klass.get_options(@options, CustomPost)
83
+
84
+ ### without model defaults via SPREADSHEET_OPTIONS
85
+ assert_not_empty klass.get_options(@options, Post)
86
+
87
+ ### without :headers removes :header_style
88
+ assert_equal klass.get_options({header_style: false, headers: false}, SpreadsheetArchitect)[:header_style], false
89
+
90
+ ### sets :sheet_name if needed
91
+ assert_equal klass.get_options({sheet_name: false}, SpreadsheetArchitect)[:sheet_name], 'Sheet1'
92
+
93
+ ### sets :sheet_name if needed, using pluralized only when using Rails
94
+ assert_equal klass.get_options({sheet_name: false}, Post)[:sheet_name], 'Posts'
95
+ end
96
+
97
+ test "convert_styles_to_ods" do
98
+ ods_styles = klass.convert_styles_to_ods({
99
+ background_color: '333333',
100
+ color: '000000',
101
+ align: true,
102
+ bold: true,
103
+ font_size: 14,
104
+ italic: true,
105
+ underline: true,
106
+ test: true
107
+ })
108
+
109
+ assert_equal(ods_styles, {
110
+ 'cell' => {
111
+ 'background-color' => '#333333'
112
+ },
113
+ 'text' => {
114
+ 'color' => '#000000',
115
+ 'align' => true,
116
+ 'font-weight' => 'bold',
117
+ 'font-size' => 14,
118
+ 'font-style' => 'italic',
119
+ 'text-underline-type' => 'single',
120
+ 'text-underline-style' => 'solid'
121
+ }
122
+ })
123
+ end
124
+
125
+ test "is_ar_model" do
126
+ assert klass.is_ar_model?(Post)
127
+
128
+ assert_not klass.is_ar_model?(SpreadsheetArchitect)
129
+ end
130
+
131
+ test "str_titleize" do
132
+ assert_equal(klass.str_titleize('my_project_export'), 'My Project Export')
133
+ assert_equal(klass.str_titleize('My Project Export'), 'My Project Export')
134
+ assert_equal(klass.str_titleize('TBS report'), 'TBS Report')
135
+ end
136
+
137
+ test "check_option_type" do
138
+ klass.check_option_type(@options, :data, Array)
139
+
140
+ klass.check_option_type(@options, :foo, Array)
141
+
142
+ assert_raise SpreadsheetArchitect::Exceptions::InvalidTypeError do
143
+ klass.check_option_type({foo: :bar}, :foo, Array)
144
+ end
145
+ end
146
+
147
+ test "verify_option_types" do
148
+ klass.verify_option_types(@options)
149
+
150
+ assert_raise SpreadsheetArchitect::Exceptions::InvalidTypeError do
151
+ klass.verify_option_types(@options.merge({column_widths: :foobar}))
152
+ end
153
+ end
154
+
155
+ test "stringify_keys" do
156
+ hash = klass.stringify_keys
157
+ assert_empty hash
158
+
159
+ hash = klass.stringify_keys({foo: :bar})
160
+ assert_nil hash[:foo]
161
+ assert_equal hash['foo'], :bar
162
+
163
+ hash = klass.stringify_keys({foo: :bar, 'bar' => :foo})
164
+ assert_nil hash[:foo]
165
+ assert_equal hash['foo'], :bar
166
+
167
+ hash = klass.stringify_keys({foo: {foo: :bar}})
168
+ assert_nil hash[:foo]
169
+ assert_equal hash['foo']['foo'], :bar
170
+
171
+ hash = klass.stringify_keys({foo: {foo: {foo: :bar}}})
172
+ assert_nil hash[:foo]
173
+ assert_equal hash['foo']['foo']['foo'], :bar
174
+
175
+ hash = klass.stringify_keys({foo: {foo: {foo: {foo: :bar}}}})
176
+ assert_nil hash[:foo]
177
+ assert_equal hash['foo']['foo']['foo']['foo'], :bar
178
+ end
179
+ end