jsanders-ruport 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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