ruport 0.7.1 → 0.7.2

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.
@@ -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]]