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.
- checksums.yaml +7 -0
- data/.gitignore +71 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +16 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cuker.gemspec +43 -0
- data/lib/cuker.rb +7 -0
- data/lib/cuker/gherkin_lexer.rb +33 -0
- data/lib/cuker/gherkin_parser.rb +23 -0
- data/lib/cuker/gherkin_reporter.rb +85 -0
- data/lib/cuker/gherkin_ripper.rb +67 -0
- data/lib/cuker/gp.rb +82 -0
- data/lib/cuker/helper/file_helper.rb +14 -0
- data/lib/cuker/helper/gherkin_helper.rb +28 -0
- data/lib/cuker/high.rb +57 -0
- data/lib/cuker/log_utils.rb +88 -0
- data/lib/cuker/models/model_try.rb +30 -0
- data/lib/cuker/models/models_forming.rb +65 -0
- data/lib/cuker/models/models_ready.rb +132 -0
- data/lib/cuker/models/state.rb +3 -0
- data/lib/cuker/state/in_background.rb +0 -0
- data/lib/cuker/state/in_comment.rb +3 -0
- data/lib/cuker/state/in_feature.rb +0 -0
- data/lib/cuker/state/in_scenario.rb +0 -0
- data/lib/cuker/state/in_scenario_outline.rb +0 -0
- data/lib/cuker/state/in_table.rb +0 -0
- data/lib/cuker/state/in_tag.rb +0 -0
- data/lib/cuker/version.rb +3 -0
- data/lib/cuker/writer_helper/_interfact.rb +7 -0
- data/lib/cuker/writer_helper/abstract_model.rb +37 -0
- data/lib/cuker/writer_helper/abstract_writer.rb +77 -0
- data/lib/cuker/writer_helper/csv_model.rb +148 -0
- data/lib/cuker/writer_helper/csv_writer.rb +59 -0
- data/lib/cuker/writer_helper/jira_model.rb +174 -0
- data/lib/cuker/writer_helper/jira_writer.rb +55 -0
- data/lib/cuker/writer_helper/ruby_x_l_writer.rb +32 -0
- data/lib/cuker/writer_helper/title.rb +14 -0
- metadata +129 -0
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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
|