ruport 0.4.9 → 0.4.11
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.
- 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
|