ruport 1.0.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +3 -0
- data/README +11 -5
- data/Rakefile +2 -2
- data/examples/btree/commaleon/commaleon.rb +1 -1
- data/examples/simple_templating_example.rb +34 -0
- data/examples/tattle_rubygems_version.rb +6 -5
- data/examples/trac_ticket_status.rb +2 -2
- data/lib/ruport.rb +5 -4
- data/lib/ruport/acts_as_reportable.rb +63 -37
- data/lib/ruport/data.rb +1 -0
- data/lib/ruport/data/feeder.rb +111 -0
- data/lib/ruport/data/grouping.rb +84 -22
- data/lib/ruport/data/record.rb +1 -1
- data/lib/ruport/data/table.rb +127 -87
- data/lib/ruport/formatter.rb +22 -9
- data/lib/ruport/formatter/csv.rb +27 -3
- data/lib/ruport/formatter/html.rb +26 -6
- data/lib/ruport/formatter/pdf.rb +169 -36
- data/lib/ruport/formatter/template.rb +167 -0
- data/lib/ruport/formatter/text.rb +47 -15
- data/lib/ruport/query.rb +1 -1
- data/lib/ruport/renderer.rb +46 -56
- data/test/acts_as_reportable_test.rb +20 -20
- data/test/csv_formatter_test.rb +26 -1
- data/test/data_feeder_test.rb +88 -0
- data/test/grouping_test.rb +90 -4
- data/test/html_formatter_test.rb +25 -2
- data/test/pdf_formatter_test.rb +69 -3
- data/test/query_test.rb +3 -2
- data/test/record_test.rb +2 -1
- data/test/renderer_test.rb +49 -3
- data/test/sql_split_test.rb +4 -2
- data/test/table_test.rb +159 -65
- data/test/template_test.rb +37 -0
- data/test/text_formatter_test.rb +33 -1
- metadata +9 -4
- data/lib/ruport/renderer.rb.orig +0 -542
- data/test/renderer_test.rb.orig +0 -512
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
3
|
+
|
2
4
|
begin
|
3
5
|
require "mocha"
|
4
|
-
require "stubba"
|
5
|
-
require "active_record"
|
6
|
+
require "stubba"
|
7
|
+
Ruport.quiet { require "active_record" }
|
6
8
|
rescue LoadError
|
7
9
|
nil
|
8
10
|
end
|
9
11
|
|
10
12
|
if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
11
13
|
|
12
|
-
require "ruport/acts_as_reportable"
|
14
|
+
require "ruport/acts_as_reportable"
|
13
15
|
|
14
16
|
class Team < ActiveRecord::Base
|
15
17
|
acts_as_reportable :except => 'id', :include => :players
|
@@ -148,16 +150,7 @@ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
|
148
150
|
:include => { :players => { :only => 'name' } })
|
149
151
|
expected = [["Testers", "Player 1"],
|
150
152
|
["Testers", "Player 2"],
|
151
|
-
["Others", nil]].to_table(%w[name
|
152
|
-
assert_equal expected, actual
|
153
|
-
end
|
154
|
-
|
155
|
-
def test_preserve_namespace_option
|
156
|
-
actual = Player.report_table(:all, :only => 'name',
|
157
|
-
:include => :personal_trainer, :preserve_namespace => true)
|
158
|
-
expected = [["Player 1", "Trainer 1"],
|
159
|
-
["Player 2", "Trainer 2"]].to_table(%w[name
|
160
|
-
some_module/personal_trainer.name])
|
153
|
+
["Others", nil]].to_table(%w[name players.name])
|
161
154
|
assert_equal expected, actual
|
162
155
|
end
|
163
156
|
|
@@ -176,8 +169,15 @@ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
|
176
169
|
assert_equal :players, Team.send(:get_include_for_find, nil)
|
177
170
|
assert_equal nil, Player.send(:get_include_for_find, nil)
|
178
171
|
assert_equal :team, Player.send(:get_include_for_find, :team)
|
179
|
-
|
172
|
+
expected = {:team => {}}
|
173
|
+
assert_equal expected,
|
180
174
|
Player.send(:get_include_for_find, {:team => {:except => 'id'}})
|
175
|
+
expected = {:team => {:a => {}, :b => {}},
|
176
|
+
:c => {:d => {:e => {}, :f => {}}},
|
177
|
+
:g => {}}
|
178
|
+
assert_equal expected,
|
179
|
+
Player.send(:get_include_for_find, {:team => {:include => [:a,:b]},
|
180
|
+
:c => {:include => {:d => {:include => [:e,:f]}}}, :g => {}})
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
@@ -195,10 +195,10 @@ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
|
195
195
|
{ :players => { :only => 'name' } })
|
196
196
|
expected = [{ 'name' => "Testers",
|
197
197
|
'league' => "My League",
|
198
|
-
'
|
198
|
+
'players.name' => "Player 1" },
|
199
199
|
{ 'name' => "Testers",
|
200
200
|
'league' => "My League",
|
201
|
-
'
|
201
|
+
'players.name' => "Player 2" }]
|
202
202
|
assert_equal expected, actual
|
203
203
|
end
|
204
204
|
|
@@ -206,7 +206,7 @@ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
|
206
206
|
actual = @players[0].send(:add_includes,
|
207
207
|
[{ 'name' => "Player 1" }], :personal_trainer)
|
208
208
|
expected = [{ 'name' => "Player 1",
|
209
|
-
'
|
209
|
+
'personal_trainer.name' => "Trainer 1" }]
|
210
210
|
assert_equal expected, actual
|
211
211
|
end
|
212
212
|
|
@@ -237,8 +237,8 @@ if Object.const_defined?(:ActiveRecord) && Object.const_defined?(:Mocha)
|
|
237
237
|
assert_equal expected, actual
|
238
238
|
|
239
239
|
actual = @players[0].send(:get_attributes_with_options,
|
240
|
-
{ :only => 'name', :qualify_attribute_names =>
|
241
|
-
expected = { '
|
240
|
+
{ :only => 'name', :qualify_attribute_names => :players })
|
241
|
+
expected = { 'players.name' => "Player 1" }
|
242
242
|
assert_equal expected, actual
|
243
243
|
end
|
244
244
|
end
|
data/test/csv_formatter_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
2
3
|
|
3
4
|
class TestRenderCSVRow < Test::Unit::TestCase
|
4
5
|
def test_render_csv_row
|
@@ -34,6 +35,30 @@ class TestRenderCSVTable < Test::Unit::TestCase
|
|
34
35
|
assert_equal("1,2,3\n4,5,6\n",actual)
|
35
36
|
end
|
36
37
|
|
38
|
+
def test_render_with_template
|
39
|
+
Ruport::Formatter::Template.create(:simple) do |t|
|
40
|
+
t.table_format = {
|
41
|
+
:show_headings => false
|
42
|
+
}
|
43
|
+
t.grouping_format = {
|
44
|
+
:style => :justified,
|
45
|
+
:show_headings => false
|
46
|
+
}
|
47
|
+
t.format_options = { :col_sep => ":" }
|
48
|
+
end
|
49
|
+
|
50
|
+
formatter = Ruport::Formatter::CSV.new
|
51
|
+
formatter.options = Ruport::Renderer::Options.new
|
52
|
+
formatter.options.template = :simple
|
53
|
+
formatter.apply_template
|
54
|
+
|
55
|
+
assert_equal false, formatter.options.show_table_headers
|
56
|
+
|
57
|
+
assert_equal :justified, formatter.options.style
|
58
|
+
assert_equal false, formatter.options.show_group_headers
|
59
|
+
|
60
|
+
assert_equal ":", formatter.options.format_options[:col_sep]
|
61
|
+
end
|
37
62
|
end
|
38
63
|
|
39
64
|
class TestRenderCSVGroup < Test::Unit::TestCase
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
3
|
+
|
4
|
+
class DataFeederTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "when using a default data feeder" do
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
|
10
|
+
end
|
11
|
+
|
12
|
+
def specify_data_attribute_should_return_wrapped_data
|
13
|
+
assert_equal Table(%w[a b c]), @feeder.data
|
14
|
+
end
|
15
|
+
|
16
|
+
def specify_append_should_forward_to_wrapped_data_by_default
|
17
|
+
t = Table(%w[a b c])
|
18
|
+
t << [1,2,3] << {"a" => 2, "b" => 3, "c" => 4}
|
19
|
+
@feeder << [1,2,3] << {"a" => 2, "b" => 3, "c" => 4}
|
20
|
+
assert_equal t, @feeder.data
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when using a feeder with a filter" do
|
26
|
+
def setup
|
27
|
+
@feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
|
28
|
+
@feeder.filter { |r| r.a != 1 }
|
29
|
+
end
|
30
|
+
|
31
|
+
def specify_filter_should_only_append_rows_for_which_block_is_true
|
32
|
+
@feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
|
33
|
+
assert_equal Table(%w[a b c], :data => [[4,1,2],[3,1,1]]), @feeder.data
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when using a feeder with a transform" do
|
38
|
+
def setup
|
39
|
+
@feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
|
40
|
+
@feeder.transform { |r| r.a += 1 }
|
41
|
+
end
|
42
|
+
|
43
|
+
def specify_filter_should_be_applied_to_all_rows
|
44
|
+
@feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
|
45
|
+
assert_equal Table(%w[a b c], :data => [[2,2,3],[5,1,2],[4,1,1],[2,2,5]]),
|
46
|
+
@feeder.data
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when using a feeder and a filter together" do
|
51
|
+
def setup
|
52
|
+
@feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
|
53
|
+
end
|
54
|
+
|
55
|
+
def specify_filter_is_called_first_when_defined_first
|
56
|
+
@feeder.filter { |r| r.b != 2 }
|
57
|
+
@feeder.transform { |r| r.b += 1 }
|
58
|
+
@feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
|
59
|
+
assert_equal Table(%w[a b c], :data => [[4,2,2],[3,2,1]]),
|
60
|
+
@feeder.data
|
61
|
+
end
|
62
|
+
|
63
|
+
def specify_transform_is_called_first_when_defined_first
|
64
|
+
@feeder.transform { |r| r.b += 1 }
|
65
|
+
@feeder.filter { |r| r.b != 2 }
|
66
|
+
@feeder << [1,2,3] << [4,1,2] << [3,1,1] << [1,2,5]
|
67
|
+
assert_equal Table(%w[a b c], :data => [[1,3,3],[1,3,5]]),
|
68
|
+
@feeder.data
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when using many feeders and filters together" do
|
73
|
+
def setup
|
74
|
+
@feeder = Ruport::Data::Feeder.new(Table(%w[a b c]))
|
75
|
+
@feeder.transform { |r| r.a += 1 }
|
76
|
+
@feeder.filter { |r| r.a > 5 }
|
77
|
+
@feeder.transform { |r| r.b = r.b.to_s }
|
78
|
+
@feeder.filter { |r| r.b == "3" }
|
79
|
+
end
|
80
|
+
|
81
|
+
def specify_all_blocks_are_executed_in_order
|
82
|
+
@feeder << [1,2,3] << [4,1,9] << [5,3,1] << [2,3,0] << [7,3,5]
|
83
|
+
assert_equal Table(%w[a b c], :data => [[6,"3",1],[8,"3",5]]),
|
84
|
+
@feeder.data
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/test/grouping_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
2
3
|
|
3
4
|
class TestGroup < Test::Unit::TestCase
|
4
5
|
|
@@ -232,7 +233,8 @@ class TestGrouping < Test::Unit::TestCase
|
|
232
233
|
end
|
233
234
|
|
234
235
|
def test_grouping_summary
|
235
|
-
source = Table(
|
236
|
+
source = Table(File.join(File.expand_path(File.dirname(__FILE__)),
|
237
|
+
*%w[samples ticket_count.csv]),
|
236
238
|
:record_class => TicketStatus)
|
237
239
|
grouping = Grouping(source,:by => "date")
|
238
240
|
|
@@ -254,8 +256,92 @@ class TestGrouping < Test::Unit::TestCase
|
|
254
256
|
:opened => lambda { |g| g.sigma(:opened) },
|
255
257
|
:closed => lambda { |g| g.sigma(:closed) }
|
256
258
|
|
257
|
-
assert_equal [], expected.column_names - actual.column_names
|
258
|
-
end
|
259
|
+
assert_equal [], expected.column_names - actual.column_names
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_grouping_sigma
|
263
|
+
assert_respond_to @grouping, :sigma
|
264
|
+
assert_respond_to @grouping, :sum
|
265
|
+
|
266
|
+
expected = {}
|
267
|
+
@grouping.data[@grouping.data.keys.first].column_names.each do |col|
|
268
|
+
expected[col] = @grouping.inject(0) do |s, (group_name, group)|
|
269
|
+
s + group.sigma(col)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
expected.keys.each do |col|
|
273
|
+
assert_equal expected[col], @grouping.sigma(col)
|
274
|
+
end
|
275
|
+
|
276
|
+
expected = {}
|
277
|
+
@grouping.data[@grouping.data.keys.first].column_names.each do |col|
|
278
|
+
expected[col] = @grouping.inject(0) do |s, (group_name, group)|
|
279
|
+
s + group.sigma {|r| r[col] + 2 }
|
280
|
+
end
|
281
|
+
end
|
282
|
+
expected.keys.each do |col|
|
283
|
+
assert_equal expected[col], @grouping.sigma {|r| r[col] + 2 }
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context "when sorting groupings" do
|
288
|
+
|
289
|
+
def setup
|
290
|
+
@table = Table(%w[a b c]) << ["dog",1,2] << ["cat",3,5] <<
|
291
|
+
["banana",8,1] << ["dog",5,6]
|
292
|
+
end
|
293
|
+
|
294
|
+
def specify_can_set_by_group_name_order_in_constructor
|
295
|
+
a = Grouping(@table, :by => "a", :order => :name)
|
296
|
+
names = %w[banana cat dog]
|
297
|
+
data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
|
298
|
+
a.each do |name,group|
|
299
|
+
assert_equal names.shift, name
|
300
|
+
assert_equal data.shift, group.map { |r| r.to_a }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def specify_can_set_by_proc_ordering_in_constructor
|
305
|
+
a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
|
306
|
+
names = %w[dog banana cat]
|
307
|
+
data = [ [[1,2],[5,6]], [[8,1]], [[3,5]] ]
|
308
|
+
a.each do |name,group|
|
309
|
+
assert_equal names.shift, name
|
310
|
+
assert_equal data.shift, group.map { |r| r.to_a }
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def specify_can_override_sorting
|
315
|
+
a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
|
316
|
+
a.sort_grouping_by!(:name)
|
317
|
+
names = %w[banana cat dog]
|
318
|
+
data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
|
319
|
+
a.each do |name,group|
|
320
|
+
assert_equal names.shift, name
|
321
|
+
assert_equal data.shift, group.map { |r| r.to_a }
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def specify_can_get_a_new_sorted_grouping
|
326
|
+
a = Grouping(@table, :by => "a", :order => lambda { |g| -g.length } )
|
327
|
+
b = a.sort_grouping_by(:name)
|
328
|
+
|
329
|
+
names = %w[banana cat dog]
|
330
|
+
data = [ [[8,1]], [[3,5]], [[1,2],[5,6]] ]
|
331
|
+
b.each do |name,group|
|
332
|
+
assert_equal names.shift, name
|
333
|
+
assert_equal data.shift, group.map { |r| r.to_a }
|
334
|
+
end
|
335
|
+
|
336
|
+
# assert original retained
|
337
|
+
names = %w[dog banana cat]
|
338
|
+
data = [ [[1,2],[5,6]], [[8,1]], [[3,5]] ]
|
339
|
+
a.each do |name,group|
|
340
|
+
assert_equal names.shift, name
|
341
|
+
assert_equal data.shift, group.map { |r| r.to_a }
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
259
345
|
|
260
346
|
class MyRecord < Ruport::Data::Record; end
|
261
347
|
|
data/test/html_formatter_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
2
3
|
|
3
4
|
class TestRenderHTMLTable < Test::Unit::TestCase
|
4
5
|
|
@@ -30,7 +31,29 @@ class TestRenderHTMLTable < Test::Unit::TestCase
|
|
30
31
|
"\n\t\t\t<td>4</td>\n\t\t\t<td>5</td>\n\t\t\t<td>6</td>\n\t"+
|
31
32
|
"\t</tr>\n\t</table>",actual)
|
32
33
|
|
33
|
-
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_render_with_template
|
37
|
+
Ruport::Formatter::Template.create(:simple) do |t|
|
38
|
+
t.table_format = {
|
39
|
+
:show_headings => false
|
40
|
+
}
|
41
|
+
t.grouping_format = {
|
42
|
+
:style => :justified,
|
43
|
+
:show_headings => false
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
formatter = Ruport::Formatter::HTML.new
|
48
|
+
formatter.options = Ruport::Renderer::Options.new
|
49
|
+
formatter.options.template = :simple
|
50
|
+
formatter.apply_template
|
51
|
+
|
52
|
+
assert_equal false, formatter.options.show_table_headers
|
53
|
+
|
54
|
+
assert_equal :justified, formatter.options.style
|
55
|
+
assert_equal false, formatter.options.show_group_headers
|
56
|
+
end
|
34
57
|
end
|
35
58
|
|
36
59
|
|
data/test/pdf_formatter_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "helpers")
|
2
3
|
|
3
4
|
class TestRenderPDFTable < Test::Unit::TestCase
|
4
5
|
|
@@ -17,7 +18,8 @@ class TestRenderPDFTable < Test::Unit::TestCase
|
|
17
18
|
|
18
19
|
# this is mostly to check that the transaction hack gets called
|
19
20
|
def test_relatively_large_pdf
|
20
|
-
table = Table(
|
21
|
+
table = Table(File.join(File.expand_path(File.dirname(__FILE__)),
|
22
|
+
%w[samples dates.csv]))
|
21
23
|
table.reduce(0..99)
|
22
24
|
assert_nothing_raised { table.to_pdf }
|
23
25
|
end
|
@@ -32,6 +34,59 @@ class TestRenderPDFTable < Test::Unit::TestCase
|
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
37
|
+
def test_render_with_template
|
38
|
+
Ruport::Formatter::Template.create(:simple) do |t|
|
39
|
+
t.page_format = {
|
40
|
+
:size => "LETTER",
|
41
|
+
:layout => :landscape
|
42
|
+
}
|
43
|
+
t.text_format = {
|
44
|
+
:font_size => 16
|
45
|
+
}
|
46
|
+
t.table_format = {
|
47
|
+
:show_headings => false
|
48
|
+
}
|
49
|
+
t.column_format = {
|
50
|
+
:alignment => :center,
|
51
|
+
:width => 50
|
52
|
+
}
|
53
|
+
t.heading_format = {
|
54
|
+
:alignment => :right,
|
55
|
+
:bold => false,
|
56
|
+
:title => "Test"
|
57
|
+
}
|
58
|
+
t.grouping_format = {
|
59
|
+
:style => :separated
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
formatter = Ruport::Formatter::PDF.new
|
64
|
+
formatter.options = Ruport::Renderer::Options.new
|
65
|
+
formatter.options.template = :simple
|
66
|
+
formatter.apply_template
|
67
|
+
|
68
|
+
assert_equal "LETTER", formatter.options.paper_size
|
69
|
+
assert_equal :landscape, formatter.options.paper_orientation
|
70
|
+
|
71
|
+
assert_equal 16, formatter.options.text_format[:font_size]
|
72
|
+
|
73
|
+
assert_equal false, formatter.options.table_format[:show_headings]
|
74
|
+
|
75
|
+
assert_equal :center,
|
76
|
+
formatter.options.table_format[:column_options][:justification]
|
77
|
+
assert_equal 50,
|
78
|
+
formatter.options.table_format[:column_options][:width]
|
79
|
+
|
80
|
+
assert_equal :right,
|
81
|
+
formatter.options.table_format[:column_options][:heading][:justification]
|
82
|
+
assert_equal false,
|
83
|
+
formatter.options.table_format[:column_options][:heading][:bold]
|
84
|
+
assert_equal "Test",
|
85
|
+
formatter.options.table_format[:column_options][:heading][:title]
|
86
|
+
|
87
|
+
assert_equal :separated, formatter.options.style
|
88
|
+
end
|
89
|
+
|
35
90
|
#--------BUG TRAPS--------#
|
36
91
|
|
37
92
|
# PDF::SimpleTable does not handle symbols as column names
|
@@ -146,4 +201,15 @@ class TestPDFFormatterHelpers < Test::Unit::TestCase
|
|
146
201
|
|
147
202
|
assert_equal 80, a.cursor
|
148
203
|
end
|
149
|
-
|
204
|
+
|
205
|
+
def test_draw_text_retains_cursor
|
206
|
+
a = Ruport::Formatter::PDF.new
|
207
|
+
a.move_cursor_to(100)
|
208
|
+
|
209
|
+
a.draw_text "foo", :left => a.left_boundary
|
210
|
+
assert_equal 100, a.cursor
|
211
|
+
|
212
|
+
a.draw_text "foo", :left => a.left_boundary + 50, :y => 500
|
213
|
+
assert_equal 100, a.cursor
|
214
|
+
end
|
215
|
+
end
|