bddgenx 2.3.2 → 2.3.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 +4 -4
- data/README.md +48 -20
- data/Rakefile +23 -36
- data/VERSION +1 -1
- data/lib/bddgenx/generators/runner.rb +8 -3
- data/lib/bddgenx/ia/chatgtp_cliente.rb +29 -16
- data/lib/bddgenx/ia/gemini_cliente.rb +32 -15
- data/lib/bddgenx/support/loader.rb +31 -0
- data/lib/env.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5f895b922c947b8d97296d56a17cfbdc9c31e5bbf6bbfc383c01ebc3e4cfe9d
|
4
|
+
data.tar.gz: 001d68f9b89e12e52e446bc02db6ee249392c864ad1955172dff31203a1a6a6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce291e292b64946fcc493e9a590ef335fc652d321bee8637fdd7b5c30a7d411f34d7a26baf26c2a8f6ea1208fb2c943c11219b07695aa6e87fd7a932677a25a3
|
7
|
+
data.tar.gz: 52710f0f98ba329340956d8e657c09fd802f7f51a34b6437fd692f1e20924db8354a0ed3adcaa29d297461bf566e31fd9dfff54efa9945bbbd719f3f619c4c57
|
data/README.md
CHANGED
@@ -149,34 +149,42 @@ Bddgenx::Runner.execute
|
|
149
149
|
|
150
150
|
## 📦 Geração manual via Rake
|
151
151
|
```Ruby
|
152
|
-
require_relative 'lib/env' # ajuste conforme seu projeto
|
153
152
|
require 'rake'
|
153
|
+
require 'bddgenx'
|
154
154
|
|
155
155
|
namespace :bddgenx do
|
156
|
-
desc '
|
157
|
-
task :generate
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
156
|
+
desc 'Executa geração interativa: escolha entre static, chatgpt, gemini ou deepseek'
|
157
|
+
task :generate do
|
158
|
+
puts "=== Qual modo deseja usar para gerar os cenários? ==="
|
159
|
+
puts "1. static (sem IA)"
|
160
|
+
puts "2. chatgpt (via OpenAI)"
|
161
|
+
puts "3. gemini (via Google)"
|
162
|
+
print "Digite o número (1-3): "
|
163
|
+
|
164
|
+
escolha = STDIN.gets.chomp.to_i
|
165
|
+
|
166
|
+
modo = case escolha
|
167
|
+
when 1 then :static
|
168
|
+
when 2 then :chatgpt
|
169
|
+
when 3 then :gemini
|
170
|
+
else
|
171
|
+
puts "❌ Opção inválida. Saindo."; exit 1
|
172
|
+
end
|
165
173
|
|
166
174
|
Bddgenx.configure do |config|
|
167
175
|
config.mode = modo
|
168
176
|
config.openai_api_key_env = 'OPENAI_API_KEY'
|
169
177
|
config.gemini_api_key_env = 'GEMINI_API_KEY'
|
170
|
-
config.deepseek_api_key_env = 'DEEPSEEK_API_KEY'
|
171
178
|
end
|
172
179
|
|
173
|
-
|
180
|
+
# ⚠️ Limpa o ARGV antes de executar para evitar que [static] seja interpretado como nome de arquivo
|
181
|
+
ARGV.clear
|
174
182
|
|
175
|
-
|
183
|
+
ENV['BDDGENX_MODE'] = modo.to_s
|
184
|
+
puts "\n⚙️ Modo selecionado: #{modo}\n\n"
|
176
185
|
Bddgenx::Runner.execute
|
177
186
|
end
|
178
187
|
end
|
179
|
-
|
180
188
|
```
|
181
189
|
|
182
190
|
## 📝 Formato do Arquivo de Entrada (`.txt`)
|
@@ -184,17 +192,37 @@ end
|
|
184
192
|
```txt
|
185
193
|
# language: pt
|
186
194
|
Como um usuário do sistema
|
187
|
-
Quero fazer login
|
188
|
-
Para acessar minha conta
|
195
|
+
Quero fazer login corretamente
|
196
|
+
Para acessar minha conta com segurança
|
197
|
+
|
198
|
+
[CONTEXT]
|
199
|
+
Dado que estou na tela de login
|
189
200
|
|
190
201
|
[SUCCESS]
|
191
|
-
Quando preencho
|
202
|
+
Quando preencho email e senha válidos
|
192
203
|
Então vejo a tela inicial
|
193
204
|
|
205
|
+
[SUCCESS]
|
206
|
+
Quando tento logar com "<email>" e "<senha>"
|
207
|
+
Então recebo "<mensagem>"
|
208
|
+
|
209
|
+
[EXAMPLES]
|
210
|
+
| email | senha | mensagem |
|
211
|
+
| user@site.com | 123456 | login realizado |
|
212
|
+
| errado@site.com | senha | credenciais inválidas |
|
213
|
+
| | senha | email é obrigatório |
|
214
|
+
| user@site.com | | senha é obrigatória |
|
215
|
+
|
216
|
+
[SUCCESS]
|
217
|
+
Quando deixo o campo "<campo>" vazio
|
218
|
+
Então recebo a mensagem "<mensagem>"
|
219
|
+
|
194
220
|
[EXAMPLES]
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
221
|
+
| campo | mensagem |
|
222
|
+
| | login realizado |
|
223
|
+
| | credenciais inválidas |
|
224
|
+
| email | email é obrigatório |
|
225
|
+
| senha | senha é obrigatória |
|
198
226
|
```
|
199
227
|
|
200
228
|
---
|
data/Rakefile
CHANGED
@@ -1,49 +1,36 @@
|
|
1
|
-
# Rakefile
|
2
|
-
require_relative 'lib/env'
|
3
1
|
require 'rake'
|
2
|
+
require 'bddgenx'
|
4
3
|
|
5
4
|
namespace :bddgenx do
|
6
|
-
desc '
|
7
|
-
task :setup do
|
8
|
-
Bddgenx::Setup.inicializar_projeto
|
9
|
-
end
|
10
|
-
|
11
|
-
desc 'Executa a geração BDD usando o modo atual (static, chatgpt, gemini)'
|
5
|
+
desc 'Executa geração interativa: escolha entre static, chatgpt, gemini ou deepseek'
|
12
6
|
task :generate do
|
13
|
-
puts "
|
7
|
+
puts "=== Qual modo deseja usar para gerar os cenários? ==="
|
8
|
+
puts "1. static (sem IA)"
|
9
|
+
puts "2. chatgpt (via OpenAI)"
|
10
|
+
puts "3. gemini (via Google)"
|
11
|
+
print "Digite o número (1-3): "
|
14
12
|
|
15
|
-
|
16
|
-
ARGV.clear
|
13
|
+
escolha = STDIN.gets.chomp.to_i
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
ENV['BDDGENX_MODE'] = 'static'
|
27
|
-
Rake::Task['bddgenx:generate'].invoke
|
28
|
-
end
|
15
|
+
modo = case escolha
|
16
|
+
when 1 then :static
|
17
|
+
when 2 then :chatgpt
|
18
|
+
when 3 then :gemini
|
19
|
+
else
|
20
|
+
puts "❌ Opção inválida. Saindo."; exit 1
|
21
|
+
end
|
29
22
|
|
30
|
-
desc 'Gera features usando ChatGPT'
|
31
|
-
task :chatgpt do
|
32
23
|
Bddgenx.configure do |config|
|
33
|
-
config.mode =
|
24
|
+
config.mode = modo
|
34
25
|
config.openai_api_key_env = 'OPENAI_API_KEY'
|
35
|
-
end
|
36
|
-
ENV['BDDGENX_MODE'] = 'chatgpt'
|
37
|
-
Rake::Task['bddgenx:generate'].invoke
|
38
|
-
end
|
39
|
-
|
40
|
-
desc 'Gera features usando Gemini'
|
41
|
-
task :gemini do
|
42
|
-
Bddgenx.configure do |config|
|
43
|
-
config.mode = :gemini
|
44
26
|
config.gemini_api_key_env = 'GEMINI_API_KEY'
|
45
27
|
end
|
46
|
-
|
47
|
-
|
28
|
+
|
29
|
+
# ⚠️ Limpa o ARGV antes de executar para evitar que [static] seja interpretado como nome de arquivo
|
30
|
+
ARGV.clear
|
31
|
+
|
32
|
+
ENV['BDDGENX_MODE'] = modo.to_s
|
33
|
+
puts "\n⚙️ Modo selecionado: #{modo}\n\n"
|
34
|
+
Bddgenx::Runner.execute
|
48
35
|
end
|
49
36
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.3
|
@@ -101,15 +101,18 @@ module Bddgenx
|
|
101
101
|
end
|
102
102
|
|
103
103
|
# Geração de feature
|
104
|
-
if
|
104
|
+
if %w[gemini chatgpt].include?(modo)
|
105
105
|
puts "🤖 Gerando cenários com IA (#{modo.capitalize})..."
|
106
106
|
idioma = IA::GeminiCliente.detecta_idioma_arquivo(arquivo)
|
107
|
-
|
107
|
+
|
108
|
+
feature_text = Bddgenx::Support::Loader.run("⏳ Aguardando resposta da IA...") do
|
108
109
|
if modo == 'gemini'
|
109
110
|
IA::GeminiCliente.gerar_cenarios(historia, idioma)
|
110
111
|
else
|
111
112
|
IA::ChatGptCliente.gerar_cenarios(historia, idioma)
|
112
113
|
end
|
114
|
+
end
|
115
|
+
|
113
116
|
if feature_text
|
114
117
|
feature_path = Generator.path_para_feature(arquivo)
|
115
118
|
feature_content = Bddgenx::GherkinCleaner.limpar(feature_text)
|
@@ -119,7 +122,9 @@ module Bddgenx
|
|
119
122
|
next
|
120
123
|
end
|
121
124
|
else
|
122
|
-
feature_path, feature_content =
|
125
|
+
feature_path, feature_content = Bddgenx::Support::Loader.run("⛏️ Gerando feature estática...", :dots) do
|
126
|
+
Generator.gerar_feature(historia)
|
127
|
+
end
|
123
128
|
end
|
124
129
|
|
125
130
|
Backup.salvar_versao_antiga(feature_path)
|
@@ -55,21 +55,31 @@ module Bddgenx
|
|
55
55
|
|
56
56
|
# Prompt base enviado ao ChatGPT, instruindo a saída no formato correto
|
57
57
|
prompt_base = <<~PROMPT
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
58
|
+
Gere cenários BDD no formato Gherkin, utilizando as palavras-chave estruturais no idioma "#{idioma}":
|
59
|
+
Feature: #{keywords[:feature]}
|
60
|
+
Scenario: #{keywords[:scenario]}
|
61
|
+
Scenario Outline: #{keywords[:scenario_outline]}
|
62
|
+
Examples: #{keywords[:examples]}
|
63
|
+
Given: #{keywords[:given]}
|
64
|
+
When: #{keywords[:when]}
|
65
|
+
Then: #{keywords[:then]}
|
66
|
+
And: #{keywords[:and]}
|
67
|
+
|
68
|
+
Instruções:
|
69
|
+
- Todos os textos dos passos devem ser escritos em **português**.
|
70
|
+
- Use as palavras-chave Gherkin no idioma especificado ("#{idioma}").
|
71
|
+
- Gere **vários cenários**, incluindo positivos e negativos.
|
72
|
+
- Use `Scenario Outline` e `Examples` sempre que houver valores variáveis.
|
73
|
+
- Mantenha os parâmetros como `<email>`, `<senha>` e outros entre colchetes angulares, exatamente como aparecem.
|
74
|
+
- Se a história fornecer contexto (ex: `[CONTEXT]` ou "Dado que..."), utilize-o como base para os cenários.
|
75
|
+
- Se não houver contexto explícito, **crie um coerente** baseado na história.
|
76
|
+
- A primeira linha do resultado deve conter obrigatoriamente `# language: #{idioma}`.
|
77
|
+
- Evite passos vagos ou genéricos. Use ações claras e específicas.
|
78
|
+
- Gere apenas o conteúdo da feature, sem explicações adicionais.
|
79
|
+
|
80
|
+
História fornecida:
|
81
|
+
#{historia}
|
82
|
+
PROMPT
|
73
83
|
|
74
84
|
uri = URI(CHATGPT_API_URL)
|
75
85
|
request_body = {
|
@@ -107,7 +117,10 @@ module Bddgenx
|
|
107
117
|
return fallback_com_gemini(historia, idioma)
|
108
118
|
end
|
109
119
|
else
|
110
|
-
|
120
|
+
if response.code.to_i == 429
|
121
|
+
warn "❌ Limite de uso da API OpenAI excedido."
|
122
|
+
warn "🔗 Verifique sua conta: https://platform.openai.com/account/usage"
|
123
|
+
end
|
111
124
|
return fallback_com_gemini(historia, idioma)
|
112
125
|
end
|
113
126
|
end
|
@@ -46,21 +46,33 @@ module Bddgenx
|
|
46
46
|
|
47
47
|
# Prompt base que instrui a IA a gerar cenários Gherkin no idioma indicado
|
48
48
|
prompt_base = <<~PROMPT
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
49
|
+
Gere cenários BDD no formato Gherkin, utilizando as palavras-chave estruturais no idioma "#{idioma}":
|
50
|
+
Feature: #{keywords[:feature]}
|
51
|
+
Scenario: #{keywords[:scenario]}
|
52
|
+
Scenario Outline: #{keywords[:scenario_outline]}
|
53
|
+
Examples: #{keywords[:examples]}
|
54
|
+
Given: #{keywords[:given]}
|
55
|
+
When: #{keywords[:when]}
|
56
|
+
Then: #{keywords[:then]}
|
57
|
+
And: #{keywords[:and]}
|
58
|
+
|
59
|
+
Instruções:
|
60
|
+
- Todos os textos dos passos devem ser escritos em **português**.
|
61
|
+
- Use as palavras-chave Gherkin no idioma especificado ("#{idioma}").
|
62
|
+
- Gere **vários cenários**, incluindo positivos e negativos.
|
63
|
+
- Use `Scenario Outline` e `Examples` sempre que houver valores variáveis.
|
64
|
+
- Mantenha os parâmetros como `<email>`, `<senha>` e outros entre colchetes angulares, exatamente como aparecem.
|
65
|
+
- Se a história fornecer contexto (ex: `[CONTEXT]` ou "Dado que..."), utilize-o como base para os cenários.
|
66
|
+
- Se não houver contexto explícito, **crie um coerente** baseado na história.
|
67
|
+
- A primeira linha do resultado deve conter obrigatoriamente `# language: #{idioma}`.
|
68
|
+
- Evite passos vagos ou genéricos. Use ações claras e específicas.
|
69
|
+
- Gere apenas o conteúdo da feature, sem explicações adicionais.
|
70
|
+
|
71
|
+
História fornecida:
|
72
|
+
#{historia}
|
73
|
+
PROMPT
|
74
|
+
|
75
|
+
|
64
76
|
|
65
77
|
unless api_key
|
66
78
|
warn "❌ API Key do Gemini não encontrada no .env (GEMINI_API_KEY)"
|
@@ -101,6 +113,11 @@ module Bddgenx
|
|
101
113
|
texto_limpo.sub!(/^# language: .*/, "# language: #{idioma}")
|
102
114
|
texto_limpo.prepend("# language: #{idioma}\n") unless texto_limpo.start_with?("# language:")
|
103
115
|
|
116
|
+
# Garante diretiva de idioma
|
117
|
+
feature_text = Bddgenx::GherkinCleaner.limpar(texto_ia)
|
118
|
+
feature_text.sub!(/^# language: .*/, "") # remove qualquer # language: existente
|
119
|
+
feature_text.prepend("# language: #{idioma}\n") # insere a correta
|
120
|
+
|
104
121
|
return texto_limpo
|
105
122
|
else
|
106
123
|
warn "❌ Resposta da IA sem conteúdo de texto"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bddgenx
|
2
|
+
module Support
|
3
|
+
class Loader
|
4
|
+
SPINNERS = {
|
5
|
+
default: %w[| / - \\],
|
6
|
+
dots: %w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏]
|
7
|
+
}
|
8
|
+
|
9
|
+
def self.run(mensagem = "⏳ Processando...", tipo = :default)
|
10
|
+
spinner = SPINNERS[tipo] || SPINNERS[:default]
|
11
|
+
done = false
|
12
|
+
|
13
|
+
thread = Thread.new do
|
14
|
+
i = 0
|
15
|
+
print "\n"
|
16
|
+
until done
|
17
|
+
print "\r#{mensagem} #{spinner[i % spinner.length]}"
|
18
|
+
sleep(0.1)
|
19
|
+
i += 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
result = yield
|
24
|
+
done = true
|
25
|
+
thread.join
|
26
|
+
print "\r#{mensagem} ✅\n"
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/env.rb
CHANGED
@@ -46,6 +46,7 @@ require_relative 'bddgenx/reports/tracer' # Rastreabilidade
|
|
46
46
|
|
47
47
|
require_relative 'bddgenx/configuration' # Configuração das variaveis de IA
|
48
48
|
require_relative 'bddgenx/setup' # Verifica estrutura do projeto, caso nao exista cria a nova.
|
49
|
+
require_relative 'bddgenx/support/loader'
|
49
50
|
|
50
51
|
# Define variável de ambiente global para indicar que o ambiente BDDGENX está em modo desenvolvimento
|
51
52
|
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.
|
4
|
+
version: 2.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Nascimento
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- lib/bddgenx/setup.rb
|
139
139
|
- lib/bddgenx/support/font_loader.rb
|
140
140
|
- lib/bddgenx/support/gherkin_cleaner.rb
|
141
|
+
- lib/bddgenx/support/loader.rb
|
141
142
|
- lib/bddgenx/support/remover_steps_duplicados.rb
|
142
143
|
- lib/bddgenx/support/validator.rb
|
143
144
|
- lib/bddgenx/version.rb
|