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 CHANGED
@@ -12,3 +12,10 @@ Parse::Input which is the base for Ruport::Parser
12
12
 
13
13
  Francis Hwang:
14
14
  SQLSplit
15
+
16
+ Simon Claret:
17
+ PDF table support for Format::Builder
18
+
19
+ Dudley Flanders:
20
+ DataSet improvements
21
+
data/CHANGELOG CHANGED
@@ -1,4 +1,27 @@
1
- The current version of Ruby Reports is 0.4.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.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:
@@ -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.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
@@ -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 ordinal
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 data and field names as well as some optional parameters and
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>:filler</tt>:: this will be used as a default value for empty
35
- # <tt>:tags</tt>:: an initial set of tags for the row
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 [1,2,3,4,5], [:a,:b,:c,:d,:e],
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({ :a => 'moo', :c => 'caw'} , [:a,:b,:c,:d,:e],
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 [1,2,3], [:a,:b,:c,:d,:e], :tags => %w[cat dog],
50
- # :filler => 0
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( data, fields, options={} )
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 { |key, index| @data[index] = data.shift || options[:filler] }
65
+ lambda {|key, index| @data[index] = data.shift || options[:default]}
67
66
  when DataRow
68
- lambda { |key, index| @data = data.to_a }
67
+ lambda {|key, index| @data = data.to_a}
69
68
  else
70
- lambda { |key, index| @data[index] = data[key] || options[:filler] }
69
+ lambda {|key, index| @data[index] = data[key] || options[:default]}
71
70
  end
72
- @fields.each_with_index { |key, index| nr_action.call(key,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 an array of values. Should probably return a DataRow.
79
- # Loses field information.
77
+ # Returns a new DataRow
80
78
  def +(other)
81
- DataRow.new @data + other.to_a, @fields + other.fields
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 @data, @fields, :tags => @tags
165
+ self.class.new @fields, :data => @data, :tags => @tags
168
166
  end
169
167
 
170
168
  alias_method :dup, :clone
@@ -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 DataSet
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
- # You can optionally pass in some content as well. (Must be Enumerable)
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
- # data = Ruport::DataSet.new(%w[ id name phone],content)
67
- def initialize(fields=[], content=nil, default=nil)
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
- @default = default
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 &block; self
63
+ end
64
+
83
65
  #provides a deep copy of the DataSet.
84
66
  def clone
85
- DataSet.new(@fields,@data)
67
+ self.class.new(@fields, :data => @data)
86
68
  end
87
69
 
88
- #Allows ordinal access to rows
89
- #
90
- # my_data[2] -> Ruport::DataRow
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 (providing a DataRow is passed in)
74
+
75
+ #allows setting of rows
96
76
  def []=(index,data)
97
- @data[index] = DataRow.new data, @fields
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
- # appends a row to the DataSet
101
- # can be added as an array or a keyed hash-like object.
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
- @data << DataRow.new(stuff,@fields,:filler => filler); self;
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
- # Returns true if DataSet contains no rows, false otherwise.
131
- def empty?
132
- return @data.empty?
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
- csv_klass = defined?(FasterCSV) ? FasterCSV : CSV
148
- input = csv_klass.read(source) if source =~ /\.csv/
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| loaded_data << 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
- builder = Format::Builder.new( self )
197
- builder.format = format
198
- action.call(builder) if block_given?
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,default=nil)
236
- Ruport::DataSet.new(fields,to_a,default)
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
@@ -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
- ERB.new(@content).result(@binding)
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
- require "redcloth"
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
@@ -120,6 +120,7 @@ module Ruport
120
120
  attr_accessor :erb_enabled
121
121
 
122
122
  def apply_red_cloth
123
+ require "redcloth"
123
124
  active_plugin.data = RedCloth.new(active_plugin.data).to_html
124
125
  end
125
126
 
@@ -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, :output_type => :html
113
+ Format.document :data => rc, :plugin => :html
108
114
  end
109
115
 
110
116
  format_field_names do
@@ -23,7 +23,7 @@ class TestBuilder < Test::Unit::TestCase
23
23
  end
24
24
 
25
25
  assert_equal(DataSet.new( %w[ col1 col2 col3 ],
26
- [ %w[ a b c ], %w[ d e f ]]),
26
+ :data => [ %w[ a b c ], %w[ d e f ]]),
27
27
  @builder.render_data_snatcher)
28
28
 
29
29
  end
@@ -33,10 +33,10 @@ class TestDataRow < Test::Unit::TestCase
33
33
  end
34
34
 
35
35
  def test_constructor
36
- row = Ruport::DataRow.new([1,2,3],%w[a b c])
37
- row2 = Ruport::DataRow.new({"a" => 1, "b" => 2, "c" => 3}, %w[a b c])
38
- row3 = Ruport::DataRow.new(row2, %w[ a b c])
39
- row4 = Ruport::DataRow.new(row3, %w[ a b c], :tags => [:awesome, :cool])
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([1,2], %w[ a b ]) ==
80
- Ruport::DataRow.new([1,2], %w[ a b ]) )
81
- assert( Ruport::DataRow.new([1,2], %w[ a b ]) !=
82
- Ruport::DataRow.new([1,2], %w[ c d ]) )
83
- a = Ruport::DataRow.new([1,2,3], %w[ a b c ])
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([1,2,3], %w[ a b c ])
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 [1,2,3], %w[ a b c ]
93
- row2 = Ruport::DataRow.new [4,5,6], %w[ d e f ]
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 [1,2,3,4,5,6], %w[ a b c d e f ]
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 [1,2,3], %w[ a b c ]
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 [1,2,3], %w[ a b c ]
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 arr, %w[ a b c ]
119
+ row1 = Ruport::DataRow.new %w[ a b c ], :data => arr
120
120
  assert_equal( [1,2,3], arr )
121
121
  end
122
122
 
@@ -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.each_with_index do |row,r_index|
93
- row.each_with_index do |field,f_index|
94
- assert_equal(field,loaded_data[r_index][f_index])
95
- end
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
- #FIXME: add error edges
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 <tr>\n <th>col1</th><th>col2</th>" +
108
- "<th>col3</th>\n </tr>\n" +
109
- " <tr>\n <td>a</td><td>b</td><td>c</td>\n </tr>\n" +
110
- " <tr>\n <td>d</td><td></td><td>e</td>\n </tr>\n" +
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 <tr>\n <th>col1</th><th>col2</th>" +
136
- "<th>col3</th>\n </tr>\n" +
137
- " <tr>\n <td>a</td><td>b</td><td>c</td>\n </tr>\n" +
138
- " <tr>\n <td>d</td><td>e</td><td>f</td>\n </tr>\n" +
139
- "</table>", data.as(:html) )
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[apple banana orange], %w[col1 col2 col3])
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[apple banana orange], %w[col1 col2 col3])
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([1,2],%w[a b])]),
214
- [DataRow.new([1,2],%w[a b])].to_ds(%w[a b]) )
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([1,2],%w[a b])]),
218
- # [DataRow.new([1,2],%w[a q])].to_ds(%w[a b]) )
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.4
7
- date: 2006-06-06 00:00:00 -04:00
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/tc_format_engine.rb
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
@@ -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!