ruport 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -33,7 +33,8 @@ class Ruport::Renderer
33
33
  plugin.send something if plugin.respond_to? something
34
34
  end
35
35
  end
36
- # allows you to register a format with the renderer.
36
+
37
+ # Allows you to register a format with the renderer.
37
38
  #
38
39
  # example:
39
40
  #
@@ -44,9 +45,11 @@ class Ruport::Renderer
44
45
  # SomeRenderer.add_format self, :my_plugin
45
46
  #
46
47
  # end
48
+ #
47
49
  def self.add_format(format,name=nil)
48
50
  return formats[name] = format if name
49
51
 
52
+ # NOTE: MEANT FOR INTERNAL USE
50
53
  add_core_format(format)
51
54
  end
52
55
 
@@ -58,6 +61,7 @@ class Ruport::Renderer
58
61
 
59
62
  # same as Renderer#layout, but can be used to specify a default layout object
60
63
  # for the entire class.
64
+ #
61
65
  def self.layout
62
66
  @layout ||= Ruport::Layout::Component.new
63
67
  yield(@layout) if block_given?
@@ -72,6 +76,7 @@ class Ruport::Renderer
72
76
  # The run() method is then called on the renderer method.
73
77
  #
74
78
  # Finally, the value of the plugin's output accessor is returned
79
+ #
75
80
  def self.render(format,&block)
76
81
  rend = build format, &block
77
82
  rend.run
@@ -84,6 +89,7 @@ class Ruport::Renderer
84
89
  # yielded.
85
90
  #
86
91
  # Returns the renderer instance.
92
+ #
87
93
  def self.build(format)
88
94
  rend = self.new
89
95
 
@@ -108,6 +114,7 @@ class Ruport::Renderer
108
114
  end
109
115
 
110
116
  # sets +data+ attribute on both the renderer and any active plugin
117
+ #
111
118
  def data=(val)
112
119
  @data = val.dup
113
120
  plugin.data = @data if plugin
@@ -115,6 +122,7 @@ class Ruport::Renderer
115
122
 
116
123
  # General purpose openstruct which is shared with the current formatting
117
124
  # plugin.
125
+ #
118
126
  def options
119
127
  yield(plugin.options) if block_given?
120
128
  plugin.options
@@ -127,6 +135,7 @@ class Ruport::Renderer
127
135
  #
128
136
  # when a block is given without block variables, instance_evals the block
129
137
  # within the context of the plugin
138
+ #
130
139
  def plugin(&block)
131
140
  if block.nil?
132
141
  return @plugin
@@ -150,6 +159,7 @@ class Ruport::Renderer
150
159
 
151
160
  # tries to autoload and register a format which is part of the Ruport::Format
152
161
  # module. For internal use only.
162
+ #
153
163
  def self.add_core_format(format)
154
164
  try_require(format)
155
165
 
@@ -160,12 +170,14 @@ class Ruport::Renderer
160
170
  end
161
171
 
162
172
  # internal shortcut for format registering
173
+ #
163
174
  def self.add_formats(*formats)
164
175
  formats.each { |f| add_format f }
165
176
  end
166
177
 
167
178
  # Trys to autoload a given format,
168
179
  # silently fails
180
+ #
169
181
  def self.try_require(format)
170
182
  begin
171
183
  require "ruport/format/#{format}"
@@ -175,12 +187,14 @@ class Ruport::Renderer
175
187
  end
176
188
 
177
189
  # selects a plugin for use by format name
190
+ #
178
191
  def use_plugin(format)
179
192
  self.plugin = self.class.formats[format].new
180
193
  end
181
194
 
182
195
  # provides a shortcut to render() to allow
183
196
  # render(:csv) to become render_csv
197
+ #
184
198
  def self.method_missing(id,*args,&block)
185
199
  id.to_s =~ /^render_(.*)/
186
200
  $1 ? render($1.to_sym,&block) : super
data/lib/ruport/report.rb CHANGED
@@ -63,16 +63,9 @@ module Ruport
63
63
  # }
64
64
  #
65
65
  #
66
- # This class can also be used to run templates and process text filters.
67
- #
68
- # See the examples in the documentation below to see how to use these
69
- # features (namely Report#process_text , Report#text_processor, and
70
- # Report#eval_template).
71
- #
72
66
  class Report
73
67
  extend Forwardable
74
68
 
75
- #
76
69
  # When initializing a report, you can provide a default mailer and source by
77
70
  # giving a name of a valid source or mailer you've defined via
78
71
  # Ruport::Config.
@@ -93,7 +86,6 @@ module Ruport
93
86
  # By default, this file will be used by Report#write.
94
87
  attr_accessor :file
95
88
 
96
- #
97
89
  # This attribute will get the results of Report#generate when the report is
98
90
  # run.
99
91
  #
@@ -114,9 +106,9 @@ module Ruport
114
106
  # # will return the value of the last statement, "select * from foo"
115
107
  # result = query "insert into foo values(1,2); select * from foo"
116
108
  #
117
- # You can iterate by row or return the entire set:
109
+ # You can iterate by row:
118
110
  #
119
- # query("select * from foo", :yield_type => :by_row) { |r|
111
+ # query("select * from foo") { |r|
120
112
  # #do something with the rows here
121
113
  # }
122
114
  #
@@ -165,7 +157,6 @@ module Ruport
165
157
  File.open(my_file,"w") { |f| f << my_results }
166
158
  end
167
159
 
168
- #
169
160
  # Like Report#write, but will append to a file rather than overwrite it if
170
161
  # the file already exists.
171
162
  #
@@ -182,7 +173,6 @@ module Ruport
182
173
  self.class.run(options,&block)
183
174
  end
184
175
 
185
- #
186
176
  # Loads a CSV in from a file.
187
177
  #
188
178
  # Example:
@@ -202,7 +192,6 @@ module Ruport
202
192
  end
203
193
  end
204
194
 
205
- #
206
195
  # Executes an erb template. If a filename is given which matches the
207
196
  # pattern /\.r\w+$/ (eg foo.rhtml, bar.rtxt, etc),
208
197
  # it will be loaded and evaluated. Otherwise, the string will be processed
@@ -234,13 +223,11 @@ module Ruport
234
223
  RedCloth.new(s).to_html
235
224
  end
236
225
 
237
- #
238
226
  # Allows logging and other fun stuff.
239
227
  # See also Ruport.log
240
228
  #
241
229
  def log(*args); Ruport.log(*args) end
242
230
 
243
- #
244
231
  # Creates a new Mailer and sets the <tt>to</tt> attribute to the addresses
245
232
  # specified. Yields a Mailer object, which can be modified before delivery.
246
233
  #
@@ -256,7 +243,6 @@ module Ruport
256
243
 
257
244
  class << self
258
245
 
259
- #
260
246
  # Defines an instance method which will be run before the
261
247
  # <tt>generate</tt> method when Ruport.run is executed.
262
248
  #
@@ -264,7 +250,6 @@ module Ruport
264
250
  #
265
251
  def prepare(&block); define_method(:prepare,&block) end
266
252
 
267
- #
268
253
  # Defines an instance method which will be executed by Report.run.
269
254
  #
270
255
  # The return value of this method is assigned to the <tt>results</tt>
@@ -272,13 +257,13 @@ module Ruport
272
257
  #
273
258
  def generate(&block); define_method(:generate,&block) end
274
259
 
275
- #
276
260
  # Defines an instance method which will be executed after the object is
277
261
  # yielded in Report.run.
278
262
  #
279
263
  def cleanup(&block); define_method(:cleanup,&block) end
264
+
265
+ private :prepare, :generate, :cleanup
280
266
 
281
- #
282
267
  # Runs the reports specified. If no reports are specified, then it
283
268
  # creates a new instance via <tt>self.new</tt>.
284
269
  #
@@ -290,9 +275,7 @@ module Ruport
290
275
  #
291
276
  # This method will return the contents of Report#results, as a single
292
277
  # value for single reports, and an array of outputs for multiple reports.
293
-
294
- private :prepare, :generate, :cleanup
295
-
278
+ #
296
279
  def run(options={})
297
280
  options[:reports] ||= [self.new]
298
281
 
data/test/test_mailer.rb CHANGED
@@ -2,6 +2,14 @@ require "test/unit"
2
2
  require "ruport"
3
3
  begin; require "rubygems"; rescue LoadError; nil end
4
4
 
5
+ begin
6
+ require 'mocha'
7
+ require 'stubba'
8
+ require 'net/smtp'
9
+ rescue LoadError
10
+ $stderr.puts "Warning: Mocha not found -- skipping some Mailer tests"
11
+ end
12
+
5
13
  class TestMailer < Test::Unit::TestCase
6
14
 
7
15
  def setup
@@ -40,7 +48,12 @@ class TestMailer < Test::Unit::TestCase
40
48
  def test_constructor_with_mailer_label
41
49
  assert_mailer_equal @other_opts, @other_mailer
42
50
  end
43
-
51
+
52
+ def test_constructor_without_mailer
53
+ Ruport::Config.mailers[:default] = nil
54
+ assert_raise(RuntimeError) { Ruport::Mailer.new }
55
+ end
56
+
44
57
  def test_select_mailer
45
58
  mailer = Ruport::Mailer.new :default
46
59
  assert_mailer_equal @default_opts, mailer
@@ -79,30 +92,79 @@ class TestMailer < Test::Unit::TestCase
79
92
  assert_equal ['RuportDay!'], @default_mailer.subject
80
93
  end
81
94
 
82
- # def test_html
83
- # @default_mailer.instance_eval "@mail.html = 'RuportDay!'"
84
- # assert_equal 'RuportDay!', @default_mailer.html
85
- # end
86
- #
87
- # def test_html_equals
88
- # @default_mailer.html = 'RuportDay!'
89
- # assert_equal 'RuportDay!', @default_mailer.html
90
- # end
91
- #
92
- # def test_text
93
- # @default_mailer.instance_eval "@mail.text = 'RuportDay!'"
94
- # assert_equal 'RuportDay!', @default_mailer.text
95
- # end
96
- #
97
- # def test_text_equals
98
- # @default_mailer.text = 'RuportDay!'
99
- # assert_equal 'RuportDay!', @default_mailer.text
100
- # end
101
-
102
- def test_no_default
103
- Ruport::Config.mailers[:default] = nil
104
- assert_raise(RuntimeError){ Ruport::Mailer.new }
95
+ def test_send_mail_with_default
96
+ return unless Object.const_defined? :Mocha
97
+ setup_mock_mailer(1)
98
+ assert_equal "250 ok",
99
+ @default_mailer.deliver(:to => "clyde@example.com",
100
+ :from => "sue@example.com",
101
+ :subject => "Hello",
102
+ :text => "This is a test.")
103
+ end
104
+
105
+ def test_send_mail_with_other
106
+ return unless Object.const_defined? :Mocha
107
+ setup_mock_mailer(1, @other_mailer)
108
+ assert_equal "250 ok",
109
+ @other_mailer.deliver(:to => "sue@example.com",
110
+ :from => "clyde@example.com",
111
+ :subject => "Hello",
112
+ :text => "This is a test.")
113
+ end
114
+
115
+ def test_send_mail_without_to
116
+ return unless Object.const_defined? :Mocha
117
+ setup_mock_mailer(1)
118
+ assert_raise(Net::SMTPSyntaxError) {
119
+ @default_mailer.deliver(:from => "sue@example.com",
120
+ :subject => "Hello",
121
+ :text => "This is a test.")
122
+ }
123
+ end
124
+
125
+ def test_send_html_mail
126
+ return unless Object.const_defined? :Mocha
127
+ setup_mock_mailer(1)
128
+ assert_equal "250 ok",
129
+ @default_mailer.deliver(:to => "clyde@example.com",
130
+ :from => "sue@example.com",
131
+ :subject => "Hello",
132
+ :html => "<p>This is a test.</p>")
133
+ end
134
+
135
+ def test_send_mail_with_attachment
136
+ return unless Object.const_defined? :Mocha
137
+ setup_mock_mailer(1)
138
+ @default_mailer.attach 'test/samples/data.csv'
139
+ assert_equal "250 ok",
140
+ @default_mailer.deliver(:to => "clyde@example.com",
141
+ :from => "sue@example.com",
142
+ :subject => "Hello",
143
+ :text => "This is a test.")
105
144
  end
106
145
 
146
+ private
147
+
148
+ def setup_mock_mailer(count, mailer=@default_mailer)
149
+ host = mailer.instance_variable_get(:@host)
150
+ port = mailer.instance_variable_get(:@port)
151
+ user = mailer.instance_variable_get(:@user)
152
+ password = mailer.instance_variable_get(:@password)
153
+ auth = mailer.instance_variable_get(:@auth)
154
+
155
+ @smtp = mock('smtp')
156
+
157
+ Net::SMTP.expects(:start).
158
+ with(host,port,host,user,password,auth).
159
+ yields(@smtp).
160
+ returns("250 ok").times(count)
161
+ @smtp.stubs(:send_message).
162
+ with {|*params| !params[2].nil? }.
163
+ returns("250 ok")
164
+ @smtp.stubs(:send_message).
165
+ with {|*params| params[2].nil? }.
166
+ raises(Net::SMTPSyntaxError)
167
+ end
168
+
107
169
  end
108
170
 
data/test/test_report.rb CHANGED
@@ -6,12 +6,22 @@
6
6
  require "test/unit"
7
7
  require "ruport"
8
8
  begin; require "rubygems"; rescue LoadError; nil; end
9
+
10
+ begin
11
+ require 'mocha'
12
+ require 'stubba'
13
+ require 'net/smtp'
14
+ rescue LoadError
15
+ $stderr.puts "Warning: Mocha not found -- skipping some Report tests"
16
+ end
17
+
9
18
  class TestReport < Test::Unit::TestCase
10
19
  include Ruport
11
20
 
12
21
  def setup
13
22
  @report = Report.new
14
- Ruport::Config.source :default, :dsn => "ruport:test", :user => "foo", :password => "bar"
23
+ Ruport::Config.source :default, :dsn => "ruport:test",
24
+ :user => "foo", :password => "bar"
15
25
  @query1 = Ruport::Query.new "select * from foo", :cache_enabled => true
16
26
  @query1.cached_data = [[1,2,3],[4,5,6],[7,8,9]].to_table(%w[a b c])
17
27
  end
@@ -106,5 +116,66 @@ class TestReport < Test::Unit::TestCase
106
116
  assert_equal ["hello dolly", "hello dolly"],
107
117
  rep_klass.run(:reports => [rep_klass.new,rep_klass.new])
108
118
  end
119
+
120
+ def test_send_to
121
+ return unless Object.const_defined? :Mocha
122
+ setup_mock_mailer
123
+ @report = Report.new
124
+ assert_equal "250 ok", @report.send_to("clyde@example.com") { |mail|
125
+ mail.subject = "Test Report"
126
+ mail.text = "Test"
127
+ }
128
+ end
129
+
130
+ def test_write_to_file
131
+ return unless Object.const_defined? :Mocha
132
+ setup_mock_file
133
+ @report = Report.new
134
+ assert @report.write("foo.csv")
135
+ end
136
+
137
+ def test_append_to_file
138
+ return unless Object.const_defined? :Mocha
139
+ setup_mock_file
140
+ @report = Report.new
141
+ assert @report.append("foo.csv")
142
+ end
143
+
144
+ def test_load_csv
145
+ expected = [%w[a b c],['d', nil, 'e']].to_table(%w[col1 col2 col3])
146
+
147
+ @report = Report.new
148
+ table = @report.load_csv("test/samples/data.csv")
149
+
150
+ assert_equal expected, table
151
+ end
152
+
153
+ def test_load_csv_as_array
154
+ expected = [%w[a b c],['d', nil, 'e']]
155
+
156
+ @report = Report.new
157
+ array = @report.load_csv("test/samples/data.csv", :as => :array)
158
+
159
+ assert_equal expected, array
160
+ end
161
+
162
+ private
163
+
164
+ def setup_mock_mailer
165
+ @smtp = mock('smtp')
166
+
167
+ Net::SMTP.expects(:start).
168
+ yields(@smtp).
169
+ returns("250 ok").at_least_once
170
+ @smtp.stubs(:send_message).
171
+ returns("250 ok")
172
+ end
173
+
174
+ def setup_mock_file
175
+ @file = mock("file")
176
+
177
+ File.expects(:open).yields(@file).returns(@file).at_least_once
178
+ @file.expects(:<<).returns(@file).at_least_once
179
+ end
109
180
 
110
181
  end
data/test/test_table.rb CHANGED
@@ -294,6 +294,21 @@ class TestTable < Test::Unit::TestCase
294
294
 
295
295
  end
296
296
 
297
+
298
+ #Ticket #142
299
+ def test_ensure_constructor_dups_record_tags
300
+ a = [[1,2,3],[4,5,6],[7,8,9]].to_table(%w[a b c])
301
+ b = a.dup
302
+
303
+ a[0].tag :foo
304
+ assert_equal [], b[0].tags
305
+ assert_equal [:foo],a[0].tags
306
+
307
+ b[1].tag :bar
308
+ assert_equal [], a[1].tags
309
+ assert_equal [:bar], b[1].tags
310
+ end
311
+
297
312
  def test_setting_column_names_changes_record_attributes
298
313
  table = Ruport::Data::Table.new :column_names => %w[a b c],
299
314
  :data => [[1,2,3],[4,5,6]]