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 +4 -4
- data/VERSION +1 -1
- data/lib/bddgenx/generator.rb +1 -1
- data/lib/bddgenx/utils/fontLoader.rb +4 -4
- data/lib/bddgenx/utils/pdf_exporter.rb +68 -83
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27d5aae37397f6f4cbebc64d87ea9046812aa8ca9754f15963f7a943e04c870f
|
4
|
+
data.tar.gz: cad3d2ef7e11724824d2cd3c3a31ffd09725d189f6f20813488fd5164db1ea01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f9d4ff065c91d9b4c20e77fa2ef267c13c43d574d5f825afa0eb07f90518ba1994666a95464058152a8f8346a1283a9419311ad4ee3a55ed42ce75ae492a222
|
7
|
+
data.tar.gz: b7f6fc413a78140a23812ab38db086b49c5cb5db1fdd0f51251e5607df6a6c57481c07acee2c95303b9e99ffa1120ae8f165dde5a698dca4c915ab9c7ad0c1cb
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.43
|
data/lib/bddgenx/generator.rb
CHANGED
@@ -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]}:
|
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
|
7
|
+
# Retorna o diretório assets/fonts dentro da gem
|
8
8
|
def self.fonts_path
|
9
|
-
File.expand_path('../../
|
9
|
+
File.expand_path('../../assets/fonts', __dir__)
|
10
10
|
end
|
11
11
|
|
12
|
-
#
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
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
|
-
|
32
|
+
|
33
|
+
if only_new && File.exist?(destino)
|
23
34
|
skipped << destino
|
24
|
-
|
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
|
-
|
47
|
-
|
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
|
-
|
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
|
-
#
|
76
|
-
if text =~
|
77
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
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
|
103
|
-
|
104
|
-
|
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]
|
108
|
-
{ text:
|
109
|
-
], size:
|
101
|
+
{ text: keyword, styles: [:bold] },
|
102
|
+
{ text: rest ? " #{rest}" : '' }
|
103
|
+
], size: 9
|
110
104
|
end
|
111
105
|
pdf.move_down 2
|
112
|
-
when
|
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
|
-
#
|
128
|
-
if
|
129
|
-
pdf.table(
|
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 = ['
|
132
|
-
self.cell_style = { size:
|
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.
|
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.
|
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-
|
11
|
+
date: 2025-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prawn
|