testability-driver 1.0.3 → 1.0.4

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 (116) hide show
  1. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +2 -2
  2. data/lib/tdriver-devtools/tdriver-devtools.rb +1 -1
  3. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +3 -3
  4. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +6 -1
  5. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +5 -3
  6. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +1 -1
  7. data/lib/tdriver/base/behaviour/factory.rb +225 -225
  8. data/lib/tdriver/base/errors.rb +1 -1
  9. data/lib/tdriver/base/state_object.rb +227 -179
  10. data/lib/tdriver/base/sut/controller.rb +2 -2
  11. data/lib/tdriver/base/sut/factory.rb +190 -182
  12. data/lib/tdriver/base/sut/generic/behaviours/application.rb +69 -25
  13. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +1 -1
  14. data/lib/tdriver/base/sut/generic/behaviours/find.rb +4 -4
  15. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +3 -3
  16. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +350 -165
  17. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +9 -9
  18. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +191 -103
  19. data/lib/tdriver/base/sut/generic/commands/application.rb +1 -1
  20. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +1 -1
  21. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +1 -1
  22. data/lib/tdriver/base/sut/generic/plugin.rb +1 -1
  23. data/lib/tdriver/base/sut/sut.rb +5 -1
  24. data/lib/tdriver/base/test_object/abstract.rb +136 -151
  25. data/lib/tdriver/base/test_object/adapter.rb +293 -82
  26. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +20 -17
  27. data/lib/tdriver/base/test_object/behaviours/test_object.rb +159 -532
  28. data/lib/tdriver/base/test_object/cache.rb +1 -1
  29. data/lib/tdriver/base/test_object/factory.rb +254 -605
  30. data/lib/tdriver/base/test_object/identificator.rb +1 -1
  31. data/lib/tdriver/base/test_object/loader.rb +1 -1
  32. data/lib/tdriver/base/test_object/verification.rb +17 -17
  33. data/lib/tdriver/loader.rb +20 -9
  34. data/lib/tdriver/report/report.rb +5 -0
  35. data/lib/tdriver/report/report_creator.rb +2 -2
  36. data/lib/tdriver/report/report_cucumber_listener.rb +4 -4
  37. data/lib/tdriver/report/report_cucumber_reporter.rb +4 -4
  38. data/lib/tdriver/report/report_execution_statistics.rb +22 -22
  39. data/lib/tdriver/report/report_grouping.rb +2 -2
  40. data/lib/tdriver/report/report_javascript.rb +11 -4
  41. data/lib/tdriver/report/report_test_case_run.rb +2 -2
  42. data/lib/tdriver/report/report_test_run.rb +5 -5
  43. data/lib/tdriver/report/report_test_unit.rb +74 -26
  44. data/lib/tdriver/report/report_writer.rb +70 -13
  45. data/lib/tdriver/tdriver.rb +17 -8
  46. data/lib/tdriver/util/common/array.rb +1 -1
  47. data/lib/tdriver/util/common/crc16.rb +1 -1
  48. data/lib/tdriver/util/common/environment.rb +1 -1
  49. data/lib/tdriver/util/common/file.rb +18 -9
  50. data/lib/tdriver/util/common/gem.rb +1 -1
  51. data/lib/tdriver/util/common/hash.rb +21 -0
  52. data/lib/tdriver/util/common/kernel.rb +1 -1
  53. data/lib/tdriver/util/common/loader.rb +5 -2
  54. data/lib/tdriver/util/common/numeric.rb +54 -3
  55. data/lib/tdriver/util/common/retryable.rb +30 -12
  56. data/lib/tdriver/util/common/stackable.rb +185 -0
  57. data/lib/tdriver/util/common/string.rb +21 -5
  58. data/lib/tdriver/util/{dbaccess/dbaccess.rb → database/access.rb} +4 -1
  59. data/lib/tdriver/util/{dbaccess/dbconnection.rb → database/connection.rb} +3 -0
  60. data/lib/tdriver/util/{dbaccess → database}/error.rb +0 -1
  61. data/lib/tdriver/util/{dbaccess → database}/loader.rb +5 -6
  62. data/lib/tdriver/util/{dynamic_attribute_filter.rb → filters/dynamic_attributes.rb} +1 -1
  63. data/lib/tdriver/util/hooking/hooking.rb +477 -0
  64. data/lib/tdriver/util/loader.rb +35 -29
  65. data/lib/tdriver/util/localisation/error.rb +0 -1
  66. data/lib/tdriver/util/localisation/loader.rb +1 -4
  67. data/lib/tdriver/util/localisation/localisation.rb +30 -27
  68. data/lib/tdriver/util/{common.rb → logger/loader.rb} +2 -4
  69. data/lib/tdriver/util/logger/logger.rb +574 -0
  70. data/lib/tdriver/util/operator_data/loader.rb +4 -3
  71. data/lib/tdriver/util/operator_data/operator_data.rb +5 -5
  72. data/lib/tdriver/util/parameter/parameter.rb +7 -1
  73. data/lib/tdriver/util/parameter/parameter_hash.rb +1 -1
  74. data/lib/tdriver/util/parameter/parameter_template.rb +1 -1
  75. data/lib/tdriver/util/parameter/parameter_user_api.rb +28 -20
  76. data/lib/tdriver/util/parameter/parameter_xml.rb +1 -1
  77. data/lib/tdriver/util/plugin/abstract.rb +1 -1
  78. data/lib/tdriver/util/plugin/service.rb +1 -1
  79. data/lib/tdriver/util/{localisation.rb → recorder/loader.rb} +4 -3
  80. data/lib/tdriver/util/recorder/recorder.rb +66 -0
  81. data/lib/tdriver/util/recorder/scripter.rb +258 -0
  82. data/lib/tdriver/util/{stats.rb → statistics/statistics.rb} +7 -8
  83. data/lib/tdriver/util/user_data/error.rb +0 -1
  84. data/lib/tdriver/util/user_data/loader.rb +1 -2
  85. data/lib/tdriver/util/user_data/user_data.rb +6 -6
  86. data/lib/tdriver/util/video/camera.rb +67 -0
  87. data/lib/tdriver/util/video/camera_linux.rb +139 -0
  88. data/lib/tdriver/util/video/camera_windows.rb +174 -0
  89. data/lib/tdriver/util/video/loader.rb +31 -0
  90. data/lib/tdriver/util/video/video_utils.rb +139 -0
  91. data/lib/tdriver/util/xml/abstraction.rb +56 -5
  92. data/lib/tdriver/util/xml/builder.rb +2 -5
  93. data/lib/tdriver/util/{parameter.rb → xml/comment.rb} +10 -2
  94. data/lib/tdriver/util/xml/loader.rb +32 -22
  95. data/lib/tdriver/util/xml/nil_node.rb +2 -2
  96. data/lib/tdriver/util/xml/parsers/loader.rb +0 -1
  97. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +18 -44
  98. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +9 -13
  99. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +9 -3
  100. data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
  101. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +6 -11
  102. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +2 -122
  103. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +26 -16
  104. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +203 -0
  105. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +1 -2
  106. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +2 -20
  107. data/lib/tdriver/util/xml/xml.rb +52 -20
  108. data/lib/tdriver/verify/verify.rb +238 -81
  109. data/xml/behaviours/generic.xml +12 -10
  110. metadata +156 -180
  111. data/lib/tdriver/base/test_object/factory_new.rb +0 -202
  112. data/lib/tdriver/util/hooking.rb +0 -434
  113. data/lib/tdriver/util/logger.rb +0 -506
  114. data/lib/tdriver/util/recorder.rb +0 -297
  115. data/lib/tdriver/util/video_utils.rb +0 -384
  116. data/lib/tdriver/util/xml/nil_element.rb +0 -89
@@ -18,7 +18,6 @@
18
18
  ############################################################################
19
19
 
20
20
  include TDriverReportJavascript
21
-
22
21
  module TDriverReportWriter
23
22
 
24
23
  def write_style_sheet(page)
@@ -327,11 +326,10 @@ a:hover { color:White; background-color:#005B9A;}
327
326
  }
328
327
  #statistics_table th
329
328
  {
330
- font-size: 13px;
331
- font-weight: normal;
332
329
  padding: 8px;
333
- background: #b9c9fe;
334
- color: #039;
330
+ border-bottom: 1px solid Black;
331
+ color: #669;
332
+ border-top: 1px solid transparent;
335
333
  }
336
334
  #statistics_table td
337
335
  {
@@ -411,7 +409,7 @@ FORM { DISPLAY:inline; }
411
409
 
412
410
  html.isJS .togList dd
413
411
  {
414
- display: none;
412
+ display: block;
415
413
  }
416
414
  input.btn {
417
415
  color:#050;
@@ -438,9 +436,9 @@ display: none;
438
436
  File.open(page, 'w') {|f| f.write(css) }
439
437
  css=nil
440
438
  end
439
+
441
440
  def format_duration(seconds)
442
- if Gem.available?('chronic_duration')
443
- require 'chronic_duration'
441
+ if Gem.available?('chronic_duration')
444
442
  duration_str=ChronicDuration.output(seconds)
445
443
  else
446
444
  m, s = seconds.divmod(60)
@@ -448,6 +446,64 @@ display: none;
448
446
  end
449
447
  duration_str
450
448
  end
449
+
450
+ def write_stack_file_to_html(file,page,linen)
451
+ code=File.read(file)
452
+ html_code=[]
453
+ code_line=1
454
+ code.each do |line|
455
+ if linen.to_s==code_line.to_s
456
+ html_code << "<b><a style=\"color: #FF0000\" name=\"#{code_line}\">#{code_line}: #{line.gsub(' ','&nbsp;' )} </a></b><br />"
457
+ else
458
+ html_code << "<a name=\"#{code_line}\">#{code_line}: #{line.gsub(' ','&nbsp;' )} </a><br />"
459
+ end
460
+ code_line+=1
461
+ end
462
+ File.open(page, 'w') do |f2|
463
+ f2.puts html_code
464
+ end
465
+ end
466
+
467
+ def copy_code_file_to_test_case_report(file,folder,linen)
468
+ begin
469
+ FileUtils.mkdir_p(folder.to_s+'/stack_files') if File::directory?(folder.to_s+'/stack_files')==false
470
+ if File.directory?("#{Dir.pwd}/#{@report_folder}/#{folder}")
471
+ write_stack_file_to_html(file,"#{Dir.pwd}/#{@report_folder}/#{folder}/stack_files/#{File.basename(file)}.html",linen)
472
+ FileUtils.copy(file,"#{Dir.pwd}/#{@report_folder}/#{folder}/stack_files/#{File.basename(file)}")
473
+ else
474
+ write_stack_file_to_html(file,"#{folder}/stack_files/#{File.basename(file)}.html",linen)
475
+ FileUtils.copy(file,"#{folder}/stack_files/#{File.basename(file)}")
476
+ end
477
+
478
+ rescue Exception => e
479
+ puts e.message
480
+ puts e.backtrace
481
+ end
482
+ end
483
+
484
+ def reporter_link_to_code(log_line,folder=nil)
485
+ begin
486
+ log_line.gsub(/([\w\*\/\w\/\.-]+)\:(\d+)/) do |match|
487
+ line=match[/(\d+)/]
488
+ f=match[/([\w\*\/\w\/\.-]+)/]
489
+ file="#{File.dirname(f.strip)}/#{File.basename(f.strip)}"
490
+ file = file if File.exist?(file)
491
+ file = "#{Dir.pwd}/#{file}" if File.exist?("#{Dir.pwd}/#{file}")
492
+ if File.exist?(file) && match.include?('testability-driver')==false
493
+ copy_code_file_to_test_case_report(file,folder,line.strip)
494
+ link_to_stack='<a style="color: #FF0000" href="stack_files/'<<
495
+ File.basename(file.to_s)+'.html#'+line.to_s<<
496
+ '">'+match+'</a>'
497
+ log_line=log_line.gsub(match,link_to_stack)
498
+ end
499
+ end
500
+ rescue Exception => e
501
+ puts e.message
502
+ puts e.backtrace
503
+ end
504
+ log_line
505
+ end
506
+
451
507
  def behaviour_log_summary(log,log_format='string')
452
508
  begin
453
509
  log_table = Array.new
@@ -566,11 +622,12 @@ display: none;
566
622
  '-'
567
623
  end
568
624
  end
569
- def format_execution_log(log)
625
+ def format_execution_log(log,folder=nil)
570
626
  begin
571
627
  formatted_log=Array.new
572
628
  log.each do |line|
573
- if line.include?('test_unit.rb')
629
+ line=reporter_link_to_code(line,folder)
630
+ if line.include?('testability-driver')==false
574
631
  formatted_log << line.gsub('PASSED','<b style="color: #00FF00">PASSED</b>').gsub('FAILED','<b style="color: #FF0000">FAILED</b>').gsub('SKIPPED','<b>SKIPPED</b>')
575
632
  else
576
633
  formatted_log << "<b style=\"color: #2554C7\">#{line}</b>".gsub('PASSED','<b style="color: #00FF00">PASSED</b>').gsub('FAILED','<b style="color: #FF0000">FAILED</b>').gsub('SKIPPED','<b>SKIPPED</b>')
@@ -700,7 +757,7 @@ display: none;
700
757
  '<td style="font-weight: 700">'<<
701
758
  'Details</td>'<<
702
759
  '<td style="font-size: small; font-weight: bold">'<<
703
- format_execution_log(@test_case_execution_log)<<
760
+ format_execution_log(@test_case_execution_log,folder.to_s)<<
704
761
  '</td></tr>'
705
762
 
706
763
  if File::directory?(folder.to_s+'/crash_files')==true
@@ -786,7 +843,7 @@ display: none;
786
843
  if @test_case_behaviour_log.length > 0
787
844
  html_body=html_body<<
788
845
  '<dl class="togList">'<<
789
- '<dt onclick="tog(this)" style="background-color: #CCCCCC;"><b style="font-size: large"><span><input id="Button1" type="button" value="Open" class="btn" /></span> Behaviours</b></dt>'<<
846
+ '<dt onclick="tog(this)" style="background-color: #CCCCCC;"><b style="font-size: large"><span><input id="Button1" type="button" value="Close" class="btn" /></span> Behaviours</b></dt>'<<
790
847
  '<dd style="font-size: small">'<<
791
848
  format_behaviour_log(@test_case_behaviour_log)<<
792
849
  '</dd>'<<
@@ -795,7 +852,7 @@ display: none;
795
852
  if @test_case_user_data!=nil && !@test_case_user_data.empty?
796
853
  html_body=html_body<<
797
854
  '<dl class="togList">'<<
798
- '<dt onclick="tog(this)" style="background-color: #CCCCCC;"><b style="font-size: large"><span><input id="Button1" type="button" value="Open" class="btn" /></span> User Data</b></dt>'<<
855
+ '<dt onclick="tog(this)" style="background-color: #CCCCCC;"><b style="font-size: large"><span><input id="Button1" type="button" value="Close" class="btn" /></span> User Data</b></dt>'<<
799
856
  '<dd style="font-size: small">'<<
800
857
  format_user_log_table( @test_case_user_data,@test_case_user_data_columns)<<
801
858
  '</dd>'<<
@@ -34,8 +34,16 @@ $KCODE = 'u'
34
34
  # prevent Object#id Warnings
35
35
  Object.send( :undef_method, :id ) if Object.respond_to?( :id )
36
36
 
37
+ # TODO: document me
38
+ def require_relative( file )
39
+
40
+ # require with full expanded path
41
+ require File.expand_path( File.join( File.dirname( caller.first.scan( /(.*?):/ ).to_s ), file ) )
42
+
43
+ end
44
+
37
45
  # load all required components
38
- require File.expand_path( File.join( File.dirname( __FILE__ ), 'loader' ) )
46
+ require File.expand_path( File.join( File.dirname( __FILE__ ), 'loader.rb' ) )
39
47
 
40
48
  module TDriver
41
49
 
@@ -102,30 +110,31 @@ module TDriver
102
110
  # Wrapper for MobyUtil::Parameter.configured_suts to retrieve all configured sut names
103
111
  def self.suts
104
112
 
105
- MobyUtil::Parameter.configured_suts
113
+ $parameters.configured_suts
106
114
 
107
115
  end
108
116
 
109
117
  # Wrapper for MobyUtil::ParameterUserAPI class with methods e.g. [] and []=, files and load_xml etc.
110
118
  def self.parameter
111
119
 
112
- @matti_parameter_instance || ( @matti_parameter_instance = MobyUtil::ParameterUserAPI.instance )
113
-
120
+ $parameters_api
121
+
114
122
  end
115
123
 
124
+ # Wrapper for MobyUtil::Logger class
116
125
  def self.logger
117
126
 
118
- @tdriver_logger_instance || ( @tdriver_logger_instance = MobyUtil::Logger.instance )
119
-
127
+ $logger
128
+
120
129
  end
121
130
 
122
131
  # enable hooking for performance measurement & debug logging
123
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
132
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
124
133
 
125
134
  end # TDriver
126
135
 
127
136
  # enable logging engine
128
- MobyUtil::Logger.instance.enable_logging()
137
+ $logger.enable_logging
129
138
 
130
139
  # initialization done, everything is ready
131
140
  $TDRIVER_INITIALIZED = true
@@ -32,7 +32,7 @@ module MobyUtil
32
32
  end
33
33
 
34
34
  # enable hooking for performance measurement & debug logging
35
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
35
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
36
36
 
37
37
  end # ArrayHelper
38
38
 
@@ -93,7 +93,7 @@ module CRC
93
93
  end
94
94
 
95
95
  # enable hooking for performance measurement & debug logging
96
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
96
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
97
97
 
98
98
  end # Crc16
99
99
 
@@ -146,7 +146,7 @@ module MobyUtil
146
146
  end
147
147
 
148
148
  # enable hooking for performance measurement & debug logging
149
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
149
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
150
150
 
151
151
  end # EnvironmentHelper
152
152
 
@@ -17,7 +17,7 @@
17
17
  ##
18
18
  ############################################################################
19
19
 
20
- require 'ftools'
20
+ require "fileutils" unless defined?( ::FileUtils )
21
21
 
22
22
  module MobyUtil
23
23
 
@@ -49,7 +49,12 @@ module MobyUtil
49
49
 
50
50
  # deterimine caller methods working folder
51
51
  source_path = File.dirname( MobyUtil::KernelHelper.parse_caller( caller(3).first ).first )
52
-
52
+
53
+ # Compatiblity for Ruby 1.9.2 caller format
54
+ if source_path == "." || source_path[0].to_s == "<"
55
+ source_path = File.dirname( MobyUtil::KernelHelper.parse_caller( caller(2).first ).first )
56
+ end
57
+
53
58
  path.each{ | path |
54
59
 
55
60
  # expand path if given path is relative path
@@ -60,7 +65,7 @@ module MobyUtil
60
65
 
61
66
  require_files = Dir.glob( MobyUtil::FileHelper.fix_path( path ) )
62
67
 
63
- Kernel::raise RuntimeError.new( "File not found %s" % [ path ] ) if !File.directory?( path ) && !File.file?( path ) && require_files.empty?
68
+ Kernel::raise RuntimeError, "File not found #{ path }" if !File.directory?( path ) && !File.file?( path ) && require_files.empty?
64
69
 
65
70
  # load each module found from given folder
66
71
  require_files.each { | module_name |
@@ -94,7 +99,7 @@ module MobyUtil
94
99
  # == params
95
100
  # == returns
96
101
  # String:: String presentation of TDriver home directory
97
- def self.tdriver_home()
102
+ def self.tdriver_home
98
103
 
99
104
  File.expand_path(
100
105
  MobyUtil::FileHelper.fix_path(
@@ -150,7 +155,7 @@ module MobyUtil
150
155
 
151
156
  _file_path = MobyUtil::FileHelper.fix_path( _file_path )
152
157
 
153
- MobyUtil::FileHelper.is_relative_path?( _file_path ) ? File.join( MobyUtil::FileHelper.tdriver_home, _file_path ) : _file_path
158
+ File.expand_path( MobyUtil::FileHelper.is_relative_path?( _file_path ) ? File.join( MobyUtil::FileHelper.tdriver_home, _file_path ) : _file_path )
154
159
 
155
160
  end
156
161
 
@@ -165,8 +170,12 @@ module MobyUtil
165
170
  # ParameterFileParseError:: If parsing failes
166
171
  def self.get_file( file_path )
167
172
 
173
+ #p __method__, file_path, caller
174
+
175
+ #file_path.check_type( String, "wrong argument type $1 for get_file method (expected $2)")
176
+
168
177
  # raise exception if file name is empty or nil
169
- Kernel::raise EmptyFilenameError.new( "File name is empty or not defined" ) if file_path.nil? || file_path.to_s.empty?
178
+ Kernel::raise EmptyFilenameError, "File name is empty or not defined" if file_path.nil? || file_path.to_s.empty?
170
179
 
171
180
  # raise exception if file name is file_path variable format other than string
172
181
  Kernel::raise UnexpectedVariableTypeError.new( "Invalid filename format %s (Expected: %s)" % [ file_path.class, "String"] ) if !file_path.kind_of?( String )
@@ -281,11 +290,11 @@ module MobyUtil
281
290
 
282
291
  Kernel::raise RuntimeError.new( "Unable to copy %s to %s due to source file does not exist" % [ source, destination ] ) unless File.exist?( source )
283
292
 
284
- File.copy(
293
+ ::FileUtils.copy(
285
294
 
286
295
  MobyUtil::FileHelper.fix_path( source ),
287
296
  destination,
288
- verbose
297
+ :verbose => verbose
289
298
 
290
299
  ) unless ( !overwrite && File.exist?( destination ) )
291
300
 
@@ -314,7 +323,7 @@ module MobyUtil
314
323
  end
315
324
 
316
325
  # enable hooking for performance measurement & debug logging
317
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
326
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
318
327
 
319
328
  end # FileHelper
320
329
 
@@ -102,7 +102,7 @@ module MobyUtil
102
102
  end
103
103
 
104
104
  # enable hooking for performance measurement & debug logging
105
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
105
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
106
106
 
107
107
  end # GemHelper
108
108
 
@@ -97,6 +97,27 @@ class Hash
97
97
 
98
98
  end
99
99
 
100
+ # remove keys from hash, return hash of deleted keys as result
101
+ def delete_keys!( *keys )
102
+
103
+ deleted_keys = []
104
+
105
+ Hash[ keys.flatten.collect{ | key | [ key, delete( key ) ] if has_key?( key ) }.compact ]
106
+
107
+ end
108
+
109
+ # delete multiple keys from hash, does not modify original hash
110
+ def delete_keys( *keys )
111
+
112
+ # create a duplicate of current hash
113
+ result = dup
114
+
115
+ keys.flatten.each{ | key | result.delete( key ) }
116
+
117
+ result
118
+
119
+ end
120
+
100
121
  # store keys and values to hash if not already defined
101
122
  def default_values( hash )
102
123
 
@@ -197,7 +197,7 @@ module MobyUtil
197
197
  end
198
198
 
199
199
  # enable hooking for performance measurement & debug logging
200
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
200
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
201
201
 
202
202
  end # KernelHelper
203
203
 
@@ -36,8 +36,11 @@ require 'rbconfig' # ??
36
36
  'file.rb',
37
37
  'gem.rb',
38
38
  'kernel.rb',
39
- 'retryable.rb' ].each{ | filename |
39
+ 'retryable.rb',
40
+ 'stackable.rb'
40
41
 
41
- require File.expand_path( File.join( File.dirname( __FILE__ ), filename ) )
42
+ ].each{ | filename |
43
+
44
+ require File.expand_path( File.join( File.dirname( __FILE__ ), filename ) )
42
45
 
43
46
  }
@@ -20,20 +20,71 @@
20
20
  # extend Ruby Numeric class functionality
21
21
  class Numeric
22
22
 
23
+ # TODO: document me
23
24
  def positive?
25
+
24
26
  self > 0
27
+
25
28
  end
26
-
29
+
30
+ # TODO: document me
27
31
  def non_negative?
32
+
28
33
  self >= 0
34
+
29
35
  end
30
-
36
+
37
+ # TODO: document me
31
38
  def non_positive?
39
+
32
40
  self <= 0
41
+
33
42
  end
34
-
43
+
44
+ # TODO: document me
35
45
  def negative?
46
+
36
47
  self < 0
48
+
49
+ end
50
+
51
+ # TODO: document me
52
+ def limit( minimum_value, maximum_value )
53
+
54
+ value = self
55
+
56
+ value.min( minimum_value ).max( maximum_value )
57
+
58
+ end
59
+
60
+ # TODO: document me
61
+ def max( value )
62
+
63
+ if value.kind_of?( Numeric )
64
+
65
+ self > value ? value : self
66
+
67
+ else
68
+
69
+ raise TypeError, 'wrong type %2 for value (expected Numeric)'
70
+
71
+ end
72
+
73
+ end
74
+
75
+ # TODO: document me
76
+ def min( value )
77
+
78
+ if value.kind_of?( Numeric )
79
+
80
+ self < value ? value : self
81
+
82
+ else
83
+
84
+ raise TypeError, 'wrong type %2 for value (expected Numeric)'
85
+
86
+ end
87
+
37
88
  end
38
89
 
39
90
  end