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,164 @@
1
+ #!/usr/bin/env ruby -w
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
3
+
4
+ class TestRenderCSVRow < Test::Unit::TestCase
5
+ def test_render_csv_row
6
+ actual = Ruport::Controller::Row.render_csv(:data => [1,2,3])
7
+ assert_equal("1,2,3\n", actual)
8
+ end
9
+ end
10
+
11
+ class TestRenderCSVTable < Test::Unit::TestCase
12
+
13
+ def setup
14
+ Ruport::Formatter::Template.create(:simple) do |format|
15
+ format.table = {
16
+ :show_headings => false
17
+ }
18
+ format.grouping = {
19
+ :style => :justified,
20
+ :show_headings => false
21
+ }
22
+ format.format_options = { :col_sep => ":" }
23
+ end
24
+ end
25
+
26
+ def test_render_csv_table
27
+ actual = Ruport::Controller::Table.render_csv do |r|
28
+ r.data = Table([], :data => [[1,2,3],[4,5,6]])
29
+ end
30
+ assert_equal("1,2,3\n4,5,6\n",actual)
31
+
32
+ actual = Ruport::Controller::Table.render_csv do |r|
33
+ r.data = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
34
+ end
35
+ assert_equal("a,b,c\n1,2,3\n4,5,6\n",actual)
36
+ end
37
+
38
+ def test_format_options
39
+ a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
40
+ assert_equal "a\tb\tc\n1\t2\t3\n4\t5\t6\n",
41
+ a.as(:csv,:format_options => { :col_sep => "\t" })
42
+ end
43
+
44
+ def test_table_headers
45
+ actual = Ruport::Controller::Table.
46
+ render_csv(:show_table_headers => false,
47
+ :data => Table(%w[a b c], :data => [[1,2,3],[4,5,6]]))
48
+ assert_equal("1,2,3\n4,5,6\n",actual)
49
+ end
50
+
51
+ def test_render_with_template
52
+ formatter = Ruport::Formatter::CSV.new
53
+ formatter.options = Ruport::Controller::Options.new
54
+ formatter.options.template = :simple
55
+ formatter.apply_template
56
+
57
+ assert_equal false, formatter.options.show_table_headers
58
+
59
+ assert_equal :justified, formatter.options.style
60
+ assert_equal false, formatter.options.show_group_headers
61
+
62
+ assert_equal ":", formatter.options.format_options[:col_sep]
63
+ end
64
+
65
+ def test_options_hashes_override_template
66
+ opts = nil
67
+ table = Table(%w[a b c])
68
+ table.to_csv(
69
+ :template => :simple,
70
+ :table_format => {
71
+ :show_headings => true
72
+ },
73
+ :grouping_format => {
74
+ :style => :raw,
75
+ :show_headings => true
76
+ }
77
+ ) do |r|
78
+ opts = r.options
79
+ end
80
+
81
+ assert_equal true, opts.show_table_headers
82
+
83
+ assert_equal :raw, opts.style
84
+ assert_equal true, opts.show_group_headers
85
+ end
86
+
87
+ def test_individual_options_override_template
88
+ opts = nil
89
+ table = Table(%w[a b c])
90
+ table.to_csv(
91
+ :template => :simple,
92
+ :show_table_headers => true,
93
+ :style => :raw,
94
+ :show_group_headers => true,
95
+ :format_options => { :col_sep => ";" }
96
+ ) do |r|
97
+ opts = r.options
98
+ end
99
+
100
+ assert_equal true, opts.show_table_headers
101
+
102
+ assert_equal :raw, opts.style
103
+ assert_equal true, opts.show_group_headers
104
+
105
+ assert_equal ";", opts.format_options[:col_sep]
106
+ end
107
+ end
108
+
109
+ class TestRenderCSVGroup < Test::Unit::TestCase
110
+
111
+ def test_render_csv_group
112
+ group = Ruport::Data::Group.new(:name => 'test',
113
+ :data => [[1,2,3],[4,5,6]],
114
+ :column_names => %w[a b c])
115
+ actual = Ruport::Controller::Group.
116
+ render_csv(:data => group, :show_table_headers => false )
117
+ assert_equal("test\n\n1,2,3\n4,5,6\n",actual)
118
+ end
119
+
120
+ end
121
+
122
+ class RenderCSVGrouping < Test::Unit::TestCase
123
+ def test_render_csv_grouping
124
+ table = Table(%w[hi red snapper]) << %w[is this annoying] <<
125
+ %w[is it funny]
126
+ grouping = Grouping(table,:by => "hi")
127
+
128
+ actual = grouping.to_csv
129
+
130
+ assert_equal "is\n\nred,snapper\nthis,annoying\nit,funny\n\n", actual
131
+ end
132
+
133
+ def test_render_csv_grouping_without_header
134
+ table = Table(%w[hi red snapper]) << %w[is this annoying] <<
135
+ %w[is it funny]
136
+ grouping = Grouping(table,:by => "hi")
137
+
138
+ actual = grouping.to_csv :show_table_headers => false
139
+
140
+ assert_equal "is\n\nthis,annoying\nit,funny\n\n", actual
141
+ end
142
+
143
+ def test_alternative_styles
144
+ g = Grouping((Table(%w[a b c]) << [1,2,3] << [1,1,4] <<
145
+ [2,1,2] << [1,9,1] ), :by => "a")
146
+
147
+ assert_raise(NotImplementedError) { g.to_csv :style => :not_real }
148
+
149
+ assert_equal "a,b,c\n1,2,3\n,1,4\n,9,1\n\n2,1,2\n\n",
150
+ g.to_csv(:style => :justified)
151
+
152
+ assert_equal "a,b,c\n1,2,3\n1,1,4\n1,9,1\n\n2,1,2\n\n",
153
+ g.to_csv(:style => :raw)
154
+ end
155
+
156
+ # -----------------------------------------------------------------------
157
+ # BUG TRAPS
158
+ # ------------------------------------------------------------------------
159
+
160
+ def test_ensure_group_names_are_converted_to_string
161
+ g = Grouping((Table(%w[a b c])<<[1,2,3]<<[1,1,4]), :by => "a")
162
+ assert_equal "1\n\nb,c\n2,3\n1,4\n\n", g.to_csv
163
+ end
164
+ end
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby -w
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
3
+
4
+ class DataFeederTest < Test::Unit::TestCase
5
+
6
+ context "when using a default data feeder" do
7
+
8
+ def setup
9
+ @feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
10
+ end
11
+
12
+ def specify_data_attribute_should_return_wrapped_data
13
+ assert_equal Table(%w[a b c]), @feeder.data
14
+ end
15
+
16
+ def specify_append_should_forward_to_wrapped_data_by_default
17
+ t = Table(%w[a b c])
18
+ t << [1,2,3] << {"a" => 2, "b" => 3, "c" => 4}
19
+ @feeder << [1,2,3] << {"a" => 2, "b" => 3, "c" => 4}
20
+ assert_equal t, @feeder.data
21
+ end
22
+
23
+ end
24
+
25
+ context "when using a feeder with a filter" do
26
+ def setup
27
+ @feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
28
+ @feeder.filter { |r| r.a != 1 }
29
+ end
30
+
31
+ def specify_filter_should_only_append_rows_for_which_block_is_true
32
+ @feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
33
+ assert_equal Table(%w[a b c], :data => [[4,1,2],[3,1,1]]), @feeder.data
34
+ end
35
+ end
36
+
37
+ context "when using a feeder with a transform" do
38
+ def setup
39
+ @feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
40
+ @feeder.transform { |r| r.a += 1 }
41
+ end
42
+
43
+ def specify_filter_should_be_applied_to_all_rows
44
+ @feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
45
+ assert_equal Table(%w[a b c], :data => [[2,2,3],[5,1,2],[4,1,1],[2,2,5]]),
46
+ @feeder.data
47
+ end
48
+ end
49
+
50
+ context "when using a feeder and a filter together" do
51
+ def setup
52
+ @feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
53
+ end
54
+
55
+ def specify_filter_is_called_first_when_defined_first
56
+ @feeder.filter { |r| r.b != 2 }
57
+ @feeder.transform { |r| r.b += 1 }
58
+ @feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
59
+ assert_equal Table(%w[a b c], :data => [[4,2,2],[3,2,1]]),
60
+ @feeder.data
61
+ end
62
+
63
+ def specify_transform_is_called_first_when_defined_first
64
+ @feeder.transform { |r| r.b += 1 }
65
+ @feeder.filter { |r| r.b != 2 }
66
+ @feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
67
+ assert_equal Table(%w[a b c], :data => [[1,3,3],[1,3,5]]),
68
+ @feeder.data
69
+ end
70
+ end
71
+
72
+ context "when using many feeders and filters together" do
73
+ def setup
74
+ @feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
75
+ @feeder.transform { |r| r.a += 1 }
76
+ @feeder.filter { |r| r.a > 5 }
77
+ @feeder.transform { |r| r.b = r.b.to_s }
78
+ @feeder.filter { |r| r.b == "3" }
79
+ end
80
+
81
+ def specify_all_blocks_are_executed_in_order
82
+ @feeder << [1,2,3] << [4,1,9] << [5,3,1] << [2,3,0] << [7,3,5]
83
+ assert_equal Table(%w[a b c], :data => [[6,"3",1],[8,"3",5]]),
84
+ @feeder.data
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,410 @@
1
+ #!/usr/bin/env ruby -w
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
3
+
4
+ class TestGroup < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @group = Ruport::Data::Group.new(:name => 'test',
8
+ :data => [[1,2,3]],
9
+ :column_names => %w[a b c])
10
+ end
11
+
12
+ def test_group_constructor
13
+ group = Ruport::Data::Group.new(:name => 'test',
14
+ :data => [[1,2,3]],
15
+ :column_names => %w[a b c])
16
+ assert_equal 'test', group.name
17
+ assert_equal Ruport::Data::Record.new([1,2,3],:attributes => %w[a b c]),
18
+ group.data[0]
19
+ assert_equal %w[a b c], group.column_names
20
+ end
21
+
22
+ def test_should_copy_group
23
+ @group.send(:create_subgroups, "a")
24
+ copy = @group.dup
25
+ assert_equal 'test', copy.name
26
+ assert_equal Ruport::Data::Record.new([1,2,3],:attributes => %w[a b c]),
27
+ copy.data[0]
28
+ assert_equal %w[a b c], copy.column_names
29
+
30
+ b = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
31
+ :column_names => %w[b c],
32
+ :name => 1 ) }
33
+ assert_equal b, copy.subgroups
34
+ end
35
+
36
+ def test_eql
37
+ table = Table(%w[a b c], :data => [[1,2,3]])
38
+
39
+ group2 = Ruport::Data::Group.new(:name => 'test',
40
+ :data => [[1,2,3]],
41
+ :column_names => %w[a b c])
42
+
43
+ assert_raises(NoMethodError) { @group == table }
44
+ assert_equal @group, group2
45
+ assert_equal @group, @group.dup
46
+ end
47
+
48
+ def test_create_subgroups
49
+ group = @group << [4,5,6]
50
+ group.send(:create_subgroups, "a")
51
+ b = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
52
+ :column_names => %w[b c],
53
+ :name => 1 ),
54
+ 4 => Ruport::Data::Group.new( :data => [[5,6]],
55
+ :column_names => %w[b c],
56
+ :name => 4 ) }
57
+ assert_equal b, group.subgroups
58
+
59
+ group.send(:create_subgroups, "b")
60
+ c = { 2 => Ruport::Data::Group.new( :data => [[3]],
61
+ :column_names => %w[c],
62
+ :name => 2 ) }
63
+ d = { 5 => Ruport::Data::Group.new( :data => [[6]],
64
+ :column_names => %w[c],
65
+ :name => 5 ) }
66
+ assert_equal c, group.subgroups[1].subgroups
67
+ assert_equal d, group.subgroups[4].subgroups
68
+ end
69
+
70
+ def test_grouped_data
71
+ a = @group << [4,5,6]
72
+ b = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
73
+ :column_names => %w[b c],
74
+ :name => 1 ),
75
+ 4 => Ruport::Data::Group.new( :data => [[5,6]],
76
+ :column_names => %w[b c],
77
+ :name => 4 ) }
78
+ assert_equal b, a.send(:grouped_data, "a")
79
+ end
80
+ end
81
+
82
+ class TestGroupRendering < Test::Unit::TestCase
83
+
84
+ def setup
85
+ @group = Ruport::Data::Group.new(:name => 'test',
86
+ :data => [[1,2,3]],
87
+ :column_names => %w[a b c])
88
+ end
89
+
90
+ def test_group_as
91
+ assert_equal(7, @group.to_text.to_a.length)
92
+ assert_equal(5, @group.as(:text,
93
+ :show_table_headers => false).to_a.length)
94
+ assert_equal(13, @group.to_html.to_a.length)
95
+ end
96
+
97
+ def test_as_throws_proper_errors
98
+ assert_nothing_raised { @group.as(:csv) }
99
+ assert_nothing_raised { @group.to_csv }
100
+ assert_raises(Ruport::Controller::UnknownFormatError) {
101
+ @group.as(:nothing) }
102
+ assert_raises(Ruport::Controller::UnknownFormatError) {
103
+ @group.to_nothing }
104
+ end
105
+
106
+ class MyGroupSub < Ruport::Data::Group; end
107
+
108
+ def test_ensure_group_subclasses_render_properly
109
+ t = MyGroupSub.new(:column_names => %w[b c],:name => "1") << [2,3]
110
+ assert_equal "1\n\nb,c\n2,3\n", t.to_csv
111
+ end
112
+ end
113
+
114
+ class TestGrouping < Test::Unit::TestCase
115
+
116
+ def setup
117
+ table = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
118
+ @grouping = Ruport::Data::Grouping.new(table, :by => "a")
119
+ end
120
+
121
+ def test_grouping_constructor
122
+ a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
123
+ b = Ruport::Data::Grouping.new(a, :by => "a")
124
+ c = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
125
+ :column_names => %w[b c],
126
+ :name => 1 ),
127
+ 4 => Ruport::Data::Group.new( :data => [[5,6]],
128
+ :column_names => %w[b c],
129
+ :name => 4 ) }
130
+ assert_equal c, b.data
131
+ end
132
+
133
+ def test_empty_grouping
134
+ a = Ruport::Data::Grouping.new()
135
+ a << Group("foo",:data => [[1,2,3],[4,5,6]],
136
+ :column_names => %w[a b c] )
137
+ assert_equal "foo", a["foo"].name
138
+ assert_nil a.grouped_by
139
+ end
140
+
141
+ def test_empty_grouping_with_grouped_by
142
+ a = Ruport::Data::Grouping.new(:by => "nada")
143
+ a << Group("foo",:data => [[1,2,3],[4,5,6]],
144
+ :column_names => %w[a b c] )
145
+ assert_equal "foo", a["foo"].name
146
+ assert_equal "nada", a.grouped_by
147
+ end
148
+
149
+ def test_grouping_indexing
150
+ a = [Ruport::Data::Group.new( :data => [[2,3]],
151
+ :column_names => %w[b c],
152
+ :name => 1 ),
153
+ Ruport::Data::Group.new( :data => [[5,6]],
154
+ :column_names => %w[b c],
155
+ :name => 4 ),
156
+ Ruport::Data::Group.new( :data => [],
157
+ :column_names => %w[b c],
158
+ :name => 2)]
159
+ assert_equal a[0], @grouping[1]
160
+ assert_equal a[1], @grouping[4]
161
+ assert_raises(IndexError) { @grouping[2] }
162
+ end
163
+
164
+ def test_should_copy_grouping
165
+ a = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
166
+ :column_names => %w[b c],
167
+ :name => 1 ),
168
+ 4 => Ruport::Data::Group.new( :data => [[5,6]],
169
+ :column_names => %w[b c],
170
+ :name => 4 ) }
171
+ copy = @grouping.dup
172
+ assert_equal a, copy.data
173
+ assert_equal "a", copy.grouped_by
174
+ end
175
+
176
+ def test_append
177
+ a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
178
+ @grouping << a.to_group("red snapper")
179
+ assert_equal @grouping["red snapper"], a.to_group("red snapper")
180
+
181
+ assert_raises(ArgumentError) { @grouping << a.to_group("red snapper") }
182
+ end
183
+
184
+ def test_grouped_by
185
+ assert_equal "a", @grouping.grouped_by
186
+ end
187
+
188
+ def test_grouping_on_multiple_columns
189
+ a = Table(%w[a b c d], :data => [[1,2,3,4],[4,5,6,7]])
190
+ b = Ruport::Data::Grouping.new(a, :by => %w[a b c])
191
+ c = { 1 => Ruport::Data::Group.new( :data => [[2,3,4]],
192
+ :column_names => %w[b c d],
193
+ :name => 1 ),
194
+ 4 => Ruport::Data::Group.new( :data => [[5,6,7]],
195
+ :column_names => %w[b c d],
196
+ :name => 4 ) }
197
+ assert_equal c, b.data
198
+
199
+ d = { 2 => Ruport::Data::Group.new( :data => [[3,4]],
200
+ :column_names => %w[c d],
201
+ :name => 2 ) }
202
+ e = { 5 => Ruport::Data::Group.new( :data => [[6,7]],
203
+ :column_names => %w[c d],
204
+ :name => 5 ) }
205
+ assert_equal d, b[1].subgroups
206
+ assert_equal e, b[4].subgroups
207
+ end
208
+
209
+ def test_subgrouping
210
+ a = Table(%w[first_name last_name id])
211
+ a << %w[ greg brown awesome ]
212
+ a << %w[ mike milner schweet ]
213
+ a << %w[ greg brown sick ]
214
+ g = Grouping(a,:by => %w[first_name last_name])
215
+
216
+ sub = g.subgrouping("greg")["brown"]
217
+ assert_equal %w[awesome sick], sub.column("id")
218
+
219
+ sub = (g / "mike")["milner"]
220
+ assert_equal %w[schweet], sub.column("id")
221
+ end
222
+
223
+ class TicketStatus < Ruport::Data::Record
224
+
225
+ def closed
226
+ title =~ /Ticket.+(\w+ closed)/ ? 1 : 0
227
+ end
228
+
229
+ def opened
230
+ title =~ /Ticket.+(\w+ created)|(\w+ reopened)/ ? 1 : 0
231
+ end
232
+
233
+ end
234
+
235
+ def test_grouping_summary
236
+ source = Table(File.join(File.expand_path(File.dirname(__FILE__)),
237
+ *%w[samples ticket_count.csv]),
238
+ :record_class => TicketStatus)
239
+ grouping = Grouping(source,:by => "date")
240
+
241
+ expected = Table(:date, :opened,:closed)
242
+ grouping.each do |date,group|
243
+ opened = group.sigma { |r| r.opened }
244
+ closed = group.sigma { |r| r.closed }
245
+ expected << { :date => date, :opened => opened, :closed => closed }
246
+ end
247
+
248
+ actual = grouping.summary :date,
249
+ :opened => lambda { |g| g.sigma(:opened) },
250
+ :closed => lambda { |g| g.sigma(:closed) },
251
+ :order => [:date,:opened,:closed]
252
+
253
+ assert_equal expected, actual
254
+
255
+ actual = grouping.summary :date,
256
+ :opened => lambda { |g| g.sigma(:opened) },
257
+ :closed => lambda { |g| g.sigma(:closed) }
258
+
259
+ assert_equal [], expected.column_names - actual.column_names
260
+ end
261
+
262
+ def test_grouping_sigma
263
+ assert_respond_to @grouping, :sigma
264
+ assert_respond_to @grouping, :sum
265
+
266
+ expected = {}
267
+ @grouping.data[@grouping.data.keys.first].column_names.each do |col|
268
+ expected[col] = @grouping.inject(0) do |s, (group_name, group)|
269
+ s + group.sigma(col)
270
+ end
271
+ end
272
+ expected.keys.each do |col|
273
+ assert_equal expected[col], @grouping.sigma(col)
274
+ end
275
+
276
+ expected = {}
277
+ @grouping.data[@grouping.data.keys.first].column_names.each do |col|
278
+ expected[col] = @grouping.inject(0) do |s, (group_name, group)|
279
+ s + group.sigma {|r| r[col] + 2 }
280
+ end
281
+ end
282
+ expected.keys.each do |col|
283
+ assert_equal expected[col], @grouping.sigma {|r| r[col] + 2 }
284
+ end
285
+ end
286
+
287
+ context "when sorting groupings" do
288
+
289
+ def setup
290
+ @table = Table(%w[a b c]) << ["dog",1,2] << ["cat",3,5] <<
291
+ ["banana",8,1] << ["dog",5,6]
292
+ end
293
+
294
+ def specify_can_set_by_group_name_order_in_constructor
295
+ a = Grouping(@table, :by => "a", :order => :name)
296
+ names = %w[banana cat dog]
297
+ data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
298
+ a.each do |name,group|
299
+ assert_equal names.shift, name
300
+ assert_equal data.shift, group.map { |r| r.to_a }
301
+ end
302
+ end
303
+
304
+ def specify_can_set_by_proc_ordering_in_constructor
305
+ a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
306
+ names = %w[dog banana cat]
307
+ data = [ [[1,2],[5,6]], [[8,1]], [[3,5]] ]
308
+ a.each do |name,group|
309
+ assert_equal names.shift, name
310
+ assert_equal data.shift, group.map { |r| r.to_a }
311
+ end
312
+ end
313
+
314
+ def specify_can_override_sorting
315
+ a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
316
+ a.sort_grouping_by!(:name)
317
+ names = %w[banana cat dog]
318
+ data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
319
+ a.each do |name,group|
320
+ assert_equal names.shift, name
321
+ assert_equal data.shift, group.map { |r| r.to_a }
322
+ end
323
+ end
324
+
325
+ def specify_can_get_a_new_sorted_grouping
326
+ a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
327
+ b = a.sort_grouping_by(:name)
328
+
329
+ names = %w[banana cat dog]
330
+ data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
331
+ b.each do |name,group|
332
+ assert_equal names.shift, name
333
+ assert_equal data.shift, group.map { |r| r.to_a }
334
+ end
335
+
336
+ # assert original retained
337
+ names = %w[dog banana cat]
338
+ data = [ [[1,2],[5,6]], [[8,1]], [[3,5]] ]
339
+ a.each do |name,group|
340
+ assert_equal names.shift, name
341
+ assert_equal data.shift, group.map { |r| r.to_a }
342
+ end
343
+ end
344
+ end
345
+
346
+ class MyRecord < Ruport::Data::Record; end
347
+
348
+ def test_grouping_should_set_record_class
349
+ a = Table(%w[a b c], :record_class => MyRecord) { |t|
350
+ t << [1,2,3]
351
+ t << [4,5,6]
352
+ }
353
+ b = Ruport::Data::Grouping.new(a, :by => "a")
354
+ assert_equal MyRecord, b[1].record_class
355
+ end
356
+
357
+ class MyGroupingSub < Ruport::Data::Grouping; end
358
+
359
+ def test_ensure_grouping_subclasses_render_properly
360
+ t = Table(%w[a b c]) << [1,2,3]
361
+ a = MyGroupingSub.new(t, :by => "a")
362
+ assert_equal "1\n\nb,c\n2,3\n\n", a.to_csv
363
+ end
364
+ end
365
+
366
+ class TestGroupingRendering < Test::Unit::TestCase
367
+
368
+ def setup
369
+ table = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
370
+ @grouping = Ruport::Data::Grouping.new(table, :by => "a")
371
+ end
372
+
373
+ def test_grouping_as
374
+ assert_equal(16, @grouping.to_text.to_a.length)
375
+ assert_equal(12, @grouping.as(:text,
376
+ :show_table_headers => false).to_a.length)
377
+ end
378
+
379
+ def test_as_throws_proper_errors
380
+ assert_nothing_raised { @grouping.as(:csv) }
381
+ assert_nothing_raised { @grouping.to_csv }
382
+ assert_raises(Ruport::Controller::UnknownFormatError) {
383
+ @grouping.as(:nothing) }
384
+ assert_raises(Ruport::Controller::UnknownFormatError) {
385
+ @grouping.to_nothing }
386
+ end
387
+ end
388
+
389
+ class TestGroupingKernelHacks < Test::Unit::TestCase
390
+
391
+ def test_group_kernel_hack
392
+ group = Ruport::Data::Group.new( :name => 'test',
393
+ :data => [[1,2,3]],
394
+ :column_names => %w[a b c])
395
+ assert_equal group, Group('test', :data => [[1,2,3]],
396
+ :column_names => %w[a b c])
397
+ end
398
+
399
+ def test_grouping_kernel_hack
400
+ table = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
401
+ grouping = Ruport::Data::Grouping.new(table, :by => "a")
402
+ a = { 1 => Ruport::Data::Group.new( :data => [[2,3]],
403
+ :column_names => %w[b c],
404
+ :name => 1 ),
405
+ 4 => Ruport::Data::Group.new( :data => [[5,6]],
406
+ :column_names => %w[b c],
407
+ :name => 4 ) }
408
+ assert_equal a, grouping.data
409
+ end
410
+ end