bddgenx 0.1.42 → 0.1.43

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9d0fa653a6cce274a37045260ebaa2aa15c155e86e0ec5c0bc786fd452c338e
4
- data.tar.gz: 31d0a6db315449deb19fa51a4cb2dd82405b467f3116798505cafeaff27e8a4a
3
+ metadata.gz: 27d5aae37397f6f4cbebc64d87ea9046812aa8ca9754f15963f7a943e04c870f
4
+ data.tar.gz: cad3d2ef7e11724824d2cd3c3a31ffd09725d189f6f20813488fd5164db1ea01
5
5
  SHA512:
6
- metadata.gz: 69e4664c77d38ba18dd4c37329136894af94cf49c931f1675f876796446df4df2aa976b4cb8580f7a4bd43f616b99cf9da92fe251952c3a8c5265ce4bcc65ee7
7
- data.tar.gz: 14a58ba2da3e62c03f30ba0c724676ba59831f3bf2f6565d882e4e33f0f85d76492a6e0a78b7e24c46a19d18a227f1f1c2eeedc051d48cfba0bf4025bf523002
6
+ metadata.gz: 8f9d4ff065c91d9b4c20e77fa2ef267c13c43d574d5f825afa0eb07f90518ba1994666a95464058152a8f8346a1283a9419311ad4ee3a55ed42ce75ae492a222
7
+ data.tar.gz: b7f6fc413a78140a23812ab38db086b49c5cb5db1fdd0f51251e5607df6a6c57481c07acee2c95303b9e99ffa1120ae8f165dde5a698dca4c915ab9c7ad0c1cb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.42
1
+ 0.1.43
@@ -55,7 +55,7 @@ module Bddgenx
55
55
  if exemplos.any?
56
56
  # Scenario Outline
57
57
  conteudo << " #{tag_line}\n"
58
- conteudo << " #{palavras[:esquema]}: Exemplo #{idx+1}\n"
58
+ conteudo << " #{palavras[:esquema]}: #{historia[:quero]}\n"
59
59
 
60
60
  # Renderiza cada passo, mapeando connector mesmo se não for Gherkin padrão
61
61
  passos.each do |p|
@@ -4,12 +4,12 @@ require 'rubygems' # para Gem.loaded_specs
4
4
 
5
5
  module Bddgenx
6
6
  class FontLoader
7
- # Retorna o diretório assets/fonts dentro da gem, mesmo em dev local
7
+ # Retorna o diretório assets/fonts dentro da gem
8
8
  def self.fonts_path
9
- File.expand_path('../../bddgenx/assets/fonts', __dir__)
9
+ File.expand_path('../../assets/fonts', __dir__)
10
10
  end
11
11
 
12
- # Retorna famílias de fontes TrueType para Prawn; vazio se faltar arquivos
12
+ # Carrega famílias de fontes TrueType para Prawn
13
13
  def self.families
14
14
  base = fonts_path
15
15
  return {} unless Dir.exist?(base)
@@ -24,7 +24,7 @@ module Bddgenx
24
24
  if files.values.all? { |path| File.file?(path) && File.size(path) > 12 }
25
25
  { 'DejaVuSansMono' => files }
26
26
  else
27
- warn "⚠️ Fontes DejaVuSansMono ausentes ou corrompidas em #{base}."
27
+ warn "⚠️ Fontes DejaVuSansMono ausentes ou corrompidas em #{base}. Usando fallback Courier."
28
28
  {}
29
29
  end
30
30
  end
@@ -1,144 +1,129 @@
1
1
  # lib/bddgenx/pdf_exporter.rb
2
2
  require 'prawn'
3
+ require 'prawn/table'
3
4
  require 'fileutils'
4
5
  require_relative 'fontLoader'
5
6
 
7
+ # Suprime aviso de internacionalização para fontes AFM built-in
8
+ Prawn::Fonts::AFM.hide_m17n_warning = true
9
+
6
10
  module Bddgenx
7
11
  class PDFExporter
8
- KEYWORD_COLORS = {
9
- 'Given' => '0000FF',
10
- 'When' => '008000',
11
- 'Then' => '800080',
12
- 'And' => '000000',
13
- 'But' => 'FF0000'
14
- }
15
-
16
- def self.exportar_todos(only_new: false)
12
+ # Gera PDFs a partir de arquivos .feature no estilo pretty Cucumber em P/B
13
+ # Params:
14
+ # +caminho_feature+:: (String) caminho para um arquivo .feature específico. Se nil, gera para todos em features/*.feature
15
+ # +only_new+:: (Boolean) se true, não sobrescreve PDFs já existentes
16
+ def self.exportar_todos(caminho_feature: nil, only_new: false)
17
17
  FileUtils.mkdir_p('reports/pdf')
18
+ features_list = if caminho_feature && !caminho_feature.empty?
19
+ [caminho_feature]
20
+ else
21
+ Dir.glob('features/*.feature')
22
+ end
23
+
18
24
  generated, skipped = [], []
19
- Dir.glob('features/*.feature').each do |feature|
25
+ features_list.each do |feature|
26
+ unless File.file?(feature)
27
+ warn "⚠️ Feature não encontrada: #{feature}"
28
+ next
29
+ end
20
30
  nome = File.basename(feature, '.feature')
21
31
  destino = "reports/pdf/#{camel_case(nome)}.pdf"
22
- if File.exist?(destino)
32
+
33
+ if only_new && File.exist?(destino)
23
34
  skipped << destino
24
- else
25
- exportar_arquivo(feature, destino)
26
- generated << destino
35
+ next
27
36
  end
37
+
38
+ exportar_arquivo(feature, destino)
39
+ generated << destino
28
40
  end
41
+
29
42
  { generated: generated, skipped: skipped }
30
43
  end
31
44
 
45
+ # Converte string para camelCase, removendo caracteres especiais
32
46
  def self.camel_case(str)
33
47
  clean = str.gsub(/[^0-9A-Za-z ]/, '')
34
48
  parts = clean.split(/ |_/)
35
49
  ([parts.first&.downcase] + (parts[1..] || []).map(&:capitalize)).join
36
50
  end
37
51
 
52
+ # Gera o PDF formatado a partir de um único arquivo .feature, sem executar testes
38
53
  def self.exportar_arquivo(origem, destino)
39
54
  FileUtils.mkdir_p(File.dirname(destino))
40
55
  conteudo = File.read(origem, encoding: 'utf-8')
41
56
 
42
- families = FontLoader.families
43
- usar_ttf = !families.empty?
44
-
45
57
  Prawn::Document.generate(destino, page_size: 'A4', margin: 50) do |pdf|
46
- if usar_ttf
47
- pdf.font_families.update(families)
48
- pdf.font 'DejaVuSansMono'
49
- else
50
- pdf.font 'Courier'
51
- end
52
- pdf.font_size 10
53
-
54
- # Cabeçalho da Feature
55
- feature_title = conteudo.lines.find { |l| l =~ /^Feature:/i }&.strip || File.basename(origem)
56
- pdf.text feature_title, size: 18, style: :bold
57
- pdf.move_down 8
58
-
59
- # Descrição pós-Feature
60
- descr = []
61
- conteudo.each_line.drop_while { |l| l !~ /^Feature:/i }.drop(1).each do |l|
62
- break unless l.strip.start_with?('#')
63
- descr << l.strip.sub(/^#\s*/, '')
64
- end
65
- unless descr.empty?
66
- pdf.text descr.join("\n"), size: 11, align: :left
67
- pdf.move_down 12
68
- end
58
+ pdf.font 'Courier'
59
+ pdf.font_size 9
69
60
 
70
- examples_rows = []
61
+ table_buffer = []
71
62
  conteudo.each_line do |linha|
72
63
  text = linha.chomp
73
- next if text =~ /^#\s*language:/i
74
64
 
75
- # Coleciona linhas de tabela
76
- if text =~ /^\|.*\|$/
77
- examples_rows << text.gsub(/^\||\|$/, '').split('|').map(&:strip)
65
+ # Agrupa linhas de tabela e renderiza quando termina
66
+ if text =~ /^\s*\|.*\|/i
67
+ table_buffer << text.gsub(/^\s*\||\|\s*$/, '').split('|').map(&:strip)
78
68
  next
79
- else
80
- if examples_rows.any?
81
- pdf.table(examples_rows, header: true, width: pdf.bounds.width) do
82
- self.header = true
83
- self.row_colors = ['EFEFEF', 'FFFFFF']
84
- self.cell_style = { size: 9, font: pdf.font }
85
- end
86
- pdf.move_down 6
87
- examples_rows.clear
69
+ elsif table_buffer.any?
70
+ pdf.table(table_buffer, header: true, width: pdf.bounds.width) do
71
+ self.header = true
72
+ self.row_colors = ['EEEEEE', 'FFFFFF']
73
+ self.cell_style = { size: 8, font: 'Courier' }
88
74
  end
75
+ pdf.move_down 4
76
+ table_buffer.clear
89
77
  end
90
78
 
91
79
  case text
92
- when /^Scenario Outline:/i, /^Scenario:/i
93
- pdf.stroke_color 'CCCCCC'
94
- pdf.stroke_horizontal_rule
95
- pdf.stroke_color '000000'
80
+ when /^\s*(Feature|Funcionalidade):/i
96
81
  pdf.move_down 6
97
82
  pdf.text text, size: 14, style: :bold
83
+ pdf.move_down 4
84
+ when /^\s*(Background):/i
85
+ pdf.text text, size: 11, style: :italic
86
+ pdf.move_down 4
87
+ when /^\s*(Scenario(?: Outline)?|Esquema do Cenário):/i
98
88
  pdf.move_down 6
99
- when /^Examples:/i
100
89
  pdf.text text, size: 12, style: :bold
101
90
  pdf.move_down 4
102
- when /^(Given|When|Then|And|But)\b/i
103
- keyword, rest = text.split(' ', 2)
104
- color = KEYWORD_COLORS[keyword] || '000000'
91
+ when /^\s*(Examples|Exemplos):/i
92
+ pdf.text text, size: 11, style: :bold
93
+ pdf.move_down 4
94
+ when /^\s*@/i
95
+ pdf.text text, size: 8, style: :italic
96
+ pdf.move_down 4
97
+ when /^(?:\s*)(Given|When|Then|And|But|Dado|Quando|Então|E|Mas)\b/i
98
+ keyword, rest = text.strip.split(' ', 2)
105
99
  pdf.indent(20) do
106
100
  pdf.formatted_text [
107
- { text: keyword, styles: [:bold], color: color },
108
- { text: " " + (rest || ''), color: '000000' }
109
- ], size: 10
101
+ { text: keyword, styles: [:bold] },
102
+ { text: rest ? " #{rest}" : '' }
103
+ ], size: 9
110
104
  end
111
105
  pdf.move_down 2
112
- when /^@/ # tags
113
- pdf.formatted_text [
114
- { text: text, styles: [:italic], size: 9, color: '555555' }
115
- ]
116
- pdf.move_down 4
117
- when /^#/ # comentários
118
- pdf.text text.sub(/^#\s*/, ''), size: 9, style: :italic, color: '777777'
119
- pdf.move_down 4
120
- when ''
106
+ when /^\s*$/
121
107
  pdf.move_down 4
122
108
  else
123
109
  pdf.text text
124
110
  end
125
111
  end
126
112
 
127
- # Exibe última tabela se houver
128
- if examples_rows.any?
129
- pdf.table(examples_rows, header: true, width: pdf.bounds.width) do
113
+ # Renderiza qualquer tabela remanescente
114
+ if table_buffer.any?
115
+ pdf.table(table_buffer, header: true, width: pdf.bounds.width) do
130
116
  self.header = true
131
- self.row_colors = ['EFEFEF', 'FFFFFF']
132
- self.cell_style = { size: 9, font: pdf.font }
117
+ self.row_colors = ['EEEEEE', 'FFFFFF']
118
+ self.cell_style = { size: 8, font: 'Courier' }
133
119
  end
120
+ pdf.move_down 4
134
121
  end
135
122
 
136
- pdf.move_down 20
137
- pdf.number_pages('Página <page> de <total>', align: :right, size: 8)
123
+ pdf.number_pages 'Página <page> de <total>', align: :right, size: 8
138
124
  end
139
125
  rescue => e
140
126
  warn "❌ Erro ao gerar PDF de #{origem}: #{e.message}"
141
127
  end
142
128
  end
143
- end
144
-
129
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bddgenx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.42
4
+ version: 0.1.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Nascimento
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-15 00:00:00.000000000 Z
11
+ date: 2025-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prawn