ruport 0.4.23 → 0.4.99

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.
Files changed (71) hide show
  1. data/AUTHORS +16 -8
  2. data/CHANGELOG +30 -1
  3. data/README +144 -114
  4. data/Rakefile +12 -4
  5. data/TODO +4 -7
  6. data/bin/rope +21 -28
  7. data/examples/line_graph.rb +36 -0
  8. data/examples/sample_invoice_report.rb +1 -1
  9. data/examples/simple_graph.rb +8 -0
  10. data/lib/SVG/Graph/Bar.rb +137 -0
  11. data/lib/SVG/Graph/BarBase.rb +140 -0
  12. data/lib/SVG/Graph/BarHorizontal.rb +136 -0
  13. data/lib/SVG/Graph/Graph.rb +977 -0
  14. data/lib/SVG/Graph/Line.rb +444 -0
  15. data/lib/SVG/Graph/Pie.rb +394 -0
  16. data/lib/SVG/Graph/Plot.rb +494 -0
  17. data/lib/SVG/Graph/Schedule.rb +373 -0
  18. data/lib/SVG/Graph/TimeSeries.rb +241 -0
  19. data/lib/ruport.rb +2 -2
  20. data/lib/ruport/config.rb +47 -3
  21. data/lib/ruport/data/collection.rb +17 -1
  22. data/lib/ruport/data/record.rb +101 -8
  23. data/lib/ruport/data/set.rb +81 -2
  24. data/lib/ruport/data/set.rb.rej +147 -0
  25. data/lib/ruport/data/set.rb~ +73 -0
  26. data/lib/ruport/data/table.rb +127 -2
  27. data/lib/ruport/data/taggable.rb +21 -2
  28. data/lib/ruport/format.rb +36 -44
  29. data/lib/ruport/format/engine.rb +21 -1
  30. data/lib/ruport/format/plugin.rb +64 -1
  31. data/lib/ruport/mailer.rb +70 -36
  32. data/lib/ruport/meta_tools.rb +15 -6
  33. data/lib/ruport/query.rb +1 -1
  34. data/lib/ruport/rails/reportable.rb +23 -1
  35. data/lib/ruport/report.rb +11 -11
  36. data/lib/ruport/report/invoice.rb +16 -0
  37. data/lib/ruport/system_extensions.rb +3 -55
  38. data/test/{tc_database.rb → _test_database.rb} +0 -0
  39. data/test/{tc_config.rb → test_config.rb} +0 -0
  40. data/test/{tc_format.rb → test_format.rb} +1 -0
  41. data/test/{tc_format_engine.rb → test_format_engine.rb} +14 -2
  42. data/test/test_graph.rb +101 -0
  43. data/test/{tc_invoice.rb → test_invoice.rb} +7 -1
  44. data/test/test_mailer.rb +108 -0
  45. data/test/test_meta_tools.rb +14 -0
  46. data/test/{tc_plugin.rb → test_plugin.rb} +12 -1
  47. data/test/{tc_query.rb → test_query.rb} +0 -0
  48. data/test/{tc_record.rb → test_record.rb} +9 -0
  49. data/test/{tc_report.rb → test_report.rb} +2 -1
  50. data/test/{tc_ruport.rb → test_ruport.rb} +0 -0
  51. data/test/test_set.rb +118 -0
  52. data/test/test_set.rb.rej +16 -0
  53. data/test/{tc_set.rb → test_set.rb~} +17 -0
  54. data/test/{tc_sql_split.rb → test_sql_split.rb} +0 -0
  55. data/test/{tc_table.rb → test_table.rb} +15 -0
  56. data/test/{tc_taggable.rb → test_taggable.rb} +0 -0
  57. data/test/unit.log +361 -0
  58. metadata +52 -30
  59. data/examples/bar.pdf +0 -193
  60. data/examples/f.log +0 -5
  61. data/examples/foo.pdf +0 -193
  62. data/lib/ruport/format/document.rb +0 -78
  63. data/lib/ruport/format/open_node.rb +0 -38
  64. data/test/tc_data_row.rb +0 -132
  65. data/test/tc_data_set.rb +0 -386
  66. data/test/tc_document.rb +0 -42
  67. data/test/tc_element.rb +0 -18
  68. data/test/tc_page.rb +0 -42
  69. data/test/tc_section.rb +0 -45
  70. data/test/ts_all.rb +0 -12
  71. data/test/ts_format.rb +0 -7
@@ -1,10 +1,26 @@
1
1
  module Ruport
2
2
  class Report
3
3
  module Invoice
4
+
5
+ # Returns a Format::Engine::Invoice object
6
+ #
7
+ # If a block is given, it is possible to customize this object before it
8
+ # is returned
9
+ #
10
+ # Example:
11
+ #
12
+ # inv = build_invoice do |i|
13
+ # i.company_info = "Foo Inc.\n42 Front Street\nNew Haven CT"
14
+ # i.customer_info = "Joe User\njoe@test.com"
15
+ # i.data = [["Aspirin","$2.00"]].to_table(%w[item cost])
16
+ # end
4
17
  def build_invoice
5
18
  a = Ruport::Format.invoice_object(:plugin => :pdf)
6
19
  yield(a); return a
7
20
  end
21
+
22
+ # Takes a block and calls build_invoice then calls render on the resulting
23
+ # Format::Engine::Invoice object
8
24
  def render_invoice(&block)
9
25
  build_invoice(&block).render
10
26
  end
@@ -9,6 +9,9 @@
9
9
  # - Outer Module is changed from HighLine to Ruport
10
10
  # - terminal_width / terminal_height added
11
11
  #
12
+ # The following modifications have been made by Gregory Brown on 2006.08.13
13
+ # - removed most methods, preserving only terminal geometry features
14
+ #
12
15
  # All modifications are under the distributions terms of Ruport.
13
16
  # Copyright 2006, Gregory Brown. All Rights Reserved
14
17
  #
@@ -32,18 +35,6 @@ module Ruport
32
35
  begin
33
36
  require "Win32API" # See if we're on Windows.
34
37
 
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
38
  # A Windows savvy method to fetch the console columns, and rows.
48
39
  def terminal_size
49
40
  m_GetStdHandle = Win32API.new( 'kernel32',
@@ -64,49 +55,6 @@ module Ruport
64
55
  return right - left + 1, bottom - top + 1
65
56
  end
66
57
  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
58
  # A Unix savvy method to fetch the console columns, and rows.
111
59
  def terminal_size
112
60
  `stty size`.split.map { |x| x.to_i }.reverse
File without changes
@@ -1,6 +1,7 @@
1
1
  require "ruport"
2
2
  require "test/unit"
3
3
 
4
+ require "rubygems" rescue LoadError nil
4
5
  class TestFormat < Test::Unit::TestCase
5
6
 
6
7
  def setup
@@ -1,5 +1,5 @@
1
- require 'rubygems' rescue LoadError nil
2
1
  require 'ruport'
2
+ require 'rubygems' rescue LoadError nil
3
3
  require 'test/unit'
4
4
 
5
5
  class MockPlugin < Ruport::Format::Plugin
@@ -75,6 +75,15 @@ class TestTabularFormatEngine < Test::Unit::TestCase
75
75
  assert_equal "#{@engine.data}", @engine.render
76
76
  end
77
77
 
78
+ # test that attempting to render using an invalid plugin returns an exception
79
+ # with a useful message
80
+ def test_render_with_invalid_plugin
81
+ assert_raises(InvalidPluginError) {
82
+ Format.table(:plugin => :monkeys,
83
+ :data => [[1,2,3],[4,5,6],[7,8,9]].to_table(%w[a b c]))
84
+ }
85
+ end
86
+
78
87
  def test_simple_interface
79
88
  expected = "#{[[1,2],[3,4]]}"
80
89
  actual = Format.table(:plugin => :mock, :data => [[1,2],[3,4]])
@@ -138,7 +147,7 @@ class TestTabularFormatEngine < Test::Unit::TestCase
138
147
  assert_equal( [[1,2,3],[nil,2,4],[nil,3,7],
139
148
  [2,1,9],[nil,2,3],[nil,2,9]], @engine.data)
140
149
 
141
- data = Data::Table.new :column_names => %w[name date service amount]
150
+ data = Ruport::Data::Table.new :column_names => %w[name date service amount]
142
151
  data << [ "Greg Gibson", "1/1/2000", "Prophy", "100.00" ] <<
143
152
  [ "Greg Gibson", "1/1/2000", "Filling", "100.00" ] <<
144
153
  [ "Greg Gibson", "1/12/2000", "Prophy", "100.00" ] <<
@@ -163,6 +172,9 @@ class TestTabularFormatEngine < Test::Unit::TestCase
163
172
  end
164
173
 
165
174
  class TestDocumentFormatEngine < Test::Unit::TestCase
175
+
176
+ include Ruport
177
+
166
178
  def setup
167
179
  @engine = Format::Engine::Document.dup
168
180
  end
@@ -0,0 +1,101 @@
1
+ require "ruport"
2
+ require 'rubygems' rescue LoadError nil
3
+ require "test/unit"
4
+
5
+ class TestGraph < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @data = [[1,2,3,2],[3,4,5,6]].to_table(%w[a b c d])
9
+ @data_mismatched_headings = [[3,2],[3,4]].to_table(%w[a b c])
10
+ @data_float = [[1.3,2],[3.28322,4]].to_table(%w[a b])
11
+ @data_not_numbers = [["d",:sdfs,"not a number","1"],[3,4,5,6]].to_table(%w[a b c d])
12
+ end
13
+
14
+ # basic test to ensure bar charts render
15
+ def test_bar
16
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
17
+ graph.options = {:graph_style => :bar}
18
+ output = graph.render
19
+
20
+ assert_not_equal nil, output
21
+ end
22
+
23
+ # basic test to ensure horizontal pie charts render
24
+ def test_bar_horizontal
25
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
26
+ graph.options = {:graph_style => :bar_horizontal}
27
+ output = graph.render
28
+
29
+ assert_not_equal nil, output
30
+ end
31
+
32
+ # basic test to ensure line charts render
33
+ def test_line
34
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
35
+ graph.options = {:graph_style => :line}
36
+ output = graph.render
37
+
38
+ assert_not_equal nil, output
39
+ end
40
+
41
+ # basic test to ensure pie charts render
42
+ def test_pie
43
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
44
+ graph.options = {:graph_style => :pie}
45
+ output = graph.render
46
+
47
+ assert_not_equal nil, output
48
+ end
49
+
50
+ # ensure an exception is raised if the user doesn't name every column
51
+ def test_mismatched_headings
52
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_mismatched_headings
53
+ graph.options = {:graph_style => :line}
54
+
55
+ assert_raises(ArgumentError) {
56
+ output = graph.render
57
+ }
58
+ end
59
+
60
+ # test to ensure floats can be graphed
61
+ def test_floats
62
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_float
63
+ graph.options = {:graph_style => :line}
64
+ output = graph.render
65
+
66
+ assert_not_equal nil, output
67
+ end
68
+
69
+ # ensure an exception is raised if non numeric data is graphed
70
+ def test_not_numbers
71
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_not_numbers
72
+ graph.options = {:graph_style => :line}
73
+
74
+ assert_raises(ArgumentError) {
75
+ output = graph.render
76
+ }
77
+ end
78
+
79
+ # ensure an exception is raised if user tries to render a graph without setting any options
80
+ def test_no_options
81
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
82
+
83
+ assert_raises(RuntimeError) {
84
+ output = graph.render
85
+ }
86
+
87
+ end
88
+
89
+ # test to make sure user requested options are applied to the resulting graph
90
+ def test_options_applied_to_rendered_graph
91
+ graph = Ruport::Format.graph_object :plugin => :svg, :data => @data
92
+ graph.options = {:graph_style => :line, :graph_title => 'Test', :show_graph_title => true, :no_css => true}
93
+ output = graph.render
94
+
95
+ # ensure the requested graph title is included in the SVG output. If that's there, we can
96
+ # assume the rest are as well
97
+ assert_not_equal nil, output[/class='mainTitle'/]
98
+
99
+ end
100
+
101
+ end
@@ -1,3 +1,4 @@
1
+ require 'ruport'
1
2
  require 'rubygems' rescue LoadError nil
2
3
  require "test/unit"
3
4
 
@@ -6,8 +7,13 @@ class SampleInvoiceReport < Ruport::Report
6
7
  end
7
8
 
8
9
  class TestInvoice < Test::Unit::TestCase
9
-
10
+
10
11
  def test_basic
12
+ begin
13
+ require "pdf/writer"
14
+ rescue LoadError
15
+ warn "skipping pdf test"; return
16
+ end
11
17
  inv = SampleInvoiceReport.build_invoice do |i|
12
18
  i.company_info = "Foo Inc.\n42 Bar Street\nBaz, CT\n"
13
19
  i.customer_info = "Gregory Brown\ngregory.t.brown@gmail.com"
@@ -0,0 +1,108 @@
1
+ require "test/unit"
2
+ require "ruport"
3
+ begin; require "rubygems"; rescue LoadError; nil end
4
+
5
+ class TestMailer < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @default_opts = {
9
+ :host => "mail.example.com",
10
+ :address => "sue@example.com",
11
+ :user => "inky",
12
+ :password => "chunky"
13
+ }
14
+
15
+ @other_opts = {
16
+ :host => "moremail.example.com",
17
+ :address => "clyde@example.com",
18
+ :user => "blinky",
19
+ :password => "bacon"
20
+ }
21
+
22
+ Ruport::Config.mailer :default, @default_opts
23
+ Ruport::Config.mailer :other, @other_opts
24
+
25
+ @default_mailer = Ruport::Mailer.new
26
+ @other_mailer = Ruport::Mailer.new :other
27
+ end
28
+
29
+ def assert_mailer_equal(expected, mailer)
30
+ assert_equal expected[:host], mailer.instance_variable_get(:@host)
31
+ assert_equal expected[:address], mailer.instance_variable_get(:@address)
32
+ assert_equal expected[:user], mailer.instance_variable_get(:@user)
33
+ assert_equal expected[:password], mailer.instance_variable_get(:@password)
34
+ end
35
+
36
+ def test_default_constructor
37
+ assert_mailer_equal @default_opts, @default_mailer
38
+ end
39
+
40
+ def test_constructor_with_mailer_label
41
+ assert_mailer_equal @other_opts, @other_mailer
42
+ end
43
+
44
+ def test_select_mailer
45
+ mailer = Ruport::Mailer.new :default
46
+ assert_mailer_equal @default_opts, mailer
47
+
48
+ mailer.send(:select_mailer, :other)
49
+ assert_mailer_equal @other_opts, mailer
50
+ end
51
+
52
+ def test_to
53
+ @default_mailer.instance_eval "@mail.to = ['foo@bar.com']"
54
+ assert_equal ['foo@bar.com'], @default_mailer.to
55
+ end
56
+
57
+ def test_to_equals
58
+ @default_mailer.to = ['foo@bar.com']
59
+ assert_equal ['foo@bar.com'], @default_mailer.to
60
+ end
61
+
62
+ def test_from
63
+ @default_mailer.instance_eval "@mail.from = ['foo@bar.com']"
64
+ assert_equal ['foo@bar.com'], @default_mailer.from
65
+ end
66
+
67
+ def test_from_equals
68
+ @default_mailer.from = ['foo@bar.com']
69
+ assert_equal ['foo@bar.com'], @default_mailer.from
70
+ end
71
+
72
+ def test_subject
73
+ @default_mailer.instance_eval "@mail.subject = ['RuportDay!']"
74
+ assert_equal ['RuportDay!'], @default_mailer.subject
75
+ end
76
+
77
+ def test_subject_equals
78
+ @default_mailer.subject = ['RuportDay!']
79
+ assert_equal ['RuportDay!'], @default_mailer.subject
80
+ end
81
+
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 }
105
+ end
106
+
107
+ end
108
+
@@ -0,0 +1,14 @@
1
+ require "test/unit"
2
+ require "ruport"
3
+
4
+ class A; extend Ruport::MetaTools; end
5
+
6
+ class TestMetaTools < Test::Unit::TestCase
7
+
8
+ def test_action
9
+ assert_nothing_raised { A.action(:foo) { |x| x + 1 } }
10
+ assert_equal 4, A.foo(3)
11
+ assert_raise(ActionAlreadyDefinedError) { A.action(:foo) { } }
12
+ end
13
+
14
+ end
@@ -1,6 +1,6 @@
1
1
  require "test/unit"
2
2
  require "ruport"
3
-
3
+ require "rubygems" rescue LoadError nil
4
4
 
5
5
  include Ruport
6
6
 
@@ -49,6 +49,11 @@ end
49
49
  class PDFPluginTest < Test::Unit::TestCase
50
50
 
51
51
  def test_ensure_fails_on_array
52
+ begin
53
+ require "pdf/writer"
54
+ rescue LoadError
55
+ warn "skipping pdf test"; return
56
+ end
52
57
  a = Format.table_object :plugin => :pdf, :data => [[1,2],[3,4]]
53
58
  assert_raise(RuntimeError) { a.render }
54
59
 
@@ -61,6 +66,12 @@ class PDFPluginTest < Test::Unit::TestCase
61
66
  end
62
67
 
63
68
  def test_hooks
69
+ begin
70
+ require "pdf/writer"
71
+ rescue LoadError
72
+ warn "skipping pdf test"; return
73
+ end
74
+ a = Format.table_object :plugin => :pdf, :data => [[1,2],[3,4]]
64
75
  a = Format.table_object :plugin => :pdf,
65
76
  :data => [[1,2],[3,4]].to_table(:column_names => %w[a b])
66
77
  y = 0
File without changes
@@ -135,6 +135,15 @@ class RecordTest < Test::Unit::TestCase
135
135
  @record.reorder! 3,1,2
136
136
  assert_equal [3,4,2], @record.data
137
137
  assert_equal %w[c d b], @record.attributes
138
+
139
+ r.reorder! %w[a b c]
140
+ assert_equal [1,2,3], r.data
141
+ assert_equal %w[a b c], r.attributes
142
+
143
+ assert_raise(ArgumentError) { r.reorder "foo" }
144
+ assert_raise(ArgumentError) { r.reorder 0,5 }
145
+ assert_nothing_raised { r.reorder 0 }
146
+ assert_nothing_raised { r.reorder "a","b" }
138
147
  end
139
148
 
140
149
  def test_dup