testability-driver 1.0.3 → 1.0.4

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