bddgenx 0.1.25 → 0.1.27

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: 754519f4799f4645e2b121e8241383840f478f7a60ceddb150ecc76b27aae120
4
- data.tar.gz: b0da57182e5023af9986b58877c3ab723e6438c77d40d4e29f3dc51013241a31
3
+ metadata.gz: 8f4d4a0d722941eb7d15b474586da0bc25a2aae85b0542ed74841c13b2a545d3
4
+ data.tar.gz: d4e0b1bf37384a517d97ee71b2ad3d6d8ba87e4cbc9a1c2b456be181e68e4f87
5
5
  SHA512:
6
- metadata.gz: 1c0bfeb42580760a697f006ad6ac29dfd252935ec2eb2504d725b98eda9f8bd5bf92bc4a5e2bf464831f45d548db4b516be0440384d9bab5961772d5f335bc0a
7
- data.tar.gz: 923515914b2cdf46a3c2122e8af0c7c426c9bda025bd6db8d974739ba74827f5d88d68191bae88b4704387e15af3c39874ce4c1e93a204870352052604c5f050
6
+ metadata.gz: 67ece000b01a4d5abe5fda121ebe5486ed3eb8866e102fee704793df7d1c93e369e2c8b92f803df3b43cde3c4d6b25e78efeda48ec6de943734123b01bdb872b
7
+ data.tar.gz: 11180ba8fed1854d60ad6250376949807332ff04f4432d5e24b5b1b3af89d0d119036c4c38585d1826548c02f099ab4779129030537790e2837d9829766f6cb9
@@ -6,10 +6,11 @@ module Bddgenx
6
6
  def self.salvar_versao_antiga(caminho)
7
7
  return unless File.exist?(caminho)
8
8
 
9
- FileUtils.mkdir_p("backup")
9
+ pasta = 'reports/backup'
10
+ FileUtils.mkdir_p(pasta)
10
11
  base = File.basename(caminho, ".feature")
11
12
  timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
12
- destino = "backup/#{base}_#{timestamp}.feature"
13
+ destino = "reports/backup/#{base}_#{timestamp}.feature"
13
14
 
14
15
  FileUtils.cp(caminho, destino)
15
16
  puts "📦 Backup criado: #{destino}"
@@ -23,7 +23,12 @@ module Bddgenx
23
23
  regra: idioma == 'en' ? 'Rule' : 'Regra'
24
24
  }
25
25
 
26
- nome_base = historia[:quero].gsub(/[^a-z0-9]/i, '_').downcase
26
+ frase_quero = historia[:quero].sub(/^\s*quero\s*/i, '')
27
+ partes = frase_quero.split(/\s+/)[0,3] # pega só as 3 primeiras palavras
28
+ slug = partes.join('_')
29
+ .gsub(/[^a-z0-9_]/i, '') # remove caracteres especiais
30
+ .downcase
31
+ nome_base = slug
27
32
  caminho = "features/#{nome_base}.feature"
28
33
 
29
34
  conteudo = <<~GHERKIN
@@ -11,55 +11,61 @@ module Bddgenx
11
11
  .map(&:strip)
12
12
  .reject(&:empty?)
13
13
 
14
- # idioma
14
+ # Detecta idioma (padrão pt, usa en se encontrar '# lang: en')
15
15
  idioma = linhas.first.downcase.include?('# lang: en') ? 'en' : 'pt'
16
16
  linhas.shift if linhas.first.downcase.start_with?('# lang:')
17
17
 
18
- # cabeçalho Gherkin: Como / Quero / Para
19
- until linhas.empty?
20
- linha = linhas.shift
21
- break if linha =~ /^(Como |As a )/
18
+ # Cabeçalho Gherkin (case-insensitive): Como, Eu Como ou As a
19
+ como = nil
20
+ linhas.each_with_index do |l, i|
21
+ if l =~ /^\s*(?:como|eu como|as a)\b/i || l =~ /^\s*(?:COMO|EU COMO|AS A)\b/i
22
+ como = l
23
+ linhas = linhas[(i+1)..]
24
+ break
25
+ end
26
+ end
27
+
28
+ # 'Quero' ou 'Eu Quero'
29
+ quero = nil
30
+ linhas.each_with_index do |l, i|
31
+ if l =~ /^\s*(?:quero|eu quero|quero que)\b/i || l =~ /^\s*(?:QUERO|EU QUERO|QUERO QUE)\b/i
32
+ quero = l
33
+ linhas = linhas[(i+1)..]
34
+ break
35
+ end
22
36
  end
23
- como = linha
24
- quero = linhas.shift
25
- para = linhas.shift
26
37
 
27
- historia = {
28
- como: como,
29
- quero: quero,
30
- para: para,
31
- idioma: idioma,
32
- grupos: [] # cada bloco ([TIPO]@tag) será um grupo
33
- }
38
+ # 'Para', 'Para Eu' ou 'Para Que'
39
+ para = nil
40
+ linhas.each_with_index do |l, i|
41
+ if l =~ /^\s*(?:para|para eu|para que)\b/i || l =~ /^\s*(?:PRA|PARA EU|PARA QUE)\b/i
42
+ para = l
43
+ linhas = linhas[(i+1)..]
44
+ break
45
+ end
46
+ end
34
47
 
48
+ historia = { como: como, quero: quero, para: para, idioma: idioma, grupos: [] }
35
49
  exemplos_mode = false
36
- tipo_atual = nil
37
- tag_atual = nil
38
50
 
39
51
  linhas.each do |linha|
40
- # início de bloco EXAMPLES: modo exemplos para último grupo
41
- if linha =~ /^\[EXAMPLES\](?:@(\w+))?$/
52
+ # Início de bloco de exemplos
53
+ if linha =~ /^\[EXAMPLES\](?:@(\w+))?$/i
42
54
  exemplos_mode = true
43
- raise "Formato inválido: EXAMPLES sem bloco anterior" if historia[:grupos].empty?
44
55
  historia[:grupos].last[:exemplos] = []
45
56
  next
46
57
  end
47
58
 
48
- # início de um novo bloco (exceto EXAMPLES)
49
- if linha =~ /^\[(#{TIPOS_BLOCOS.join('|')})\](?:@(\w+))?$/
59
+ # Início de bloco de tipo (SUCCESS, FAILURE etc.)
60
+ if linha =~ /^\[(#{TIPOS_BLOCOS.join('|')})\](?:@(\w+))?$/i
50
61
  exemplos_mode = false
51
- tipo_atual = $1
52
- tag_atual = $2
53
- historia[:grupos] << {
54
- tipo: tipo_atual,
55
- tag: tag_atual,
56
- passos: [],
57
- exemplos: []
58
- }
62
+ tipo = $1.upcase
63
+ tag = $2
64
+ historia[:grupos] << { tipo: tipo, tag: tag, passos: [], exemplos: [] }
59
65
  next
60
66
  end
61
67
 
62
- # atribuir linhas ao bloco atual
68
+ # Atribui linhas ao último grupo existente
63
69
  next if historia[:grupos].empty?
64
70
  atual = historia[:grupos].last
65
71
 
@@ -4,12 +4,12 @@ require 'fileutils'
4
4
  module Bddgenx
5
5
  class PDFExporter
6
6
  def self.exportar_todos
7
- FileUtils.mkdir_p('pdf')
7
+ FileUtils.mkdir_p('reports/pdf')
8
8
 
9
9
  Dir.glob('features/*.feature').each do |feature_file|
10
10
  base = File.basename(feature_file, '.feature')
11
11
  nome_pdf = camel_case(base)
12
- destino = "pdf/#{nome_pdf}.pdf"
12
+ destino = "reports/pdf/#{nome_pdf}.pdf"
13
13
 
14
14
  if File.exist?(destino)
15
15
  puts "⚠️ PDF já existe: #{destino}"
@@ -26,10 +26,10 @@ module Bddgenx
26
26
  conector = conectores.find { |c| linha.strip.start_with?(c) }
27
27
  next unless conector
28
28
 
29
- corpo = linha.strip.sub(/^#{conector}\s*/, '')
30
- corpo_sanitizado = corpo.gsub(/"(<[^>]+>)"/, '\1')
29
+ corpo = linha.strip.sub(/^#{conector}\s*/, '')
30
+ corpo_sanitizado = corpo.gsub(/"(<[^>]+>)"/, '\1')
31
31
 
32
- # tenta encontrar grupo de exemplos compatível, se existir
32
+ # Identifica grupo de exemplo compatível
33
33
  grupo_exemplo_compat = nil
34
34
  if exemplos
35
35
  exemplos.each do |tabela|
@@ -42,7 +42,7 @@ module Bddgenx
42
42
  end
43
43
  end
44
44
 
45
- # detecta todos os parametros <...> e gera arg list
45
+ # Detecta parâmetros e gera corpo parametrizado
46
46
  nomes_param = corpo.scan(/<([^>]+)>/).flatten.map(&:strip)
47
47
  if nomes_param.any?
48
48
  corpo_param = corpo_sanitizado.dup
@@ -74,8 +74,17 @@ module Bddgenx
74
74
  end
75
75
 
76
76
  nome_base = File.basename(nome_arquivo_feature, '.feature')
77
- caminho = "steps/#{nome_base}_steps.rb"
78
- FileUtils.mkdir_p(File.dirname(caminho))
77
+
78
+ # Define caminho de saída: prioriza pasta steps dentro de features/<nome>
79
+ feature_dir = File.dirname(nome_arquivo_feature)
80
+ feature_steps_dir = File.join(feature_dir, 'steps')
81
+ if Dir.exist?(feature_steps_dir)
82
+ FileUtils.mkdir_p(feature_steps_dir)
83
+ caminho = File.join(feature_steps_dir, "#{nome_base}_steps.rb")
84
+ else
85
+ FileUtils.mkdir_p('steps')
86
+ caminho = "steps/#{nome_base}_steps.rb"
87
+ end
79
88
 
80
89
  comentario = "# Step definitions para #{File.basename(nome_arquivo_feature)}"
81
90
  comentario += idioma == 'en' ? " (English)" : " (Português)"
@@ -98,7 +107,6 @@ module Bddgenx
98
107
  true
99
108
  end
100
109
 
101
- # Detecta tipo do parâmetro baseado em exemplos ou default
102
110
  def self.detectar_tipo_param(nome_coluna, exemplos)
103
111
  return 'string' unless exemplos[:cabecalho].include?(nome_coluna)
104
112
 
@@ -112,7 +120,6 @@ module Bddgenx
112
120
  'string'
113
121
  end
114
122
 
115
- # Divide múltiplas tabelas de exemplo em grupos
116
123
  def self.dividir_examples(tabela_bruta)
117
124
  grupos = []
118
125
  grupo = []
@@ -4,8 +4,8 @@ require 'fileutils'
4
4
  module Bddgenx
5
5
  class Tracer
6
6
  def self.adicionar_entrada(historia, nome_arquivo_feature)
7
- FileUtils.mkdir_p('output')
8
- arquivo_csv = 'output/rastreabilidade.csv'
7
+ FileUtils.mkdir_p('reports/output')
8
+ arquivo_csv = 'reports/output/rastreabilidade.csv'
9
9
 
10
10
  cabecalho = ['Funcionalidade', 'Tipo', 'Tag', 'Cenário', 'Passo', 'Origem']
11
11
 
@@ -1,3 +1,3 @@
1
1
  module Bddgenx
2
- VERSION = "0.1.25"
2
+ VERSION = "0.1.27"
3
3
  end
data/lib/bddgenx.rb CHANGED
@@ -34,11 +34,13 @@ arquivos.each do |arquivo_path|
34
34
  cont_features += 1 if Bddgenx::Generator.salvar_feature(nome_feature, conteudo_feature)
35
35
  cont_steps += 1 if Bddgenx::StepsGenerator.gerar_passos(historia, nome_feature)
36
36
 
37
+ # cria pasta reports raiz
38
+ FileUtils.mkdir_p('reports')
37
39
  Bddgenx::Tracer.adicionar_entrada(historia, nome_feature)
38
40
  Bddgenx::PDFExporter.exportar_todos
39
41
  end
40
42
  puts "\n✅ Processamento finalizado. Arquivos gerados em: features/, steps/, output/"
41
- puts "🔄 Versões antigas salvas em: backup/"
43
+ puts "🔄 Versões antigas salvas em: reports/backup/"
42
44
 
43
45
  puts "\n✅ Processamento finalizado:"
44
46
  puts "- Arquivos processados: #{cont_total}"
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.25
4
+ version: 0.1.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Nascimento
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2025-05-12 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
13
27
  description: Transforma arquivos .txt com histórias em arquivos .feature, com steps,
14
28
  rastreabilidade e integração com CI/CD.
15
29
  email: