cuker 0.3.15

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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +71 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CHANGELOG.md +0 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE +21 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +39 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/cuker.gemspec +43 -0
  14. data/lib/cuker.rb +7 -0
  15. data/lib/cuker/gherkin_lexer.rb +33 -0
  16. data/lib/cuker/gherkin_parser.rb +23 -0
  17. data/lib/cuker/gherkin_reporter.rb +85 -0
  18. data/lib/cuker/gherkin_ripper.rb +67 -0
  19. data/lib/cuker/gp.rb +82 -0
  20. data/lib/cuker/helper/file_helper.rb +14 -0
  21. data/lib/cuker/helper/gherkin_helper.rb +28 -0
  22. data/lib/cuker/high.rb +57 -0
  23. data/lib/cuker/log_utils.rb +88 -0
  24. data/lib/cuker/models/model_try.rb +30 -0
  25. data/lib/cuker/models/models_forming.rb +65 -0
  26. data/lib/cuker/models/models_ready.rb +132 -0
  27. data/lib/cuker/models/state.rb +3 -0
  28. data/lib/cuker/state/in_background.rb +0 -0
  29. data/lib/cuker/state/in_comment.rb +3 -0
  30. data/lib/cuker/state/in_feature.rb +0 -0
  31. data/lib/cuker/state/in_scenario.rb +0 -0
  32. data/lib/cuker/state/in_scenario_outline.rb +0 -0
  33. data/lib/cuker/state/in_table.rb +0 -0
  34. data/lib/cuker/state/in_tag.rb +0 -0
  35. data/lib/cuker/version.rb +3 -0
  36. data/lib/cuker/writer_helper/_interfact.rb +7 -0
  37. data/lib/cuker/writer_helper/abstract_model.rb +37 -0
  38. data/lib/cuker/writer_helper/abstract_writer.rb +77 -0
  39. data/lib/cuker/writer_helper/csv_model.rb +148 -0
  40. data/lib/cuker/writer_helper/csv_writer.rb +59 -0
  41. data/lib/cuker/writer_helper/jira_model.rb +174 -0
  42. data/lib/cuker/writer_helper/jira_writer.rb +55 -0
  43. data/lib/cuker/writer_helper/ruby_x_l_writer.rb +32 -0
  44. data/lib/cuker/writer_helper/title.rb +14 -0
  45. metadata +129 -0
@@ -0,0 +1,3 @@
1
+ class State
2
+
3
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ class InComment < State
2
+
3
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ module Cuker
2
+ VERSION = "0.3.15"
3
+ end
@@ -0,0 +1,7 @@
1
+ module Interface
2
+ def method(name)
3
+ define_method(name) {|*args|
4
+ raise NotImplementedError.new("implemented interface method: '#{name}'")
5
+ }
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ module IModel
2
+ extend Interface
3
+ method :initialize
4
+ method :write_title
5
+ method :write_new_row
6
+
7
+ method :make_file
8
+ method :write_new_sheet
9
+ end
10
+
11
+
12
+ class AbstractModel
13
+ include LoggerSetup
14
+
15
+ # @return [Array] writable rows of title
16
+ # Defaults to []
17
+ attr_accessor :title
18
+
19
+ # @return [Array] writable array of rows of data
20
+ # Defaults to []
21
+ attr_accessor :data
22
+
23
+ def initialize _model_input = []
24
+ init_logger
25
+ @title = []
26
+ @data = []
27
+ end
28
+
29
+ def get_values_ary ary_of_hshs
30
+ ary_of_hshs.map {|hsh| hsh.values}.flatten
31
+ end
32
+
33
+ def get_keys_ary ary_of_hshs
34
+ ary_of_hshs.map {|hsh| hsh.keys}.flatten
35
+ end
36
+
37
+ end
@@ -0,0 +1,77 @@
1
+ module IWriter
2
+ extend Interface
3
+ method :initialize
4
+ method :write_title
5
+ method :write_new_row
6
+
7
+ method :make_file
8
+ method :write_new_sheet
9
+ end
10
+
11
+ class AbstractWriter
12
+ include IWriter
13
+ include LoggerSetup
14
+
15
+ NoNewFileMadeError = Class.new IOError
16
+
17
+ attr_accessor :ext
18
+ attr_accessor :sheets, :active_sheet
19
+ attr_reader :out_dir
20
+
21
+ def initialize
22
+ init_logger
23
+ # @out_dir = output_path
24
+ # FileUtils.mkdir_p(output_path) unless Dir.exist? output_path
25
+ @log.debug "initing AbstractWriter"
26
+ @active_sheet = nil
27
+ @sheets = {}
28
+ end
29
+
30
+ def write_title data
31
+ raise_unless_active_loc data
32
+ end
33
+
34
+ def write_new_row data
35
+ raise_unless_active_loc data
36
+ end
37
+
38
+ def raise_unless_active_loc data
39
+ raise NoNewFileMadeError.new "Please run 'make_file' before trying to write: '#{data}'" if @active_sheet.nil?
40
+ end
41
+
42
+ def make_new_sheet name = nil
43
+ file_name = name.nil? ? "Sheet_#{@sheets.size + 1}" : name
44
+ @log.debug "make a new abstract sheet: #{file_name}"
45
+ file_name
46
+ # todo: file name collision handle
47
+ end
48
+
49
+ def make_file name
50
+ @log.debug "make a new abstract file: #{name}"
51
+ end
52
+ end
53
+
54
+ class AbstractSheet
55
+ include LoggerSetup
56
+ attr_accessor :name, :rows
57
+
58
+ def initialize name
59
+ init_logger
60
+ @name = name
61
+ @rows = []
62
+ end
63
+
64
+ def current_row
65
+ @rows.size + 1
66
+ end
67
+
68
+ def add_row ary
69
+ @log.error "argument not an array.. instead is a '#{ary.class}' -> '#{ary}'" unless ary.is_a? Array
70
+ @rows << ary
71
+ end
72
+
73
+ # @return ary of rows
74
+ def read_rows
75
+ @rows
76
+ end
77
+ end
@@ -0,0 +1,148 @@
1
+ require_relative 'abstract_writer'
2
+
3
+ module Cuker
4
+ class CsvModel < AbstractModel
5
+ include LoggerSetup
6
+
7
+ attr_accessor :special_tag_list
8
+
9
+ def initialize ast_map
10
+ super
11
+ @log.trace "initing #{self.class}"
12
+ @log.debug "has #{ast_map.size} items"
13
+
14
+ @asts = ast_map
15
+
16
+ @order = make_order
17
+ @title = make_title @order
18
+ @data = make_rows
19
+ end
20
+
21
+ private
22
+
23
+ def make_order
24
+ [
25
+ {:counter => "Sl.No"},
26
+ {:s_type => "Type"},
27
+ {:s_title => "Title"},
28
+ # {:tags => special_tag_titles},
29
+ {:feature_title => "Feature"},
30
+ {:file_s_num => "S.no"},
31
+ {:file_name => "File"},
32
+ {:other_tags => "Tags"},
33
+ ]
34
+ # todo: make title order reorderable
35
+ # todo: tag based reordering
36
+ end
37
+
38
+ def special_tag_titles
39
+ @special_tag_titles ||= get_values_ary @special_tag_list if @special_tag_list
40
+ end
41
+
42
+ def special_tag_lookup
43
+ @special_tag_lookup ||= get_keys_ary @special_tag_list if @special_tag_list
44
+ end
45
+
46
+ def make_title order
47
+ get_values_ary order
48
+ end
49
+
50
+ def make_rows
51
+ if @asts.nil? or @asts.empty?
52
+ @log.warn "No asts to parse!"
53
+ return []
54
+ end
55
+
56
+ total_counter = 0
57
+ res = []
58
+ @asts.each do |file_path, ast|
59
+ @file_path = file_path
60
+ in_feat_counter = 0
61
+ if ast[:type] == :GherkinDocument
62
+ in_feature(ast) do |feat_tags, feat_title, feat_item|
63
+ in_item(feat_item) do |tags, title, type|
64
+ all_tags = (feat_tags.to_set | tags.to_set).to_a # union
65
+ special_tags, other_tags = filter_special_tags all_tags
66
+ row_hsh = {
67
+ :counter => total_counter += 1,
68
+ :s_type => type,
69
+ :s_title => title,
70
+ :feature_title => feat_title,
71
+ :file_s_num => in_feat_counter += 1,
72
+ :file_name => @file_path,
73
+ :other_tags => other_tags.join(', '),
74
+
75
+ :tags => special_tags
76
+ }
77
+ row_ary = []
78
+ get_keys_ary(@order).each {|k| row_ary << row_hsh[k]}
79
+ # todo: a lot of flattening?
80
+ res << row_ary
81
+ end
82
+ end
83
+ end
84
+ end
85
+ @file_path = nil
86
+ res
87
+ end
88
+
89
+ def filter_special_tags(all_tags)
90
+ return [[],all_tags] unless special_tag_lookup
91
+ ignore_list = all_tags - special_tag_lookup
92
+ select_list = all_tags - ignore_list
93
+ [select_list, ignore_list]
94
+ end
95
+
96
+ def in_feature(hsh)
97
+ if hsh[:feature]
98
+ feat = hsh[:feature]
99
+ feat_tags = get_tags feat
100
+ feat_title = name_merge feat
101
+ children = feat[:children]
102
+ children.each do |item|
103
+ yield feat_tags, feat_title, item
104
+ end
105
+ else
106
+ @log.warn "No Features found in file @ #{@file_path}"
107
+ end
108
+ end
109
+
110
+ def in_item(item)
111
+ item_title = name_merge item
112
+ tags = get_tags item
113
+ if item[:type] == :Background
114
+ @log.debug "Skipping BG"
115
+ elsif item[:type] == :Scenario
116
+ yield tags, item_title, "S"
117
+ elsif item[:type] == :ScenarioOutline
118
+ yield tags, item_title, "SO"
119
+ else
120
+ @log.warn "Unknown type '#{item[:type]}' found in file @ #{@file_path}"
121
+ end
122
+ end
123
+
124
+ def get_tags(hsh)
125
+ if hsh[:tags] and hsh[:tags].any?
126
+ hsh[:tags].map {|tag| tag[:name]}
127
+ else
128
+ @log.warn "No Tags found in #{hsh[:keyword]} @ #{@file_path}"
129
+ []
130
+ end
131
+ end
132
+
133
+ def name_merge hsh
134
+ str = ""
135
+ @log.warn "name merge for #{hsh}"
136
+ str += hsh[:name].strip.force_encoding("UTF-8") if hsh[:name]
137
+ str += " - #{hsh[:description].strip.force_encoding("UTF-8")}" if hsh[:description]
138
+ str
139
+ end
140
+
141
+ end
142
+
143
+ class Identifier
144
+ attr_accessor :name, :title, :pattern
145
+ end
146
+
147
+ end
148
+
@@ -0,0 +1,59 @@
1
+ require_relative 'abstract_writer'
2
+
3
+ class CsvWriter < AbstractWriter
4
+ def initialize
5
+ @ext = '.csv'
6
+ super
7
+ @log.debug "initing #{self.class}"
8
+ end
9
+
10
+ def write_title title_ary
11
+ super title_ary
12
+ @log.debug "csv write title"
13
+ @active_sheet.add_row title_ary
14
+ end
15
+
16
+ def write_new_row row_ary
17
+ super row_ary
18
+ @log.debug "csv write row: #{row_ary}"
19
+ @active_sheet.add_row row_ary
20
+ end
21
+
22
+ def make_new_sheet name
23
+ @log.debug "csv make new sheet"
24
+ path = super name
25
+ @sheets[path] = CsvSheet.new path, @ext
26
+ @active_sheet = @sheets[path]
27
+ end
28
+
29
+ def make_file name
30
+ super name
31
+ make_new_sheet name
32
+ end
33
+ end
34
+
35
+ require 'csv'
36
+ # == CSV Sheet
37
+ # extends sheet to give csv read/write-ability
38
+ # {file:https://docs.ruby-lang.org/en/2.1.0/CSV.html CSV usage documentation}
39
+
40
+ class CsvSheet < AbstractSheet
41
+ def initialize path, ext
42
+ file_name = "#{path}#{ext}"
43
+ super file_name
44
+ @csv_sheet = CSV.open(file_name, "wb")
45
+ end
46
+
47
+ def add_row row_ary
48
+ super row_ary
49
+ # @csv_sheet << ary
50
+ CSV.open(@name, "ab") do |csv|
51
+ csv << row_ary
52
+ end
53
+ end
54
+
55
+ # @return ary of rows
56
+ def read_rows
57
+ @rows = CSV.read(@name)
58
+ end
59
+ end
@@ -0,0 +1,174 @@
1
+ require_relative 'abstract_writer'
2
+ module Cuker
3
+ class JiraModel < AbstractModel
4
+ include LoggerSetup
5
+
6
+ def initialize ast_map
7
+ super
8
+ @log.trace "initing #{self.class}"
9
+ @log.debug "has #{ast_map.size} items"
10
+
11
+ @asts = ast_map
12
+
13
+ @order = make_order
14
+ title = make_title @order
15
+ data = make_rows
16
+
17
+ @title = [surround(title, '||')]
18
+ @data = data.join("\n").split("\n")
19
+ end
20
+
21
+ private
22
+
23
+ def make_order
24
+ [
25
+ # {:counter => "Sl.No"},
26
+ {:s_num => "Scen ID"},
27
+ {:s_content => "Scenario"},
28
+ {:item => "Result"},
29
+ ]
30
+ # # todo: make title order reorderable
31
+ # # todo: tag based reordering
32
+ end
33
+
34
+ def make_title order
35
+ get_values_ary order
36
+ end
37
+
38
+ def make_rows
39
+ if @asts.nil? or @asts.empty?
40
+ @log.warn "No asts to parse!"
41
+ return []
42
+ end
43
+
44
+ feat_counter = 1
45
+ res = []
46
+ @asts.each do |file_path, ast|
47
+ @file_path = file_path
48
+ in_feat_counter = 0
49
+ if ast[:type] == :GherkinDocument
50
+ in_feature(ast) do |feat_tags, feat_title, feat_item|
51
+ in_item(feat_item) do |tags, title, content|
52
+ row_hsh = {
53
+ :s_num => "#{feat_counter}.#{in_feat_counter += 1}",
54
+ :s_content => content.join("\n"),
55
+ :item => "|(/)|",
56
+ }
57
+ row_ary = []
58
+ get_keys_ary(@order).each {|k| row_ary << row_hsh[k]}
59
+ res << surround(row_ary, '|')
60
+ end
61
+ end
62
+ end
63
+ feat_counter += 1
64
+ end
65
+ @file_path = nil
66
+ res
67
+ end
68
+
69
+ def in_feature(hsh)
70
+ if hsh[:feature]
71
+ feat = hsh[:feature]
72
+ feat_tags = get_tags feat
73
+ feat_title = name_merge feat
74
+ children = feat[:children]
75
+ children.each do |item|
76
+ yield feat_tags, feat_title, item
77
+ end
78
+ else
79
+ @log.warn "No Features found in file @ #{@file_path}"
80
+ end
81
+ end
82
+
83
+ def in_item(item)
84
+ item_title = name_merge item
85
+ tags = get_tags item
86
+ @bg_steps ||= []
87
+ if item[:type] == :Background
88
+ yield tags, item_title, get_steps(item)
89
+ # todo: think about handling this
90
+ elsif item[:type] == :Scenario
91
+ yield tags, item_title, get_steps(item)
92
+ @bg_steps = nil
93
+ elsif item[:type] == :ScenarioOutline
94
+ yield tags, item_title, get_steps(item)
95
+ @bg_steps = nil
96
+ else
97
+ @log.warn "Unknown type '#{item[:type]}' found in file @ #{@file_path}"
98
+ end
99
+ end
100
+
101
+ def get_steps(hsh)
102
+ if hsh[:steps] and hsh[:steps].any?
103
+ content = []
104
+ steps = hsh[:steps]
105
+ in_step(steps) do |step|
106
+ content += step
107
+ end
108
+ content
109
+ else
110
+ @log.warn "No Tags found in #{hsh[:keyword]} @ #{@file_path}"
111
+ []
112
+ end
113
+ end
114
+
115
+ def in_step(steps)
116
+ # todo: table
117
+ steps.each do |step|
118
+ if step[:type] == :Step
119
+ step_ary = []
120
+ step_ary << [
121
+ step[:keyword].strip,
122
+ step[:text].strip
123
+ ].join(" ")
124
+ step_ary += in_step_args(step[:argument]) if step[:argument]
125
+ # todo: padding as needed
126
+ yield step_ary
127
+ else
128
+ @log.warn "Unknown type '#{item[:type]}' found in file @ #{@file_path}"
129
+ end
130
+ end
131
+ end
132
+
133
+ def in_step_args arg
134
+ if arg[:type] == :DataTable
135
+ res = []
136
+ arg[:rows].each_with_index do |row, i|
137
+ sep = i == 0 ? '||' : '|'
138
+ res << surround(row[:cells].map {|hsh| hsh[:value]}, sep)
139
+ end
140
+ return res
141
+ elsif arg[:type] == :DocString
142
+ # todo: handle if needed
143
+ else
144
+ @log.warn "Unknown type '#{arg[:type]}' found in file @ #{@file_path}"
145
+ end
146
+ []
147
+ end
148
+
149
+ def get_tags(hsh)
150
+ if hsh[:tags] and hsh[:tags].any?
151
+ hsh[:tags].map {|tag| tag[:name]}
152
+ else
153
+ @log.warn "No Tags found in #{hsh[:keyword]} @ #{@file_path}"
154
+ []
155
+ end
156
+ end
157
+
158
+ def union feat_tags, tags
159
+ (feat_tags.to_set | tags.to_set).to_a # union
160
+ end
161
+
162
+ def surround ary, sep
163
+ "#{sep}#{ary.join(sep)}#{sep}"
164
+ end
165
+
166
+ def name_merge hsh
167
+ str = ""
168
+ @log.warn hsh
169
+ str += hsh[:name].strip.force_encoding("UTF-8") if hsh[:name]
170
+ str += hsh[:description].strip.force_encoding("UTF-8") if hsh[:description]
171
+ str
172
+ end
173
+ end
174
+ end