bddgenx 1.0.0 → 2.1.0

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: 691d4d259476c68894a8859cc74ab4d926fdfe3b7304f5a020f05843442f33d2
4
- data.tar.gz: 0aeff404aee94ac4d8419dec2772379a0816fdb5ce69a1e8cf967d47499e2f48
3
+ metadata.gz: bc08ad6528e8d4134da51f3f5b1adb28f58f23b0774f75c5b909532a89ffcf94
4
+ data.tar.gz: 93e5e417b5a8ccdda7f1b9e32be61079fcd4d42bf56fd0f17a2cf7d7cdbe30ea
5
5
  SHA512:
6
- metadata.gz: c08188d0e944723b8e109063d2c2e682e335be6c05ff731f51962daba3a3dccac072201107fb23dda9f0d0b3901f75b97a10e1bcb289cf3305ad6deab8ccc198
7
- data.tar.gz: fd8bf60a0b13bb05e63486daa3b4ccead3ddfdc4653046e5f48b252eede5cb8af35498d0d259a23870c203a5912a63a1c70cfc01fdd9b1e5141e58bc56d4c986
6
+ metadata.gz: f89ff60aa9af4fc6fe1b81b95420b7a2c434aa1c746125f62ef4a164e8207352352ad398904541af5906750c01fd50f3f811c66eb35f684004b9ce1764fb37f2
7
+ data.tar.gz: d4ff2d93180bbde669cf4f9cb6bba2ace91b65d46d9a19c7cfb8c901074df5c592d6b7b2c3704c69d6ad610c847e13fb5dfb52034c0f3cccb778a582cdb8858a
data/README.md CHANGED
@@ -3,7 +3,78 @@
3
3
 
4
4
  ## Visão Geral
5
5
 
6
- Ferramenta Ruby para gerar automaticamente arquivos Gherkin (`.feature`) e definições de passos (`steps.rb`) a partir de histórias em texto. Atende aos padrões ISTQB, suporta parametrização com blocos de exemplos e fornece relatórios de QA (rastreabilidade, backups e PDF).
6
+ Ferramenta Ruby para gerar automaticamente arquivos Gherkin (`.feature`) e definições de passos (`steps.rb`) a partir de histórias em texto. Atende aos padrões ISTQB, suporta parametrização com blocos de exemplos e fornece relatórios de QA (rastreabilidade, backups e PDF). Também suporta geração via IA (OpenAI / Gemini) e configuração por ambiente.
7
+
8
+ ---
9
+
10
+ ## Estrutura do Projeto
11
+
12
+ ```
13
+ bdd-generation/
14
+ ├── .github/ # Workflows de CI/CD
15
+ │ └── workflows/
16
+ │ └── main.yml # Workflow de build/test
17
+ ├── bin/ # Scripts CLI e de configuração
18
+ │ ├── bddgenx # Executável CLI para gerar BDD (static/chatgpt/gemini)
19
+ │ └── setup.rb # Script para preparar o ambiente local (gera .env, input/)
20
+ ├── features/ # Gherkin gerados automaticamente
21
+ │ └── steps/ # Steps correspondentes aos cenários
22
+ ├── input/ # Arquivos de entrada (.txt com histórias)
23
+ │ ├── historia.txt
24
+ │ ├── historia_en.txt
25
+ │ └── ...
26
+ ├── lib/
27
+ │ ├── bddgenx/
28
+ │ │ ├── generators/ # Lógica de geração de features e execução geral
29
+ │ │ │ ├── generator.rb
30
+ │ │ │ ├── steps_generator.rb
31
+ │ │ │ └── runner.rb
32
+ │ │ │
33
+ │ │ ├── ia/ # Integração com APIs de IA
34
+ │ │ │ ├── chatgpt_cliente.rb
35
+ │ │ │ └── gemini_cliente.rb
36
+ │ │ │
37
+ │ │ ├── reports/ # Exportação de artefatos QA
38
+ │ │ │ ├── backup.rb
39
+ │ │ │ ├── pdf_exporter.rb
40
+ │ │ │ └── tracer.rb
41
+ │ │ │
42
+ │ │ ├── support/ # Utilitários auxiliares e validadores
43
+ │ │ │ ├── font_loader.rb
44
+ │ │ │ ├── gherkin_cleaner.rb
45
+ │ │ │ ├── remover_steps_duplicados.rb
46
+ │ │ │ └── validator.rb
47
+ │ │ │
48
+ │ │ ├── configuration.rb # Configuração global da gem (modo, ENV keys)
49
+ │ │ └── version.rb # Leitura da versão a partir do arquivo VERSION
50
+ │ │
51
+ │ ├── bddgenx.rb # Entrada principal da gem (require env)
52
+ │ └── parser.rb # Parser de arquivos de entrada
53
+ ├── reports/ # Artefatos gerados
54
+ │ ├── pdf/ # Features exportadas em PDF
55
+ │ ├── backup/ # Versões antigas de features
56
+ │ └── rastreabilidade/ # Arquivos de rastreabilidade (se implementado)
57
+ ├── spec/ # Testes unitários RSpec
58
+ │ ├── support/
59
+ │ ├── utils/
60
+ │ ├── ia/
61
+ │ ├── spec_helper.rb
62
+ │ └── version_spec.rb
63
+ ├── .env # Arquivo com chaves reais (não versionado)
64
+ ├── .env.example # Modelo para configurar variáveis de ambiente
65
+ ├── .gitignore # Arquivos/pastas ignoradas pelo Git
66
+ ├── bddgenx.gemspec # Especificação da gem
67
+ ├── bump_version.sh # Script de versionamento automático (semântico)
68
+ ├── Gemfile
69
+ ├── Gemfile.lock
70
+ ├── LICENSE
71
+ ├── Rakefile # Tarefas automatizadas (static, chatgpt, gemini)
72
+ ├── README.md # Documentação principal do projeto
73
+ └── VERSION # Arquivo contendo a versão atual da gem
74
+
75
+ ```
76
+
77
+ ---
7
78
 
8
79
  ## Instalação
9
80
 
@@ -13,44 +84,70 @@ Adicione ao seu `Gemfile`:
13
84
  gem 'bddgenx'
14
85
  ```
15
86
 
16
- Execute:
87
+ Ou instale diretamente:
88
+
89
+ ```bash
90
+ gem install bddgenx
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 🔧 Configuração
96
+
97
+ ### 1. Instale dependências
17
98
 
18
99
  ```bash
19
100
  bundle install
20
101
  ```
21
102
 
22
- Ou instale diretamente:
103
+ ### 2. Configure seu `.env`
23
104
 
24
105
  ```bash
25
- gem install bddgenx
106
+ cp .env.example .env
26
107
  ```
27
108
 
28
- ## Uso no Código
109
+ Edite o `.env`:
29
110
 
30
- ```ruby
31
- require 'bddgenx'
111
+ ```env
112
+ OPENAI_API_KEY=sk-...
113
+ GEMINI_API_KEY=ya29-...
114
+ BDDGENX_MODE=chatgpt # static | chatgpt | gemini
115
+ ```
32
116
 
33
- # Gera todas as features e steps a partir dos .txt em input/
34
- Bddgenx::Runner.execute
117
+ > 🔐 Dica: nunca versionar o `.env` ele está no `.gitignore`
118
+
119
+ ---
120
+
121
+ ## 🚀 Uso com Rake
122
+
123
+ Com os arquivos `.txt` dentro da pasta `input/`, execute:
124
+
125
+ ```bash
126
+ rake bddgenx:static # geração sem IA
127
+ rake bddgenx:chatgpt # usando ChatGPT
128
+ rake bddgenx:gemini # usando Gemini
35
129
  ```
36
130
 
37
- ## Tarefa Rake (opcional)
131
+ > O modo pode ser sobrescrito via ENV ou `Bddgenx.configure`
132
+
133
+ ---
38
134
 
39
- Em um projeto Rails ou Ruby com Rake, adicione ao `Rakefile`:
135
+ ## 📦 Geração manual via Ruby
40
136
 
41
137
  ```ruby
42
138
  require 'bddgenx'
43
- require 'rake'
44
139
 
45
- namespace :bddgenx do
46
- desc 'Gera .feature e steps a partir de histórias em input/'
47
- task :gerar do
48
- Bddgenx::Runner.execute
49
- end
140
+ Bddgenx.configure do |config|
141
+ config.mode = :chatgpt
142
+ config.openai_api_key_env = 'OPENAI_API_KEY'
50
143
  end
144
+
145
+ Bddgenx::Runner.execute
51
146
  ```
52
147
 
53
- ## Formato do Arquivo de Entrada (`.txt`)
148
+ ---
149
+
150
+ ## 📝 Formato do Arquivo de Entrada (`.txt`)
54
151
 
55
152
  ```txt
56
153
  # language: pt
@@ -63,19 +160,36 @@ Quando preencho <email> e <senha>
63
160
  Então vejo a tela inicial
64
161
 
65
162
  [EXAMPLES]
66
- | email | senha | resultado |
67
- | user@site.com | 123456 | login realizado |
68
- | errado@site.com | senha | credenciais inválidas |
163
+ | email | senha |
164
+ | user@site.com | 123456 |
165
+ | errado@site.com | senha |
69
166
  ```
70
167
 
71
- ## Artefatos de QA
168
+ ---
72
169
 
73
- * **Backup**: versões antigas de `.feature` em `reports/backup` com timestamp
74
- * **PDF**: exporta features em P/B para `reports/pdf` via `PDFExporter`
170
+ ## 🧪 Setup Rápido para Novos Usuários
75
171
 
76
- ## Integração CI/CD
172
+ ```bash
173
+ ruby bin/setup.rb
174
+ ```
175
+
176
+ Esse comando:
177
+
178
+ - Cria `.env` a partir de `.env.example`
179
+ - Garante que `input/` existe
180
+
181
+ ---
77
182
 
78
- Exemplo de GitHub Actions:
183
+ ## 🧾 Artefatos Gerados
184
+
185
+ - ✅ `.feature` → dentro de `features/`
186
+ - ✅ `steps.rb` → dentro de `features/steps/`
187
+ - 🗂️ Backup automático → `reports/backup/`
188
+ - 📄 PDF das features → `reports/pdf/`
189
+
190
+ ---
191
+
192
+ ## ⚙️ CI/CD Exemplo com GitHub Actions
79
193
 
80
194
  ```yaml
81
195
  jobs:
@@ -85,11 +199,15 @@ jobs:
85
199
  - uses: actions/checkout@v3
86
200
  - uses: ruby/setup-ruby@v1
87
201
  with:
88
- ruby-version: '3.x'
202
+ ruby-version: '3.1'
89
203
  - run: bundle install
90
- - run: bundle exec ruby -e "require 'bddgenx'; Bddgenx::Runner.execute(only_new: true)"
204
+ - run: bundle exec rake bddgenx:chatgpt
205
+ env:
206
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
91
207
  ```
92
208
 
209
+ ---
210
+
93
211
  ## Licença
94
212
 
95
213
  MIT © 2025 David Nascimento
data/Rakefile CHANGED
@@ -1,55 +1,49 @@
1
1
  # Rakefile
2
- # Tarefas para geração automática de BDD e relatórios com bddgenx
3
-
2
+ require_relative 'lib/env'
4
3
  require 'rake'
5
- require 'fileutils'
6
- require 'bddgenx'
7
4
 
8
5
  namespace :bddgenx do
9
- desc 'Gerar arquivos .feature, steps, rastreabilidade e backups'
10
- task :gerar, [:only_new, :input_dir] do |t, args|
11
- # Parâmetros: only_new (true/false), input_dir (pasta com .txt)
12
- args.with_defaults(only_new: 'false', input_dir: 'input')
13
- only_new = args.only_new == 'true'
14
- input_dir = args.input_dir
15
-
16
- files = FileList["#{input_dir}/*.txt"]
17
- if files.empty?
18
- puts "❌ Nenhum arquivo encontrado em \#{input_dir}"
19
- next
20
- end
6
+ desc 'Inicializar projeto'
7
+ task :setup do
8
+ Bddgenx::Setup.inicializar_projeto
9
+ end
21
10
 
22
- files.each do |file|
23
- puts "🔄 Processando história: \#{file}"
24
- historia = Bddgenx::Parser.ler_historia(file)
25
- next unless Bddgenx::Validator.validar(historia)
11
+ desc 'Executa a geração BDD usando o modo atual (static, chatgpt, gemini)'
12
+ task :generate do
13
+ puts "⚙️ Modo de geração: #{Bddgenx.configuration.mode}"
26
14
 
27
- feature_path, conteudo = Bddgenx::Generator.gerar_feature(historia)
15
+ # Evita que ARGV contenha o nome da task (como "bddgenx:static")
16
+ ARGV.clear
28
17
 
29
- Bddgenx::Backup.salvar_versao_antiga(feature_path)
30
- Bddgenx::Generator.salvar_feature(feature_path, conteudo)
18
+ Bddgenx::Runner.execute
19
+ end
31
20
 
32
- Bddgenx::StepsGenerator.gerar_passos(feature_path)
33
- Bddgenx::Tracer.adicionar_entrada(historia, feature_path)
21
+ desc 'Gera features no modo estático (sem IA)'
22
+ task :static do
23
+ Bddgenx.configure do |config|
24
+ config.mode = :static
34
25
  end
35
-
36
- puts "✅ Geração concluída#{' (apenas novos)' if only_new}!"
26
+ ENV['BDDGENX_MODE'] = 'static'
27
+ Rake::Task['bddgenx:generate'].invoke
37
28
  end
38
29
 
39
- desc 'Exportar todos os arquivos .feature para PDF'
40
- task :pdf do
41
- puts '📦 Exportando features para PDF...'
42
- result = Bddgenx::PDFExporter.exportar_todos
43
- puts " Gerados: \#{result[:generated].size}, Pulados: \#{result[:skipped].size}"
30
+ desc 'Gera features usando ChatGPT'
31
+ task :chatgpt do
32
+ Bddgenx.configure do |config|
33
+ config.mode = :chatgpt
34
+ config.openai_api_key_env = 'OPENAI_API_KEY'
35
+ end
36
+ ENV['BDDGENX_MODE'] = 'chatgpt'
37
+ Rake::Task['bddgenx:generate'].invoke
44
38
  end
45
39
 
46
- desc 'Remover diretórios gerados (reports/ e features/)'
47
- task :clean do
48
- %w[reports features].each do |dir|
49
- FileUtils.rm_rf(dir)
50
- puts "🗑️ Diretório removido: \#{dir}"
40
+ desc 'Gera features usando Gemini'
41
+ task :gemini do
42
+ Bddgenx.configure do |config|
43
+ config.mode = :gemini
44
+ config.gemini_api_key_env = 'GEMINI_API_KEY'
51
45
  end
46
+ ENV['BDDGENX_MODE'] = 'gemini'
47
+ Rake::Task['bddgenx:generate'].invoke
52
48
  end
53
49
  end
54
-
55
- task default: 'bddgenx:gerar'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 2.1.0
data/bin/bddgenx CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative "../lib/bddgenx/runner"
2
+ require_relative "../lib/bddgenx/generators/runner"
3
3
 
4
4
  Bddgenx::Runner.execute
@@ -0,0 +1,35 @@
1
+ # lib/bddgenx/configuration.rb
2
+ module Bddgenx
3
+ class Configuration
4
+ # :static, :chatgpt ou :gemini
5
+ attr_accessor :mode
6
+
7
+ # Nomes das ENV vars para as chaves
8
+ attr_accessor :openai_api_key_env, :gemini_api_key_env
9
+
10
+ def initialize
11
+ @mode = :static
12
+ @openai_api_key_env = 'OPENAI_API_KEY'
13
+ @gemini_api_key_env = 'GEMINI_API_KEY'
14
+ end
15
+
16
+ # Retorna a chave real, carregada do ENV
17
+ def openai_api_key
18
+ ENV[@openai_api_key_env]
19
+ end
20
+
21
+ def gemini_api_key
22
+ ENV[@gemini_api_key_env]
23
+ end
24
+ end
25
+
26
+ # Singleton de configuração
27
+ def self.configuration
28
+ @configuration ||= Configuration.new
29
+ end
30
+
31
+ # DSL para configurar
32
+ def self.configure
33
+ yield(configuration)
34
+ end
35
+ end
@@ -6,30 +6,45 @@
6
6
  # Suporta Gherkin em Português e Inglês, inclusão de tags, cenários simples
7
7
  # e esquemas de cenário com exemplos.
8
8
 
9
- require 'fileutils'
10
- require 'set'
11
- require_relative 'utils/gherkin_cleaner'
12
- require_relative 'ia/gemini_cliente'
13
- require_relative 'utils/remover_steps_duplicados'
14
- # require_relative 'clients/chatgpt_cliente'
15
-
16
9
  module Bddgenx
17
10
  class Generator
11
+ # Palavras-chave do Gherkin em Português
18
12
  GHERKIN_KEYS_PT = %w[Dado Quando Então E Mas].freeze
13
+
14
+ # Palavras-chave do Gherkin em Inglês
19
15
  GHERKIN_KEYS_EN = %w[Given When Then And But].freeze
16
+
17
+ # Mapeamento de PT → EN
20
18
  GHERKIN_MAP_PT_EN = GHERKIN_KEYS_PT.zip(GHERKIN_KEYS_EN).to_h
19
+
20
+ # Mapeamento de EN → PT
21
21
  GHERKIN_MAP_EN_PT = GHERKIN_KEYS_EN.zip(GHERKIN_KEYS_PT).to_h
22
+
23
+ # Todas as palavras-chave reconhecidas
22
24
  ALL_KEYS = GHERKIN_KEYS_PT + GHERKIN_KEYS_EN
23
25
 
26
+ ##
27
+ # Extrai todas as linhas de exemplo de um array de strings.
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
24
31
  def self.dividir_examples(raw)
25
32
  raw.select { |l| l.strip.start_with?('|') }
26
33
  end
27
34
 
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.
39
+ #
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
28
43
  def self.gerar_feature(input, override_path = nil)
29
44
  modo = ENV['BDD_MODE']&.to_sym || :static
30
45
 
31
- # IA: Lê o arquivo txt e passa para IA → aplica limpeza
32
46
  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
33
48
  raw_txt = File.read(input)
34
49
  historia = {
35
50
  idioma: 'pt',
@@ -50,15 +65,15 @@ module Bddgenx
50
65
  tag: 'ia',
51
66
  passos: GherkinCleaner.limpar(texto_gerado).lines.map(&:strip).reject(&:empty?)
52
67
  }
53
-
54
68
  else
55
- # Caminho tradicional (hash de entrada ou parser de arquivo)
69
+ # Modo estático: utiliza estrutura vinda do Parser ou de um hash diretamente
56
70
  historia = input.is_a?(String) ? Parser.ler_historia(input) : input
57
71
  end
58
72
 
59
73
  idioma = historia[:idioma] || 'pt'
60
74
  cont = 1
61
75
 
76
+ # Normaliza o nome base do arquivo
62
77
  nome_base = historia[:quero]
63
78
  .gsub(/[^a-z0-9]/i, '_')
64
79
  .downcase
@@ -69,6 +84,7 @@ module Bddgenx
69
84
 
70
85
  caminho = override_path || "features/#{nome_base}.feature"
71
86
 
87
+ # Define palavras-chave com base no idioma
72
88
  palavras = {
73
89
  feature: idioma == 'en' ? 'Feature' : 'Funcionalidade',
74
90
  contexto: idioma == 'en' ? 'Background' : 'Contexto',
@@ -79,15 +95,13 @@ module Bddgenx
79
95
  }
80
96
 
81
97
  conteudo = <<~GHK
82
- # language: #{idioma}
83
- #{palavras[:feature]}: #{historia[:quero].sub(/^Quero\s*/i,'')}
84
- # #{historia[:como]}
85
- # #{historia[:quero]}
86
- # #{historia[:para]}
87
-
98
+ # language: #{idioma}
99
+ #{palavras[:feature]}: #{historia[:quero].sub(/^Quero\s*/i,'')}
100
+ # #{historia[:como]}
101
+ # #{historia[:quero]}
102
+ # #{historia[:para]}
88
103
  GHK
89
104
 
90
- # Set para rastrear steps únicos
91
105
  passos_unicos = Set.new
92
106
  pt_map = GHERKIN_MAP_PT_EN
93
107
  en_map = GHERKIN_MAP_EN_PT
@@ -100,7 +114,6 @@ module Bddgenx
100
114
  next if passos.empty?
101
115
 
102
116
  tag_line = ["@#{grupo[:tipo].downcase}", ("@#{grupo[:tag]}" if grupo[:tag])].compact.join(' ')
103
-
104
117
  conteudo << " #{tag_line}\n"
105
118
 
106
119
  if exemplos.any?
@@ -137,11 +150,22 @@ module Bddgenx
137
150
  [caminho, conteudo]
138
151
  end
139
152
 
153
+ ##
154
+ # Gera o caminho padrão de saída para um arquivo `.feature` com base no nome do `.txt`.
155
+ #
156
+ # @param arquivo_txt [String] caminho do arquivo .txt de entrada
157
+ # @return [String] caminho completo do arquivo .feature correspondente
140
158
  def self.path_para_feature(arquivo_txt)
141
159
  nome = File.basename(arquivo_txt, '.txt')
142
160
  File.join('features', "#{nome}.feature")
143
161
  end
144
162
 
163
+ ##
164
+ # Salva o conteúdo gerado no disco, criando diretórios se necessário.
165
+ #
166
+ # @param caminho [String] caminho completo para salvar o arquivo
167
+ # @param conteudo [String] conteúdo do arquivo .feature
168
+ # @return [void]
145
169
  def self.salvar_feature(caminho, conteudo)
146
170
  FileUtils.mkdir_p(File.dirname(caminho))
147
171
  File.write(caminho, conteudo)
@@ -4,16 +4,7 @@
4
4
  # Este arquivo define a classe Runner (CLI) da gem bddgenx,
5
5
  # responsável por orquestrar o fluxo de leitura de histórias,
6
6
  # validação, geração de features, steps, backups e exportação de PDFs.
7
- require 'dotenv/load'
8
- require 'fileutils'
9
- require_relative 'utils/parser'
10
- require_relative 'generator'
11
- require_relative 'utils/pdf_exporter'
12
- require_relative 'steps_generator'
13
- require_relative 'utils/validator'
14
- require_relative 'utils/backup'
15
- require_relative 'ia/gemini_cliente'
16
- require_relative 'utils/gherkin_cleaner'
7
+ require_relative '../../bddgenx'
17
8
 
18
9
  module Bddgenx
19
10
  # Ponto de entrada da gem: coordena todo o processo de geração BDD.
@@ -110,26 +101,15 @@ module Bddgenx
110
101
  end
111
102
 
112
103
  # Geração de feature
113
- if modo == 'gemini'
114
- puts "🤖 Gerando cenários com IA (Gemini)..."
115
- idioma = IA::GeminiCliente.detecta_idioma_arquivo(arquivo) # Seu método que detecta o idioma no .txt (ex: 'pt' ou 'en')
116
- spinner = Thread.new do
117
- loop do
118
- print "\r⏳ Aguardando resposta da IA "
119
- 3.times do |i|
120
- print "." * (i + 1)
121
- sleep(0.4)
122
- print "\r⏳ Aguardando resposta da IA#{'.' * (i + 1)} "
123
- end
104
+ if modo == 'gemini' || modo == 'chatgpt'
105
+ puts "🤖 Gerando cenários com IA (#{modo.capitalize})..."
106
+ idioma = IA::GeminiCliente.detecta_idioma_arquivo(arquivo)
107
+ feature_text =
108
+ if modo == 'gemini'
109
+ IA::GeminiCliente.gerar_cenarios(historia, idioma)
110
+ else
111
+ IA::ChatGptCliente.gerar_cenarios(historia, idioma)
124
112
  end
125
- end
126
- begin
127
- feature_text = IA::GeminiCliente.gerar_cenarios(historia, idioma)
128
- ensure
129
- Thread.kill(spinner)
130
- print "\r✅ Resposta da IA recebida! \n"
131
- end
132
- # feature_text = IA::GeminiCliente.gerar_cenarios(historia, idioma)
133
113
  if feature_text
134
114
  feature_path = Generator.path_para_feature(arquivo)
135
115
  feature_content = Bddgenx::GherkinCleaner.limpar(feature_text)
@@ -6,26 +6,45 @@
6
6
  # Suporta palavras-chave Gherkin em Português e Inglês e parametriza
7
7
  # strings e números conforme necessário.
8
8
 
9
- require 'fileutils'
10
- require 'strscan' # Para uso de StringScanner
11
- require 'set'
12
-
13
9
  module Bddgenx
14
10
  class StepsGenerator
11
+ # Palavras-chave Gherkin em Português
15
12
  GHERKIN_KEYS_PT = %w[Dado Quando Então E Mas].freeze
13
+
14
+ # Palavras-chave Gherkin em Inglês
16
15
  GHERKIN_KEYS_EN = %w[Given When Then And But].freeze
16
+
17
+ # Conjunto de todas as palavras-chave suportadas
17
18
  ALL_KEYS = GHERKIN_KEYS_PT + GHERKIN_KEYS_EN
18
19
 
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.
25
+ #
19
26
  def self.camelize(str)
20
27
  partes = str.strip.split(/[^a-zA-Z0-9]+/)
21
28
  partes.map.with_index { |palavra, i| i.zero? ? palavra.downcase : palavra.capitalize }.join
22
29
  end
23
30
 
31
+ ##
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.
41
+ #
24
42
  def self.gerar_passos(feature_path)
25
43
  raise ArgumentError, "Caminho esperado como String, recebeu #{feature_path.class}" unless feature_path.is_a?(String)
26
44
 
27
45
  linhas = File.readlines(feature_path)
28
46
 
47
+ # Detecta o idioma com base na diretiva "# language:"
29
48
  lang = if (m = linhas.find { |l| l =~ /^#\s*language:\s*(\w+)/i })
30
49
  m[/^#\s*language:\s*(\w+)/i, 1].downcase
31
50
  else
@@ -35,6 +54,7 @@ module Bddgenx
35
54
  pt_para_en = GHERKIN_KEYS_PT.zip(GHERKIN_KEYS_EN).to_h
36
55
  en_para_pt = GHERKIN_KEYS_EN.zip(GHERKIN_KEYS_PT).to_h
37
56
 
57
+ # Seleciona apenas linhas que começam com palavras-chave Gherkin
38
58
  linhas_passos = linhas.map(&:strip).select do |linha|
39
59
  ALL_KEYS.any? { |chave| linha.start_with?(chave + ' ') }
40
60
  end
@@ -53,6 +73,7 @@ module Bddgenx
53
73
  linhas_passos.each do |linha|
54
74
  palavra_original, restante = linha.split(' ', 2)
55
75
 
76
+ # Tradução de palavras-chave se necessário
56
77
  chave = case lang
57
78
  when 'en' then pt_para_en[palavra_original] || palavra_original
58
79
  else en_para_pt[palavra_original] || palavra_original
@@ -63,6 +84,7 @@ module Bddgenx
63
84
  padrao = ''
64
85
  tokens = []
65
86
 
87
+ # Analisa e parametriza o conteúdo dos passos
66
88
  until scanner.eos?
67
89
  if scanner.check(/"<([^>]+)>"/)
68
90
  scanner.scan(/"<([^>]+)>"/)
@@ -87,7 +109,7 @@ module Bddgenx
87
109
 
88
110
  padrao_seguro = padrao.gsub('"', '\\"')
89
111
 
90
- # Impede duplicatas
112
+ # Impede criação de métodos duplicados
91
113
  next if passos_unicos.include?(padrao_seguro)
92
114
 
93
115
  passos_unicos << padrao_seguro