acts_as_reportable 1.0.0

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/Rakefile ADDED
@@ -0,0 +1,63 @@
1
+ require "rake/rdoctask"
2
+ require "rake/testtask"
3
+ require "rake/gempackagetask"
4
+
5
+ AAR_VERSION = "1.0.0"
6
+
7
+ begin
8
+ require "rubygems"
9
+ rescue LoadError
10
+ nil
11
+ end
12
+
13
+ task :default => [:test]
14
+
15
+ Rake::TestTask.new do |test|
16
+ test.libs << "test"
17
+ test.test_files = Dir[ "test/*_test.rb" ]
18
+ test.verbose = true
19
+ end
20
+
21
+ spec = Gem::Specification.new do |spec|
22
+ spec.name = "acts_as_reportable"
23
+ spec.version = AAR_VERSION
24
+ spec.platform = Gem::Platform::RUBY
25
+ spec.summary = "ActiveRecord support for Ruby Reports"
26
+ spec.files = Dir.glob("{lib,test}/**/**/*") +
27
+ ["Rakefile"]
28
+ spec.require_path = "lib"
29
+
30
+ spec.test_files = Dir[ "test/*_test.rb" ]
31
+ spec.has_rdoc = true
32
+ #spec.extra_rdoc_files = %w{README LICENSE AUTHORS}
33
+ spec.rdoc_options << '--title' << 'Ruport Documentation'
34
+ spec.add_dependency('ruport', '>= 1.3.0')
35
+ spec.author = "Michael Milner"
36
+ spec.email = "mikem836@gmail.com"
37
+ spec.rubyforge_project = "ruport"
38
+ spec.homepage = "http://rubyreports.org"
39
+ spec.description = <<END_DESC
40
+ acts_as_reportable provides ActiveRecord support for Ruby Reports
41
+ END_DESC
42
+ end
43
+
44
+ Rake::RDocTask.new do |rdoc|
45
+ rdoc.rdoc_files.include( "lib/" )
46
+ rdoc.main = "README"
47
+ rdoc.rdoc_dir = "doc/html"
48
+ rdoc.title = "acts_as_reportable Documentation"
49
+ end
50
+
51
+ Rake::GemPackageTask.new(spec) do |pkg|
52
+ pkg.need_zip = true
53
+ pkg.need_tar = true
54
+ end
55
+
56
+ begin
57
+ require 'rcov/rcovtask'
58
+ Rcov::RcovTask.new do |t|
59
+ t.test_files = Dir[ "test/*_test.rb" ]
60
+ end
61
+ rescue LoadError
62
+ nil
63
+ end
@@ -0,0 +1,383 @@
1
+ # Ruport : Extensible Reporting System
2
+ #
3
+ # acts_as_reportable.rb provides ActiveRecord integration for Ruport.
4
+ #
5
+ # Originally created by Dudley Flanders, 2006
6
+ # Revised and updated by Michael Milner, 2007
7
+ # Copyright (C) 2006-2007 Dudley Flanders / Michael Milner, All Rights Reserved.
8
+ #
9
+ # This is free software distributed under the same terms as Ruby 1.8
10
+ # See LICENSE and COPYING for details.
11
+ #
12
+ require "ruport"
13
+ Ruport.quiet { require "active_record" }
14
+
15
+ module Ruport
16
+
17
+ # === Overview
18
+ #
19
+ # This module is designed to allow an ActiveRecord model to be converted to
20
+ # Ruport's data structures. If ActiveRecord is available when Ruport is
21
+ # loaded, this module will be automatically mixed into ActiveRecord::Base.
22
+ #
23
+ # Add the acts_as_reportable call to the model class that you want to
24
+ # integrate with Ruport:
25
+ #
26
+ # class Book < ActiveRecord::Base
27
+ # acts_as_reportable
28
+ # belongs_to :author
29
+ # end
30
+ #
31
+ # Then you can use the <tt>report_table</tt> method to get data from the
32
+ # model using ActiveRecord.
33
+ #
34
+ # Book.report_table(:all, :include => :author)
35
+ #
36
+ module Reportable
37
+
38
+ def self.included(base) #:nodoc:
39
+ base.extend ClassMethods
40
+ end
41
+
42
+ # === Overview
43
+ #
44
+ # This module contains class methods that will automatically be available
45
+ # to ActiveRecord models.
46
+ #
47
+ module ClassMethods
48
+
49
+ # In the ActiveRecord model you wish to integrate with Ruport, add the
50
+ # following line just below the class definition:
51
+ #
52
+ # acts_as_reportable
53
+ #
54
+ # Available options:
55
+ #
56
+ # <b><tt>:only</tt></b>:: an attribute name or array of attribute
57
+ # names to include in the results, other
58
+ # attributes will be excuded.
59
+ # <b><tt>:except</tt></b>:: an attribute name or array of attribute
60
+ # names to exclude from the results.
61
+ # <b><tt>:methods</tt></b>:: a method name or array of method names
62
+ # whose result(s) will be included in the
63
+ # table.
64
+ # <b><tt>:include</tt></b>:: an associated model or array of associated
65
+ # models to include in the results.
66
+ #
67
+ # Example:
68
+ #
69
+ # class Book < ActiveRecord::Base
70
+ # acts_as_reportable, :only => 'title', :include => :author
71
+ # end
72
+ #
73
+ def acts_as_reportable(options = {})
74
+ cattr_accessor :aar_options, :aar_columns
75
+
76
+ self.aar_options = options
77
+
78
+ include Ruport::Reportable::InstanceMethods
79
+ extend Ruport::Reportable::SingletonMethods
80
+ end
81
+ end
82
+
83
+ # === Overview
84
+ #
85
+ # This module contains methods that will be made available as singleton
86
+ # class methods to any ActiveRecord model that calls
87
+ # <tt>acts_as_reportable</tt>.
88
+ #
89
+ module SingletonMethods
90
+
91
+ # Creates a Ruport::Data::Table from an ActiveRecord find. Takes
92
+ # parameters just like a regular find.
93
+ #
94
+ # Additional options include:
95
+ #
96
+ # <b><tt>:only</tt></b>:: An attribute name or array of attribute
97
+ # names to include in the results, other
98
+ # attributes will be excuded.
99
+ # <b><tt>:except</tt></b>:: An attribute name or array of attribute
100
+ # names to exclude from the results.
101
+ # <b><tt>:methods</tt></b>:: A method name or array of method names
102
+ # whose result(s) will be included in the
103
+ # table.
104
+ # <b><tt>:include</tt></b>:: An associated model or array of associated
105
+ # models to include in the results.
106
+ # <b><tt>:filters</tt></b>:: A proc or array of procs that set up
107
+ # conditions to filter the data being added
108
+ # to the table.
109
+ # <b><tt>:transforms</tt></b>:: A proc or array of procs that perform
110
+ # transformations on the data being added
111
+ # to the table.
112
+ # <b><tt>:record_class</tt></b>:: Specify the class of the table's
113
+ # records.
114
+ # <b><tt>:eager_loading</tt></b>:: Set to false if you don't want to
115
+ # eager load included associations.
116
+ #
117
+ # The :only, :except, :methods, and :include options may also be passed
118
+ # to the :include option in order to specify the output for any
119
+ # associated models. In this case, the :include option must be a hash,
120
+ # where the keys are the names of the associations and the values
121
+ # are hashes of options.
122
+ #
123
+ # Any options passed to report_table will disable the options set by
124
+ # the acts_as_reportable class method.
125
+ #
126
+ # Example:
127
+ #
128
+ # class Book < ActiveRecord::Base
129
+ # belongs_to :author
130
+ # acts_as_reportable
131
+ # end
132
+ #
133
+ # Book.report_table(:all, :only => ['title'],
134
+ # :include => { :author => { :only => 'name' } }).as(:html)
135
+ #
136
+ # Returns:
137
+ #
138
+ # an html version of the table with two columns, title from
139
+ # the book, and name from the associated author.
140
+ #
141
+ # Example:
142
+ #
143
+ # Book.report_table(:all, :include => :author).as(:html)
144
+ #
145
+ # Returns:
146
+ #
147
+ # an html version of the table with all columns from books and authors.
148
+ #
149
+ # Note: column names for attributes of included models will be qualified
150
+ # with the name of the association.
151
+ #
152
+ def report_table(number = :all, options = {})
153
+ only = options.delete(:only)
154
+ except = options.delete(:except)
155
+ methods = options.delete(:methods)
156
+ includes = options.delete(:include)
157
+ filters = options.delete(:filters)
158
+ transforms = options.delete(:transforms)
159
+ record_class = options.delete(:record_class) || Ruport::Data::Record
160
+ self.aar_columns = []
161
+
162
+ unless options.delete(:eager_loading) == false
163
+ options[:include] = get_include_for_find(includes)
164
+ end
165
+
166
+ data = [find(number, options)].flatten
167
+ data = data.map {|r| r.reportable_data(:include => includes,
168
+ :only => only,
169
+ :except => except,
170
+ :methods => methods) }.flatten
171
+
172
+
173
+ table = Ruport::Data::Table.new(:data => data,
174
+ :column_names => aar_columns,
175
+ :record_class => record_class,
176
+ :filters => filters,
177
+ :transforms => transforms )
178
+ end
179
+
180
+ # Creates a Ruport::Data::Table from an ActiveRecord find_by_sql.
181
+ #
182
+ # Additional options include:
183
+ #
184
+ # <b><tt>:filters</tt></b>:: A proc or array of procs that set up
185
+ # conditions to filter the data being added
186
+ # to the table.
187
+ # <b><tt>:transforms</tt></b>:: A proc or array of procs that perform
188
+ # transformations on the data being added
189
+ # to the table.
190
+ # <b><tt>:record_class</tt></b>:: Specify the class of the table's
191
+ # records.
192
+ #
193
+ # Example:
194
+ #
195
+ # class Book < ActiveRecord::Base
196
+ # belongs_to :author
197
+ # acts_as_reportable
198
+ # end
199
+ #
200
+ # Book.report_table_by_sql("SELECT * FROM books")
201
+ #
202
+ def report_table_by_sql(sql, options = {})
203
+ record_class = options.delete(:record_class) || Ruport::Data::Record
204
+ filters = options.delete(:filters)
205
+ transforms = options.delete(:transforms)
206
+ self.aar_columns = []
207
+
208
+ data = find_by_sql(sql)
209
+ data = data.map {|r| r.reportable_data }.flatten
210
+
211
+ table = Ruport::Data::Table.new(:data => data,
212
+ :column_names => aar_columns,
213
+ :record_class => record_class,
214
+ :filters => filters,
215
+ :transforms => transforms)
216
+ end
217
+
218
+ private
219
+
220
+ def get_include_for_find(report_option)
221
+ includes = report_option.blank? ? aar_options[:include] : report_option
222
+ if includes.is_a?(Hash)
223
+ result = {}
224
+ includes.each do |k,v|
225
+ if v.empty? || !v[:include]
226
+ result.merge!(k => {})
227
+ else
228
+ result.merge!(k => get_include_for_find(v[:include]))
229
+ end
230
+ end
231
+ result
232
+ elsif includes.is_a?(Array)
233
+ result = {}
234
+ includes.each {|i| result.merge!(i => {}) }
235
+ result
236
+ else
237
+ includes
238
+ end
239
+ end
240
+ end
241
+
242
+ # === Overview
243
+ #
244
+ # This module contains methods that will be made available as instance
245
+ # methods to any ActiveRecord model that calls <tt>acts_as_reportable</tt>.
246
+ #
247
+ module InstanceMethods
248
+
249
+ # Grabs all of the object's attributes and the attributes of the
250
+ # associated objects and returns them as an array of record hashes.
251
+ #
252
+ # Associated object attributes are stored in the record with
253
+ # "association.attribute" keys.
254
+ #
255
+ # Passing :only as an option will only get those attributes.
256
+ # Passing :except as an option will exclude those attributes.
257
+ # Must pass :include as an option to access associations. Options
258
+ # may be passed to the included associations by providing the :include
259
+ # option as a hash.
260
+ # Passing :methods as an option will include any methods on the object.
261
+ #
262
+ # Example:
263
+ #
264
+ # class Book < ActiveRecord::Base
265
+ # belongs_to :author
266
+ # acts_as_reportable
267
+ # end
268
+ #
269
+ # abook.reportable_data(:only => ['title'], :include => [:author])
270
+ #
271
+ # Returns:
272
+ #
273
+ # [{'title' => 'book title',
274
+ # 'author.id' => 'author id',
275
+ # 'author.name' => 'author name' }]
276
+ #
277
+ # NOTE: title will only be returned if the value exists in the table.
278
+ # If the books table does not have a title column, it will not be
279
+ # returned.
280
+ #
281
+ # Example:
282
+ #
283
+ # abook.reportable_data(:only => ['title'],
284
+ # :include => { :author => { :only => ['name'] } })
285
+ #
286
+ # Returns:
287
+ #
288
+ # [{'title' => 'book title',
289
+ # 'author.name' => 'author name' }]
290
+ #
291
+ def reportable_data(options = {})
292
+ options = options.merge(self.class.aar_options) unless
293
+ has_report_options?(options)
294
+
295
+ data_records = [get_attributes_with_options(options)]
296
+ Array(options[:methods]).each do |method|
297
+ if options[:qualify_attribute_names]
298
+ m = "#{options[:qualify_attribute_names]}.#{method}"
299
+ else
300
+ m = "#{method}"
301
+ end
302
+ data_records.first[m] = send(method)
303
+ end
304
+
305
+ # Reorder columns to match options[:only]
306
+ self.class.aar_columns = options[:only] if Array === options[:only]
307
+
308
+ self.class.aar_columns |= data_records.first.keys
309
+
310
+ data_records =
311
+ add_includes(data_records, options[:include]) if options[:include]
312
+ data_records
313
+ end
314
+
315
+ private
316
+
317
+ # Add data for all included associations
318
+ #
319
+ def add_includes(data_records, includes)
320
+ include_has_options = includes.is_a?(Hash)
321
+ associations = include_has_options ? includes.keys : Array(includes)
322
+
323
+ associations.each do |association|
324
+ existing_records = data_records.dup
325
+ data_records = []
326
+
327
+ if include_has_options
328
+ assoc_options = includes[association].merge({
329
+ :qualify_attribute_names => association })
330
+ else
331
+ assoc_options = { :qualify_attribute_names => association }
332
+ end
333
+
334
+ association_objects = [send(association)].flatten.compact
335
+
336
+ existing_records.each do |existing_record|
337
+ if association_objects.empty?
338
+ data_records << existing_record
339
+ else
340
+ association_objects.each do |obj|
341
+ association_records = obj.reportable_data(assoc_options)
342
+ association_records.each do |assoc_record|
343
+ data_records << existing_record.merge(assoc_record)
344
+ end
345
+ self.class.aar_columns |= data_records.last.keys
346
+ end
347
+ end
348
+ end
349
+ end
350
+ data_records
351
+ end
352
+
353
+ # Check if the options hash has any report options
354
+ # (:only, :except, :methods, or :include).
355
+ #
356
+ def has_report_options?(options)
357
+ options[:only] || options[:except] || options[:methods] ||
358
+ options[:include]
359
+ end
360
+
361
+ # Get the object's attributes using the supplied options.
362
+ #
363
+ # Use the :only or :except options to limit the attributes returned.
364
+ #
365
+ # Use the :qualify_attribute_names option to append the association
366
+ # name to the attribute name as association.attribute
367
+ #
368
+ def get_attributes_with_options(options = {})
369
+ only_or_except =
370
+ if options[:only] or options[:except]
371
+ { :only => options[:only], :except => options[:except] }
372
+ end
373
+ attrs = attributes(only_or_except)
374
+ attrs = attrs.inject({}) {|h,(k,v)|
375
+ h["#{options[:qualify_attribute_names]}.#{k}"] = v; h
376
+ } if options[:qualify_attribute_names]
377
+ attrs
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ ActiveRecord::Base.send :include, Ruport::Reportable
@@ -0,0 +1,279 @@
1
+ class Array
2
+ def to_table(columns)
3
+ Table(columns) { |t| each { |r| t << r } }
4
+ end
5
+ end
6
+
7
+
8
+ #!/usr/bin/env ruby -w
9
+ require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
10
+
11
+ begin
12
+ require "mocha"
13
+ require "stubba"
14
+ Ruport.quiet { require "active_record" }
15
+ rescue LoadError
16
+ nil
17
+ end
18
+
19
+ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
20
+
21
+ require "ruport/acts_as_reportable"
22
+
23
+ class Team < ActiveRecord::Base
24
+ acts_as_reportable :except => 'id', :include => :players
25
+ has_many :players
26
+ end
27
+
28
+ class Player < ActiveRecord::Base
29
+ acts_as_reportable
30
+ belongs_to :team
31
+ belongs_to :personal_trainer
32
+
33
+ def stats
34
+ "#{name} stats"
35
+ end
36
+ end
37
+
38
+ module SomeModule
39
+ class PersonalTrainer < ActiveRecord::Base
40
+ acts_as_reportable
41
+ has_one :team
42
+ has_many :players
43
+ end
44
+ end
45
+
46
+ module ModelStubsSetup
47
+ Column = ActiveRecord::ConnectionAdapters::Column
48
+ PersonalTrainer = SomeModule::PersonalTrainer
49
+
50
+ def setup
51
+ setup_column_stubs
52
+
53
+ @trainers = []
54
+ @trainers << PersonalTrainer.new(:name => "Trainer 1")
55
+ @trainers << PersonalTrainer.new(:name => "Trainer 2")
56
+ @teams = []
57
+ @teams << Team.new( :name => "Testers",
58
+ :league => "My League")
59
+ @teams << Team.new( :name => "Others",
60
+ :league => "Other League")
61
+ @players = []
62
+ @players << Player.new( :team_id => 1,
63
+ :name => "Player 1",
64
+ :personal_trainer_id => 1)
65
+ @players << Player.new( :team_id => 1,
66
+ :name => "Player 2",
67
+ :personal_trainer_id => 2)
68
+
69
+ setup_find_stubs
70
+ end
71
+
72
+ private
73
+
74
+ def setup_column_stubs
75
+ PersonalTrainer.stubs(:columns).returns([
76
+ Column.new("id", nil, "integer", false),
77
+ Column.new("name", nil, "string", false)])
78
+ Team.stubs(:columns).returns([Column.new("id", nil, "integer", false),
79
+ Column.new("name", nil, "string", false),
80
+ Column.new("league", nil, "string", true)])
81
+ Player.stubs(:columns).returns([Column.new("id", nil, "integer", false),
82
+ Column.new("team_id", nil, "integer", true),
83
+ Column.new("name", nil, "string", false),
84
+ Column.new("personal_trainer_id", nil, "integer", true)])
85
+ end
86
+
87
+ def setup_find_stubs
88
+ PersonalTrainer.stubs(:find).returns(@trainers)
89
+ @trainers[0].stubs(:players).returns([@players[0]])
90
+ @trainers[1].stubs(:players).returns([@players[1]])
91
+ Team.stubs(:find).returns(@teams)
92
+ @teams[0].stubs(:players).returns(@players)
93
+ @teams[1].stubs(:players).returns([])
94
+ Player.stubs(:find).returns(@players)
95
+ Player.stubs(:find_by_sql).returns(@players)
96
+ @players[0].stubs(:team).returns(@teams[0])
97
+ @players[1].stubs(:team).returns(@teams[0])
98
+ @players[0].stubs(:personal_trainer).returns(@trainers[0])
99
+ @players[1].stubs(:personal_trainer).returns(@trainers[1])
100
+ end
101
+ end
102
+
103
+
104
+ class TestActsAsReportableClassMethods < Test::Unit::TestCase
105
+
106
+ def test_aar_options_set
107
+ assert_equal({:except => 'id', :include => :players}, Team.aar_options)
108
+ end
109
+ end
110
+
111
+ class TestActsAsReportableSingletonMethods < Test::Unit::TestCase
112
+ include ModelStubsSetup
113
+
114
+ def test_basic_report_table
115
+ actual = Player.report_table
116
+ expected = [[1, "Player 1", 1],
117
+ [1, "Player 2", 2]].to_table(%w[team_id name personal_trainer_id])
118
+ assert_equal expected, actual
119
+ end
120
+
121
+ def test_report_table_by_sql
122
+ actual = Player.report_table_by_sql("SELECT * FROM players")
123
+ expected = [[1, "Player 1", 1],
124
+ [1, "Player 2", 2]].to_table(%w[team_id name personal_trainer_id])
125
+ assert_equal expected, actual
126
+ end
127
+
128
+ def test_only_option
129
+ actual = Player.report_table(:all, :only => 'name')
130
+ expected = [["Player 1"],["Player 2"]].to_table(%w[name])
131
+ assert_equal expected, actual
132
+ end
133
+
134
+ def test_only_option_preserves_column_sort_order
135
+ column_order = %w[name personal_trainer_id team_id]
136
+ actual = Player.report_table(:all, :only => column_order)
137
+ expected = [["Player 1", 1, 1],
138
+ ["Player 2", 2, 1]].to_table(column_order)
139
+ assert_equal expected, actual
140
+ end
141
+
142
+ def test_except_option
143
+ actual = Player.report_table(:all, :except => 'personal_trainer_id')
144
+ expected = [[1, "Player 1"],[1, "Player 2"]].to_table(%w[team_id name])
145
+ assert_equal expected, actual
146
+ end
147
+
148
+ def test_methods_option
149
+ actual = Player.report_table(:all, :only => 'name', :methods => :stats)
150
+ expected = [["Player 1", "Player 1 stats"],
151
+ ["Player 2", "Player 2 stats"]].to_table(%w[name stats])
152
+ assert_equal expected, actual
153
+ end
154
+
155
+ def test_include_option
156
+ actual = Player.report_table(:all, :only => 'name',
157
+ :include => :personal_trainer)
158
+ expected = [["Player 1", "Trainer 1"],
159
+ ["Player 2", "Trainer 2"]].to_table(%w[name personal_trainer.name])
160
+ assert_equal expected, actual
161
+ end
162
+
163
+ def test_column_sorting_works_with_include_option
164
+ actual = Player.report_table(:all,
165
+ :only => %w[name personal_trainer.name],
166
+ :include => { :personal_trainer => { :only => %w[name] } })
167
+ expected = [["Player 1", "Trainer 1"],
168
+ ["Player 2", "Trainer 2"]].to_table(%w[name personal_trainer.name])
169
+ assert_equal expected, actual
170
+
171
+ actual = Player.report_table(:all,
172
+ :only => %w[personal_trainer.name name],
173
+ :include => { :personal_trainer => { :only => %w[name] } })
174
+ expected = [["Trainer 1", "Player 1"],
175
+ ["Trainer 2", "Player 2"]].to_table(%w[personal_trainer.name name])
176
+ assert_equal expected, actual
177
+ end
178
+
179
+ def test_include_has_options
180
+ actual = Team.report_table(:all, :only => 'name',
181
+ :include => { :players => { :only => 'name' } })
182
+ expected = [["Testers", "Player 1"],
183
+ ["Testers", "Player 2"],
184
+ ["Others", nil]].to_table(%w[name players.name])
185
+ assert_equal expected, actual
186
+ end
187
+
188
+ class CustomRecord < Ruport::Data::Record; end
189
+
190
+ def test_record_class_option
191
+ actual = Player.report_table(:all, :record_class => CustomRecord)
192
+ actual.each { |r| assert_equal CustomRecord, r.class }
193
+
194
+ actual = Player.report_table_by_sql("SELECT * FROM players",
195
+ :record_class => CustomRecord)
196
+ actual.each { |r| assert_equal CustomRecord, r.class }
197
+ end
198
+
199
+ def test_get_include_for_find
200
+ assert_equal :players, Team.send(:get_include_for_find, nil)
201
+ assert_equal nil, Player.send(:get_include_for_find, nil)
202
+ assert_equal :team, Player.send(:get_include_for_find, :team)
203
+ expected = {:team => {}}
204
+ assert_equal expected,
205
+ Player.send(:get_include_for_find, {:team => {:except => 'id'}})
206
+ expected = {:team => {:a => {}, :b => {}},
207
+ :c => {:d => {:e => {}, :f => {}}},
208
+ :g => {}}
209
+ assert_equal expected,
210
+ Player.send(:get_include_for_find, {:team => {:include => [:a,:b]},
211
+ :c => {:include => {:d => {:include => [:e,:f]}}}, :g => {}})
212
+ end
213
+ end
214
+
215
+ class TestActsAsReportableInstanceMethods < Test::Unit::TestCase
216
+ include ModelStubsSetup
217
+
218
+ def test_reportable_data
219
+ actual = @players[0].reportable_data
220
+ expected = [{ 'team_id' => 1,
221
+ 'name' => "Player 1",
222
+ 'personal_trainer_id' => 1 }]
223
+ assert_equal expected, actual
224
+
225
+ actual = @teams[0].reportable_data(:include =>
226
+ { :players => { :only => 'name' } })
227
+ expected = [{ 'name' => "Testers",
228
+ 'league' => "My League",
229
+ 'players.name' => "Player 1" },
230
+ { 'name' => "Testers",
231
+ 'league' => "My League",
232
+ 'players.name' => "Player 2" }]
233
+ assert_equal expected, actual
234
+ end
235
+
236
+ def test_add_includes
237
+ actual = @players[0].send(:add_includes,
238
+ [{ 'name' => "Player 1" }], :personal_trainer)
239
+ expected = [{ 'name' => "Player 1",
240
+ 'personal_trainer.name' => "Trainer 1" }]
241
+ assert_equal expected, actual
242
+ end
243
+
244
+ def test_has_report_options
245
+ assert @teams[0].send(:has_report_options?, { :only => 'name' })
246
+ assert @teams[0].send(:has_report_options?, { :except => 'name' })
247
+ assert @teams[0].send(:has_report_options?, { :methods => 'name' })
248
+ assert @teams[0].send(:has_report_options?, { :include => 'name' })
249
+ assert !@teams[0].send(:has_report_options?, { :foo => 'name' })
250
+ end
251
+
252
+ def test_get_attributes_with_options
253
+ actual = @players[0].send(:get_attributes_with_options)
254
+ expected = { 'team_id' => 1,
255
+ 'name' => "Player 1",
256
+ 'personal_trainer_id' => 1 }
257
+ assert_equal expected, actual
258
+
259
+ actual = @players[0].send(:get_attributes_with_options,
260
+ { :only => 'name' })
261
+ expected = { 'name' => "Player 1" }
262
+ assert_equal expected, actual
263
+
264
+ actual = @players[0].send(:get_attributes_with_options,
265
+ { :except => 'personal_trainer_id' })
266
+ expected = { 'team_id' => 1,
267
+ 'name' => "Player 1" }
268
+ assert_equal expected, actual
269
+
270
+ actual = @players[0].send(:get_attributes_with_options,
271
+ { :only => 'name', :qualify_attribute_names => :players })
272
+ expected = { 'players.name' => "Player 1" }
273
+ assert_equal expected, actual
274
+ end
275
+ end
276
+
277
+ else
278
+ $stderr.puts "Warning: Mocha and/or ActiveRecord not found -- skipping AAR tests"
279
+ end
data/test/helpers.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "test/unit"
2
+ begin; require "rubygems"; rescue LoadError; nil; end
3
+ require "ruport"
4
+ require "spec-unit"
5
+
6
+ class Test::Unit::TestCase
7
+ include SpecUnit
8
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: acts_as_reportable
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-12-25 00:00:00 -05:00
8
+ summary: ActiveRecord support for Ruby Reports
9
+ require_paths:
10
+ - lib
11
+ email: mikem836@gmail.com
12
+ homepage: http://rubyreports.org
13
+ rubyforge_project: ruport
14
+ description: acts_as_reportable provides ActiveRecord support for Ruby Reports
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Michael Milner
31
+ files:
32
+ - lib/ruport
33
+ - lib/ruport/acts_as_reportable.rb
34
+ - test/helpers.rb
35
+ - test/acts_as_reportable_test.rb
36
+ - Rakefile
37
+ test_files:
38
+ - test/acts_as_reportable_test.rb
39
+ rdoc_options:
40
+ - --title
41
+ - Ruport Documentation
42
+ extra_rdoc_files: []
43
+
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ requirements: []
49
+
50
+ dependencies:
51
+ - !ruby/object:Gem::Dependency
52
+ name: ruport
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Version::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 1.3.0
59
+ version: