hiptest-publisher 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d7e6e951a54117005ef23edde89a7b774c0e0406
4
- data.tar.gz: 8ac2f19e6510ee971d2dcbeb3d3fb4944e97e8d8
3
+ metadata.gz: cb3bcbe735b896844146dc4141ee87a7a8edd184
4
+ data.tar.gz: 39259e0186e04ca5abf63ff9933a926a646301d8
5
5
  SHA512:
6
- metadata.gz: 8ecb02311bb95c630d339d286f664b6cfe373f038a2cabfd8637e41176a167b479ee9316f917fd75d5521853b2440e4affe8d162341584dc2851bd9f6e0407ad
7
- data.tar.gz: fc29b7ef057e6b543bd122e1606d1210c638a6068559a7bf494a71a43446e5c9a5196b0f95991bee35acbb2f4ac2d6a36439cbd1a061f15adf6a652268a52420
6
+ metadata.gz: 611f35d620f0545a61257915c46d767dc44d5c7575c850ba17ae3acd5b0cd04a88ca8df0b90aa87e42e7990d0157a55d571f5009a7d790680d3160258822daf1
7
+ data.tar.gz: 7a8f4f5489980971836a49e68116a4e13712290d4c7d3c6cc289ee25cd842fdc5c4fb42a746b38f3cd242c9ed80c4ff0dcfad8c9ec1044992c23d6fef8d71505
@@ -1,5 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ # Use the following command to run hiptest-publisher and test your changes:
4
+ #
5
+ # bundle exec ruby -I lib bin/hiptest-publisher
6
+ #
7
+ # You can define an alias for this command and run it as if you were running
8
+ # the gem.
9
+ #
10
+ # alias hiptest-publisher='bundle exec ruby -I lib bin/hiptest-publisher'
11
+ # hiptest-publisher -v --token=1234567890
12
+ #
13
+
3
14
  begin
4
15
  require 'rubygems'
5
16
  gem 'hiptest-publisher'
@@ -7,5 +18,6 @@ rescue LoadError
7
18
  end
8
19
 
9
20
  require 'hiptest-publisher'
21
+ require 'pry'
10
22
 
11
23
  Hiptest::Publisher.new(ARGV).run
@@ -228,6 +228,7 @@ module Hiptest
228
228
  Hiptest::Nodes::ParentAdder.add(@project)
229
229
  Hiptest::Nodes::ParameterTypeAdder.add(@project)
230
230
  Hiptest::DefaultArgumentAdder.add(@project)
231
+ Hiptest::GherkinAdder.add(@project)
231
232
 
232
233
  unless @options.actionwords_only
233
234
  @options.leafless_export ? export_tests : export_scenarios
@@ -249,4 +250,4 @@ module Hiptest
249
250
  end
250
251
  end
251
252
  end
252
- end
253
+ end
@@ -0,0 +1,31 @@
1
+ module Hiptest
2
+ class ActionwordIndexer
3
+ def initialize(project)
4
+ @project = project
5
+ @indexed = {}
6
+ index_actionwords
7
+ end
8
+
9
+ def index_actionwords
10
+ @project.find_sub_nodes(Hiptest::Nodes::Actionword).each do |aw|
11
+ aw_name = aw.children[:name]
12
+ indexed_parameters = {}
13
+
14
+ aw.children[:parameters].map do |param|
15
+ param_name = param.children[:name]
16
+ indexed_parameters[param_name] = param.children[:default]
17
+ end
18
+
19
+ @indexed[aw_name] = {
20
+ :actionword => aw,
21
+ :parameters => indexed_parameters
22
+ }
23
+
24
+ end
25
+ end
26
+
27
+ def get_index(name)
28
+ @indexed[name]
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,4 @@
1
+ require 'hiptest-publisher/actionword_indexer'
1
2
  require 'hiptest-publisher/nodes'
2
3
 
3
4
  module Hiptest
@@ -30,34 +31,4 @@ module Hiptest
30
31
  end
31
32
  end
32
33
  end
33
-
34
- class ActionwordIndexer
35
- def initialize(project)
36
- @project = project
37
- @indexed = {}
38
- index_actionwords
39
- end
40
-
41
- def index_actionwords
42
- @project.find_sub_nodes(Hiptest::Nodes::Actionword).each do |aw|
43
- aw_name = aw.children[:name]
44
- indexed_parameters = {}
45
-
46
- aw.children[:parameters].map do |param|
47
- param_name = param.children[:name]
48
- indexed_parameters[param_name] = param.children[:default]
49
- end
50
-
51
- @indexed[aw_name] = {
52
- :actionword => aw,
53
- :parameters => indexed_parameters
54
- }
55
-
56
- end
57
- end
58
-
59
- def get_index(name)
60
- @indexed[name]
61
- end
62
- end
63
- end
34
+ end
@@ -0,0 +1,123 @@
1
+ require 'hiptest-publisher/actionword_indexer'
2
+ require 'hiptest-publisher/nodes'
3
+
4
+ module Hiptest
5
+ class GherkinAdder
6
+ def self.add(project)
7
+ GherkinAdder.new(project).update_calls
8
+ end
9
+
10
+ def initialize(project)
11
+ @project = project
12
+ @indexer = ActionwordIndexer.new(project)
13
+ end
14
+
15
+ def update_calls
16
+ @project.find_sub_nodes(Hiptest::Nodes::Call).each do |call|
17
+ call.children[:gherkin_text] ||= "#{annotation(call)} #{prettified(call)}"
18
+ if actionword = get_actionword(call)
19
+ actionword.children[:gherkin_annotation] ||= annotation(call)
20
+ actionword.children[:gherkin_pattern] ||= pattern(actionword)
21
+ end
22
+ end
23
+ end
24
+
25
+ def annotation(call)
26
+ if call.children[:annotation]
27
+ call.children[:annotation].capitalize
28
+ else
29
+ "Given"
30
+ end
31
+ end
32
+
33
+ def prettified(call)
34
+ all_arguments = all_valued_arguments_for(call)
35
+ inline_parameter_names = []
36
+
37
+ call_chunks = call.children[:actionword].split("\"", -1)
38
+ call_chunks.each_slice(2) do |text, inline_parameter_name|
39
+ if all_arguments.has_key?(inline_parameter_name)
40
+ inline_parameter_names << inline_parameter_name.clone
41
+ value = all_arguments[inline_parameter_name]
42
+ inline_parameter_name.replace(value)
43
+ end
44
+ end
45
+
46
+ missing_parameter_names = all_arguments.keys - inline_parameter_names
47
+
48
+ prettified = call_chunks.join("\"")
49
+ missing_parameter_names.each do |missing_parameter_name|
50
+ value = all_arguments[missing_parameter_name]
51
+ prettified << " \"#{value}\""
52
+ end
53
+ prettified
54
+ end
55
+
56
+ def pattern(actionword)
57
+ name = actionword.children[:name]
58
+ actionword_parameters = evaluated_map(actionword.children[:parameters])
59
+ name_chunks = name.split("\"", -1)
60
+ result = []
61
+ inline_parameter_names = []
62
+ name_chunks.each_slice(2) do |text, inline_parameter_name|
63
+ result << text.gsub(/[.|()\\.+*?\[\]{}^$]/) { |c| "\\#{c}" }
64
+ inline_parameter_names << inline_parameter_name if inline_parameter_name
65
+ if actionword_parameters.has_key?(inline_parameter_name)
66
+ result << "(.*)"
67
+ else
68
+ result << inline_parameter_name if inline_parameter_name
69
+ end
70
+ end
71
+ missing_parameter_names = actionword_parameters.keys - inline_parameter_names
72
+
73
+ patterned = result.join("\"")
74
+ missing_parameter_names.each do |missing_parameter_name|
75
+ patterned << " \"(.*)\""
76
+ end
77
+ "^#{patterned}$"
78
+ end
79
+
80
+ def all_valued_arguments_for(call)
81
+ evaluated_call_arguments = evaluated_map(call.children[:arguments])
82
+ evaluated_actionword_parameters = evaluated_map(get_actionword_parameters(call))
83
+ names = evaluated_actionword_parameters.keys
84
+
85
+ names.map { |name|
86
+ value = evaluated_call_arguments[name] || evaluated_actionword_parameters[name] || ""
87
+ [name, value]
88
+ }.to_h
89
+ end
90
+
91
+ def get_actionword_parameters(call)
92
+ actionword = get_actionword(call)
93
+ actionword && actionword.children[:parameters] || []
94
+ end
95
+
96
+ def get_actionword(call)
97
+ actionword = @indexer.get_index(call.children[:actionword])
98
+ actionword && actionword[:actionword] || nil
99
+ end
100
+
101
+ def evaluated_map(named_values)
102
+ named_values.map do |named_value|
103
+ name = named_value.children[:name]
104
+ value = evaluate(named_value.children[:value] || named_value.children[:default])
105
+ [name, value]
106
+ end.to_h
107
+ end
108
+
109
+ def evaluate(value)
110
+ if value.nil?
111
+ nil
112
+ elsif Hiptest::Nodes::Variable === value
113
+ "<#{value.children[:name]}>"
114
+ elsif value.children[:chunks]
115
+ value.children[:chunks].map {|chunk| evaluate(chunk) }.join('')
116
+ elsif value.children[:value]
117
+ value.children[:value]
118
+ else
119
+ nil
120
+ end
121
+ end
122
+ end
123
+ end
@@ -8,6 +8,10 @@ module Hiptest
8
8
  attr_reader :children, :parent
9
9
  attr_writer :parent
10
10
 
11
+ def pretty_print_instance_variables
12
+ super - [:@parent] # do not overload pry output
13
+ end
14
+
11
15
  def render(language = 'ruby', context = {})
12
16
  return Hiptest::Renderer.render(self, language, context)
13
17
  end
@@ -39,19 +43,25 @@ module Hiptest
39
43
  direct
40
44
  end
41
45
 
46
+ def ==(other)
47
+ other.class == self.class && other.children == @children
48
+ end
49
+
42
50
  private
43
51
 
44
52
  def all_sub_nodes
45
53
  path = [self]
46
54
  children = []
55
+ parsed_nodes_id = Set.new
47
56
 
48
57
  until path.empty?
49
58
  current_node = path.pop
50
59
 
51
60
  if current_node.is_a?(Node)
52
- next if children.include? current_node
61
+ next if parsed_nodes_id.include? current_node.object_id
53
62
 
54
63
  children << current_node
64
+ parsed_nodes_id << current_node.object_id
55
65
  current_node.children.values.reverse.each {|item| path << item}
56
66
  elsif current_node.is_a?(Array)
57
67
  current_node.reverse.each {|item| path << item}
@@ -169,9 +179,10 @@ module Hiptest
169
179
  end
170
180
 
171
181
  class Call < Node
172
- def initialize(actionword, arguments = [])
182
+ def initialize(actionword, arguments = [], annotation = nil)
173
183
  super()
174
- @children = {:actionword => actionword, :arguments => arguments}
184
+ annotation = nil if annotation == ""
185
+ @children = {:actionword => actionword, :arguments => arguments, :all_arguments => arguments, :annotation => annotation}
175
186
  end
176
187
  end
177
188
 
@@ -174,16 +174,23 @@ class OptionsParser
174
174
  end
175
175
 
176
176
  class LanguageConfigParser
177
- def initialize(options)
177
+ def initialize(options, language_config_path = nil)
178
178
  @options = options
179
- @config = ParseConfig.new(find_config_file(options))
179
+ language_config_path ||= LanguageConfigParser.config_path_for(options)
180
+ @config = ParseConfig.new(language_config_path)
180
181
  end
181
182
 
182
- def find_config_file(options)
183
- ["#{options.language}/#{options.framework}", "#{options.language}"].map do |p|
183
+ def self.config_path_for(options)
184
+ config_path = ["#{options.language}/#{options.framework}", "#{options.language}"].map do |p|
184
185
  path = "#{hiptest_publisher_path}/lib/templates/#{p}/output_config"
185
- path if File.file?(path)
186
+ File.expand_path(path) if File.file?(path)
186
187
  end.compact.first
188
+ if config_path.nil?
189
+ message = "cannot find output_config file in \"#{hiptest_publisher_path}/lib/templates\" for language #{options.language.inspect}"
190
+ message << " and framework #{options.framework.inspect}" if options.framework
191
+ raise ArgumentError.new(message)
192
+ end
193
+ config_path
187
194
  end
188
195
 
189
196
  def scenario_output_file(scenario_name)
@@ -1,5 +1,6 @@
1
1
  require 'ruby-handlebars'
2
2
 
3
+ require 'hiptest-publisher/gherkin_adder'
3
4
  require 'hiptest-publisher/nodes_walker'
4
5
  require 'hiptest-publisher/handlebars_helper'
5
6
  require 'hiptest-publisher/render_context_maker'
@@ -22,6 +23,7 @@ module Hiptest
22
23
  @rendered = {}
23
24
  @context = context
24
25
  @handlebars = Handlebars::Handlebars.new
26
+ @compiled_handlebars = {}
25
27
  register_partials()
26
28
 
27
29
  Hiptest::HandlebarsHelper.register_helpers(@handlebars, @context)
@@ -71,7 +73,15 @@ module Hiptest
71
73
  render_context[:context] = @context
72
74
 
73
75
  template = get_template_path(node)
74
- @handlebars.compile(File.read(template)).call(render_context)
76
+ if template
77
+ get_compiled_handlebars(template).call(render_context)
78
+ else
79
+ raise ArgumentError.new("no template for node #{node.class}")
80
+ end
81
+ end
82
+
83
+ def get_compiled_handlebars(template)
84
+ @compiled_handlebars[template] ||= @handlebars.compile(File.read(template))
75
85
  end
76
86
 
77
87
  def get_template_by_name(name, extension)
@@ -81,13 +91,21 @@ module Hiptest
81
91
  end.compact.first
82
92
  end
83
93
 
94
+ def fallback_template(extension)
95
+ @fallback_template ||= begin
96
+ if @context[:fallback_template]
97
+ get_template_by_name(@context[:fallback_template], extension)
98
+ end
99
+ end
100
+ end
101
+
84
102
  def get_template_path(node, extension = 'hbs')
85
103
  normalized_name = node.class.name.split('::').last.downcase
86
104
  unless @context[:forced_templates][normalized_name].nil?
87
105
  normalized_name = @context[:forced_templates][normalized_name]
88
106
  end
89
107
 
90
- get_template_by_name(normalized_name, extension)
108
+ get_template_by_name(normalized_name, extension) || fallback_template(extension)
91
109
  end
92
110
  end
93
- end
111
+ end
@@ -14,8 +14,7 @@ class String
14
14
  end
15
15
 
16
16
  def normalize_lower
17
- literated = self.literate
18
- literated.strip.gsub(/\s+/, '_').gsub(/\W/, '').downcase
17
+ self.normalize.downcase
19
18
  end
20
19
 
21
20
  def underscore
@@ -49,4 +48,4 @@ class String
49
48
  def clear_extension
50
49
  self.split('.')[0]
51
50
  end
52
- end
51
+ end
@@ -110,7 +110,8 @@ module Hiptest
110
110
  def build_call(call)
111
111
  Hiptest::Nodes::Call.new(
112
112
  css_first_content(call, '> actionword'),
113
- build_arguments(call))
113
+ build_arguments(call),
114
+ css_first_content(call, '> annotation'))
114
115
  end
115
116
 
116
117
  def build_arguments(arguments)
@@ -0,0 +1,5 @@
1
+ {{#if rendered_children.gherkin_annotation }}
2
+ {{{ rendered_children.gherkin_annotation }}} /{{{ rendered_children.gherkin_pattern }}}/ do{{#if has_parameters?}} |{{{ join rendered_children.parameters ', '}}}|{{/if}}
3
+ {{#indent}}{{ underscore rendered_children.name }}{{#if has_parameters?}}({{{ join rendered_children.parameters ', '}}}){{/if}}{{/indent}}
4
+ end
5
+ {{/if}}
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'actionwords'
4
+ World(Actionwords)
5
+ {{#each rendered_children.actionwords}}{{{this}}}{{/each}}
@@ -0,0 +1 @@
1
+ {{{ remove_quotes rendered_children.value }}}
@@ -0,0 +1 @@
1
+ {{{ rendered_children.gherkin_text }}}
@@ -0,0 +1 @@
1
+ | {{{ join rendered_children.arguments ' | ' }}} | {{#if rendered_children.uid}}uid:{{{rendered_children.uid}}}{{/if}} |
@@ -0,0 +1,2 @@
1
+ {{#each rendered_children.datasets}}{{{this}}}
2
+ {{/each}}
File without changes
@@ -0,0 +1,10 @@
1
+ [tests]
2
+ filename = 'features.feature'
3
+ scenario_filename = '%s.feature'
4
+ indentation = " "
5
+
6
+ [actionwords]
7
+ filename = 'step_definitions.rb'
8
+ indentation = " "
9
+ naming_convention = 'underscore'
10
+ fallback_template = 'empty'
@@ -0,0 +1 @@
1
+ {{{ underscore rendered_children.name }}}
@@ -0,0 +1,16 @@
1
+ Feature: {{{ rendered_children.name }}}{{#indent}}
2
+ {{#if has_datasets?}}
3
+ Scenario Outline: {{{ rendered_children.name }}}{{#indent}}
4
+ {{#each rendered_children.body}}{{{ this }}}
5
+ {{/each}}
6
+ Examples:{{#indent}}
7
+ | {{ join rendered_children.parameters ' | ' }} | hiptest-uid |
8
+ {{{rendered_children.datatable}}}
9
+ {{/indent}}{{/indent}}
10
+ {{else}}
11
+ Scenario: {{{ rendered_children.name }}}{{#if rendered_children.uid}} (uid:{{{rendered_children.uid}}}){{/if}}{{#indent}}
12
+ {{#each rendered_children.body}}{{{ this }}}
13
+ {{/each}}
14
+ {{/indent}}
15
+ {{/if}}
16
+ {{/indent}}
@@ -0,0 +1,3 @@
1
+ Scenario: {{{ rendered_children.name }}}{{#indent}}
2
+ {{#each rendered_children.body}}{{{ this }}}
3
+ {{/each}}{{/indent}}
@@ -0,0 +1 @@
1
+ {{#comment '#'}}{{{rendered_children.key}}}: {{{rendered_children.value}}}{{/comment}}
@@ -0,0 +1 @@
1
+ {{ rendered_children.value }}
@@ -0,0 +1 @@
1
+ "{{#each treated_chunks}}{{#if this.is_variable?}}#{{#curly}}{{{this.raw.children.name}}}{{/curly}}{{else}}{{{ escape_quotes this.raw.children.value }}}{{/if}}{{/each}}"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiptest-publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiptest R&D
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-27 00:00:00.000000000 Z
11
+ date: 2015-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -138,6 +138,20 @@ dependencies:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
+ - !ruby/object:Gem::Dependency
142
+ name: pry-byebug
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
141
155
  - !ruby/object:Gem::Dependency
142
156
  name: pry-stack_explorer
143
157
  requirement: !ruby/object:Gem::Requirement
@@ -244,7 +258,9 @@ files:
244
258
  - README.md
245
259
  - bin/hiptest-publisher
246
260
  - lib/hiptest-publisher.rb
261
+ - lib/hiptest-publisher/actionword_indexer.rb
247
262
  - lib/hiptest-publisher/call_arguments_adder.rb
263
+ - lib/hiptest-publisher/gherkin_adder.rb
248
264
  - lib/hiptest-publisher/handlebars_helper.rb
249
265
  - lib/hiptest-publisher/nodes.rb
250
266
  - lib/hiptest-publisher/nodes_walker.rb
@@ -265,6 +281,20 @@ files:
265
281
  - lib/templates/common/numericliteral.hbs
266
282
  - lib/templates/common/stringliteral.hbs
267
283
  - lib/templates/common/variable.hbs
284
+ - lib/templates/cucumber/actionword.hbs
285
+ - lib/templates/cucumber/actionwords.hbs
286
+ - lib/templates/cucumber/argument.hbs
287
+ - lib/templates/cucumber/call.hbs
288
+ - lib/templates/cucumber/dataset.hbs
289
+ - lib/templates/cucumber/datatable.hbs
290
+ - lib/templates/cucumber/empty.hbs
291
+ - lib/templates/cucumber/output_config
292
+ - lib/templates/cucumber/parameter.hbs
293
+ - lib/templates/cucumber/single_scenario.hbs
294
+ - lib/templates/cucumber/single_test.hbs
295
+ - lib/templates/cucumber/step.hbs
296
+ - lib/templates/cucumber/stringliteral.hbs
297
+ - lib/templates/cucumber/template.hbs
268
298
  - lib/templates/java/_body.hbs
269
299
  - lib/templates/java/_item_as_function.hbs
270
300
  - lib/templates/java/_scenario.hbs
@@ -483,7 +513,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
483
513
  version: '0'
484
514
  requirements: []
485
515
  rubyforge_project:
486
- rubygems_version: 2.4.3
516
+ rubygems_version: 2.4.5
487
517
  signing_key:
488
518
  specification_version: 4
489
519
  summary: Export your tests from Hiptest into executable tests.