gruff 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (584) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +14 -0
  3. data/Gemfile +10 -0
  4. data/History.txt +193 -0
  5. data/MIT-LICENSE +22 -0
  6. data/Manifest.txt +81 -0
  7. data/README.md +139 -0
  8. data/RELEASE.md +92 -0
  9. data/Rakefile +218 -0
  10. data/assets/bubble.png +0 -0
  11. data/assets/city_scene/background/0000.png +0 -0
  12. data/assets/city_scene/background/0600.png +0 -0
  13. data/assets/city_scene/background/2000.png +0 -0
  14. data/assets/city_scene/clouds/cloudy.png +0 -0
  15. data/assets/city_scene/clouds/partly_cloudy.png +0 -0
  16. data/assets/city_scene/clouds/stormy.png +0 -0
  17. data/assets/city_scene/grass/default.png +0 -0
  18. data/assets/city_scene/haze/true.png +0 -0
  19. data/assets/city_scene/number_sample/1.png +0 -0
  20. data/assets/city_scene/number_sample/2.png +0 -0
  21. data/assets/city_scene/number_sample/default.png +0 -0
  22. data/assets/city_scene/sky/0000.png +0 -0
  23. data/assets/city_scene/sky/0200.png +0 -0
  24. data/assets/city_scene/sky/0400.png +0 -0
  25. data/assets/city_scene/sky/0600.png +0 -0
  26. data/assets/city_scene/sky/0800.png +0 -0
  27. data/assets/city_scene/sky/1000.png +0 -0
  28. data/assets/city_scene/sky/1200.png +0 -0
  29. data/assets/city_scene/sky/1400.png +0 -0
  30. data/assets/city_scene/sky/1500.png +0 -0
  31. data/assets/city_scene/sky/1700.png +0 -0
  32. data/assets/city_scene/sky/2000.png +0 -0
  33. data/assets/pc306715.jpg +0 -0
  34. data/assets/plastik/blue.png +0 -0
  35. data/assets/plastik/green.png +0 -0
  36. data/assets/plastik/red.png +0 -0
  37. data/gruff.gemspec +36 -0
  38. data/init.rb +2 -0
  39. data/lib/gruff.rb +32 -0
  40. data/lib/gruff/accumulator_bar.rb +18 -0
  41. data/lib/gruff/area.rb +51 -0
  42. data/lib/gruff/bar.rb +108 -0
  43. data/lib/gruff/bar_conversion.rb +46 -0
  44. data/lib/gruff/base.rb +1169 -0
  45. data/lib/gruff/bezier.rb +46 -0
  46. data/lib/gruff/bullet.rb +111 -0
  47. data/lib/gruff/deprecated.rb +39 -0
  48. data/lib/gruff/dot.rb +125 -0
  49. data/lib/gruff/line.rb +242 -0
  50. data/lib/gruff/mini/bar.rb +37 -0
  51. data/lib/gruff/mini/legend.rb +109 -0
  52. data/lib/gruff/mini/pie.rb +36 -0
  53. data/lib/gruff/mini/side_bar.rb +35 -0
  54. data/lib/gruff/net.rb +138 -0
  55. data/lib/gruff/photo_bar.rb +100 -0
  56. data/lib/gruff/pie.rb +124 -0
  57. data/lib/gruff/scatter.rb +264 -0
  58. data/lib/gruff/scene.rb +209 -0
  59. data/lib/gruff/side_bar.rb +138 -0
  60. data/lib/gruff/side_stacked_bar.rb +97 -0
  61. data/lib/gruff/spider.rb +131 -0
  62. data/lib/gruff/stacked_area.rb +67 -0
  63. data/lib/gruff/stacked_bar.rb +57 -0
  64. data/lib/gruff/stacked_mixin.rb +23 -0
  65. data/lib/gruff/themes.rb +102 -0
  66. data/lib/gruff/version.rb +3 -0
  67. data/rails_generators/gruff/gruff_generator.rb +63 -0
  68. data/rails_generators/gruff/templates/controller.rb +32 -0
  69. data/rails_generators/gruff/templates/functional_test.rb +24 -0
  70. data/test/gruff_test_case.rb +155 -0
  71. data/test/image_compare.rb +58 -0
  72. data/test/output/accum_bar.png +0 -0
  73. data/test/output/area_keynote.png +0 -0
  74. data/test/output/area_keynote_small.png +0 -0
  75. data/test/output/area_many.png +0 -0
  76. data/test/output/area_many_areas_small.png +0 -0
  77. data/test/output/area_tiny.png +0 -0
  78. data/test/output/area_wide.png +0 -0
  79. data/test/output/bar2_wrapped_legend_16_400.png +0 -0
  80. data/test/output/bar2_wrapped_legend_16_800.png +0 -0
  81. data/test/output/bar2_wrapped_legend_30_400.png +0 -0
  82. data/test/output/bar2_wrapped_legend_30_800.png +0 -0
  83. data/test/output/bar2_wrapped_legend_4_400.png +0 -0
  84. data/test/output/bar2_wrapped_legend_4_800.png +0 -0
  85. data/test/output/bar2_wrapped_legend__400.png +0 -0
  86. data/test/output/bar2_wrapped_legend__800.png +0 -0
  87. data/test/output/bar_background_gradient_bottom_top.png +0 -0
  88. data/test/output/bar_background_gradient_left_right.png +0 -0
  89. data/test/output/bar_background_gradient_right_left.png +0 -0
  90. data/test/output/bar_background_gradient_top_bottom.png +0 -0
  91. data/test/output/bar_background_gradient_topleft_bottomright.png +0 -0
  92. data/test/output/bar_background_gradient_topright_bottomleft.png +0 -0
  93. data/test/output/bar_formatted_numbers.png +0 -0
  94. data/test/output/bar_keynote.png +0 -0
  95. data/test/output/bar_keynote_small.png +0 -0
  96. data/test/output/bar_long_legend_text.png +0 -0
  97. data/test/output/bar_manual_colors.png +0 -0
  98. data/test/output/bar_marker_shadow.png +0 -0
  99. data/test/output/bar_nearly_zero_max_10.png +0 -0
  100. data/test/output/bar_no_legend.png +0 -0
  101. data/test/output/bar_no_line_markers.png +0 -0
  102. data/test/output/bar_no_title.png +0 -0
  103. data/test/output/bar_no_title_or_legend.png +0 -0
  104. data/test/output/bar_odeo.png +0 -0
  105. data/test/output/bar_one_value.png +0 -0
  106. data/test/output/bar_pos_neg.png +0 -0
  107. data/test/output/bar_rails_keynote.png +0 -0
  108. data/test/output/bar_set_absolute_trunc.png +0 -0
  109. data/test/output/bar_set_label_stagger_height.png +0 -0
  110. data/test/output/bar_set_legend_box_size_lg.png +0 -0
  111. data/test/output/bar_set_legend_box_size_sm.png +0 -0
  112. data/test/output/bar_set_marker.png +0 -0
  113. data/test/output/bar_set_trailing_dots_trunc.png +0 -0
  114. data/test/output/bar_spacing_full.png +0 -0
  115. data/test/output/bar_spacing_half.png +0 -0
  116. data/test/output/bar_spacing_none.png +0 -0
  117. data/test/output/bar_tall_graph.png +0 -0
  118. data/test/output/bar_tall_graph_small.png +0 -0
  119. data/test/output/bar_themed.png +0 -0
  120. data/test/output/bar_title_margin.png +0 -0
  121. data/test/output/bar_value_labels.png +0 -0
  122. data/test/output/bar_wide_graph.png +0 -0
  123. data/test/output/bar_wide_graph_small.png +0 -0
  124. data/test/output/bar_wrapped_legend_16_400.png +0 -0
  125. data/test/output/bar_wrapped_legend_16_800.png +0 -0
  126. data/test/output/bar_wrapped_legend_30_400.png +0 -0
  127. data/test/output/bar_wrapped_legend_30_800.png +0 -0
  128. data/test/output/bar_wrapped_legend_4_400.png +0 -0
  129. data/test/output/bar_wrapped_legend_4_800.png +0 -0
  130. data/test/output/bar_wrapped_legend__400.png +0 -0
  131. data/test/output/bar_wrapped_legend__800.png +0 -0
  132. data/test/output/bar_x_y_labels.png +0 -0
  133. data/test/output/bar_y_increment_1.png +0 -0
  134. data/test/output/bar_y_increment_2.0.png +0 -0
  135. data/test/output/bar_y_increment_20.png +0 -0
  136. data/test/output/bar_y_increment_5.png +0 -0
  137. data/test/output/bar_zero_marker_count.png +0 -0
  138. data/test/output/bar_zero_spacing.png +0 -0
  139. data/test/output/bezier.png +0 -0
  140. data/test/output/bezier_2.png +0 -0
  141. data/test/output/bezier_3.png +0 -0
  142. data/test/output/bullet_greyscale.png +0 -0
  143. data/test/output/bullet_no_options.png +0 -0
  144. data/test/output/dot.png +0 -0
  145. data/test/output/dot_manual_colors.png +0 -0
  146. data/test/output/dot_nearly_zero_max_10.png +0 -0
  147. data/test/output/dot_no_legend.png +0 -0
  148. data/test/output/dot_no_line_markers.png +0 -0
  149. data/test/output/dot_no_title.png +0 -0
  150. data/test/output/dot_no_title_or_legend.png +0 -0
  151. data/test/output/dot_one_value.png +0 -0
  152. data/test/output/dot_pos_neg.png +0 -0
  153. data/test/output/dot_set_legend_box_size_lg.png +0 -0
  154. data/test/output/dot_set_legend_box_size_sm.png +0 -0
  155. data/test/output/dot_set_marker.png +0 -0
  156. data/test/output/dot_small.png +0 -0
  157. data/test/output/dot_tall_graph.png +0 -0
  158. data/test/output/dot_tall_graph_small.png +0 -0
  159. data/test/output/dot_themed.png +0 -0
  160. data/test/output/dot_wide_graph.png +0 -0
  161. data/test/output/dot_wide_graph_small.png +0 -0
  162. data/test/output/dot_x_y_labels.png +0 -0
  163. data/test/output/dot_y_increment_1.png +0 -0
  164. data/test/output/dot_y_increment_2.0.png +0 -0
  165. data/test/output/dot_y_increment_20.png +0 -0
  166. data/test/output/dot_y_increment_5.png +0 -0
  167. data/test/output/enhancements-1.png +0 -0
  168. data/test/output/enhancements.png +0 -0
  169. data/test/output/line_all_neg.png +0 -0
  170. data/test/output/line_all_neg_400.png +0 -0
  171. data/test/output/line_all_neg_no_max.png +0 -0
  172. data/test/output/line_baseline.png +0 -0
  173. data/test/output/line_hang_value.png +0 -0
  174. data/test/output/line_hide_dots.png +0 -0
  175. data/test/output/line_hide_lines.png +0 -0
  176. data/test/output/line_jruby_error.png +0 -0
  177. data/test/output/line_large.png +0 -0
  178. data/test/output/line_large_baseline.png +0 -0
  179. data/test/output/line_legend_at_bottom.png +0 -0
  180. data/test/output/line_many.png +0 -0
  181. data/test/output/line_many_lines_small.png +0 -0
  182. data/test/output/line_many_numbers.png +0 -0
  183. data/test/output/line_marker_label_accuracy.png +0 -0
  184. data/test/output/line_more_sets_than_colors.png +0 -0
  185. data/test/output/line_no_data.png +0 -0
  186. data/test/output/line_no_data_msg.png +0 -0
  187. data/test/output/line_no_data_other.png +0 -0
  188. data/test/output/line_no_hide.png +0 -0
  189. data/test/output/line_no_legend.png +0 -0
  190. data/test/output/line_no_line_markers.png +0 -0
  191. data/test/output/line_no_title.png +0 -0
  192. data/test/output/line_nothing_but_the_graph.png +0 -0
  193. data/test/output/line_one_value.png +0 -0
  194. data/test/output/line_one_value_array.png +0 -0
  195. data/test/output/line_pos_neg.png +0 -0
  196. data/test/output/line_pos_neg_400.png +0 -0
  197. data/test/output/line_similar_high_end_values.png +0 -0
  198. data/test/output/line_similar_high_end_values_with_floor.png +0 -0
  199. data/test/output/line_small_small_zero.png +0 -0
  200. data/test/output/line_small_values.png +0 -0
  201. data/test/output/line_small_values_small.png +0 -0
  202. data/test/output/line_small_zero.png +0 -0
  203. data/test/output/line_some_nil_points.png +0 -0
  204. data/test/output/line_theme_37signals_.png +0 -0
  205. data/test/output/line_theme_37signals_400.png +0 -0
  206. data/test/output/line_theme_keynote_.png +0 -0
  207. data/test/output/line_theme_keynote_400.png +0 -0
  208. data/test/output/line_theme_odeo_.png +0 -0
  209. data/test/output/line_theme_odeo_400.png +0 -0
  210. data/test/output/line_theme_rails_keynote_.png +0 -0
  211. data/test/output/line_theme_rails_keynote_400.png +0 -0
  212. data/test/output/line_tiny.png +0 -0
  213. data/test/output/line_transparent.png +0 -0
  214. data/test/output/line_very_small.png +0 -0
  215. data/test/output/line_wide_graph.png +0 -0
  216. data/test/output/line_wide_graph_small.png +0 -0
  217. data/test/output/line_xy.png +0 -0
  218. data/test/output/line_xy_pairs.png +0 -0
  219. data/test/output/line_y_axis_increment.png +0 -0
  220. data/test/output/mini_bar.png +0 -0
  221. data/test/output/mini_pie.png +0 -0
  222. data/test/output/mini_pie_right_legend.png +0 -0
  223. data/test/output/mini_side_bar.png +0 -0
  224. data/test/output/mini_side_bar_multi_color.png +0 -0
  225. data/test/output/net_dots_tiny.png +0 -0
  226. data/test/output/net_large.png +0 -0
  227. data/test/output/net_many.png +0 -0
  228. data/test/output/net_many_nets_small.png +0 -0
  229. data/test/output/net_no_data.png +0 -0
  230. data/test/output/net_no_data_msg.png +0 -0
  231. data/test/output/net_no_data_other.png +0 -0
  232. data/test/output/net_no_legend.png +0 -0
  233. data/test/output/net_no_net_markers.png +0 -0
  234. data/test/output/net_no_title.png +0 -0
  235. data/test/output/net_nothing_but_the_graph.png +0 -0
  236. data/test/output/net_similar_high_end_values.png +0 -0
  237. data/test/output/net_small.png +0 -0
  238. data/test/output/net_small_small.png +0 -0
  239. data/test/output/net_small_small_zero.png +0 -0
  240. data/test/output/net_small_zero.png +0 -0
  241. data/test/output/net_wide_graph.png +0 -0
  242. data/test/output/net_wide_graph_small.png +0 -0
  243. data/test/output/pie_equal.png +0 -0
  244. data/test/output/pie_grey.png +0 -0
  245. data/test/output/pie_keynote.png +0 -0
  246. data/test/output/pie_keynote_small.png +0 -0
  247. data/test/output/pie_legend.png +0 -0
  248. data/test/output/pie_legend_small.png +0 -0
  249. data/test/output/pie_nearly_equal.png +0 -0
  250. data/test/output/pie_one_val.png +0 -0
  251. data/test/output/pie_pastel.png +0 -0
  252. data/test/output/pie_simple.png +0 -0
  253. data/test/output/pie_wide.png +0 -0
  254. data/test/output/pie_wrapped_legend_16_400.png +0 -0
  255. data/test/output/pie_wrapped_legend_16_800.png +0 -0
  256. data/test/output/pie_wrapped_legend_30_400.png +0 -0
  257. data/test/output/pie_wrapped_legend_30_800.png +0 -0
  258. data/test/output/pie_wrapped_legend_4_400.png +0 -0
  259. data/test/output/pie_wrapped_legend_4_800.png +0 -0
  260. data/test/output/pie_wrapped_legend__400.png +0 -0
  261. data/test/output/pie_wrapped_legend__800.png +0 -0
  262. data/test/output/pie_zero.png +0 -0
  263. data/test/output/scatter_all_neg.png +0 -0
  264. data/test/output/scatter_all_neg_400.png +0 -0
  265. data/test/output/scatter_basic.png +0 -0
  266. data/test/output/scatter_many.png +0 -0
  267. data/test/output/scatter_no_data.png +0 -0
  268. data/test/output/scatter_no_data_msg.png +0 -0
  269. data/test/output/scatter_no_data_other.png +0 -0
  270. data/test/output/scatter_no_hide.png +0 -0
  271. data/test/output/scatter_no_labels.png +0 -0
  272. data/test/output/scatter_no_legend.png +0 -0
  273. data/test/output/scatter_no_line_markers.png +0 -0
  274. data/test/output/scatter_no_title.png +0 -0
  275. data/test/output/scatter_nothing_but_the_graph.png +0 -0
  276. data/test/output/scatter_pos_neg.png +0 -0
  277. data/test/output/scatter_pos_neg_400.png +0 -0
  278. data/test/output/scatter_wide_graph.png +0 -0
  279. data/test/output/scatter_wide_graph_small.png +0 -0
  280. data/test/output/scene_hazy_night.png +0 -0
  281. data/test/output/scene_not_hazy_day.png +0 -0
  282. data/test/output/scene_partly_cloudy_day.png +0 -0
  283. data/test/output/scene_stormy_day.png +0 -0
  284. data/test/output/scene_stormy_night.png +0 -0
  285. data/test/output/side_bar.png +0 -0
  286. data/test/output/side_bar_data_range.png +0 -0
  287. data/test/output/side_bar_labels.png +0 -0
  288. data/test/output/side_bar_spacing_full.png +0 -0
  289. data/test/output/side_bar_spacing_half.png +0 -0
  290. data/test/output/side_bar_spacing_none.png +0 -0
  291. data/test/output/side_stacked_bar_keynote.png +0 -0
  292. data/test/output/side_stacked_bar_keynote_small.png +0 -0
  293. data/test/output/side_stacked_bar_labels.png +0 -0
  294. data/test/output/side_stacked_bar_long_label.png +0 -0
  295. data/test/output/side_stacked_bar_wide.png +0 -0
  296. data/test/output/spider_37signals.png +0 -0
  297. data/test/output/spider_equal.png +0 -0
  298. data/test/output/spider_keynote.png +0 -0
  299. data/test/output/spider_legend.png +0 -0
  300. data/test/output/spider_legend_small.png +0 -0
  301. data/test/output/spider_lots_of_data.png +0 -0
  302. data/test/output/spider_lots_of_data_normal_names.png +0 -0
  303. data/test/output/spider_nearly_equal.png +0 -0
  304. data/test/output/spider_no_axes.png +0 -0
  305. data/test/output/spider_no_background.png +0 -0
  306. data/test/output/spider_no_print.png +0 -0
  307. data/test/output/spider_overlay_1.png +0 -0
  308. data/test/output/spider_overlay_2.png +0 -0
  309. data/test/output/spider_rotation.png +0 -0
  310. data/test/output/spider_small.png +0 -0
  311. data/test/output/spider_wide.png +0 -0
  312. data/test/output/spider_zero.png +0 -0
  313. data/test/output/stacked_area_keynote.png +0 -0
  314. data/test/output/stacked_area_keynote_small.png +0 -0
  315. data/test/output/stacked_bar_keynote.png +0 -0
  316. data/test/output/stacked_bar_keynote_small.png +0 -0
  317. data/test/output_java/accum_bar.png +0 -0
  318. data/test/output_java/area_keynote.png +0 -0
  319. data/test/output_java/area_keynote_small.png +0 -0
  320. data/test/output_java/area_many.png +0 -0
  321. data/test/output_java/area_many_areas_small.png +0 -0
  322. data/test/output_java/area_tiny.png +0 -0
  323. data/test/output_java/area_wide.png +0 -0
  324. data/test/output_java/bar2_wrapped_legend_16_400.png +0 -0
  325. data/test/output_java/bar2_wrapped_legend_16_800.png +0 -0
  326. data/test/output_java/bar2_wrapped_legend_30_400.png +0 -0
  327. data/test/output_java/bar2_wrapped_legend_30_800.png +0 -0
  328. data/test/output_java/bar2_wrapped_legend_4_400.png +0 -0
  329. data/test/output_java/bar2_wrapped_legend_4_800.png +0 -0
  330. data/test/output_java/bar2_wrapped_legend__400.png +0 -0
  331. data/test/output_java/bar2_wrapped_legend__800.png +0 -0
  332. data/test/output_java/bar_background_gradient_bottom_top.png +0 -0
  333. data/test/output_java/bar_background_gradient_left_right.png +0 -0
  334. data/test/output_java/bar_background_gradient_right_left.png +0 -0
  335. data/test/output_java/bar_background_gradient_top_bottom.png +0 -0
  336. data/test/output_java/bar_background_gradient_topleft_bottomright.png +0 -0
  337. data/test/output_java/bar_background_gradient_topright_bottomleft.png +0 -0
  338. data/test/output_java/bar_formatted_numbers.png +0 -0
  339. data/test/output_java/bar_keynote.png +0 -0
  340. data/test/output_java/bar_keynote_small.png +0 -0
  341. data/test/output_java/bar_long_legend_text.png +0 -0
  342. data/test/output_java/bar_manual_colors.png +0 -0
  343. data/test/output_java/bar_marker_shadow.png +0 -0
  344. data/test/output_java/bar_nearly_zero_max_10.png +0 -0
  345. data/test/output_java/bar_no_legend.png +0 -0
  346. data/test/output_java/bar_no_line_markers.png +0 -0
  347. data/test/output_java/bar_no_title.png +0 -0
  348. data/test/output_java/bar_no_title_or_legend.png +0 -0
  349. data/test/output_java/bar_odeo.png +0 -0
  350. data/test/output_java/bar_one_value.png +0 -0
  351. data/test/output_java/bar_pos_neg.png +0 -0
  352. data/test/output_java/bar_rails_keynote.png +0 -0
  353. data/test/output_java/bar_set_absolute_trunc.png +0 -0
  354. data/test/output_java/bar_set_label_stagger_height.png +0 -0
  355. data/test/output_java/bar_set_legend_box_size_lg.png +0 -0
  356. data/test/output_java/bar_set_legend_box_size_sm.png +0 -0
  357. data/test/output_java/bar_set_marker.png +0 -0
  358. data/test/output_java/bar_set_trailing_dots_trunc.png +0 -0
  359. data/test/output_java/bar_spacing_full.png +0 -0
  360. data/test/output_java/bar_spacing_half.png +0 -0
  361. data/test/output_java/bar_spacing_none.png +0 -0
  362. data/test/output_java/bar_tall_graph.png +0 -0
  363. data/test/output_java/bar_tall_graph_small.png +0 -0
  364. data/test/output_java/bar_themed.png +0 -0
  365. data/test/output_java/bar_title_margin.png +0 -0
  366. data/test/output_java/bar_value_labels.png +0 -0
  367. data/test/output_java/bar_wide_graph.png +0 -0
  368. data/test/output_java/bar_wide_graph_small.png +0 -0
  369. data/test/output_java/bar_wrapped_legend_16_400.png +0 -0
  370. data/test/output_java/bar_wrapped_legend_16_800.png +0 -0
  371. data/test/output_java/bar_wrapped_legend_30_400.png +0 -0
  372. data/test/output_java/bar_wrapped_legend_30_800.png +0 -0
  373. data/test/output_java/bar_wrapped_legend_4_400.png +0 -0
  374. data/test/output_java/bar_wrapped_legend_4_800.png +0 -0
  375. data/test/output_java/bar_wrapped_legend__400.png +0 -0
  376. data/test/output_java/bar_wrapped_legend__800.png +0 -0
  377. data/test/output_java/bar_x_y_labels.png +0 -0
  378. data/test/output_java/bar_y_increment_1.png +0 -0
  379. data/test/output_java/bar_y_increment_2.0.png +0 -0
  380. data/test/output_java/bar_y_increment_20.png +0 -0
  381. data/test/output_java/bar_y_increment_5.png +0 -0
  382. data/test/output_java/bar_zero_marker_count.png +0 -0
  383. data/test/output_java/bar_zero_spacing.png +0 -0
  384. data/test/output_java/bezier.png +0 -0
  385. data/test/output_java/bezier_2.png +0 -0
  386. data/test/output_java/bezier_3.png +0 -0
  387. data/test/output_java/bullet_greyscale.png +0 -0
  388. data/test/output_java/bullet_no_options.png +0 -0
  389. data/test/output_java/dot.png +0 -0
  390. data/test/output_java/dot_manual_colors.png +0 -0
  391. data/test/output_java/dot_nearly_zero_max_10.png +0 -0
  392. data/test/output_java/dot_no_legend.png +0 -0
  393. data/test/output_java/dot_no_line_markers.png +0 -0
  394. data/test/output_java/dot_no_title.png +0 -0
  395. data/test/output_java/dot_no_title_or_legend.png +0 -0
  396. data/test/output_java/dot_one_value.png +0 -0
  397. data/test/output_java/dot_pos_neg.png +0 -0
  398. data/test/output_java/dot_set_legend_box_size_lg.png +0 -0
  399. data/test/output_java/dot_set_legend_box_size_sm.png +0 -0
  400. data/test/output_java/dot_set_marker.png +0 -0
  401. data/test/output_java/dot_small.png +0 -0
  402. data/test/output_java/dot_tall_graph.png +0 -0
  403. data/test/output_java/dot_tall_graph_small.png +0 -0
  404. data/test/output_java/dot_themed.png +0 -0
  405. data/test/output_java/dot_wide_graph.png +0 -0
  406. data/test/output_java/dot_wide_graph_small.png +0 -0
  407. data/test/output_java/dot_x_y_labels.png +0 -0
  408. data/test/output_java/dot_y_increment_1.png +0 -0
  409. data/test/output_java/dot_y_increment_2.0.png +0 -0
  410. data/test/output_java/dot_y_increment_20.png +0 -0
  411. data/test/output_java/dot_y_increment_5.png +0 -0
  412. data/test/output_java/enhancements-1.png +0 -0
  413. data/test/output_java/enhancements.png +0 -0
  414. data/test/output_java/line_all_neg.png +0 -0
  415. data/test/output_java/line_all_neg_400.png +0 -0
  416. data/test/output_java/line_all_neg_no_max.png +0 -0
  417. data/test/output_java/line_baseline.png +0 -0
  418. data/test/output_java/line_hang_value.png +0 -0
  419. data/test/output_java/line_hide_dots.png +0 -0
  420. data/test/output_java/line_hide_lines.png +0 -0
  421. data/test/output_java/line_jruby_error.png +0 -0
  422. data/test/output_java/line_large.png +0 -0
  423. data/test/output_java/line_large_baseline.png +0 -0
  424. data/test/output_java/line_legend_at_bottom.png +0 -0
  425. data/test/output_java/line_many.png +0 -0
  426. data/test/output_java/line_many_lines_small.png +0 -0
  427. data/test/output_java/line_many_numbers.png +0 -0
  428. data/test/output_java/line_marker_label_accuracy.png +0 -0
  429. data/test/output_java/line_more_sets_than_colors.png +0 -0
  430. data/test/output_java/line_no_data.png +0 -0
  431. data/test/output_java/line_no_data_msg.png +0 -0
  432. data/test/output_java/line_no_data_other.png +0 -0
  433. data/test/output_java/line_no_hide.png +0 -0
  434. data/test/output_java/line_no_legend.png +0 -0
  435. data/test/output_java/line_no_line_markers.png +0 -0
  436. data/test/output_java/line_no_title.png +0 -0
  437. data/test/output_java/line_nothing_but_the_graph.png +0 -0
  438. data/test/output_java/line_one_value.png +0 -0
  439. data/test/output_java/line_one_value_array.png +0 -0
  440. data/test/output_java/line_pos_neg.png +0 -0
  441. data/test/output_java/line_pos_neg_400.png +0 -0
  442. data/test/output_java/line_similar_high_end_values.png +0 -0
  443. data/test/output_java/line_similar_high_end_values_with_floor.png +0 -0
  444. data/test/output_java/line_small_small_zero.png +0 -0
  445. data/test/output_java/line_small_values.png +0 -0
  446. data/test/output_java/line_small_values_small.png +0 -0
  447. data/test/output_java/line_small_zero.png +0 -0
  448. data/test/output_java/line_some_nil_points.png +0 -0
  449. data/test/output_java/line_theme_37signals_.png +0 -0
  450. data/test/output_java/line_theme_37signals_400.png +0 -0
  451. data/test/output_java/line_theme_keynote_.png +0 -0
  452. data/test/output_java/line_theme_keynote_400.png +0 -0
  453. data/test/output_java/line_theme_odeo_.png +0 -0
  454. data/test/output_java/line_theme_odeo_400.png +0 -0
  455. data/test/output_java/line_theme_rails_keynote_.png +0 -0
  456. data/test/output_java/line_theme_rails_keynote_400.png +0 -0
  457. data/test/output_java/line_tiny.png +0 -0
  458. data/test/output_java/line_transparent.png +0 -0
  459. data/test/output_java/line_very_small.png +0 -0
  460. data/test/output_java/line_wide_graph.png +0 -0
  461. data/test/output_java/line_wide_graph_small.png +0 -0
  462. data/test/output_java/line_xy.png +0 -0
  463. data/test/output_java/line_xy_pairs.png +0 -0
  464. data/test/output_java/line_y_axis_increment.png +0 -0
  465. data/test/output_java/mini_bar.png +0 -0
  466. data/test/output_java/mini_pie.png +0 -0
  467. data/test/output_java/mini_pie_right_legend.png +0 -0
  468. data/test/output_java/mini_side_bar.png +0 -0
  469. data/test/output_java/mini_side_bar_multi_color.png +0 -0
  470. data/test/output_java/net_dots_tiny.png +0 -0
  471. data/test/output_java/net_large.png +0 -0
  472. data/test/output_java/net_many.png +0 -0
  473. data/test/output_java/net_many_nets_small.png +0 -0
  474. data/test/output_java/net_no_data.png +0 -0
  475. data/test/output_java/net_no_data_msg.png +0 -0
  476. data/test/output_java/net_no_data_other.png +0 -0
  477. data/test/output_java/net_no_legend.png +0 -0
  478. data/test/output_java/net_no_net_markers.png +0 -0
  479. data/test/output_java/net_no_title.png +0 -0
  480. data/test/output_java/net_nothing_but_the_graph.png +0 -0
  481. data/test/output_java/net_similar_high_end_values.png +0 -0
  482. data/test/output_java/net_small.png +0 -0
  483. data/test/output_java/net_small_small.png +0 -0
  484. data/test/output_java/net_small_small_zero.png +0 -0
  485. data/test/output_java/net_small_zero.png +0 -0
  486. data/test/output_java/net_wide_graph.png +0 -0
  487. data/test/output_java/net_wide_graph_small.png +0 -0
  488. data/test/output_java/pie_equal.png +0 -0
  489. data/test/output_java/pie_grey.png +0 -0
  490. data/test/output_java/pie_keynote.png +0 -0
  491. data/test/output_java/pie_keynote_small.png +0 -0
  492. data/test/output_java/pie_legend.png +0 -0
  493. data/test/output_java/pie_legend_small.png +0 -0
  494. data/test/output_java/pie_nearly_equal.png +0 -0
  495. data/test/output_java/pie_one_val.png +0 -0
  496. data/test/output_java/pie_pastel.png +0 -0
  497. data/test/output_java/pie_simple.png +0 -0
  498. data/test/output_java/pie_wide.png +0 -0
  499. data/test/output_java/pie_wrapped_legend_16_400.png +0 -0
  500. data/test/output_java/pie_wrapped_legend_16_800.png +0 -0
  501. data/test/output_java/pie_wrapped_legend_30_400.png +0 -0
  502. data/test/output_java/pie_wrapped_legend_30_800.png +0 -0
  503. data/test/output_java/pie_wrapped_legend_4_400.png +0 -0
  504. data/test/output_java/pie_wrapped_legend_4_800.png +0 -0
  505. data/test/output_java/pie_wrapped_legend__400.png +0 -0
  506. data/test/output_java/pie_wrapped_legend__800.png +0 -0
  507. data/test/output_java/pie_zero.png +0 -0
  508. data/test/output_java/scatter_all_neg.png +0 -0
  509. data/test/output_java/scatter_all_neg_400.png +0 -0
  510. data/test/output_java/scatter_basic.png +0 -0
  511. data/test/output_java/scatter_many.png +0 -0
  512. data/test/output_java/scatter_no_data.png +0 -0
  513. data/test/output_java/scatter_no_data_msg.png +0 -0
  514. data/test/output_java/scatter_no_data_other.png +0 -0
  515. data/test/output_java/scatter_no_hide.png +0 -0
  516. data/test/output_java/scatter_no_labels.png +0 -0
  517. data/test/output_java/scatter_no_legend.png +0 -0
  518. data/test/output_java/scatter_no_line_markers.png +0 -0
  519. data/test/output_java/scatter_no_title.png +0 -0
  520. data/test/output_java/scatter_nothing_but_the_graph.png +0 -0
  521. data/test/output_java/scatter_pos_neg.png +0 -0
  522. data/test/output_java/scatter_pos_neg_400.png +0 -0
  523. data/test/output_java/scatter_wide_graph.png +0 -0
  524. data/test/output_java/scatter_wide_graph_small.png +0 -0
  525. data/test/output_java/scene_hazy_night.png +0 -0
  526. data/test/output_java/scene_not_hazy_day.png +0 -0
  527. data/test/output_java/scene_partly_cloudy_day.png +0 -0
  528. data/test/output_java/scene_stormy_day.png +0 -0
  529. data/test/output_java/scene_stormy_night.png +0 -0
  530. data/test/output_java/side_bar.png +0 -0
  531. data/test/output_java/side_bar_data_range.png +0 -0
  532. data/test/output_java/side_bar_labels.png +0 -0
  533. data/test/output_java/side_bar_spacing_full.png +0 -0
  534. data/test/output_java/side_bar_spacing_half.png +0 -0
  535. data/test/output_java/side_bar_spacing_none.png +0 -0
  536. data/test/output_java/side_stacked_bar_keynote.png +0 -0
  537. data/test/output_java/side_stacked_bar_keynote_small.png +0 -0
  538. data/test/output_java/side_stacked_bar_labels.png +0 -0
  539. data/test/output_java/side_stacked_bar_long_label.png +0 -0
  540. data/test/output_java/side_stacked_bar_wide.png +0 -0
  541. data/test/output_java/spider_37signals.png +0 -0
  542. data/test/output_java/spider_equal.png +0 -0
  543. data/test/output_java/spider_keynote.png +0 -0
  544. data/test/output_java/spider_legend.png +0 -0
  545. data/test/output_java/spider_legend_small.png +0 -0
  546. data/test/output_java/spider_lots_of_data.png +0 -0
  547. data/test/output_java/spider_lots_of_data_normal_names.png +0 -0
  548. data/test/output_java/spider_nearly_equal.png +0 -0
  549. data/test/output_java/spider_no_axes.png +0 -0
  550. data/test/output_java/spider_no_background.png +0 -0
  551. data/test/output_java/spider_no_print.png +0 -0
  552. data/test/output_java/spider_overlay_1.png +0 -0
  553. data/test/output_java/spider_overlay_2.png +0 -0
  554. data/test/output_java/spider_rotation.png +0 -0
  555. data/test/output_java/spider_small.png +0 -0
  556. data/test/output_java/spider_wide.png +0 -0
  557. data/test/output_java/spider_zero.png +0 -0
  558. data/test/output_java/stacked_area_keynote.png +0 -0
  559. data/test/output_java/stacked_area_keynote_small.png +0 -0
  560. data/test/output_java/stacked_bar_keynote.png +0 -0
  561. data/test/output_java/stacked_bar_keynote_small.png +0 -0
  562. data/test/test_accumulator_bar.rb +51 -0
  563. data/test/test_area.rb +134 -0
  564. data/test/test_bar.rb +505 -0
  565. data/test/test_base.rb +8 -0
  566. data/test/test_bezier.rb +33 -0
  567. data/test/test_bullet.rb +26 -0
  568. data/test/test_dot.rb +263 -0
  569. data/test/test_legend.rb +68 -0
  570. data/test/test_line.rb +626 -0
  571. data/test/test_mini_bar.rb +33 -0
  572. data/test/test_mini_pie.rb +25 -0
  573. data/test/test_mini_side_bar.rb +36 -0
  574. data/test/test_net.rb +231 -0
  575. data/test/test_photo.rb +41 -0
  576. data/test/test_pie.rb +154 -0
  577. data/test/test_scatter.rb +233 -0
  578. data/test/test_scene.rb +100 -0
  579. data/test/test_side_bar.rb +56 -0
  580. data/test/test_sidestacked_bar.rb +105 -0
  581. data/test/test_spider.rb +226 -0
  582. data/test/test_stacked_area.rb +52 -0
  583. data/test/test_stacked_bar.rb +52 -0
  584. metadata +1176 -0
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.dirname(__FILE__) + "/gruff_test_case"
4
+
5
+ class TestGruffBase < GruffTestCase
6
+
7
+
8
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/gruff_test_case"
2
+
3
+ class TestBezier < GruffTestCase
4
+
5
+ def setup
6
+ @data_args = [75, 100, {
7
+ :target => 80,
8
+ :low => 50,
9
+ :high => 90
10
+ }]
11
+ end
12
+
13
+ def test_bezier
14
+ g = Gruff::Bezier.new
15
+ g.title = "Bezier?"
16
+ g.data 'Series 1', [0, 100]
17
+ g.write("test/output/bezier.png")
18
+ end
19
+
20
+ def test_bezier_2
21
+ g = Gruff::Bezier.new
22
+ g.data 'Series 2', [0, 127, 150]
23
+ g.write("test/output/bezier_2.png")
24
+ end
25
+
26
+ def test_bezier_3
27
+ g = Gruff::Bezier.new
28
+ g.data 'Series 3', [100,300,200,250]
29
+ g.minimum_value = 0
30
+ g.write("test/output/bezier_3.png")
31
+ end
32
+
33
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + "/gruff_test_case"
2
+
3
+ class TestGruffBullet < GruffTestCase
4
+
5
+ def setup
6
+ @data_args = [75, 100, {
7
+ :target => 80,
8
+ :low => 50,
9
+ :high => 90
10
+ }]
11
+ end
12
+
13
+ def test_bullet_graph
14
+ g = Gruff::Bullet.new
15
+ g.title = "Monthly Revenue"
16
+ g.data *@data_args
17
+ g.write("test/output/bullet_greyscale.png")
18
+ end
19
+
20
+ def test_no_options
21
+ g = Gruff::Bullet.new
22
+ g.data *@data_args
23
+ g.write("test/output/bullet_no_options.png")
24
+ end
25
+
26
+ end
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.dirname(__FILE__) + '/gruff_test_case'
4
+
5
+ class TestGruffDot < GruffTestCase
6
+
7
+ # TODO Delete old output files once when starting tests
8
+
9
+ def setup
10
+ @datasets = [
11
+ [:Jimmy, [25, 36, 86, 39]],
12
+ [:Charles, [80, 54, 67, 54]],
13
+ [:Julie, [22, 29, 35, 38]],
14
+ #[:Jane, [95, 95, 95, 90, 85, 80, 88, 100]],
15
+ #[:Philip, [90, 34, 23, 12, 78, 89, 98, 88]],
16
+ #["Arthur", [5, 10, 13, 11, 6, 16, 22, 32]],
17
+ ]
18
+ end
19
+
20
+ def test_dot_graph
21
+ g = setup_basic_graph
22
+ g.title = 'Dot Graph Test'
23
+ g.write('test/output/dot.png')
24
+ end
25
+
26
+ def test_dot_graph_set_colors
27
+ g = Gruff::Dot.new
28
+ g.title = 'Dot Graph With Manual Colors'
29
+ g.labels = {
30
+ 0 => '5/6',
31
+ 1 => '5/15',
32
+ 2 => '5/24',
33
+ 3 => '5/30',
34
+ }
35
+ g.data(:Art, [0, 5, 8, 15], '#990000')
36
+ g.data(:Philosophy, [10, 3, 2, 8], '#009900')
37
+ g.data(:Science, [2, 15, 8, 11], '#990099')
38
+
39
+ g.minimum_value = 0
40
+
41
+ g.write('test/output/dot_manual_colors.png')
42
+ end
43
+
44
+ def test_dot_graph_small
45
+ g = setup_basic_graph(400)
46
+ g.title = 'Visual Multi-Line Dot Graph Test'
47
+ g.write('test/output/dot_small.png')
48
+ end
49
+
50
+ # Somewhat worthless test. Should an error be thrown?
51
+ # def test_nil_font
52
+ # g = setup_basic_graph 400
53
+ # g.title = "Nil Font"
54
+ # g.font = nil
55
+ # g.write "test/output/dot_nil_font.png"
56
+ # end
57
+
58
+
59
+ def test_no_line_markers
60
+ g = setup_basic_graph(400)
61
+ g.title = 'No Line Markers'
62
+ g.hide_line_markers = true
63
+ g.write('test/output/dot_no_line_markers.png')
64
+ end
65
+
66
+ def test_no_legend
67
+ g = setup_basic_graph(400)
68
+ g.title = 'No Legend'
69
+ g.hide_legend = true
70
+ g.write('test/output/dot_no_legend.png')
71
+ end
72
+
73
+ def test_no_title
74
+ g = setup_basic_graph(400)
75
+ g.title = 'No Title'
76
+ g.hide_title = true
77
+ g.write('test/output/dot_no_title.png')
78
+ end
79
+
80
+ def test_no_title_or_legend
81
+ g = setup_basic_graph(400)
82
+ g.title = 'No Title or Legend'
83
+ g.hide_legend = true
84
+ g.hide_title = true
85
+ g.write('test/output/dot_no_title_or_legend.png')
86
+ end
87
+
88
+ def test_set_marker_count
89
+ g = setup_basic_graph(400)
90
+ g.title = 'Set marker'
91
+ g.marker_count = 10
92
+ g.write('test/output/dot_set_marker.png')
93
+ end
94
+
95
+ def test_set_legend_box_size
96
+ g = setup_basic_graph(400)
97
+ g.title = 'Set Small Legend Box Size'
98
+ g.legend_box_size = 10.0
99
+ g.write('test/output/dot_set_legend_box_size_sm.png')
100
+
101
+ g = setup_basic_graph(400)
102
+ g.title = 'Set Large Legend Box Size'
103
+ g.legend_box_size = 50.0
104
+ g.write('test/output/dot_set_legend_box_size_lg.png')
105
+ end
106
+
107
+ def test_x_y_labels
108
+ g = setup_basic_graph(400)
109
+ g.title = 'X Y Labels'
110
+ g.x_axis_label = 'Score (%)'
111
+ g.y_axis_label = 'Students'
112
+ g.write('test/output/dot_x_y_labels.png')
113
+ end
114
+
115
+ def test_wide_graph
116
+ g = setup_basic_graph('800x400')
117
+ g.title = 'Wide Graph'
118
+ g.write('test/output/dot_wide_graph.png')
119
+
120
+ g = setup_basic_graph('400x200')
121
+ g.title = 'Wide Graph Small'
122
+ g.write('test/output/dot_wide_graph_small.png')
123
+ end
124
+
125
+
126
+ def test_tall_graph
127
+ g = setup_basic_graph('400x600')
128
+ g.title = 'Tall Graph'
129
+ g.write('test/output/dot_tall_graph.png')
130
+
131
+ g = setup_basic_graph('200x400')
132
+ g.title = 'Tall Graph Small'
133
+ g.write('test/output/dot_tall_graph_small.png')
134
+ end
135
+
136
+
137
+ def test_one_value
138
+ g = Gruff::Dot.new
139
+ g.title = 'One Value Graph Test'
140
+ g.labels = {
141
+ 0 => '1',
142
+ 1 => '2'
143
+ }
144
+ g.data('one', [1,1])
145
+
146
+ g.write('test/output/dot_one_value.png')
147
+ end
148
+
149
+
150
+ def test_negative
151
+ g = Gruff::Dot.new
152
+ g.title = 'Pos/Neg Dot Graph Test'
153
+ g.labels = {
154
+ 0 => '5/6',
155
+ 1 => '5/15',
156
+ 2 => '5/24',
157
+ 3 => '5/30',
158
+ }
159
+ g.data(:apples, [-1, 0, 4, -4])
160
+ g.data(:peaches, [10, 8, 6, 3])
161
+
162
+ g.write('test/output/dot_pos_neg.png')
163
+ end
164
+
165
+
166
+ def test_nearly_zero
167
+ g = Gruff::Dot.new
168
+ g.title = 'Nearly Zero Graph'
169
+ g.labels = {
170
+ 0 => '5/6',
171
+ 1 => '5/15',
172
+ 2 => '5/24',
173
+ 3 => '5/30',
174
+ }
175
+ g.data(:apples, [1, 2, 3, 4])
176
+ g.data(:peaches, [4, 3, 2, 1])
177
+ g.minimum_value = 0
178
+ g.maximum_value = 10
179
+ g.write('test/output/dot_nearly_zero_max_10.png')
180
+ end
181
+
182
+ def test_y_axis_increment
183
+ generate_with_y_axis_increment 2.0
184
+ generate_with_y_axis_increment 1
185
+ generate_with_y_axis_increment 5
186
+ generate_with_y_axis_increment 20
187
+ end
188
+
189
+ def generate_with_y_axis_increment(increment)
190
+ g = Gruff::Dot.new
191
+ g.title = "Y Axis Set to #{increment}"
192
+ g.labels = {
193
+ 0 => '5/6',
194
+ 1 => '5/15',
195
+ 2 => '5/24',
196
+ 3 => '5/30',
197
+ }
198
+ g.y_axis_increment = increment
199
+ g.data(:apples, [1, 0.2, 0.5, 0.7])
200
+ g.data(:peaches, [2.5, 2.3, 2, 6.1])
201
+ g.write("test/output/dot_y_increment_#{increment}.png")
202
+ end
203
+
204
+
205
+ def test_custom_theme
206
+ g = Gruff::Dot.new
207
+ g.title = 'Custom Theme'
208
+ g.font = File.expand_path('CREABBRG.TTF', ENV['MAGICK_FONT_PATH'])
209
+ g.title_font_size = 60
210
+ g.legend_font_size = 32
211
+ g.marker_font_size = 32
212
+ g.theme = {
213
+ :colors => %w(#efd250 #666699 #e5573f #9595e2),
214
+ :marker_color => 'white',
215
+ :font_color => 'blue',
216
+ :background_image => 'assets/pc306715.jpg'
217
+ }
218
+ g.labels = {
219
+ 0 => '5/6',
220
+ 1 => '5/15',
221
+ 2 => '5/24',
222
+ 3 => '5/30',
223
+ }
224
+ g.data(:vancouver, [1, 2, 3, 4])
225
+ g.data(:seattle, [2, 4, 6, 8])
226
+ g.data(:portland, [3, 1, 7, 3])
227
+ g.data(:victoria, [4, 3, 5, 7])
228
+ g.minimum_value = 0
229
+ g.write('test/output/dot_themed.png')
230
+ end
231
+
232
+ def test_july_enhancements
233
+ g = Gruff::Dot.new(600)
234
+ g.hide_legend = true
235
+ g.title = 'Full speed ahead'
236
+ g.labels = (0..10).inject({}) { |memo, i| memo.merge({ i => (i*10).to_s}) }
237
+ g.data(:apples, (0..9).map { rand(20)/10.0 })
238
+ g.y_axis_increment = 1.0
239
+ g.x_axis_label = 'Score (%)'
240
+ g.y_axis_label = 'Students'
241
+ write_test_file g, 'enhancements.png'
242
+ end
243
+
244
+
245
+ protected
246
+
247
+ def setup_basic_graph(size=800)
248
+ g = Gruff::Dot.new(size)
249
+ g.title = 'My Dot Graph'
250
+ g.labels = {
251
+ 0 => '5/6',
252
+ 1 => '5/15',
253
+ 2 => '5/24',
254
+ 3 => '5/30',
255
+ }
256
+ @datasets.each do |data|
257
+ g.data(data[0], data[1])
258
+ end
259
+ g
260
+ end
261
+
262
+ end
263
+
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/gruff_test_case'
2
+
3
+ class TestGruffLegend < GruffTestCase
4
+
5
+ def setup
6
+ @datasets = [
7
+ [:Jimmy, [25, 36, 86, 39, 25, 31, 79, 88]],
8
+ [:Charles, [80, 54, 67, 54, 68, 70, 90, 95]],
9
+ [:Julie, [22, 29, 35, 38, 36, 40, 46, 57]],
10
+ [:Jane, [95, 95, 95, 90, 85, 80, 88, 100]],
11
+ [:Philip, [90, 34, 23, 12, 78, 89, 98, 88]],
12
+ [:Arthur, [5, 10, 13, 11, 6, 16, 22, 32]],
13
+ [:Vincent, [5, 10, 13, 11, 6, 16, 22, 32]],
14
+ [:Jake, [5, 10, 13, 11, 6, 16, 22, 32]],
15
+ [:Stephen, [5, 10, 13, 11, 6, 16, 22, 32]],
16
+ ]
17
+
18
+ @sample_labels = {
19
+ 0 => '5/6',
20
+ 1 => '5/15',
21
+ 2 => '5/24',
22
+ 3 => '5/30',
23
+ 4 => '6/4',
24
+ 5 => '6/12',
25
+ 6 => '6/21',
26
+ 7 => '6/28',
27
+ }
28
+ end
29
+
30
+ def full_suite_for(name, type)
31
+ [800, 400].each do |width|
32
+ [nil, 4, 16, 30].each do |font_size|
33
+ g = type.new(width)
34
+ g.title = "Wrapped Legend Bar Test #{font_size}pts #{width}px"
35
+ g.labels = @sample_labels
36
+ 0xEFD250.step(0xFF0000, 60) do |num|
37
+ g.colors << '#%x' % num
38
+ end
39
+
40
+ @datasets.each do |data|
41
+ g.data(data[0], data[1])
42
+ end
43
+
44
+ g.legend_font_size = font_size unless font_size.nil?
45
+ g.write("test/output/#{name}_wrapped_legend_#{font_size}_#{width}.png")
46
+ end
47
+ end
48
+ end
49
+
50
+ def test_bar_legend_wrap
51
+ full_suite_for(:bar, Gruff::Bar)
52
+ end
53
+
54
+ def test_pie_legend_wrap
55
+ full_suite_for(:pie, Gruff::Pie)
56
+ end
57
+
58
+ def test_more_than_two_lines_of_legends
59
+ @datasets = @datasets + [[:Julie2, [22, 29, 35, 38, 36, 40, 46, 57]],
60
+ [:Jane2, [95, 95, 95, 90, 85, 80, 88, 100]],
61
+ [:Philip2, [90, 34, 23, 12, 78, 89, 98, 88]],
62
+ [:Arthur2, [5, 10, 13, 11, 6, 16, 22, 32]],
63
+ [:Vincent2, [5, 10, 13, 11, 6, 16, 22, 32]],
64
+ [:Jake2, [5, 10, 13, 11, 6, 16, 22, 32]],
65
+ [:Stephen2, [5, 10, 13, 11, 6, 16, 22, 32]]]
66
+ full_suite_for(:bar2, Gruff::Bar)
67
+ end
68
+ end
@@ -0,0 +1,626 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.dirname(__FILE__) + '/gruff_test_case'
4
+
5
+ class TestGruffLine < GruffTestCase
6
+ def test_should_render_with_transparent_theme
7
+ g = Gruff::Line.new(400)
8
+ g.title = 'Transparent Background'
9
+ g.theme = {
10
+ :colors => %w(black grey),
11
+ :marker_color => 'grey',
12
+ :font_color => 'black',
13
+ :background_colors => 'transparent'
14
+ }
15
+
16
+ g.labels = {
17
+ 0 => '5/6',
18
+ 1 => '5/15',
19
+ 2 => '5/24',
20
+ 3 => '5/30',
21
+ }
22
+ g.data(:apples, [-1, 0, 4, -4])
23
+ g.data(:peaches, [10, 8, 6, 3])
24
+ g.write('test/output/line_transparent.png')
25
+ end
26
+
27
+ def test_very_small
28
+ g = Gruff::Line.new(200)
29
+ g.title = 'Very Small Line Chart 200px'
30
+ g.labels = @labels
31
+ @datasets.each do |data|
32
+ g.data(data[0], data[1])
33
+ end
34
+ g.write('test/output/line_very_small.png')
35
+ end
36
+
37
+ def test_line_graph_with_themes
38
+ line_graph_with_themes()
39
+ line_graph_with_themes(400)
40
+ end
41
+
42
+ def test_one_value
43
+ g = Gruff::Line.new
44
+ g.title = 'One Value'
45
+ g.labels = {
46
+ 0 => '1',
47
+ 1 => '2'
48
+ }
49
+ g.data('one', 1)
50
+
51
+ g.write('test/output/line_one_value.png')
52
+ end
53
+
54
+ def test_one_value_array
55
+ g = Gruff::Line.new
56
+ g.title = 'One Value in an Array'
57
+ g.labels = {
58
+ 0 => '1',
59
+ 1 => '2'
60
+ }
61
+ g.data('one', [1])
62
+
63
+ g.write('test/output/line_one_value_array.png')
64
+ end
65
+
66
+
67
+ def test_should_not_hang_with_0_0_100
68
+ g = Gruff::Line.new(320)
69
+ g.title = 'Hang Value Graph Test'
70
+ g.data('test', [0, 0, 100])
71
+
72
+ g.write('test/output/line_hang_value.png')
73
+ end
74
+
75
+ # TODO
76
+ # def test_fix_crash
77
+ # g = Gruff::Line.new(370)
78
+ # g.title = "Crash Test"
79
+ # g.data "ichi", [5]
80
+ # g.data "ni", [0]
81
+ # g.data "san", [0]
82
+ # g.data "shi", [0]
83
+ # g.write("test/output/line_crash_fix_test.png")
84
+ # end
85
+
86
+
87
+ def test_line_small_values
88
+ @datasets = [
89
+ [:small, [0.1, 0.14356, 0.0, 0.5674839, 0.456]],
90
+ [:small2, [0.2, 0.3, 0.1, 0.05, 0.9]]
91
+ ]
92
+
93
+ g = Gruff::Line.new
94
+ g.title = 'Small Values Line Graph Test'
95
+ @datasets.each do |data|
96
+ g.data(data[0], data[1])
97
+ end
98
+ g.write('test/output/line_small_values.png')
99
+
100
+ g = Gruff::Line.new(400)
101
+ g.title = 'Small Values Line Graph Test 400px'
102
+ @datasets.each do |data|
103
+ g.data(data[0], data[1])
104
+ end
105
+ g.write('test/output/line_small_values_small.png')
106
+ end
107
+
108
+ def test_line_starts_with_zero
109
+ @datasets = [
110
+ [:first0, [0, 5, 10, 8, 18]],
111
+ [:normal, [1, 2, 3, 4, 5]]
112
+ ]
113
+
114
+ g = Gruff::Line.new
115
+ g.title = 'Small Values Line Graph Test'
116
+ @datasets.each do |data|
117
+ g.data(data[0], data[1])
118
+ end
119
+ g.write('test/output/line_small_zero.png')
120
+
121
+ g = Gruff::Line.new(400)
122
+ g.title = 'Small Values Line Graph Test 400px'
123
+ @datasets.each do |data|
124
+ g.data(data[0], data[1])
125
+ end
126
+ g.write('test/output/line_small_small_zero.png')
127
+ end
128
+
129
+
130
+ def test_line_large_values
131
+ @datasets = [
132
+ [:large, [100_005, 35_000, 28_000, 27_000]],
133
+ [:large2, [35_000, 28_000, 27_000, 100_005]],
134
+ [:large3, [28_000, 27_000, 100_005, 35_000]],
135
+ [:large4, [1_238, 39_092, 27_938, 48_876]]
136
+ ]
137
+
138
+ g = Gruff::Line.new
139
+ g.title = 'Very Large Values Line Graph Test'
140
+ g.baseline_value = 50_000
141
+ g.baseline_color = 'green'
142
+ g.dot_radius = 15
143
+ g.line_width = 3
144
+ @datasets.each do |data|
145
+ g.data(data[0], data[1])
146
+ end
147
+
148
+ g.write('test/output/line_large.png')
149
+ end
150
+
151
+ # def test_long_title
152
+ #
153
+ # end
154
+ #
155
+ # def test_add_colors
156
+ #
157
+ # end
158
+ #
159
+
160
+ def test_request_too_many_colors
161
+ g = Gruff::Line.new
162
+ g.title = 'More Sets Than in Color Array'
163
+ # g.theme = {} # Sets theme with only black and white
164
+ @datasets.each do |data|
165
+ g.data(data[0], data[1])
166
+ end
167
+ @datasets.each do |data|
168
+ g.data("#{data[0]}-B", data[1].map { |d| d + 20 })
169
+ end
170
+ g.write('test/output/line_more_sets_than_colors.png')
171
+ end
172
+
173
+ #
174
+ # def test_add_data
175
+ #
176
+ # end
177
+
178
+ def test_many_datapoints
179
+ g = Gruff::Line.new
180
+ g.title = 'Many Multi-Line Graph Test'
181
+ g.labels = {
182
+ 0 => 'June',
183
+ 10 => 'July',
184
+ 30 => 'August',
185
+ 50 => 'September',
186
+ }
187
+ g.data('many points', (0..50).collect { |i| rand(100) })
188
+ g.x_axis_label = 'Months'
189
+
190
+ # Default theme
191
+ g.write('test/output/line_many.png')
192
+ end
193
+
194
+
195
+ def test_similar_high_end_values
196
+ @dataset = %w(29.43 29.459 29.498 29.53 29.548 29.589 29.619 29.66 29.689 29.849 29.878 29.74 29.769 29.79 29.808 29.828).collect { |i| i.to_f }
197
+
198
+ g = Gruff::Line.new
199
+ g.title = 'Similar High End Values Test'
200
+ g.data('similar points', @dataset)
201
+ g.write('test/output/line_similar_high_end_values.png')
202
+
203
+ g = Gruff::Line.new
204
+ g.title = 'Similar High End Values With Floor'
205
+ g.data('similar points', @dataset)
206
+ g.minimum_value = 0
207
+ g.y_axis_label = 'Barometric Pressure'
208
+ g.write('test/output/line_similar_high_end_values_with_floor.png')
209
+ end
210
+
211
+ def test_many_lines_graph_small
212
+ g = Gruff::Line.new(400)
213
+ g.title = 'Many Values Line Test 400px'
214
+ g.labels = {
215
+ 0 => '5/6',
216
+ 10 => '5/15',
217
+ 20 => '5/24',
218
+ 30 => '5/30',
219
+ 40 => '6/4',
220
+ 50 => '6/16'
221
+ }
222
+ %w{jimmy jane philip arthur julie bert}.each do |student_name|
223
+ g.data(student_name, (0..50).collect { |i| rand 100 })
224
+ end
225
+
226
+ # Default theme
227
+ g.write('test/output/line_many_lines_small.png')
228
+ end
229
+
230
+ def test_graph_tiny
231
+ g = Gruff::Line.new(300)
232
+ g.title = 'Tiny Test 300px'
233
+ g.labels = {
234
+ 0 => '5/6',
235
+ 10 => '5/15',
236
+ 20 => '5/24',
237
+ 30 => '5/30',
238
+ 40 => '6/4',
239
+ 50 => '6/16'
240
+ }
241
+ %w{jimmy jane philip arthur julie bert}.each do |student_name|
242
+ g.data(student_name, (0..50).collect { |i| rand 100 })
243
+ end
244
+
245
+ # Default theme
246
+ g.write('test/output/line_tiny.png')
247
+ end
248
+
249
+ def test_no_data
250
+ g = Gruff::Line.new(400)
251
+ g.title = 'No Data'
252
+ # Default theme
253
+ g.write('test/output/line_no_data.png')
254
+
255
+ g = Gruff::Line.new(400)
256
+ g.title = 'No Data Title'
257
+ g.no_data_message = 'There is no data'
258
+ g.write('test/output/line_no_data_msg.png')
259
+ end
260
+
261
+
262
+ def test_all_zeros
263
+ g = Gruff::Line.new(400)
264
+ g.title = 'All Zeros'
265
+
266
+ g.data(:gus, [0, 0, 0, 0])
267
+
268
+ # Default theme
269
+ g.write('test/output/line_no_data_other.png')
270
+ end
271
+
272
+
273
+ def test_some_nil_points
274
+ g = Gruff::Line.new
275
+ g.title = 'Some Nil Points'
276
+
277
+ @datasets = [
278
+ [:data1, [1, 2, 3, nil, 3, 5, 6]],
279
+ [:data2, [5, nil, nil, 5, nil, nil, 5]],
280
+ [:data3, [4, nil, 2, 1, 0]],
281
+ [:data4, [nil, nil, 3, 1, 2]]
282
+ ]
283
+
284
+ @datasets.each do |data|
285
+ g.data(*data)
286
+ end
287
+
288
+ # Default theme
289
+ g.write('test/output/line_some_nil_points.png')
290
+ end
291
+
292
+ def test_no_title
293
+ g = Gruff::Line.new(400)
294
+ g.labels = @labels
295
+ @datasets.each do |data|
296
+ g.data(data[0], data[1])
297
+ end
298
+
299
+ g.write('test/output/line_no_title.png')
300
+ end
301
+
302
+ def test_no_line_markers
303
+ g = setup_basic_graph(400)
304
+ g.title = 'No Line Markers'
305
+ g.hide_line_markers = true
306
+ g.write('test/output/line_no_line_markers.png')
307
+ end
308
+
309
+ def test_no_legend
310
+ g = setup_basic_graph(400)
311
+ g.title = 'No Legend'
312
+ g.hide_legend = true
313
+ g.write('test/output/line_no_legend.png')
314
+ end
315
+
316
+ def test_nothing_but_the_graph
317
+ g = setup_basic_graph(400)
318
+ g.title = 'THIS TITLE SHOULD NOT DISPLAY!!!'
319
+ g.hide_line_markers = true
320
+ g.hide_legend = true
321
+ g.hide_title = true
322
+ g.write('test/output/line_nothing_but_the_graph.png')
323
+ end
324
+
325
+ def test_legend_below_the_chart
326
+ g = setup_basic_graph(400)
327
+ g.title = 'Legend below the chart'
328
+ g.legend_at_bottom = true
329
+ g.write('test/output/line_legend_at_bottom.png')
330
+ end
331
+
332
+ def test_baseline_larger_than_data
333
+ g = setup_basic_graph(400)
334
+ g.title = 'Baseline Larger Than Data'
335
+ g.baseline_value = 150
336
+ g.write('test/output/line_large_baseline.png')
337
+ end
338
+
339
+ def test_hide_dots
340
+ g = setup_basic_graph(400)
341
+ g.title = 'Hide Dots'
342
+ g.hide_dots = true
343
+ g.write('test/output/line_hide_dots.png')
344
+ end
345
+
346
+ def test_hide_lines
347
+ g = setup_basic_graph(400)
348
+ g.title = 'Hide Lines'
349
+ g.hide_lines = true
350
+ g.write('test/output/line_hide_lines.png')
351
+ end
352
+
353
+ def test_wide_graph
354
+ g = setup_basic_graph('800x400')
355
+ g.title = 'Wide Graph'
356
+ g.write('test/output/line_wide_graph.png')
357
+
358
+ g = setup_basic_graph('400x200')
359
+ g.title = 'Wide Graph Small'
360
+ g.write('test/output/line_wide_graph_small.png')
361
+ end
362
+
363
+ def test_negative
364
+ g = setup_pos_neg(800)
365
+ g.write('test/output/line_pos_neg.png')
366
+
367
+ g = setup_pos_neg(400)
368
+ g.title = 'Pos/Neg Line Test Small'
369
+ g.write('test/output/line_pos_neg_400.png')
370
+ end
371
+
372
+ def test_all_negative
373
+ g = setup_all_neg(800)
374
+ g.maximum_value = 0
375
+ g.write('test/output/line_all_neg.png')
376
+ end
377
+
378
+ def test_all_negative_no_max_value
379
+ g = setup_all_neg(800)
380
+ g.write('test/output/line_all_neg_no_max.png')
381
+ end
382
+
383
+ def test_all_negative_400
384
+ g = setup_all_neg(400)
385
+ g.maximum_value = 0
386
+ g.title = 'All Neg Line Test Small'
387
+ g.write('test/output/line_all_neg_400.png')
388
+ end
389
+
390
+ def test_many_numbers
391
+ g = Gruff::Line.new('400x170')
392
+ g.title = 'Line Test, Many Numbers'
393
+
394
+ data = [
395
+ {:date => '01',
396
+ :wpm => 0,
397
+ :errors => 0,
398
+ :accuracy => 0},
399
+ {:date => '02',
400
+ :wpm => 10,
401
+ :errors => 2,
402
+ :accuracy => 80},
403
+ {:date => '03',
404
+ :wpm => 15,
405
+ :errors => 0,
406
+ :accuracy => 100},
407
+ {:date => '04',
408
+ :wpm => 16,
409
+ :errors => 2,
410
+ :accuracy => 87},
411
+ {:date => '05'},
412
+ {:date => '06',
413
+ :wpm => 18,
414
+ :errors => 1,
415
+ :accuracy => 94},
416
+ {:date => '07'},
417
+ {:date => '08'},
418
+ {:date => '09',
419
+ :wpm => 21,
420
+ :errors => 1,
421
+ :accuracy => 95},
422
+ {:date => '10'},
423
+ {:date => '11'},
424
+ {:date => '12'},
425
+ {:date => '13'},
426
+ {:date => '14'},
427
+ {:date => '15'},
428
+ {:date => '16'},
429
+ {:date => '17'},
430
+ {:date => '18'},
431
+ {:date => '19',
432
+ :wpm => 28,
433
+ :errors => 5,
434
+ :accuracy => 82},
435
+ {:date => '20'},
436
+ {:date => '21'},
437
+ {:date => '22'},
438
+ {:date => '23'},
439
+ {:date => '24'},
440
+ {:date => '25'},
441
+ {:date => '26'},
442
+ {:date => '27',
443
+ :wpm => 37,
444
+ :errors => 3,
445
+ :accuracy => 92},
446
+ ]
447
+
448
+ [:wpm, :errors, :accuracy].each do |field|
449
+ g.dataxy(field, data.each_with_index.map { |d, i| [i + 1, d[field]] if d[field] }.compact)
450
+ end
451
+
452
+ labels = Hash.new
453
+ data.each_with_index do |d, i|
454
+ labels[i + 1] = d[:date] if d.size > 1
455
+ end
456
+ g.labels = labels
457
+
458
+ g.write('test/output/line_many_numbers.png')
459
+ end
460
+
461
+ def test_no_hide_line_no_labels
462
+ g = Gruff::Line.new
463
+ g.title = 'No Hide Line No Labels'
464
+ @datasets.each do |data|
465
+ g.data(data[0], data[1])
466
+ end
467
+ g.hide_line_markers = false
468
+ g.write('test/output/line_no_hide.png')
469
+ end
470
+
471
+ def test_xy_data
472
+ g = Gruff::Line.new
473
+ g.title = 'X/Y Dataset'
474
+ g.dataxy('Apples', [1, 3, 4, 5, 6, 10], [1, 2, 3, 4, 4, 3])
475
+ g.dataxy('Bapples', [1, 3, 4, 5, 7, 9], [1, 1, 2, 2, 3, 3])
476
+ g.data('Capples', [1, 1, 2, 2, 3, 3])
477
+ g.labels = {0 => '2003', 2 => '2004', 4 => '2005', 6 => '2006', 8 => '2007', 10 => '2008'}
478
+ g.write('test/output/line_xy.png')
479
+ end
480
+
481
+ def test_xy_data_pairs
482
+ g = Gruff::Line.new
483
+ g.title = 'X/Y Dataset Pairs'
484
+ g.dataxy('Apples', [[1, 1], [3, 2], [4, 3], [5, 4], [6, 4], [10, 3]])
485
+ g.dataxy('Bapples', [[1, 1], [3, 1], [4, 2], [5, 2], [7, 3], [9, 3]])
486
+ g.data('Capples', [1, 1, 2, 2, 3, 3])
487
+ g.dataxy('Dapples', [[1, 1], [2, 3], [5, 8], [13, 21]])
488
+ g.dataxy('Eapples', [[1, 1], [2, 3], [5, 8], [13, 21], [13, 8], [5, 3], [2, 1], [1, 1]])
489
+ g.labels = {0 => '2003', 2 => '2004', 4 => '2005', 6 => '2006', 8 => '2007', 10 => '2008', 12 => '2009'}
490
+ g.write('test/output/line_xy_pairs.png')
491
+ end
492
+
493
+ def test_jruby_error
494
+ g = Gruff::Line.new
495
+ g.theme = {
496
+ :colors => %w(#7F0099 #2F85ED #2FED09 #EC962F),
497
+ :marker_color => '#aaa',
498
+ :background_colors => %w(#E8E8E8 #B9FD6C)
499
+ }
500
+ g.hide_title = true
501
+
502
+ g.legend_font_size = 12
503
+ g.marker_font_size = 16
504
+ g.hide_dots = false
505
+
506
+ g.write('test/output/line_jruby_error.png')
507
+ end
508
+
509
+ def test_marker_label_accuracy
510
+ g = Gruff::Line.new
511
+ g.title = 'Marker label accuracy'
512
+ g.labels = {
513
+ 0 => '1',
514
+ 1 => '2',
515
+ 2 => '3',
516
+ 3 => '4',
517
+ 4 => '5'
518
+ }
519
+ g.data('first', [0.5, 0.51, 0.52, 0.53, 0.54])
520
+ g.data('second', [0.6, 0.61, 0.62, 0.63, 0.64])
521
+ g.data('third', [0.7, 0.71, 0.72, 0.73, 0.74])
522
+
523
+ g.write('test/output/line_marker_label_accuracy.png')
524
+ end
525
+
526
+ def test_y_axis_increment
527
+ g = Gruff::Line.new
528
+ g.title = 'y axis increment'
529
+
530
+ g.data('data', [1, 2, 3])
531
+
532
+ g.y_axis_increment = 1
533
+
534
+ g.write('test/output/line_y_axis_increment.png')
535
+ end
536
+
537
+ def test_baseline
538
+ g = Gruff::Line.new
539
+ g.title = 'Line Chart with Baseline = 5'
540
+
541
+ g.data('Apples', [3, 2, 3, 4, 4, 3])
542
+ g.data('Oranges', [4, 8, 7, 9, 8, 9])
543
+ g.data('Watermelon', [2, 3, 4, 5, 6, 8])
544
+ g.data('Peaches', [9, 9, 10, 8, 7, 9])
545
+
546
+ g.labels = {0 => '2003', 2 => '2004', 4 => '2005'}
547
+ g.baseline_value = 5
548
+
549
+ g.write('line_baseline.png')
550
+ end
551
+
552
+ private
553
+
554
+ # TODO Reset data after each theme
555
+ def line_graph_with_themes(size=nil)
556
+ g = Gruff::Line.new(size)
557
+ g.title = "Multi-Line Graph Test #{size}"
558
+ g.labels = @labels
559
+ g.baseline_value = 90
560
+ @datasets.each do |data|
561
+ g.data(data[0], data[1])
562
+ end
563
+ # Default theme
564
+ g.write("test/output/line_theme_keynote_#{size}.png")
565
+
566
+ g = Gruff::Line.new(size)
567
+ g.title = "Multi-Line Graph Test #{size}"
568
+ g.labels = @labels
569
+ g.baseline_value = 90
570
+ g.theme = Gruff::Themes::THIRTYSEVEN_SIGNALS
571
+ @datasets.each do |data|
572
+ g.data(data[0], data[1])
573
+ end
574
+ g.write("test/output/line_theme_37signals_#{size}.png")
575
+
576
+ g = Gruff::Line.new(size)
577
+ g.title = "Multi-Line Graph Test #{size}"
578
+ g.labels = @labels
579
+ g.baseline_value = 90
580
+ g.theme = Gruff::Themes::RAILS_KEYNOTE
581
+ @datasets.each do |data|
582
+ g.data(data[0], data[1])
583
+ end
584
+ g.write("test/output/line_theme_rails_keynote_#{size}.png")
585
+
586
+ g = Gruff::Line.new(size)
587
+ g.title = "Multi-Line Graph Test #{size}"
588
+ g.labels = @labels
589
+ g.baseline_value = 90
590
+ g.theme = Gruff::Themes::ODEO
591
+ @datasets.each do |data|
592
+ g.data(data[0], data[1])
593
+ end
594
+ g.write("test/output/line_theme_odeo_#{size}.png")
595
+ end
596
+
597
+ def setup_pos_neg(size=800)
598
+ g = Gruff::Line.new(size)
599
+ g.title = 'Pos/Neg Line Graph Test'
600
+ g.labels = {
601
+ 0 => '5/6',
602
+ 1 => '5/15',
603
+ 2 => '5/24',
604
+ 3 => '5/30',
605
+ }
606
+ g.data(:apples, [-1, 0, 4, -4])
607
+ g.data(:peaches, [10, 8, 6, 3])
608
+ g
609
+ end
610
+
611
+
612
+ def setup_all_neg(size=800)
613
+ g = Gruff::Line.new(size)
614
+ g.title = 'All Neg Line Graph Test'
615
+ g.labels = {
616
+ 0 => '5/6',
617
+ 1 => '5/15',
618
+ 2 => '5/24',
619
+ 3 => '5/30',
620
+ }
621
+ g.data(:apples, [-1, -5, -20, -4])
622
+ g.data(:peaches, [-10, -8, -6, -3])
623
+ g
624
+ end
625
+
626
+ end