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,82 @@
1
+ require 'thor'
2
+
3
+ require 'require_all'
4
+ # require_all 'lib/cuker/**/*.rb'
5
+ # require_all 'lib/cuker/*.rb'
6
+ require_rel '**/*.rb'
7
+ require_rel '*.rb'
8
+
9
+
10
+ module Cuker
11
+ module GPHelper
12
+ def self.dash_print(ary)
13
+ # ary.each {|x| puts " - '#{x}'"}
14
+ end
15
+ end
16
+
17
+ class GherkinParserCmd < Thor
18
+ include LoggerSetup
19
+
20
+ GPTOOL = GherkinParser.new
21
+ PRESET_LOCS = ['*', './*']
22
+
23
+ desc "gp LOCATION", "parse all *.feature files in the given LOCATION"
24
+
25
+ def gp loc = "../jira*/**/*", file_name = nil
26
+ init
27
+ @log.warn "running GPTOOL @ #{loc}"
28
+ end
29
+
30
+ desc "gpp", "parse all *.feature files in the preset locations: \n#{GPHelper.dash_print PRESET_LOCS}"
31
+
32
+ def gpp
33
+ init
34
+ @log.warn "running GPTOOL @ #{PRESET_LOCS}"
35
+ end
36
+
37
+
38
+ desc "gpr FEATURE_PATH REPORT_PATH [REPORT_FILE_NAME]",
39
+ "reports parsed results into REPORT_FILE_NAME for all *.feature files in the given LOCATION"
40
+
41
+ def gpr report_file_name = 'sample_report', feat_path = "../", report_path = "reports"
42
+ init
43
+ @log.warn "running GPTOOL @ '#{feat_path}' => '#{report_path}' '#{report_file_name}.csv' "
44
+
45
+ report_path = File.join report_path, LOG_TIME_TODAY
46
+ @log.info Dir.pwd
47
+
48
+ gr = GherkinRipper.new feat_path
49
+ ast_map = gr.ast_map
50
+ csv_model = CsvModel.new ast_map
51
+ csv_writer = CsvWriter.new
52
+ grr = GherkinReporter.new csv_writer, csv_model, report_path, report_file_name
53
+ grr.write
54
+ end
55
+
56
+ desc "gpj FEATURE_PATH REPORT_PATH [REPORT_FILE_NAME]",
57
+ "reports parsed results into REPORT_FILE_NAME for all *.feature files in the given LOCATION"
58
+
59
+ def gpj feat_path = "spec/cuker_spec/testdata", report_path = "reports/#{LOG_TIME_TODAY}", report_file_name = 'sample_report'
60
+ init
61
+ @log.warn "running GPTOOL @ '#{feat_path}' => '#{report_path}' '#{report_file_name}.csv' "
62
+
63
+ @log.info Dir.pwd
64
+
65
+ gr = GherkinRipper.new feat_path
66
+ ast_map = gr.ast_map
67
+ csv_model = JiraModel.new ast_map
68
+ csv_writer = JiraWriter.new
69
+ grr = GherkinReporter.new csv_writer, csv_model, report_path, report_file_name
70
+ grr.write
71
+ end
72
+
73
+
74
+ private
75
+
76
+ def init
77
+ init_logger :warn
78
+ end
79
+ end
80
+
81
+ # GherkinParserCmd.start(ARGV)
82
+ end
@@ -0,0 +1,14 @@
1
+ module FileHelper
2
+ def self.get_files path, target_pattern, ignore_patterns = nil
3
+ Dir.glob("#{path}/**/*#{target_pattern}").select {|x| x !~ ignore_patterns}
4
+ end
5
+
6
+ def self.get_file file_name, target_pattern, ignore_patterns = nil
7
+ Dir.glob("*#{file_name}*#{target_pattern}").select {|x| x !~ ignore_patterns}
8
+ end
9
+
10
+ def self.file_path path, file_name
11
+ FileUtils.mkdir_p(path) unless Dir.exist? path
12
+ File.join(path, file_name)
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ require 'gherkin/parser'
2
+ require 'gherkin/token_scanner'
3
+ require 'gherkin/token_matcher'
4
+ require 'gherkin/ast_builder'
5
+ require 'gherkin/errors'
6
+
7
+ module GherkinHelper
8
+ include Gherkin
9
+
10
+ def parse_handle(file_name)
11
+ begin
12
+ yield
13
+ rescue Gherkin::ParserError => e
14
+ msg = "unable to read #{file_name}..\n Issues:\n#{error_digest e}"
15
+ @log.error msg
16
+ #todo: handle issues promot to user on cli
17
+ end
18
+ end
19
+
20
+ def error_digest(e)
21
+ # todo: maybe give friendly error promots?
22
+ e.errors.map do |err|
23
+ err.message
24
+ .gsub(/^\((\d+):(\d+)\):/, ' ( line \1 : char \2 ) :')
25
+ # .gsub(' : ', "\t:\t") # not so pretty, but if needed
26
+ end.join "\n"
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ # require 'highline'
2
+ #
3
+ # # Basic usage
4
+ #
5
+ # cli = HighLine.new
6
+ # answer = cli.ask "What do you think?"
7
+ # puts "You have answered: #{answer}"
8
+ #
9
+ #
10
+ # # Default answer
11
+ #
12
+ # cli.ask("Company? ") { |q| q.default = "none" }
13
+ #
14
+ #
15
+ # # Validation
16
+ #
17
+ # cli.ask("Age? ", Integer) { |q| q.in = 0..105 }
18
+ # cli.ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
19
+ #
20
+ #
21
+ # # Type conversion for answers:
22
+ #
23
+ # cli.ask("Birthday? ", Date)
24
+ # cli.ask("Interests? (comma sep list) ", lambda { |str| str.split(/,\s*/) })
25
+ #
26
+ #
27
+ # # Reading passwords:
28
+ #
29
+ # cli.ask("Enter your password: ") { |q| q.echo = false }
30
+ # cli.ask("Enter your password: ") { |q| q.echo = "x" }
31
+ #
32
+ #
33
+ # # ERb based output (with HighLine's ANSI color tools):
34
+ #
35
+ # cli.say("This should be <%= color('bold', BOLD) %>!")
36
+ #
37
+ #
38
+ # # Menus:
39
+ #
40
+ # cli.choose do |menu|
41
+ # menu.prompt = "Please choose your favorite programming language? "
42
+ # menu.choice(:ruby) { cli.say("Good choice!") }
43
+ # menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
44
+ # menu.default = :ruby
45
+ # end
46
+ #
47
+ # ## Using colored indices on Menus
48
+ #
49
+ # HighLine::Menu.index_color = :rgb_77bbff # set default index color
50
+ #
51
+ # cli.choose do |menu|
52
+ # menu.index_color = :rgb_999999 # override default color of index
53
+ # # you can also use constants like :blue
54
+ # menu.prompt = "Please choose your favorite programming language? "
55
+ # menu.choice(:ruby) { cli.say("Good choice!") }
56
+ # menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
57
+ # end
@@ -0,0 +1,88 @@
1
+ # $LOAD_PATH << File.expand_path("#{File.dirname(__FILE__)}")
2
+ require 'logging'
3
+
4
+ # Logger params
5
+ Logging.init :trace, :debug, :info, :warn, :error, :fatal
6
+
7
+ # Custom colour set
8
+ Logging.color_scheme('my_bright',
9
+ :levels => {
10
+ :trace => :white,
11
+ :debug => :blue,
12
+ :info => :green,
13
+ :warn => :yellow,
14
+ :error => :red,
15
+ :fatal => [:black, :on_red]
16
+ },
17
+ :date => :blue,
18
+ :logger => :cyan,
19
+ :message => :white
20
+ )
21
+
22
+ # https://www.rubydoc.info/gems/logging/Logging/Layouts/Pattern/FormatMethodBuilder
23
+
24
+ LOG_PATTERN_SIMPLE = "[%d] %-5l %m\n"
25
+ LOG_PATTERN_WITH_CLASS = "[%d] %-5l %c: %m\n"
26
+ LOG_PATTERN_WITH_METHODS = "[%d] %-5l %c: %M: %m\n" # need to get this to work
27
+ LOG_PATTERN_WITH_ALL = "[%d] %-5l %c: %M: %h: %p: %r: %T: %t: %F: %L: %M: %x\n"
28
+
29
+
30
+ TIMESTAMP_PATTERN = "%Y-%m-%d %H:%M:%S.%L"
31
+ LOG_TIME_TODAY = Time.now.strftime("%Y-%m-%d")
32
+ LOG_TIME_NOW = Time.now.strftime("%Y-%m-%d_%H-%M-%S")
33
+
34
+ LOG_LOC = "./logs"
35
+ LOG_FILE = "log_#{LOG_TIME_TODAY}.log"
36
+ LOG_FILE_PATH = File.join(LOG_LOC, LOG_FILE)
37
+
38
+ LOG_STDOUT = 'stdout'
39
+
40
+ Dir.mkdir(LOG_LOC) unless Dir.exists? LOG_LOC
41
+
42
+ module LoggerSetup
43
+ def self.reset_appender_log_levels stdout_level = :info, file_level = :trace
44
+
45
+ # Stdout appender
46
+ Logging.appenders.stdout(LOG_STDOUT,
47
+ # level: :info, # a different log level to your file appender
48
+ level: stdout_level, # a different log level to your file appender
49
+ layout: Logging.layouts.pattern(
50
+ pattern: LOG_PATTERN_WITH_CLASS,
51
+ color_scheme: 'my_bright', # best not to use color_schemes on file loggers
52
+ date_pattern: TIMESTAMP_PATTERN))
53
+
54
+ # File appender
55
+ Logging.appenders.file(LOG_FILE_PATH,
56
+ # level: :debug, # or your custom lowest level init-ed
57
+ level: file_level, # or your custom lowest level init-ed
58
+ layout: Logging.layouts.pattern(
59
+ pattern: LOG_PATTERN_WITH_CLASS,
60
+ # color_scheme: 'my_bright', # best not to use color_schemes on file loggers
61
+ date_pattern: TIMESTAMP_PATTERN),
62
+ # truncate: true, # if you want to clear old log information
63
+ # age: 5 * 60, # feel free to play around with these
64
+ roll_by: :date # for rolling logs if you want to change files periodically
65
+ )
66
+
67
+ end
68
+ end
69
+
70
+ # to restore defaults, run
71
+ # LoggerSetup.reset_appender_log_levels # stdout_level = :info, file_level = :debug
72
+ LoggerSetup.reset_appender_log_levels :error, :trace
73
+
74
+
75
+ # sample logger setup module
76
+ module LoggerSetup
77
+ attr_reader :log
78
+
79
+ def init_logger(level = nil)
80
+ @log = Logging.logger[self]
81
+ @log.level = level || :debug # your lowest level
82
+ @log.add_appenders(
83
+ LOG_STDOUT,
84
+ LOG_FILE_PATH
85
+ )
86
+ @log
87
+ end
88
+ end
@@ -0,0 +1,30 @@
1
+ # class Item
2
+ #
3
+ # end
4
+ #
5
+ # class Collection
6
+ # attr_accessor :tags
7
+ # attr_accessor :title, :comments
8
+ # attr_accessor :items
9
+ # end
10
+ #
11
+ # class Feature < Collection
12
+ # attr_accessor :background
13
+ # end
14
+ #
15
+ # class Background < Collection
16
+ #
17
+ # end
18
+ #
19
+ # class Scenario < Collection
20
+ #
21
+ # end
22
+ #
23
+ # class ScenarioOutline < Scenario
24
+ # attr_accessor :examples
25
+ # end
26
+ #
27
+ # class Step < Item
28
+ # attr_accessor :keyword, :line
29
+ # attr_accessor :table # optional
30
+ # end
@@ -0,0 +1,65 @@
1
+ # class Item
2
+ # attr_accessor :content
3
+ # end
4
+ #
5
+ # class Step < Item
6
+ # attr_accessor :keyword, :line
7
+ # attr_accessor :table # optional
8
+ # end
9
+ #
10
+ # class Comment < Item
11
+ #
12
+ # end
13
+ #
14
+ # class InlineComment < Comment
15
+ #
16
+ # end
17
+ #
18
+ # class Tag < Item
19
+ #
20
+ # end
21
+ #
22
+ # class Row < Item
23
+ #
24
+ # end
25
+ #
26
+ # class Collection < Item
27
+ # attr_accessor :items
28
+ # end
29
+ #
30
+ # class Tags < Collection
31
+ #
32
+ # end
33
+ #
34
+ # class Table < Collection
35
+ #
36
+ # end
37
+ #
38
+ # class Example < Table
39
+ #
40
+ # end
41
+ #
42
+ # class SimpleGherkinCollection < Collection
43
+ # attr_accessor :title, :comments
44
+ # end
45
+ #
46
+ # class Background < SimpleGherkinCollection
47
+ #
48
+ # end
49
+ #
50
+ # class TaggedGherkinCollection < SimpleGherkinCollection
51
+ # attr_accessor :tags
52
+ # end
53
+ #
54
+ # class Feature < TaggedGherkinCollection
55
+ # attr_accessor :background
56
+ # # attr_accessor :collections
57
+ # end
58
+ #
59
+ # class Scenario < TaggedGherkinCollection
60
+ #
61
+ # end
62
+ #
63
+ # class ScenarioOutline < Scenario
64
+ # attr_accessor :examples
65
+ # end
@@ -0,0 +1,132 @@
1
+ class Item
2
+ attr_accessor :content
3
+
4
+ def initialize content_str
5
+ @content = content_str
6
+ end
7
+
8
+ def to_s
9
+ @content
10
+ end
11
+ end
12
+
13
+ class Step < Item
14
+ attr_accessor :keyword, :line
15
+ attr_accessor :table # optional
16
+ end
17
+
18
+ class Comment < Item
19
+
20
+ end
21
+
22
+ class InlineComment < Comment
23
+
24
+ end
25
+
26
+ class Tag < Item
27
+
28
+ end
29
+
30
+ class TableRow < Item
31
+
32
+ end
33
+
34
+ class Collection < Item
35
+ attr_accessor :items
36
+ attr_reader :keyword
37
+
38
+ def initialize content_str
39
+ super content_str
40
+ @items = []
41
+ end
42
+
43
+ def to_s
44
+ ([super] + items.map(&:to_s)).join "\n"
45
+ end
46
+ end
47
+
48
+ class Tags < Collection
49
+
50
+ end
51
+
52
+ class Table < Collection
53
+ attr_accessor :title_row, :table_rows
54
+ def initialize content_str
55
+ super content_str
56
+ @table_rows = []
57
+ @title_row = @items[0]
58
+ @table_rows = @items[1..-1]
59
+ end
60
+
61
+ end
62
+
63
+ class Examples < Table
64
+
65
+ end
66
+
67
+ class SimpleGherkinCollection < Collection
68
+ attr_accessor :title, :comments
69
+
70
+ def initialize content_str, keyword
71
+ super content_str
72
+ @title = parse_title content_str, keyword
73
+ end
74
+
75
+ def parse_title content, keyword
76
+ match = content[/^\s*#{keyword}(.*)$/, 1]
77
+ warn "no matches for '#{keyword}' in '#{content}'" unless match
78
+ match
79
+ end
80
+ end
81
+
82
+ class Background < SimpleGherkinCollection
83
+ def initialize content_str
84
+ @keyword = "Background:"
85
+ super content_str, keyword
86
+ end
87
+ end
88
+
89
+ class TaggedGherkinCollection < SimpleGherkinCollection
90
+ attr_accessor :tags
91
+
92
+ end
93
+
94
+ class Feature < TaggedGherkinCollection
95
+ attr_accessor :background
96
+
97
+ def initialize content_str
98
+ @keyword = "Feature:"
99
+ super content_str, keyword
100
+ #todo: think about item ordering
101
+ end
102
+
103
+ def comments= content
104
+ @items << content
105
+ @comments = content
106
+ end
107
+
108
+ def tags= content
109
+ @items << content
110
+ @tags = content
111
+ end
112
+
113
+ end
114
+
115
+ class Scenario < TaggedGherkinCollection
116
+ attr_accessor :steps
117
+
118
+ def initialize content_str, keyword = "Scenario:"
119
+ @steps = []
120
+ @keyword = keyword
121
+ super content_str, @keyword
122
+ end
123
+ end
124
+
125
+ class ScenarioOutline < Scenario
126
+ attr_accessor :examples
127
+
128
+ def initialize content_str, keyword = "Scenario Outline:"
129
+ @keyword = keyword
130
+ super content_str, @keyword
131
+ end
132
+ end