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.
- data/AUTHORS +48 -0
- data/LICENSE +59 -0
- data/README +114 -0
- data/Rakefile +93 -0
- data/examples/RWEmerson.jpg +0 -0
- data/examples/anon.rb +43 -0
- data/examples/btree/commaleon/commaleon.rb +263 -0
- data/examples/btree/commaleon/sample_data/ticket_count.csv +124 -0
- data/examples/btree/commaleon/sample_data/ticket_count2.csv +119 -0
- data/examples/centered_pdf_text_box.rb +83 -0
- data/examples/data/tattle.dump +82 -0
- data/examples/example.csv +3 -0
- data/examples/line_plotter.rb +61 -0
- data/examples/pdf_report_with_common_base.rb +72 -0
- data/examples/png_embed.rb +54 -0
- data/examples/roadmap.png +0 -0
- data/examples/row_renderer.rb +39 -0
- data/examples/simple_pdf_lines.rb +25 -0
- data/examples/simple_templating_example.rb +34 -0
- data/examples/tattle_ruby_version.rb +39 -0
- data/examples/tattle_rubygems_version.rb +37 -0
- data/examples/trac_ticket_status.rb +59 -0
- data/lib/ruport.rb +127 -0
- data/lib/ruport/controller.rb +616 -0
- data/lib/ruport/controller/grouping.rb +71 -0
- data/lib/ruport/controller/table.rb +54 -0
- data/lib/ruport/data.rb +4 -0
- data/lib/ruport/data/feeder.rb +111 -0
- data/lib/ruport/data/grouping.rb +399 -0
- data/lib/ruport/data/record.rb +297 -0
- data/lib/ruport/data/table.rb +950 -0
- data/lib/ruport/extensions.rb +4 -0
- data/lib/ruport/formatter.rb +254 -0
- data/lib/ruport/formatter/csv.rb +149 -0
- data/lib/ruport/formatter/html.rb +161 -0
- data/lib/ruport/formatter/pdf.rb +591 -0
- data/lib/ruport/formatter/template.rb +187 -0
- data/lib/ruport/formatter/text.rb +231 -0
- data/lib/uport.rb +1 -0
- data/test/controller_test.rb +743 -0
- data/test/csv_formatter_test.rb +164 -0
- data/test/data_feeder_test.rb +88 -0
- data/test/grouping_test.rb +410 -0
- data/test/helpers.rb +11 -0
- data/test/html_formatter_test.rb +201 -0
- data/test/pdf_formatter_test.rb +354 -0
- data/test/record_test.rb +332 -0
- data/test/samples/addressbook.csv +6 -0
- data/test/samples/data.csv +3 -0
- data/test/samples/data.tsv +3 -0
- data/test/samples/dates.csv +1409 -0
- data/test/samples/erb_test.sql +1 -0
- data/test/samples/query_test.sql +1 -0
- data/test/samples/ruport_test.sql +8 -0
- data/test/samples/test.sql +2 -0
- data/test/samples/test.yaml +3 -0
- data/test/samples/ticket_count.csv +124 -0
- data/test/table_pivot_test.rb +134 -0
- data/test/table_test.rb +838 -0
- data/test/template_test.rb +48 -0
- data/test/text_formatter_test.rb +258 -0
- data/util/bench/data/record/bench_as_vs_to.rb +18 -0
- data/util/bench/data/record/bench_constructor.rb +46 -0
- data/util/bench/data/record/bench_indexing.rb +65 -0
- data/util/bench/data/record/bench_reorder.rb +35 -0
- data/util/bench/data/record/bench_to_a.rb +19 -0
- data/util/bench/data/table/bench_column_manip.rb +103 -0
- data/util/bench/data/table/bench_dup.rb +24 -0
- data/util/bench/data/table/bench_init.rb +67 -0
- data/util/bench/data/table/bench_manip.rb +125 -0
- data/util/bench/formatter/bench_csv.rb +14 -0
- data/util/bench/formatter/bench_html.rb +14 -0
- data/util/bench/formatter/bench_pdf.rb +14 -0
- data/util/bench/formatter/bench_text.rb +14 -0
- data/util/bench/samples/tattle.csv +1237 -0
- metadata +176 -0
@@ -0,0 +1 @@
|
|
1
|
+
select * from <%= @table %>
|
@@ -0,0 +1 @@
|
|
1
|
+
select * from foo
|
@@ -0,0 +1,124 @@
|
|
1
|
+
title,date
|
2
|
+
Ticket #238 (enhancement closed): Table#sort_rows_by!,2007-04-17
|
3
|
+
Ticket #225 (task closed): corner bottlenecks with focused benchmarks,2007-04-17
|
4
|
+
Ticket #223 (task closed): Identify a small set of key benchmarks,2007-04-17
|
5
|
+
Ticket #209 (task closed): Refactor Formatters,2007-04-15
|
6
|
+
Ticket #236 (task closed): api.rubyreports.org/edge,2007-04-13
|
7
|
+
Ticket #212 (task closed): Users Field Guide,2007-04-13
|
8
|
+
Ticket #186 (enhancement closed): simple_html_table,2007-04-13
|
9
|
+
Ticket #235 (task closed): Get a big list of all the methods in Ruport. Stare at them. Identify their interface. Cry.,2007-04-13
|
10
|
+
Ticket #196 (defect closed): as() returns unintelligible error for non-registered formats,2007-04-13
|
11
|
+
Ticket #244 (defect closed): Allow proper copying of Grouping,2007-04-12
|
12
|
+
Ticket #249 (enhancement closed): Table#rename_columns should accept a block,2007-04-11
|
13
|
+
Ticket #249 (enhancement created): Table#rename_columns should accept a block,2007-04-11
|
14
|
+
Ticket #188 (defect closed): class_str broken in 0.9.2,2007-04-11
|
15
|
+
Ticket #224 (task closed): Build ruport_bench which will run benchmarks and generate reports,2007-04-11
|
16
|
+
Ticket #241 (task closed): rewrite Table/Group dup methods to use initialize_copy instead,2007-04-11
|
17
|
+
Ticket #220 (enhancement closed): rope rake tasks for ruport-util,2007-04-10
|
18
|
+
Ticket #219 (task closed): XML/FO Formatter,2007-04-07
|
19
|
+
Ticket #211 (task closed): Remove Multilevel Grouping Formatters,2007-04-06
|
20
|
+
Ticket #248 (task created): AAR Name,2007-04-05
|
21
|
+
Ticket #204 (task closed): Merge AAR to Trunk,2007-04-05
|
22
|
+
Ticket #203 (task closed): AAR Tests,2007-04-05
|
23
|
+
Ticket #226 (task closed): investigate Ara's xx for html helpers.,2007-04-04
|
24
|
+
"Ticket #247 (task created): Ruport Utils wiki page, and update of deprecated plugin pages",2007-04-04
|
25
|
+
Ticket #245 (task closed): Make initial RubyForge release,2007-04-04
|
26
|
+
Ticket #246 (enhancement created): Grouping#summary,2007-04-04
|
27
|
+
Ticket #245 (task created): Make initial RubyForge release,2007-04-04
|
28
|
+
Ticket #229 (enhancement closed): Add tests for invoice,2007-04-04
|
29
|
+
Ticket #231 (enhancement closed): ReportManager tests,2007-04-04
|
30
|
+
Ticket #221 (task closed): improve invoice interface,2007-04-04
|
31
|
+
Ticket #233 (task closed): ReportManager example,2007-04-04
|
32
|
+
Ticket #230 (enhancement closed): Add support for line labels in graph,2007-04-04
|
33
|
+
Ticket #242 (task closed): set mike up with stats access,2007-04-04
|
34
|
+
Ticket #202 (task closed): AAR Branch,2007-04-04
|
35
|
+
Ticket #234 (defect closed): options should not be used as an argument name anywhere in Renderers or Formatters,2007-04-04
|
36
|
+
Ticket #244 (defect created): Allow proper copying of Grouping,2007-04-04
|
37
|
+
Ticket #240 (task closed): use self.class.new where appropriate,2007-04-04
|
38
|
+
Ticket #243 (task closed): fix circular dependency issue in rope,2007-04-04
|
39
|
+
Ticket #243 (task created): fix circular dependency issue in rope,2007-04-04
|
40
|
+
Ticket #242 (task created): set mike up with stats access,2007-04-03
|
41
|
+
Ticket #241 (task created): rewrite Table/Group dup methods to use initialize_copy instead,2007-04-03
|
42
|
+
Ticket #237 (task closed): set mike up with all the necessary resource permissions for releases,2007-04-02
|
43
|
+
Ticket #227 (task closed): packaging rake task for Release,2007-04-02
|
44
|
+
Ticket #240 (task created): use self.class.new where appropriate,2007-04-02
|
45
|
+
Ticket #191 (enhancement closed): render_grouping,2007-04-01
|
46
|
+
Ticket #239 (enhancement created): Table#sort_rows_by should accept non-array single arg.,2007-04-01
|
47
|
+
Ticket #238 (enhancement created): Table#sort_rows_by!,2007-04-01
|
48
|
+
Ticket #237 (task created): set mike up with all the necessary resource permissions for releases,2007-04-01
|
49
|
+
Ticket #78 (enhancement closed): Do we need to bring back a SQL generator?,2007-03-31
|
50
|
+
Ticket #236 (task created): api.rubyreports.org/edge,2007-03-31
|
51
|
+
Ticket #235 (task created): Get a big list of all the methods in Ruport. Stare at them. Identify their interface. Cry.,2007-03-31
|
52
|
+
Ticket #228 (enhancement closed): Layout method,2007-03-31
|
53
|
+
Ticket #234 (defect created): options should not be used as an argument name anywhere in Renderers or Formatters,2007-03-31
|
54
|
+
Ticket #217 (task closed): Depluginize initial set of utils,2007-03-31
|
55
|
+
Ticket #232 (task closed): ReportManager example,2007-03-31
|
56
|
+
Ticket #233 (task created): ReportManager example,2007-03-31
|
57
|
+
Ticket #232 (task created): ReportManager example,2007-03-31
|
58
|
+
Ticket #231 (enhancement created): ReportManager tests,2007-03-31
|
59
|
+
Ticket #230 (enhancement created): Add support for line labels in graph,2007-03-31
|
60
|
+
Ticket #216 (task closed): Fix Graphing,2007-03-31
|
61
|
+
Ticket #229 (enhancement created): Add tests for invoice,2007-03-31
|
62
|
+
Ticket #228 (enhancement created): Layout method,2007-03-31
|
63
|
+
Ticket #222 (task closed): add ruport-util component in Trac,2007-03-31
|
64
|
+
Ticket #218 (task closed): move svn repository up one level,2007-03-31
|
65
|
+
Ticket #227 (task created): packaging rake task for Release,2007-03-31
|
66
|
+
Ticket #226 (task created): investigate Ara's xx for html helpers.,2007-03-30
|
67
|
+
Ticket #199 (task closed): Update License Information,2007-03-30
|
68
|
+
Ticket #178 (task closed): Grouping Renderer,2007-03-30
|
69
|
+
Ticket #225 (task created): corner bottlenecks with focused benchmarks,2007-03-30
|
70
|
+
Ticket #224 (task created): Build ruport_bench which will run benchmarks and generate reports,2007-03-30
|
71
|
+
Ticket #223 (task created): Identify a small set of key benchmarks,2007-03-30
|
72
|
+
Ticket #106 (task closed): standardize API documentation format and cleanup where needed,2007-03-30
|
73
|
+
Ticket #199 (task closed): Update License Information,2007-03-30
|
74
|
+
Ticket #184 (task closed): Consistent Errors,2007-03-30
|
75
|
+
Ticket #222 (task created): add ruport-util component in Trac,2007-03-30
|
76
|
+
Ticket #221 (task created): improve invoice interface,2007-03-30
|
77
|
+
Ticket #220 (enhancement created): rope rake tasks for ruport-util,2007-03-30
|
78
|
+
Ticket #219 (task created): XML/FO Formatter,2007-03-30
|
79
|
+
Ticket #218 (task created): move svn repository up one level,2007-03-30
|
80
|
+
Ticket #217 (task created): Depluginize initial set of utils,2007-03-30
|
81
|
+
Ticket #216 (task created): Fix Graphing,2007-03-30
|
82
|
+
Ticket #215 (task closed): apply for RubyForge project,2007-03-30
|
83
|
+
Ticket #215 (task created): apply for RubyForge project,2007-03-30
|
84
|
+
Ticket #214 (task created): Determine if cheatsheets can be released,2007-03-30
|
85
|
+
Ticket #213 (task created): Contributors Field Guide,2007-03-30
|
86
|
+
Ticket #212 (task created): Users Field Guide,2007-03-30
|
87
|
+
Ticket #211 (task created): Remove Multilevel Grouping Formatters,2007-03-30
|
88
|
+
Ticket #210 (task created): Formatting Helpers,2007-03-30
|
89
|
+
Ticket #209 (task created): Refactor Formatters,2007-03-30
|
90
|
+
Ticket #208 (task created): API Stability,2007-03-30
|
91
|
+
Ticket #207 (task created): Refactor Unit Tests,2007-03-30
|
92
|
+
Ticket #206 (task created): Testing Audit,2007-03-30
|
93
|
+
Ticket #205 (task created): Custom Exceptions,2007-03-30
|
94
|
+
Ticket #204 (task created): Merge AAR to Trunk,2007-03-30
|
95
|
+
Ticket #203 (task created): AAR Tests,2007-03-30
|
96
|
+
Ticket #202 (task created): AAR Branch,2007-03-30
|
97
|
+
Ticket #201 (task created): Standardize API Docs,2007-03-30
|
98
|
+
Ticket #200 (task created): Remove Deprecated Docs,2007-03-30
|
99
|
+
Ticket #199 (task created): Update License Information,2007-03-30
|
100
|
+
Ticket #198 (task created): rubyreports.org webpage,2007-03-30
|
101
|
+
Ticket #197 (task created): Proper Licensing Statements,2007-03-28
|
102
|
+
Ticket #196 (defect created): as() returns unintelligible error for non-registered formats,2007-03-28
|
103
|
+
Ticket #195 (enhancement closed): Formatter::PDF#draw_table,2007-03-27
|
104
|
+
"Ticket #194 (enhancement closed): renders_for should take multiple formats, renderers.",2007-03-26
|
105
|
+
Ticket #193 (task closed): Make Renderer.add_format private and remove add_core_format,2007-03-26
|
106
|
+
Ticket #195 (enhancement created): Formatter::PDF#draw_table,2007-03-26
|
107
|
+
"Ticket #194 (enhancement created): renders_for should take multiple formats, renderers.",2007-03-26
|
108
|
+
Ticket #193 (task created): Make Renderer.add_format private and remove add_core_format,2007-03-26
|
109
|
+
Ticket #183 (task closed): Remove Shortcuts from Core,2007-03-26
|
110
|
+
Ticket #192 (enhancement created): renders_with should take default options,2007-03-26
|
111
|
+
Ticket #191 (enhancement created): render_grouping,2007-03-25
|
112
|
+
Ticket #190 (enhancement created): Report shortcuts for rendering,2007-03-25
|
113
|
+
Ticket #189 (enhancement created): sub_table / reduce should take single arg range,2007-03-25
|
114
|
+
Ticket #187 (enhancement closed): Ruport::Format::Plugin becomes Ruport::Formatter,2007-03-24
|
115
|
+
Ticket #163 (task closed): Data::Group,2007-03-23
|
116
|
+
Ticket #144 (enhancement closed): SQL Formatter?,2007-03-23
|
117
|
+
Ticket #188 (defect created): class_str broken in 0.9.2,2007-03-23
|
118
|
+
Ticket #187 (enhancement created): Ruport::Format::Plugin becomes Ruport::Formatter,2007-03-23
|
119
|
+
Ticket #174 (enhancement closed): Grouping & Group data structures,2007-03-23
|
120
|
+
Ticket #186 (enhancement created): simple_html_table,2007-03-23
|
121
|
+
Ticket #185 (task created): Sanitize,2007-03-22
|
122
|
+
Ticket #184 (task created): Consistent Errors,2007-03-22
|
123
|
+
Ticket #183 (task created): Remove Shortcuts from Core,2007-03-22
|
124
|
+
Ticket #182 (defect closed): rope does not regenerate deleted test_files when using 'rake build',2007-03-19
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
3
|
+
|
4
|
+
class TablePivotSimpleCaseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
table = Table('a', 'b', 'c')
|
8
|
+
table << [1,3,6]
|
9
|
+
table << [1,4,7]
|
10
|
+
table << [2,3,8]
|
11
|
+
table << [2,4,9]
|
12
|
+
@pivoted = table.pivot('b', :group_by => 'a', :values => 'c')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_produces_correct_columns
|
16
|
+
assert_equal(['a', 3, 4], @pivoted.column_names)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_produces_correct_full_table
|
20
|
+
expected = Table("a",3,4) { |t| t << [1,6,7] << [2,8,9] }
|
21
|
+
assert_equal(expected, @pivoted)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class PivotConvertRowOrderToGroupOrderTest < Test::Unit::TestCase
|
27
|
+
|
28
|
+
def convert(src)
|
29
|
+
Ruport::Data::Table::Pivot.new(
|
30
|
+
nil, nil, nil, nil
|
31
|
+
).convert_row_order_to_group_order(src)
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup
|
35
|
+
@group = mock('group')
|
36
|
+
@row = mock('row')
|
37
|
+
@group.stubs(:[]).with(0).returns(@row)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_bare_field_name
|
41
|
+
converted = convert(:field_name)
|
42
|
+
@row.expects(:[]).with(:field_name)
|
43
|
+
converted.call(@group)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_array_of_field_names
|
47
|
+
converted = convert([:field1, :field2])
|
48
|
+
@row.stubs(:[]).with(:field1).returns('f1val')
|
49
|
+
@row.stubs(:[]).with(:field2).returns('f2val')
|
50
|
+
assert_equal(['f1val', 'f2val'], converted.call(@group))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_proc_operating_on_row
|
54
|
+
converted = convert(proc {|row| row[:field1] })
|
55
|
+
@row.stubs(:[]).with(:field1).returns('f1val')
|
56
|
+
assert_equal('f1val', converted.call(@group))
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_nil
|
60
|
+
assert_equal(nil, convert(nil))
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class PivotPreservesOrdering < Test::Unit::TestCase
|
66
|
+
|
67
|
+
def test_group_column_entries_preserves_order_of_occurrence
|
68
|
+
table = Table('group', 'a', 'b')
|
69
|
+
[
|
70
|
+
[1, 0, 0],
|
71
|
+
[9, 0, 0],
|
72
|
+
[1, 0, 0],
|
73
|
+
[9, 0, 0],
|
74
|
+
[1, 0, 0],
|
75
|
+
[8, 0, 0],
|
76
|
+
[1, 0, 0]
|
77
|
+
].each {|e| table << e}
|
78
|
+
assert_equal([1,9,8],
|
79
|
+
Ruport::Data::Table::Pivot.
|
80
|
+
new(table, 'group', 'a', 'b').group_column_entries)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_resulting_columns_preserve_ordering_of_rows
|
84
|
+
table = Table('group', 'a', 'b', 'c')
|
85
|
+
[
|
86
|
+
[200, 1, 2, 1],
|
87
|
+
[200, 4, 5, 2],
|
88
|
+
[200, 5, 0, 3],
|
89
|
+
[100, 1, 8, 4],
|
90
|
+
[100, 4,11, 5]
|
91
|
+
].each {|e| table << e}
|
92
|
+
assert_equal(
|
93
|
+
[1,4,5],
|
94
|
+
Ruport::Data::Table::Pivot.new(
|
95
|
+
table, 'group', 'a', 'b', :pivot_order => ['c']
|
96
|
+
).columns_from_pivot)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_preserves_ordering
|
100
|
+
table = Table('group', 'a', 'b', 'c')
|
101
|
+
[
|
102
|
+
[200, 1, 2, 3],
|
103
|
+
[200, 4, 5, 6],
|
104
|
+
[100, 1, 8, 9],
|
105
|
+
[100, 4,11,12]
|
106
|
+
].each {|e| table << e}
|
107
|
+
pivoted = table.pivot('a', :group_by => 'group', :values => 'b')
|
108
|
+
expected = Table("group",1,4) { |t| t << [200,2,5] << [100,8,11] }
|
109
|
+
assert_equal(expected, pivoted)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_preserves_ordering_on_calculated_column
|
113
|
+
table = Table('group', 'a')
|
114
|
+
[
|
115
|
+
[1, 1], [2, 2], [3, 3]
|
116
|
+
].each {|e| table << e}
|
117
|
+
table.add_column('pivotme') {|row| 10 - row.group.to_i}
|
118
|
+
pivoted = table.pivot('pivotme', :group_by => 'group', :values => 'a',
|
119
|
+
:pivot_order => :name)
|
120
|
+
assert_equal(['group', 7, 8, 9], pivoted.column_names)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_preserves_ordering_on_calculated_column_with_proc_pivot_order
|
124
|
+
table = Table('group', 'a')
|
125
|
+
[
|
126
|
+
[1, 1], [2, 2], [3, 3]
|
127
|
+
].each {|e| table << e}
|
128
|
+
table.add_column('pivotme') {|row| 10 - row.group.to_i}
|
129
|
+
pivoted = table.pivot('pivotme', :group_by => 'group', :values => 'a',
|
130
|
+
:pivot_order => proc {|row, pivot| pivot })
|
131
|
+
assert_equal(['group', 7, 8, 9], pivoted.column_names)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
data/test/table_test.rb
ADDED
@@ -0,0 +1,838 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
3
|
+
TEST_SAMPLES = File.join(File.expand_path(File.dirname(__FILE__)), "samples")
|
4
|
+
|
5
|
+
class Person < Ruport::Data::Record
|
6
|
+
|
7
|
+
def name
|
8
|
+
first_name + " " + last_name
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
class DuckRecord < Ruport::Data::Record; end
|
14
|
+
|
15
|
+
class TestTable < Test::Unit::TestCase
|
16
|
+
def test_constructors
|
17
|
+
table = Ruport::Data::Table.new
|
18
|
+
|
19
|
+
table2 = Ruport::Data::Table.new :column_names => %w[a b c]
|
20
|
+
table3 = Ruport::Data::Table.new :data => [[1,2,3]]
|
21
|
+
table4 = Ruport::Data::Table.new :column_names => %w[col1 col2 col3],
|
22
|
+
:data => [[1,2,3]]
|
23
|
+
tables = [table,table2,table3,table4]
|
24
|
+
|
25
|
+
tables.zip([[],%w[a b c], [], %w[col1 col2 col3]]).each do |t,n|
|
26
|
+
assert_equal n, t.column_names
|
27
|
+
|
28
|
+
t = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
29
|
+
table_from_records = Table(t.column_names, :data => t.data)
|
30
|
+
end
|
31
|
+
|
32
|
+
a = Ruport::Data::Record.new [1,2,3]
|
33
|
+
b = Ruport::Data::Record.new [1,2,3], :attributes => %w[col1 col2 col3]
|
34
|
+
tables.zip([[],[],[a],[b]]).each do |t,n|
|
35
|
+
assert_equal n, t.data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when filtering data" do
|
40
|
+
|
41
|
+
def setup
|
42
|
+
@data = [[1,2,3],[4,5,6],[7,8,9]]
|
43
|
+
end
|
44
|
+
|
45
|
+
def specify_filters_should_discard_unmatched_rows
|
46
|
+
table = Ruport::Data::Table.new(:column_names => %w[a b c],
|
47
|
+
:data => [[1,2,3],[4,5,6],[7,8,9]],
|
48
|
+
:filters => [ lambda { |r| r.a % 2 == 1 } ] )
|
49
|
+
assert_equal Table(%w[a b c]) << [1,2,3] << [7,8,9], table
|
50
|
+
end
|
51
|
+
|
52
|
+
def specify_filters_should_work_on_csvs
|
53
|
+
only_ids_less_than_3 = lambda { |r| r["id"].to_i < 3 }
|
54
|
+
table = Table(File.join(TEST_SAMPLES,"addressbook.csv"),
|
55
|
+
:filters => [only_ids_less_than_3])
|
56
|
+
assert_equal ["1","2"], table.map { |r| r["id"] }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when transforming data" do
|
61
|
+
|
62
|
+
def setup
|
63
|
+
@data = [[1,2,3],[4,5,6],[7,8,9]]
|
64
|
+
end
|
65
|
+
|
66
|
+
def specify_transforms_should_modify_table_data
|
67
|
+
|
68
|
+
stringify_c = lambda { |r| r.c = r.c.to_s }
|
69
|
+
add_two_to_all_int_cols = lambda { |r|
|
70
|
+
r.each_with_index do |c,i|
|
71
|
+
if Fixnum === c
|
72
|
+
r[i] += 2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
table = Ruport::Data::Table.new(:column_names => %w[a b c],
|
79
|
+
:data => @data,
|
80
|
+
:transforms => [stringify_c,
|
81
|
+
add_two_to_all_int_cols])
|
82
|
+
assert_equal Table(%w[a b c]) << [3,4,"3"] << [6,7,"6"] << [9,10,"9"],
|
83
|
+
table
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def specify_transforms_should_work_on_csvs
|
88
|
+
ids_to_i = lambda { |r| r["id"] = r["id"].to_i }
|
89
|
+
table = Table(File.join(TEST_SAMPLES,"addressbook.csv"),
|
90
|
+
:filters => [ids_to_i])
|
91
|
+
assert_equal [1,2,3,4,5], table.map { |r| r["id"] }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_to_group
|
96
|
+
a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]]).to_group("Packrats")
|
97
|
+
b = Ruport::Data::Group.new( :data => [[1,2,3],[4,5,6]],
|
98
|
+
:column_names => %w[a b c],
|
99
|
+
:name => "Packrats" )
|
100
|
+
assert_equal a,b
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_rows_with
|
104
|
+
table = Table(%w[a b c], :data => [[1,2,3],[1,3,4],[7,8,9]])
|
105
|
+
|
106
|
+
assert_equal([table[0],table[1]],table.rows_with("a" => 1))
|
107
|
+
assert_equal([table[1]],table.rows_with("a" => 1, "b" => 3))
|
108
|
+
assert_equal([table[0]],table.rows_with(:a => 1, :b => 2))
|
109
|
+
assert_equal([table[2]], table.rows_with_b(8))
|
110
|
+
assert_equal [table[1]], table.rows_with(%w[a b]) { |a,b| [a,b] == [1,3] }
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_sigma
|
114
|
+
table = Table(%w[col1 col2], :data => [[1,2],[3,4],[5,6]])
|
115
|
+
assert table.respond_to?(:sigma)
|
116
|
+
assert table.respond_to?(:sum)
|
117
|
+
assert_equal(9,table.sigma(0))
|
118
|
+
assert_equal(9,table.sigma("col1"))
|
119
|
+
assert_equal(21,table.sigma { |r| r.col1 + r.col2 })
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_sub_table
|
123
|
+
table = Table(%w[a b c d],
|
124
|
+
:data => [ [1,2,3,4],[5,6,7,9],[10,11,12,13],[14,15,16,17] ])
|
125
|
+
|
126
|
+
assert_equal Table(%w[b c], :data => [[6,7],[11,12]]),
|
127
|
+
table.sub_table(%w[b c],1..-2)
|
128
|
+
|
129
|
+
assert_equal Table(%w[c d a], :data => [[3,4,1],[7,9,5]]),
|
130
|
+
table.sub_table(%w[c d a]) { |r| r.a < 10 }
|
131
|
+
|
132
|
+
assert_equal Table(%w[a c], :data => [[1,3],[5,7],[10,12],[14,16]]),
|
133
|
+
table.sub_table(%w[a c])
|
134
|
+
|
135
|
+
assert_equal Table(%w[a b c d], :data => [[10,11,12,13],[14,15,16,17]]),
|
136
|
+
table.sub_table { |r| r.c > 10 }
|
137
|
+
|
138
|
+
assert_equal Table(%w[a b c d], :data => [[10,11,12,13],[14,15,16,17]]),
|
139
|
+
table.sub_table(2..-1)
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_subtable_records_have_correct_data
|
144
|
+
table = Table(%w[a b c d],
|
145
|
+
:data => [ [1,2,3,4],[5,6,7,9],[10,11,12,13],[14,15,16,17] ])
|
146
|
+
sub = table.sub_table(%w[b c d]) {|r| r.a == 1 }
|
147
|
+
assert_equal({"b"=>2, "c"=>3, "d"=>4}, sub[0].data)
|
148
|
+
assert_equal(["b", "c", "d"], sub[0].attributes)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_reduce
|
152
|
+
table = Table(%w[a b c d],
|
153
|
+
:data => [ [1,2,3,4],[5,6,7,9],[10,11,12,13],[14,15,16,17] ])
|
154
|
+
|
155
|
+
table.reduce(%w[b c],1..-2)
|
156
|
+
assert_equal Table(%w[b c], :data => [[6,7],[11,12]]), table
|
157
|
+
|
158
|
+
table = Table(%w[a b c d],
|
159
|
+
:data => [ [1,2,3,4],[5,6,7,9],[10,11,12,13],[14,15,16,17] ])
|
160
|
+
table.reduce(%w[c d a]) { |r| r.a < 10 }
|
161
|
+
|
162
|
+
assert_equal Table(%w[c d a], :data => [[3,4,1],[7,9,5]]), table
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_reorder
|
166
|
+
table = Ruport::Data::Table.load(File.join(TEST_SAMPLES,"data.csv"))
|
167
|
+
table.reorder(*%w[col1 col3])
|
168
|
+
assert_equal %w[col1 col3], table.column_names
|
169
|
+
rows = [%w[a c], %w[d e]]
|
170
|
+
table.each { |r| assert_equal rows.shift, r.to_a
|
171
|
+
assert_equal %w[col1 col3], r.attributes }
|
172
|
+
a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]]).reorder 2,0
|
173
|
+
rows = [[3,1],[6,4]]
|
174
|
+
a.each { |r| assert_equal rows.shift, r.to_a
|
175
|
+
assert_equal %w[c a], r.attributes }
|
176
|
+
assert_equal %w[c a], a.column_names
|
177
|
+
|
178
|
+
b = Table(%w[a b c], :data => [[1,2,3],[4,5,6]]).reorder(%w[a c])
|
179
|
+
rows = [[1,3],[4,6]]
|
180
|
+
b.each { |r|
|
181
|
+
assert_equal rows.shift, r.to_a
|
182
|
+
assert_equal %w[a c], r.attributes
|
183
|
+
assert_equal b.column_names.object_id,
|
184
|
+
r.instance_eval{@attributes}.object_id
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
context "when sorting rows" do
|
189
|
+
|
190
|
+
def setup
|
191
|
+
@table = Table(%w[a b c]) << [1,2,3] << [6,1,8] << [9,1,4]
|
192
|
+
@table_with_nils = Table(%w[a b c]) << [1,nil,3] << [9,3,4] << [6,1,8]
|
193
|
+
end
|
194
|
+
|
195
|
+
def specify_should_sort_in_reverse_order_on_descending
|
196
|
+
t = @table.sort_rows_by("a", :order => :descending )
|
197
|
+
assert_equal Table(%w[a b c]) << [9,1,4] << [6,1,8] << [1,2,3], t
|
198
|
+
|
199
|
+
t = @table.sort_rows_by("c", :order => :descending )
|
200
|
+
assert_equal Table(%w[a b c]) << [6,1,8] << [9,1,4] << [1,2,3], t
|
201
|
+
end
|
202
|
+
|
203
|
+
def specify_show_put_rows_with_nil_columns_after_sorted_rows
|
204
|
+
# should not effect when using columns that are all populated
|
205
|
+
t = @table_with_nils.sort_rows_by("a")
|
206
|
+
assert_equal Table(%w[a b c]) << [1,nil,3] << [6,1,8] << [9,3,4], t
|
207
|
+
|
208
|
+
t = @table_with_nils.sort_rows_by("b")
|
209
|
+
assert_equal Table(%w[a b c]) << [6,1,8] << [9,3,4] << [1,nil,3], t
|
210
|
+
|
211
|
+
t = @table_with_nils.sort_rows_by("b", :order => :descending)
|
212
|
+
assert_equal Table(%w[a b c]) << [1,nil,3] << [9,3,4] << [6,1,8], t
|
213
|
+
end
|
214
|
+
|
215
|
+
def specify_in_place_sort_should_allow_order_by
|
216
|
+
@table.sort_rows_by!("a", :order => :descending )
|
217
|
+
assert_equal Table(%w[a b c]) << [9,1,4] << [6,1,8] << [1,2,3], @table
|
218
|
+
end
|
219
|
+
|
220
|
+
def specify_sort_rows_by
|
221
|
+
table = Ruport::Data::Table.new :column_names => %w[a b c]
|
222
|
+
table << [1,2,3] << [6,1,8] << [9,1,4]
|
223
|
+
|
224
|
+
table2 = Ruport::Data::Table.new :column_names => [:a, :b, :c]
|
225
|
+
table2 << [1,2,3] << [6,1,8] << [9,1,4]
|
226
|
+
|
227
|
+
sorted_table_a = Ruport::Data::Table.new :column_names => %w[a b c]
|
228
|
+
sorted_table_a << [1,2,3] << [6,1,8] << [9,1,4]
|
229
|
+
|
230
|
+
sorted_table_b = Ruport::Data::Table.new :column_names => %w[a b c]
|
231
|
+
sorted_table_b << [6,1,8] << [9,1,4] << [1,2,3]
|
232
|
+
|
233
|
+
sorted_table_bc = Ruport::Data::Table.new :column_names => %w[a b c]
|
234
|
+
sorted_table_bc << [9,1,4] << [6,1,8] << [1,2,3]
|
235
|
+
|
236
|
+
sorted_table_bs = Ruport::Data::Table.new :column_names => [:a, :b, :c]
|
237
|
+
sorted_table_bs << [6,1,8] << [9,1,4] << [1,2,3]
|
238
|
+
|
239
|
+
assert_equal sorted_table_a, table.sort_rows_by {|r| r['a']}
|
240
|
+
assert_equal sorted_table_b, table.sort_rows_by(['b'])
|
241
|
+
assert_equal sorted_table_bc, table.sort_rows_by(['b', 'c'])
|
242
|
+
assert_equal sorted_table_bs, table2.sort_rows_by(:b)
|
243
|
+
end
|
244
|
+
|
245
|
+
def specify_sort_rows_by!
|
246
|
+
table = Ruport::Data::Table.new :column_names => %w[a b c]
|
247
|
+
table << [1,2,3] << [6,1,8] << [9,1,4]
|
248
|
+
|
249
|
+
sorted_table_a = Ruport::Data::Table.new :column_names => %w[a b c]
|
250
|
+
sorted_table_a << [1,2,3] << [6,1,8] << [9,1,4]
|
251
|
+
|
252
|
+
sorted_table_b = Ruport::Data::Table.new :column_names => %w[a b c]
|
253
|
+
sorted_table_b << [6,1,8] << [9,1,4] << [1,2,3]
|
254
|
+
|
255
|
+
sorted_table_bc = Ruport::Data::Table.new :column_names => %w[a b c]
|
256
|
+
sorted_table_bc << [9,1,4] << [6,1,8] << [1,2,3]
|
257
|
+
|
258
|
+
table_a = table.dup
|
259
|
+
table_a.sort_rows_by! { |r| r['a'] }
|
260
|
+
|
261
|
+
table_b = table.dup
|
262
|
+
table_b.sort_rows_by!("b")
|
263
|
+
|
264
|
+
table_bc = table.dup
|
265
|
+
table_bc.sort_rows_by!(['b', 'c'])
|
266
|
+
|
267
|
+
assert_equal sorted_table_a, table_a
|
268
|
+
assert_equal sorted_table_b, table_b
|
269
|
+
assert_equal sorted_table_bc, table_bc
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_record_class
|
275
|
+
a = Ruport::Data::Table.new( :column_names => %w[first_name last_name c],
|
276
|
+
:data =>[['joe','loop',3],['jim','blue',6]],
|
277
|
+
:record_class => Person )
|
278
|
+
assert_equal a, Table(%w[first_name last_name c],
|
279
|
+
:data => [ ['joe','loop',3],['jim','blue',6] ])
|
280
|
+
assert_kind_of Person, a[0]
|
281
|
+
assert_equal 'joe loop', a[0].name
|
282
|
+
assert_equal 'jim blue', a[1].name
|
283
|
+
|
284
|
+
b = Table(%w[first_name last_name], :record_class => Person) do |t|
|
285
|
+
t << { 'first_name' => 'joe', 'last_name' => 'frasier' }
|
286
|
+
t << { 'first_name' => 'brian', 'last_name' => 'black' }
|
287
|
+
end
|
288
|
+
|
289
|
+
b.each { |r| assert_kind_of Person, r }
|
290
|
+
|
291
|
+
assert_equal ['joe frasier', 'brian black'], b.map { |r| r.name }
|
292
|
+
end
|
293
|
+
|
294
|
+
## BUG Traps -------------------------------------------------
|
295
|
+
|
296
|
+
def test_ensure_table_creation_allows_record_coercion
|
297
|
+
table = Table([], :data => [[1,2,3],[4,5,6],[7,8,9]])
|
298
|
+
table_with_names = Table(%w[a b c], :data => [[1,2,3],[4,5,6],[7,8,9]])
|
299
|
+
|
300
|
+
a,b,c = nil
|
301
|
+
assert_nothing_raised { a = Table(%w[a b c], :data => table.to_a) }
|
302
|
+
assert_nothing_raised { b = Table(%w[d e f], :data => table.to_a) }
|
303
|
+
assert_nothing_raised { c = Table(table_with_names.column_names,
|
304
|
+
:data => table_with_names.to_a) }
|
305
|
+
|
306
|
+
[a,b,c].each { |t| assert_equal(3,t.length) }
|
307
|
+
assert_equal %w[a b c], a.column_names
|
308
|
+
a.each { |r|
|
309
|
+
assert_equal %w[a b c], r.attributes
|
310
|
+
assert_nothing_raised { r.a; r.b; r.c }
|
311
|
+
[r.a,r.b,r.c].each { |i| assert(i.kind_of?(Numeric)) }
|
312
|
+
}
|
313
|
+
assert_equal %w[d e f], b.column_names
|
314
|
+
b.each { |r|
|
315
|
+
assert_equal %w[d e f], r.attributes
|
316
|
+
assert_nothing_raised { r.d; r.e; r.f }
|
317
|
+
[r.d,r.e,r.f].each { |i| assert(i.kind_of?(Numeric)) }
|
318
|
+
}
|
319
|
+
c.each { |r|
|
320
|
+
assert_nothing_raised { r[0]; r[1]; r[2] }
|
321
|
+
[r[0],r[1],r[2]].each { |i| assert(i.kind_of?(Numeric)) }
|
322
|
+
}
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_ensure_coerce_sum
|
326
|
+
s = Table([], :data => [["1"],["3"],["5"]])
|
327
|
+
t = Table([], :data => [["1.23"],["1.5"]])
|
328
|
+
|
329
|
+
assert_equal(9,s.sum(0))
|
330
|
+
assert_equal(2.73,t.sum(0))
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_to_yaml
|
334
|
+
require "yaml"
|
335
|
+
a = Table([])
|
336
|
+
assert_nothing_raised { a.to_yaml }
|
337
|
+
a = Table(%w[first_name last_name],:record_class => Person) { |t|
|
338
|
+
t << %w[joe loop]
|
339
|
+
}
|
340
|
+
assert_equal "joe loop", a[0].name
|
341
|
+
assert_nothing_raised { a.to_yaml }
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_ensure_subtable_works_with_unnamed_tables
|
345
|
+
a = Table([], :data => [[1,2,3],[4,5,6]])
|
346
|
+
b = a.sub_table { |r| (r[0] % 2).zero? }
|
347
|
+
assert_equal Table([], :data => [[4,5,6]]), b
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_ensure_appending_records_works_with_unnamed_tables
|
351
|
+
a = Table([], :data => [[1,2,3],[4,5,6]])
|
352
|
+
a << Ruport::Data::Record.new([7,8,9])
|
353
|
+
assert_equal Table([], :data => [[1,2,3],[4,5,6],[7,8,9]]),a
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_ensure_propagate_record_class
|
357
|
+
a = Table(:record_class => DuckRecord)
|
358
|
+
assert_equal DuckRecord, a.record_class
|
359
|
+
|
360
|
+
b = a.dup
|
361
|
+
assert_equal DuckRecord, b.record_class
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_ensure_reorder_raises_on_bad_reorder_use
|
365
|
+
a = Table() << [1,2,3] << [4,5,6]
|
366
|
+
assert_raise(ArgumentError) { a.reorder("a","b","c") }
|
367
|
+
assert_raise(ArgumentError) { a.reorder(%w[a b c]) }
|
368
|
+
assert_raise(ArgumentError) { a.reorder(2,1,0) }
|
369
|
+
end
|
370
|
+
|
371
|
+
class MySubClass < Ruport::Data::Table; end
|
372
|
+
|
373
|
+
def test_ensure_table_subclasses_render_properly
|
374
|
+
a = MySubClass.new
|
375
|
+
a << [1,2,3] << [4,5,6]
|
376
|
+
assert_equal("1,2,3\n4,5,6\n",a.as(:csv))
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
class TestTableAppendOperations < Test::Unit::TestCase
|
382
|
+
def test_append_record
|
383
|
+
table = Ruport::Data::Table.new :column_names => %w[a b c]
|
384
|
+
table << Ruport::Data::Record.new([1,2,3], :attributes => %w[a b c])
|
385
|
+
assert_equal([1,2,3],table[0].to_a)
|
386
|
+
assert_equal(%w[a b c],table[0].attributes)
|
387
|
+
rec = table[0].dup
|
388
|
+
rec.attributes = %w[a b c d]
|
389
|
+
assert_raise(NoMethodError) { table << Object.new }
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_append_hash
|
393
|
+
table = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
394
|
+
table << { "a" => 7, "c" => 9, "b" => 8 }
|
395
|
+
|
396
|
+
assert_equal Table(%w[a b c], :data => [[1,2,3],[4,5,6],[7,8,9]]), table
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_append_table
|
400
|
+
first = Ruport::Data::Table.new :column_names => %w[a b c],
|
401
|
+
:data => [[1,2,3],[4,5,6]]
|
402
|
+
|
403
|
+
second = Ruport::Data::Table.new :column_names => %w[a b c],
|
404
|
+
:data => [[7,8,9],[10,11,12]]
|
405
|
+
|
406
|
+
combo = first + second
|
407
|
+
|
408
|
+
assert_equal Ruport::Data::Table.new(:column_names => %w[a b c],
|
409
|
+
:data => [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]), combo
|
410
|
+
end
|
411
|
+
|
412
|
+
def test_append_chain
|
413
|
+
table = Ruport::Data::Table.new :column_names => %w[a b c]
|
414
|
+
table << [1,2,3] << [4,5,6] << [7,8,9]
|
415
|
+
assert_equal 3, table.length
|
416
|
+
assert_equal 5, table[1].b
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
class TestTableFormattingHooks < Test::Unit::TestCase
|
421
|
+
|
422
|
+
def test_to_hack_takes_args
|
423
|
+
a = Table(%w[hello mr crowley]) << %w[would you like] << %w[one red cat]
|
424
|
+
|
425
|
+
assert_equal "would,you,like\none,red,cat\n",
|
426
|
+
a.to_csv(:show_table_headers => false)
|
427
|
+
|
428
|
+
assert_equal "would,you,like\none,red,cat\n",
|
429
|
+
a.to_csv { |r| r.options.show_table_headers = false }
|
430
|
+
|
431
|
+
assert_equal "would\tyou\tlike\none\tred\tcat\n",
|
432
|
+
a.to_csv(:show_table_headers => false) { |r|
|
433
|
+
r.options.format_options = { :col_sep => "\t" }
|
434
|
+
}
|
435
|
+
end
|
436
|
+
|
437
|
+
def test_to_hack
|
438
|
+
table = Ruport::Data::Table.new :column_names => %w[a b],
|
439
|
+
:data => [[1,2],[3,4],[5,6]]
|
440
|
+
assert_equal("a,b\n1,2\n3,4\n5,6\n",table.to_csv)
|
441
|
+
assert_raises(Ruport::Controller::UnknownFormatError) { table.to_nothing }
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_as_throws_proper_errors
|
445
|
+
a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
446
|
+
assert_nothing_raised { a.as(:csv) }
|
447
|
+
assert_nothing_raised { a.to_csv }
|
448
|
+
assert_raises(Ruport::Controller::UnknownFormatError) { a.as(:nothing) }
|
449
|
+
assert_raises(Ruport::Controller::UnknownFormatError) { a.to_nothing }
|
450
|
+
end
|
451
|
+
|
452
|
+
end
|
453
|
+
|
454
|
+
class TestTableColumnOperations < Test::Unit::TestCase
|
455
|
+
|
456
|
+
def test_column
|
457
|
+
a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
458
|
+
assert_equal [3,6], a.column(2)
|
459
|
+
assert_equal [2,5], a.column("b")
|
460
|
+
|
461
|
+
assert_raise(ArgumentError) { a.column("d") }
|
462
|
+
assert_raise(ArgumentError) { a.column(42) }
|
463
|
+
|
464
|
+
a = Table([], :data => [[1],[2],[3],[4]])
|
465
|
+
assert_equal [1,2,3,4], a.column(0)
|
466
|
+
end
|
467
|
+
|
468
|
+
def test_set_column_names
|
469
|
+
a = Table([], :data => [[1,2,3],[4,5,6]])
|
470
|
+
|
471
|
+
assert_equal([],a.column_names)
|
472
|
+
assert_equal([[1,2,3],[4,5,6]],a.map { |r| r.to_a } )
|
473
|
+
|
474
|
+
a.column_names = %w[a b c]
|
475
|
+
assert_equal(%w[a b c],a.column_names)
|
476
|
+
a.each { |r| assert_equal(%w[a b c], r.attributes) }
|
477
|
+
assert_equal([[1,2,3],[4,5,6]],a.map { |r| r.to_a })
|
478
|
+
|
479
|
+
a.column_names = %w[d e f]
|
480
|
+
assert_equal(%w[d e f],a.column_names)
|
481
|
+
a.each { |r| assert_equal(%w[d e f], r.attributes) }
|
482
|
+
assert_equal([[1,2,3],[4,5,6]],a.map { |r| r.to_a })
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_add_column
|
486
|
+
a = Table(%w[a b], :data => [[1,2],[3,4],[5,6]])
|
487
|
+
a.add_column("c")
|
488
|
+
assert_equal Table(%w[a b c], :data => [[1,2,nil],[3,4,nil],[5,6,nil]]), a
|
489
|
+
|
490
|
+
a = Table(%w[a b], :data => [[1,2],[3,4],[5,6]])
|
491
|
+
a.add_column("c",:default => "x")
|
492
|
+
assert_equal Table(%w[a b c], :data => [[1,2,'x'],[3,4,'x'],[5,6,'x']]), a
|
493
|
+
|
494
|
+
b = a.dup
|
495
|
+
b.add_column("x",:before => "b")
|
496
|
+
assert_equal Table(%w[a x b c],
|
497
|
+
:data => [[1,nil,2,'x'],[3,nil,4,'x'],[5,nil,6,'x']]), b
|
498
|
+
|
499
|
+
b = a.dup
|
500
|
+
b.add_column("x",:after => "b")
|
501
|
+
assert_equal Table(%w[a b x c],
|
502
|
+
:data => [[1,2,nil,'x'],[3,4,nil,'x'],[5,6,nil,'x']]), b
|
503
|
+
|
504
|
+
|
505
|
+
a.add_column("d") { |r| r[0]+r[1] }
|
506
|
+
assert_equal Table(%w[a b c d],
|
507
|
+
:data => [ [1,2,'x',3],[3,4,'x',7],[5,6,'x',11] ]), a
|
508
|
+
|
509
|
+
a.add_column("x",:position => 1)
|
510
|
+
assert_equal Table(%w[a x b c d],
|
511
|
+
:data => [ [1,nil,2,'x',3],[3,nil,4,'x',7],[5,nil,6,'x',11] ]), a
|
512
|
+
end
|
513
|
+
|
514
|
+
def test_add_columns
|
515
|
+
a = Table(%w[a b], :data => [[1,2],[3,4],[5,6]])
|
516
|
+
a.add_columns(%w[c d])
|
517
|
+
expected = Table(%w[a b c d],
|
518
|
+
:data => [ [1,2,nil,nil],[3,4,nil,nil],[5,6,nil,nil] ])
|
519
|
+
|
520
|
+
assert_equal expected, a
|
521
|
+
|
522
|
+
a = Table(%w[a b], :data => [[1,2],[3,4],[5,6]])
|
523
|
+
|
524
|
+
a.add_columns(%w[c d],:after => "a")
|
525
|
+
|
526
|
+
expected = Table(%w[a c d b],
|
527
|
+
:data => [ [1,nil,nil,2],[3,nil,nil,4],[5,nil,nil,6], ])
|
528
|
+
|
529
|
+
assert_equal expected, a
|
530
|
+
|
531
|
+
a.add_columns(%w[x f],:before => "a")
|
532
|
+
|
533
|
+
expected = Table(%w[x f a c d b],
|
534
|
+
:data => [ [nil,nil,1,nil,nil,2],
|
535
|
+
[nil,nil,3,nil,nil,4],
|
536
|
+
[nil,nil,5,nil,nil,6] ])
|
537
|
+
|
538
|
+
assert_equal expected, a
|
539
|
+
|
540
|
+
a = Table(%w[a b c], :data => [[1,2,0],[3,4,0],[5,6,0]])
|
541
|
+
|
542
|
+
a.add_columns(%w[x y],:default => 9, :position => 1)
|
543
|
+
|
544
|
+
expected = Table(%w[a x y b c],
|
545
|
+
:data => [[1,9,9,2,0],[3,9,9,4,0],[5,9,9,6,0]])
|
546
|
+
|
547
|
+
assert_equal expected, a
|
548
|
+
|
549
|
+
a = Table(%w[a b], :data => [[1,2],[3,4],[5,6]])
|
550
|
+
a.add_columns(%w[f x],:default => 0)
|
551
|
+
|
552
|
+
expected = Table(%w[a b f x], :data => [[1,2,0,0],[3,4,0,0],[5,6,0,0]])
|
553
|
+
assert_equal expected, a
|
554
|
+
|
555
|
+
assert_raises(RuntimeError) do
|
556
|
+
a.add_columns(%w[a b]) { }
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_remove_column
|
561
|
+
a = Table(%w[a b c]) { |t| t << [1,2,3] << [4,5,6] }
|
562
|
+
b = a.dup
|
563
|
+
|
564
|
+
a.remove_column("b")
|
565
|
+
assert_equal Table(%w[a c]) { |t| t << [1,3] << [4,6] }, a
|
566
|
+
|
567
|
+
b.remove_column(2)
|
568
|
+
assert_equal Table(%w[a b]) { |t| t << [1,2] << [4,5] }, b
|
569
|
+
end
|
570
|
+
|
571
|
+
def test_remove_columns
|
572
|
+
a = Table(%w[a b c d]) { |t| t << [1,2,3,4] << [5,6,7,8] }
|
573
|
+
b = a.dup
|
574
|
+
a.remove_columns("b","d")
|
575
|
+
assert_equal Table(%w[a c]) { |t| t << [1,3] << [5,7] }, a
|
576
|
+
b.remove_columns(%w[a c])
|
577
|
+
assert_equal Table(%w[b d]) { |t| t << [2,4] << [6,8] }, b
|
578
|
+
end
|
579
|
+
|
580
|
+
def test_rename_column
|
581
|
+
a = Table(%w[a b]) { |t| t << [1,2] << [3,4] }
|
582
|
+
a.rename_column("b","x")
|
583
|
+
assert_equal Table(%w[a x]) { |t| t << [1,2] << [3,4] }, a
|
584
|
+
end
|
585
|
+
|
586
|
+
def test_rename_columns
|
587
|
+
a = Table(%w[a b]) { |t| t << [1,2] << [3,4] }
|
588
|
+
a.rename_columns(%w[a b], %w[x y])
|
589
|
+
assert_equal Table(%w[x y]) { |t| t << [1,2] << [3,4] }, a
|
590
|
+
|
591
|
+
a = Table(%w[a b]) { |t| t << [1,2] << [3,4] }
|
592
|
+
a.rename_columns("a"=>"x","b"=>"y")
|
593
|
+
assert_equal Table(%w[x y]) { |t| t << [1,2] << [3,4] }, a
|
594
|
+
|
595
|
+
a = Table(%w[a b]) { |t| t << [1,2] << [3,4] }
|
596
|
+
assert_raise(ArgumentError) { a.rename_columns(%w[a b], %w[x]) }
|
597
|
+
|
598
|
+
a = Table(%w[a b c]) { |t| t << [1,2,3] << [4,5,6] }
|
599
|
+
a.rename_columns { |r| r.to_sym }
|
600
|
+
assert_equal(a, Table(:a,:b,:c) { |t| t << [1,2,3] << [4,5,6] })
|
601
|
+
|
602
|
+
a = Table(%w[a b c]) { |t| t << [1,2,3] << [4,5,6] }
|
603
|
+
a.rename_columns(%w[a c]) { |r| r.to_sym }
|
604
|
+
assert_equal(a, Table(:a,"b",:c) { |t| t << [1,2,3] << [4,5,6] })
|
605
|
+
end
|
606
|
+
|
607
|
+
def test_swap_column
|
608
|
+
a = Table(%w[a b]) { |t| t << [1,2] << [3,4] }
|
609
|
+
a.swap_column("a","b")
|
610
|
+
assert_equal Table(%w[b a]) { |t| t << [2,1] << [4,3] }, a
|
611
|
+
a.swap_column(1,0)
|
612
|
+
assert_equal Table(%w[a b]) { |t| t << [1,2] << [3,4] }, a
|
613
|
+
end
|
614
|
+
|
615
|
+
def test_replace_column
|
616
|
+
a = Table(%w[a b c]) { |t| t << [1,2,3] << [4,5,6] }
|
617
|
+
a.replace_column("b","d") { |r| r.b.to_s }
|
618
|
+
assert_equal Table(%w[a d c]) { |t| t << [1,"2",3] << [4,"5",6] }, a
|
619
|
+
a.replace_column("d") { |r| r.d.to_i }
|
620
|
+
assert_equal Table(%w[a d c]) { |t| t << [1,2,3] << [4,5,6] }, a
|
621
|
+
end
|
622
|
+
|
623
|
+
# --- BUG TRAPS ------------------------------------
|
624
|
+
|
625
|
+
def test_ensure_setting_column_names_changes_record_attributes
|
626
|
+
table = Ruport::Data::Table.new :column_names => %w[a b c],
|
627
|
+
:data => [[1,2,3],[4,5,6]]
|
628
|
+
|
629
|
+
assert_equal %w[a b c], table.column_names
|
630
|
+
assert_equal %w[a b c], table.data[0].attributes
|
631
|
+
assert_equal %w[a b c], table.data[1].attributes
|
632
|
+
|
633
|
+
table.column_names = %w[d e f]
|
634
|
+
|
635
|
+
assert_equal %w[d e f], table.column_names
|
636
|
+
assert_equal %w[d e f], table.data[0].attributes
|
637
|
+
assert_equal %w[d e f], table.data[1].attributes
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_ensure_setting_column_names_later_does_not_break_replace_column
|
641
|
+
a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
642
|
+
a.replace_column("b","q") { |r| r.a + r.c }
|
643
|
+
a.column_names = %w[d e f]
|
644
|
+
assert_equal Table(%w[d e f], :data => [[1,4,3],[4,10,6]]), a
|
645
|
+
|
646
|
+
a = Table([], :data => [[1,2,3],[4,5,6]])
|
647
|
+
|
648
|
+
a.replace_column(1) { |r| r[0] + r[2] }
|
649
|
+
|
650
|
+
a.column_names = %w[d e f]
|
651
|
+
assert_equal Table(%w[d e f], :data => [[1,4,3],[4,10,6]]), a
|
652
|
+
|
653
|
+
a = Table([], :data => [[1,2,3],[4,5,6]])
|
654
|
+
|
655
|
+
a.replace_column(2) { |r| r[0] + 5 }
|
656
|
+
|
657
|
+
a.column_names = %w[a b c]
|
658
|
+
|
659
|
+
a.replace_column("b") { |r| r.a + 4 }
|
660
|
+
a.replace_column("b","foo") { |r| r.b + 1 }
|
661
|
+
|
662
|
+
assert_equal Table(%w[a foo c], :data => [[1,6,6],[4,9,9]]), a
|
663
|
+
end
|
664
|
+
|
665
|
+
def test_ensure_renaming_a_missing_column_fails_silently
|
666
|
+
a = Table(%w[a b c])
|
667
|
+
assert_nothing_raised do
|
668
|
+
a.rename_column("d", "z")
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
end
|
673
|
+
|
674
|
+
class TestTableFromCSV < Test::Unit::TestCase
|
675
|
+
|
676
|
+
def test_csv_load
|
677
|
+
table = Ruport::Data::Table.load(File.join(TEST_SAMPLES,"data.csv"))
|
678
|
+
assert_equal %w[col1 col2 col3], table.column_names
|
679
|
+
rows = [%w[a b c],["d",nil,"e"]]
|
680
|
+
table.each { |r| assert_equal rows.shift, r.to_a
|
681
|
+
assert_equal %w[col1 col2 col3], r.attributes }
|
682
|
+
expected = Table(%w[a b c], :data => [%w[1 2 3],%w[4 5 6]])
|
683
|
+
|
684
|
+
# ticket:94
|
685
|
+
table = Ruport::Data::Table.load( File.join(TEST_SAMPLES,"data.tsv"),
|
686
|
+
:csv_options => { :col_sep => "\t" } )
|
687
|
+
assert_equal expected, table
|
688
|
+
|
689
|
+
expected = ['c','e']
|
690
|
+
|
691
|
+
table = Ruport::Data::Table.load( File.join(TEST_SAMPLES,"data.csv"),
|
692
|
+
:csv_options => { :headers => true, :header_converters => :symbol }
|
693
|
+
) do |s,r|
|
694
|
+
assert_equal expected.shift, r[:col3]
|
695
|
+
end
|
696
|
+
|
697
|
+
assert_equal [:col1,:col2,:col3], table.column_names
|
698
|
+
|
699
|
+
expected = ['c','e']
|
700
|
+
|
701
|
+
Ruport::Data::Table.load( File.join(TEST_SAMPLES,"data.csv"),
|
702
|
+
:records => true ) do |s,r|
|
703
|
+
assert_equal expected.shift, r.col3
|
704
|
+
assert_kind_of Ruport::Data::Record, r
|
705
|
+
end
|
706
|
+
|
707
|
+
table = Ruport::Data::Table.load( File.join(TEST_SAMPLES, "data.csv"),
|
708
|
+
:has_names => false )
|
709
|
+
assert_equal([],table.column_names)
|
710
|
+
assert_equal(Table([],
|
711
|
+
:data => [%w[col1 col2 col3],%w[a b c],["d",nil,"e"]]), table)
|
712
|
+
end
|
713
|
+
|
714
|
+
# ticket:76
|
715
|
+
def test_parse
|
716
|
+
assert_nothing_raised {
|
717
|
+
Ruport::Data::Table.parse("a,b,c\n1,2,3\n")
|
718
|
+
}
|
719
|
+
|
720
|
+
table = Ruport::Data::Table.parse("a,b,c\n1,2,3\n4,5,6\n")
|
721
|
+
expected = Table(%w[a b c], :data => [%w[1 2 3],%w[4 5 6]])
|
722
|
+
|
723
|
+
table = Ruport::Data::Table.parse( "a\tb\tc\n1\t2\t3\n4\t5\t6\n",
|
724
|
+
:csv_options => { :col_sep => "\t" } )
|
725
|
+
assert_equal expected, table
|
726
|
+
|
727
|
+
table = Ruport::Data::Table.parse( "a,b,c\n1,2,3\n4,5,6\n",
|
728
|
+
:has_names => false)
|
729
|
+
assert_equal([],table.column_names)
|
730
|
+
assert_equal(Table([], :data => [%w[a b c],%w[1 2 3],%w[4 5 6]]), table)
|
731
|
+
end
|
732
|
+
|
733
|
+
def test_csv_block_form
|
734
|
+
expected = [%w[a b],%w[1 2],%w[3 4]]
|
735
|
+
t = Ruport::Data::Table.send(:get_table_from_csv,
|
736
|
+
:parse, "a,b\n1,2\n3,4",
|
737
|
+
:has_names => false) do |s,r|
|
738
|
+
assert_equal expected.shift, r
|
739
|
+
s << r
|
740
|
+
end
|
741
|
+
assert_equal Table([], :data => [%w[a b],%w[1 2],%w[3 4]]), t
|
742
|
+
end
|
743
|
+
|
744
|
+
# - BUG TRAPS --------------------
|
745
|
+
|
746
|
+
def test_ensure_using_csv_block_mode_works
|
747
|
+
expected = [%w[a b],%w[1 2],%w[3 4]]
|
748
|
+
t = Ruport::Data::Table.parse("a,b\n1,2\n3,4",:has_names => false) { |s,r|
|
749
|
+
assert_equal expected.shift, r
|
750
|
+
s << r
|
751
|
+
s << r
|
752
|
+
}
|
753
|
+
assert_equal Table([],
|
754
|
+
:data => [%w[a b],%w[a b],%w[1 2], %w[1 2],%w[3 4],%w[3 4]]), t
|
755
|
+
x = Ruport::Data::Table.load(File.join(TEST_SAMPLES,"data.csv")) { |s,r|
|
756
|
+
assert_kind_of Ruport::Data::Feeder, s
|
757
|
+
assert_kind_of Array, r
|
758
|
+
s << r
|
759
|
+
s << r
|
760
|
+
}
|
761
|
+
assert_equal 4, x.length
|
762
|
+
end
|
763
|
+
|
764
|
+
def test_ensure_csv_loading_accepts_table_options
|
765
|
+
a = Table(File.join(TEST_SAMPLES,"addressbook.csv"),
|
766
|
+
:record_class => DuckRecord)
|
767
|
+
a.each { |r| assert_kind_of(DuckRecord,r) }
|
768
|
+
end
|
769
|
+
|
770
|
+
def test_ensure_table_from_csv_accepts_record_class_in_block_usage
|
771
|
+
a = Table(File.join(TEST_SAMPLES,"addressbook.csv"),
|
772
|
+
:record_class => DuckRecord, :records => true) do |s,r|
|
773
|
+
assert_kind_of(DuckRecord,r)
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
end
|
778
|
+
|
779
|
+
class TestTableKernelHack < Test::Unit::TestCase
|
780
|
+
|
781
|
+
def test_simple
|
782
|
+
assert_equal Ruport::Data::Table.new(:column_names => %w[a b c]),
|
783
|
+
Table(%w[a b c])
|
784
|
+
assert_equal Ruport::Data::Table.new(:column_names => %w[a b c]),
|
785
|
+
Table("a","b","c")
|
786
|
+
assert_equal Ruport::Data::Table.load(
|
787
|
+
File.join(TEST_SAMPLES,"addressbook.csv")),
|
788
|
+
Table(File.join(TEST_SAMPLES,"addressbook.csv"))
|
789
|
+
assert_equal Ruport::Data::Table.load(
|
790
|
+
File.join(TEST_SAMPLES,"addressbook.csv"), :has_names => false),
|
791
|
+
Table(File.join(TEST_SAMPLES,"addressbook.csv"), :has_names => false)
|
792
|
+
Table("a","b","c") do |t|
|
793
|
+
t << [1,2,3]
|
794
|
+
assert_equal(
|
795
|
+
Ruport::Data::Table.new(:column_names => %w[a b c], :data => [[1,2,3]]),
|
796
|
+
t.data
|
797
|
+
)
|
798
|
+
end
|
799
|
+
|
800
|
+
assert_equal Table("a"), Table(%w[a])
|
801
|
+
assert_equal Table(:a), Table([:a])
|
802
|
+
end
|
803
|
+
|
804
|
+
def test_iterators
|
805
|
+
Table(File.join(TEST_SAMPLES,"addressbook.csv")) do |s,r|
|
806
|
+
assert_kind_of(Array,r)
|
807
|
+
assert_kind_of(Ruport::Data::Feeder,s)
|
808
|
+
end
|
809
|
+
|
810
|
+
n = 0
|
811
|
+
|
812
|
+
Table(:string => "a,b,c\n1,2,3\n4,5,6\n") do |s,r|
|
813
|
+
assert_kind_of(Array,r)
|
814
|
+
assert_kind_of(Ruport::Data::Feeder,s)
|
815
|
+
n += 1
|
816
|
+
end
|
817
|
+
|
818
|
+
assert_equal 2, n
|
819
|
+
end
|
820
|
+
|
821
|
+
def test_with_file_arg
|
822
|
+
assert_equal Table(File.join(TEST_SAMPLES,"addressbook.csv")),
|
823
|
+
Table(:file => File.join(TEST_SAMPLES,"addressbook.csv"))
|
824
|
+
end
|
825
|
+
|
826
|
+
def test_with_string_arg
|
827
|
+
csv_string = "id,name\n1,Inky\n2,Blinky\n3,Clyde"
|
828
|
+
|
829
|
+
assert_equal Ruport::Data::Table.parse(csv_string),
|
830
|
+
Table(:string => csv_string)
|
831
|
+
end
|
832
|
+
|
833
|
+
def test_ensure_table_hack_accepts_normal_constructor_args
|
834
|
+
assert_equal Ruport::Data::Table.new(:column_names => %w[a b c]),
|
835
|
+
Table(:column_names => %w[a b c])
|
836
|
+
end
|
837
|
+
|
838
|
+
end
|