ruport 0.4.9 → 0.4.11
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +7 -9
- data/CHANGELOG +36 -2
- data/Rakefile +14 -1
- data/TODO +0 -7
- data/examples/create.sql +2 -0
- data/examples/sql_query.rb +19 -0
- data/lib/ruport.rb +1 -1
- data/lib/ruport/data_row.rb +2 -1
- data/lib/ruport/data_set.rb +28 -6
- data/lib/ruport/format.rb +3 -3
- data/lib/ruport/format/engine.rb +42 -46
- data/lib/ruport/format/plugin.rb +57 -9
- data/lib/ruport/query.rb +1 -1
- data/lib/ruport/rails/reportable.rb +5 -5
- data/lib/ruport/report.rb +3 -16
- data/lib/ruport/system_extensions.rb +125 -0
- data/test/tc_data_set.rb +47 -10
- data/test/tc_format_engine.rb +46 -53
- data/test/tc_plugin.rb +147 -2
- data/test/ts_all.rb +0 -1
- data/test/ts_format.rb +0 -1
- data/test/unit.log +2506 -288
- metadata +14 -21
- data/lib/ruport/format/builder.rb +0 -123
- data/lib/ruport/parser.rb +0 -202
- data/test/samples/car_ads.txt +0 -505
- data/test/samples/five_lines.txt +0 -5
- data/test/samples/five_paragraphs.txt +0 -9
- data/test/samples/ross_report.txt +0 -58530
- data/test/tc_builder.rb +0 -135
- data/test/tc_data_set.rb~ +0 -326
- data/test/tc_state.rb +0 -142
- data/test/ts_parser.rb +0 -10
data/lib/ruport/query.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Ruport
|
2
2
|
module Reportable
|
3
3
|
def formatted_table(type,options={},&block)
|
4
|
-
to_ds(
|
4
|
+
to_ds(:find => options[:find],:columns => options[:columns]).as(type){ |e|
|
5
5
|
block[e] if block_given?
|
6
|
-
|
7
|
-
end
|
6
|
+
}
|
8
7
|
end
|
9
8
|
def to_ds(options={})
|
10
|
-
|
9
|
+
options[:columns] ||= column_names
|
10
|
+
find(:all,options[:find]).
|
11
|
+
to_ds(column_names).select_columns(*options[:columns])
|
11
12
|
end
|
12
|
-
|
13
13
|
end
|
14
14
|
class DataSet
|
15
15
|
alias_method :old_append, :<<
|
data/lib/ruport/report.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# fixME: Copyright notice here.
|
2
2
|
|
3
3
|
#load the needed standard libraries.
|
4
4
|
%w[erb yaml date logger fileutils].each { |lib| require lib }
|
@@ -9,7 +9,6 @@ module Ruport
|
|
9
9
|
class Report
|
10
10
|
def initialize( source_name=:default, mailer_name=:default )
|
11
11
|
@source = source_name
|
12
|
-
|
13
12
|
@report_name = @report = ""
|
14
13
|
@file = nil
|
15
14
|
end
|
@@ -40,11 +39,7 @@ module Ruport
|
|
40
39
|
# Evaluates _code_ from _filename_ as pure ruby code for files ending in
|
41
40
|
# .rb, and as ERb templates for anything else.
|
42
41
|
def eval_template( filename, code )
|
43
|
-
|
44
|
-
eval(code)
|
45
|
-
else
|
46
|
-
ERB.new(code, 0, "%").run(binding)
|
47
|
-
end
|
42
|
+
filename =~ /\.rb/ ? eval(code) : ERB.new(code, 0, "%").run(binding)
|
48
43
|
end
|
49
44
|
|
50
45
|
|
@@ -55,19 +50,11 @@ module Ruport
|
|
55
50
|
# file with the specified name. Otherwise, it will print to STDOUT by
|
56
51
|
# default.
|
57
52
|
#
|
58
|
-
# Lastly, if you have your mailer configuration set up and
|
59
|
-
# you've specified recipients, the contents of @mailer.body will
|
60
|
-
# be automatically emailed by this fuction.
|
61
|
-
#
|
62
53
|
# The source for this function is probably easier to read than this
|
63
54
|
# explanation, so you may want to start there.
|
64
55
|
def generate_report
|
65
56
|
@pre.call if @pre
|
66
|
-
|
67
|
-
puts(@report)
|
68
|
-
else
|
69
|
-
File.open(@file,"w") { |f| f.puts @report }
|
70
|
-
end
|
57
|
+
@file ? File.open(@file,"w") { |f| f.puts @report } : puts(@report)
|
71
58
|
@post.call if @post
|
72
59
|
end
|
73
60
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# system_extensions.rb
|
4
|
+
#
|
5
|
+
# lovingly ganked from HighLine 1.2.1
|
6
|
+
#
|
7
|
+
# The following modifications have been made by Gregory Brown on 2006.06.25
|
8
|
+
#
|
9
|
+
# - Outer Module is changed from HighLine to Ruport
|
10
|
+
# - terminal_width / terminal_height added
|
11
|
+
#
|
12
|
+
# All modifications are under the distributions terms of Ruport.
|
13
|
+
# Copyright 2006, Gregory Brown. All Rights Reserved
|
14
|
+
#
|
15
|
+
# Original copyright notice preserved below.
|
16
|
+
# --------------------------------------------------------------------------
|
17
|
+
#
|
18
|
+
# Created by James Edward Gray II on 2006-06-14.
|
19
|
+
# Copyright 2006 Gray Productions. All rights reserved.
|
20
|
+
#
|
21
|
+
# This is Free Software. See LICENSE and COPYING for details.
|
22
|
+
|
23
|
+
module Ruport
|
24
|
+
module SystemExtensions
|
25
|
+
module_function
|
26
|
+
|
27
|
+
#
|
28
|
+
# This section builds character reading and terminal size functions
|
29
|
+
# to suit the proper platform we're running on. Be warned: Here be
|
30
|
+
# dragons!
|
31
|
+
#
|
32
|
+
begin
|
33
|
+
require "Win32API" # See if we're on Windows.
|
34
|
+
|
35
|
+
CHARACTER_MODE = "Win32API" # For Debugging purposes only.
|
36
|
+
|
37
|
+
#
|
38
|
+
# Windows savvy getc().
|
39
|
+
#
|
40
|
+
# *WARNING*: This method ignores <tt>input</tt> and reads one
|
41
|
+
# character from +STDIN+!
|
42
|
+
#
|
43
|
+
def get_character( input = STDIN )
|
44
|
+
Win32API.new("crtdll", "_getch", [ ], "L").Call
|
45
|
+
end
|
46
|
+
|
47
|
+
# A Windows savvy method to fetch the console columns, and rows.
|
48
|
+
def terminal_size
|
49
|
+
m_GetStdHandle = Win32API.new( 'kernel32',
|
50
|
+
'GetStdHandle',
|
51
|
+
['L'],
|
52
|
+
'L' )
|
53
|
+
m_GetConsoleScreenBufferInfo = Win32API.new(
|
54
|
+
'kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L'
|
55
|
+
)
|
56
|
+
|
57
|
+
format = 'SSSSSssssSS'
|
58
|
+
buf = ([0] * format.size).pack(format)
|
59
|
+
stdout_handle = m_GetStdHandle.call(0xFFFFFFF5)
|
60
|
+
|
61
|
+
m_GetConsoleScreenBufferInfo.call(stdout_handle, buf)
|
62
|
+
bufx, bufy, curx, cury, wattr,
|
63
|
+
left, top, right, bottom, maxx, maxy = buf.unpack(format)
|
64
|
+
return right - left + 1, bottom - top + 1
|
65
|
+
end
|
66
|
+
rescue LoadError # If we're not on Windows try...
|
67
|
+
begin
|
68
|
+
require "termios" # Unix, first choice.
|
69
|
+
|
70
|
+
CHARACTER_MODE = "termios" # For Debugging purposes only.
|
71
|
+
|
72
|
+
#
|
73
|
+
# Unix savvy getc(). (First choice.)
|
74
|
+
#
|
75
|
+
# *WARNING*: This method requires the "termios" library!
|
76
|
+
#
|
77
|
+
def get_character( input = STDIN )
|
78
|
+
old_settings = Termios.getattr(input)
|
79
|
+
|
80
|
+
new_settings = old_settings.dup
|
81
|
+
new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
|
82
|
+
|
83
|
+
begin
|
84
|
+
Termios.setattr(input, Termios::TCSANOW, new_settings)
|
85
|
+
input.getc
|
86
|
+
ensure
|
87
|
+
Termios.setattr(input, Termios::TCSANOW, old_settings)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
rescue LoadError # If our first choice fails, default.
|
91
|
+
CHARACTER_MODE = "stty" # For Debugging purposes only.
|
92
|
+
|
93
|
+
#
|
94
|
+
# Unix savvy getc(). (Second choice.)
|
95
|
+
#
|
96
|
+
# *WARNING*: This method requires the external "stty" program!
|
97
|
+
#
|
98
|
+
def get_character( input = STDIN )
|
99
|
+
state = `stty -g`
|
100
|
+
|
101
|
+
begin
|
102
|
+
system "stty raw -echo cbreak"
|
103
|
+
input.getc
|
104
|
+
ensure
|
105
|
+
system "stty #{state}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# A Unix savvy method to fetch the console columns, and rows.
|
111
|
+
def terminal_size
|
112
|
+
`stty size`.split.map { |x| x.to_i }.reverse
|
113
|
+
end
|
114
|
+
|
115
|
+
def terminal_width
|
116
|
+
terminal_size.first
|
117
|
+
end
|
118
|
+
|
119
|
+
def terminal_height
|
120
|
+
terminal_size.last
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/test/tc_data_set.rb
CHANGED
@@ -163,9 +163,16 @@ class TestDataSet < Test::Unit::TestCase
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def test_load
|
166
|
-
loaded_data = DataSet.load("test/samples/data.csv")
|
166
|
+
loaded_data = DataSet.load("test/samples/data.csv", :default => "")
|
167
167
|
assert_equal(@data,loaded_data)
|
168
168
|
|
169
|
+
loaded_data = DataSet.load("test/samples/data.csv", :has_names => false)
|
170
|
+
|
171
|
+
assert_equal(nil,loaded_data.fields)
|
172
|
+
assert_equal([%w[col1 col2 col3],%w[a b c],["d",nil,"e"]],loaded_data.to_a)
|
173
|
+
assert_equal(%w[a b c],loaded_data[1].to_a)
|
174
|
+
|
175
|
+
|
169
176
|
loaded_data = DataSet.load("test/samples/data.csv") do |set,row|
|
170
177
|
set << row if row.include? 'b'
|
171
178
|
end
|
@@ -175,7 +182,7 @@ class TestDataSet < Test::Unit::TestCase
|
|
175
182
|
def test_to_csv
|
176
183
|
loaded_data = DataSet.load("test/samples/data.csv" )
|
177
184
|
csv = loaded_data.to_csv
|
178
|
-
assert_equal("col1,col2,col3\na,b,c\nd
|
185
|
+
assert_equal("col1,col2,col3\na,b,c\nd,,e\n",csv)
|
179
186
|
end
|
180
187
|
|
181
188
|
def test_to_html
|
@@ -183,20 +190,27 @@ class TestDataSet < Test::Unit::TestCase
|
|
183
190
|
"<th>col2 </th>\n\t\t\t<th>col3</th>\n\t\t</tr>\n"+
|
184
191
|
"\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t<td>b</td>\n\t\t\t"+
|
185
192
|
"<td>c</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>d</td>\n\t"+
|
186
|
-
"\t\t<td
|
193
|
+
"\t\t<td> </td>\n\t\t\t<td>e</td>\n\t\t</tr>"+
|
194
|
+
"\n\t</table>", @data.to_html )
|
187
195
|
end
|
188
196
|
|
189
197
|
def test_select_columns
|
198
|
+
|
199
|
+
b = @data.select_columns(0,2)
|
200
|
+
assert_equal(%w[col1 col3], b.fields)
|
201
|
+
assert_equal([%w[a c],%w[d e]],b.to_a)
|
202
|
+
|
190
203
|
assert_equal( [["a"],["d"]],
|
191
|
-
@data.select_columns("col1").
|
204
|
+
@data.select_columns("col1").to_a )
|
192
205
|
assert_equal( [["b"],[""]] ,
|
193
|
-
@data.select_columns("col2").
|
206
|
+
@data.select_columns("col2").to_a )
|
194
207
|
assert_equal( [["c"],["e"]],
|
195
|
-
@data.select_columns("col3").
|
208
|
+
@data.select_columns("col3").to_a )
|
196
209
|
assert_equal( [["a","b","c"],["d","","e"]],
|
197
|
-
@data.select_columns("col1","col2","col3").
|
210
|
+
@data.select_columns("col1","col2","col3").to_a )
|
198
211
|
assert_equal( [["c","a"],["e","d"]],
|
199
|
-
@data.select_columns("col3","col1").
|
212
|
+
@data.select_columns("col3","col1").to_a )
|
213
|
+
|
200
214
|
end
|
201
215
|
|
202
216
|
def test_select_columns!
|
@@ -247,17 +261,40 @@ class TestDataSet < Test::Unit::TestCase
|
|
247
261
|
|
248
262
|
#check alias
|
249
263
|
sum = data.sum { |r| r["x"] }
|
250
|
-
assert_equal(18,sum)
|
251
|
-
|
264
|
+
assert_equal(18,sum)
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_add_columns
|
268
|
+
d = @data.add_columns("a","b")
|
269
|
+
assert_equal %w[col1 col2 col3 a b], d.fields
|
270
|
+
assert_equal %w[col1 col2 col3], @data.fields
|
271
|
+
assert_equal %w[col1 col2 col3 a b], d[0].fields
|
272
|
+
assert_equal %w[col1 col2 col3], @data[0].fields
|
273
|
+
assert_equal nil, d[0]["a"]
|
274
|
+
d[0]["a"] = "foo"
|
275
|
+
assert_equal %w[a b c foo] + [nil], d[0].to_a
|
276
|
+
|
277
|
+
d.add_columns!("c")
|
278
|
+
assert_equal %w[col1 col2 col3 a b c], d.fields
|
279
|
+
assert_equal %w[col1 col2 col3 a b c], d[0].fields
|
252
280
|
end
|
253
281
|
|
254
282
|
def test_remove_columns
|
283
|
+
|
284
|
+
d = @data.remove_columns(0)
|
285
|
+
assert_equal(%w[col2 col3],d.fields)
|
286
|
+
assert_equal([%w[b c],["","e"]], d.to_a)
|
287
|
+
|
255
288
|
data = @data.remove_columns("col1","col3")
|
256
289
|
assert_equal(["col2"],data.fields)
|
290
|
+
assert_equal([["b"],[""]], data.to_a)
|
257
291
|
|
258
292
|
data.remove_columns!("col2")
|
259
293
|
assert_equal([],data.fields)
|
260
294
|
assert(data.empty?)
|
295
|
+
|
296
|
+
@data.remove_columns!("col1")
|
297
|
+
assert_equal(%w[col2 col3], @data.fields)
|
261
298
|
end
|
262
299
|
|
263
300
|
def test_bracket_equals
|
data/test/tc_format_engine.rb
CHANGED
@@ -1,93 +1,83 @@
|
|
1
|
-
require 'rubygems'
|
1
|
+
begin require 'rubygems'; rescue LoadError; nil end
|
2
2
|
require 'ruport'
|
3
3
|
require 'test/unit'
|
4
4
|
|
5
|
+
class MockPlugin < Ruport::Format::Plugin
|
6
|
+
|
7
|
+
renderer(:table) { "#{rendered_field_names}#{data}" }
|
8
|
+
|
9
|
+
format_field_names { "#{data.fields}" }
|
10
|
+
|
11
|
+
renderer(:document) { data }
|
12
|
+
|
13
|
+
register_on :table_engine
|
14
|
+
register_on :document_engine
|
15
|
+
|
16
|
+
rendering_options :red_cloth_enabled => true,
|
17
|
+
:erb_enabled => true
|
18
|
+
|
19
|
+
end
|
20
|
+
|
5
21
|
class TestTabularFormatEngine < Test::Unit::TestCase
|
6
22
|
|
7
23
|
include Ruport
|
8
|
-
|
24
|
+
|
9
25
|
def setup
|
10
|
-
@engine = Format::Engine::Table
|
26
|
+
@engine = Format::Engine::Table.dup
|
11
27
|
end
|
12
28
|
|
13
29
|
def test_basic_render
|
14
|
-
@engine.plugin = :
|
15
|
-
@engine.data = [[1,2,3],[4,5,6],[7,8,9]].to_ds(%w[a b c])
|
16
|
-
assert_equal( "a,b,c\n1,2,3\n4,5,6\n7,8,9\n",
|
17
|
-
@engine.render )
|
30
|
+
@engine.plugin = :mock
|
18
31
|
@engine.data = [[1,2,3],[4,5,6],[7,8,9]]
|
19
|
-
assert_equal( "
|
32
|
+
assert_equal( "#{@engine.data}", @engine.render )
|
20
33
|
end
|
21
34
|
|
22
35
|
def test_render_without_field_names
|
23
|
-
@engine.plugin = :
|
36
|
+
@engine.plugin = :mock
|
24
37
|
@engine.show_field_names = false
|
25
38
|
|
26
|
-
@engine.data = [[1,2,3],[4,5,6],[7,8,9]].to_ds(%w[a b c])
|
27
|
-
assert_equal "1,2,3\n4,5,6\n7,8,9\n", @engine.render
|
28
|
-
|
29
39
|
@engine.data = [[1,2,3],[4,5,6],[7,8,9]]
|
30
|
-
assert_equal "
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_render_with_column_spacer
|
34
|
-
a = @engine.dup
|
35
|
-
|
36
|
-
a.plugin = :csv
|
37
|
-
a.data = [[1,2],[3,4],[5,6],[7,8]]
|
38
|
-
a.insert_column :left_of => 1
|
39
|
-
assert_equal "1,\"\",2\n3,\"\",4\n5,\"\",6\n7,\"\",8\n", a.render
|
40
|
-
|
41
|
-
b = @engine.dup
|
42
|
-
|
43
|
-
b.plugin = :csv
|
44
|
-
b.data = [%w[a b c],%w[d e f],%w[g h i]]
|
45
|
-
b.insert_column :right_of => 1
|
46
|
-
assert_equal "a,b,\"\",c\nd,e,\"\",f\ng,h,\"\",i\n", b.render
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_render_with_row_spacer
|
50
|
-
a = @engine.dup
|
51
|
-
|
52
|
-
a.plugin = :csv
|
53
|
-
a.data = [[1,2],[3,4]]
|
54
|
-
a.insert_row :above => 1
|
55
|
-
assert_equal "1,2\n\n3,4\n", a.render
|
56
|
-
|
57
|
-
b = @engine.dup
|
58
|
-
b.plugin = :csv
|
59
|
-
b.data = [[1,2],[3,4],[5,6],[7,8]]
|
60
|
-
b.insert_row :below => 2
|
61
|
-
assert_equal "1,2\n3,4\n5,6\n\n7,8\n", b.render
|
62
|
-
|
40
|
+
assert_equal "#{@engine.data}", @engine.render
|
63
41
|
end
|
64
42
|
|
65
43
|
def test_simple_interface
|
66
|
-
expected = "1,2
|
67
|
-
actual = Format.table(:plugin => :
|
44
|
+
expected = "#{[[1,2],[3,4]]}"
|
45
|
+
actual = Format.table(:plugin => :mock, :data => [[1,2],[3,4]])
|
68
46
|
assert_equal(expected,actual)
|
69
47
|
end
|
70
48
|
|
71
49
|
def test_rewrite_column
|
72
50
|
a = @engine.dup
|
73
|
-
a.plugin = :
|
51
|
+
a.plugin = :mock
|
52
|
+
|
74
53
|
a.data = [[1,2],[3,4]].to_ds(%w[a b])
|
75
54
|
a.rewrite_column("a") { |r| r["a"] + 1 }
|
76
|
-
assert_equal
|
55
|
+
assert_equal([[2,2],[4,4]].to_ds(%w[a b]),a.data)
|
56
|
+
assert_nothing_raised { a.render }
|
57
|
+
|
77
58
|
a.data = [[5,6],[7,8]]
|
78
59
|
a.rewrite_column(1) { "apple" }
|
79
|
-
assert_equal
|
60
|
+
assert_equal [[5,"apple"],[7,"apple"]], a.data
|
61
|
+
assert_nothing_raised { a.render }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_num_columns
|
65
|
+
@engine.data = [[1,2,3,4],[5,6,7,8]]
|
66
|
+
assert_equal(4,@engine.num_cols)
|
67
|
+
|
68
|
+
@engine.data = [[1,2,3],[4,5,6]].to_ds(%w[a b c])
|
69
|
+
assert_equal(3,@engine.num_cols)
|
80
70
|
end
|
81
71
|
|
82
72
|
end
|
83
73
|
|
84
74
|
class TestDocumentFormatEngine < Test::Unit::TestCase
|
85
75
|
def setup
|
86
|
-
@engine = Format::Engine::Document
|
76
|
+
@engine = Format::Engine::Document.dup
|
87
77
|
end
|
88
78
|
|
89
79
|
def test_basic_render
|
90
|
-
@engine.plugin = :
|
80
|
+
@engine.plugin = :mock
|
91
81
|
@engine.red_cloth_enabled = true
|
92
82
|
@engine.erb_enabled = true
|
93
83
|
@engine.data = "* <%= 3 + 2 %>\n* <%= 'apple'.reverse %>\n* <%= [1,2][0] %>"
|
@@ -98,7 +88,7 @@ class TestDocumentFormatEngine < Test::Unit::TestCase
|
|
98
88
|
def test_simple_interface
|
99
89
|
|
100
90
|
d = "*<%= 'apple'.reverse %>*"
|
101
|
-
opts = { :data => d, :plugin => :
|
91
|
+
opts = { :data => d, :plugin => :mock }
|
102
92
|
|
103
93
|
a = Format.document opts
|
104
94
|
assert_equal "<p><strong>elppa</strong></p>", a
|
@@ -108,6 +98,9 @@ class TestDocumentFormatEngine < Test::Unit::TestCase
|
|
108
98
|
|
109
99
|
a = Format.document opts.merge!({:erb_enabled => false})
|
110
100
|
assert_equal d, a
|
101
|
+
|
102
|
+
a = Format.document :data => d, :plugin => :mock
|
103
|
+
assert_equal "<p><strong>elppa</strong></p>", a
|
111
104
|
|
112
105
|
end
|
113
106
|
end
|