ruport 0.4.4 → 0.4.5
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 +7 -0
- data/CHANGELOG +24 -1
- data/Rakefile +1 -1
- data/TODO +2 -5
- data/lib/ruport.rb +1 -1
- data/lib/ruport/data_row.rb +21 -23
- data/lib/ruport/data_set.rb +114 -80
- data/lib/ruport/format.rb +4 -11
- data/lib/ruport/format/engine.rb +1 -0
- data/lib/ruport/format/plugin.rb +8 -2
- data/test/tc_builder.rb +1 -1
- data/test/tc_data_row.rb +16 -16
- data/test/tc_data_set.rb +125 -28
- data/test/tc_data_set.rb~ +326 -0
- metadata +5 -5
- data/test/unit.log +0 -8
data/AUTHORS
CHANGED
data/CHANGELOG
CHANGED
@@ -1,4 +1,27 @@
|
|
1
|
-
The current version of Ruby Reports is 0.4.
|
1
|
+
The current version of Ruby Reports is 0.4.5 (Developmental)
|
2
|
+
|
3
|
+
changes since 0.4.4:
|
4
|
+
|
5
|
+
- DataRow constructor now matches DataSet style.
|
6
|
+
|
7
|
+
- DataSet picked up a ton of array-like functionality
|
8
|
+
|
9
|
+
- DataSet#load now optionally accepts a block that acts something
|
10
|
+
like inject.
|
11
|
+
|
12
|
+
- Added a DataSet#select_columns!() method
|
13
|
+
|
14
|
+
- What the heck was Format#filter_ruby? It's gone now
|
15
|
+
|
16
|
+
- DataSet#as() now hooked to the new formatting system.
|
17
|
+
note API breakage in block forms
|
18
|
+
|
19
|
+
- DataSet set operations (DF)
|
20
|
+
|
21
|
+
- Much smarter DataSet#<< (Dudley Flanders)
|
22
|
+
|
23
|
+
- Ruport now has pseudo keyword support in DataSets.
|
24
|
+
(Thanks to Dudley Flanders!)
|
2
25
|
|
3
26
|
changes since 0.4.2:
|
4
27
|
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
|
22
22
|
spec = Gem::Specification.new do |spec|
|
23
23
|
spec.name = LEAN ? "ruport-lean" : "ruport"
|
24
|
-
spec.version = "0.4.
|
24
|
+
spec.version = "0.4.5"
|
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
@@ -21,19 +21,16 @@ Immediate Goals:
|
|
21
21
|
|
22
22
|
- Value modification predicate.
|
23
23
|
DataRow#set_value_if("my_value") { # my_condition }
|
24
|
-
|
24
|
+
(Update: What was I talking about here???)
|
25
|
+
|
25
26
|
- Column based default values
|
26
27
|
|
27
28
|
- Integrate Ruport::Parser into Report#parse and Format#parser
|
28
29
|
|
29
30
|
- Document the inner classes of Format
|
30
31
|
|
31
|
-
- Get unit tests up to 100% coverage
|
32
|
-
|
33
32
|
- make the Fetchable module to abstract data acquisition
|
34
33
|
|
35
|
-
- DataSet subclasses Array
|
36
|
-
|
37
34
|
- Calculated fields
|
38
35
|
|
39
36
|
Other High Priority Goals:
|
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.5 (Developmental)"
|
18
18
|
|
19
19
|
# Ruports logging and error interface.
|
20
20
|
# Can generate warnings or raise fatal errors
|
data/lib/ruport/data_row.rb
CHANGED
@@ -12,8 +12,8 @@
|
|
12
12
|
# ++
|
13
13
|
module Ruport
|
14
14
|
|
15
|
-
# DataRows are Enumerable lists which can be accessed by field name or
|
16
|
-
# position.
|
15
|
+
# DataRows are Enumerable lists which can be accessed by field name or
|
16
|
+
# ordinal position.
|
17
17
|
#
|
18
18
|
# They feature a tagging system, allowing them to be easily
|
19
19
|
# compared or recalled.
|
@@ -24,38 +24,37 @@ module Ruport
|
|
24
24
|
|
25
25
|
include Enumerable
|
26
26
|
|
27
|
-
# Takes
|
27
|
+
# Takes field names as well as some optional parameters and
|
28
28
|
# constructs a DataRow.
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# <tt>data</tt> can be specified in Hash, Array, or DataRow form
|
32
29
|
#
|
33
30
|
# Options:
|
34
|
-
# <tt>:
|
35
|
-
# <tt>:
|
31
|
+
# <tt>:data</tt>:: can be specified in Hash, Array, or DataRow form
|
32
|
+
# <tt>:default</tt>:: The default value for empty fields
|
33
|
+
# <tt>:tags</tt>:: an initial set of tags for the row
|
36
34
|
#
|
37
35
|
#
|
38
36
|
# Examples:
|
39
|
-
# >> Ruport::DataRow.new [
|
37
|
+
# >> Ruport::DataRow.new [:a,:b,:c,:d,:e], :data => [1,2,3,4,5]
|
40
38
|
# :tags => %w[cat dog]
|
41
39
|
# => #<Ruport::DataRow:0xb77e4b04 @fields=[:a, :b, :c, :d, :e],
|
42
40
|
# @data=[1, 2, 3, 4, 5], @tags=["cat", "dog"]>
|
43
41
|
#
|
44
|
-
# >> Ruport::DataRow.new(
|
42
|
+
# >> Ruport::DataRow.new([:a,:b,:c,:d,:e],
|
43
|
+
# :data => { :a => 'moo', :c => 'caw'} ,
|
45
44
|
# :tags => %w[cat dog])
|
46
45
|
# => #<Ruport::DataRow:0xb77c298c @fields=[:a, :b, :c, :d, :e],
|
47
46
|
# @data=["moo", nil, "caw", nil, nil], @tags=["cat", "dog"]>
|
48
47
|
#
|
49
|
-
# >> Ruport::DataRow.new [
|
50
|
-
# :
|
48
|
+
# >> Ruport::DataRow.new [:a,:b,:c,:d,:e], :data => [1,2,3],
|
49
|
+
# :tags => %w[cat dog], :default => 0
|
51
50
|
# => #<Ruport::DataRow:0xb77bb4d4 @fields=[:a, :b, :c, :d, :e],
|
52
51
|
# @data=[1, 2, 3, 0, 0], @tags=["cat", "dog"]>
|
53
52
|
#
|
54
|
-
def initialize(
|
53
|
+
def initialize(fields, options={})
|
55
54
|
|
56
55
|
#checks to ensure data is convertable
|
57
|
-
verify data
|
58
|
-
data = data.dup
|
56
|
+
verify options[:data]
|
57
|
+
data = options[:data].dup
|
59
58
|
|
60
59
|
@fields = fields.dup
|
61
60
|
@tags = (options[:tags] || {}).dup
|
@@ -63,22 +62,21 @@ module Ruport
|
|
63
62
|
|
64
63
|
nr_action = case(data)
|
65
64
|
when Array
|
66
|
-
lambda {
|
65
|
+
lambda {|key, index| @data[index] = data.shift || options[:default]}
|
67
66
|
when DataRow
|
68
|
-
lambda {
|
67
|
+
lambda {|key, index| @data = data.to_a}
|
69
68
|
else
|
70
|
-
lambda {
|
69
|
+
lambda {|key, index| @data[index] = data[key] || options[:default]}
|
71
70
|
end
|
72
|
-
@fields.each_with_index {
|
71
|
+
@fields.each_with_index {|key, index| nr_action.call(key,index)}
|
73
72
|
end
|
74
73
|
|
75
74
|
|
76
75
|
attr_accessor :fields, :tags
|
77
76
|
|
78
|
-
# Returns
|
79
|
-
# Loses field information.
|
77
|
+
# Returns a new DataRow
|
80
78
|
def +(other)
|
81
|
-
DataRow.new @
|
79
|
+
DataRow.new @fields + other.fields, :data => (@data + other.to_a)
|
82
80
|
end
|
83
81
|
|
84
82
|
# Lets you access individual fields
|
@@ -164,7 +162,7 @@ module Ruport
|
|
164
162
|
end
|
165
163
|
|
166
164
|
def clone
|
167
|
-
self.class.new @
|
165
|
+
self.class.new @fields, :data => @data, :tags => @tags
|
168
166
|
end
|
169
167
|
|
170
168
|
alias_method :dup, :clone
|
data/lib/ruport/data_set.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# data_set.rb : Ruby Reports core datastructure.
|
2
2
|
#
|
3
3
|
# Author: Gregory T. Brown (gregory.t.brown at gmail dot com)
|
4
|
-
#
|
5
4
|
# Copyright (c) 2006, All Rights Reserved.
|
6
5
|
#
|
6
|
+
# Pseudo keyword argument support, improved <<, and set operations submitted by
|
7
|
+
# Dudley Flanders
|
8
|
+
#
|
7
9
|
# This is free software. You may modify and redistribute this freely under
|
8
10
|
# your choice of the GNU General Public License or the Ruby License.
|
9
11
|
#
|
@@ -15,42 +17,12 @@ module Ruport
|
|
15
17
|
# and user-defined sets of data.
|
16
18
|
#
|
17
19
|
# It is tightly integrated with Ruport's formatting and query systems, so if
|
18
|
-
# you'd like to take advantage of these models, you will probably find
|
19
|
-
# useful.
|
20
|
-
#
|
21
|
-
# Sample Usage:
|
22
|
-
#
|
23
|
-
# my_data = [[1,2,3],[4,5,6],[7,8,9]]
|
24
|
-
#
|
25
|
-
# ds = Ruport::DataSet.new([:col1, :col2, :col3],my_data)
|
26
|
-
# ds << [ 10, 11, 12]
|
27
|
-
# ds << { :col3 => 15, :col1 => 13, :col2 => 14 }
|
28
|
-
# puts ds.select_columns(:col1, :col3).to_csv
|
29
|
-
#
|
30
|
-
# Output:
|
31
|
-
#
|
32
|
-
# col1,col3
|
33
|
-
# 1,3
|
34
|
-
# 4,6
|
35
|
-
# 7,9
|
36
|
-
# 10,12
|
37
|
-
# 13,15
|
38
|
-
#
|
39
|
-
# The wild and crazy might want to try the Array hack:
|
40
|
-
#
|
41
|
-
# puts [[1,2,3],[4,5,6],[7,8,9]].to_ds(%w[col1 col2 col3])
|
42
|
-
#
|
43
|
-
# Output:
|
44
|
-
#
|
45
|
-
# fields: ( col1, col2, col3 )
|
46
|
-
# row0: ( 1, 2, 3 )
|
47
|
-
# row1: ( 4, 5, 6 )
|
48
|
-
# row2: ( 7, 8, 9 )
|
49
|
-
#
|
20
|
+
# you'd like to take advantage of these models, you will probably find
|
21
|
+
# DataSet useful.
|
50
22
|
class DataSet
|
51
23
|
#FIXME: Add logging to this class
|
52
24
|
include Enumerable
|
53
|
-
|
25
|
+
extend Forwardable
|
54
26
|
# DataSets must be given a set of fields to be defined.
|
55
27
|
#
|
56
28
|
# These field names will define the columns for the DataSet and how you
|
@@ -58,17 +30,19 @@ module Ruport
|
|
58
30
|
#
|
59
31
|
# data = Ruport::DataSet.new %w[ id name phone ]
|
60
32
|
#
|
61
|
-
#
|
33
|
+
# Options:
|
34
|
+
# * <tt>:data</tt> - An Enumerable with the content for this DataSet
|
35
|
+
# * <tt>:default</tt> - The default value for empty cells
|
62
36
|
#
|
63
|
-
# content = [ %w[ a1 gregory 203-525-0523 ],
|
64
|
-
# %w[ a2 james 555-555-5555 ] ]
|
65
37
|
#
|
66
|
-
#
|
67
|
-
|
38
|
+
# DataSet supports the following Array methods through delegators
|
39
|
+
# length, empty?, delete_at, first, last, pop
|
40
|
+
#
|
41
|
+
def initialize(fields=[], options={})
|
68
42
|
@fields = fields
|
43
|
+
@default = options[:default] || default
|
69
44
|
@data = []
|
70
|
-
|
71
|
-
content.each { |r| self << r } if content
|
45
|
+
options[:data].each { |r| self << r } if options[:data]
|
72
46
|
end
|
73
47
|
|
74
48
|
#an array which contains column names
|
@@ -79,35 +53,59 @@ module Ruport
|
|
79
53
|
|
80
54
|
#data holds the elements of the Row
|
81
55
|
attr_reader :data
|
82
|
-
|
56
|
+
|
57
|
+
def_delegators :@data, :length, :[], :empty?,
|
58
|
+
:delete_at, :first, :last, :pop,
|
59
|
+
:each, :reverse_each, :at, :clear
|
60
|
+
|
61
|
+
def delete_if(&block)
|
62
|
+
@data.delete_if █ self
|
63
|
+
end
|
64
|
+
|
83
65
|
#provides a deep copy of the DataSet.
|
84
66
|
def clone
|
85
|
-
|
67
|
+
self.class.new(@fields, :data => @data)
|
86
68
|
end
|
87
69
|
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
def [](index)
|
92
|
-
@data[index]
|
70
|
+
# Creates a new DataSet with the same shape as this one, but empty.
|
71
|
+
def empty_clone
|
72
|
+
self.class.new(@fields)
|
93
73
|
end
|
94
|
-
|
95
|
-
#allows setting of rows
|
74
|
+
|
75
|
+
#allows setting of rows
|
96
76
|
def []=(index,data)
|
97
|
-
@data[index] = DataRow.new
|
77
|
+
@data[index] = DataRow.new @fields, :data => data
|
78
|
+
end
|
79
|
+
|
80
|
+
def [](index)
|
81
|
+
case(index)
|
82
|
+
when Range
|
83
|
+
self.class.new @fields, :data => @data[index]
|
84
|
+
else
|
85
|
+
@data[index]
|
86
|
+
end
|
98
87
|
end
|
99
88
|
|
100
|
-
#
|
101
|
-
#
|
89
|
+
# Appends a row to the DataSet
|
90
|
+
# Can be added as an array, an array of DataRows, a DataRow, or a keyed
|
91
|
+
# hash-like object.
|
102
92
|
#
|
103
93
|
# Columns left undefined will be filled with DataSet#default values.
|
104
94
|
#
|
105
95
|
# data << [ 1, 2, 3 ]
|
106
96
|
# data << { :some_field_name => 3, :other => 2, :another => 1 }
|
107
97
|
def << ( stuff, filler=@default )
|
108
|
-
|
98
|
+
if stuff.kind_of?(DataRow)
|
99
|
+
@data << stuff
|
100
|
+
elsif stuff.kind_of?(Array) && stuff[0].kind_of?(DataRow)
|
101
|
+
@data.concat(stuff)
|
102
|
+
else
|
103
|
+
@data << DataRow.new(@fields, :data => stuff,:default => filler)
|
104
|
+
end
|
105
|
+
return self
|
109
106
|
end
|
110
|
-
|
107
|
+
alias_method :push, :<<
|
108
|
+
|
111
109
|
# checks if one dataset equals another
|
112
110
|
# FIXME: expand this doc.
|
113
111
|
def eql?(data2)
|
@@ -127,10 +125,38 @@ module Ruport
|
|
127
125
|
eql?(data2)
|
128
126
|
end
|
129
127
|
|
130
|
-
#
|
131
|
-
|
132
|
-
|
128
|
+
# Set union - returns a DataSet with the elements that are contained in
|
129
|
+
# in either of the two given sets, with no duplicates.
|
130
|
+
def |(other)
|
131
|
+
clone << other.reject { |x| self.include? x }
|
132
|
+
end
|
133
|
+
alias_method :union, :|
|
134
|
+
|
135
|
+
# Set intersection
|
136
|
+
def &(other)
|
137
|
+
empty_clone << select { |x| other.include? x }
|
138
|
+
end
|
139
|
+
alias_method :intersection, :&
|
140
|
+
|
141
|
+
# Set difference
|
142
|
+
def -(other)
|
143
|
+
empty_clone << reject { |x| other.include? x }
|
144
|
+
end
|
145
|
+
alias_method :difference, :-
|
146
|
+
|
147
|
+
# Checks if one DataSet has the same set of fields as another
|
148
|
+
def shaped_like?(other)
|
149
|
+
return true if @fields.eql?(other.fields)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Concatenates one DataSet onto another if they have the same shape
|
153
|
+
def concat(other)
|
154
|
+
if other.shaped_like?(self)
|
155
|
+
@data.concat(other.data)
|
156
|
+
return self
|
157
|
+
end
|
133
158
|
end
|
159
|
+
alias_method :+, :concat
|
134
160
|
|
135
161
|
# Allows loading of CSV files or YAML dumps. Returns a DataSet
|
136
162
|
#
|
@@ -139,34 +165,44 @@ module Ruport
|
|
139
165
|
# my_data = Ruport::DataSet.load("foo.csv")
|
140
166
|
# my_data = Ruport::DataSet.load("foo.yaml")
|
141
167
|
# my_data = Ruport::DataSet.load("foo.yml")
|
142
|
-
def self.load ( source, default="")
|
168
|
+
def self.load ( source, default="", &block)
|
143
169
|
case source
|
144
170
|
when /\.(yaml|yml)/
|
145
171
|
return YAML.load(File.open(source))
|
146
172
|
when /\.csv/
|
147
|
-
|
148
|
-
input =
|
173
|
+
require "fastercsv"
|
174
|
+
input = FasterCSV.read(source) if source =~ /\.csv/
|
149
175
|
loaded_data = self.new
|
176
|
+
|
177
|
+
action = if block_given?
|
178
|
+
lambda { |r| block[loaded_data,r] }
|
179
|
+
else
|
180
|
+
lambda { |r| loaded_data << r }
|
181
|
+
end
|
182
|
+
|
150
183
|
loaded_data.fields = input[0]
|
151
184
|
loaded_data.default = default
|
152
|
-
input[1..-1].each { |row|
|
185
|
+
input[1..-1].each { |row| action[row] }
|
153
186
|
return loaded_data
|
154
187
|
else
|
155
188
|
raise "Invalid file type"
|
156
189
|
end
|
157
190
|
end
|
158
191
|
|
159
|
-
# Iterates through the rows, yielding a DataRow for each.
|
160
|
-
def each(&action)
|
161
|
-
@data.each(&action)
|
162
|
-
end
|
163
192
|
|
164
193
|
# Returns a new DataSet composed of the fields specified.
|
165
194
|
def select_columns(*fields)
|
166
195
|
rows = fields.inject([]) { |s,e| s << map { |row| row[e] } }.transpose
|
167
|
-
my_data = DataSet.new(fields,rows)
|
196
|
+
my_data = DataSet.new(fields, :data => rows)
|
168
197
|
end
|
169
198
|
|
199
|
+
# Prunes the dataset to contain only the fields specified. (DESTRUCTIVE)
|
200
|
+
def select_columns!(*fields)
|
201
|
+
a = select_columns(*fields)
|
202
|
+
@fields = a.fields; @data = a.data
|
203
|
+
end
|
204
|
+
|
205
|
+
|
170
206
|
# Returns a new DataSet with the specified fields removed
|
171
207
|
def remove_columns(*fields)
|
172
208
|
select_columns(*(@fields-fields))
|
@@ -193,10 +229,9 @@ module Ruport
|
|
193
229
|
#
|
194
230
|
# This will enable <tt>data.as(:my_format_name)</tt>
|
195
231
|
def as(format,&action)
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
builder.render
|
232
|
+
t = Format.table_object(:data => clone, :plugin => format)
|
233
|
+
action.call(t) if block_given?
|
234
|
+
t.render
|
200
235
|
end
|
201
236
|
|
202
237
|
# Will iterate row by row yielding each row
|
@@ -210,6 +245,11 @@ module Ruport
|
|
210
245
|
end
|
211
246
|
|
212
247
|
alias_method :sum, :sigma
|
248
|
+
|
249
|
+
# Converts a DataSet to an array of arrays
|
250
|
+
def to_a
|
251
|
+
@data.map {|x| x.to_a }
|
252
|
+
end
|
213
253
|
|
214
254
|
# Converts a DataSet to CSV
|
215
255
|
def to_csv; as(:csv) end
|
@@ -219,11 +259,6 @@ module Ruport
|
|
219
259
|
|
220
260
|
# Readable string representation of the DataSet
|
221
261
|
def to_s; as(:text) end
|
222
|
-
|
223
|
-
def clone
|
224
|
-
self.class.new @fields.dup, @data.dup, @default
|
225
|
-
end
|
226
|
-
|
227
262
|
|
228
263
|
end
|
229
264
|
end
|
@@ -232,8 +267,7 @@ class Array
|
|
232
267
|
|
233
268
|
# Will convert Arrays of Enumerable objects to DataSets.
|
234
269
|
# May have dragons.
|
235
|
-
def to_ds(fields,
|
236
|
-
Ruport::DataSet.new
|
237
|
-
end
|
238
|
-
|
270
|
+
def to_ds(fields,options={})
|
271
|
+
Ruport::DataSet.new fields, :data => to_a, :default => options[:default]
|
272
|
+
end
|
239
273
|
end
|
data/lib/ruport/format.rb
CHANGED
@@ -112,22 +112,15 @@ module Ruport
|
|
112
112
|
# Processes the ERB text in <tt>@content</tt> in the context
|
113
113
|
# of the object that Format is bound to.
|
114
114
|
def filter_erb
|
115
|
-
|
115
|
+
self.class.document :data => @content,
|
116
|
+
:klass_binding => @binding,
|
117
|
+
:plugin => :text
|
116
118
|
end
|
117
119
|
|
118
120
|
# Processes the RedCloth text in <tt>@content</tt> in the context
|
119
121
|
# of the object that Format is bound to.
|
120
122
|
def filter_red_cloth
|
121
|
-
|
122
|
-
RedCloth.new(@content).to_html
|
123
|
-
end
|
124
|
-
|
125
|
-
# Processes the ruby code in <tt>@content</tt> in the context
|
126
|
-
# of the object that Format is bound to.
|
127
|
-
#
|
128
|
-
# (Does an eval on the binding)
|
129
|
-
def filter_ruby
|
130
|
-
eval(@content,@binding)
|
123
|
+
self.class.document :data => @content, :plugin => :html
|
131
124
|
end
|
132
125
|
|
133
126
|
# Takes a name and a block and creates a filter method
|
data/lib/ruport/format/engine.rb
CHANGED
data/lib/ruport/format/plugin.rb
CHANGED
@@ -60,6 +60,11 @@ module Ruport
|
|
60
60
|
end
|
61
61
|
|
62
62
|
class TextPlugin < Format::Plugin
|
63
|
+
|
64
|
+
rendering_options :erb_enabled => true, :red_cloth_enabled => false
|
65
|
+
|
66
|
+
renderer :document
|
67
|
+
|
63
68
|
renderer :table do
|
64
69
|
data.inject(rendered_field_names){ |s,r|
|
65
70
|
s << " #{r.to_a.join(' | ')} \n"
|
@@ -70,6 +75,7 @@ module Ruport
|
|
70
75
|
end
|
71
76
|
|
72
77
|
register_on :table_engine
|
78
|
+
register_on :document_engine
|
73
79
|
end
|
74
80
|
|
75
81
|
class PDFPlugin < Format::Plugin
|
@@ -98,13 +104,13 @@ module Ruport
|
|
98
104
|
|
99
105
|
rendering_options :red_cloth_enabled => true, :erb_enabled => true
|
100
106
|
|
101
|
-
renderer :document
|
107
|
+
renderer :document
|
102
108
|
|
103
109
|
renderer :table do
|
104
110
|
rc = data.inject(rendered_field_names) { |s,r|
|
105
111
|
s << "|#{r.to_a.join('|')}|\n"
|
106
112
|
}
|
107
|
-
Format.document :data => rc, :
|
113
|
+
Format.document :data => rc, :plugin => :html
|
108
114
|
end
|
109
115
|
|
110
116
|
format_field_names do
|
data/test/tc_builder.rb
CHANGED
data/test/tc_data_row.rb
CHANGED
@@ -33,10 +33,10 @@ class TestDataRow < Test::Unit::TestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_constructor
|
36
|
-
row = Ruport::DataRow.new(
|
37
|
-
row2 = Ruport::DataRow.new({"a" => 1, "b" => 2, "c" => 3}
|
38
|
-
row3 = Ruport::DataRow.new(
|
39
|
-
row4 = Ruport::DataRow.new(
|
36
|
+
row = Ruport::DataRow.new(%w[a b c], :data => [1,2,3])
|
37
|
+
row2 = Ruport::DataRow.new(%w[a b c], :data => {"a" => 1, "b" => 2, "c" => 3})
|
38
|
+
row3 = Ruport::DataRow.new(%w[a b c], :data => row2)
|
39
|
+
row4 = Ruport::DataRow.new(%w[a b c], {:data => row3, :tags => [:awesome, :cool]})
|
40
40
|
|
41
41
|
assert_equal(row, row2)
|
42
42
|
assert_equal(row2, row3)
|
@@ -76,29 +76,29 @@ class TestDataRow < Test::Unit::TestCase
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_equality
|
79
|
-
assert( Ruport::DataRow.new(
|
80
|
-
Ruport::DataRow.new(
|
81
|
-
assert( Ruport::DataRow.new(
|
82
|
-
Ruport::DataRow.new(
|
83
|
-
a = Ruport::DataRow.new(
|
79
|
+
assert( Ruport::DataRow.new(%w[ a b ], :data => [1,2]) ==
|
80
|
+
Ruport::DataRow.new(%w[ a b ], :data => [1,2]) )
|
81
|
+
assert( Ruport::DataRow.new(%w[ a b ], :data => [1,2]) !=
|
82
|
+
Ruport::DataRow.new(%w[ c d ], :data => [1,2]) )
|
83
|
+
a = Ruport::DataRow.new(%w[ a b c ], :data => [1,2,3])
|
84
84
|
a.tag_as :apple
|
85
|
-
b = Ruport::DataRow.new(
|
85
|
+
b = Ruport::DataRow.new(%w[ a b c ], :data => [1,2,3])
|
86
86
|
assert( a == b )
|
87
87
|
assert( a.eql?(b) )
|
88
88
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def test_addition
|
92
|
-
row1 = Ruport::DataRow.new
|
93
|
-
row2 = Ruport::DataRow.new
|
92
|
+
row1 = Ruport::DataRow.new %w[ a b c ], :data => [1,2,3]
|
93
|
+
row2 = Ruport::DataRow.new %w[ d e f ], :data => [4,5,6]
|
94
94
|
|
95
|
-
expected = Ruport::DataRow.new
|
95
|
+
expected = Ruport::DataRow.new %w[ a b c d e f ], :data => [1,2,3,4,5,6]
|
96
96
|
|
97
97
|
assert_equal( expected, row1 + row2 )
|
98
98
|
end
|
99
99
|
|
100
100
|
def test_clone
|
101
|
-
row1 = Ruport::DataRow.new
|
101
|
+
row1 = Ruport::DataRow.new %w[ a b c ], :data => [1,2,3]
|
102
102
|
row2 = row1.clone
|
103
103
|
|
104
104
|
assert( row1.object_id != row2.object_id )
|
@@ -109,14 +109,14 @@ class TestDataRow < Test::Unit::TestCase
|
|
109
109
|
|
110
110
|
#FIXME: add edge cases
|
111
111
|
def test_to_h
|
112
|
-
row1 = Ruport::DataRow.new
|
112
|
+
row1 = Ruport::DataRow.new %w[ a b c ], :data => [1,2,3]
|
113
113
|
assert_instance_of(Hash,row1.to_h)
|
114
114
|
assert_equal({ "a" => 1, "b" => 2, "c" => 3},row1.to_h)
|
115
115
|
end
|
116
116
|
|
117
117
|
def test_ensure_arrays_not_modified
|
118
118
|
arr = [1,2,3]
|
119
|
-
row1 = Ruport::DataRow.new
|
119
|
+
row1 = Ruport::DataRow.new %w[ a b c ], :data => arr
|
120
120
|
assert_equal( [1,2,3], arr )
|
121
121
|
end
|
122
122
|
|
data/test/tc_data_set.rb
CHANGED
@@ -11,8 +11,7 @@ class TestDataSet < Test::Unit::TestCase
|
|
11
11
|
@data = DataSet.new
|
12
12
|
@data.fields = %w[ col1 col2 col3 ]
|
13
13
|
@data.default = ""
|
14
|
-
@data << %w[ a b c ]
|
15
|
-
@data << { "col1" => "d", "col3" => "e"}
|
14
|
+
@data << %w[ a b c ] << { "col1" => "d", "col3" => "e"}
|
16
15
|
end
|
17
16
|
|
18
17
|
def test_new
|
@@ -20,14 +19,14 @@ class TestDataSet < Test::Unit::TestCase
|
|
20
19
|
my_data = DataSet.new(fields)
|
21
20
|
assert_equal(fields,my_data.fields)
|
22
21
|
|
23
|
-
my_filled_data = DataSet.new( fields, [[1,2,3],[4,5,6]] )
|
22
|
+
my_filled_data = DataSet.new( fields, :data => [[1,2,3],[4,5,6]] )
|
24
23
|
|
25
24
|
assert_equal( [[1,2,3],[4,5,6]], my_filled_data.map { |r| r.to_a } )
|
26
25
|
|
27
26
|
hash_filling = [ { "col1" => 9, "col2" => 6, "col3" => 0 },
|
28
27
|
{ "col1" => 54, "col3" => 1 } ]
|
29
28
|
|
30
|
-
my_filled_data = DataSet.new(fields,hash_filling)
|
29
|
+
my_filled_data = DataSet.new(fields, :data => hash_filling)
|
31
30
|
|
32
31
|
assert_equal( [[9,6,0],[54,nil,1]], my_filled_data.map { |r| r.to_a } )
|
33
32
|
|
@@ -46,6 +45,11 @@ class TestDataSet < Test::Unit::TestCase
|
|
46
45
|
assert_equal( ['x','x','x'],
|
47
46
|
@data[2].to_a )
|
48
47
|
end
|
48
|
+
|
49
|
+
def test_delete_if
|
50
|
+
@data.delete_if { |r| r.any? { |e| e.empty? } }
|
51
|
+
assert_equal([%w[a b c]],@data.to_a)
|
52
|
+
end
|
49
53
|
|
50
54
|
def test_brackets
|
51
55
|
row0 = { "col1" => "a", "col2" => "b", "col3" => "c" }
|
@@ -77,6 +81,71 @@ class TestDataSet < Test::Unit::TestCase
|
|
77
81
|
assert(@data.eql?(data2) && data2.eql?(@data))
|
78
82
|
end
|
79
83
|
|
84
|
+
def test_shaped_like?
|
85
|
+
a = DataSet.new
|
86
|
+
a.fields = %w[ col1 col2 col3 ]
|
87
|
+
assert(@data.shaped_like?(a))
|
88
|
+
assert(a.shaped_like?(@data))
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_union
|
92
|
+
a = DataSet.new
|
93
|
+
a.fields = %w[ col1 col2 col3 ]
|
94
|
+
a << %w[ a b c ]
|
95
|
+
a << %w[ x y z ]
|
96
|
+
b = a | @data
|
97
|
+
assert_kind_of(DataSet, b)
|
98
|
+
assert_equal(b.data.length, 3)
|
99
|
+
assert_equal([ %w[a b c], %w[x y z], ["d","","e"] ], b.to_a)
|
100
|
+
assert_equal((a | @data), a.union(@data))
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_difference
|
104
|
+
a = DataSet.new
|
105
|
+
a.fields = %w[ col1 col2 col3 ]
|
106
|
+
a << %w[ a b c ]
|
107
|
+
a << %w[ x y z ]
|
108
|
+
b = a - @data
|
109
|
+
assert_kind_of(DataSet, b)
|
110
|
+
assert_equal(b.data.length, 1)
|
111
|
+
assert_equal([ %w[x y z] ], b.to_a)
|
112
|
+
assert_equal((a - @data), a.difference(@data))
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_intersection
|
116
|
+
a = DataSet.new
|
117
|
+
a.fields = %w[ col1 col2 col3 ]
|
118
|
+
a << %w[ a b c ]
|
119
|
+
a << %w[ x y z ]
|
120
|
+
b = a & @data
|
121
|
+
assert_kind_of(DataSet, b)
|
122
|
+
assert_equal(b.data.length, 1)
|
123
|
+
assert_equal([ %w[a b c] ], b.to_a)
|
124
|
+
assert_equal((a & @data), a.intersection(@data))
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_concatenation
|
128
|
+
a = DataSet.new
|
129
|
+
a.fields = %w[ col1 col2 col3 ]
|
130
|
+
a << %w[ x y z ]
|
131
|
+
newdata = @data.concat(a)
|
132
|
+
assert_equal([ %w[a b c], ["d","","e"], %w[x y z] ], newdata.to_a)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_append_datarow
|
136
|
+
row = DataRow.new(%w[ x y z ], :data => %w[ col1 col2 col3 ])
|
137
|
+
@data << row
|
138
|
+
assert_equal(@data[2], row)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_append_datarows
|
142
|
+
row = DataRow.new(%w[ x y z ], :data => %w[ col1 col2 col3 ])
|
143
|
+
row2 = DataRow.new(%w[ u v w ], :data => %w[ col1, col2, col3 ])
|
144
|
+
@data << [row, row2]
|
145
|
+
assert_equal(@data[2], row)
|
146
|
+
assert_equal(@data[3], row2)
|
147
|
+
end
|
148
|
+
|
80
149
|
def test_empty?
|
81
150
|
a = DataSet.new
|
82
151
|
a.fields = %w[a b c]
|
@@ -87,14 +156,20 @@ class TestDataSet < Test::Unit::TestCase
|
|
87
156
|
assert_equal(false,a.empty?)
|
88
157
|
end
|
89
158
|
|
159
|
+
def test_length
|
160
|
+
assert_equal(2, @data.length)
|
161
|
+
@data << [1,2,3]
|
162
|
+
assert_equal(3, @data.length)
|
163
|
+
end
|
164
|
+
|
90
165
|
def test_load
|
91
166
|
loaded_data = DataSet.load("test/samples/data.csv")
|
92
|
-
@data
|
93
|
-
|
94
|
-
|
95
|
-
|
167
|
+
assert_equal(@data,loaded_data)
|
168
|
+
|
169
|
+
loaded_data = DataSet.load("test/samples/data.csv") do |set,row|
|
170
|
+
set << row if row.include? 'b'
|
96
171
|
end
|
97
|
-
|
172
|
+
assert_equal([%w[a b c]],loaded_data.to_a)
|
98
173
|
end
|
99
174
|
|
100
175
|
def test_to_csv
|
@@ -104,11 +179,11 @@ class TestDataSet < Test::Unit::TestCase
|
|
104
179
|
end
|
105
180
|
|
106
181
|
def test_to_html
|
107
|
-
assert_equal("<table>\n
|
108
|
-
"<th>col3</th>\n
|
109
|
-
"
|
110
|
-
"
|
111
|
-
"</table>", @data.to_html )
|
182
|
+
assert_equal("<table>\n\t\t<tr>\n\t\t\t<th>col1 </th>\n\t\t\t"+
|
183
|
+
"<th>col2 </th>\n\t\t\t<th>col3</th>\n\t\t</tr>\n"+
|
184
|
+
"\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t<td>b</td>\n\t\t\t"+
|
185
|
+
"<td>c</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>d</td>\n\t"+
|
186
|
+
"\t\t<td>e</td>\n\t\t</tr>\n\t</table>", @data.to_html )
|
112
187
|
end
|
113
188
|
|
114
189
|
def test_select_columns
|
@@ -123,6 +198,27 @@ class TestDataSet < Test::Unit::TestCase
|
|
123
198
|
assert_equal( [["c","a"],["e","d"]],
|
124
199
|
@data.select_columns("col3","col1").map { |r| r.to_a } )
|
125
200
|
end
|
201
|
+
|
202
|
+
def test_select_columns!
|
203
|
+
a = [[1,2],[3,4]].to_ds(%w[a b])
|
204
|
+
a.select_columns!(*%w[b a])
|
205
|
+
|
206
|
+
assert_equal(%w[b a],a.fields)
|
207
|
+
assert_equal([[2,1],[4,3]],a.to_a)
|
208
|
+
|
209
|
+
a.select_columns!('a')
|
210
|
+
|
211
|
+
assert_equal(%w[a], a.fields)
|
212
|
+
assert_equal([[1],[3]],a.to_a)
|
213
|
+
|
214
|
+
a.select_columns!('a','q')
|
215
|
+
assert_equal(%w[a q], a.fields)
|
216
|
+
assert_equal([[1,nil],[3,nil]],a.to_a)
|
217
|
+
|
218
|
+
a[0]['q'] =2
|
219
|
+
assert_equal([[1,2],[3,nil]],a.to_a)
|
220
|
+
|
221
|
+
end
|
126
222
|
|
127
223
|
def test_as
|
128
224
|
data = DataSet.new
|
@@ -132,15 +228,16 @@ class TestDataSet < Test::Unit::TestCase
|
|
132
228
|
assert_equal("col1,col2,col3\na,b,c\nd,e,f\n",
|
133
229
|
data.as(:csv) )
|
134
230
|
|
135
|
-
assert_equal("<table>\n
|
136
|
-
"<th>
|
137
|
-
"
|
138
|
-
"
|
139
|
-
"</
|
231
|
+
assert_equal("<table>\n\t\t<tr>\n\t\t\t<th>col1 </th>"+
|
232
|
+
"\n\t\t\t<th>col2 </th>\n\t\t\t<th>col3</th>"+
|
233
|
+
"\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t"+
|
234
|
+
"<td>b</td>\n\t\t\t<td>c</td>\n\t\t</tr>\n\t\t<tr>"+
|
235
|
+
"\n\t\t\t<td>d</td>\n\t\t\t<td>e</td>\n\t\t\t<td>f</td>"+
|
236
|
+
"\n\t\t</tr>\n\t</table>", data.as(:html) )
|
140
237
|
end
|
141
238
|
|
142
239
|
def test_sigma
|
143
|
-
data = Ruport::DataSet.new(%w[x],[[3],[5],[8],[2]])
|
240
|
+
data = Ruport::DataSet.new(%w[x], :data => [[3],[5],[8],[2]])
|
144
241
|
|
145
242
|
sum = data.sigma { |r| r["x"] if (r["x"] % 2).zero? }
|
146
243
|
assert_equal(10, sum)
|
@@ -164,11 +261,11 @@ class TestDataSet < Test::Unit::TestCase
|
|
164
261
|
end
|
165
262
|
|
166
263
|
def test_bracket_equals
|
167
|
-
expected = DataRow.new(%w[
|
264
|
+
expected = DataRow.new(%w[col1 col2 col3], :data => %w[apple banana orange])
|
168
265
|
|
169
266
|
raw = [ %w[apple banana orange],
|
170
267
|
{ "col1" => "apple", "col2" => "banana", "col3" => "orange" },
|
171
|
-
DataRow.new(%w[
|
268
|
+
DataRow.new(%w[col1 col2 col3], :data => %w[apple banana orange])
|
172
269
|
]
|
173
270
|
raw.each do |my_row|
|
174
271
|
@data[1] = my_row
|
@@ -205,17 +302,17 @@ class TestDataSet < Test::Unit::TestCase
|
|
205
302
|
[1,2,3].to_ds(%w[foo bar soup])
|
206
303
|
}
|
207
304
|
|
208
|
-
assert_equal( DataSet.new(%w[a b], [[1,2],[3,4]]),
|
305
|
+
assert_equal( DataSet.new(%w[a b], :data => [[1,2],[3,4]]),
|
209
306
|
[[1,2],[3,4]].to_ds(%w[a b]) )
|
210
307
|
|
211
|
-
assert_equal( DataSet.new(%w[a b], [{ "a" => 1 },{ "b" => 2}]),
|
308
|
+
assert_equal( DataSet.new(%w[a b], :data => [{ "a" => 1 },{ "b" => 2}]),
|
212
309
|
[{"a" => 1}, {"b" => 2}].to_ds(%w[a b]) )
|
213
|
-
assert_equal( DataSet.new(%w[a b], [DataRow.new(
|
214
|
-
[DataRow.new(
|
310
|
+
assert_equal( DataSet.new(%w[a b], :data => [DataRow.new(%w[a b], :data => [1,2])]),
|
311
|
+
[DataRow.new(%w[a b], :data => [1,2])].to_ds(%w[a b]) )
|
215
312
|
|
216
313
|
# FIXME: Decide whether this test should pass or fail.
|
217
|
-
# assert_equal( DataSet.new(%w[a b], [DataRow.new(
|
218
|
-
# [DataRow.new(
|
314
|
+
# assert_equal( DataSet.new(%w[a b], [DataRow.new(%w[a b], [1,2])]),
|
315
|
+
# [DataRow.new(%w[a q], [1,2])].to_ds(%w[a b]) )
|
219
316
|
|
220
317
|
end
|
221
318
|
|
@@ -0,0 +1,326 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "ruport"
|
5
|
+
|
6
|
+
class TestDataSet < Test::Unit::TestCase
|
7
|
+
|
8
|
+
include Ruport
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@data = DataSet.new
|
12
|
+
@data.fields = %w[ col1 col2 col3 ]
|
13
|
+
@data.default = ""
|
14
|
+
@data << %w[ a b c ] << { "col1" => "d", "col3" => "e"}
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_new
|
18
|
+
fields = %w[ col1 col2 col3 ]
|
19
|
+
my_data = DataSet.new(fields)
|
20
|
+
assert_equal(fields,my_data.fields)
|
21
|
+
|
22
|
+
my_filled_data = DataSet.new( fields, :content => [[1,2,3],[4,5,6]] )
|
23
|
+
|
24
|
+
assert_equal( [[1,2,3],[4,5,6]], my_filled_data.map { |r| r.to_a } )
|
25
|
+
|
26
|
+
hash_filling = [ { "col1" => 9, "col2" => 6, "col3" => 0 },
|
27
|
+
{ "col1" => 54, "col3" => 1 } ]
|
28
|
+
|
29
|
+
my_filled_data = DataSet.new(fields, :content => hash_filling)
|
30
|
+
|
31
|
+
assert_equal( [[9,6,0],[54,nil,1]], my_filled_data.map { |r| r.to_a } )
|
32
|
+
|
33
|
+
cloned_set = @data.clone
|
34
|
+
|
35
|
+
assert_equal( [ %w[a b c], ["d","","e"] ], cloned_set.map { |r| r.to_a } )
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_fields
|
39
|
+
assert_equal(%w[ col1 col2 col3 ], @data.fields )
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_default
|
43
|
+
@data.default = "x"
|
44
|
+
@data << { }
|
45
|
+
assert_equal( ['x','x','x'],
|
46
|
+
@data[2].to_a )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_delete_if
|
50
|
+
@data.delete_if { |r| r.any? { |e| e.empty? } }
|
51
|
+
assert_equal([%w[a b c]],@data.to_a)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_brackets
|
55
|
+
row0 = { "col1" => "a", "col2" => "b", "col3" => "c" }
|
56
|
+
row1 = { "col1" => "d", "col2" => "", "col3" => "e" }
|
57
|
+
row0.each do |key,value|
|
58
|
+
assert_equal( value, @data[0][key] )
|
59
|
+
end
|
60
|
+
row1.each do |key,value|
|
61
|
+
assert_equal( value, @data[1][key] )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_eql?
|
66
|
+
data2 = DataSet.new
|
67
|
+
data2.fields = %w[ col1 col2 col3 ]
|
68
|
+
data2.default = ""
|
69
|
+
data2 << %w[ a b c ]
|
70
|
+
data2 << { "col1" => "d", "col3" => "e" }
|
71
|
+
|
72
|
+
#FIXME: This looks like some shady discrete math assignment
|
73
|
+
assert(@data.eql?(data2) && data2.eql?(@data))
|
74
|
+
data2 << [2, 3, 4]
|
75
|
+
assert(!( @data.eql?(data2) || data2.eql?(@data) ))
|
76
|
+
@data << [2, 3, 4]
|
77
|
+
assert(@data.eql?(data2) && data2.eql?(@data))
|
78
|
+
@data << [8, 9, 10]
|
79
|
+
assert(!( @data.eql?(data2) || data2.eql?(@data) ))
|
80
|
+
data2 << [8, 9, 10]
|
81
|
+
assert(@data.eql?(data2) && data2.eql?(@data))
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_shaped_like?
|
85
|
+
a = DataSet.new
|
86
|
+
a.fields = %w[ col1 col2 col3 ]
|
87
|
+
assert(@data.shaped_like?(a))
|
88
|
+
assert(a.shaped_like?(@data))
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_union
|
92
|
+
a = DataSet.new
|
93
|
+
a.fields = %w[ col1 col2 col3 ]
|
94
|
+
a << %w[ a b c ]
|
95
|
+
a << %w[ x y z ]
|
96
|
+
b = a | @data
|
97
|
+
assert_kind_of(DataSet, b)
|
98
|
+
assert_equal(b.data.length, 3)
|
99
|
+
assert_equal([ %w[a b c], %w[x y z], ["d","","e"] ], b.to_a)
|
100
|
+
assert_equal((a | @data), a.union(@data))
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_difference
|
104
|
+
a = DataSet.new
|
105
|
+
a.fields = %w[ col1 col2 col3 ]
|
106
|
+
a << %w[ a b c ]
|
107
|
+
a << %w[ x y z ]
|
108
|
+
b = a - @data
|
109
|
+
assert_kind_of(DataSet, b)
|
110
|
+
assert_equal(b.data.length, 1)
|
111
|
+
assert_equal([ %w[x y z] ], b.to_a)
|
112
|
+
assert_equal((a - @data), a.difference(@data))
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_intersection
|
116
|
+
a = DataSet.new
|
117
|
+
a.fields = %w[ col1 col2 col3 ]
|
118
|
+
a << %w[ a b c ]
|
119
|
+
a << %w[ x y z ]
|
120
|
+
b = a & @data
|
121
|
+
assert_kind_of(DataSet, b)
|
122
|
+
assert_equal(b.data.length, 1)
|
123
|
+
assert_equal([ %w[a b c] ], b.to_a)
|
124
|
+
assert_equal((a & @data), a.intersection(@data))
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_concatenation
|
128
|
+
a = DataSet.new
|
129
|
+
a.fields = %w[ col1 col2 col3 ]
|
130
|
+
a << %w[ x y z ]
|
131
|
+
newdata = @data.concat(a)
|
132
|
+
assert_equal([ %w[a b c], ["d","","e"], %w[x y z] ], newdata.to_a)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_append_datarow
|
136
|
+
row = DataRow.new(%w[ x y z ],%w[ col1 col2 col3 ])
|
137
|
+
@data << row
|
138
|
+
assert_equal(@data[2], row)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_append_datarows
|
142
|
+
row = DataRow.new(%w[ x y z ],%w[ col1 col2 col3 ])
|
143
|
+
row2 = DataRow.new(%w[ u v w ], %w[ col1, col2, col3 ])
|
144
|
+
@data << [row, row2]
|
145
|
+
assert_equal(@data[2], row)
|
146
|
+
assert_equal(@data[3], row2)
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_empty?
|
150
|
+
a = DataSet.new
|
151
|
+
a.fields = %w[a b c]
|
152
|
+
assert_equal(true,a.empty?)
|
153
|
+
assert_equal(false,@data.empty?)
|
154
|
+
|
155
|
+
a << [1,2,3]
|
156
|
+
assert_equal(false,a.empty?)
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_length
|
160
|
+
assert_equal(2, @data.length)
|
161
|
+
@data << [1,2,3]
|
162
|
+
assert_equal(3, @data.length)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_load
|
166
|
+
loaded_data = DataSet.load("test/samples/data.csv")
|
167
|
+
assert_equal(@data,loaded_data)
|
168
|
+
|
169
|
+
loaded_data = DataSet.load("test/samples/data.csv") do |set,row|
|
170
|
+
set << row if row.include? 'b'
|
171
|
+
end
|
172
|
+
assert_equal([%w[a b c]],loaded_data.to_a)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_to_csv
|
176
|
+
loaded_data = DataSet.load("test/samples/data.csv" )
|
177
|
+
csv = loaded_data.to_csv
|
178
|
+
assert_equal("col1,col2,col3\na,b,c\nd,\"\",e\n",csv)
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_to_html
|
182
|
+
assert_equal("<table>\n\t\t<tr>\n\t\t\t<th>col1 </th>\n\t\t\t"+
|
183
|
+
"<th>col2 </th>\n\t\t\t<th>col3</th>\n\t\t</tr>\n"+
|
184
|
+
"\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t<td>b</td>\n\t\t\t"+
|
185
|
+
"<td>c</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>d</td>\n\t"+
|
186
|
+
"\t\t<td>e</td>\n\t\t</tr>\n\t</table>", @data.to_html )
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_select_columns
|
190
|
+
assert_equal( [["a"],["d"]],
|
191
|
+
@data.select_columns("col1").map { |r| r.to_a } )
|
192
|
+
assert_equal( [["b"],[""]] ,
|
193
|
+
@data.select_columns("col2").map { |r| r.to_a } )
|
194
|
+
assert_equal( [["c"],["e"]],
|
195
|
+
@data.select_columns("col3").map { |r| r.to_a } )
|
196
|
+
assert_equal( [["a","b","c"],["d","","e"]],
|
197
|
+
@data.select_columns("col1","col2","col3").map { |r| r.to_a })
|
198
|
+
assert_equal( [["c","a"],["e","d"]],
|
199
|
+
@data.select_columns("col3","col1").map { |r| r.to_a } )
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_select_columns!
|
203
|
+
a = [[1,2],[3,4]].to_ds(%w[a b])
|
204
|
+
a.select_columns!(*%w[b a])
|
205
|
+
|
206
|
+
assert_equal(%w[b a],a.fields)
|
207
|
+
assert_equal([[2,1],[4,3]],a.to_a)
|
208
|
+
|
209
|
+
a.select_columns!('a')
|
210
|
+
|
211
|
+
assert_equal(%w[a], a.fields)
|
212
|
+
assert_equal([[1],[3]],a.to_a)
|
213
|
+
|
214
|
+
a.select_columns!('a','q')
|
215
|
+
assert_equal(%w[a q], a.fields)
|
216
|
+
assert_equal([[1,nil],[3,nil]],a.to_a)
|
217
|
+
|
218
|
+
a[0]['q'] =2
|
219
|
+
assert_equal([[1,2],[3,nil]],a.to_a)
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_as
|
224
|
+
data = DataSet.new
|
225
|
+
data.fields = %w[ col1 col2 col3]
|
226
|
+
data << %w[ a b c]
|
227
|
+
data << %w[ d e f]
|
228
|
+
assert_equal("col1,col2,col3\na,b,c\nd,e,f\n",
|
229
|
+
data.as(:csv) )
|
230
|
+
|
231
|
+
assert_equal("<table>\n\t\t<tr>\n\t\t\t<th>col1 </th>"+
|
232
|
+
"\n\t\t\t<th>col2 </th>\n\t\t\t<th>col3</th>"+
|
233
|
+
"\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t"+
|
234
|
+
"<td>b</td>\n\t\t\t<td>c</td>\n\t\t</tr>\n\t\t<tr>"+
|
235
|
+
"\n\t\t\t<td>d</td>\n\t\t\t<td>e</td>\n\t\t\t<td>f</td>"+
|
236
|
+
"\n\t\t</tr>\n\t</table>", data.as(:html) )
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_sigma
|
240
|
+
data = Ruport::DataSet.new(%w[x], :content => [[3],[5],[8],[2]])
|
241
|
+
|
242
|
+
sum = data.sigma { |r| r["x"] if (r["x"] % 2).zero? }
|
243
|
+
assert_equal(10, sum)
|
244
|
+
|
245
|
+
sum = data.sigma { |r| r["x"] }
|
246
|
+
assert_equal(18,sum)
|
247
|
+
|
248
|
+
#check alias
|
249
|
+
sum = data.sum { |r| r["x"] }
|
250
|
+
assert_equal(18,sum)
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_remove_columns
|
255
|
+
data = @data.remove_columns("col1","col3")
|
256
|
+
assert_equal(["col2"],data.fields)
|
257
|
+
|
258
|
+
data.remove_columns!("col2")
|
259
|
+
assert_equal([],data.fields)
|
260
|
+
assert(data.empty?)
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_bracket_equals
|
264
|
+
expected = DataRow.new(%w[apple banana orange], %w[col1 col2 col3])
|
265
|
+
|
266
|
+
raw = [ %w[apple banana orange],
|
267
|
+
{ "col1" => "apple", "col2" => "banana", "col3" => "orange" },
|
268
|
+
DataRow.new(%w[apple banana orange], %w[col1 col2 col3])
|
269
|
+
]
|
270
|
+
raw.each do |my_row|
|
271
|
+
@data[1] = my_row
|
272
|
+
assert_instance_of(DataRow, @data[1])
|
273
|
+
assert_equal(expected, @data[1])
|
274
|
+
end
|
275
|
+
|
276
|
+
assert_raise(ArgumentError) { @data[1] = "apple" }
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_clone
|
280
|
+
data2 = @data.clone
|
281
|
+
assert( @data.object_id != data2.object_id )
|
282
|
+
assert_equal( @data, data2 )
|
283
|
+
data2 << %w[ f o o ]
|
284
|
+
assert( @data != data2 )
|
285
|
+
assert( data2 != @data )
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_array_hack
|
289
|
+
assert_nothing_raised {
|
290
|
+
[ { :a => :b, :c => :d }, { :e => :f, :g => :h } ].to_ds(%w[a e])
|
291
|
+
}
|
292
|
+
assert_nothing_raised {
|
293
|
+
[ [1,2,3], [4,5,6], [7,8,9] ].to_ds(%w[a b c])
|
294
|
+
}
|
295
|
+
assert_raise(ArgumentError) {
|
296
|
+
%w[d e f].to_ds(%w[a b c])
|
297
|
+
}
|
298
|
+
assert_raise(ArgumentError) {
|
299
|
+
[:foo,:bar,:dog].to_ds(%w[tree cat animal])
|
300
|
+
}
|
301
|
+
assert_raise(ArgumentError) {
|
302
|
+
[1,2,3].to_ds(%w[foo bar soup])
|
303
|
+
}
|
304
|
+
|
305
|
+
assert_equal( DataSet.new(%w[a b], :content => [[1,2],[3,4]]),
|
306
|
+
[[1,2],[3,4]].to_ds(%w[a b]) )
|
307
|
+
|
308
|
+
assert_equal( DataSet.new(%w[a b], :content => [{ "a" => 1 },{ "b" => 2}]),
|
309
|
+
[{"a" => 1}, {"b" => 2}].to_ds(%w[a b]) )
|
310
|
+
assert_equal( DataSet.new(%w[a b], :content => [DataRow.new([1,2],%w[a b])]),
|
311
|
+
[DataRow.new([1,2],%w[a b])].to_ds(%w[a b]) )
|
312
|
+
|
313
|
+
# FIXME: Decide whether this test should pass or fail.
|
314
|
+
# assert_equal( DataSet.new(%w[a b], [DataRow.new([1,2],%w[a b])]),
|
315
|
+
# [DataRow.new([1,2],%w[a q])].to_ds(%w[a b]) )
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_append_chain
|
320
|
+
data2 = DataSet.new(%w[col1 col2 col3])
|
321
|
+
data2.default=""
|
322
|
+
data2 << %w[ a b c ] << { "col1" => "d", "col3" => "e" }
|
323
|
+
assert_equal @data, data2
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruport
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
7
|
-
date: 2006-06-
|
6
|
+
version: 0.4.5
|
7
|
+
date: 2006-06-09 00:00:00 -04:00
|
8
8
|
summary: A generalized Ruby report generation and templating engine.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -28,11 +28,11 @@ cert_chain:
|
|
28
28
|
authors:
|
29
29
|
- Gregory Brown
|
30
30
|
files:
|
31
|
+
- examples/fieldless_table.rb
|
31
32
|
- examples/line_plotter.rb
|
32
33
|
- examples/pdf.rb
|
33
34
|
- examples/long.txt
|
34
35
|
- examples/new_plugin.rb
|
35
|
-
- examples/fieldless_table.rb
|
36
36
|
- lib/ruport
|
37
37
|
- lib/ruport.rb
|
38
38
|
- lib/ruport/query
|
@@ -53,12 +53,12 @@ files:
|
|
53
53
|
- lib/ruport/format/plugin.rb
|
54
54
|
- lib/ruport/report/mailer.rb
|
55
55
|
- test/samples
|
56
|
+
- test/tc_format_engine.rb
|
56
57
|
- test/tc_element.rb
|
57
58
|
- test/tc_format.rb
|
58
59
|
- test/ts_all.rb
|
59
60
|
- test/tc_data_row.rb
|
60
61
|
- test/tc_ruport.rb
|
61
|
-
- test/unit.log
|
62
62
|
- test/tc_section.rb
|
63
63
|
- test/tc_database.rb
|
64
64
|
- test/tc_query.rb
|
@@ -73,7 +73,7 @@ files:
|
|
73
73
|
- test/tc_state.rb
|
74
74
|
- test/tc_data_set.rb
|
75
75
|
- test/tc_builder.rb
|
76
|
-
- test/
|
76
|
+
- test/tc_data_set.rb~
|
77
77
|
- test/tc_plugin.rb
|
78
78
|
- test/samples/five_paragraphs.txt
|
79
79
|
- test/samples/ross_report.txt
|
data/test/unit.log
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
# Logfile created on Tue Jun 06 00:16:40 EDT 2006 by logger.rb/1.5.2.7
|
2
|
-
F, [2006-06-06T00:16:40.836111 #10456] FATAL -- : Missing host for mailer bar
|
3
|
-
F, [2006-06-06T00:16:40.837386 #10456] FATAL -- : Missing DSN for source foo!
|
4
|
-
F, [2006-06-06T00:16:40.855495 #10456] FATAL -- : Cannot convert data to DataRow
|
5
|
-
F, [2006-06-06T00:16:40.855965 #10456] FATAL -- : Cannot convert data to DataRow
|
6
|
-
F, [2006-06-06T00:16:40.856380 #10456] FATAL -- : Cannot convert data to DataRow
|
7
|
-
F, [2006-06-06T00:16:40.859864 #10456] FATAL -- : Cannot convert data to DataRow
|
8
|
-
F, [2006-06-06T00:16:40.915668 #10456] FATAL -- : no block given!
|