gauge-ruby 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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