ruport 0.4.13 → 0.4.15
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/CHANGELOG +23 -1
- data/Rakefile +1 -1
- data/TODO +0 -4
- data/lib/ruport/data/collection.rb +20 -0
- data/lib/ruport/data/record.rb +81 -0
- data/lib/ruport/data/table.rb +57 -0
- data/lib/ruport/data/taggable.rb +27 -0
- data/lib/ruport/data.rb +1 -0
- data/lib/ruport/data_row.rb +8 -2
- data/lib/ruport/data_set.rb +10 -1
- data/lib/ruport/format/engine.rb +38 -12
- data/lib/ruport/format/plugin.rb +32 -24
- data/lib/ruport/meta_tools.rb +19 -0
- data/lib/ruport/rails/reportable.rb +2 -2
- data/lib/ruport/report.rb +2 -2
- data/lib/ruport.rb +2 -2
- data/test/tc_data_row.rb +8 -0
- data/test/tc_data_set.rb +17 -0
- data/test/tc_format_engine.rb +94 -4
- data/test/tc_record.rb +140 -0
- data/test/tc_table.rb +39 -0
- data/test/tc_taggable.rb +53 -0
- data/test/ts_all.rb +3 -0
- data/test/unit.log +2080 -0
- metadata +12 -2
data/CHANGELOG
CHANGED
@@ -1,4 +1,26 @@
|
|
1
|
-
The current version of Ruby Reports is 0.4.
|
1
|
+
The current version of Ruby Reports is 0.4.15
|
2
|
+
|
3
|
+
changes since 0.4.13
|
4
|
+
|
5
|
+
- Began building a new data handling system, which is much faster than
|
6
|
+
DataSet/DataRow and takes up less memory. It is also very young, though.
|
7
|
+
(See Data::Table and Data::Record)
|
8
|
+
|
9
|
+
- Added init_plugin hooks
|
10
|
+
|
11
|
+
- Added DataSet#rename_columns
|
12
|
+
|
13
|
+
- Added taggable mixin
|
14
|
+
|
15
|
+
- Added an options accessor to help solve ticket #8
|
16
|
+
|
17
|
+
- Alioth now has a powerful hook back into the engine from plugins via helpers
|
18
|
+
|
19
|
+
- added action / attribute methods for format engine / plugin via MetaTools
|
20
|
+
|
21
|
+
- added accessor style methods to DataRow via method_missing
|
22
|
+
|
23
|
+
- added prune method for Table formmatting.
|
2
24
|
|
3
25
|
changes since 0.4.11
|
4
26
|
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
|
22
22
|
spec = Gem::Specification.new do |spec|
|
23
23
|
spec.name = LEAN ? "lean-ruport" : "ruport"
|
24
|
-
spec.version = "0.4.
|
24
|
+
spec.version = "0.4.15"
|
25
25
|
spec.platform = Gem::Platform::RUBY
|
26
26
|
spec.summary = "A generalized Ruby report generation and templating engine."
|
27
27
|
spec.files = Dir.glob("{examples,lib,test}/**/**/*") +
|
data/TODO
CHANGED
@@ -6,8 +6,6 @@ Immediate Goals:
|
|
6
6
|
|
7
7
|
- PDF document support + example
|
8
8
|
|
9
|
-
- event system
|
10
|
-
|
11
9
|
- Composite key selection
|
12
10
|
|
13
11
|
- Value modification predicate.
|
@@ -18,6 +16,4 @@ Immediate Goals:
|
|
18
16
|
|
19
17
|
- Document the inner classes of Format
|
20
18
|
|
21
|
-
- make the Fetchable module to abstract data acquisition
|
22
|
-
|
23
19
|
- Calculated fields
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ruport::Data
|
2
|
+
class Collection
|
3
|
+
require "forwardable"
|
4
|
+
extend Forwardable
|
5
|
+
include Enumerable
|
6
|
+
include Taggable
|
7
|
+
|
8
|
+
def initialize(data=nil,options={})
|
9
|
+
@data = data.dup if data
|
10
|
+
end
|
11
|
+
|
12
|
+
def as(type)
|
13
|
+
Ruport::Format.table :data => self, :plugin => type
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :data
|
17
|
+
def_delegators :@data, :each, :length, :[], :empty?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Ruport::Data
|
2
|
+
class Record
|
3
|
+
require "forwardable"
|
4
|
+
extend Forwardable
|
5
|
+
include Enumerable
|
6
|
+
include Taggable
|
7
|
+
|
8
|
+
def initialize(data,options={})
|
9
|
+
@data = data.dup
|
10
|
+
@attributes = options[:attributes]
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :data
|
14
|
+
def_delegators :@data,:each, :length
|
15
|
+
|
16
|
+
|
17
|
+
def [](index)
|
18
|
+
if index.kind_of? Integer
|
19
|
+
@data[index]
|
20
|
+
else
|
21
|
+
@data[@attributes.index(index)]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def []=(index, value)
|
26
|
+
if index.kind_of? Integer
|
27
|
+
@data[index] = value
|
28
|
+
else
|
29
|
+
@data[attributes.index(index)] = value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def ==(other)
|
34
|
+
return false if attributes && !other.attributes
|
35
|
+
return false if other.attributes && !attributes
|
36
|
+
(attributes == other.attributes) && (data == other.data)
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :eql?, :==
|
40
|
+
|
41
|
+
def to_a; data.dup; end
|
42
|
+
|
43
|
+
def to_h; Hash[*attributes.zip(data).flatten] end
|
44
|
+
|
45
|
+
def attributes; @attributes && @attributes.dup; end
|
46
|
+
|
47
|
+
def attributes=(a); @attributes=a; end
|
48
|
+
|
49
|
+
def reorder(*indices)
|
50
|
+
dup.reorder! *indices
|
51
|
+
end
|
52
|
+
|
53
|
+
def reorder!(*indices)
|
54
|
+
@data = indices.map { |i| self[i] }
|
55
|
+
if attributes
|
56
|
+
if indices.all? { |e| e.kind_of? Integer }
|
57
|
+
@attributes = indices.map { |i| @attributes[i] }
|
58
|
+
else
|
59
|
+
@attributes = indices
|
60
|
+
end
|
61
|
+
end; self
|
62
|
+
end
|
63
|
+
|
64
|
+
def dup
|
65
|
+
self.class.new(data,:attributes => attributes)
|
66
|
+
end
|
67
|
+
|
68
|
+
#FIXME: This does not take into account frozen / tainted state
|
69
|
+
alias_method :clone, :dup
|
70
|
+
|
71
|
+
def method_missing(id,*args)
|
72
|
+
id = id.to_s.gsub(/=$/,"")
|
73
|
+
if @attributes.include?(id)
|
74
|
+
args.empty? ? self[id] : self[id] = args.first
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ruport::Data
|
2
|
+
class Table < Collection
|
3
|
+
def initialize(options={})
|
4
|
+
@column_names = options[:column_names].dup if options[:column_names]
|
5
|
+
@data = []
|
6
|
+
options[:data].each { |e| self << e } if options[:data]
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :column_names
|
10
|
+
|
11
|
+
def column_names=(other)
|
12
|
+
@column_names = other.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
def <<(other)
|
16
|
+
case(other)
|
17
|
+
when Array
|
18
|
+
@data << Record.new(other, :attributes => @column_names)
|
19
|
+
when Hash
|
20
|
+
raise unless @column_names
|
21
|
+
arr = @column_names.map { |k| other[k] }
|
22
|
+
@data << Record.new(arr, :attributes => @column_names)
|
23
|
+
when Record
|
24
|
+
@data << Record.reorder(*column_names)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def reorder!(*indices)
|
29
|
+
@column_names = indices
|
30
|
+
@data.each { |r| r.reorder! *indices }; self
|
31
|
+
end
|
32
|
+
|
33
|
+
def reorder(*indices)
|
34
|
+
dup.reorder! *indices
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.load(csv_file, options = {})
|
38
|
+
options = {:has_names => true}.merge(options)
|
39
|
+
require "fastercsv"
|
40
|
+
loaded_data = self.new
|
41
|
+
|
42
|
+
first_line = true
|
43
|
+
FasterCSV.foreach(csv_file) do |row|
|
44
|
+
if first_line && options[:has_names]
|
45
|
+
loaded_data.column_names = row
|
46
|
+
first_line = false
|
47
|
+
elsif !block_given?
|
48
|
+
loaded_data << row
|
49
|
+
else
|
50
|
+
yield(loaded_data,row)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
return loaded_data
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ruport::Data
|
2
|
+
|
3
|
+
module Taggable
|
4
|
+
|
5
|
+
def tag(tag_name)
|
6
|
+
tags << tag_name unless has_tag? tag_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def delete_tag(tag_name)
|
10
|
+
tags.delete tag_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_tag?(tag_name)
|
14
|
+
tags.include? tag_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def tags
|
18
|
+
@ruport_tags ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def tags=(tags_list)
|
22
|
+
@ruport_tags = tags_list
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/ruport/data.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
%w[taggable record collection table].each { |l| require "ruport/data/#{l}" }
|
data/lib/ruport/data_row.rb
CHANGED
@@ -74,7 +74,7 @@ module Ruport
|
|
74
74
|
|
75
75
|
attr_accessor :fields, :tags
|
76
76
|
alias_method :column_names, :fields
|
77
|
-
|
77
|
+
alias_method :attributes, :fields
|
78
78
|
# Returns a new DataRow
|
79
79
|
def +(other)
|
80
80
|
DataRow.new @fields + other.fields, :data => (@data + other.to_a)
|
@@ -177,5 +177,11 @@ module Ruport
|
|
177
177
|
:status => :fatal, :exception => ArgumentError, :level => :log_only
|
178
178
|
end
|
179
179
|
end
|
180
|
-
|
180
|
+
|
181
|
+
def method_missing(id,*args)
|
182
|
+
f = id.to_s.gsub(/=$/,'')
|
183
|
+
return super unless fields.include?(f)
|
184
|
+
args.empty? ? self[f] : self[f] = args[0]
|
185
|
+
end
|
186
|
+
end
|
181
187
|
end
|
data/lib/ruport/data_set.rb
CHANGED
@@ -234,6 +234,14 @@ module Ruport
|
|
234
234
|
@fields = d.fields
|
235
235
|
end
|
236
236
|
|
237
|
+
def rename_columns(cols)
|
238
|
+
if cols.kind_of?(Array)
|
239
|
+
cols.each_with_index { |c,i| fields[i] = c }
|
240
|
+
else
|
241
|
+
cols.map { |k,v| fields[fields.index(k)] = v }
|
242
|
+
end
|
243
|
+
@data.each { |r| r.fields = fields }
|
244
|
+
end
|
237
245
|
# uses Format::Builder to render DataSets in various ready to output
|
238
246
|
# formats.
|
239
247
|
#
|
@@ -249,7 +257,7 @@ module Ruport
|
|
249
257
|
#
|
250
258
|
# This will enable <tt>data.as(:my_format_name)</tt>
|
251
259
|
def as(format,&action)
|
252
|
-
t = Format.table_object(:data =>
|
260
|
+
t = Format.table_object(:data => self, :plugin => format)
|
253
261
|
action.call(t) if block_given?
|
254
262
|
t.render
|
255
263
|
end
|
@@ -286,6 +294,7 @@ module Ruport
|
|
286
294
|
f.all? { |e| e.kind_of? Integer } &&
|
287
295
|
f.inject([]) { |s,e| s + [@fields[e]] } || f
|
288
296
|
end
|
297
|
+
|
289
298
|
|
290
299
|
end
|
291
300
|
end
|
data/lib/ruport/format/engine.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
module Ruport
|
2
2
|
class Format::Engine
|
3
3
|
require "forwardable"
|
4
|
-
|
5
4
|
class << self
|
6
5
|
|
7
6
|
include Enumerable
|
7
|
+
include MetaTools
|
8
8
|
extend Forwardable
|
9
9
|
|
10
|
-
def_delegator :@data, :each
|
11
|
-
|
12
|
-
def renderer(&block)
|
13
|
-
block = lambda { data } unless block_given?
|
14
|
-
(class << self; self; end).send(:define_method, :render, &block)
|
15
|
-
end
|
16
|
-
|
17
10
|
attr_accessor :engine_klasses
|
18
11
|
attr_reader :plugin
|
19
12
|
attr_reader :data
|
20
13
|
attr_accessor :klass_binding
|
14
|
+
attr_reader :options
|
15
|
+
|
16
|
+
def_delegator :@data, :each
|
17
|
+
private :attribute, :attributes, :singleton, :action
|
18
|
+
|
19
|
+
def renderer(&block)
|
20
|
+
block = lambda { data } unless block_given?
|
21
|
+
singleton.send(:define_method, :render,&block)
|
22
|
+
end
|
21
23
|
|
22
24
|
def alias_engine(klass,name)
|
23
25
|
Format::Engine.engine_klasses ||= {}
|
@@ -28,10 +30,15 @@ module Ruport
|
|
28
30
|
@data = data
|
29
31
|
active_plugin.data = data.dup if active_plugin
|
30
32
|
end
|
33
|
+
|
34
|
+
def options=(opts)
|
35
|
+
@options = opts
|
36
|
+
active_plugin.options = options if active_plugin
|
37
|
+
end
|
31
38
|
|
32
39
|
def active_plugin
|
40
|
+
return yield(@format_plugins[:current]) if block_given?
|
33
41
|
@format_plugins[:current]
|
34
|
-
#plugin && @format_plugins[plugin]
|
35
42
|
end
|
36
43
|
|
37
44
|
def plugin=(p)
|
@@ -49,6 +56,9 @@ module Ruport
|
|
49
56
|
raise "No plugin specified" unless plugin
|
50
57
|
raise "No data provided" unless data
|
51
58
|
active_plugin.data = data.dup
|
59
|
+
if active_plugin.respond_to? :init_plugin_helper
|
60
|
+
active_plugin.init_plugin_helper(self)
|
61
|
+
end
|
52
62
|
end
|
53
63
|
|
54
64
|
def flush_data
|
@@ -73,6 +83,11 @@ module Ruport
|
|
73
83
|
format_plugins.values
|
74
84
|
end
|
75
85
|
|
86
|
+
def method_missing(id)
|
87
|
+
super unless active_plugin.respond_to?("#{id}_helper")
|
88
|
+
return active_plugin.send("#{id}_helper",self)
|
89
|
+
end
|
90
|
+
|
76
91
|
end
|
77
92
|
end
|
78
93
|
|
@@ -81,8 +96,8 @@ module Ruport
|
|
81
96
|
renderer do
|
82
97
|
super
|
83
98
|
active_plugin.rendered_field_names = ""
|
84
|
-
build_field_names if (data.respond_to?(:
|
85
|
-
data.
|
99
|
+
build_field_names if (data.respond_to?(:column_names) &&
|
100
|
+
data.column_names && show_field_names)
|
86
101
|
a = active_plugin.render_table
|
87
102
|
end
|
88
103
|
|
@@ -96,6 +111,17 @@ module Ruport
|
|
96
111
|
data[0].to_a.length
|
97
112
|
end
|
98
113
|
|
114
|
+
def prune(limit=data[0].length)
|
115
|
+
(0...limit).each do |field|
|
116
|
+
last = ""
|
117
|
+
data.each_with_index { |e,i|
|
118
|
+
next if i.zero? || field.nonzero? && data[i][field-1]
|
119
|
+
last = data[i-1][field] if data[i-1][field]
|
120
|
+
data[i][field] = nil if e[field] == last
|
121
|
+
}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
99
125
|
attr_accessor :show_field_names
|
100
126
|
|
101
127
|
private
|
@@ -105,7 +131,7 @@ module Ruport
|
|
105
131
|
active_plugin.rendered_field_names = active_plugin.build_field_names
|
106
132
|
end
|
107
133
|
end
|
108
|
-
|
134
|
+
|
109
135
|
end
|
110
136
|
|
111
137
|
alias_engine Table, :table_engine
|
data/lib/ruport/format/plugin.rb
CHANGED
@@ -4,10 +4,17 @@ module Ruport
|
|
4
4
|
class << self
|
5
5
|
|
6
6
|
attr_accessor :data
|
7
|
+
attr_accessor :options
|
8
|
+
|
9
|
+
include MetaTools
|
7
10
|
|
8
|
-
def
|
9
|
-
|
11
|
+
def helper(name,&block)
|
12
|
+
singleton.send( :define_method, "#{name}_helper", &block )
|
10
13
|
end
|
14
|
+
|
15
|
+
private :singleton, :attribute, :attributes, :action
|
16
|
+
|
17
|
+
def plugin_name(name=nil); @name ||= name; end
|
11
18
|
|
12
19
|
def format_name
|
13
20
|
pattern = /Ruport::Format|Plugin/
|
@@ -18,11 +25,11 @@ module Ruport
|
|
18
25
|
def renderer(render_type,&block)
|
19
26
|
m = "render_#{render_type}".to_sym
|
20
27
|
block = lambda { data } unless block_given?
|
21
|
-
|
28
|
+
singleton.send(:define_method, m, &block)
|
22
29
|
end
|
23
30
|
|
24
31
|
def format_field_names(&block)
|
25
|
-
|
32
|
+
singleton.send( :define_method, :build_field_names, &block)
|
26
33
|
end
|
27
34
|
|
28
35
|
def register_on(klass)
|
@@ -39,7 +46,7 @@ module Ruport
|
|
39
46
|
@options.merge!(hash)
|
40
47
|
@options.dup
|
41
48
|
end
|
42
|
-
|
49
|
+
|
43
50
|
attr_accessor :rendered_field_names
|
44
51
|
attr_accessor :pre, :post
|
45
52
|
attr_accessor :header, :footer
|
@@ -47,14 +54,14 @@ module Ruport
|
|
47
54
|
|
48
55
|
|
49
56
|
class CSVPlugin < Format::Plugin
|
50
|
-
|
57
|
+
|
58
|
+
helper(:init_plugin) { require "fastercsv" }
|
59
|
+
|
51
60
|
format_field_names do
|
52
|
-
|
53
|
-
FasterCSV.generate { |csv| csv << data.fields }
|
61
|
+
FasterCSV.generate { |csv| csv << data.column_names }
|
54
62
|
end
|
55
63
|
|
56
64
|
renderer :table do
|
57
|
-
require "fastercsv"
|
58
65
|
rendered_field_names +
|
59
66
|
FasterCSV.generate { |csv| data.each { |r| csv << r } }
|
60
67
|
end
|
@@ -78,7 +85,7 @@ module Ruport
|
|
78
85
|
}
|
79
86
|
}
|
80
87
|
|
81
|
-
a = data.inject(th){ |s,r|
|
88
|
+
a = data.inject(th){ |s,r|
|
82
89
|
s + "| #{r.to_a.join(' | ')} |\n"
|
83
90
|
} << hr
|
84
91
|
|
@@ -88,39 +95,40 @@ module Ruport
|
|
88
95
|
r.gsub!(/\A.{#{width},}/) { |m| m[0,width-2] += ">>" }
|
89
96
|
}.join("\n") << "\n"
|
90
97
|
end
|
98
|
+
|
91
99
|
format_field_names do
|
92
|
-
data.
|
93
|
-
data.
|
100
|
+
data.column_names.each_with_index { |f,i|
|
101
|
+
data.column_names[i] = f.to_s.center(max_col_width(i))
|
94
102
|
}
|
95
|
-
"#{hr}| #{data.
|
103
|
+
"#{hr}| #{data.column_names.to_a.join(' | ')} |\n"
|
96
104
|
end
|
97
105
|
|
98
|
-
|
99
|
-
f = data.
|
106
|
+
action :max_col_width do |index|
|
107
|
+
f = data.column_names if data.respond_to? :column_names
|
100
108
|
d = DataSet.new f, :data => data
|
101
109
|
|
102
110
|
cw = d.map { |r| r[index].to_s.length }.max
|
103
111
|
|
104
|
-
return cw unless d.
|
112
|
+
return cw unless d.column_names
|
105
113
|
|
106
|
-
nw = (index.kind_of?(Integer) ? d.
|
114
|
+
nw = (index.kind_of?(Integer) ? d.column_names[index] : index ).to_s.length
|
107
115
|
|
108
116
|
[cw,nw].max
|
109
117
|
end
|
110
118
|
|
111
|
-
|
112
|
-
f = data.
|
119
|
+
action :table_width do
|
120
|
+
f = data.column_names if data.respond_to? :column_names
|
113
121
|
d = DataSet.new f, :data => data
|
114
122
|
|
115
|
-
d[0].
|
123
|
+
d[0].attributes.inject(0) { |s,e| s + max_col_width(e) }
|
116
124
|
end
|
117
125
|
|
118
|
-
|
126
|
+
action :hr do
|
119
127
|
len = data[0].to_a.length * 3 + table_width + 1
|
120
128
|
"+" + "-"*(len-2) + "+\n"
|
121
129
|
end
|
122
130
|
|
123
|
-
|
131
|
+
attribute :right_margin
|
124
132
|
|
125
133
|
register_on :table_engine
|
126
134
|
register_on :document_engine
|
@@ -145,7 +153,7 @@ module Ruport
|
|
145
153
|
pdf.render
|
146
154
|
end
|
147
155
|
|
148
|
-
format_field_names { data.
|
156
|
+
format_field_names { data.column_names }
|
149
157
|
|
150
158
|
register_on :table_engine
|
151
159
|
end
|
@@ -165,7 +173,7 @@ module Ruport
|
|
165
173
|
end
|
166
174
|
|
167
175
|
format_field_names do
|
168
|
-
s = "|_." + data.
|
176
|
+
s = "|_." + data.column_names.join(" |_.") + "|\n"
|
169
177
|
end
|
170
178
|
|
171
179
|
register_on :table_engine
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ruport
|
2
|
+
module MetaTools
|
3
|
+
def singleton; (class << self; self; end); end
|
4
|
+
|
5
|
+
def attribute(sym,value = nil)
|
6
|
+
singleton.send(:attr_accessor, sym )
|
7
|
+
self.send("#{sym}=",value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def attributes(syms)
|
11
|
+
syms.each { |s| attribute s }
|
12
|
+
end
|
13
|
+
|
14
|
+
def action(name,&block)
|
15
|
+
singleton.send(:define_method, name, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Ruport
|
2
2
|
module Reportable
|
3
|
-
def formatted_table(type,options={}
|
3
|
+
def formatted_table(type,options={})
|
4
4
|
to_ds(:find => options[:find],:columns => options[:columns]).as(type){ |e|
|
5
|
-
|
5
|
+
yield(e) if block_given?
|
6
6
|
}
|
7
7
|
end
|
8
8
|
def to_ds(options={})
|
data/lib/ruport/report.rb
CHANGED
@@ -137,7 +137,7 @@ module Ruport
|
|
137
137
|
# result = query "select * from foo", :as => :pdf
|
138
138
|
#
|
139
139
|
# See source of this function and methods of Ruport::Query for details.
|
140
|
-
def query(sql, options={}
|
140
|
+
def query(sql, options={})
|
141
141
|
options[:origin] ||= :string
|
142
142
|
options[:source] ||= @source
|
143
143
|
|
@@ -147,7 +147,7 @@ module Ruport
|
|
147
147
|
elsif options[:as]
|
148
148
|
Format.table :data => q.result, :plugin => options[:as]
|
149
149
|
else
|
150
|
-
block_given? ?
|
150
|
+
block_given? ? yield(q.result) : q.result
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
data/lib/ruport.rb
CHANGED
@@ -14,7 +14,7 @@ module Ruport
|
|
14
14
|
|
15
15
|
begin; require 'rubygems'; rescue LoadError; nil end
|
16
16
|
|
17
|
-
VERSION = "Ruby Reports Version 0.4.
|
17
|
+
VERSION = "Ruby Reports Version 0.4.15"
|
18
18
|
|
19
19
|
# Ruports logging and error interface.
|
20
20
|
# Can generate warnings or raise fatal errors
|
@@ -57,6 +57,6 @@ module Ruport
|
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
|
-
%w[config report format query data_row data_set].each { |lib|
|
60
|
+
%w[config meta_tools report format query data_row data_set data].each { |lib|
|
61
61
|
require "ruport/#{lib}"
|
62
62
|
}
|
data/test/tc_data_row.rb
CHANGED
@@ -21,6 +21,14 @@ class TestDataRow < Test::Unit::TestCase
|
|
21
21
|
assert_equal("[1,2]",@rows[0].to_s)
|
22
22
|
end
|
23
23
|
|
24
|
+
def test_accessor_style
|
25
|
+
row = @rows[0]
|
26
|
+
assert_equal 1, row.foo
|
27
|
+
assert_equal 2, row.bar
|
28
|
+
row.bar = 17
|
29
|
+
assert_equal [1,17], row.to_a
|
30
|
+
end
|
31
|
+
|
24
32
|
def test_tagging
|
25
33
|
@rows[0].tag_as :foo
|
26
34
|
assert_equal(true, @rows[0].has_tag?(:foo) )
|
data/test/tc_data_set.rb
CHANGED
@@ -46,6 +46,23 @@ class TestDataSet < Test::Unit::TestCase
|
|
46
46
|
@data[2].to_a )
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_rename_columns
|
50
|
+
@data.rename_columns "col1" => "Column 1",
|
51
|
+
"col2" => "Column 2",
|
52
|
+
"col3" => "Column 3"
|
53
|
+
assert_equal %w[Column\ 1 Column\ 2 Column\ 3], @data.fields
|
54
|
+
@data.each do |r|
|
55
|
+
assert_equal %w[Column\ 1 Column\ 2 Column\ 3], r.fields
|
56
|
+
end
|
57
|
+
assert_equal "b", @data[0]["Column 2"]
|
58
|
+
assert_equal "e", @data[1]["Column 3"]
|
59
|
+
@data.rename_columns %w[one two three]
|
60
|
+
assert_equal %w[one two three], @data.fields
|
61
|
+
@data.each do |r|
|
62
|
+
assert_equal %w[one two three], r.fields
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
49
66
|
def test_delete_if
|
50
67
|
@data.delete_if { |r| r.any? { |e| e.empty? } }
|
51
68
|
assert_equal([%w[a b c]],@data.to_a)
|