jsanders-ruport 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/AUTHORS +48 -0
  2. data/LICENSE +59 -0
  3. data/README +114 -0
  4. data/Rakefile +93 -0
  5. data/examples/RWEmerson.jpg +0 -0
  6. data/examples/anon.rb +43 -0
  7. data/examples/btree/commaleon/commaleon.rb +263 -0
  8. data/examples/btree/commaleon/sample_data/ticket_count.csv +124 -0
  9. data/examples/btree/commaleon/sample_data/ticket_count2.csv +119 -0
  10. data/examples/centered_pdf_text_box.rb +83 -0
  11. data/examples/data/tattle.dump +82 -0
  12. data/examples/example.csv +3 -0
  13. data/examples/line_plotter.rb +61 -0
  14. data/examples/pdf_report_with_common_base.rb +72 -0
  15. data/examples/png_embed.rb +54 -0
  16. data/examples/roadmap.png +0 -0
  17. data/examples/row_renderer.rb +39 -0
  18. data/examples/simple_pdf_lines.rb +25 -0
  19. data/examples/simple_templating_example.rb +34 -0
  20. data/examples/tattle_ruby_version.rb +39 -0
  21. data/examples/tattle_rubygems_version.rb +37 -0
  22. data/examples/trac_ticket_status.rb +59 -0
  23. data/lib/ruport.rb +127 -0
  24. data/lib/ruport/controller.rb +616 -0
  25. data/lib/ruport/controller/grouping.rb +71 -0
  26. data/lib/ruport/controller/table.rb +54 -0
  27. data/lib/ruport/data.rb +4 -0
  28. data/lib/ruport/data/feeder.rb +111 -0
  29. data/lib/ruport/data/grouping.rb +399 -0
  30. data/lib/ruport/data/record.rb +297 -0
  31. data/lib/ruport/data/table.rb +950 -0
  32. data/lib/ruport/extensions.rb +4 -0
  33. data/lib/ruport/formatter.rb +254 -0
  34. data/lib/ruport/formatter/csv.rb +149 -0
  35. data/lib/ruport/formatter/html.rb +161 -0
  36. data/lib/ruport/formatter/pdf.rb +591 -0
  37. data/lib/ruport/formatter/template.rb +187 -0
  38. data/lib/ruport/formatter/text.rb +231 -0
  39. data/lib/uport.rb +1 -0
  40. data/test/controller_test.rb +743 -0
  41. data/test/csv_formatter_test.rb +164 -0
  42. data/test/data_feeder_test.rb +88 -0
  43. data/test/grouping_test.rb +410 -0
  44. data/test/helpers.rb +11 -0
  45. data/test/html_formatter_test.rb +201 -0
  46. data/test/pdf_formatter_test.rb +354 -0
  47. data/test/record_test.rb +332 -0
  48. data/test/samples/addressbook.csv +6 -0
  49. data/test/samples/data.csv +3 -0
  50. data/test/samples/data.tsv +3 -0
  51. data/test/samples/dates.csv +1409 -0
  52. data/test/samples/erb_test.sql +1 -0
  53. data/test/samples/query_test.sql +1 -0
  54. data/test/samples/ruport_test.sql +8 -0
  55. data/test/samples/test.sql +2 -0
  56. data/test/samples/test.yaml +3 -0
  57. data/test/samples/ticket_count.csv +124 -0
  58. data/test/table_pivot_test.rb +134 -0
  59. data/test/table_test.rb +838 -0
  60. data/test/template_test.rb +48 -0
  61. data/test/text_formatter_test.rb +258 -0
  62. data/util/bench/data/record/bench_as_vs_to.rb +18 -0
  63. data/util/bench/data/record/bench_constructor.rb +46 -0
  64. data/util/bench/data/record/bench_indexing.rb +65 -0
  65. data/util/bench/data/record/bench_reorder.rb +35 -0
  66. data/util/bench/data/record/bench_to_a.rb +19 -0
  67. data/util/bench/data/table/bench_column_manip.rb +103 -0
  68. data/util/bench/data/table/bench_dup.rb +24 -0
  69. data/util/bench/data/table/bench_init.rb +67 -0
  70. data/util/bench/data/table/bench_manip.rb +125 -0
  71. data/util/bench/formatter/bench_csv.rb +14 -0
  72. data/util/bench/formatter/bench_html.rb +14 -0
  73. data/util/bench/formatter/bench_pdf.rb +14 -0
  74. data/util/bench/formatter/bench_text.rb +14 -0
  75. data/util/bench/samples/tattle.csv +1237 -0
  76. metadata +176 -0
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby -w
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
3
+
4
+ class TemplateTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @template_class = Ruport::Formatter::Template.dup
8
+ end
9
+
10
+ def teardown
11
+ Ruport::Formatter::Template.instance_variable_set(:@templates, nil)
12
+ end
13
+
14
+ def test_template_should_exist
15
+ @template_class.create(:foo)
16
+ assert_instance_of @template_class,
17
+ @template_class[:foo]
18
+ end
19
+
20
+ def test_template_creation_yields_an_options_object
21
+ @template_class.create(:foo) do |template|
22
+ template.page_format = { :layout => :landscape,
23
+ :paper_size => :letter }
24
+ end
25
+ assert_equal :landscape, @template_class[:foo].page_format[:layout]
26
+ assert_equal :letter, @template_class[:foo].page_format[:paper_size]
27
+ end
28
+
29
+ def test_create_derived_template
30
+ Ruport::Formatter::Template.create(:foo) do |template|
31
+ template.page_format = { :layout => :landscape,
32
+ :paper_size => :letter }
33
+ end
34
+ Ruport::Formatter::Template.create(:bar, :base => :foo)
35
+ assert_equal :landscape,
36
+ Ruport::Formatter::Template[:bar].page_format[:layout]
37
+ assert_equal :letter,
38
+ Ruport::Formatter::Template[:bar].page_format[:paper_size]
39
+ end
40
+
41
+ def test_default_template
42
+ assert_nil Ruport::Formatter::Template.default
43
+ Ruport::Formatter::Template.create(:default)
44
+ assert_equal Ruport::Formatter::Template[:default],
45
+ Ruport::Formatter::Template.default
46
+ end
47
+
48
+ end
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env ruby -w
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
3
+
4
+ class TestRenderTextTable < Test::Unit::TestCase
5
+
6
+ def setup
7
+ Ruport::Formatter::Template.create(:simple) do |format|
8
+ format.table = {
9
+ :show_headings => false,
10
+ :width => 50,
11
+ :ignore_width => true
12
+ }
13
+ format.column = {
14
+ :maximum_width => [5,5,7],
15
+ :alignment => :center
16
+ }
17
+ format.grouping = {
18
+ :show_headings => false
19
+ }
20
+ end
21
+ end
22
+
23
+ def test_basic
24
+ tf = "+-------+\n"
25
+
26
+ a = Table([], :data => [[1,2],[3,4]]).to_text
27
+ assert_equal("#{tf}| 1 | 2 |\n| 3 | 4 |\n#{tf}",a)
28
+
29
+ a = Table(%w[a b], :data => [[1,2],[3,4]]).to_text
30
+ assert_equal("#{tf}| a | b |\n#{tf}| 1 | 2 |\n| 3 | 4 |\n#{tf}", a)
31
+ end
32
+
33
+ def test_centering
34
+ tf = "+---------+\n"
35
+
36
+ a = Table([], :data => [[1,2],[300,4]])
37
+ assert_equal( "#{tf}| 1 | 2 |\n| 300 | 4 |\n#{tf}",
38
+ a.to_text(:alignment => :center) )
39
+
40
+ tf = "+------------+\n"
41
+ a.column_names = %w[a bark]
42
+ assert_equal("#{tf}| a | bark |\n#{tf}| 1 | 2 |\n"+
43
+ "| 300 | 4 |\n#{tf}", a.to_text(:alignment => :center) )
44
+ end
45
+
46
+ def test_justified
47
+ tf = "+----------+\n"
48
+ a = Table([], :data => [[1,'Z'],[300,'BB']])
49
+
50
+ # justified alignment can be set explicitly
51
+ assert_equal "#{tf}| 1 | Z |\n| 300 | BB |\n#{tf}",
52
+ a.to_text(:alignment => :justified)
53
+
54
+ # justified alignment is also default
55
+ assert_equal "#{tf}| 1 | Z |\n| 300 | BB |\n#{tf}", a.to_s
56
+ end
57
+
58
+ def test_wrapping
59
+ a = Table([], :data => [[1,2],[300,4]]).to_text(:table_width => 10)
60
+ assert_equal("+------->>\n| 1 | >>\n| 300 | >>\n+------->>\n",a)
61
+ end
62
+
63
+ def test_ignore_wrapping
64
+ a = Table([], :data => [[1,2],[300,4]]).to_text(:table_width => 10,
65
+ :ignore_table_width => true )
66
+ assert_equal("+---------+\n| 1 | 2 |\n| 300 | 4 |\n+---------+\n",a)
67
+ end
68
+
69
+ def test_render_empty_table
70
+ assert_raise(Ruport::FormatterError) { Table([]).to_text }
71
+ assert_nothing_raised { Table(%w[a b c]).to_text }
72
+
73
+ a = Table(%w[a b c]).to_text
74
+ expected = "+-----------+\n"+
75
+ "| a | b | c |\n"+
76
+ "+-----------+\n"
77
+ assert_equal expected, a
78
+ end
79
+
80
+ def test_render_with_template
81
+ formatter = Ruport::Formatter::Text.new
82
+ formatter.options = Ruport::Controller::Options.new
83
+ formatter.options.template = :simple
84
+ formatter.apply_template
85
+
86
+ assert_equal false, formatter.options.show_table_headers
87
+ assert_equal 50, formatter.options.table_width
88
+ assert_equal true, formatter.options.ignore_table_width
89
+
90
+ assert_equal [5,5,7], formatter.options.max_col_width
91
+ assert_equal :center, formatter.options.alignment
92
+
93
+ assert_equal false, formatter.options.show_group_headers
94
+ end
95
+
96
+ def test_options_hashes_override_template
97
+ opts = nil
98
+ table = Table(%w[a b c])
99
+ table.to_text(
100
+ :template => :simple,
101
+ :table_format => {
102
+ :show_headings => true,
103
+ :width => 25,
104
+ :ignore_width => false
105
+ },
106
+ :column_format => {
107
+ :maximum_width => [10,10,10],
108
+ :alignment => :left
109
+ },
110
+ :grouping_format => {
111
+ :show_headings => true
112
+ }
113
+ ) do |r|
114
+ opts = r.options
115
+ end
116
+
117
+ assert_equal true, opts.show_table_headers
118
+ assert_equal 25, opts.table_width
119
+ assert_equal false, opts.ignore_table_width
120
+
121
+ assert_equal [10,10,10], opts.max_col_width
122
+ assert_equal :left, opts.alignment
123
+
124
+ assert_equal true, opts.show_group_headers
125
+ end
126
+
127
+ def test_individual_options_override_template
128
+ opts = nil
129
+ table = Table(%w[a b c])
130
+ table.to_text(
131
+ :template => :simple,
132
+ :show_table_headers => true,
133
+ :table_width => 75,
134
+ :ignore_table_width => false,
135
+ :max_col_width => [4,4,4],
136
+ :alignment => :left,
137
+ :show_group_headers => true
138
+ ) do |r|
139
+ opts = r.options
140
+ end
141
+
142
+ assert_equal true, opts.show_table_headers
143
+ assert_equal 75, opts.table_width
144
+ assert_equal false, opts.ignore_table_width
145
+
146
+ assert_equal [4,4,4], opts.max_col_width
147
+ assert_equal :left, opts.alignment
148
+
149
+ assert_equal true, opts.show_group_headers
150
+ end
151
+
152
+ # -- BUG TRAPS ------------------------------
153
+
154
+ def test_should_render_without_column_names
155
+ a = Table([], :data => [[1,2,3]]).to_text
156
+ expected = "+-----------+\n"+
157
+ "| 1 | 2 | 3 |\n"+
158
+ "+-----------+\n"
159
+ assert_equal(expected,a)
160
+ end
161
+
162
+ end
163
+
164
+
165
+ class TestRenderTextRow < Test::Unit::TestCase
166
+
167
+ def test_row_basic
168
+ actual = Ruport::Controller::Row.render_text(:data => [1,2,3])
169
+ assert_equal("| 1 | 2 | 3 |\n", actual)
170
+ end
171
+
172
+ end
173
+
174
+
175
+ class TestRenderTextGroup < Test::Unit::TestCase
176
+
177
+ def test_render_text_group
178
+ group = Ruport::Data::Group.new(:name => 'test',
179
+ :data => [ %w[is this more],
180
+ %w[interesting red snapper]],
181
+ :column_names => %w[i hope so])
182
+
183
+ actual = Ruport::Controller::Group.render_text(:data => group)
184
+ expected = "test:\n\n"+
185
+ "+------------------------------+\n"+
186
+ "| i | hope | so |\n"+
187
+ "+------------------------------+\n"+
188
+ "| is | this | more |\n"+
189
+ "| interesting | red | snapper |\n"+
190
+ "+------------------------------+\n"
191
+ assert_equal(expected, actual)
192
+ end
193
+
194
+ def test_render_text_group_without_headers
195
+ group = Ruport::Data::Group.new(:name => 'test',
196
+ :data => [ %w[is this more],
197
+ %w[interesting red snapper]],
198
+ :column_names => %w[i hope so])
199
+
200
+ actual = Ruport::Controller::Group.render(:text, :data => group,
201
+ :show_table_headers => false )
202
+ expected = "test:\n\n"+
203
+ "+------------------------------+\n"+
204
+ "| is | this | more |\n"+
205
+ "| interesting | red | snapper |\n"+
206
+ "+------------------------------+\n"
207
+ assert_equal(expected, actual)
208
+ end
209
+ end
210
+
211
+
212
+ class TestRenderTextGrouping < Test::Unit::TestCase
213
+
214
+ def test_render_text_grouping
215
+ table = Ruport::Data::Table.new(:data => [ %w[is this more],
216
+ %w[interesting red snapper]],
217
+ :column_names => %w[i hope so])
218
+ grouping = Grouping(table, :by => "i")
219
+
220
+ actual = Ruport::Controller::Grouping.render(:text, :data => grouping)
221
+ expected = "interesting:\n\n"+
222
+ "+----------------+\n"+
223
+ "| hope | so |\n"+
224
+ "+----------------+\n"+
225
+ "| red | snapper |\n"+
226
+ "+----------------+\n\n"+
227
+ "is:\n\n"+
228
+ "+-------------+\n"+
229
+ "| hope | so |\n"+
230
+ "+-------------+\n"+
231
+ "| this | more |\n"+
232
+ "+-------------+\n\n"
233
+ assert_equal(expected, actual)
234
+
235
+ actual = grouping.to_s
236
+ assert_equal(expected,actual)
237
+ end
238
+
239
+ def test_render_text_grouping_without_headers
240
+ table = Ruport::Data::Table.new(:data => [ %w[is this more],
241
+ %w[interesting red snapper]],
242
+ :column_names => %w[i hope so])
243
+ grouping = Grouping(table, :by => "i")
244
+
245
+ actual = Ruport::Controller::Grouping.render(:text, :data => grouping,
246
+ :show_table_headers => false)
247
+ expected = "interesting:\n\n"+
248
+ "+----------------+\n"+
249
+ "| red | snapper |\n"+
250
+ "+----------------+\n\n"+
251
+ "is:\n\n"+
252
+ "+-------------+\n"+
253
+ "| this | more |\n"+
254
+ "+-------------+\n\n"
255
+ assert_equal(expected, actual)
256
+ end
257
+
258
+ end
@@ -0,0 +1,18 @@
1
+
2
+ require "benchmark"
3
+ require "rubygems"
4
+ require "ruport"
5
+ require "ruport/util/bench"
6
+ include Ruport::Bench
7
+
8
+ class MyFormat < Ruport::Formatter;
9
+ renders :nothing, :for => Ruport::Controller::Row
10
+ end
11
+
12
+ record = Ruport::Data::Record.new [1,2,3]
13
+
14
+ bench_suite do
15
+ N = 10000
16
+ bench_case("as(:nothing)",N) { record.as(:nothing) }
17
+ bench_case("to_nothing",N) { record.to_nothing }
18
+ end
@@ -0,0 +1,46 @@
1
+ require "ruport"
2
+ require "benchmark"
3
+ require "rubygems"
4
+ require "ruport/util/bench"
5
+ include Ruport::Bench
6
+
7
+ large = (1..1000).to_a
8
+ large_attributes = large.map { |e| e.to_s.reverse }
9
+
10
+ large_hash = large.inject({}) do |s,r|
11
+ s.merge(r-1 => r)
12
+ end
13
+
14
+ la = large_hash.keys.sort_by { rand }
15
+ SMALL_N = 10000
16
+ LARGE_N = 10
17
+
18
+ bench_suite do
19
+
20
+ bench_case("Array - No Attributes",SMALL_N) {
21
+ Ruport::Data::Record.new [1,2,3]
22
+ }
23
+ bench_case("Array w. Attributes - Small",SMALL_N) {
24
+ Ruport::Data::Record.new [1,2,3], :attributes => %w[a b c]
25
+ }
26
+ bench_case("Array - No Attributes - Large",LARGE_N) {
27
+ Ruport::Data::Record.new large
28
+ }
29
+ bench_case("Array w. Attributes - Large",LARGE_N) {
30
+ Ruport::Data::Record.new large, :attributes => large_attributes
31
+ }
32
+ bench_case("Hash - No Attributes - Small", SMALL_N) {
33
+ Ruport::Data::Record.new({ 0 => 1, 1 => 2, 2 => 3 })
34
+ }
35
+ bench_case("Hash w. Attributes - Small",SMALL_N) {
36
+ Ruport::Data::Record.new({"a" => 1, "b" => 2, "c" => 3},
37
+ :attributes => %w[a b c])
38
+ }
39
+ bench_case("Hash - No Attributes - Large",LARGE_N) {
40
+ Ruport::Data::Record.new(large_hash)
41
+ }
42
+ bench_case("Hash w. Attributes - Large",LARGE_N) {
43
+ Ruport::Data::Record.new(large_hash, :attributes => la )
44
+ }
45
+
46
+ end
@@ -0,0 +1,65 @@
1
+ require "ruport"
2
+ require "rubygems"
3
+ require "ruport/util/bench"
4
+ include Ruport::Bench
5
+
6
+ large = (1..1000).to_a
7
+ large_attributes = large.map { |e| e.to_s.reverse }
8
+ sym_l_attributes = large_attributes.map { |r| r.intern }
9
+
10
+ large_record = Ruport::Data::Record.new large,
11
+ :attributes => large_attributes
12
+
13
+ small_record = Ruport::Data::Record.new({ "foo" => 'bar',
14
+ "baz" => "bang",
15
+ "Quux" => "adfdsa" })
16
+
17
+ small_attributes = small_record.attributes
18
+ sym_s_attributes = small_attributes.map { |r| r.intern }
19
+
20
+ SMALL_N = 10000
21
+ LARGE_N = 10
22
+
23
+ bench_suite do
24
+
25
+ bench_case("Integer Index - Small",SMALL_N) {
26
+ (0..2).each { |i| small_record[i] }
27
+ }
28
+
29
+ bench_case("Integer Index - Large",LARGE_N) {
30
+ large.each_index { |r| large_record[r] }
31
+ }
32
+
33
+ bench_case("String Index - Small", SMALL_N) {
34
+ small_attributes.each { |a| small_record[a] }
35
+ }
36
+
37
+ bench_case("String Index - Large", LARGE_N) {
38
+ large_attributes.each { |a| large_record[a] }
39
+ }
40
+
41
+ bench_case("Integer get() - Small", SMALL_N) {
42
+ (0..2).each { |i| small_record.get(i) }
43
+ }
44
+
45
+ bench_case("Integer get() - Large", LARGE_N) {
46
+ large.each_index { |r| large_record.get(r) }
47
+ }
48
+
49
+ bench_case("String get() - Small", SMALL_N) {
50
+ small_attributes.each { |a| small_record.get(a) }
51
+ }
52
+
53
+ bench_case("String get() - Large", LARGE_N) {
54
+ large_attributes.each { |a| large_record.get(a) }
55
+ }
56
+
57
+ bench_case("Symbol get() - Small", SMALL_N) {
58
+ sym_s_attributes.each { |a| small_record.get(a) }
59
+ }
60
+
61
+ bench_case("Symbol get() - Large", LARGE_N) {
62
+ sym_l_attributes.each { |a| large_record.get(a) }
63
+ }
64
+
65
+ end
@@ -0,0 +1,35 @@
1
+ require "ruport"
2
+ require "rubygems"
3
+ require "ruport/util/bench"
4
+ include Ruport::Bench
5
+
6
+ large = (1..1000).to_a
7
+ large_attributes = large.map { |e| e.to_s.reverse }
8
+
9
+ rand_large_attributes = large_attributes.sort_by { rand }
10
+
11
+
12
+ large_record = Ruport::Data::Record.new large,
13
+ :attributes => large_attributes
14
+
15
+ small_record = Ruport::Data::Record.new({ "foo" => 'bar',
16
+ "baz" => "bang",
17
+ "Quux" => "adfdsa" })
18
+
19
+ rand_small_attributes = small_record.attributes.sort_by { rand }
20
+
21
+ SMALL_N = 10000
22
+ LARGE_N = 100
23
+
24
+ bench_suite do
25
+
26
+ bench_case("reorder - small", SMALL_N) {
27
+ record = small_record.dup
28
+ record.reorder(rand_small_attributes)
29
+ }
30
+ bench_case("reorder - large", LARGE_N) {
31
+ record = large_record.dup
32
+ record.reorder(rand_large_attributes)
33
+ }
34
+
35
+ end