ruport 0.2.2 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +7 -1
- data/CHANGELOG +22 -1
- data/README +3 -0
- data/Rakefile +1 -1
- data/TODO +5 -6
- data/bin/ruport +1 -1
- data/lib/ruport/format/builder.rb +34 -0
- data/lib/ruport/report/data_row.rb +8 -2
- data/lib/ruport/report/data_set.rb +20 -17
- data/lib/ruport/report/engine.rb +12 -54
- data/lib/ruport/report/fake_engine.rb +2 -24
- data/lib/ruport/report/fake_mailer.rb +23 -0
- data/lib/ruportlib.rb +2 -0
- data/test/tc_builder.rb +25 -0
- data/test/tc_data_row.rb +1 -8
- data/test/tc_data_set.rb +14 -2
- data/test/tc_engine.rb +23 -43
- data/test/tc_mailer.rb +21 -0
- data/test/ts_all.rb +2 -0
- metadata +9 -3
data/AUTHORS
CHANGED
data/CHANGELOG
CHANGED
@@ -1,4 +1,25 @@
|
|
1
|
-
The current version of Ruby Reports is 0.2.
|
1
|
+
The current version of Ruby Reports is 0.2.4
|
2
|
+
|
3
|
+
changes since Ruport 0.2.2:
|
4
|
+
|
5
|
+
- Report::DataSet and Report::DataRow are now enumerable
|
6
|
+
|
7
|
+
- DataSet#eql? fixed
|
8
|
+
|
9
|
+
- Format::Builder has been added to handle formatting
|
10
|
+
(Supports CSV / HTML currently)
|
11
|
+
|
12
|
+
- Format::Builder is easily extendable via send("render_#{@type}")
|
13
|
+
|
14
|
+
- DataSet#to_html convenience method added
|
15
|
+
|
16
|
+
- DataSet#fields can now be arbitrary objects (does not need to be Strings)
|
17
|
+
|
18
|
+
- Dropped DataRow#middle? because it was useless. (And poorly named)
|
19
|
+
|
20
|
+
- FakeMailer added for testing goodness.
|
21
|
+
|
22
|
+
- Dropped select() and execute() in favor of query()
|
2
23
|
|
3
24
|
changes since Ruport 0.2.0:
|
4
25
|
|
data/README
CHANGED
@@ -81,6 +81,9 @@ point, unless you're magic, you'll probably need to either read the
|
|
81
81
|
{API Documentation}[http://ruport.rubyforge.org/docs/] or the source, whichever
|
82
82
|
you're most comfortable with.
|
83
83
|
|
84
|
+
There is also a set of examples at:
|
85
|
+
http://rubyforge.org/frs/?group_id=856&release_id=3481
|
86
|
+
|
84
87
|
I hope you enjoy this software and that it is useful to you.
|
85
88
|
|
86
89
|
-Greg
|
data/Rakefile
CHANGED
data/TODO
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
TODO:
|
2
2
|
|
3
3
|
Bugfixes:
|
4
|
-
- Fix potential failure in Ruport::Report::DataSet#eql?
|
5
|
-
- Is there an OS X packaging problem with the gems?
|
6
4
|
- Fix the manual that is in the example package so it it reads FakeDB instead
|
7
|
-
of MockDB
|
5
|
+
of MockDB. Update the manual to cover new features in 0.2.4
|
8
6
|
|
9
7
|
Improvement:
|
10
8
|
|
11
9
|
- Mail system
|
12
|
-
Hook up unit tests
|
13
10
|
Make attachments doable
|
14
11
|
|
15
12
|
- Template Config / Line Editing
|
@@ -27,6 +24,7 @@ Improvement:
|
|
27
24
|
Expand so that it covers most common SQL commands.
|
28
25
|
Form better more complete unit tests.
|
29
26
|
|
27
|
+
- Queries from file / db need to use ERb or some other replacement ability
|
30
28
|
|
31
29
|
Begin implementing new features:
|
32
30
|
|
@@ -120,5 +118,6 @@ Other:
|
|
120
118
|
This is only the tip of the iceburg. Please feel free to continue to fill my
|
121
119
|
plate by sending any suggestions to gregory.t.brown@gmail.com
|
122
120
|
|
123
|
-
|
124
|
-
|
121
|
+
JEG2 Code Review 2005.11.14: (email me if you find any of this interesting)
|
122
|
+
- use the many levels of logger
|
123
|
+
- RQL (Ruport Query Language)
|
data/bin/ruport
CHANGED
@@ -65,7 +65,7 @@ if ARGV[0].eql?("generate")
|
|
65
65
|
}
|
66
66
|
exit
|
67
67
|
elsif ARGV[0].eql?("-v")
|
68
|
-
puts "Ruport Version 0.2.
|
68
|
+
puts "Ruport Version 0.2.4 \nA ruby report generation system by Gregory " +
|
69
69
|
"Brown.\nThis application is Free Software under the GPL/Ruby License. " +
|
70
70
|
"\nAll praise and/or criticism can be directed to "+
|
71
71
|
"gregory.t.brown@gmail.com"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Ruport
|
2
|
+
module Format
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
def initialize( data_set )
|
6
|
+
@data = data_set
|
7
|
+
@type = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :type
|
11
|
+
|
12
|
+
def render
|
13
|
+
send("render_#{@type}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_csv
|
17
|
+
@data.inject(CSV.generate_line(@data.fields) + "\n") do |out,r|
|
18
|
+
out << CSV.generate_line(@data.fields.map { |f| r[f] }) + "\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_html
|
23
|
+
fields_html = "<tr>\n <td>#{@data.fields.join('</td><td>')}</td>\n </tr>"
|
24
|
+
@data.inject("<table>\n #{fields_html}"){|html,row|
|
25
|
+
html << row.inject(" <tr>\n "){ |row_html, field|
|
26
|
+
row_html << "<td>#{field}</td>"
|
27
|
+
} + "\n </tr>"
|
28
|
+
} + "\n</table>"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -11,6 +11,8 @@ module Ruport
|
|
11
11
|
module Report
|
12
12
|
class DataRow
|
13
13
|
|
14
|
+
include Enumerable
|
15
|
+
|
14
16
|
attr_accessor :fields
|
15
17
|
|
16
18
|
# DataRows are essentially arrays with named ordinal fields and
|
@@ -27,7 +29,7 @@ module Ruport
|
|
27
29
|
#
|
28
30
|
# i.e. row["phone"]
|
29
31
|
def [](key)
|
30
|
-
key.kind_of?(
|
32
|
+
key.kind_of?(Fixnum) ? @data[key] : @data[@fields.index(key)]
|
31
33
|
end
|
32
34
|
|
33
35
|
# Lets you set field values
|
@@ -53,13 +55,17 @@ module Ruport
|
|
53
55
|
# DataRow#first? DataRow#last? DataRow#middle?
|
54
56
|
# DataRow#odd? DataRow#even? which are all conditional methods.
|
55
57
|
def method_missing(method)
|
56
|
-
if %[last? first?
|
58
|
+
if %[last? first? center?].include? method.to_s
|
57
59
|
return @position.eql?(method.to_s[0..-2].to_sym)
|
58
60
|
elsif %[odd? even?].include? method.to_s
|
59
61
|
return @oddness.eql?(method.to_s[0..-2].to_sym)
|
60
62
|
end
|
61
63
|
super
|
62
64
|
end
|
65
|
+
|
66
|
+
def each(&action)
|
67
|
+
@data.each(&action)
|
68
|
+
end
|
63
69
|
|
64
70
|
attr_accessor :position
|
65
71
|
end
|
@@ -9,6 +9,9 @@
|
|
9
9
|
module Ruport
|
10
10
|
module Report
|
11
11
|
class DataSet
|
12
|
+
|
13
|
+
include Enumerable
|
14
|
+
|
12
15
|
def initialize
|
13
16
|
@data = []
|
14
17
|
end
|
@@ -48,19 +51,21 @@ module Ruport
|
|
48
51
|
|
49
52
|
oddness = (@data.length % 2 == 0 ? :even : :odd)
|
50
53
|
position = (@data.length == 0 ? :first : :last)
|
51
|
-
@data[@data.length - 1].position =
|
54
|
+
@data[@data.length - 1].position = nil if @data.length > 1
|
52
55
|
@data << DataRow.new(new_row,@fields,oddness,position)
|
53
56
|
end
|
54
57
|
|
55
58
|
# This works in best case scenario. It should return true if
|
56
59
|
# both DataSets have the same values. Still working out the kinks here.
|
57
60
|
def eql?(data2)
|
58
|
-
return false unless (@data.length == data2.data.length
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
return false unless ( @data.length == data2.data.length and
|
62
|
+
@fields.eql?(data2.fields) )
|
63
|
+
@data.each_with_index do |row, r_index|
|
64
|
+
row.each_with_index do |field, f_index|
|
65
|
+
return false unless field.eql?(data2[r_index][f_index])
|
62
66
|
end
|
63
67
|
end
|
68
|
+
|
64
69
|
return true
|
65
70
|
end
|
66
71
|
|
@@ -82,21 +87,19 @@ module Ruport
|
|
82
87
|
|
83
88
|
# Converts a DataSet to CSV
|
84
89
|
def to_csv
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
builder = Format::Builder.new(self)
|
91
|
+
builder.type = :csv
|
92
|
+
builder.render
|
93
|
+
end
|
94
|
+
# Converts a Dataset to Html
|
95
|
+
def to_html
|
96
|
+
builder = Format::Builder.new(self)
|
97
|
+
builder.type = :html
|
98
|
+
builder.render
|
90
99
|
end
|
91
|
-
|
92
100
|
# Works like a standard each iterator
|
93
101
|
def each(&action)
|
94
|
-
@data
|
95
|
-
end
|
96
|
-
|
97
|
-
# Works like a standard each_with_index iterator
|
98
|
-
def each_with_index(&action)
|
99
|
-
@data[0..-1].each_with_index(&action)
|
102
|
+
@data.each(&action)
|
100
103
|
end
|
101
104
|
|
102
105
|
end
|
data/lib/ruport/report/engine.rb
CHANGED
@@ -21,69 +21,25 @@ module Ruport
|
|
21
21
|
module Report
|
22
22
|
class Engine
|
23
23
|
def initialize( dsn, user, password, mailer=nil )
|
24
|
+
|
25
|
+
File.exists?("log") or FileUtils.mkdir("log")
|
26
|
+
@logger = Logger.new("log/ruport.log")
|
27
|
+
|
24
28
|
@dsn = dsn
|
25
29
|
@user = user
|
26
30
|
@password = password
|
27
|
-
@report_name = ""
|
28
31
|
@mailer = mailer
|
29
|
-
File.exists?("log") or FileUtils.mkdir("log")
|
30
|
-
@logger = Logger.new("log/ruport.log")
|
31
32
|
@generate = true
|
33
|
+
@report_name = ""
|
32
34
|
@report = ""
|
35
|
+
@query_table = nil
|
36
|
+
@file = nil
|
37
|
+
@config = nil
|
33
38
|
end
|
34
39
|
|
35
40
|
attr_accessor :query_table, :file
|
36
41
|
attr_reader :mailer, :generate, :config, :logger
|
37
42
|
|
38
|
-
# * DEPRECATED: Use query() *
|
39
|
-
#
|
40
|
-
# Takes a query, an optional sourcetype, and a block which is passed the
|
41
|
-
# results row by row. When passed a query in string form, it adds the
|
42
|
-
# SELECT clause to the string and executes the query. When passed a
|
43
|
-
# filename and a source :file, it looks in queries/ for the file specified.
|
44
|
-
# When given a database query label, it looks in config[query_table] for a
|
45
|
-
# query with the label specified. If no source is specified, it uses
|
46
|
-
# string by default for the source.
|
47
|
-
#
|
48
|
-
# Example:
|
49
|
-
#
|
50
|
-
# select ( "* FROM test" )
|
51
|
-
# Passes "SELECT * FROM test" to the database
|
52
|
-
#
|
53
|
-
# select ( "test.sql", :file )
|
54
|
-
# Passes the contents of queries/test.sql to the database
|
55
|
-
#
|
56
|
-
# select ( "TEST", :db )
|
57
|
-
# Calls the query TEST stored in the database and query_table specified in
|
58
|
-
# config/ruport.yaml
|
59
|
-
|
60
|
-
def select( query, source = :string, &action )
|
61
|
-
source != :string || query = "SELECT " + query
|
62
|
-
execute( query, source ) do |sth|
|
63
|
-
@column_names = sth.column_names
|
64
|
-
@first_row = true
|
65
|
-
sth.fetch do |row|
|
66
|
-
action.call(row) if block_given?
|
67
|
-
@first_row = false
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# * DEPRECATED, Use query() *
|
73
|
-
#
|
74
|
-
# Takes a query and an optional sourcetype and then runs the query
|
75
|
-
# against the database. The output is not returned. This is useful for
|
76
|
-
# doing construction and destruction actions.
|
77
|
-
def execute( query, source = :string )
|
78
|
-
query = get_query(source, query)
|
79
|
-
DBI.connect(@dsn, @user, @password) do |dbh|
|
80
|
-
dbh.prepare(query) do |sth|
|
81
|
-
sth.execute()
|
82
|
-
yield(sth)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
43
|
# Takes a query and an optional sourcetype and then runs the query
|
88
44
|
# against the database. The return from the query is then converted
|
89
45
|
# into a DataSet which can then be manipulated.
|
@@ -159,8 +115,10 @@ module Ruport
|
|
159
115
|
when :file
|
160
116
|
load_file( query )
|
161
117
|
when :db
|
162
|
-
|
163
|
-
|
118
|
+
query ( "SELECT query FROM #{@query_table} WHERE " +
|
119
|
+
"label LIKE '#{query}';" ) do |data|
|
120
|
+
return data[0]["query"]
|
121
|
+
end
|
164
122
|
end
|
165
123
|
end
|
166
124
|
|
@@ -13,32 +13,10 @@ module Ruport
|
|
13
13
|
|
14
14
|
attr_accessor :fake_db
|
15
15
|
|
16
|
-
def execute (query, source = :string)
|
17
|
-
query = get_query(source, query)
|
18
|
-
yield(@fake_db.process(@dsn,@user,@password, query))
|
19
|
-
end
|
20
|
-
|
21
|
-
def select( query, source = :string, &action )
|
22
|
-
source != :string || query = "SELECT " + query
|
23
|
-
execute( query, source ) do |table|
|
24
|
-
if table.kind_of?(DataSet)
|
25
|
-
@column_names = table.fields
|
26
|
-
else
|
27
|
-
@column_names = table[0].keys
|
28
|
-
end
|
29
|
-
@first_row = true
|
30
|
-
table.each do |row|
|
31
|
-
row = row.to_hash if table.kind_of?(DataSet)
|
32
|
-
action.call(row) if block_given?
|
33
|
-
@first_row = false
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
16
|
|
38
17
|
def query ( query, source = :string, &action)
|
39
|
-
|
40
|
-
|
41
|
-
end
|
18
|
+
query = get_query(source, query)
|
19
|
+
yield(@fake_db.process(@dsn,@user,@password, query))
|
42
20
|
end
|
43
21
|
|
44
22
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ruport
|
2
|
+
module Report
|
3
|
+
class FakeMailer < Mailer
|
4
|
+
|
5
|
+
@@fake_server = Hash.new
|
6
|
+
@@fake_server[:port] = 25
|
7
|
+
|
8
|
+
def self.[]=(key,value)
|
9
|
+
@@fake_server[key] = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def send_report(report_name="No Subject")
|
13
|
+
raise "Invalid Host" unless @@fake_server[:host].eql?(@host)
|
14
|
+
raise "Invalid Account" unless @@fake_server[:account].eql?(@account)
|
15
|
+
raise "Bad Email Address" unless @@fake_server[:address].eql?(@address)
|
16
|
+
raise "Bad Password" unless @@fake_server[:password].eql?(@password)
|
17
|
+
raise "Invalid Port" unless @@fake_server[:port].eql?(@port)
|
18
|
+
raise "Bad Authorization Type" unless @@fake_server[:auth].eql?(@auth)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/ruportlib.rb
CHANGED
data/test/tc_builder.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
require "test/unit"
|
3
|
+
require "lib/ruportlib"
|
4
|
+
class TestBuilder < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@data = Report::DataSet.new
|
7
|
+
@data.fields = %w[ col1 col2 col3 ]
|
8
|
+
@data.default = ""; @data << %w[ a b c ]; @data << %w[ d e f ]
|
9
|
+
@builder = Format::Builder.new( @data )
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_render_html
|
13
|
+
@builder.type = :html
|
14
|
+
assert_equal("<table>\n <tr>\n <td>col1</td><td>col2</td>" +
|
15
|
+
"<td>col3</td>\n </tr>" +
|
16
|
+
" <tr>\n <td>a</td><td>b</td><td>c</td>\n </tr>" +
|
17
|
+
" <tr>\n <td>d</td><td>e</td><td>f</td>\n </tr>" +
|
18
|
+
"\n</table>", @builder.render )
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_render_csv
|
22
|
+
@builder.type = :csv
|
23
|
+
assert_equal("col1,col2,col3\na,b,c\nd,e,f\n", @builder.render)
|
24
|
+
end
|
25
|
+
end
|
data/test/tc_data_row.rb
CHANGED
@@ -11,6 +11,7 @@ class TestDataRow < Test::Unit::TestCase
|
|
11
11
|
@rows << [ 3 , 4 ]
|
12
12
|
@rows << [ 5 , 6 ]
|
13
13
|
@rows << { "foo" => 7, "bar" => 8 }
|
14
|
+
@rows << [ 9, 10 ]
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_first?
|
@@ -20,14 +21,6 @@ class TestDataRow < Test::Unit::TestCase
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
def test_middle?
|
24
|
-
assert(!@rows[0].middle?)
|
25
|
-
assert(!@rows[-1].middle?)
|
26
|
-
@rows[1..-2].each do |row|
|
27
|
-
assert(row.middle?)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
24
|
def test_last?
|
32
25
|
@rows[0..-2].each do |row|
|
33
26
|
assert(!row.last?)
|
data/test/tc_data_set.rb
CHANGED
@@ -54,8 +54,12 @@ class TestDataSet < Test::Unit::TestCase
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def test_load
|
57
|
-
|
58
|
-
|
57
|
+
loaded_data = Report::DataSet.load("test/data.csv")
|
58
|
+
@data.each_with_index do |row,r_index|
|
59
|
+
row.each_with_index do |field,f_index|
|
60
|
+
assert_equal(field,loaded_data[r_index][f_index])
|
61
|
+
end
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
def test_to_csv
|
@@ -64,4 +68,12 @@ class TestDataSet < Test::Unit::TestCase
|
|
64
68
|
assert_equal("col1,col2,col3\na,b,c\nd,\"\",e\n",csv)
|
65
69
|
end
|
66
70
|
|
71
|
+
def test_to_html
|
72
|
+
assert_equal("<table>\n <tr>\n <td>col1</td><td>col2</td>" +
|
73
|
+
"<td>col3</td>\n </tr>" +
|
74
|
+
" <tr>\n <td>a</td><td>b</td><td>c</td>\n </tr>" +
|
75
|
+
" <tr>\n <td>d</td><td></td><td>e</td>\n </tr>" +
|
76
|
+
"\n</table>", @data.to_html )
|
77
|
+
end
|
78
|
+
|
67
79
|
end
|
data/test/tc_engine.rb
CHANGED
@@ -5,27 +5,28 @@
|
|
5
5
|
|
6
6
|
require "test/unit"
|
7
7
|
require "lib/ruportlib"
|
8
|
-
class
|
8
|
+
class TestEngine < Test::Unit::TestCase
|
9
9
|
|
10
|
-
def setup
|
11
|
-
|
12
|
-
|
10
|
+
def setup
|
11
|
+
@report = Report::FakeEngine.new( "DBI:mysql:ruport:localhost",
|
12
|
+
"test", "123")
|
13
|
+
@report.query_table = "ruport_queries"
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
@report.fake_db = Report::FakeDB.new([ "DBI:mysql","ruport",
|
16
|
+
"localhost", "test", "123"])
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
18
|
+
@report.fake_db["SELECT * FROM ruport_test"] = @data =
|
19
|
+
[ { "a" => "a column, row 1", "b" => "b column, row 1",
|
20
|
+
"c" => "c column, row 1", "d" => "d column, row 1" },
|
21
|
+
{ "a" => "a column, row 2", "b" => "b column, row 2",
|
22
|
+
"c" => "c column, row 2", "d" => "d column, row 2" },
|
23
|
+
{ "a" => "a column, row 3", "b" => "b column, row 3",
|
24
|
+
"c" => "c column, row 3", "d" => "d column, row 3" } ]
|
25
|
+
|
26
|
+
@report.fake_db[ "SELECT query FROM #{@report.query_table} " +
|
27
|
+
"WHERE label LIKE 'sql_stored_test';"] =
|
28
|
+
[ "query" => "SELECT * FROM ruport_test" ]
|
29
|
+
end
|
29
30
|
|
30
31
|
def test_load_file
|
31
32
|
contents = "SELECT * FROM ruport_test"
|
@@ -62,36 +63,15 @@ end
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
def test_sql
|
66
|
-
row_i = 0
|
67
|
-
@report.select("* FROM ruport_test") do |row|
|
68
|
-
assert_equal(@data[row_i]["a"], row["a"].to_s)
|
69
|
-
assert_equal(@data[row_i]["b"], row["b"].to_s)
|
70
|
-
assert_equal(@data[row_i]["c"], row["c"].to_s)
|
71
|
-
assert_equal(@data[row_i]["d"], row["d"].to_s)
|
72
|
-
row_i += 1
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
66
|
def test_sql_file
|
77
|
-
|
78
|
-
|
79
|
-
assert_equal(@data[row_i]["a"], row["a"].to_s)
|
80
|
-
assert_equal(@data[row_i]["b"], row["b"].to_s)
|
81
|
-
assert_equal(@data[row_i]["c"], row["c"].to_s)
|
82
|
-
assert_equal(@data[row_i]["d"], row["d"].to_s)
|
83
|
-
row_i += 1
|
67
|
+
@report.query("test/test.sql",:file) do |result|
|
68
|
+
assert_equal(@data,result)
|
84
69
|
end
|
85
70
|
end
|
86
71
|
|
87
72
|
def test_sql_stored
|
88
|
-
|
89
|
-
|
90
|
-
assert_equal(@data[row_i]["a"], row["a"].to_s)
|
91
|
-
assert_equal(@data[row_i]["b"], row["b"].to_s)
|
92
|
-
assert_equal(@data[row_i]["c"], row["c"].to_s)
|
93
|
-
assert_equal(@data[row_i]["d"], row["d"].to_s)
|
94
|
-
row_i += 1
|
73
|
+
@report.query("sql_stored_test",:db) do |result|
|
74
|
+
assert_equal(@data,result)
|
95
75
|
end
|
96
76
|
end
|
97
77
|
|
data/test/tc_mailer.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "ruportlib"
|
3
|
+
|
4
|
+
class TestMailer < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
Report::FakeMailer[:host] = "mail.fakeruport.org"
|
8
|
+
Report::FakeMailer[:address] = "greg@fakeruport.org"
|
9
|
+
Report::FakeMailer[:account] = "greg"
|
10
|
+
Report::FakeMailer[:password] = "bubbles"
|
11
|
+
Report::FakeMailer[:auth] = :login
|
12
|
+
|
13
|
+
@mailer = Report::FakeMailer.new( "mail.fakeruport.org",
|
14
|
+
"greg@fakeruport.org",
|
15
|
+
"greg","bubbles", 25, :login )
|
16
|
+
end
|
17
|
+
def test_send
|
18
|
+
assert_nothing_raised { @mailer.send_report }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/test/ts_all.rb
CHANGED
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: ruport
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.
|
7
|
-
date: 2005-11-
|
6
|
+
version: 0.2.4
|
7
|
+
date: 2005-11-16 00:00:00 -06:00
|
8
8
|
summary: A generalized Ruby report generation and templating engine.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -24,21 +24,27 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
24
24
|
version: 0.0.0
|
25
25
|
version:
|
26
26
|
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
27
29
|
authors:
|
28
30
|
- Gregory Brown
|
29
31
|
files:
|
30
32
|
- lib/ruportlib.rb
|
33
|
+
- lib/ruport/format/builder.rb
|
31
34
|
- lib/ruport/format/chart.rb
|
32
35
|
- lib/ruport/report/data_row.rb
|
33
36
|
- lib/ruport/report/data_set.rb
|
34
37
|
- lib/ruport/report/engine.rb
|
35
38
|
- lib/ruport/report/fake_db.rb
|
36
39
|
- lib/ruport/report/fake_engine.rb
|
40
|
+
- lib/ruport/report/fake_mailer.rb
|
37
41
|
- lib/ruport/report/mailer.rb
|
38
42
|
- lib/ruport/report/sql.rb
|
43
|
+
- test/tc_builder.rb
|
39
44
|
- test/tc_data_row.rb
|
40
45
|
- test/tc_data_set.rb
|
41
46
|
- test/tc_engine.rb
|
47
|
+
- test/tc_mailer.rb
|
42
48
|
- test/ts_all.rb
|
43
49
|
- Rakefile
|
44
50
|
- README
|