bddgenx 0.1.41 → 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/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/bddgenx/generator.rb +1 -1
- data/lib/bddgenx/runner.rb +4 -5
- data/lib/bddgenx/steps_generator.rb +1 -1
- data/lib/bddgenx/utils/fontLoader.rb +32 -0
- data/lib/bddgenx/utils/pdf_exporter.rb +129 -0
- metadata +8 -11
- data/assets/fonts/DejaVuSansMono-Bold.ttf +0 -0
- data/assets/fonts/DejaVuSansMono-BoldOblique.ttf +0 -0
- data/assets/fonts/DejaVuSansMono-Oblique.ttf +0 -0
- data/assets/fonts/DejaVuSansMono.ttf +0 -0
- data/lib/bddgenx/pdf_exporter.rb +0 -128
- /data/lib/bddgenx/{backup.rb → utils/backup.rb} +0 -0
- /data/lib/bddgenx/{parser.rb → utils/parser.rb} +0 -0
- /data/lib/bddgenx/{tracer.rb → utils/tracer.rb} +0 -0
- /data/lib/bddgenx/{validator.rb → utils/validator.rb} +0 -0
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/Rakefile
CHANGED
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|
|
data/lib/bddgenx/runner.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
# lib/bddgenx/cli.rb
|
2
2
|
require 'fileutils'
|
3
|
-
require_relative 'parser'
|
3
|
+
require_relative 'utils/parser'
|
4
4
|
require_relative 'generator'
|
5
|
-
require_relative 'pdf_exporter'
|
5
|
+
require_relative 'utils/pdf_exporter'
|
6
6
|
require_relative 'steps_generator'
|
7
|
-
require_relative 'validator'
|
8
|
-
require_relative 'backup'
|
9
|
-
require_relative 'pdf_exporter'
|
7
|
+
require_relative 'utils/validator'
|
8
|
+
require_relative 'utils/backup'
|
10
9
|
|
11
10
|
module Bddgenx
|
12
11
|
class Runner
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# lib/bddgenx/font_loader.rb
|
2
|
+
require 'prawn'
|
3
|
+
require 'rubygems' # para Gem.loaded_specs
|
4
|
+
|
5
|
+
module Bddgenx
|
6
|
+
class FontLoader
|
7
|
+
# Retorna o diretório assets/fonts dentro da gem
|
8
|
+
def self.fonts_path
|
9
|
+
File.expand_path('../../assets/fonts', __dir__)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Carrega famílias de fontes TrueType para Prawn
|
13
|
+
def self.families
|
14
|
+
base = fonts_path
|
15
|
+
return {} unless Dir.exist?(base)
|
16
|
+
|
17
|
+
files = {
|
18
|
+
normal: File.join(base, 'DejaVuSansMono.ttf'),
|
19
|
+
bold: File.join(base, 'DejaVuSansMono-Bold.ttf'),
|
20
|
+
italic: File.join(base, 'DejaVuSansMono-Oblique.ttf'),
|
21
|
+
bold_italic: File.join(base, 'DejaVuSansMono-BoldOblique.ttf')
|
22
|
+
}
|
23
|
+
|
24
|
+
if files.values.all? { |path| File.file?(path) && File.size(path) > 12 }
|
25
|
+
{ 'DejaVuSansMono' => files }
|
26
|
+
else
|
27
|
+
warn "⚠️ Fontes DejaVuSansMono ausentes ou corrompidas em #{base}. Usando fallback Courier."
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# lib/bddgenx/pdf_exporter.rb
|
2
|
+
require 'prawn'
|
3
|
+
require 'prawn/table'
|
4
|
+
require 'fileutils'
|
5
|
+
require_relative 'fontLoader'
|
6
|
+
|
7
|
+
# Suprime aviso de internacionalização para fontes AFM built-in
|
8
|
+
Prawn::Fonts::AFM.hide_m17n_warning = true
|
9
|
+
|
10
|
+
module Bddgenx
|
11
|
+
class PDFExporter
|
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
|
+
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
|
+
|
24
|
+
generated, skipped = [], []
|
25
|
+
features_list.each do |feature|
|
26
|
+
unless File.file?(feature)
|
27
|
+
warn "⚠️ Feature não encontrada: #{feature}"
|
28
|
+
next
|
29
|
+
end
|
30
|
+
nome = File.basename(feature, '.feature')
|
31
|
+
destino = "reports/pdf/#{camel_case(nome)}.pdf"
|
32
|
+
|
33
|
+
if only_new && File.exist?(destino)
|
34
|
+
skipped << destino
|
35
|
+
next
|
36
|
+
end
|
37
|
+
|
38
|
+
exportar_arquivo(feature, destino)
|
39
|
+
generated << destino
|
40
|
+
end
|
41
|
+
|
42
|
+
{ generated: generated, skipped: skipped }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Converte string para camelCase, removendo caracteres especiais
|
46
|
+
def self.camel_case(str)
|
47
|
+
clean = str.gsub(/[^0-9A-Za-z ]/, '')
|
48
|
+
parts = clean.split(/ |_/)
|
49
|
+
([parts.first&.downcase] + (parts[1..] || []).map(&:capitalize)).join
|
50
|
+
end
|
51
|
+
|
52
|
+
# Gera o PDF formatado a partir de um único arquivo .feature, sem executar testes
|
53
|
+
def self.exportar_arquivo(origem, destino)
|
54
|
+
FileUtils.mkdir_p(File.dirname(destino))
|
55
|
+
conteudo = File.read(origem, encoding: 'utf-8')
|
56
|
+
|
57
|
+
Prawn::Document.generate(destino, page_size: 'A4', margin: 50) do |pdf|
|
58
|
+
pdf.font 'Courier'
|
59
|
+
pdf.font_size 9
|
60
|
+
|
61
|
+
table_buffer = []
|
62
|
+
conteudo.each_line do |linha|
|
63
|
+
text = linha.chomp
|
64
|
+
|
65
|
+
# Agrupa linhas de tabela e renderiza quando termina
|
66
|
+
if text =~ /^\s*\|.*\|/i
|
67
|
+
table_buffer << text.gsub(/^\s*\||\|\s*$/, '').split('|').map(&:strip)
|
68
|
+
next
|
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' }
|
74
|
+
end
|
75
|
+
pdf.move_down 4
|
76
|
+
table_buffer.clear
|
77
|
+
end
|
78
|
+
|
79
|
+
case text
|
80
|
+
when /^\s*(Feature|Funcionalidade):/i
|
81
|
+
pdf.move_down 6
|
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
|
88
|
+
pdf.move_down 6
|
89
|
+
pdf.text text, size: 12, style: :bold
|
90
|
+
pdf.move_down 4
|
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)
|
99
|
+
pdf.indent(20) do
|
100
|
+
pdf.formatted_text [
|
101
|
+
{ text: keyword, styles: [:bold] },
|
102
|
+
{ text: rest ? " #{rest}" : '' }
|
103
|
+
], size: 9
|
104
|
+
end
|
105
|
+
pdf.move_down 2
|
106
|
+
when /^\s*$/
|
107
|
+
pdf.move_down 4
|
108
|
+
else
|
109
|
+
pdf.text text
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Renderiza qualquer tabela remanescente
|
114
|
+
if table_buffer.any?
|
115
|
+
pdf.table(table_buffer, header: true, width: pdf.bounds.width) do
|
116
|
+
self.header = true
|
117
|
+
self.row_colors = ['EEEEEE', 'FFFFFF']
|
118
|
+
self.cell_style = { size: 8, font: 'Courier' }
|
119
|
+
end
|
120
|
+
pdf.move_down 4
|
121
|
+
end
|
122
|
+
|
123
|
+
pdf.number_pages 'Página <page> de <total>', align: :right, size: 8
|
124
|
+
end
|
125
|
+
rescue => e
|
126
|
+
warn "❌ Erro ao gerar PDF de #{origem}: #{e.message}"
|
127
|
+
end
|
128
|
+
end
|
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
|
@@ -36,25 +36,22 @@ files:
|
|
36
36
|
- README.md
|
37
37
|
- Rakefile
|
38
38
|
- VERSION
|
39
|
-
- assets/fonts/DejaVuSansMono-Bold.ttf
|
40
|
-
- assets/fonts/DejaVuSansMono-BoldOblique.ttf
|
41
|
-
- assets/fonts/DejaVuSansMono-Oblique.ttf
|
42
|
-
- assets/fonts/DejaVuSansMono.ttf
|
43
39
|
- bin/bddgenx
|
44
40
|
- lib/bddgenx.rb
|
45
41
|
- lib/bddgenx/assets/fonts/DejaVuSansMono-Bold.ttf
|
46
42
|
- lib/bddgenx/assets/fonts/DejaVuSansMono-BoldOblique.ttf
|
47
43
|
- lib/bddgenx/assets/fonts/DejaVuSansMono-Oblique.ttf
|
48
44
|
- lib/bddgenx/assets/fonts/DejaVuSansMono.ttf
|
49
|
-
- lib/bddgenx/backup.rb
|
50
45
|
- lib/bddgenx/generator.rb
|
51
|
-
- lib/bddgenx/parser.rb
|
52
|
-
- lib/bddgenx/pdf_exporter.rb
|
53
46
|
- lib/bddgenx/runner.rb
|
54
47
|
- lib/bddgenx/steps_generator.rb
|
55
|
-
- lib/bddgenx/
|
48
|
+
- lib/bddgenx/utils/backup.rb
|
49
|
+
- lib/bddgenx/utils/fontLoader.rb
|
50
|
+
- lib/bddgenx/utils/parser.rb
|
51
|
+
- lib/bddgenx/utils/pdf_exporter.rb
|
56
52
|
- lib/bddgenx/utils/tipo_param.rb
|
57
|
-
- lib/bddgenx/
|
53
|
+
- lib/bddgenx/utils/tracer.rb
|
54
|
+
- lib/bddgenx/utils/validator.rb
|
58
55
|
- lib/bddgenx/version.rb
|
59
56
|
homepage: https://github.com/David-Nascimento/bdd-generation
|
60
57
|
licenses:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/bddgenx/pdf_exporter.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'prawn'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module Bddgenx
|
5
|
-
class PDFExporter
|
6
|
-
def self.exportar_todos(only_new: false)
|
7
|
-
FileUtils.mkdir_p('reports/pdf')
|
8
|
-
generated = []
|
9
|
-
skipped = []
|
10
|
-
|
11
|
-
Dir.glob('features/*.feature').each do |feature|
|
12
|
-
nome = File.basename(feature, '.feature')
|
13
|
-
destino = "reports/pdf/#{camel_case(nome)}.pdf"
|
14
|
-
|
15
|
-
if File.exist?(destino)
|
16
|
-
skipped << destino
|
17
|
-
next
|
18
|
-
end
|
19
|
-
|
20
|
-
exportar_arquivo(feature, destino)
|
21
|
-
generated << destino
|
22
|
-
end
|
23
|
-
|
24
|
-
return { generated: generated, skipped: skipped }
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
# Converte string para camelCase, removendo caracteres especiais
|
29
|
-
def self.camel_case(str)
|
30
|
-
# Remove tudo que não for letra ou número ou espaço
|
31
|
-
str = str.gsub(/[^0-9A-Za-z ]/, '')
|
32
|
-
parts = str.split(/ |_/)
|
33
|
-
# Primeira palavra minúscula, demais capitalizadas
|
34
|
-
([parts.first&.downcase] + parts[1..].map(&:capitalize)).join
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.sanitizar_utf8_para_ascii(texto)
|
38
|
-
if texto.respond_to?(:unicode_normalize)
|
39
|
-
# Decompõe em base + acentos, remove acentos, e garante ASCII
|
40
|
-
texto
|
41
|
-
.unicode_normalize(:nfkd) # separa letra + marca
|
42
|
-
.chars
|
43
|
-
.reject { |c| c.match?(/\p{Mn}/) } # descarta marcas de acento
|
44
|
-
.join
|
45
|
-
.encode('ASCII', undef: :replace, replace: '?')
|
46
|
-
else
|
47
|
-
# Fallback simples se por algum motivo unicode_normalize não existir
|
48
|
-
texto
|
49
|
-
.gsub(/[áàâãä]/i, 'a')
|
50
|
-
.gsub(/[éèêë]/i, 'e')
|
51
|
-
.gsub(/[íìîï]/i, 'i')
|
52
|
-
.gsub(/[óòôõö]/i, 'o')
|
53
|
-
.gsub(/[úùûü]/i, 'u')
|
54
|
-
.gsub(/[ç]/i, 'c')
|
55
|
-
.encode('ASCII', undef: :replace, replace: '?')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.exportar_arquivo(origem, destino)
|
60
|
-
conteudo = File.read(origem, encoding: 'utf-8')
|
61
|
-
|
62
|
-
Prawn::Document.generate(destino) do |pdf|
|
63
|
-
fonte_existe = File.exist?("assets/fonts/DejaVuSansMono.ttf")
|
64
|
-
font_dir = File.expand_path("assets/fonts", __dir__)
|
65
|
-
|
66
|
-
if File.exist?(File.join(font_dir, "DejaVuSansMono.ttf"))
|
67
|
-
pdf.font_families.update(
|
68
|
-
"DejaVu" => {
|
69
|
-
normal: File.join(font_dir, "DejaVuSansMono.ttf"),
|
70
|
-
bold: File.join(font_dir, "DejaVuSansMono-Bold.ttf"),
|
71
|
-
italic: File.join(font_dir, "DejaVuSansMono-Oblique.ttf"),
|
72
|
-
bold_italic: File.join(font_dir, "DejaVuSansMono-BoldOblique.ttf")
|
73
|
-
}
|
74
|
-
)
|
75
|
-
pdf.font "DejaVu"
|
76
|
-
else
|
77
|
-
puts "⚠️ Fonte não encontrada: #{font_dir}"
|
78
|
-
pdf.font "Courier"
|
79
|
-
end
|
80
|
-
|
81
|
-
pdf.font_size 10
|
82
|
-
pdf.text "📄 #{File.basename(origem)}", style: :bold, size: 14
|
83
|
-
pdf.move_down 10
|
84
|
-
|
85
|
-
conteudo.each_line do |linha|
|
86
|
-
linha = fonte_existe ? linha.strip : sanitizar_utf8_para_ascii(linha.chomp)
|
87
|
-
|
88
|
-
case linha
|
89
|
-
when /^#/
|
90
|
-
pdf.fill_color "888888"
|
91
|
-
pdf.text linha, style: :italic, size: 8
|
92
|
-
pdf.fill_color "000000"
|
93
|
-
when /^Funcionalidade:|^Feature:/
|
94
|
-
pdf.move_down 6
|
95
|
-
pdf.text linha, style: :bold, size: 12
|
96
|
-
pdf.move_down 4
|
97
|
-
when /^Cenário:|^Scenario:|^Esquema do Cenário:|^Scenario Outline:/
|
98
|
-
pdf.move_down 4
|
99
|
-
pdf.text linha, style: :bold
|
100
|
-
when /^@/
|
101
|
-
pdf.text linha, style: :italic, color: "555555"
|
102
|
-
when /^(Dado|Quando|Então|E|Mas|Given|When|Then|And|But)\b/
|
103
|
-
pdf.indent(20) { pdf.text linha }
|
104
|
-
when /^Exemplos:|^Examples:/
|
105
|
-
pdf.move_down 4
|
106
|
-
pdf.text linha, style: :bold
|
107
|
-
when /^\|.*\|$/
|
108
|
-
pdf.indent(20) { pdf.text linha }
|
109
|
-
when /^\s*$/
|
110
|
-
pdf.move_down 4
|
111
|
-
else
|
112
|
-
pdf.text linha
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
pdf.move_down 20
|
117
|
-
pdf.number_pages "Página <page> de <total>", align: :right, size: 8
|
118
|
-
end
|
119
|
-
rescue => e
|
120
|
-
puts "❌ Erro ao gerar PDF de #{origem}: #{e.message}"
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Execute automaticamente se chamado como script direto
|
126
|
-
if __FILE__ == $PROGRAM_NAME
|
127
|
-
Bddgen::PDFExporter.exportar_todos
|
128
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|