gauge-ruby 0.4.2 → 0.4.3

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.
@@ -20,25 +20,26 @@ require_relative '../code_parser'
20
20
  module Gauge
21
21
  module Processors
22
22
  def refactor_step(message)
23
- oldStepValue = message.refactorRequest.oldStepValue.stepValue
24
- newStep = message.refactorRequest.newStepValue
23
+ request = message.refactorRequest
25
24
  refactor_response = Messages::RefactorResponse.new(success: true)
26
25
  begin
27
- stepBlock = get_step oldStepValue
28
- CodeParser.refactor stepBlock, message.refactorRequest.paramPositions, newStep.parameters, newStep.parameterizedStepValue
29
- file, _ = stepBlock.source_location
26
+ step_info = get_step request.oldStepValue.stepValue
27
+ refactored_code = CodeParser.refactor step_info, request.paramPositions, request.newStepValue
28
+ file = step_info[:locations][0][:file]
29
+ File.write file, refactored_code if request.saveChanges
30
30
  refactor_response.filesChanged = [file]
31
+ refactor_response.fileChanges = [Messages::FileChanges.new(:fileName => file, :fileContent => refactored_code)]
31
32
  rescue Exception => e
32
- refactor_response.success=false
33
- refactor_response.error=e.message
33
+ refactor_response.success = false
34
+ refactor_response.error = e.message
34
35
  end
35
36
  Messages::Message.new(:messageType => Messages::Message::MessageType::RefactorResponse, :messageId => message.messageId, refactorResponse: refactor_response)
36
37
  end
37
38
 
38
39
  def get_step(step_text)
39
- blocks = MethodCache.get_steps step_text
40
- raise "Multiple step implementations found for => '#{step_text}'" if blocks.length > 1
41
- blocks[0]
40
+ md = MethodCache.multiple_implementation? step_text
41
+ raise "Multiple step implementations found for => '#{step_text}'" if md
42
+ MethodCache.get_step_info(step_text)
42
43
  end
43
44
  end
44
45
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2015 ThoughtWorks, Inc.
1
+ # Copyright 2018 ThoughtWorks, Inc.
2
2
 
3
3
  # This file is part of Gauge-Ruby.
4
4
 
@@ -18,12 +18,18 @@
18
18
  module Gauge
19
19
  module Processors
20
20
  def process_step_name_request(message)
21
- parsed_step_text = message.stepNameRequest.stepValue
22
- is_valid = MethodCache.valid_step?(parsed_step_text)
23
- step_text = is_valid ? MethodCache.get_step_text(parsed_step_text) : ""
24
- has_alias = MethodCache.has_alias?(step_text)
25
- get_step_name_response = Messages::StepNameResponse.new(isStepPresent: is_valid, stepName: [step_text], hasAlias: has_alias)
26
- Messages::Message.new(:messageType => Messages::Message::MessageType::StepNameResponse, :messageId => message.messageId, :stepNameResponse => get_step_name_response)
21
+ step_value = message.stepNameRequest.stepValue
22
+ if MethodCache.valid_step?(step_value)
23
+ step_text = MethodCache.get_step_text(step_value)
24
+ has_alias = MethodCache.has_alias?(step_text)
25
+ loc = MethodCache.get_step_info(step_value)[:locations][0]
26
+ span = Gauge::Messages::Span.new(start: loc[:span].begin.line, end: loc[:span].end.line, startChar: loc[:span].begin.column, endChar: loc[:span].end.column)
27
+ r = Messages::StepNameResponse.new(isStepPresent: true, stepName: [step_text], hasAlias: has_alias, fileName: loc[:file], span: span)
28
+ Messages::Message.new(:messageType => Messages::Message::MessageType::StepNameResponse, :messageId => message.messageId, :stepNameResponse => r)
29
+ else
30
+ r = Messages::StepNameResponse.new(isStepPresent: false, stepName: [''], hasAlias: false, fileName: '', span: nil)
31
+ Messages::Message.new(:messageType => Messages::Message::MessageType::StepNameResponse, :messageId => message.messageId, :stepNameResponse => r)
32
+ end
27
33
  end
28
34
  end
29
35
  end
@@ -0,0 +1,35 @@
1
+ # Copyright 2018 ThoughtWorks, Inc.
2
+
3
+ # This file is part of Gauge-Ruby.
4
+
5
+ # Gauge-Ruby is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # Gauge-Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Gauge-Ruby. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module Gauge
19
+ module Processors
20
+ def process_step_positions_request(message)
21
+ file = message.stepPositionsRequest.filePath
22
+ positions = MethodCache.step_positions(file)
23
+ p = create_step_position_messages(positions)
24
+ r = Messages::StepPositionsResponse.new(:stepPositions => p)
25
+ Messages::Message.new(:messageType => Messages::Message::MessageType::StepPositionsResponse, :messageId => message.messageId, :stepPositionsResponse => r)
26
+ end
27
+
28
+ def create_step_position_messages(positions)
29
+ positions.map do |p|
30
+ span = Gauge::Messages::Span.new(:start => p[:span].begin.line, :end => p[:span].end.line, :startChar => p[:span].begin.column, :endChar => p[:span].end.column)
31
+ Messages::StepPositionsResponse::StepPosition.new(:stepValue => p[:stepValue], :span => span)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -18,24 +18,32 @@
18
18
  module Gauge
19
19
  module Processors
20
20
  def process_step_validation_request(message)
21
- step_validate_request = message.stepValidateRequest
21
+ request = message.stepValidateRequest
22
22
  is_valid = true
23
- msg = ''
23
+ msg,suggestion = ''
24
24
  err_type = nil
25
- blocks = MethodCache.get_steps(step_validate_request.stepText)
26
- if blocks.length > 1
27
- is_valid = false
28
- msg = "Multiple step implementations found for => '#{step_validate_request.stepText}'"
29
- err_type = Messages::StepValidateResponse::ErrorType::DUPLICATE_STEP_IMPLEMENTATION
30
- elsif blocks.length == 0
25
+ if !MethodCache.valid_step? request.stepText
31
26
  is_valid = false
32
27
  msg = 'Step implementation not found'
33
28
  err_type = Messages::StepValidateResponse::ErrorType::STEP_IMPLEMENTATION_NOT_FOUND
29
+ suggestion = create_suggestion(request.stepValue) unless request.stepValue.stepValue.empty?
30
+ elsif MethodCache.multiple_implementation?(request.stepText)
31
+ is_valid = false
32
+ msg = "Multiple step implementations found for => '#{request.stepText}'"
33
+ err_type = Messages::StepValidateResponse::ErrorType::DUPLICATE_STEP_IMPLEMENTATION
34
+ suggestion = ''
34
35
  end
35
- step_validate_response = Messages::StepValidateResponse.new(:isValid => is_valid, :errorMessage => msg, :errorType => err_type)
36
+ step_validate_response = Messages::StepValidateResponse.new(:isValid => is_valid, :errorMessage => msg, :errorType => err_type, :suggestion => suggestion)
36
37
  Messages::Message.new(:messageType => Messages::Message::MessageType::StepValidateResponse,
37
- :messageId => message.messageId,
38
- :stepValidateResponse => step_validate_response)
38
+ :messageId => message.messageId,
39
+ :stepValidateResponse => step_validate_response)
40
+ end
41
+
42
+ def create_suggestion(step_value)
43
+ count = -1
44
+ step_text = step_value.stepValue.gsub(/{}/) {"<arg#{count += 1}>"}
45
+ params = step_value.parameters.map.with_index {|v,i| "arg#{i}"}.join ", "
46
+ "step '#{step_text}' do |#{params}|\n\traise 'Unimplemented Step'\nend"
39
47
  end
40
48
  end
41
49
  end
@@ -0,0 +1,46 @@
1
+ # Copyright 2018 ThoughtWorks, Inc.
2
+
3
+ # This file is part of Gauge-Ruby.
4
+
5
+ # Gauge-Ruby is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # Gauge-Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Gauge-Ruby. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require_relative '../../lib/util'
19
+
20
+ module Gauge
21
+ module Processors
22
+ def process_stub_implementation_code_request(message)
23
+ codes = message.stubImplementationCodeRequest.codes
24
+ file_path = message.stubImplementationCodeRequest.implementationFilePath
25
+ content = ''
26
+ if File.file? file_path
27
+ content = File.read(file_path)
28
+ else
29
+ file_path = Util.get_file_name
30
+ end
31
+ text_diffs = [Messages::TextDiff.new(span: create_span(content, codes), content: codes.join("\n"))]
32
+ file_diff = Messages::FileDiff.new(filePath: file_path, textDiffs: text_diffs)
33
+ Messages::Message.new(messageType: Messages::Message::MessageType::FileDiff, messageId: message.messageId, fileDiff: file_diff)
34
+ end
35
+
36
+ def create_span(content, codes)
37
+ unless content.empty?
38
+ eof_char = content.strip.length == content.length ? "\n" : ''
39
+ codes.unshift(eof_char)
40
+ line = content.split("\n").length
41
+ return Messages::Span.new(start: line, startChar: 0, end: line, endChar: 0)
42
+ end
43
+ Messages::Span.new(start: 0, startChar: 0, end: 0, endChar: 0)
44
+ end
45
+ end
46
+ end
@@ -24,6 +24,7 @@ module Gauge
24
24
  class ProtoHookFailure < ::ProtocolBuffers::Message; end
25
25
  class ProtoSuiteResult < ::ProtocolBuffers::Message; end
26
26
  class ProtoSpecResult < ::ProtocolBuffers::Message; end
27
+ class Error < ::ProtocolBuffers::Message; end
27
28
  class ProtoStepValue < ::ProtocolBuffers::Message; end
28
29
 
29
30
  # enums
@@ -44,10 +45,12 @@ module Gauge
44
45
  optional :string, :specHeading, 1
45
46
  repeated ::Gauge::Messages::ProtoItem, :items, 2
46
47
  optional :bool, :isTableDriven, 3
47
- optional ::Gauge::Messages::ProtoHookFailure, :preHookFailure, 4
48
- optional ::Gauge::Messages::ProtoHookFailure, :postHookFailure, 5
48
+ repeated ::Gauge::Messages::ProtoHookFailure, :preHookFailures, 4
49
+ repeated ::Gauge::Messages::ProtoHookFailure, :postHookFailures, 5
49
50
  optional :string, :fileName, 6
50
51
  repeated :string, :tags, 7
52
+ repeated :string, :preHookMessages, 8
53
+ repeated :string, :postHookMessages, 9
51
54
  end
52
55
 
53
56
  class ProtoItem < ::ProtocolBuffers::Message
@@ -97,6 +100,8 @@ module Gauge
97
100
  repeated ::Gauge::Messages::ProtoItem, :tearDownSteps, 12
98
101
  optional ::Gauge::Messages::Span, :span, 13
99
102
  optional ::Gauge::Messages::ExecutionStatus, :executionStatus, 14
103
+ repeated :string, :preHookMessages, 15
104
+ repeated :string, :postHookMessages, 16
100
105
  end
101
106
 
102
107
  class Span < ::ProtocolBuffers::Message
@@ -104,6 +109,8 @@ module Gauge
104
109
 
105
110
  optional :int64, :start, 1
106
111
  optional :int64, :end, 2
112
+ optional :int64, :startChar, 3
113
+ optional :int64, :endChar, 4
107
114
  end
108
115
 
109
116
  class ProtoTableDrivenScenario < ::ProtocolBuffers::Message
@@ -120,6 +127,8 @@ module Gauge
120
127
  optional :string, :parsedText, 2
121
128
  repeated ::Gauge::Messages::Fragment, :fragments, 3
122
129
  optional ::Gauge::Messages::ProtoStepExecutionResult, :stepExecutionResult, 4
130
+ repeated :string, :preHookMessages, 5
131
+ repeated :string, :postHookMessages, 6
123
132
  end
124
133
 
125
134
  class ProtoConcept < ::ProtocolBuffers::Message
@@ -240,6 +249,7 @@ module Gauge
240
249
  optional :string, :stackTrace, 1
241
250
  optional :string, :errorMessage, 2
242
251
  optional :bytes, :screenShot, 3
252
+ optional :int32, :tableRowIndex, 4
243
253
  end
244
254
 
245
255
  class ProtoSuiteResult < ::ProtocolBuffers::Message
@@ -257,6 +267,8 @@ module Gauge
257
267
  optional :string, :projectName, 10
258
268
  optional :string, :timestamp, 11
259
269
  optional :int32, :specsSkippedCount, 12
270
+ repeated :string, :preHookMessages, 13
271
+ repeated :string, :postHookMessages, 14
260
272
  end
261
273
 
262
274
  class ProtoSpecResult < ::ProtocolBuffers::Message
@@ -269,8 +281,30 @@ module Gauge
269
281
  repeated :int32, :failedDataTableRows, 5
270
282
  optional :int64, :executionTime, 6
271
283
  optional :bool, :skipped, 7
272
- optional :int32, :scenarioSkippedCount, 9
273
- repeated :int32, :skippedDataTableRows, 10
284
+ optional :int32, :scenarioSkippedCount, 8
285
+ repeated :int32, :skippedDataTableRows, 9
286
+ repeated ::Gauge::Messages::Error, :errors, 10
287
+ end
288
+
289
+ class Error < ::ProtocolBuffers::Message
290
+ # forward declarations
291
+
292
+ # enums
293
+ module ErrorType
294
+ include ::ProtocolBuffers::Enum
295
+
296
+ set_fully_qualified_name "gauge.messages.Error.ErrorType"
297
+
298
+ PARSE_ERROR = 0
299
+ VALIDATION_ERROR = 1
300
+ end
301
+
302
+ set_fully_qualified_name "gauge.messages.Error"
303
+
304
+ optional ::Gauge::Messages::Error::ErrorType, :type, 1
305
+ optional :string, :filename, 2
306
+ optional :int32, :lineNumber, 3
307
+ optional :string, :message, 4
274
308
  end
275
309
 
276
310
  class ProtoStepValue < ::ProtocolBuffers::Message
@@ -0,0 +1,103 @@
1
+ # Copyright 2018 ThoughtWorks, Inc.
2
+
3
+ # This file is part of Gauge-Ruby.
4
+
5
+ # Gauge-Ruby is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # Gauge-Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Gauge-Ruby. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require_relative 'gauge'
19
+ require_relative 'code_parser'
20
+ require_relative 'method_cache'
21
+
22
+ module Gauge
23
+ # @api private
24
+ module StaticLoader
25
+ def self.load_files(dir)
26
+ Dir["#{dir}/**/*.rb"].each do |x|
27
+ load_steps(x, CodeParser.code_to_ast(File.read(x)))
28
+ end
29
+ end
30
+
31
+ def self.traverse(ast, &visitor)
32
+ return if ast.class != Parser::AST::Node
33
+ if ast && step_node?(ast)
34
+ visitor.call(ast)
35
+ elsif ast&.children
36
+ ast.children.each {|node|
37
+ traverse(node, &visitor)
38
+ }
39
+ end
40
+ end
41
+
42
+ def self.load_steps(file, ast)
43
+ traverse ast do |node|
44
+ process_node(file, node)
45
+ end
46
+ end
47
+
48
+ def self.reload_steps(file, ast)
49
+ return unless ast
50
+ remove_steps file
51
+ load_steps(file, ast)
52
+ end
53
+
54
+ def self.remove_steps(file)
55
+ Gauge::MethodCache.remove_steps file
56
+ end
57
+
58
+ def self.step_node?(node)
59
+ node.type == :block && node.children[0].children[1] == :step
60
+ end
61
+
62
+ def self.process_node(file, node)
63
+ if aliases?(node)
64
+ load_aliases(file, node)
65
+ else
66
+ step_text = node.children[0].children[2].children[0]
67
+ step_value = Gauge::Connector.step_value step_text
68
+ load_step(file, step_value, step_text, node, {recoverable: recoverable?(node)})
69
+ end
70
+ end
71
+
72
+ def self.aliases?(node)
73
+ return node.children[0].children.size > 3 && node.children[0].children[3].type == :str
74
+ end
75
+
76
+ def self.load_aliases(file, node)
77
+ recoverable = false
78
+ if recoverable? node
79
+ aliases = node.children[0].children.slice(2, node.children[0].children.length() - 3)
80
+ recoverable = true
81
+ else
82
+ aliases = node.children[0].children.slice(2, node.children[0].children.length() - 2)
83
+ end
84
+ Gauge::MethodCache.add_step_alias(*aliases.map {|x| x.children[0]})
85
+ aliases.each {|x|
86
+ sv = Gauge::Connector.step_value x.children[0]
87
+ load_step(file, sv, x.children[0], node, {recoverable: recoverable})
88
+ }
89
+ end
90
+
91
+ def self.recoverable?(node)
92
+ size = node.children[0].children.length
93
+ options = node.children[0].children[size - 1]
94
+ options.type == :hash && options.children[0].children[0].children[0] == :continue_on_failure
95
+ end
96
+
97
+ def self.load_step(file, step_value, step_text, block, options)
98
+ si = {location: {file: file, span: block.loc}, step_text: step_text,
99
+ block: block, recoverable: options[:recoverable]}
100
+ Gauge::MethodCache.add_step(step_value, si)
101
+ end
102
+ end
103
+ end
@@ -18,7 +18,7 @@
18
18
  module Gauge
19
19
  class Util
20
20
  def self.valid_variable_name?(var_name)
21
- Object.new.instance_variable_set ('@'+var_name).to_sym, nil
21
+ Object.new.instance_variable_set ('@' + var_name).to_sym, nil
22
22
  true
23
23
  rescue NameError
24
24
  !!(var_name =~ /^[0-9]+$/)
@@ -26,12 +26,24 @@ module Gauge
26
26
 
27
27
  def self.remove_special_chars(param)
28
28
  new_param = ''
29
- param.each_char { |c|
29
+ param.each_char {|c|
30
30
  if valid_variable_name? c
31
- new_param += c
31
+ new_param += c
32
32
  end
33
33
  }
34
34
  return new_param
35
- end
35
+ end
36
+
37
+ def self.get_step_implementation_dir
38
+ return File.join(ENV["GAUGE_PROJECT_ROOT"].gsub(/\\/, "/"), 'step_implementations')
39
+ end
40
+
41
+ def self.get_file_name(prefix = '', counter = 0)
42
+ name = "step_implementation#{prefix}.rb"
43
+ file_name = File.join(get_step_implementation_dir, name)
44
+ return file_name unless File.file? file_name
45
+ counter += 1
46
+ get_file_name("_#{counter}", counter)
47
+ end
36
48
  end
37
- end
49
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gauge-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gauge Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-05 00:00:00.000000000 Z
11
+ date: 2018-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-protocol-buffers
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: unparser
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.6
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.2.6
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: method_source
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,34 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: 0.8.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-debug-ide
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.6.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.6.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: debase
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.2
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.2
69
111
  description: Adds Ruby support into Gauge tests
70
112
  email:
71
113
  - gauge@thoughtworks.com
@@ -82,19 +124,25 @@ files:
82
124
  - lib/gauge.rb
83
125
  - lib/gauge_messages.rb
84
126
  - lib/gauge_runtime.rb
127
+ - lib/log.rb
85
128
  - lib/message_processor.rb
86
129
  - lib/messages.pb.rb
87
130
  - lib/method_cache.rb
131
+ - lib/processors/cache_file_processor.rb
88
132
  - lib/processors/datastore_init_processor.rb
89
133
  - lib/processors/execute_step_request_processor.rb
90
134
  - lib/processors/execution_handler.rb
91
135
  - lib/processors/execution_hook_processors.rb
136
+ - lib/processors/implementation_file_list_processor.rb
92
137
  - lib/processors/kill_request_processor.rb
93
138
  - lib/processors/refactor_step_request_processor.rb
94
139
  - lib/processors/step_name_request_processor.rb
95
140
  - lib/processors/step_names_request_processor.rb
141
+ - lib/processors/step_positions_request_processor.rb
96
142
  - lib/processors/step_validation_request_processor.rb
143
+ - lib/processors/stub_implementation_processor.rb
97
144
  - lib/spec.pb.rb
145
+ - lib/static_loader.rb
98
146
  - lib/table.rb
99
147
  - lib/util.rb
100
148
  homepage: http://www.getgauge.io