bddgenx 0.1.41 → 0.1.42
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/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 +144 -0
- metadata +7 -10
- 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: e9d0fa653a6cce274a37045260ebaa2aa15c155e86e0ec5c0bc786fd452c338e
|
4
|
+
data.tar.gz: 31d0a6db315449deb19fa51a4cb2dd82405b467f3116798505cafeaff27e8a4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69e4664c77d38ba18dd4c37329136894af94cf49c931f1675f876796446df4df2aa976b4cb8580f7a4bd43f616b99cf9da92fe251952c3a8c5265ce4bcc65ee7
|
7
|
+
data.tar.gz: 14a58ba2da3e62c03f30ba0c724676ba59831f3bf2f6565d882e4e33f0f85d76492a6e0a78b7e24c46a19d18a227f1f1c2eeedc051d48cfba0bf4025bf523002
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.42
|
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, mesmo em dev local
|
8
|
+
def self.fonts_path
|
9
|
+
File.expand_path('../../bddgenx/assets/fonts', __dir__)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Retorna famílias de fontes TrueType para Prawn; vazio se faltar arquivos
|
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}."
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# lib/bddgenx/pdf_exporter.rb
|
2
|
+
require 'prawn'
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative 'fontLoader'
|
5
|
+
|
6
|
+
module Bddgenx
|
7
|
+
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)
|
17
|
+
FileUtils.mkdir_p('reports/pdf')
|
18
|
+
generated, skipped = [], []
|
19
|
+
Dir.glob('features/*.feature').each do |feature|
|
20
|
+
nome = File.basename(feature, '.feature')
|
21
|
+
destino = "reports/pdf/#{camel_case(nome)}.pdf"
|
22
|
+
if File.exist?(destino)
|
23
|
+
skipped << destino
|
24
|
+
else
|
25
|
+
exportar_arquivo(feature, destino)
|
26
|
+
generated << destino
|
27
|
+
end
|
28
|
+
end
|
29
|
+
{ generated: generated, skipped: skipped }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.camel_case(str)
|
33
|
+
clean = str.gsub(/[^0-9A-Za-z ]/, '')
|
34
|
+
parts = clean.split(/ |_/)
|
35
|
+
([parts.first&.downcase] + (parts[1..] || []).map(&:capitalize)).join
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.exportar_arquivo(origem, destino)
|
39
|
+
FileUtils.mkdir_p(File.dirname(destino))
|
40
|
+
conteudo = File.read(origem, encoding: 'utf-8')
|
41
|
+
|
42
|
+
families = FontLoader.families
|
43
|
+
usar_ttf = !families.empty?
|
44
|
+
|
45
|
+
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
|
69
|
+
|
70
|
+
examples_rows = []
|
71
|
+
conteudo.each_line do |linha|
|
72
|
+
text = linha.chomp
|
73
|
+
next if text =~ /^#\s*language:/i
|
74
|
+
|
75
|
+
# Coleciona linhas de tabela
|
76
|
+
if text =~ /^\|.*\|$/
|
77
|
+
examples_rows << text.gsub(/^\||\|$/, '').split('|').map(&:strip)
|
78
|
+
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
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
case text
|
92
|
+
when /^Scenario Outline:/i, /^Scenario:/i
|
93
|
+
pdf.stroke_color 'CCCCCC'
|
94
|
+
pdf.stroke_horizontal_rule
|
95
|
+
pdf.stroke_color '000000'
|
96
|
+
pdf.move_down 6
|
97
|
+
pdf.text text, size: 14, style: :bold
|
98
|
+
pdf.move_down 6
|
99
|
+
when /^Examples:/i
|
100
|
+
pdf.text text, size: 12, style: :bold
|
101
|
+
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'
|
105
|
+
pdf.indent(20) do
|
106
|
+
pdf.formatted_text [
|
107
|
+
{ text: keyword, styles: [:bold], color: color },
|
108
|
+
{ text: " " + (rest || ''), color: '000000' }
|
109
|
+
], size: 10
|
110
|
+
end
|
111
|
+
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 ''
|
121
|
+
pdf.move_down 4
|
122
|
+
else
|
123
|
+
pdf.text text
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Exibe última tabela se houver
|
128
|
+
if examples_rows.any?
|
129
|
+
pdf.table(examples_rows, header: true, width: pdf.bounds.width) do
|
130
|
+
self.header = true
|
131
|
+
self.row_colors = ['EFEFEF', 'FFFFFF']
|
132
|
+
self.cell_style = { size: 9, font: pdf.font }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
pdf.move_down 20
|
137
|
+
pdf.number_pages('Página <page> de <total>', align: :right, size: 8)
|
138
|
+
end
|
139
|
+
rescue => e
|
140
|
+
warn "❌ Erro ao gerar PDF de #{origem}: #{e.message}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.42
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Nascimento
|
@@ -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
|