gherkin_checker 1.0.0 → 1.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: 4711b2c3890a6a9afec7106533d5aa5819b7ace4c99e449a00584a7573083ee1
4
- data.tar.gz: 113c6415dd7d8b49ebc7549ad27c5eeb441872aa7b7d736f9a2bd015a73ca578
3
+ metadata.gz: b6e75527842d4edd3ba0a9b366fc61ef604607cebc78fb1f46ff7d74cb8b2acd
4
+ data.tar.gz: 4b58b609c8c60043fce92b276c0a4eae5fc4649ef2c8e0192000d25e4fbbdc01
5
5
  SHA512:
6
- metadata.gz: 2bef2f8db640cea542bf432b387d005cb571c684a20692766a8ea616d0ca92c995cb61936c0226ba3055a319b0b776e1afd297e475930b3685e6bb5e1d9e83d4
7
- data.tar.gz: 115dce1ae49277fca57e56b694dc96e5e1127d7e4918e021e71c7f8894dc4352b3502917e528c6c09fe305484e27947031a8334fd923cae156ecc7126d142adf
6
+ metadata.gz: 1fbf801b604bfb6288be8b6300e0aae13588a5faff0e03f165e09d2748653570a3fa0c1932cbfcfc8438e292c561f9525ea9b3459239695dea5f7ba4584294ff
7
+ data.tar.gz: 40c710475a69b523b18fb792deef53526da51e61eb7c2ad7861f691b3fd2899e23ec3a1e40025539395e9db77d2391b99c36d5847b0fc3a0caa2e76188dd8fa7
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # GherkinChecker
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
4
-
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/gherkin_checker`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ .feature file checker
6
4
 
7
5
  ## Installation
8
6
 
data/exe/gherkin_checker CHANGED
@@ -7,13 +7,5 @@ require "gherkin_checker"
7
7
  checker = GherkinChecker::Checker.new("gherkin_checker.yml")
8
8
 
9
9
  # Run the check and print the results
10
- errors = checker.check_feature_files
10
+ checker.check_feature_files
11
11
 
12
- if errors.empty?
13
- puts "All scenarios have the required tags."
14
- else
15
- puts "The following scenarios have the required tags:"
16
- errors.each do |error|
17
- puts "#{error[:file]}: Line #{error[:line]} - #{error[:character]}"
18
- end
19
- end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GherkinChecker
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "find"
4
4
  require "yaml"
5
+ require "set"
5
6
 
6
7
  require_relative "gherkin_checker/version"
7
8
 
@@ -9,22 +10,26 @@ module GherkinChecker
9
10
  # Checker class
10
11
  class Checker
11
12
  def initialize(config_file = "gherkin_checker.yml")
12
- puts config_file.inspect
13
- system("ls -l")
14
- system("cat #{config_file}")
15
-
16
13
  unless File.exist?(config_file)
17
- puts "Error: Configuration file #{config_file} not found."
14
+ log_message("Error: Configuration file #{config_file} not found.", level: :error)
18
15
  exit(1) # Exit with a status of 1 to indicate an error
19
16
  end
20
17
 
21
18
  @config = YAML.load_file(config_file)
22
- @feature_files_path = @config["feature_files_path"] || "./features"
23
- @one_of_tag_groups = @config.dig("mandatory_tags", "one_of")
24
- @must_be_tags = @config.dig("mandatory_tags", "must_be")
19
+ if @config
20
+ @skip_check = false
21
+ else
22
+ log_message("Warning: The gherkin_checker.yml not define", level: :warn)
23
+ @skip_check = true
24
+ end
25
+
26
+ @feature_files_path = @config&.key?("feature_files_path") ? @config.fetch("feature_files_path") : "./features"
27
+ @one_of_tags = @config.dig("mandatory_tags", "one_of") if @config
28
+ @must_be_tags = @config.dig("mandatory_tags", "must_be") if @config
25
29
 
26
- puts @one_of_tag_groups.inspect
27
- puts @must_be_tags.inspect
30
+ # Flags to ensure warnings are only printed once
31
+ @one_of_tags_warning_shown = false
32
+ @must_be_tags_warning_shown = false
28
33
  end
29
34
 
30
35
  def check_feature_files
@@ -32,42 +37,171 @@ module GherkinChecker
32
37
  Find.find(@feature_files_path) do |file|
33
38
  next unless File.extname(file) == ".feature"
34
39
 
35
- lines = File.readlines(file)
36
- lines.each_with_index do |line, index|
37
- next unless line.strip.start_with?("Scenario", "Scenario Outline")
40
+ errors += check_one_of_tags(file)
41
+ errors += check_must_be_tags(file)
42
+ end
43
+
44
+ report_errors(errors)
45
+ end
38
46
 
39
- puts scenario_valid?(lines, index)
47
+ private
40
48
 
41
- next if scenario_valid?(lines, index)
49
+ def check_one_of_tags(file)
50
+ return log_one_of_tags_warning if @one_of_tags.nil?
42
51
 
52
+ errors = []
53
+ extract_scenarios_with_tags(file).each do |data|
54
+ is_tags_nil = data[:tags].nil?
55
+ tags = data[:tags]
56
+ file_line = data[:file_line]
57
+ scenario = data[:scenario]
58
+
59
+ if is_tags_nil
43
60
  errors << {
44
- file: file,
45
- line: index + 1,
46
- scenario: line.strip
61
+ check: :one_of_tags,
62
+ file_line: file_line,
63
+ scenario: scenario,
64
+ tags: tags
47
65
  }
48
66
  end
67
+
68
+ next if is_tags_nil
69
+
70
+ next if @one_of_tags.any? { |tag| tags.include?(tag) }
71
+
72
+ errors << {
73
+ check: :one_of_tags,
74
+ file_line: file_line,
75
+ scenario: scenario,
76
+ tags: tags
77
+ }
49
78
  end
79
+
50
80
  errors
51
81
  end
52
82
 
53
- private
83
+ def check_must_be_tags(file)
84
+ return log_must_be_tags_warning if @must_be_tags.nil?
54
85
 
55
- def scenario_valid?(lines, index)
56
- one_of_tags?(lines, index) && must_be_tags?(lines, index)
86
+ errors = []
87
+ extract_scenarios_with_tags(file).each do |data|
88
+ is_tags_nil = data[:tags].nil?
89
+ tags = data[:tags]
90
+ file_line = data[:file_line]
91
+ scenario = data[:scenario]
92
+
93
+ if is_tags_nil
94
+ errors << {
95
+ check: :must_be_tags,
96
+ file_line: file_line,
97
+ scenario: scenario,
98
+ tags: tags
99
+ }
100
+ end
101
+
102
+ next if is_tags_nil
103
+
104
+ next if @must_be_tags.all? { |item| tags.include?(item) }
105
+
106
+ errors << {
107
+ check: :must_be_tags,
108
+ file_line: file_line,
109
+ scenario: scenario,
110
+ tags: tags
111
+ }
112
+ end
113
+
114
+ errors
115
+ end
116
+
117
+ def log_one_of_tags_warning
118
+ return [] if @one_of_tags_warning_shown
119
+
120
+ log_message("Warning: Optional tags not set in 'gherkin_checker.yml'.", level: :warn) unless @skip_check
121
+ @one_of_tags_warning_shown = true
122
+ [] # Return an empty array to maintain consistency
57
123
  end
58
124
 
59
- def one_of_tags?(lines, start_line)
60
- return false if @one_of_tag_groups.nil?
125
+ def log_must_be_tags_warning
126
+ return [] if @must_be_tags_warning_shown
61
127
 
62
- @one_of_tag_groups.all? do |tag_group|
63
- tag_group.any? { |tag| lines[0...start_line].reverse.any? { |line| line.include?(tag) } }
128
+ log_message("Warning: Mandatory tags not set in 'gherkin_checker.yml'.", level: :warn) unless @skip_check
129
+ @must_be_tags_warning_shown = true
130
+ [] # Return an empty array to maintain consistency
131
+ end
132
+
133
+ def report_errors(errors)
134
+ if errors.empty?
135
+ if @skip_check
136
+ log_message("Skip gherkin checking", level: :warn)
137
+ else
138
+ log_message("All scenarios have the required tags.")
139
+ end
140
+ else
141
+ log_message("Gherkin Checker found Error:", level: :error)
142
+ errors.each do |error|
143
+ tags = error[:tags]
144
+ tags = error[:tags].nil? ? "Tagging not set" : "Just found '#{tags}'"
145
+
146
+ message = case error[:check]
147
+ when :one_of_tags
148
+ "one_of_tags '#{@one_of_tags}' not found!, #{tags}"
149
+ when :must_be_tags
150
+ "must_be_tags '#{@must_be_tags}' not found!, #{tags}"
151
+ else
152
+ "error undefined"
153
+ end
154
+
155
+ # Log error to console
156
+ log_message("#{error[:file_line]}: #{error[:scenario]} - #{message}", level: :error)
157
+ end
64
158
  end
65
159
  end
66
160
 
67
- def must_be_tags?(lines, start_line)
68
- return false if @must_be_tags.nil?
161
+ # Define a method to log messages with different levels
162
+ def log_message(message, level: :info)
163
+ # Define color codes
164
+ colors = {
165
+ debug: "\e[36m", # Cyan
166
+ info: "\e[32m", # Green
167
+ warn: "\e[33m", # Yellow
168
+ error: "\e[31m", # Red
169
+ fatal: "\e[35m", # Magenta
170
+ reset: "\e[0m" # Reset to default color
171
+ }
172
+
173
+ color = colors[level] || colors[:reset]
174
+
175
+ puts "#{color}#{message}#{colors[:reset]}"
176
+ end
177
+
178
+ def extract_scenarios_with_tags(file)
179
+ scenarios = []
180
+ current_tags = []
181
+
182
+ lines = File.readlines(file)
183
+
184
+ lines.each_with_index do |line, index|
185
+ # Remove leading/trailing whitespace
186
+ line.strip!
187
+
188
+ if line.start_with?("@")
189
+ # Capture tags if line contains tags
190
+ current_tags = line.scan(/@(\w+)/).flatten
191
+ elsif line.start_with?("Scenario:", "Scenario Outline:")
192
+ # Capture scenario names
193
+ scenario_name = line.sub(/^Scenario(?: Outline)?:\s*/, "").strip
194
+ # Store scenario with current tags (nil if no tags), then reset tags for next scenario
195
+ scenarios << {
196
+ file_line: "#{file}:#{index + 1}",
197
+ scenario: scenario_name,
198
+ tags: current_tags.empty? ? nil : current_tags.dup
199
+ }
200
+ current_tags = [] # Reset tags for next scenario
201
+ end
202
+ end
69
203
 
70
- @must_be_tags.all? { |tag| lines[0...start_line].reverse.any? { |line| line.include?(tag) } }
204
+ scenarios
71
205
  end
72
206
  end
73
207
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gherkin_checker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dikakoko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-02 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Checking .feature files
14
14
  email:
@@ -22,7 +22,7 @@ files:
22
22
  - exe/gherkin_checker
23
23
  - lib/gherkin_checker.rb
24
24
  - lib/gherkin_checker/version.rb
25
- homepage: https://github.com/yourusername/feature_tag_checker
25
+ homepage: https://github.com/dikako/gherkin_checker
26
26
  licenses:
27
27
  - MIT
28
28
  metadata:
@@ -45,5 +45,5 @@ requirements: []
45
45
  rubygems_version: 3.2.32
46
46
  signing_key:
47
47
  specification_version: 4
48
- summary: A gem to validate mandatory tags in .feature files
48
+ summary: ".feature files checkers"
49
49
  test_files: []