topherfangio-active_report 0.1.1

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Topher Fangio
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ = active_report
2
+
3
+ ActiveReport is a gem designed to assist you in creating reports. Currently is supports
4
+ HTML and CSV reports through an intuitive interface.
5
+
6
+ == Generators
7
+
8
+ Generators are included to create all neccessary files.
9
+
10
+ To create a new report, run the following command:
11
+
12
+ ruby script/generate active_report UserReport
13
+
14
+ You also need to generate the default ActiveReportController which your report controllers
15
+ will extend:
16
+
17
+ ruby script/generate active_report_controller
18
+
19
+ If this file already exists, it will ask if you wish to overwrite it.
20
+
21
+ After running the two previous commands, and starting/restarting your web server (so that
22
+ it rereads routes.rb), you should be able to go to http://localhost/user_reports and see
23
+ a basic form containing a submit button that says "Generate". Clicking this button will
24
+ return you to the "new" page since no data was submitted. Currently you cannot submit an
25
+ empty report, which turns out to be a bad thing, so this is considered a bug and will be
26
+ fixed in a later release.
27
+
28
+ Check out the rdoc for more information on how to use the models.
29
+
30
+ == Copyright
31
+
32
+ Copyright (c) 2009 Topher Fangio. See MIT-LICENSE for details.
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "active_report"
8
+ gem.summary = %Q{ActiveReport enables you to easily generate reports.}
9
+ gem.email = "fangiotophia@gmail.com"
10
+ gem.homepage = "http://github.com/topherfangio/active_report"
11
+ gem.authors = ["Topher Fangio"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "ActiveReport #{version}"
53
+ rdoc.options << '--line-numbers' << '--inline-source'
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
57
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,63 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{active_report}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Topher Fangio"]
9
+ s.date = %q{2009-06-18}
10
+ s.email = %q{fangiotophia@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "README.rdoc"
13
+ ]
14
+ s.files = [
15
+ ".document",
16
+ ".gitignore",
17
+ "MIT-LICENSE",
18
+ "README.rdoc",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "active_report.gemspec",
22
+ "generators/active_report/USAGE",
23
+ "generators/active_report/active_report_generator.rb",
24
+ "generators/active_report/templates/controller.rb",
25
+ "generators/active_report/templates/create.html.erb",
26
+ "generators/active_report/templates/model.rb",
27
+ "generators/active_report/templates/new.html.erb",
28
+ "generators/active_reports_controller/USAGE",
29
+ "generators/active_reports_controller/active_reports_controller_generator.rb",
30
+ "generators/active_reports_controller/templates/active_reports_controller.rb",
31
+ "lib/active_report.rb",
32
+ "lib/active_report/base.rb",
33
+ "lib/active_report/core_extention.rb",
34
+ "lib/active_report/errors.rb",
35
+ "lib/active_report/validations.rb",
36
+ "rails/init.rb",
37
+ "tasks/active_report_tasks.rake",
38
+ "test/active_report_test.rb",
39
+ "test/core_extention_test.rb",
40
+ "test/test_helper.rb"
41
+ ]
42
+ s.has_rdoc = true
43
+ s.homepage = %q{http://github.com/topherfangio/active_report}
44
+ s.rdoc_options = ["--charset=UTF-8"]
45
+ s.require_paths = ["lib"]
46
+ s.rubygems_version = %q{1.3.1}
47
+ s.summary = %q{ActiveReport enables you to easily generate reports.}
48
+ s.test_files = [
49
+ "test/test_helper.rb",
50
+ "test/core_extention_test.rb",
51
+ "test/active_report_test.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 2
57
+
58
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
+ else
60
+ end
61
+ else
62
+ end
63
+ end
@@ -0,0 +1,16 @@
1
+ Description:
2
+ Creates all of the files neccessary to generate
3
+ a basic report and adds the appropriate route to
4
+ `routes.rb`. It does not create the base class
5
+ for the controllers, to do so, run the
6
+ active_reports_controller generator.
7
+
8
+ Example:
9
+ `./script/generate active_report UserReport`
10
+
11
+ This will create:
12
+ app/controllers/user_reports_controller.rb
13
+ app/models/user_report.rb
14
+ app/view/user_reports
15
+ app/view/user_reports/create.html.erb
16
+ app/view/user_reports/new.html.erb
@@ -0,0 +1,20 @@
1
+ class ActiveReportGenerator < Rails::Generator::NamedBase
2
+ attr_reader :root
3
+
4
+ def manifest
5
+ root = "."
6
+ @root = File.expand_path(File.directory?(root) ? root : File.join(Dir.pwd, root))
7
+
8
+ record do |m|
9
+ m.template 'controller.rb', "app/controllers/#{file_name.pluralize}_controller.rb"
10
+ m.template 'model.rb', "app/models/#{file_name}.rb"
11
+
12
+ m.directory "app/views/#{file_name.pluralize}"
13
+ m.template 'create.html.erb', "app/views/#{file_name.pluralize}/create.html.erb"
14
+ m.template 'new.html.erb', "app/views/#{file_name.pluralize}/new.html.erb"
15
+
16
+ m.route_resources file_name.pluralize
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,2 @@
1
+ class <%= class_name.pluralize %>Controller < ActiveReportsController
2
+ end
@@ -0,0 +1,3 @@
1
+ <p>
2
+ <%%= link_to "New <%= class_name.titleize %>", new_<%= file_name %>_path %>
3
+ </p>
@@ -0,0 +1,9 @@
1
+ class <%= class_name %> < ActiveReport::Base
2
+
3
+ def build_report
4
+ end
5
+
6
+ def to_csv
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ <fieldset>
2
+ <legend>New <%= class_name.titleize %></legend>
3
+
4
+ <%% form_for @report do |f| %>
5
+ <%%= f.error_messages %>
6
+
7
+ <%%= f.submit "Generate Report" %>
8
+ <%% end %>
9
+ </fieldset>
@@ -0,0 +1,16 @@
1
+ Description:
2
+ Creates the file containing the base class that
3
+ all reports extend.
4
+
5
+ Example:
6
+ `./script/generate active_reports_controller`
7
+
8
+ This will create:
9
+ app/controllers/active_reports_controller.rb
10
+
11
+ If app/controllers/active_reports_controller.rb
12
+ exists, it will ask you whether or not you wish
13
+ to overwrite the file. Generally it is safest to
14
+ say no in case you have made any changes (such
15
+ as adding a `before_filter :require_admin` or
16
+ similar).
@@ -0,0 +1,7 @@
1
+ class ActiveReportsControllerGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.file 'active_reports_controller.rb', "app/controllers/active_reports_controller.rb"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,51 @@
1
+ class ActiveReportsController < ApplicationController
2
+
3
+ def new
4
+ @report = eval("#{self.controller_name.singularize.camelize}.new")
5
+
6
+ respond_to do |format|
7
+ format.html
8
+ end
9
+ end
10
+
11
+ def create
12
+ model = self.controller_name.singularize.camelize
13
+
14
+ if params.nil? or params[model.underscore].nil?
15
+ redirect_to :action => :new and return
16
+ end
17
+
18
+ @report = eval("#{model}.new(params[:#{model.underscore}])")
19
+
20
+ respond_to do |format|
21
+ if @report.generate
22
+ format.html
23
+ format.xml { render :xml => @report }
24
+ format.csv do
25
+ filename = []
26
+
27
+ filename << model.underscore
28
+ filename << '-'
29
+ filename << Time.now.strftime("%Y%m%d-%H%M%S")
30
+ filename << '.csv'
31
+
32
+ csv = @report.to_csv
33
+
34
+ if csv.present?
35
+ send_data(csv, :filename => filename.join, :type => 'text/csv', :disposition => 'attachment')
36
+ else
37
+ render :text => "This report cannot be exported to a comma separated values (CSV) list."
38
+ end
39
+ end
40
+ else
41
+ format.html { render :action => "new" }
42
+ format.xml { render :xml => @report.errors, :status => :unprocessable_entity }
43
+ format.csv { render :text => 'An error occured when processing the report.' }
44
+ end
45
+ end
46
+ end
47
+
48
+ def index
49
+ redirect_to :action => :new
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ # ActiveReport
2
+ require 'active_report/core_extention'
3
+
4
+ require 'active_report/errors'
5
+ require 'active_report/validations'
6
+
7
+ require 'active_report/base'
8
+
9
+ %w{ controllers }.each do |dir|
10
+ path = File.join(File.dirname(__FILE__), 'app', dir)
11
+
12
+ $LOAD_PATH << path
13
+ ActiveSupport::Dependencies.load_paths << path
14
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
15
+ end
@@ -0,0 +1,351 @@
1
+ module ActiveReport
2
+
3
+ # Special form of a hash that responds to methods if the method is a key in
4
+ # the entry. Also allows passing a hash as the argement to +new+ to allow for
5
+ # initialization of the +HashEntry+.
6
+ #
7
+ # *Note*: This means you should not have keys whose name is the name of an
8
+ # existing +Hash+ method.
9
+ class HashEntry < Hash
10
+ def initialize(hash = nil)
11
+ super
12
+
13
+ self.update(hash) unless has.nil?
14
+ end
15
+
16
+ def method_missing(symbol, *args, &block)
17
+ if self[symbol]
18
+ self[symbol]
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def respond_to?(symbol, include_private = false)
25
+ if self[symbol]
26
+ true
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ end # Class HashEntry
33
+
34
+ # An Entry class designed to store the sign on the entry for easier
35
+ # manipulation of the stored object.
36
+ class SignedEntry
37
+ attr_accessor :object, :sign
38
+
39
+ # Creates a new SignedEntry. The sign parameter defaults to
40
+ # <tt>:positive</tt> but accepts any object. If one of the following
41
+ # values are entered for the sign, the sign is automatically
42
+ # converted to a <tt>1</tt> or <tt>-1</tt> depending upon the value
43
+ # entered.
44
+ #
45
+ # * <tt>true</tt>
46
+ # * <tt>false</tt>
47
+ # * <tt>:true, :positive</tt>
48
+ # * <tt>:false, :negative</tt>
49
+ # * <tt>"true", "positive"</tt>
50
+ # * <tt>"false", "negative"</tt>
51
+ def initialize(object = nil, sign = :positive)
52
+ @object = object
53
+
54
+ @sign = case
55
+ when sign.to_s.eql?("true") then 1
56
+ when sign.to_s.eql?("false") then -1
57
+ when sign.to_s.eql?("positive") then 1
58
+ when sign.to_s.eql?("negative") then -1
59
+ else sign
60
+ end
61
+ end
62
+
63
+ # Returns true if the sign is greater than or equal to 0.
64
+ #
65
+ # This method is aliased as credit?.
66
+ def positive?
67
+ @sign >= 0
68
+ end
69
+
70
+ alias_method :credit?, :positive?
71
+
72
+ # Returns true if the sign is less than 0.
73
+ #
74
+ # This method is aliased as debit?.
75
+ def negative?
76
+ @sign < 0
77
+ end
78
+
79
+ alias_method :debit?, :negative?
80
+ end # Class SignedEntry
81
+
82
+
83
+ # Active Report objects define how to build a particular report and all required
84
+ # information. Unlike Active Record objects, Active Reports are not saved to nor
85
+ # retrieved from a database, but rather aggregate data from existing Active Record
86
+ # objects (or any other means required).
87
+ #
88
+ # == Creation
89
+ #
90
+ # Active Reports offer many helper methods to assist in creation. For instance, you
91
+ # can specify any number of attributes with the define_attributes method. These
92
+ # attributes will be available to the rest of the class and will be populated with
93
+ # any values that were passed to the +new+ method.
94
+ #
95
+ # class JobReport < ActiveReport::Base
96
+ # define_attribute :jobNumber
97
+ #
98
+ # validates_presence_of :jobNumber
99
+ #
100
+ # def build_report
101
+ # entries = Job.find_all_by_jobNumber(self.jobNumber)
102
+ # end
103
+ # end
104
+ #
105
+ # Alternatively, you could use an ActiveReport::HashEntry or simple +Hash+.
106
+ #
107
+ # class TestReport < ActiveReport::Base
108
+ # def build_report
109
+ # (1..5).each { |i| entries.add(ActiveReport::HashEntry.new( :i => i, :name => 'Topher' )) }
110
+ # end
111
+ # end
112
+ #
113
+ # class TestReport < ActiveReport::Base
114
+ # def build_report
115
+ # (1..5).each { |i| entries.add({ :i => i, :name => 'Topher' }) }
116
+ # end
117
+ # end
118
+ #
119
+ # == Reporting
120
+ #
121
+ # Generating reports is incredibly easy. The following example shows basic usage
122
+ # assuming that +Job+ is a class extending +ActiveRecord::Base+.
123
+ #
124
+ # Job.create( :id => 1, :jobNumber => 123456, :company => "Apple Inc." )
125
+ # Job.create( :id => 2, :jobNumber => 123456, :company => "37signals" )
126
+ #
127
+ # params = {}
128
+ # params[:jobNumber] = 123456
129
+ #
130
+ # report = JobReport.new(params)
131
+ #
132
+ # if report.generate
133
+ # report.entries.each { |e| puts "#{e.id}: Job ##{e.jobNumber} for #{e.company}" }
134
+ # end
135
+ #
136
+ # # => 1: Job #123456 for Apple Inc.
137
+ # 2: Job #123456 for 37signals
138
+ class Base
139
+ include Enumerable
140
+ include ActiveSupport::Callbacks
141
+ include ActiveReport::Validations
142
+
143
+ define_callbacks :before_initialize, :after_initialize
144
+ define_callbacks :before_build_report, :after_build_report
145
+ define_callbacks :before_validate, :validate, :after_validate
146
+
147
+ attr_accessor :id, :params, :errors, :entries
148
+
149
+ # Sets up all parameters including mulit-parameters-attributes. Sets the id of the
150
+ # report to be the current +Time+ as an integer of the +strftime+ format
151
+ # +"%Y%m%d%H%M%S"+.
152
+ def initialize(params = {})
153
+ @params = setup_parameters(params)
154
+
155
+ run_callbacks(:before_initialize)
156
+
157
+ @id = Time.now.strftime("%Y%m%d%H%M%S").to_i
158
+
159
+ @errors = ActiveReport::Errors.new
160
+ @entries = []
161
+
162
+ run_callbacks(:after_initialize)
163
+ end
164
+
165
+ private
166
+
167
+ def setup_parameters(params = {})
168
+ new_params = {}
169
+ multi_parameter_attributes = []
170
+
171
+ params.each do |k,v|
172
+ if k.to_s.include?("(")
173
+ multi_parameter_attributes << [ k.to_s, v ]
174
+ else
175
+ new_params[k.to_s] = v
176
+ end
177
+ end
178
+
179
+ new_params.merge(assign_multiparameter_attributes(multi_parameter_attributes))
180
+ end
181
+
182
+ # Very simplified version of the ActiveRecord::Base method that handles only dates/times
183
+ def execute_callstack_for_multiparameter_attributes(callstack)
184
+ attributes = {}
185
+
186
+ callstack.each do |name, values|
187
+
188
+ if values.empty?
189
+ send(name + '=', nil)
190
+ else
191
+ value = case values.size
192
+ when 2 then t = Time.new; Time.local(t.year, t.month, t.day, values[0], values[min], 0, 0)
193
+ when 5 then t = Time.time_with_datetime_fallback(:local, *values)
194
+ when 3 then Date.new(*values)
195
+ else nil
196
+ end
197
+
198
+ attributes[name.to_s] = value
199
+ end
200
+
201
+ end
202
+
203
+ attributes
204
+ end
205
+
206
+ # Note, the following private methods are copied (almost) directly from ActiveRecord::Base 2.3.3
207
+
208
+ def assign_multiparameter_attributes(pairs)
209
+ execute_callstack_for_multiparameter_attributes( extract_callstack_for_multiparameter_attributes(pairs) )
210
+ end
211
+
212
+ def extract_callstack_for_multiparameter_attributes(pairs)
213
+ attributes = { }
214
+
215
+ for pair in pairs
216
+ multiparameter_name, value = pair
217
+ attribute_name = multiparameter_name.split("(").first
218
+ attributes[attribute_name] = [] unless attributes.include?(attribute_name)
219
+
220
+ unless value.empty?
221
+ attributes[attribute_name] <<
222
+ [ find_parameter_position(multiparameter_name), type_cast_attribute_value(multiparameter_name, value) ]
223
+ end
224
+ end
225
+
226
+ attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
227
+ end
228
+
229
+ def type_cast_attribute_value(multiparameter_name, value)
230
+ multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value
231
+ end
232
+
233
+ def find_parameter_position(multiparameter_name)
234
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
235
+ end
236
+
237
+ public
238
+
239
+ # Generates the report by calling +build_report+ and runs validation if requested.
240
+ # Calls +before_build_report+ at the beginning and +after_build_report+ at the end
241
+ # and returns the report against which this method was run.
242
+ def generate(perform_validation = true)
243
+ return false if perform_validation and not self.valid?
244
+
245
+ run_callbacks(:before_build_report)
246
+ send(:build_report) if self.respond_to? :build_report
247
+ run_callbacks(:after_build_report)
248
+
249
+ self
250
+ end
251
+
252
+ # Runs +before_validate+, +validate+ and +after_validate+ and returns
253
+ # true if there were no errors, false otherwise.
254
+ def valid?
255
+ run_callbacks(:before_validate)
256
+
257
+ @errors = ActiveReport::Errors.new
258
+
259
+ run_callbacks(:validate)
260
+ run_callbacks(:after_validate)
261
+
262
+ @errors.empty?
263
+ end
264
+
265
+ # Defined to always return true since no data actually gets saved to the database.
266
+ # This is necessary for the +form_for+ methods in
267
+ # +ActionView::Helpers::FormHelper+ to work properly.
268
+ def new_record?
269
+ true
270
+ end
271
+
272
+ # Override this method to allow for exporting to a csv file.
273
+ #
274
+ # Example:
275
+ #
276
+ # def to_csv
277
+ # FasterCSV.generate do |csv|
278
+ # csv << [ 'Name', 'Date' ]
279
+ #
280
+ # @entries.each do |e|
281
+ # csv << [ e.name, e.created_at ]
282
+ # end
283
+ # end
284
+ # end
285
+ def to_csv
286
+ end
287
+
288
+ protected
289
+ # Helper method to easily define new attributes. For example, the following
290
+ #
291
+ # class TestReport < ActiveReport::Base
292
+ # define_attributes :jobNumber, :jobStage
293
+ # end
294
+ #
295
+ # is equivalent to
296
+ #
297
+ # class TestReport < ActiveReport::Base
298
+ # attr_accessor :jobNumber, :jobStage
299
+ #
300
+ # def intialize(params = {})
301
+ # super
302
+ #
303
+ # @jobNumber = params["jobNumber"]
304
+ # @jobStage = params["jobStage"]
305
+ # end
306
+ # end
307
+ #
308
+ # Accepts multiple attributes and is also aliased as +define_attribute+.
309
+ def self.define_attributes(*attribs)
310
+ return if attribs.nil?
311
+
312
+ send(:before_initialize) do |report|
313
+ attribs.each do |attrib|
314
+ report.class.instance_eval "attr_accessor :#{attrib.to_s}"
315
+
316
+ report.instance_eval("@#{attrib.to_s} = params['#{attrib.to_s}'] unless params.blank?")
317
+ end
318
+ end
319
+ end
320
+
321
+ class << self
322
+ alias_method :define_attribute, :define_attributes
323
+ end
324
+
325
+ # Callback run immediately before +build_report+.
326
+ def before_build_report
327
+ end
328
+
329
+ # Override this to builds the report and all entries.
330
+ def build_report
331
+ end
332
+
333
+ # Callback run immediately after +build_report+.
334
+ def after_build_report
335
+ end
336
+
337
+ # Callback run immediately before +validate+.
338
+ def before_validate
339
+ end
340
+
341
+ # Overwrite this method for validation checks on generation of report
342
+ # and use +Errors.add(message)+ for invalid attributes.
343
+ def validate
344
+ end
345
+
346
+ # Callback run immediately after +validate+.
347
+ def after_validate
348
+ end
349
+ end # Class Base
350
+
351
+ end # Module ActiveReport
@@ -0,0 +1,15 @@
1
+ Array.class_eval do
2
+
3
+ def count
4
+ size # Temporary fix because I can't upgrade the version of ruby on wildcat
5
+ end
6
+
7
+ alias_method :add, :<<
8
+ end unless Array.new.respond_to? :add
9
+
10
+ Object.class_eval do
11
+ def self.alias_class_method(new_name, old_name)
12
+ meta = class << self; self; end
13
+ meta.send :alias_method, new_name, old_name
14
+ end
15
+ end unless Object.respond_to? :alias_class_method
@@ -0,0 +1,11 @@
1
+ module ActiveReport
2
+
3
+ # Error class that allows the use of +f.error_messages+ inside a
4
+ # +form_for+ block.
5
+ class Errors < Array
6
+ def full_messages
7
+ self
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,33 @@
1
+ module ActiveReport
2
+
3
+ module Validations
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ # Ensures that the requested parameters exist and are not empty.
11
+ #
12
+ # class TestReport < ActiveReport::Base
13
+ # validates_presence_of :jobNumber
14
+ # end
15
+ def validates_presence_of(*params)
16
+ return if params.nil?
17
+
18
+ send(:validate) do |report|
19
+ params.each do |param|
20
+ field = report.params[param.to_s]
21
+
22
+ if field.blank?
23
+ report.errors.add "#{param} must be defined"
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end # Module ClassMethods
30
+
31
+ end # Module Validations
32
+
33
+ end # Module ActiveReport
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ require 'active_report'
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :active_report do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveReportTest < ActiveSupport::TestCase
4
+ test "Errors properly extends Array" do
5
+ assert ActiveReport::Errors.new.respond_to? :add
6
+ assert ActiveReport::Errors.new.respond_to? :full_messages
7
+ end
8
+
9
+ test "HashEntry propperly extends Hash" do
10
+ entry = ActiveReport::HashEntry.new(:jobNumber => 123)
11
+
12
+ assert (entry.respond_to? :jobNumber)
13
+ assert entry.jobNumber == 123
14
+ end
15
+
16
+ test "class can extend base" do
17
+ class TestReport < ActiveReport::Base
18
+ end
19
+
20
+ t = TestReport.new
21
+ end
22
+
23
+ test "class can build report" do
24
+ t = SimpleTestReport.new
25
+ t.generate
26
+ end
27
+
28
+ test "class can call basic functions" do
29
+ params = {}
30
+ params[:jobNumber] = 123456
31
+
32
+ t = BasicTestReport.new(params)
33
+ t.generate
34
+
35
+ t.entries.each do |entry|
36
+ assert entry.jobNumber == params[:jobNumber]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class CoreExtentionTest < ActiveSupport::TestCase
4
+ test "array responds to add" do
5
+ assert Array.new.respond_to? :add
6
+ end
7
+
8
+ test "object responds to alias_class_method" do
9
+ assert Object.respond_to? :alias_class_method
10
+
11
+ Object.alias_class_method :aliased_to_s, :to_s
12
+
13
+ assert Object.respond_to? :aliased_to_s
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+ ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '../../../../..'
3
+
4
+ require 'rubygems'
5
+ require 'active_support'
6
+ require 'active_support/test_case'
7
+
8
+ require 'test/unit'
9
+
10
+ require 'active_report'
11
+
12
+ class SimpleTestReport < ActiveReport::Base
13
+ def build_report
14
+ entries.add(ActiveReport::HashEntry.new( :first_name => "Topher", :last_name => "Fangio" ))
15
+ end
16
+ end
17
+
18
+ class BasicTestReport < ActiveReport::Base
19
+ define_attribute :jobNumber
20
+ validates_presence_of :jobNumber
21
+
22
+ def build_report
23
+ entries.add(ActiveReport::HashEntry.new( :jobNumber => @jobNumber ))
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: topherfangio-active_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Topher Fangio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-18 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: fangiotophia@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - .document
26
+ - .gitignore
27
+ - MIT-LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - VERSION
31
+ - active_report.gemspec
32
+ - generators/active_report/USAGE
33
+ - generators/active_report/active_report_generator.rb
34
+ - generators/active_report/templates/controller.rb
35
+ - generators/active_report/templates/create.html.erb
36
+ - generators/active_report/templates/model.rb
37
+ - generators/active_report/templates/new.html.erb
38
+ - generators/active_reports_controller/USAGE
39
+ - generators/active_reports_controller/active_reports_controller_generator.rb
40
+ - generators/active_reports_controller/templates/active_reports_controller.rb
41
+ - lib/active_report.rb
42
+ - lib/active_report/base.rb
43
+ - lib/active_report/core_extention.rb
44
+ - lib/active_report/errors.rb
45
+ - lib/active_report/validations.rb
46
+ - rails/init.rb
47
+ - tasks/active_report_tasks.rake
48
+ - test/active_report_test.rb
49
+ - test/core_extention_test.rb
50
+ - test/test_helper.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/topherfangio/active_report
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --charset=UTF-8
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.2.0
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: ActiveReport enables you to easily generate reports.
77
+ test_files:
78
+ - test/test_helper.rb
79
+ - test/core_extention_test.rb
80
+ - test/active_report_test.rb