rutema 2.0.1 → 2.0.2

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.
@@ -1,6 +1,6 @@
1
1
  # Copyright (c) 2007-2021 Vassilis Rizopoulos. All rights reserved.
2
2
 
3
- require 'patir/command'
3
+ require "patir/command"
4
4
 
5
5
  module Rutema
6
6
  ##
@@ -20,11 +20,11 @@ module Rutema
20
20
  # * +value+ - the initial value of the attribute
21
21
  #
22
22
  # If +symbol+ is neither a string nor a symbol this method will be a no-op.
23
- def attribute symbol,value
24
- @attributes||=Hash.new
23
+ def attribute(symbol, value)
24
+ @attributes ||= {}
25
25
  case symbol
26
- when String then @attributes[:"#{symbol}"]=value
27
- when Symbol then @attributes[symbol]=value
26
+ when String then @attributes[:"#{symbol}"] = value
27
+ when Symbol then @attributes[symbol] = value
28
28
  end
29
29
  end
30
30
 
@@ -37,29 +37,33 @@ module Rutema
37
37
  # object.attribute= will set the attribute to the right operand and
38
38
  # object.has_attribute? will return +true+ or +false+ according to the
39
39
  # existence of the attribute.
40
- def method_missing symbol,*args
41
- @attributes||=Hash.new
42
- key=symbol.id2name.chomp('?').chomp('=').sub(/^has_/,"")
43
- @attributes[:"#{key}"]=args[0] if key+"="==symbol.id2name
44
- if @attributes.has_key?(:"#{key}")
45
- return true if "has_"+key+"?"==symbol.id2name
46
- return @attributes[:"#{key}"]
40
+ def method_missing(symbol, *args)
41
+ @attributes ||= {}
42
+ key = symbol.id2name.chomp("?").chomp("=").sub(/^has_/, "")
43
+ @attributes[:"#{key}"] = args[0] if "#{key}=" == symbol.id2name
44
+ if @attributes.key?(:"#{key}")
45
+ return true if "has_#{key}?" == symbol.id2name
46
+
47
+ return @attributes[:"#{key}"]
47
48
  else
48
- return false if "has_"+key+"?"==symbol.id2name
49
- super(symbol,*args)
49
+ return false if "has_#{key}?" == symbol.id2name
50
+
51
+ super
50
52
  end
51
53
  end
52
54
 
55
+ def respond_to_missing?(*_args)
56
+ true
57
+ end
58
+
53
59
  ##
54
60
  # Return +true+ if the object responds to the given method or else +false+
55
- def respond_to? symbol,include_all
56
- @attributes||=Hash.new
57
- key=symbol.id2name.chomp('?').chomp('=').sub(/^has_/,"")
58
- if @attributes.has_key?(:"#{key}")
59
- return true
60
- else
61
- super(symbol,include_all)
62
- end
61
+ def respond_to?(symbol, include_all)
62
+ @attributes ||= {}
63
+ key = symbol.id2name.chomp("?").chomp("=").sub(/^has_/, "")
64
+ return true if @attributes.key?(:"#{key}")
65
+
66
+ super
63
67
  end
64
68
  end
65
69
 
@@ -70,6 +74,7 @@ module Rutema
70
74
  include SpecificationElement
71
75
 
72
76
  attr_accessor :scenario
77
+
73
78
  ##
74
79
  # Expects a Hash of parameters
75
80
  #
@@ -88,16 +93,14 @@ module Rutema
88
93
  # :version - The version of this specification
89
94
  #
90
95
  # Default values are empty strings and arrays. (scenario is nil)
91
- def initialize params
92
- begin
93
- @attributes=params
94
- end if params
95
- @attributes||=Hash.new
96
- @attributes[:name]||=""
97
- @attributes[:title]||=""
98
- @attributes[:filename]||=""
99
- @attributes[:description]||=""
100
- @scenario=@attributes[:scenario]
96
+ def initialize(params)
97
+ @attributes = params if params
98
+ @attributes ||= {}
99
+ @attributes[:name] ||= ""
100
+ @attributes[:title] ||= ""
101
+ @attributes[:filename] ||= ""
102
+ @attributes[:description] ||= ""
103
+ @scenario = @attributes[:scenario]
101
104
  end
102
105
 
103
106
  ##
@@ -107,93 +110,90 @@ module Rutema
107
110
  end
108
111
  end
109
112
 
110
- #A Rutema::Scenario is a sequence of Rutema::Step instances.
113
+ # A Rutema::Scenario is a sequence of Rutema::Step instances.
111
114
  #
112
- #Rutema::Step instances are run in the definition sequence and the scenario
113
- #is succesfull when all steps are succesfull.
115
+ # Rutema::Step instances are run in the definition sequence and the scenario
116
+ # is succesfull when all steps are succesfull.
114
117
  #
115
- #From the execution point of view each step is either succesfull or failed and it depends on
116
- #the exit code of the step's command.
118
+ # From the execution point of view each step is either succesfull or failed and it depends on
119
+ # the exit code of the step's command.
117
120
  #
118
- #Failure in a step results in the interruption of execution and the report of the errors.
121
+ # Failure in a step results in the interruption of execution and the report of the errors.
119
122
  class Scenario
120
123
  include SpecificationElement
121
124
 
122
- attr_reader :steps
123
-
124
- def initialize steps
125
- @attributes=Hash.new
126
- @steps=steps
127
- @steps||=Array.new
128
- end
125
+ attr_accessor :steps
129
126
 
130
- #Adds a step at the end of the step sequence
131
- def add_step step
132
- @steps<<step
127
+ def initialize(steps)
128
+ @attributes = {}
129
+ @steps = steps
130
+ @steps ||= []
133
131
  end
134
132
 
135
- #Overwrites the step sequence
136
- def steps= array_of_steps
137
- @steps=array_of_steps
133
+ # Adds a step at the end of the step sequence
134
+ def add_step(step)
135
+ @steps << step
138
136
  end
137
+
138
+ # Overwrites the step sequence
139
139
  end
140
140
 
141
- #Represents a step in a Scenario.
141
+ # Represents a step in a Scenario.
142
142
  #
143
- #Each Rutema::Step can have text and a command associated with it.
143
+ # Each Rutema::Step can have text and a command associated with it.
144
144
  #
145
- #Step standard attributes are.
145
+ # Step standard attributes are.
146
146
  #
147
- #attended - the step can only run in attended mode, it requires user input.
147
+ # attended - the step can only run in attended mode, it requires user input.
148
148
  #
149
- #step_type - a string identifying the type of the step. It is "step" by default.
149
+ # step_type - a string identifying the type of the step. It is "step" by default.
150
150
  #
151
- #ignore - set to true if the step's success or failure is to be ignored. It essentially means that the step is always considered succesfull
151
+ # ignore - set to true if the step's success or failure is to be ignored. It essentially means that the step is always considered succesfull
152
152
  #
153
- #continue - set to true if the step's success or failure is to be recognized, but following steps in the same scenario are to be carried out regardless
153
+ # continue - set to true if the step's success or failure is to be recognized, but following steps in the same scenario are to be carried out regardless
154
154
  # of if indicates test failure, but ensures any further state is carried out as needed
155
155
  #
156
156
  # skip_on_error - if the test case has been marked a failure, skip steps marked with this attribute
157
157
  #
158
- #number - this is set when the step is assigned to a Scenario and is the sequence number
158
+ # number - this is set when the step is assigned to a Scenario and is the sequence number
159
159
  #
160
- #cmd - the command associated with this step. This should quack like Patir::Command.
160
+ # cmd - the command associated with this step. This should quack like Patir::Command.
161
161
  #
162
- #status - one of :not_executed, :success, :warning, :error. Encapsulates the underlying command's status
162
+ # status - one of :not_executed, :success, :warning, :error. Encapsulates the underlying command's status
163
163
  #
164
164
  #==Dynamic behaviour
165
165
  #
166
- #A Rutema::Step can be queried dynamicaly about the attributes it posesses:
166
+ # A Rutema::Step can be queried dynamicaly about the attributes it posesses:
167
167
  # step.has_script? - will return true if script is step's attribute.
168
- #Attribute's are mostly assigned by the parser, i.e. the Rutema::BaseXMLParser from the XML element
168
+ # Attribute's are mostly assigned by the parser, i.e. the Rutema::BaseXMLParser from the XML element
169
169
  # <test script="some_script"/>
170
- #will create a Step instance with step_type=="test" and script="some_script". In this case
170
+ # will create a Step instance with step_type=="test" and script="some_script". In this case
171
171
  #
172
172
  # step.has_script? returns true
173
173
  # step.script returns "some_script"
174
174
  #
175
- #Just like an OpenStruct, Step attributes will be created by direct assignment:
175
+ # Just like an OpenStruct, Step attributes will be created by direct assignment:
176
176
  # step.script="some_script" creates the script attribute if it does not exist.
177
177
  #
178
- #See Rutema::SpecificationElement for the implementation details.
178
+ # See Rutema::SpecificationElement for the implementation details.
179
179
  class Step
180
180
  include SpecificationElement
181
181
  include Patir::Command
182
-
183
- #_txt_ describes the step, _cmd_ is the command to run
184
- def initialize txt="",cmd=nil
185
- @attributes=Hash.new
186
- #ignore is off by default
187
- @attributes[:ignore]=false
182
+
183
+ # _txt_ describes the step, _cmd_ is the command to run
184
+ def initialize(txt = "", cmd = nil)
185
+ @attributes = {}
186
+ # ignore is off by default
187
+ @attributes[:ignore] = false
188
188
  # continue is off by default
189
189
  @attributes[:continue] = false
190
190
  # skip_on_error is off by default
191
- @attributes[:skip_on_error]=false
192
- #assign
193
- @attributes[:cmd]=cmd if cmd
194
- @attributes[:text]=txt
195
- @number=0
196
- @attributes[:step_type]="step"
191
+ @attributes[:skip_on_error] = false
192
+ # assign
193
+ @attributes[:cmd] = cmd if cmd
194
+ @attributes[:text] = txt
195
+ @number = 0
196
+ @attributes[:step_type] = "step"
197
197
  end
198
198
 
199
199
  def name
@@ -202,83 +202,94 @@ module Rutema
202
202
 
203
203
  def output
204
204
  return "" unless @attributes[:cmd]
205
+
205
206
  return @attributes[:cmd].output
206
207
  end
207
208
 
208
209
  def error
209
210
  return "no command associated" unless @attributes[:cmd]
211
+
210
212
  return @attributes[:cmd].error
211
213
  end
212
214
 
213
215
  def backtrace
214
216
  return "no backtrace associated" unless @attributes[:cmd]
215
217
  return @attributes[:cmd].backtrace if @attributes[:cmd].respond_to?(:backtrace)
218
+
216
219
  return ""
217
220
  end
218
221
 
219
222
  def skip_on_error?
220
223
  return false unless @attributes[:skip_on_error]
224
+
221
225
  return @attributes[:skip_on_error]
222
226
  end
223
227
 
224
228
  def ignore?
225
229
  return false unless @attributes[:ignore]
230
+
226
231
  return @attributes[:ignore]
227
232
  end
228
233
 
229
234
  def continue?
230
235
  return false unless @attributes[:continue]
236
+
231
237
  return @attributes[:continue]
232
238
  end
233
239
 
234
240
  def exec_time
235
241
  return 0 unless @attributes[:cmd]
242
+
236
243
  return @attributes[:cmd].exec_time
237
244
  end
238
245
 
239
246
  def status
240
247
  return :warning unless @attributes[:cmd]
248
+
241
249
  return @attributes[:cmd].status
242
250
  end
243
251
 
244
- def status= st
245
- @attributes[:cmd].status=st if @attributes[:cmd]
252
+ def status=(stts)
253
+ @attributes[:cmd].status = stts if @attributes[:cmd]
246
254
  end
247
255
 
248
- def run context=nil
256
+ def run(context = nil)
249
257
  return not_executed unless @attributes[:cmd]
258
+
250
259
  return @attributes[:cmd].run(context)
251
260
  end
252
261
 
253
262
  def reset
254
- @attributes[:cmd].reset if @attributes[:cmd]
263
+ @attributes[:cmd]&.reset
255
264
  end
256
265
 
257
266
  def name_with_parameters
258
- param=" - #{self.cmd.to_s}" if self.has_cmd?
267
+ param = " - #{cmd}" if has_cmd?
259
268
  return "#{@attributes[:step_type]}#{param}"
260
269
  end
261
270
 
262
- def to_s#:nodoc:
263
- if self.has_cmd?
264
- msg="#{self.number} - #{self.cmd.to_s}"
271
+ def to_s # :nodoc:
272
+ if has_cmd?
273
+ msg = "#{number} - #{cmd}"
265
274
  else
266
- msg="#{self.number} - #{self.name}"
275
+ msg = "#{number} - #{name}"
267
276
  end
268
- msg<<" in #{self.included_in}" if self.has_included_in?
277
+ msg << " in #{included_in}" if has_included_in?
269
278
  return msg
270
279
  end
271
280
  end
272
281
  end
273
282
 
274
283
  class Patir::ShellCommand
275
- def to_s#:nodoc:
284
+ # :nodoc:
285
+ def to_s
276
286
  return @command
277
287
  end
278
288
  end
279
289
 
280
290
  class Patir::RubyCommand
281
- def to_s#:nodoc:
291
+ # :nodoc:
292
+ def to_s
282
293
  return @name
283
294
  end
284
295
  end
@@ -1,6 +1,6 @@
1
1
  # Copyright (c) 2007-2021 Vassilis Rizopoulos. All rights reserved.
2
2
 
3
- require_relative 'framework'
3
+ require_relative "framework"
4
4
 
5
5
  module Rutema
6
6
  ##
@@ -23,9 +23,9 @@ module Rutema
23
23
  ##
24
24
  # Initialize a new instance internally storing and validating the passed
25
25
  # Configuration instance
26
- def initialize configuration
27
- @configuration=configuration
28
- @configuration||={}
26
+ def initialize(configuration)
27
+ @configuration = configuration
28
+ @configuration ||= {}
29
29
  validate_configuration
30
30
  end
31
31
 
@@ -34,15 +34,15 @@ module Rutema
34
34
  #
35
35
  # The passed argument can either be the path to a test specification file
36
36
  # or the test specification itself.
37
- def parse_specification param
38
- raise ParserError,"not implemented. You should derive a parser implementation from SpecificationParser!"
37
+ def parse_specification(_param)
38
+ raise ParserError, "not implemented. You should derive a parser implementation from SpecificationParser!"
39
39
  end
40
40
 
41
41
  ##
42
42
  # Parse a setup specification
43
43
  #
44
44
  # This calls #parse_specification by default.
45
- def parse_setup param
45
+ def parse_setup(param)
46
46
  parse_specification(param)
47
47
  end
48
48
 
@@ -50,7 +50,7 @@ module Rutema
50
50
  # Parse a teardown specification
51
51
  #
52
52
  # This calls #parse_specification by default.
53
- def parse_teardown param
53
+ def parse_teardown(param)
54
54
  parse_specification(param)
55
55
  end
56
56
 
@@ -24,13 +24,13 @@ module Rutema
24
24
  #
25
25
  # * +configuration+ - the Configuration instance of the test run
26
26
  # * +dispatcher+ - unused
27
- def initialize configuration,dispatcher
28
- @configuration=configuration
27
+ def initialize(configuration, _dispatcher)
28
+ @configuration = configuration
29
29
  end
30
30
 
31
31
  ##
32
32
  #
33
- def report specifications,states,errors
33
+ def report(specifications, states, errors)
34
34
  end
35
35
  end
36
36
 
@@ -38,18 +38,18 @@ module Rutema
38
38
  # Event reporters receive and process information continually during a test
39
39
  # run
40
40
  class EventReporter
41
- def initialize configuration,dispatcher
42
- @configuration=configuration
43
- @queue=dispatcher.subscribe(self.object_id)
41
+ def initialize(configuration, dispatcher)
42
+ @configuration = configuration
43
+ @queue = dispatcher.subscribe(object_id)
44
44
  end
45
45
 
46
46
  def run!
47
- @thread=Thread.new do
48
- while true do
49
- data=@queue.pop
47
+ @thread = Thread.new do
48
+ loop do
49
+ data = @queue.pop
50
50
  begin
51
51
  update(data) if data
52
- rescue
52
+ rescue StandardError
53
53
  puts "#{self.class} failed with #{$!.message}"
54
54
  raise
55
55
  end
@@ -57,104 +57,114 @@ module Rutema
57
57
  end
58
58
  end
59
59
 
60
- def update data
60
+ def update(data)
61
61
  end
62
62
 
63
63
  def exit
64
64
  puts "Exiting #{self.class}" if $DEBUG
65
- if @thread
66
- puts "Reporter died with #{@queue.size} messages in the queue" unless @thread.alive?
67
- while @queue.size>0 && @thread.alive? do
68
- sleep 0.1
69
- end
70
- Thread.kill(@thread)
71
- end
65
+ return unless @thread
66
+
67
+ puts "Reporter died with #{@queue.size} messages in the queue" unless @thread.alive?
68
+ sleep 0.1 while !@queue.empty? && @thread.alive?
69
+ Thread.kill(@thread)
72
70
  end
73
71
  end
74
- #This reporter is always instantiated and collects all messages fired by the rutema engine
72
+
73
+ # This reporter is always instantiated and collects all messages fired by the rutema engine
75
74
  #
76
- #The collections of errors and states are then at the end of a run fed to the block reporters
77
- class Collector<EventReporter
78
- attr_reader :errors,:states
79
- def initialize params,dispatcher
80
- super(params,dispatcher)
81
- @errors=[]
82
- @states={}
75
+ # The collections of errors and states are then at the end of a run fed to the block reporters
76
+ class Collector < EventReporter
77
+ attr_reader :errors, :states
78
+
79
+ def initialize(params, dispatcher)
80
+ super
81
+ @errors = []
82
+ @states = {}
83
83
  end
84
84
 
85
- def update message
85
+ def update(message)
86
86
  case message
87
87
  when RunnerMessage
88
- test_state=@states[message.test]
88
+ test_state = @states[message.test]
89
89
  if test_state
90
- test_state<<message
90
+ test_state << message
91
91
  else
92
- test_state=Rutema::ReportState.new(message)
92
+ test_state = Rutema::ReportState.new(message)
93
93
  end
94
- @states[message.test]=test_state
94
+ @states[message.test] = test_state
95
95
  when ErrorMessage
96
- @errors<<message
96
+ @errors << message
97
97
  end
98
98
  end
99
99
  end
100
- #A very simple event reporter that outputs to the console
100
+
101
+ # A very simple event reporter that outputs to the console
101
102
  #
102
- #It has three settings: off, normal and verbose.
103
+ # It has three settings: off, normal and verbose.
103
104
  #
104
- #Example configuration:
105
+ # Example configuration:
105
106
  # cfg.reporter={:class=>Rutema::Reporters::Console, "mode"=>"verbose"}
106
- class Console<EventReporter
107
- def initialize configuration,dispatcher
108
- super(configuration,dispatcher)
109
- @mode=configuration.reporters.fetch(self.class,{})["mode"]
107
+ class Console < EventReporter
108
+ def initialize(configuration, dispatcher)
109
+ super
110
+ @mode = configuration.reporters.fetch(self.class, {})["mode"]
110
111
  end
111
- def update message
112
- unless @mode=="off"
113
- case message
114
- when RunnerMessage
115
- if message.status == :error
116
- puts "FATAL|#{message.to_s}"
117
- elsif message.status == :warning
118
- puts "WARNING|#{message.to_s}"
119
- else
120
- puts "#{message.to_s} #{message.status}." if @mode=="verbose"
121
- end
122
- when ErrorMessage
123
- puts message.to_s
124
- when Message
125
- puts message.to_s if @mode=="verbose"
112
+
113
+ # rubocop:disable Metrics/CyclomaticComplexity
114
+ def update(message)
115
+ return if @mode == "off"
116
+
117
+ case message
118
+ when RunnerMessage
119
+ if message.status == :error
120
+ puts "FATAL|#{message}"
121
+ elsif message.status == :warning
122
+ puts "WARNING|#{message}"
123
+ elsif @mode == "verbose"
124
+ puts "#{message} #{message.status}."
126
125
  end
126
+ when ErrorMessage
127
+ puts message
128
+ when Message
129
+ puts message if @mode == "verbose"
127
130
  end
128
131
  end
129
132
  end
133
+ # rubocop:enable Metrics/CyclomaticComplexity
130
134
 
131
- class Summary<BlockReporter
132
- def initialize configuration,dispatcher
133
- super(configuration,dispatcher)
134
- @silent=configuration.reporters.fetch(self.class,{})["silent"]
135
+ # Produces a summary of the test run returning aggregate numbers for tests and failures
136
+ class Summary < BlockReporter
137
+ def initialize(configuration, dispatcher)
138
+ super
139
+ @silent = configuration.reporters.fetch(self.class, {})["silent"]
135
140
  end
136
- def report specs,states,errors
137
- failures=[]
138
- states.each{|k,v| failures<<v.test if v.status==:error}
141
+
142
+ # rubocop:disable Metrics/CyclomaticComplexity
143
+ def report(specs, states, errors)
144
+ failures = []
145
+ states.each_value { |v| failures << v.test if v.status == :error }
139
146
 
140
147
  unless @silent
141
- count_tests_run = states.select { |name, state| !state.is_special }.count
148
+ count_tests_run = states.reject { |_name, state| state.is_special }.count
142
149
  puts "#{errors.size} errors. #{count_tests_run} test cases executed. #{failures.size} failed"
143
150
  unless failures.empty?
144
151
  puts "Failures:"
145
- puts specs.map{|spec| " #{spec.name} - #{spec.filename}" if failures.include?(spec.name)}.compact.join("\n")
152
+ puts specs.map { |spec| " #{spec.name} - #{spec.filename}" if failures.include?(spec.name) }.compact.join("\n")
146
153
  end
147
154
  end
148
- return failures.size+errors.size
155
+ return failures.size + errors.size
149
156
  end
157
+ # rubocop:enable Metrics/CyclomaticComplexity
150
158
  end
151
159
  end
152
160
 
161
+ # rubocop:disable Style/Documentation
153
162
  module Utilities
154
163
  require "fileutils"
155
- def self.write_file filename,content
156
- FileUtils.mkdir_p(File.dirname(filename),:verbose=>false)
157
- File.open(filename, 'wb') {|f| f.write(content) }
158
- end
164
+ def self.write_file(filename, content)
165
+ FileUtils.mkdir_p(File.dirname(filename), :verbose => false)
166
+ File.binwrite(filename, content)
167
+ end
159
168
  end
169
+ # rubocop:enable Style/Documentation
160
170
  end