bddgenx 0.1.43 → 0.1.44
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 +61 -129
- data/Rakefile +41 -40
- data/VERSION +1 -1
- data/lib/bddgenx/generator.rb +86 -41
- data/lib/bddgenx/runner.rb +52 -21
- data/lib/bddgenx/steps_generator.rb +87 -58
- data/lib/bddgenx/utils/backup.rb +19 -4
- data/lib/bddgenx/utils/fontLoader.rb +24 -6
- data/lib/bddgenx/utils/parser.rb +49 -10
- data/lib/bddgenx/utils/pdf_exporter.rb +51 -18
- data/lib/bddgenx/utils/tracer.rb +31 -3
- data/lib/bddgenx/utils/validator.rb +29 -3
- metadata +29 -2
- data/lib/bddgenx/utils/tipo_param.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd3102863b9bbf30f979673c0a24d0b0f256f434af382a3efcaed7f2dc766930
|
4
|
+
data.tar.gz: 8c36dc262f88c01373968fbc251fe543359cb95f716bc28b8e75a755557b4288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fe963d729bb3d0d467d37a3cdfdf229e9ac0ee58df5451f72a6a93206f09e830fe1695b06b18682a7ac1bf73143a1b703e91ff7714efc3428d192c378ffd893
|
7
|
+
data.tar.gz: a7cf35c73fa936673078da5a2c47ea9208e913d5f9e86b23bf882a16b6c87b27814a5b617b6a28984f810fa8d66fce8854f89b4b86b2442e80bb362877142240
|
data/README.md
CHANGED
@@ -1,142 +1,89 @@
|
|
1
|
-
#
|
2
|
-
[](https://badge.fury.io/rb/bddgenx)
|
1
|
+
# Gerador Automático de BDD em Ruby
|
3
2
|
|
4
|
-
|
3
|
+
## Visão Geral
|
5
4
|
|
6
|
-
|
5
|
+
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).
|
7
6
|
|
8
|
-
##
|
9
|
-
```txt
|
10
|
-
bddgenx/
|
11
|
-
├── bin/bddgenx # CLI executável
|
12
|
-
├── input/ # .txt de histórias de usuário
|
13
|
-
├── features/ # .feature geradas
|
14
|
-
├── features/<nome>/steps/ # step definitions por feature (se existir)
|
15
|
-
├── reports/ # todos os artefatos de saída
|
16
|
-
│ ├── backup/ # versões antigas de .feature
|
17
|
-
│ ├── output/ # rastreabilidade.csv
|
18
|
-
│ └── pdf/ # relatórios camelCase
|
19
|
-
├── lib/
|
20
|
-
│ ├── bddgenx/
|
21
|
-
│ │ ├── parser.rb
|
22
|
-
│ │ ├── validator.rb
|
23
|
-
│ │ ├── generator.rb
|
24
|
-
│ │ ├── steps_generator.rb
|
25
|
-
│ │ ├── tracer.rb
|
26
|
-
│ │ ├── backup.rb
|
27
|
-
│ │ └── pdf_exporter.rb
|
28
|
-
│ └── bddgenx.rb # Runner que orquestra tudo
|
29
|
-
├── Gemfile
|
30
|
-
├── bddgenx.gemspec
|
31
|
-
├── Rakefile
|
32
|
-
├── VERSION
|
33
|
-
├── bump_version.sh
|
34
|
-
└── README.md
|
35
|
-
```
|
36
|
-
## ▶️ Como Executar
|
7
|
+
## Instalação
|
37
8
|
|
38
|
-
|
39
|
-
- Ruby 3.x
|
40
|
-
- `bundle install` (caso use gems como `prawn` ou `jira-ruby`)
|
9
|
+
Adicione ao seu `Gemfile`:
|
41
10
|
|
42
|
-
|
11
|
+
```ruby
|
12
|
+
gem 'bddgenx'
|
13
|
+
```
|
14
|
+
|
15
|
+
Execute:
|
43
16
|
|
44
17
|
```bash
|
45
|
-
|
18
|
+
bundle install
|
46
19
|
```
|
47
20
|
|
48
|
-
|
21
|
+
Ou instale diretamente:
|
22
|
+
|
49
23
|
```bash
|
50
|
-
|
24
|
+
gem install bddgenx
|
51
25
|
```
|
52
26
|
|
53
|
-
|
54
|
-
```txt
|
55
|
-
# language: pt
|
56
|
-
Como um usuario do sistema
|
57
|
-
Quero fazer login com sucesso
|
58
|
-
Para acessar minha conta
|
27
|
+
## Uso no Código
|
59
28
|
|
60
|
-
|
61
|
-
|
62
|
-
Então vejo a tela inicial
|
29
|
+
```ruby
|
30
|
+
require 'bddgenx'
|
63
31
|
|
64
|
-
|
65
|
-
|
66
|
-
Então recebo "<resultado>"
|
32
|
+
# Gera todas as features e steps a partir dos .txt em input/
|
33
|
+
Bddgenx::Runner.execute
|
67
34
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
35
|
+
# Opcional: gerar apenas novos artefatos
|
36
|
+
Bddgenx::Runner.execute(only_new: true)
|
37
|
+
|
38
|
+
# Opcional: gerar apenas uma feature específica
|
39
|
+
Bddgenx::Runner.execute(feature: 'input/minha_historia.txt')
|
72
40
|
```
|
73
|
-
✅ Blocos Suportados
|
74
|
-
[CONTEXT] – contexto comum
|
75
41
|
|
76
|
-
|
42
|
+
## Tarefa Rake (opcional)
|
77
43
|
|
78
|
-
|
44
|
+
Em um projeto Rails ou Ruby com Rake, adicione ao `Rakefile`:
|
79
45
|
|
80
|
-
|
46
|
+
```ruby
|
47
|
+
require 'bddgenx'
|
48
|
+
require 'rake'
|
81
49
|
|
82
|
-
|
50
|
+
namespace :bddgenx do
|
51
|
+
desc 'Gera .feature e steps a partir de histórias em input/'
|
52
|
+
task :gerar do
|
53
|
+
Bddgenx::Runner.execute
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
83
57
|
|
84
|
-
|
58
|
+
## Formato do Arquivo de Entrada (`.txt`)
|
85
59
|
|
86
|
-
|
87
|
-
```gherkin
|
60
|
+
```txt
|
88
61
|
# language: pt
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
Quero adicionar produtos ao carrinho
|
93
|
-
Para finalizar minha compra com praticidade
|
62
|
+
Como um usuário do sistema
|
63
|
+
Quero fazer login
|
64
|
+
Para acessar minha conta
|
94
65
|
|
95
|
-
|
96
|
-
|
66
|
+
[SUCCESS]
|
67
|
+
Quando preencho <email> e <senha>
|
68
|
+
Então vejo a tela inicial
|
97
69
|
|
98
|
-
|
99
|
-
|
100
|
-
|
70
|
+
[EXAMPLES]
|
71
|
+
| email | senha | resultado |
|
72
|
+
| user@site.com | 123456 | login realizado |
|
73
|
+
| errado@site.com | senha | credenciais inválidas |
|
74
|
+
```
|
101
75
|
|
102
|
-
|
103
|
-
Cenário: Teste Positivo - adiciono um produto ao carrinho - ele aparece na listagem do carrinho
|
104
|
-
Quando adiciono um produto ao carrinho
|
105
|
-
Então ele aparece na listagem do carrinho
|
76
|
+
## Artefatos de QA
|
106
77
|
|
107
|
-
|
108
|
-
|
109
|
-
|
78
|
+
* **Rastreabilidade**: `reports/output/rastreabilidade.csv` com colunas:
|
79
|
+
`Funcionalidade, Tipo, Tag, Cenário, Passo, Origem`
|
80
|
+
* **Backup**: versões antigas de `.feature` em `reports/backup` com timestamp
|
81
|
+
* **PDF**: exporta features em P/B para `reports/pdf` via `PDFExporter`
|
110
82
|
|
111
|
-
|
112
|
-
| produto | quantidade | total esperado |
|
113
|
-
| Camiseta Azul | 2 | 100 |
|
114
|
-
| Tênis Branco | 1 | 250 |
|
115
|
-
```
|
83
|
+
## Integração CI/CD
|
116
84
|
|
117
|
-
|
118
|
-
```ruby
|
119
|
-
Quando('adiciono "<produto>" com quantidade <quantidade>') do |produto, quantidade|
|
120
|
-
pending 'Implementar passo: adiciono "<produto>" com quantidade <quantidade>'
|
121
|
-
end
|
85
|
+
Exemplo de GitHub Actions:
|
122
86
|
|
123
|
-
Então('vejo o total <total esperado>') do |total_esperado|
|
124
|
-
pending 'Implementar passo: vejo o total <total esperado>'
|
125
|
-
end
|
126
|
-
```
|
127
|
-
🧾 Rastreabilidade
|
128
|
-
- Gera automaticamente um CSV em output/rastreabilidade.csv com:
|
129
|
-
- Nome do cenário
|
130
|
-
- Tipo (SUCCESS, FAILURE, etc.)
|
131
|
-
- Caminho do .feature
|
132
|
-
- Origem do .txt
|
133
|
-
|
134
|
-
🔄 Backup
|
135
|
-
Toda vez que um .feature existente for sobrescrito, a versão anterior é salva em:
|
136
|
-
```
|
137
|
-
backup/
|
138
|
-
```
|
139
|
-
✅ Execução em CI/CD (GitHub Actions)
|
140
87
|
```yaml
|
141
88
|
jobs:
|
142
89
|
gerar_bdd:
|
@@ -145,26 +92,11 @@ jobs:
|
|
145
92
|
- uses: actions/checkout@v3
|
146
93
|
- uses: ruby/setup-ruby@v1
|
147
94
|
with:
|
148
|
-
ruby-version: '3.
|
149
|
-
- run:
|
95
|
+
ruby-version: '3.x'
|
96
|
+
- run: bundle install
|
97
|
+
- run: bundle exec ruby -e "require 'bddgenx'; Bddgenx::Runner.execute(only_new: true)"
|
150
98
|
```
|
151
|
-
⚙️ Alternativa: Usar via Rake
|
152
|
-
|
153
|
-
Você também pode executar a gem bddgenx com Rake, como em projetos Rails:
|
154
|
-
|
155
|
-
Crie um arquivo Rakefile:
|
156
|
-
```ruby
|
157
|
-
require "bddgenx"
|
158
|
-
require "rake"
|
159
99
|
|
160
|
-
|
161
|
-
desc "Gera arquivos .feature e steps a partir de arquivos .txt"
|
162
|
-
task :gerar do
|
163
|
-
Bddgenx::Runner.execute
|
164
|
-
end
|
165
|
-
end
|
166
|
-
```
|
100
|
+
## Licença
|
167
101
|
|
168
|
-
|
169
|
-
David Nascimento – Projeto de automação BDD com Ruby – 2025
|
170
|
-
---
|
102
|
+
MIT © 2025 David Nascimento
|
data/Rakefile
CHANGED
@@ -1,54 +1,55 @@
|
|
1
|
+
# Rakefile
|
2
|
+
# Tarefas para geração automática de BDD e relatórios com bddgenx
|
3
|
+
|
1
4
|
require 'rake'
|
2
|
-
|
3
|
-
|
4
|
-
require_relative 'lib/bddgenx/integrations/jira'
|
5
|
-
require_relative 'lib/bddgenx/integrations/testlink'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'bddgenx'
|
6
7
|
|
7
8
|
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
|
21
|
+
|
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)
|
26
|
+
|
27
|
+
feature_path, conteudo = Bddgenx::Generator.gerar_feature(historia)
|
28
|
+
|
29
|
+
Bddgenx::Backup.salvar_versao_antiga(feature_path)
|
30
|
+
Bddgenx::Generator.salvar_feature(feature_path, conteudo)
|
8
31
|
|
9
|
-
|
10
|
-
|
11
|
-
arquivos = Bddgenx::CLI.todos_arquivos('input')
|
12
|
-
arquivos.each do |arquivo|
|
13
|
-
puts "🔁 Executando: ruby bddgen.rb"
|
14
|
-
system("ruby lib/bddgen.rb")
|
32
|
+
Bddgenx::StepsGenerator.gerar_passos(feature_path)
|
33
|
+
Bddgenx::Tracer.adicionar_entrada(historia, feature_path)
|
15
34
|
end
|
16
35
|
|
36
|
+
puts "✅ Geração concluída#{' (apenas novos)' if only_new}!"
|
17
37
|
end
|
18
38
|
|
19
|
-
desc
|
39
|
+
desc 'Exportar todos os arquivos .feature para PDF'
|
20
40
|
task :pdf do
|
21
|
-
puts
|
22
|
-
Bddgenx::PDFExporter.exportar_todos
|
41
|
+
puts '📦 Exportando features para PDF...'
|
42
|
+
result = Bddgenx::PDFExporter.exportar_todos
|
43
|
+
puts " Gerados: \#{result[:generated].size}, Pulados: \#{result[:skipped].size}"
|
23
44
|
end
|
24
45
|
|
25
|
-
desc
|
26
|
-
task :
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
site: ENV['JIRA_SITE'],
|
31
|
-
project_key: ENV['JIRA_PROJECT']
|
32
|
-
)
|
33
|
-
|
34
|
-
Dir.glob("features/*.feature") do |arquivo|
|
35
|
-
conteudo = File.read(arquivo)
|
36
|
-
titulo = File.basename(arquivo, ".feature").gsub('_', ' ').capitalize
|
37
|
-
jira.enviar_cenario(titulo, conteudo)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "Enviar todos os cenários para o TestLink"
|
42
|
-
task :testlink do
|
43
|
-
testlink = Bddgen::Integrations::TestLink.new(
|
44
|
-
ENV['TESTLINK_TOKEN'],
|
45
|
-
ENV['TESTLINK_URL']
|
46
|
-
)
|
47
|
-
|
48
|
-
Dir.glob("features/*.feature") do |arquivo|
|
49
|
-
conteudo = File.readlines(arquivo).reject { |l| l.strip.start_with?("#") || l.strip.empty? }
|
50
|
-
titulo = File.basename(arquivo, ".feature").gsub('_', ' ').capitalize
|
51
|
-
testlink.criar_caso_teste(ENV['TESTLINK_PLAN_ID'].to_i, titulo, conteudo)
|
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}"
|
52
51
|
end
|
53
52
|
end
|
54
53
|
end
|
54
|
+
|
55
|
+
task default: 'bddgenx:gerar'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.44
|
data/lib/bddgenx/generator.rb
CHANGED
@@ -1,37 +1,82 @@
|
|
1
|
+
# lib/bddgenx/generator.rb
|
2
|
+
# encoding: utf-8
|
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.
|
8
|
+
|
1
9
|
require 'fileutils'
|
2
|
-
require_relative 'utils/tipo_param'
|
3
10
|
|
4
11
|
module Bddgenx
|
12
|
+
# Gera cenários e arquivos .feature baseados em histórias e grupos de passos.
|
5
13
|
class Generator
|
14
|
+
# Palavras-chave Gherkin em Português
|
15
|
+
# @return [Array<String>]
|
6
16
|
GHERKIN_KEYS_PT = %w[Dado Quando Então E Mas].freeze
|
17
|
+
|
18
|
+
# Palavras-chave Gherkin em Inglês
|
19
|
+
# @return [Array<String>]
|
7
20
|
GHERKIN_KEYS_EN = %w[Given When Then And But].freeze
|
21
|
+
|
22
|
+
# Mapeamento PT -> EN
|
23
|
+
# @return [Hash{String=>String}]
|
8
24
|
GHERKIN_MAP_PT_EN = GHERKIN_KEYS_PT.zip(GHERKIN_KEYS_EN).to_h
|
25
|
+
|
26
|
+
# Mapeamento EN -> PT
|
27
|
+
# @return [Hash{String=>String}]
|
9
28
|
GHERKIN_MAP_EN_PT = GHERKIN_KEYS_EN.zip(GHERKIN_KEYS_PT).to_h
|
29
|
+
|
30
|
+
# Conjunto de todas as palavras-chave suportadas (PT + EN)
|
31
|
+
# @return [Array<String>]
|
10
32
|
ALL_KEYS = GHERKIN_KEYS_PT + GHERKIN_KEYS_EN
|
11
33
|
|
12
|
-
#
|
34
|
+
# Seleciona apenas as linhas que representam exemplos do cenário
|
35
|
+
#
|
36
|
+
# @param raw [Array<String>] Lista de linhas brutas do bloco de exemplos
|
37
|
+
# @return [Array<String>] Linhas que começam com '|' representando a tabela de exemplos
|
13
38
|
def self.dividir_examples(raw)
|
14
39
|
raw.select { |l| l.strip.start_with?('|') }
|
15
40
|
end
|
16
41
|
|
17
|
-
# Gera .feature a partir de hash ou
|
18
|
-
#
|
42
|
+
# Gera conteúdo de um arquivo .feature a partir de um hash de história ou caminho para arquivo
|
43
|
+
#
|
44
|
+
# @param input [Hash, String]
|
45
|
+
# Objeto de história com chaves :idioma, :quero, :como, :para, :grupos
|
46
|
+
# Ou caminho para um arquivo de história que será lido via Parser.ler_historia
|
47
|
+
# @param override_path [String, nil]
|
48
|
+
# Caminho de saída alternativo para o arquivo .feature
|
49
|
+
# @raise [ArgumentError] Se Parser.ler_historia lançar erro ao ler arquivo
|
50
|
+
# @return [Array(String, String)] Array com caminho e conteúdo gerado
|
19
51
|
def self.gerar_feature(input, override_path = nil)
|
20
52
|
historia = input.is_a?(String) ? Parser.ler_historia(input) : input
|
21
|
-
idioma
|
22
|
-
|
23
|
-
|
24
|
-
|
53
|
+
idioma = historia[:idioma] || 'pt'
|
54
|
+
|
55
|
+
# Geração do nome base do arquivo
|
56
|
+
nome_base = historia[:quero]
|
57
|
+
.gsub(/[^a-z0-9]/i, '_')
|
58
|
+
.downcase
|
59
|
+
.split('_', 3)
|
60
|
+
.first(3)
|
61
|
+
.join('_')
|
62
|
+
|
63
|
+
caminho = if override_path.is_a?(String)
|
64
|
+
override_path
|
65
|
+
else
|
66
|
+
"features/#{nome_base}.feature"
|
67
|
+
end
|
25
68
|
|
69
|
+
# Definição das palavras-chave Gherkin conforme idioma
|
26
70
|
palavras = {
|
27
|
-
feature:
|
28
|
-
contexto:
|
29
|
-
cenario:
|
30
|
-
esquema:
|
31
|
-
exemplos:
|
32
|
-
regra:
|
71
|
+
feature: idioma == 'en' ? 'Feature' : 'Funcionalidade',
|
72
|
+
contexto: idioma == 'en' ? 'Background' : 'Contexto',
|
73
|
+
cenario: idioma == 'en' ? 'Scenario' : 'Cenário',
|
74
|
+
esquema: idioma == 'en' ? 'Scenario Outline' : 'Esquema do Cenário',
|
75
|
+
exemplos: idioma == 'en' ? 'Examples' : 'Exemplos',
|
76
|
+
regra: idioma == 'en' ? 'Rule' : 'Regra'
|
33
77
|
}
|
34
78
|
|
79
|
+
# Cabeçalho do arquivo .feature
|
35
80
|
conteudo = <<~GHK
|
36
81
|
# language: #{idioma}
|
37
82
|
#{palavras[:feature]}: #{historia[:quero].sub(/^Quero\s*/i,'')}
|
@@ -41,56 +86,51 @@ module Bddgenx
|
|
41
86
|
|
42
87
|
GHK
|
43
88
|
|
44
|
-
pt_map
|
45
|
-
en_map
|
46
|
-
detect
|
89
|
+
pt_map = GHERKIN_MAP_PT_EN
|
90
|
+
en_map = GHERKIN_MAP_EN_PT
|
91
|
+
detect = ALL_KEYS
|
47
92
|
|
48
|
-
historia[:grupos].
|
49
|
-
passos
|
93
|
+
historia[:grupos].each do |grupo|
|
94
|
+
passos = grupo[:passos] || []
|
50
95
|
exemplos = grupo[:exemplos] || []
|
51
96
|
next if passos.empty?
|
52
97
|
|
53
|
-
|
98
|
+
# Linha de tags para o grupo
|
99
|
+
tag_line = ["@#{grupo[:tipo].downcase}",
|
100
|
+
("@#{grupo[:tag]}" if grupo[:tag])]
|
101
|
+
.compact.join(' ')
|
54
102
|
|
55
103
|
if exemplos.any?
|
56
|
-
#
|
104
|
+
# Cenário com Esquema
|
57
105
|
conteudo << " #{tag_line}\n"
|
58
106
|
conteudo << " #{palavras[:esquema]}: #{historia[:quero]}\n"
|
59
107
|
|
60
|
-
#
|
108
|
+
# Passos do cenário
|
61
109
|
passos.each do |p|
|
62
|
-
|
63
|
-
parts = line.split(' ', 2)
|
64
|
-
# match connector case-insensitive
|
110
|
+
parts = p.strip.split(' ', 2)
|
65
111
|
con_in = detect.find { |k| k.casecmp(parts[0]) == 0 } || parts[0]
|
66
|
-
text
|
67
|
-
out_conn = idioma=='en' ? pt_map[con_in] || con_in : en_map[con_in] || con_in
|
68
|
-
conteudo << " #{out_conn} #{text}
|
69
|
-
"
|
112
|
+
text = parts[1] || ''
|
113
|
+
out_conn = idioma == 'en' ? pt_map[con_in] || con_in : en_map[con_in] || con_in
|
114
|
+
conteudo << " #{out_conn} #{text}\n"
|
70
115
|
end
|
71
116
|
|
72
|
-
#
|
73
|
-
# Renderiza o bloco de Examples exatamente como veio no TXT
|
117
|
+
# Bloco de exemplos original
|
74
118
|
conteudo << "\n #{palavras[:exemplos]}:\n"
|
75
119
|
exemplos.select { |l| l.strip.start_with?('|') }.each do |line|
|
76
|
-
# Remove aspas apenas das células, mantendo todas as colunas e valores originais
|
77
120
|
cleaned = line.strip.gsub(/^"|"$/, '')
|
78
121
|
conteudo << " #{cleaned}\n"
|
79
122
|
end
|
80
123
|
conteudo << "\n"
|
81
124
|
else
|
82
|
-
#
|
125
|
+
# Cenário simples
|
83
126
|
conteudo << " #{tag_line}\n"
|
84
127
|
conteudo << " #{palavras[:cenario]}: #{grupo[:tipo].capitalize}\n"
|
85
128
|
passos.each do |p|
|
86
|
-
|
87
|
-
parts = line.split(' ', 2)
|
88
|
-
# match connector case-insensitive
|
129
|
+
parts = p.strip.split(' ', 2)
|
89
130
|
con_in = detect.find { |k| k.casecmp(parts[0]) == 0 } || parts[0]
|
90
|
-
text
|
91
|
-
out_conn = idioma=='en' ? pt_map[con_in] || con_in : en_map[con_in] || con_in
|
92
|
-
conteudo << " #{out_conn} #{text}
|
93
|
-
"
|
131
|
+
text = parts[1] || ''
|
132
|
+
out_conn = idioma == 'en' ? pt_map[con_in] || con_in : en_map[con_in] || con_in
|
133
|
+
conteudo << " #{out_conn} #{text}\n"
|
94
134
|
end
|
95
135
|
conteudo << "\n"
|
96
136
|
end
|
@@ -99,10 +139,15 @@ module Bddgenx
|
|
99
139
|
[caminho, conteudo]
|
100
140
|
end
|
101
141
|
|
142
|
+
# Salva o conteúdo gerado em arquivo .feature no disco
|
143
|
+
#
|
144
|
+
# @param caminho [String] Caminho completo para salvar o arquivo
|
145
|
+
# @param conteudo [String] Conteúdo do arquivo .feature
|
146
|
+
# @return [nil]
|
102
147
|
def self.salvar_feature(caminho, conteudo)
|
103
148
|
FileUtils.mkdir_p(File.dirname(caminho))
|
104
149
|
File.write(caminho, conteudo)
|
105
150
|
puts "✅ Arquivo .feature gerado: #{caminho}"
|
106
151
|
end
|
107
152
|
end
|
108
|
-
end
|
153
|
+
end
|