Class: Cucumber::Formatter::Pdf

Inherits:
Ast::Visitor show all
Includes:
Console, FileUtils
Defined in:
lib/cucumber/formatter/pdf.rb

Constant Summary

Constants included from Console

Console::FORMATS

Constants included from ANSIColor

ANSIColor::ALIASES

Instance Attribute Summary collapse

Attributes inherited from Ast::Visitor

#options, #step_mother

Instance Method Summary collapse

Methods included from Console

#announce, #format_step, #format_string, #print_counts, #print_elements, #print_exception, #print_passing_wip, #print_snippets, #print_stats, #print_steps, #print_tag_limit_warnings, #record_tag_occurrences

Methods included from ANSIColor

define_grey, define_real_grey, #grey

Methods included from Duration

#format_duration

Methods inherited from Ast::Visitor

#announce, #visit_examples, #visit_examples_array, #visit_exception, #visit_step, #visit_steps, #visit_table_cell, #visit_table_cell_value, #visit_table_row, #visit_tags

Constructor Details

#initialize(step_mother, io, options) ⇒ Pdf

Returns a new instance of Pdf.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/cucumber/formatter/pdf.rb', line 18

def initialize(step_mother, io, options)
  super(step_mother)
  raise "You *must* specify --out FILE for the pdf formatter" unless File === io

  if(options[:dry_run])
    @status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK}
  else
    @status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202'}
  end

  @pdf = Prawn::Document.new
  @scrap = Prawn::Document.new
  @doc = @scrap
  @io = io
  @options = options
  @exceptions = []
  @indent = 0
  @buffer = []
  puts "writing to #{io.path}"
  begin
    @pdf.image open("features/support/logo.png"), :position => :center, :width => 500
  rescue
  end
  @pdf.text "\n\n\nCucumber features", :align => :center, :size => 32
  @pdf.text "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M")}", :size => 10, :at => [0, 24]
  @pdf.text "Command: <code>cucumber #{ARGV.join(" ")}</code>", :size => 10, :at => [0,10]
  unless options[:dry_run]
    @pdf.bounding_box [450,100] , :width => 100 do  
      @pdf.text 'Legend', :size => 10
      @status_colors.each do |k,v|
        @pdf.fill_color v
        @pdf.text k.to_s, :size => 10
        @pdf.fill_color BLACK
      end
    end
  end
end

Instance Attribute Details

#indent=(value) ⇒ Object (writeonly)

Sets the attribute indent

Parameters:

  • value

    the value to set the attribute indent to.



16
17
18
# File 'lib/cucumber/formatter/pdf.rb', line 16

def indent=(value)
  @indent = value
end

Instance Method Details

#colorize(text, status) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/cucumber/formatter/pdf.rb', line 146

def colorize(text, status)
  keep_with do
    @doc.fill_color(@status_colors[status] || BLACK)
    @doc.text(text)
    @doc.fill_color(BLACK)
  end
end

#flushObject

This method does a ‘test’ rendering on a blank page, to see the rendered height of the buffer if that too high for the space left on the age in the real document, we do a page break. This obviously doesn’t work if a scenario is longer than a whole page (God forbid)



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/cucumber/formatter/pdf.rb', line 70

def flush
  @scrap.start_new_page
  oldy = @scrap.y
  render @scrap
  height = (oldy - @scrap.y) + 36 # whops magic number
  if ((@pdf.y - height) < @pdf.bounds.bottom)
    @pdf.start_new_page
  end
  render @pdf
  @pdf.move_down(20)
  @buffer = []
end

#keep_with(&block) ⇒ Object



56
57
58
# File 'lib/cucumber/formatter/pdf.rb', line 56

def keep_with(&block)
  @buffer << block
end

#render(doc) ⇒ Object



60
61
62
63
64
65
# File 'lib/cucumber/formatter/pdf.rb', line 60

def render(doc)
  @doc = doc
  @buffer.each do |proc|
    proc.call
  end
end

#visit_background(background) ⇒ Object



159
160
161
162
163
# File 'lib/cucumber/formatter/pdf.rb', line 159

def visit_background(background)
  @in_background = true
  super
  @in_background = nil
end

#visit_background_name(keyword, name, file_colon_line, source_indent) ⇒ Object



204
205
206
# File 'lib/cucumber/formatter/pdf.rb', line 204

def visit_background_name(keyword, name, file_colon_line, source_indent)
  visit_feature_element_name(keyword, name)
end

#visit_comment(comment) ⇒ Object



192
193
194
# File 'lib/cucumber/formatter/pdf.rb', line 192

def visit_comment(comment)
  comment.accept(self)
end

#visit_comment_line(comment_line) ⇒ Object



196
197
# File 'lib/cucumber/formatter/pdf.rb', line 196

def visit_comment_line(comment_line)
end

#visit_examples_name(keyword, name) ⇒ Object



208
209
210
# File 'lib/cucumber/formatter/pdf.rb', line 208

def visit_examples_name(keyword, name)
  visit_feature_element_name(keyword, name)
end

#visit_feature(feature) ⇒ Object



115
116
117
118
# File 'lib/cucumber/formatter/pdf.rb', line 115

def visit_feature(feature)
  super
  flush
end

#visit_feature_element(feature_element) ⇒ Object



109
110
111
112
113
# File 'lib/cucumber/formatter/pdf.rb', line 109

def visit_feature_element(feature_element)
  record_tag_occurrences(feature_element, @options)
  super
  flush
end

#visit_feature_element_name(keyword, name) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cucumber/formatter/pdf.rb', line 120

def visit_feature_element_name(keyword, name)
  names = name.empty? ? [name] : name.split("\n")
  print "."
  STDOUT.flush

  keep_with do
    @doc.move_down(20)
    @doc.fill_color GREY
    @doc.text("#{keyword}", :size => 8)
    @doc.fill_color BLACK
    @doc.text("#{names[0]}", :size => 16)
    names[1..-1].each { |s| @doc.text(s, :size => 12) }
    @doc.text("\n")
  end
end

#visit_feature_name(name) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cucumber/formatter/pdf.rb', line 90

def visit_feature_name(name)
  @pdf.start_new_page
  name["Feature:"] = "" if name["Feature:"]
  names = name.split("\n")
  @pdf.fill_color GREY
  @pdf.text('Feature', :align => :center)
  @pdf.fill_color BLACK
  names.each_with_index do |nameline, i|
    case i
    when 0
      @pdf.text(nameline.strip, :size => 30, :align => :center )
      @pdf.text("\n")
    else
      @pdf.text(nameline.strip, :size => 12)
    end
  end
  @pdf.move_down(30)
end

#visit_features(features) ⇒ Object

regular visitor entries



84
85
86
87
88
# File 'lib/cucumber/formatter/pdf.rb', line 84

def visit_features(features)
  super
  @pdf.render_file(@io.path)
  puts "\ndone"
end

#visit_multiline_arg(table) ⇒ Object



165
166
167
168
169
170
171
172
# File 'lib/cucumber/formatter/pdf.rb', line 165

def visit_multiline_arg(table)
  if(table.kind_of? Cucumber::Ast::Table)
    keep_with do
      @doc.table(table.rows << table.headers , :position => :center, :row_colors => ['ffffff', 'f0f0f0'])
    end
  end
  super
end

#visit_outline_table(table) ⇒ Object

using row_color hack to highlight each row correctly



175
176
177
178
179
180
# File 'lib/cucumber/formatter/pdf.rb', line 175

def visit_outline_table(table)
  row_colors = table.example_rows.map { |r| @status_colors[r.status] unless r.status == :skipped}
  keep_with do
    @doc.table(table.rows, :headers => table.headers, :position => :center, :row_colors => row_colors)
  end
end

#visit_py_string(string) ⇒ Object



182
183
184
185
186
187
188
189
190
# File 'lib/cucumber/formatter/pdf.rb', line 182

def visit_py_string(string)
  s = %{"""\n#{string}\n"""}.indent(10)
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}
  s.each do |line|
    line.gsub!('<', '&lt;')
    line.gsub!('>', '&gt;')
    keep_with { @doc.text line, :size => 8 }
  end
end

#visit_scenario_name(keyword, name, file_colon_line, source_indent) ⇒ Object



212
213
214
# File 'lib/cucumber/formatter/pdf.rb', line 212

def visit_scenario_name(keyword, name, file_colon_line, source_indent)
  visit_feature_element_name(keyword, name)
end

#visit_step_name(keyword, step_match, status, source_indent, background) ⇒ Object



154
155
156
157
# File 'lib/cucumber/formatter/pdf.rb', line 154

def visit_step_name(keyword, step_match, status, source_indent, background)
  line = "<b>#{keyword}</b> #{step_match.format_args("%s").gsub('<', '&lt;').gsub('>', '&gt;')}"
  colorize(line, status)
end

#visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background) ⇒ Object



136
137
138
139
140
141
142
143
144
# File 'lib/cucumber/formatter/pdf.rb', line 136

def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
  if exception
    return if @exceptions.index(exception)
    @exceptions << exception
  end
  return if status != :failed && @in_background ^ background
  @status = status
  super
end

#visit_tag_name(tag_name) ⇒ Object



199
200
201
202
# File 'lib/cucumber/formatter/pdf.rb', line 199

def visit_tag_name(tag_name)
  tag = format_string(tag_name, :tag).indent(@indent)
  # TODO should we render tags at all? skipped for now. difficult to place due to page breaks
end