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