bddgenx 2.3.3 → 2.4.3

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: b5f895b922c947b8d97296d56a17cfbdc9c31e5bbf6bbfc383c01ebc3e4cfe9d
4
- data.tar.gz: 001d68f9b89e12e52e446bc02db6ee249392c864ad1955172dff31203a1a6a6c
3
+ metadata.gz: 27017e2957f3a9710eb63407c7f6d15e35e756a45890d3dc43b281b357d7d509
4
+ data.tar.gz: e50c8a8b925a0f941229ea8c79215e7671584b288cc29aab3dda78ad05db9e13
5
5
  SHA512:
6
- metadata.gz: ce291e292b64946fcc493e9a590ef335fc652d321bee8637fdd7b5c30a7d411f34d7a26baf26c2a8f6ea1208fb2c943c11219b07695aa6e87fd7a932677a25a3
7
- data.tar.gz: 52710f0f98ba329340956d8e657c09fd802f7f51a34b6437fd692f1e20924db8354a0ed3adcaa29d297461bf566e31fd9dfff54efa9945bbbd719f3f619c4c57
6
+ metadata.gz: 73d8b6d056d42b958814229d6d03384338199e6fbbb36da8110923ea955410b0b4de9a36d8f8df71343974178bebfc948a488303fe1e60d9a94bb410968f9e84
7
+ data.tar.gz: a8da8ca236ae14891de29ba9f22807581348258fb711922cc614dec74453ccb6fa6073b04cf6f74cdff24d304ff958e425d71762daaee59dc15df8bb93b3e163
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
- require 'rake'
2
1
  require 'bddgenx'
2
+ require 'rake'
3
3
 
4
4
  namespace :bddgenx do
5
5
  desc 'Executa geração interativa: escolha entre static, chatgpt, gemini ou deepseek'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.3
1
+ 2.4.3
@@ -1,10 +1,10 @@
1
1
  # lib/bddgenx/generator.rb
2
2
  # encoding: utf-8
3
3
  #
4
- # Este arquivo define a classe Generator, responsável por gerar arquivos
5
- # .feature a partir de um hash de história ou de um arquivo de história em texto.
6
- # Suporta Gherkin em Português e Inglês, inclusão de tags, cenários simples
7
- # e esquemas de cenário com exemplos.
4
+ # Classe responsável pela geração de arquivos `.feature` no formato Gherkin
5
+ # a partir de arquivos de entrada de histórias ou estruturas hash.
6
+ # Suporta palavras-chave Gherkin em Português e Inglês, além de integração com IA
7
+ # (ChatGPT ou Gemini) para geração automática de cenários.
8
8
 
9
9
  module Bddgenx
10
10
  class Generator
@@ -14,37 +14,39 @@ module Bddgenx
14
14
  # Palavras-chave do Gherkin em Inglês
15
15
  GHERKIN_KEYS_EN = %w[Given When Then And But].freeze
16
16
 
17
- # Mapeamento de PT → EN
17
+ # Mapeamento PT → EN
18
18
  GHERKIN_MAP_PT_EN = GHERKIN_KEYS_PT.zip(GHERKIN_KEYS_EN).to_h
19
19
 
20
- # Mapeamento de EN → PT
20
+ # Mapeamento EN → PT
21
21
  GHERKIN_MAP_EN_PT = GHERKIN_KEYS_EN.zip(GHERKIN_KEYS_PT).to_h
22
22
 
23
- # Todas as palavras-chave reconhecidas
23
+ # Todas as palavras-chave reconhecidas pelos parsers
24
24
  ALL_KEYS = GHERKIN_KEYS_PT + GHERKIN_KEYS_EN
25
25
 
26
26
  ##
27
27
  # Extrai todas as linhas de exemplo de um array de strings.
28
28
  #
29
- # @param raw [Array<String>] um array contendo linhas de texto
30
- # @return [Array<String>] apenas as linhas que começam com '|', ou seja, exemplos
29
+ # @param raw [Array<String>] Array com linhas do grupo de passos
30
+ # @return [Array<String>] Somente as linhas que contêm exemplos (começam com '|')
31
31
  def self.dividir_examples(raw)
32
32
  raw.select { |l| l.strip.start_with?('|') }
33
33
  end
34
34
 
35
35
  ##
36
- # Gera o conteúdo de um arquivo `.feature` a partir de uma história.
37
- # Pode operar em três modos: estático (hash ou arquivo estruturado),
38
- # IA com Gemini, ou IA com ChatGPT.
36
+ # Gera o conteúdo de um arquivo `.feature` baseado na história fornecida.
37
+ # Pode operar em três modos:
38
+ # - :static (sem IA)
39
+ # - :chatgpt (usando OpenAI)
40
+ # - :gemini (usando Google Gemini)
39
41
  #
40
- # @param input [String, Hash] caminho para um arquivo .txt ou um hash estruturado
41
- # @param override_path [String, nil] caminho alternativo para salvar o arquivo gerado
42
- # @return [Array(String, String)] caminho do arquivo gerado e conteúdo do .feature
42
+ # @param input [String, Hash] Caminho para um `.txt` ou estrutura de história já processada
43
+ # @param override_path [String, nil] Caminho alternativo de saída
44
+ # @return [Array<String, String>] Caminho e conteúdo do `.feature`
43
45
  def self.gerar_feature(input, override_path = nil)
44
46
  modo = ENV['BDD_MODE']&.to_sym || :static
45
47
 
46
48
  if input.is_a?(String) && input.end_with?('.txt') && [:gemini, :chatgpt].include?(modo)
47
- # Modo com IA: gera cenários automaticamente com base no texto da história
49
+ # Geração com IA
48
50
  raw_txt = File.read(input)
49
51
  historia = {
50
52
  idioma: 'pt',
@@ -66,14 +68,14 @@ module Bddgenx
66
68
  passos: GherkinCleaner.limpar(texto_gerado).lines.map(&:strip).reject(&:empty?)
67
69
  }
68
70
  else
69
- # Modo estático: utiliza estrutura vinda do Parser ou de um hash diretamente
71
+ # Geração estática
70
72
  historia = input.is_a?(String) ? Parser.ler_historia(input) : input
71
73
  end
72
74
 
73
75
  idioma = historia[:idioma] || 'pt'
74
76
  cont = 1
75
77
 
76
- # Normaliza o nome base do arquivo
78
+ # Cria nome-base do arquivo .feature
77
79
  nome_base = historia[:quero]
78
80
  .gsub(/[^a-z0-9]/i, '_')
79
81
  .downcase
@@ -84,7 +86,7 @@ module Bddgenx
84
86
 
85
87
  caminho = override_path || "features/#{nome_base}.feature"
86
88
 
87
- # Define palavras-chave com base no idioma
89
+ # Palavras-chave localizadas
88
90
  palavras = {
89
91
  feature: idioma == 'en' ? 'Feature' : 'Funcionalidade',
90
92
  contexto: idioma == 'en' ? 'Background' : 'Contexto',
@@ -94,6 +96,7 @@ module Bddgenx
94
96
  regra: idioma == 'en' ? 'Rule' : 'Regra'
95
97
  }
96
98
 
99
+ # Cabeçalho do arquivo .feature
97
100
  conteudo = <<~GHK
98
101
  # language: #{idioma}
99
102
  #{palavras[:feature]}: #{historia[:quero].sub(/^Quero\s*/i,'')}
@@ -102,14 +105,14 @@ module Bddgenx
102
105
  # #{historia[:para]}
103
106
  GHK
104
107
 
108
+ # Controle para não repetir passos
105
109
  passos_unicos = Set.new
106
110
  pt_map = GHERKIN_MAP_PT_EN
107
111
  en_map = GHERKIN_MAP_EN_PT
108
112
  detect = ALL_KEYS
109
- cont = 1
110
113
 
111
114
  historia[:grupos].each do |grupo|
112
- passos = grupo[:passos] || []
115
+ passos = grupo[:passos] || []
113
116
  exemplos = grupo[:exemplos] || []
114
117
  next if passos.empty?
115
118
 
@@ -151,20 +154,21 @@ module Bddgenx
151
154
  end
152
155
 
153
156
  ##
154
- # Gera o caminho padrão de saída para um arquivo `.feature` com base no nome do `.txt`.
157
+ # Retorna o caminho padrão do arquivo `.feature` baseado no nome do `.txt`.
155
158
  #
156
- # @param arquivo_txt [String] caminho do arquivo .txt de entrada
157
- # @return [String] caminho completo do arquivo .feature correspondente
159
+ # @param arquivo_txt [String] Caminho do arquivo .txt
160
+ # @return [String] Caminho final da feature gerada
158
161
  def self.path_para_feature(arquivo_txt)
159
162
  nome = File.basename(arquivo_txt, '.txt')
160
163
  File.join('features', "#{nome}.feature")
161
164
  end
162
165
 
163
166
  ##
164
- # Salva o conteúdo gerado no disco, criando diretórios se necessário.
167
+ # Salva o conteúdo do arquivo `.feature` no disco.
168
+ # Cria diretórios intermediários, se necessário.
165
169
  #
166
- # @param caminho [String] caminho completo para salvar o arquivo
167
- # @param conteudo [String] conteúdo do arquivo .feature
170
+ # @param caminho [String] Caminho completo do arquivo
171
+ # @param conteudo [String] Conteúdo da feature a ser salva
168
172
  # @return [void]
169
173
  def self.salvar_feature(caminho, conteudo)
170
174
  FileUtils.mkdir_p(File.dirname(caminho))
@@ -2,28 +2,35 @@
2
2
  # encoding: utf-8
3
3
  #
4
4
  # Este arquivo define a classe Runner (CLI) da gem bddgenx,
5
- # responsável por orquestrar o fluxo de leitura de histórias,
6
- # validação, geração de features, steps, backups e exportação de PDFs.
5
+ # responsável por orquestrar todo o fluxo de geração BDD:
6
+ # leitura e validação de histórias, geração de features, steps,
7
+ # exportação de PDFs e controle de modo (static / IA).
8
+
7
9
  require_relative '../../bddgenx'
8
10
 
9
11
  module Bddgenx
10
- # Ponto de entrada da gem: coordena todo o processo de geração BDD.
12
+ # Classe principal de execução da gem.
13
+ # Atua como ponto de entrada (CLI) para processar arquivos de entrada
14
+ # e gerar todos os artefatos BDD relacionados.
11
15
  class Runner
12
- # Seleciona arquivos de entrada para processamento.
13
- # Se houver argumentos em ARGV, usa-os como nomes de arquivos .txt;
14
- # caso contrário, exibe prompt interativo para escolha.
16
+
17
+ ##
18
+ # Retorna a lista de arquivos de entrada.
19
+ # Se houver argumentos em ARGV, utiliza-os como nomes de arquivos `.txt`.
20
+ # Caso contrário, chama prompt interativo.
15
21
  #
16
- # @param input_dir [String] Diretório onde estão os arquivos .txt de histórias
17
- # @return [Array<String>] Lista de caminhos para os arquivos a serem processados
22
+ # @param input_dir [String] Caminho do diretório de entrada
23
+ # @return [Array<String>] Lista de arquivos `.txt` a processar
18
24
  def self.choose_files(input_dir)
19
25
  ARGV.any? ? selecionar_arquivos_txt(input_dir) : choose_input(input_dir)
20
26
  end
21
27
 
22
- # Mapeia ARGV para paths de arquivos .txt em input_dir.
23
- # Adiciona extensão '.txt' se necessário e filtra arquivos inexistentes.
28
+ ##
29
+ # Processa argumentos ARGV e converte em caminhos válidos de arquivos `.txt`.
30
+ # Adiciona extensão `.txt` se ausente e remove arquivos inexistentes.
24
31
  #
25
- # @param input_dir [String] Diretório de entrada
26
- # @return [Array<String>] Caminhos válidos para processamento
32
+ # @param input_dir [String] Diretório onde estão os arquivos
33
+ # @return [Array<String>] Caminhos válidos para arquivos de entrada
27
34
  def self.selecionar_arquivos_txt(input_dir)
28
35
  ARGV.map do |arg|
29
36
  nome = arg.end_with?('.txt') ? arg : "#{arg}.txt"
@@ -36,12 +43,12 @@ module Bddgenx
36
43
  end.compact
37
44
  end
38
45
 
39
- # Exibe prompt interativo para o usuário escolher qual arquivo processar
40
- # entre todos os .txt disponíveis em input_dir.
46
+ ##
47
+ # Interface interativa para o usuário selecionar arquivos `.txt` a processar.
48
+ # Exibe uma lista dos arquivos disponíveis e solicita um número ao usuário.
41
49
  #
42
50
  # @param input_dir [String] Diretório de entrada
43
- # @exit [1] Se nenhum arquivo for encontrado ou escolha inválida
44
- # @return [Array<String>] Um único arquivo escolhido ou todos se ENTER
51
+ # @return [Array<String>] Lista com o arquivo escolhido ou todos
45
52
  def self.choose_input(input_dir)
46
53
  files = Dir.glob(File.join(input_dir, '*.txt'))
47
54
  if files.empty?
@@ -61,29 +68,29 @@ module Bddgenx
61
68
  [files[idx]]
62
69
  end
63
70
 
64
- # Executa todo o fluxo de geração BDD.
65
- # - Cria pasta 'input' se não existir
66
- # - Seleciona arquivos de histórias
67
- # - Para cada arquivo:
68
- # - e valida a história
69
- # - Gera arquivo .feature e salva backup da versão anterior
70
- # - Gera definitions de steps
71
- # - Exporta PDFs novos via PDFExporter
72
- # - Exibe resumo final com estatísticas
71
+ ##
72
+ # Executa o fluxo completo de geração BDD:
73
+ # - Define o modo (static / IA)
74
+ # - Coleta arquivos de entrada
75
+ # - Valida as histórias
76
+ # - Gera arquivos `.feature` e `steps`
77
+ # - Exporta PDFs e faz backup de versões antigas
78
+ #
79
+ # O modo de execução é lido da variável de ambiente `BDDGENX_MODE`.
73
80
  #
74
81
  # @return [void]
75
82
  def self.execute
76
83
  modo = ENV['BDDGENX_MODE'] || 'static'
77
-
78
84
  input_dir = 'input'
79
85
  Dir.mkdir(input_dir) unless Dir.exist?(input_dir)
80
86
 
81
87
  arquivos = choose_files(input_dir)
82
88
  if arquivos.empty?
83
- warn "❌ Nenhum arquivo de história para processar."; exit 1
89
+ warn I18n.t('messages.no_files')
90
+ exit 1
84
91
  end
85
92
 
86
- # Inicializa contadores
93
+ # Contadores de geração
87
94
  total = features = steps = ignored = 0
88
95
  skipped_steps = []
89
96
  generated_pdfs = []
@@ -91,25 +98,28 @@ module Bddgenx
91
98
 
92
99
  arquivos.each do |arquivo|
93
100
  total += 1
94
- puts "\n🔍 Processando: #{arquivo}"
101
+ puts "\n🔍 #{I18n.t('messages.processing')}: #{arquivo}"
95
102
 
96
103
  historia = Parser.ler_historia(arquivo)
97
104
  unless Validator.validar(historia)
98
105
  ignored += 1
99
- puts "❌ História inválida: #{arquivo}"
106
+ puts "❌ #{I18n.t('messages.invalid_story')}: #{arquivo}"
100
107
  next
101
108
  end
102
109
 
103
- # Geração de feature
104
- if %w[gemini chatgpt].include?(modo)
105
- puts "🤖 Gerando cenários com IA (#{modo.capitalize})..."
110
+ # Geração via IA (ChatGPT, Gemini, Deepseek)
111
+ if %w[gemini chatgpt deepseek].include?(modo)
112
+ puts I18n.t('messages.start_ia', modo: modo.capitalize)
106
113
  idioma = IA::GeminiCliente.detecta_idioma_arquivo(arquivo)
107
114
 
108
- feature_text = Bddgenx::Support::Loader.run("⏳ Aguardando resposta da IA...") do
109
- if modo == 'gemini'
115
+ feature_text = Support::Loader.run(I18n.t('messages.ia_waiting'), :default) do
116
+ case modo
117
+ when 'gemini'
110
118
  IA::GeminiCliente.gerar_cenarios(historia, idioma)
111
- else
119
+ when 'chatgpt'
112
120
  IA::ChatGptCliente.gerar_cenarios(historia, idioma)
121
+ when 'deepseek'
122
+ IA::DeepseekCliente.gerar_cenarios(historia, idioma)
113
123
  end
114
124
  end
115
125
 
@@ -118,11 +128,13 @@ module Bddgenx
118
128
  feature_content = Bddgenx::GherkinCleaner.limpar(feature_text)
119
129
  else
120
130
  ignored += 1
121
- puts "❌ Falha ao gerar com IA: #{arquivo}"
131
+ puts I18n.t('messages.feature_fail', arquivo: arquivo)
122
132
  next
123
133
  end
124
134
  else
125
- feature_path, feature_content = Bddgenx::Support::Loader.run("⛏️ Gerando feature estática...", :dots) do
135
+ # Geração local (modo static)
136
+ feature_path, feature_content = Support::Loader.run(I18n.t('messages.start_static'), :dots) do
137
+ sleep(2)
126
138
  Generator.gerar_feature(historia)
127
139
  end
128
140
  end
@@ -130,29 +142,23 @@ module Bddgenx
130
142
  Backup.salvar_versao_antiga(feature_path)
131
143
  features += 1 if Generator.salvar_feature(feature_path, feature_content)
132
144
 
133
- # Geração de steps
134
145
  if StepsGenerator.gerar_passos(feature_path)
135
146
  steps += 1
136
147
  else
137
148
  skipped_steps << feature_path
138
149
  end
139
150
 
140
- # Exportação de PDF (apenas novos)
141
151
  FileUtils.mkdir_p('reports')
142
152
  result = PDFExporter.exportar_todos(only_new: true)
143
153
  generated_pdfs.concat(result[:generated])
144
154
  skipped_pdfs.concat(result[:skipped])
145
155
  end
146
156
 
147
- # Exibe relatório final
148
- puts "\n✅ Processamento concluído"
149
- puts "- Total de histórias: #{total}"
150
- puts "- Features geradas: #{features}"
151
- puts "- Steps gerados: #{steps}"
152
- puts "- Steps ignorados: #{skipped_steps.size}"
153
- puts "- PDFs gerados: #{generated_pdfs.size}"
154
- puts "- PDFs já existentes: #{skipped_pdfs.size}"
155
- puts "- Histórias ignoradas: #{ignored}"
157
+ # Resumo final
158
+ puts "\n#{I18n.t('messages.processing_done')}"
159
+ puts "- #{I18n.t('messages.total_histories')}: #{total}"
160
+ puts "- #{I18n.t('messages.features_generated')}: #{features}"
161
+ puts "- #{I18n.t('messages.steps_generated')}: #{steps}"
156
162
  end
157
163
  end
158
164
  end
@@ -1,10 +1,10 @@
1
1
  # lib/bddgenx/steps_generator.rb
2
2
  # encoding: utf-8
3
3
  #
4
- # Este arquivo define a classe StepsGenerator, responsável por gerar
5
- # definições de passos do Cucumber a partir de arquivos .feature.
6
- # Suporta palavras-chave Gherkin em Português e Inglês e parametriza
7
- # strings e números conforme necessário.
4
+ # Classe responsável por gerar automaticamente os arquivos de definição
5
+ # de passos do Cucumber a partir de arquivos `.feature`.
6
+ # Suporta palavras-chave do Gherkin tanto em Português quanto em Inglês,
7
+ # além de identificar parâmetros dinamicamente (strings e números).
8
8
 
9
9
  module Bddgenx
10
10
  class StepsGenerator
@@ -14,66 +14,67 @@ module Bddgenx
14
14
  # Palavras-chave Gherkin em Inglês
15
15
  GHERKIN_KEYS_EN = %w[Given When Then And But].freeze
16
16
 
17
- # Conjunto de todas as palavras-chave suportadas
17
+ # Conjunto de todas as palavras-chave reconhecidas
18
18
  ALL_KEYS = GHERKIN_KEYS_PT + GHERKIN_KEYS_EN
19
19
 
20
20
  ##
21
- # Transforma uma string em estilo camelCase.
22
- #
23
- # @param str [String] A string a ser transformada.
24
- # @return [String] A string convertida para camelCase.
21
+ # Transforma uma string em camelCase (sem alterar acentuação).
25
22
  #
23
+ # @param str [String] A string de entrada
24
+ # @return [String] A string convertida para estilo camelCase
26
25
  def self.camelize(str)
27
26
  partes = str.strip.split(/[^a-zA-Z0-9]+/)
28
27
  partes.map.with_index { |palavra, i| i.zero? ? palavra.downcase : palavra.capitalize }.join
29
28
  end
30
29
 
31
30
  ##
32
- # Gera arquivos de passos do Cucumber a partir de um arquivo .feature.
33
- #
34
- # O método lê o arquivo, detecta o idioma, extrai os passos,
35
- # parametriza as variáveis (números e strings), e escreve os métodos
36
- # em um novo arquivo no diretório `steps/`.
37
- #
38
- # @param feature_path [String] Caminho para o arquivo .feature.
39
- # @return [Boolean] Retorna true se os passos forem gerados com sucesso, false se não houver passos.
40
- # @raise [ArgumentError] Se o caminho fornecido não for uma String.
31
+ # Gera um arquivo de definição de passos do Cucumber com base em um `.feature`.
32
+ # Detecta automaticamente o idioma e converte os passos em métodos com placeholders.
41
33
  #
34
+ # @param feature_path [String] Caminho para o arquivo `.feature`
35
+ # @return [Boolean] Retorna true se os steps foram gerados, false se nenhum foi encontrado
36
+ # @raise [ArgumentError] Se o parâmetro não for uma String
42
37
  def self.gerar_passos(feature_path)
43
- raise ArgumentError, "Caminho esperado como String, recebeu #{feature_path.class}" unless feature_path.is_a?(String)
38
+ raise ArgumentError, I18n.t('errors.invalid_path', path: feature_path.class) unless feature_path.is_a?(String)
44
39
 
45
40
  linhas = File.readlines(feature_path)
46
41
 
47
- # Detecta o idioma com base na diretiva "# language:"
42
+ # Detecta o idioma a partir da linha `# language:`
48
43
  lang = if (m = linhas.find { |l| l =~ /^#\s*language:\s*(\w+)/i })
49
44
  m[/^#\s*language:\s*(\w+)/i, 1].downcase
50
45
  else
51
46
  'pt'
52
47
  end
53
48
 
49
+ # Define o locale do I18n conforme idioma detectado
50
+ I18n.locale = lang.to_sym rescue :pt
51
+
54
52
  pt_para_en = GHERKIN_KEYS_PT.zip(GHERKIN_KEYS_EN).to_h
55
53
  en_para_pt = GHERKIN_KEYS_EN.zip(GHERKIN_KEYS_PT).to_h
56
54
 
57
- # Seleciona apenas linhas que começam com palavras-chave Gherkin
55
+ # Seleciona apenas as linhas que representam passos
58
56
  linhas_passos = linhas.map(&:strip).select do |linha|
59
57
  ALL_KEYS.any? { |chave| linha.start_with?(chave + ' ') }
60
58
  end
61
59
 
62
60
  return false if linhas_passos.empty?
63
61
 
62
+ # Cria diretório `steps` no mesmo nível do `.feature`
64
63
  dir_saida = File.join(File.dirname(feature_path), 'steps')
65
64
  FileUtils.mkdir_p(dir_saida)
65
+
66
66
  arquivo_saida = File.join(dir_saida, "#{File.basename(feature_path, '.feature')}_steps.rb")
67
67
 
68
+ # Cabeçalho do arquivo gerado
68
69
  conteudo = +"# encoding: utf-8\n"
69
- conteudo << "# Definições de passos geradas automaticamente para #{File.basename(feature_path)}\n\n"
70
+ conteudo << "# #{I18n.t('steps.header', file: File.basename(feature_path))}\n\n"
70
71
 
71
72
  passos_unicos = Set.new
72
73
 
73
74
  linhas_passos.each do |linha|
74
75
  palavra_original, restante = linha.split(' ', 2)
75
76
 
76
- # Tradução de palavras-chave se necessário
77
+ # Tradução da palavra-chave inicial
77
78
  chave = case lang
78
79
  when 'en' then pt_para_en[palavra_original] || palavra_original
79
80
  else en_para_pt[palavra_original] || palavra_original
@@ -84,7 +85,7 @@ module Bddgenx
84
85
  padrao = ''
85
86
  tokens = []
86
87
 
87
- # Analisa e parametriza o conteúdo dos passos
88
+ # Analisa e parametriza variáveis
88
89
  until scanner.eos?
89
90
  if scanner.check(/"<([^>]+)>"/)
90
91
  scanner.scan(/"<([^>]+)>"/)
@@ -94,8 +95,8 @@ module Bddgenx
94
95
  scanner.scan(/<([^>]+)>/)
95
96
  tokens << scanner[1]
96
97
  padrao << '{int}'
97
- elsif scanner.check(/"([^"<>]+)"/)
98
- scanner.scan(/"([^"<>]+)"/)
98
+ elsif scanner.check(/"([^"]+)"/)
99
+ scanner.scan(/"([^"]+)"/)
99
100
  tokens << scanner[1]
100
101
  padrao << '{string}'
101
102
  elsif scanner.check(/\d+(?:\.\d+)?/)
@@ -109,11 +110,11 @@ module Bddgenx
109
110
 
110
111
  padrao_seguro = padrao.gsub('"', '\\"')
111
112
 
112
- # Impede criação de métodos duplicados
113
+ # Evita duplicatas de métodos
113
114
  next if passos_unicos.include?(padrao_seguro)
114
-
115
115
  passos_unicos << padrao_seguro
116
116
 
117
+ # Monta assinatura do step
117
118
  assinatura = "#{chave}(\"#{padrao_seguro}\")"
118
119
  if tokens.any?
119
120
  argumentos = tokens.each_index.map { |i| "arg#{i+1}" }.join(', ')
@@ -123,12 +124,13 @@ module Bddgenx
123
124
  end
124
125
 
125
126
  conteudo << "#{assinatura}\n"
126
- conteudo << " pending 'Implementar passo: #{texto_bruto}'\n"
127
+ conteudo << " pending '#{I18n.t('steps.pending', text: texto_bruto)}'\n"
127
128
  conteudo << "end\n\n"
128
129
  end
129
130
 
131
+ # Escreve o arquivo final
130
132
  File.write(arquivo_saida, conteudo)
131
- puts "✅ Steps gerados: #{arquivo_saida}"
133
+ puts I18n.t('steps.generated', path: arquivo_saida)
132
134
  true
133
135
  end
134
136
  end
@@ -0,0 +1,28 @@
1
+ en:
2
+ messages:
3
+ start_ia: "🤖 Generating scenarios with AI (%{modo})..."
4
+ start_static: "⛏️ Generating static feature..."
5
+ ia_waiting: "⏳ Waiting for AI response..."
6
+ feature_fail: "❌ Failed to generate via AI: %{arquivo}"
7
+ no_files: "❌ No story file found to process."
8
+ not_found: "⚠️ File not found: %{arquivo}"
9
+ processing_done: "✅ Processing complete"
10
+ total_histories: "Total stories"
11
+ features_generated: "Generated features"
12
+ steps_generated: "Generated steps"
13
+ feature_created: "✅ .feature file generated: %{caminho}"
14
+ gherkin:
15
+ feature: "Feature"
16
+ context: "Background"
17
+ scenario: "Scenario"
18
+ scenario_outline: "Scenario Outline"
19
+ examples: "Examples"
20
+ rule: "Rule"
21
+ steps:
22
+ header: "Step definitions automatically generated for %{file}"
23
+ pending: "Implement step: %{text}"
24
+ generated: "✅ Steps generated: %{path}"
25
+ errors:
26
+ invalid_path: "Expected path as String, got %{path}"
27
+ messages2:
28
+ processing_done: "✅ Processing complete"
@@ -0,0 +1,27 @@
1
+ pt:
2
+ messages:
3
+ start_ia: "🤖 Gerando cenários com IA (%{modo})..."
4
+ start_static: "⛏️ Gerando feature estática..."
5
+ ia_waiting: "⏳ Aguardando resposta da IA..."
6
+ feature_fail: "❌ Falha ao gerar com IA: %{arquivo}"
7
+ no_files: "❌ Nenhum arquivo de história para processar."
8
+ not_found: "⚠️ Arquivo não encontrado: %{arquivo}"
9
+ processing_done: "✅ Processamento concluído"
10
+ total_histories: "Total de histórias"
11
+ features_generated: "Features geradas"
12
+ steps_generated: "Steps gerados"
13
+ feature_created: "✅ Arquivo .feature gerado: %{caminho}"
14
+ gherkin:
15
+ feature: "Funcionalidade"
16
+ context: "Contexto"
17
+ scenario: "Cenário"
18
+ scenario_outline: "Esquema do Cenário"
19
+ examples: "Exemplos"
20
+ rule: "Regra"
21
+ steps:
22
+ header: "Definições de passos geradas automaticamente para %{file}"
23
+ pending: "Implementar passo: %{text}"
24
+ generated: "✅ Steps gerados: %{path}"
25
+ errors:
26
+ invalid_path: "Caminho esperado como String, recebeu %{path}"
27
+
data/lib/bddgenx.rb CHANGED
@@ -1,6 +1,3 @@
1
- #!/usr/bin/env ruby
2
- # Shebang para permitir execução direta do script no Linux/macOS, usando o interpretador Ruby do PATH
3
-
4
1
  require_relative 'env'
5
2
  # Carrega o arquivo 'env.rb' relativo a este script. Geralmente contém configurações e carregamento da gem Bddgenx.
6
3
 
data/lib/env.rb CHANGED
@@ -1,52 +1,109 @@
1
1
  # lib/bddgenx/env.rb
2
+ # encoding: utf-8
3
+ #
4
+ # Responsável por carregar todas as dependências da gem bddgenx.
5
+ # Inclui bibliotecas padrão, gems externas e arquivos internos
6
+ # essenciais para o funcionamento da geração BDD, com suporte a I18n,
7
+ # IA (ChatGPT, Gemini), geração de PDF, validações e estrutura de projeto.
2
8
 
3
- # Carregamento de bibliotecas padrão e gems externas usadas no projeto
9
+ # --------------------------------------
10
+ # 📦 Gems padrão da linguagem Ruby
11
+ # --------------------------------------
4
12
 
5
- require 'json' # Para manipulação de dados JSON
6
- require 'net/http' # Para fazer requisições HTTP
7
- require 'uri' # Para manipulação de URLs
8
- require 'fileutils' # Para manipulação de arquivos e diretórios
9
- require 'prawn' # Biblioteca para geração de PDFs
10
- require 'prawn/table' # Suporte a tabelas no Prawn PDF
11
- require 'prawn-svg' # Para incorporar SVG em PDFs com Prawn
12
- require 'open3' # Para executar comandos externos com captura de saída
13
- require 'faraday' # Cliente HTTP para Gemini API
14
- require 'dotenv' # Para carregar variáveis de ambiente de arquivos .env
15
- require 'unicode' # Para manipulação avançada de strings Unicode (ex: remoção de acentos)
16
- require 'bigdecimal' # Para operações matemáticas precisas com decimais
13
+ require 'json' # Manipulação de dados JSON
14
+ require 'net/http' # Requisições HTTP nativas
15
+ require 'uri' # Manipulação de URLs
16
+ require 'fileutils' # Operações com arquivos e diretórios
17
+ require 'open3' # Execução de comandos externos com captura de saída
18
+ require 'bigdecimal' # Cálculos matemáticos de alta precisão
19
+ require 'i18n' # Internacionalização (traduções dinâmicas)
17
20
 
18
- Dotenv.load
21
+ # --------------------------------------
22
+ # 📚 Gems externas
23
+ # --------------------------------------
19
24
 
20
- # Configura o caminho base do projeto e carrega as gems definidas no Gemfile (se existir)
25
+ require 'prawn' # Geração de documentos PDF
26
+ require 'prawn/table' # Suporte a tabelas no Prawn
27
+ require 'prawn-svg' # Suporte a SVG no PDF
28
+ require 'faraday' # Cliente HTTP para integração com APIs (ex: Gemini)
29
+ require 'dotenv' # Carrega variáveis de ambiente do arquivo `.env`
30
+ require 'unicode' # Manipulação e normalização de caracteres Unicode
31
+
32
+ # --------------------------------------
33
+ # 🌍 Configuração de idioma (I18n)
34
+ # --------------------------------------
35
+
36
+ Dotenv.load # Carrega variáveis como BDDGENX_LANG e APIs
37
+
38
+ # Define o caminho de arquivos de tradução YAML
39
+ locales_path = File.expand_path('bddgenx/locales/*.yml', __dir__)
40
+ I18n.load_path += Dir[locales_path]
41
+
42
+ # Define o idioma ativo somente se estiver presente e válido
43
+ idioma_env = ENV['BDDGENX_LANG']
44
+ if idioma_env && !idioma_env.strip.empty?
45
+ I18n.locale = idioma_env.strip.to_sym
46
+ else
47
+ I18n.locale = :pt
48
+ end
49
+
50
+
51
+ # --------------------------------------
52
+ # 🔧 Bundler (para projetos com Gemfile)
53
+ # --------------------------------------
54
+
55
+ # Carrega as dependências listadas no Gemfile (se houver)
21
56
  require 'bundler/setup' if File.exist?(File.expand_path('../../Gemfile', __FILE__))
22
57
 
23
- # Carregamento dos módulos utilitários (helpers)
24
- require_relative 'bddgenx/support/gherkin_cleaner' # Limpeza e normalização de textos Gherkin
25
- require_relative 'bddgenx/support/remover_steps_duplicados' # Remoção de steps duplicados em features
26
- require_relative 'bddgenx/support/validator' # Validação de dados e entrada
27
- require_relative 'bddgenx/support/font_loader' # Carregamento de fontes para geração PDF
58
+ # --------------------------------------
59
+ # 🧩 Módulos utilitários da gem
60
+ # --------------------------------------
61
+
62
+ require_relative 'bddgenx/support/gherkin_cleaner' # Sanitização de Gherkin gerado
63
+ require_relative 'bddgenx/support/remover_steps_duplicados' # Remove passos duplicados
64
+ require_relative 'bddgenx/support/validator' # Valida estrutura de entrada
65
+ require_relative 'bddgenx/support/font_loader' # Carrega fontes do PDF
66
+
67
+ # --------------------------------------
68
+ # 🤖 Clientes de IA (ChatGPT, Gemini)
69
+ # --------------------------------------
70
+
71
+ require_relative 'bddgenx/ia/gemini_cliente' # Integração com Google Gemini
72
+ require_relative 'bddgenx/ia/chatgtp_cliente' # Integração com OpenAI (ChatGPT)
73
+
74
+ # --------------------------------------
75
+ # 🛠 Geradores (features, steps e execução)
76
+ # --------------------------------------
77
+
78
+ require_relative 'bddgenx/generators/generator' # Geração do conteúdo `.feature`
79
+ require_relative 'bddgenx/generators/steps_generator' # Geração de arquivos `*_steps.rb`
80
+ require_relative 'bddgenx/generators/runner' # Orquestrador da execução CLI
81
+
82
+ # --------------------------------------
83
+ # 📄 Parser e metadados
84
+ # --------------------------------------
85
+
86
+ require_relative 'parser' # Interpreta arquivos `.txt` de entrada
87
+ require_relative 'bddgenx/version' # Lê versão do arquivo `VERSION`
28
88
 
29
- # Carregamento dos clientes para Integração com Inteligência Artificial
30
- require_relative 'bddgenx/ia/gemini_cliente' # Cliente para API Gemini (Google)
31
- require_relative 'bddgenx/ia/chatgtp_cliente' # Cliente para API ChatGPT (OpenAI)
89
+ # --------------------------------------
90
+ # 📤 Relatórios e exportação
91
+ # --------------------------------------
32
92
 
33
- # Carregamento dos geradores de BDD (features, steps e runner)
34
- require_relative 'bddgenx/generators/generator' # Gerador principal de arquivos .feature
35
- require_relative 'bddgenx/generators/steps_generator' # Gerador de arquivos steps.rb
36
- require_relative 'bddgenx/generators/runner' # Classe responsável pela execução do processo de geração
93
+ require_relative 'bddgenx/reports/pdf_exporter' # Exporta features para PDF
94
+ require_relative 'bddgenx/reports/backup' # Gera backups de arquivos
95
+ require_relative 'bddgenx/reports/tracer' # Rastreabilidade de geração
37
96
 
38
- # Parser do arquivo de entrada e versão da gem
39
- require_relative 'parser' # Parser para interpretar arquivos de entrada
40
- require_relative 'bddgenx/version' # Informação da versão da gem
97
+ # --------------------------------------
98
+ # ⚙️ Configuração da gem e loaders auxiliares
99
+ # --------------------------------------
41
100
 
42
- # Relatórios e exportação
43
- require_relative 'bddgenx/reports/pdf_exporter' # Exporta relatórios em PDF usando Prawn
44
- require_relative 'bddgenx/reports/backup' # Mecanismo de backup dos arquivos gerados
45
- require_relative 'bddgenx/reports/tracer' # Rastreabilidade dos processos
101
+ require_relative 'bddgenx/configuration' # Variáveis de configuração (modo, APIs, etc.)
102
+ require_relative 'bddgenx/setup' # Inicializa estrutura do projeto (input/, features/, etc.)
103
+ require_relative 'bddgenx/support/loader' # Exibe loaders/spinners no terminal
46
104
 
47
- require_relative 'bddgenx/configuration' # Configuração das variaveis de IA
48
- require_relative 'bddgenx/setup' # Verifica estrutura do projeto, caso nao exista cria a nova.
49
- require_relative 'bddgenx/support/loader'
105
+ # --------------------------------------
106
+ # 🔁 Define modo de execução (ambiente de dev por padrão)
107
+ # --------------------------------------
50
108
 
51
- # Define variável de ambiente global para indicar que o ambiente BDDGENX está em modo desenvolvimento
52
109
  ENV['BDDGENX_ENV'] = 'development'
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: 2.3.3
4
+ version: 2.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Nascimento
@@ -132,6 +132,8 @@ files:
132
132
  - lib/bddgenx/generators/steps_generator.rb
133
133
  - lib/bddgenx/ia/chatgtp_cliente.rb
134
134
  - lib/bddgenx/ia/gemini_cliente.rb
135
+ - lib/bddgenx/locales/en.yml
136
+ - lib/bddgenx/locales/pt.yml
135
137
  - lib/bddgenx/reports/backup.rb
136
138
  - lib/bddgenx/reports/pdf_exporter.rb
137
139
  - lib/bddgenx/reports/tracer.rb