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
@@ -1,202 +0,0 @@
1
- ############################################################################
2
- ##
3
- ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
- ## All rights reserved.
5
- ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
- ##
7
- ## This file is part of Testability Driver.
8
- ##
9
- ## If you have questions regarding the use of this file, please contact
10
- ## Nokia at testabilitydriver@nokia.com .
11
- ##
12
- ## This library is free software; you can redistribute it and/or
13
- ## modify it under the terms of the GNU Lesser General Public
14
- ## License version 2.1 as published by the Free Software Foundation
15
- ## and appearing in the file LICENSE.LGPL included in the packaging
16
- ## of this file.
17
- ##
18
- ############################################################################
19
-
20
- module TDriver
21
-
22
- class TestObjectFactory
23
-
24
- attr_accessor :timeout, :retry_interval, :test_object_adapter
25
-
26
- def initialize( test_object_adapter )
27
-
28
- #@timeout = 5
29
-
30
- #@retry_interval = 1
31
-
32
- @test_object_adapter = test_object_adapter
33
-
34
- @timeout = MobyUtil::Parameter[ :synchronization_timeout, "20" ].to_f
35
-
36
- @retry_interval = MobyUtil::Parameter[ :synchronization_retry_interval, "1" ].to_f
37
-
38
- end # initialize
39
-
40
- def get_objects( source_data, rules, &block )
41
-
42
- # __multiple_objects
43
- # __all_children
44
- #
45
-
46
- #TDriver::TestObjectIdentificator.new( creation_hash )
47
- # {:type=>"application", :name=>"calculator"}
48
-
49
- test_object_attributes = rules[ :attributes ]
50
-
51
- dynamic_attributes = strip_dynamic_attributes!( test_object_attributes )
52
-
53
- # add keys from rules to dynamic attribute filter list -- to avoid IRB bug
54
- MobyUtil::DynamicAttributeFilter.instance.add_attributes( rules.keys )
55
-
56
- #p dynamic_attributes
57
- #p rules
58
-
59
- refresh = false
60
-
61
- MobyUtil::Retryable.until(
62
-
63
- :timeout => @timeout,
64
- :interval => @retry_interval,
65
- :exception => [ MobyBase::TestObjectNotFoundError, MobyBase::MultipleTestObjectsIdentifiedError ]
66
-
67
- ){
68
-
69
- # refresh source data if refresh flag is set to true
70
- source_data = yield( source_data ) if refresh
71
-
72
- # set refresh flag to true
73
- refresh = true
74
-
75
- matches, rule = @test_object_adapter.get_objects( source_data, test_object_attributes )
76
-
77
- # create string representation of hash merged with and dynamic attributes
78
- rules_string = test_object_attributes.merge( dynamic_attributes ).inspect
79
-
80
- # raise exception if multiple matches found
81
- Kernel::raise MobyBase::MultipleTestObjectsIdentifiedError.new(
82
-
83
- "Multiple test objects found with rule: #{ rules_string }"
84
-
85
- ) if !dynamic_attributes.has_key?( :__index ) and (!( rules[ :multiple_objects ] || false ) and matches.size > 1)
86
-
87
- # raise exception if no matches found
88
- Kernel::raise MobyBase::TestObjectNotFoundError.new(
89
-
90
- "Cannot find object with rule: #{ rules_string }"
91
-
92
- ) if matches.size.zero?
93
-
94
- # ... or proceed if no exceptions raised
95
-
96
- # sort elements if required by caller
97
- # @test_object_adapter.sort_elements....
98
-
99
- # return only one element if index given
100
- matches = [ matches[ dynamic_attributes[ :__index ] ] ] if dynamic_attributes.has_key?( :__index )
101
-
102
- # return array of matching test object(s)
103
- make_test_objects( matches, rules )
104
-
105
- }
106
-
107
- end # get_objects
108
-
109
- private
110
-
111
- def make_test_objects( matches, rules )
112
-
113
- #p rules
114
-
115
- sut = rules[ :sut ]
116
-
117
- # return array of matching test object(s)
118
- matches.collect{ | source_data |
119
-
120
- # get test object type from xml
121
- object_type = @test_object_adapter.test_object_attribute( 'type', source_data )
122
-
123
- # create new test object instance
124
- test_object = MobyBase::TestObject.new(
125
-
126
- # test object factory
127
- self,
128
-
129
- # associated sut
130
- sut,
131
-
132
- # associated parent object; either test object, application or sut
133
- rules[ :parent_object ],
134
-
135
- # test object xml data
136
- source_data
137
-
138
- )
139
-
140
- # apply object composition behaviour to test object
141
- test_object.extend( MobyBehaviour::ObjectBehaviourComposition )
142
-
143
- # TODO: behaviours should be applied by using BehaviourFactory directly
144
- # apply behaviours to test object
145
- test_object.apply_behaviour!(
146
- :object_type => [ '*', object_type ],
147
- :sut_type => [ '*', sut.ui_type ],
148
- :input_type => [ '*', sut.input.to_s ],
149
- :version => [ '*', sut.ui_version ]
150
- )
151
-
152
- # create child accessors
153
- @test_object_adapter.create_child_accessors!( test_object, source_data )
154
-
155
- # TODO: call verification block if defined (verify_ui_dump)
156
-
157
- # # do not make test object verifications if we are operating on the
158
- # # base sut itself (allow run to pass)
159
- # unless parent.kind_of?( MobyBase::SUT )
160
- # verify_ui_dump( sut ) unless sut.verify_blocks.empty?
161
- # end
162
-
163
- # pass test object with behaviours as result
164
- test_object
165
-
166
- }
167
-
168
- end # make_test_objects
169
-
170
- def strip_dynamic_attributes!( hash )
171
-
172
- # remove dynamic attributes from hash and return as result
173
- Hash[
174
-
175
- # iterate through each hash key
176
- hash.select{ | key, value |
177
-
178
- # dynamic attribute name has "__" prefix
179
- if key.to_s =~ /^__/
180
-
181
- # remove dynamic attribute key from hash
182
- hash.delete( key )
183
-
184
- # add to hash
185
- true
186
-
187
- else
188
-
189
- # do not add to hash
190
- false
191
-
192
- end
193
-
194
- }
195
-
196
- ]
197
-
198
- end # strip_dynamic_attributes!
199
-
200
- end # TestObjectFactory
201
-
202
- end # TDriver
@@ -1,434 +0,0 @@
1
- ############################################################################
2
- ##
3
- ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
- ## All rights reserved.
5
- ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
- ##
7
- ## This file is part of Testability Driver.
8
- ##
9
- ## If you have questions regarding the use of this file, please contact
10
- ## Nokia at testabilitydriver@nokia.com .
11
- ##
12
- ## This library is free software; you can redistribute it and/or
13
- ## modify it under the terms of the GNU Lesser General Public
14
- ## License version 2.1 as published by the Free Software Foundation
15
- ## and appearing in the file LICENSE.LGPL included in the packaging
16
- ## of this file.
17
- ##
18
- ############################################################################
19
- module MobyUtil
20
-
21
- class Hooking
22
-
23
- include Singleton
24
-
25
- attr_accessor :wrappee_count
26
- attr_accessor :wrapped_methods
27
- attr_accessor :benchmark
28
-
29
- # list of non-wrappable methods
30
- @@non_wrappable_methods = [ 'instance' ]
31
-
32
- def initialize
33
-
34
- # default values
35
- @wrapped_methods = {}
36
-
37
- @wrappee_count = 0
38
- @benchmark = {}
39
-
40
- @logger_method = nil
41
- @logger_instance = nil
42
-
43
- $mobyutil_hooking_instance = self
44
- $mobyutil_hooking_elapsed_time = []
45
-
46
- $mobyutil_hooking_start_benchmark_time = Time.now
47
- $mobyutil_hooking_last_call_end_time = Time.now
48
-
49
- end
50
-
51
- # Function to set logger instance used by wrapper
52
- # == params
53
- # logger_instance:: Instance of TDriver logger
54
- # == returns
55
- def set_logger_instance( logger_instance )
56
-
57
- @logger_instance = logger_instance
58
-
59
- nil
60
-
61
- end
62
-
63
- # Function to create logger event - this method is called from wrapper
64
- # == params
65
- # text:: Text sent from wrapper
66
- # arguments:: Not in use
67
- # == returns
68
- def log( text, *arguments )
69
-
70
-
71
- unless @logger_instance.nil?
72
-
73
- @logger_instance.debug( "%s" % text ) # if @logger_instance.enabled
74
-
75
- end
76
-
77
- #@logger_instance.log( "debug", "%s" % text ) unless @logger_instance.nil?
78
-
79
- nil
80
-
81
- end
82
-
83
- # Function to hook all instance and static methods of target Class/Module
84
- # == params
85
- # base:: Target Class or Module
86
- # == returns
87
- def hook_methods( _base )
88
-
89
- hook_static_methods( _base )
90
- hook_instance_methods( _base )
91
-
92
- nil
93
-
94
- end
95
-
96
- def add_wrapper( wrapper )
97
-
98
- @wrapped_methods.merge!( wrapper )
99
- @wrappee_count += 1
100
-
101
- end
102
-
103
- # Function to update method runtime & calls count for benchmark
104
- # == params
105
- # method_name:: Name of the target method
106
- # time_elapsed_in_subcalls::
107
- # total_time_elapsed::
108
- def update_method_benchmark( method_name, time_elapsed_in_subcalls, total_time_elapsed )
109
-
110
- @benchmark[ method_name ].tap{ | hash |
111
-
112
- hash[ :time_elapsed ] += ( total_time_elapsed - time_elapsed_in_subcalls )
113
- hash[ :time_elapsed_total ] += total_time_elapsed
114
- hash[ :times_called ] += 1
115
-
116
- }
117
-
118
- end
119
-
120
- def print_benchmark( rules = {} )
121
-
122
- #total_run_time = $mobyutil_hooking_last_call_end_time - $mobyutil_hooking_start_benchmark_time
123
-
124
- total_run_time = 0
125
-
126
- # :sort => :total_time || :times_called || :average_time
127
-
128
- rules = { :sort => :total_time, :order => :ascending, :show_uncalled_methods => true }.merge( rules )
129
-
130
- puts "%-80s %8s %15s %15s %9s %15s" % [ 'Name:', 'Calls:', 'Time total:', 'W/O subcalls:', '%/run', 'Total/call:' ]
131
- puts "%-80s %8s %15s %15s %9s %15s" % [ '-' * 80, '-' * 8, '-' * 15, '-' * 15, '-' * 8, '-' * 15 ]
132
-
133
- # calculate average time for method
134
- ( table = @benchmark ).each{ | key, value |
135
-
136
- table[ key ][ :average_time ] = ( value[ :times_elapsed_total ] == 0 || value[ :times_called ] == 0 ) ? 0 : value[ :time_elapsed_total ] / value[ :times_called ]
137
-
138
- total_run_time += value[ :time_elapsed ]
139
-
140
- }
141
-
142
- table = table.sort{ | method_a, method_b |
143
-
144
- case rules[ :sort ]
145
-
146
- when :name
147
- method_a[ 0 ] <=> method_b[ 0 ]
148
-
149
- when :times_called
150
- method_a[ 1 ][ :times_called ] <=> method_b[ 1 ][ :times_called ]
151
-
152
- when :total_time
153
- method_a[ 1 ][ :time_elapsed_total ] <=> method_b[ 1 ][ :time_elapsed_total ]
154
-
155
- when :total_time_no_subs
156
- method_a[ 1 ][ :time_elapsed ] <=> method_b[ 1 ][ :time_elapsed ]
157
-
158
- when :percentage
159
-
160
- ( ( method_a[ 1 ][ :time_elapsed ].to_f / total_run_time.to_f ) * 100 ) <=> ( ( method_b[ 1 ][ :time_elapsed ].to_f / total_run_time.to_f ) * 100 )
161
-
162
- when :average_time
163
- method_a[ 1 ][ :average_time ] <=> method_b[ 1 ][ :average_time ]
164
-
165
- else
166
-
167
- Kernel::raise ArgumentError.new("Invalid sorting rule, valid rules are :name, :times_called, :total_time, :total_time_no_subs, :percentage or :average_time")
168
-
169
- end
170
-
171
- }
172
-
173
- case rules[ :order ]
174
-
175
- when :ascending
176
- # do nothing
177
-
178
- when :descending
179
- table = table.reverse
180
-
181
- else
182
-
183
- Kernel::raise ArgumentError.new("Invalid sort order rule, valid rules are :ascending, :descending")
184
-
185
- end
186
-
187
- total_percentage = 0.0
188
- total_time_elapsed_total = 0.0
189
- total_average = 0.0
190
- total_calls = 0
191
-
192
- table.each{ | method |
193
-
194
- puts "%-80s %8s %15.8f %15.8f %8.3f%% %15.8f" % [
195
- method[ 0 ],
196
- method[ 1 ][ :times_called ],
197
- method[ 1 ][ :time_elapsed_total ],
198
- method[ 1 ][ :time_elapsed ],
199
-
200
- ( ( method[ 1 ][ :time_elapsed ].to_f / total_run_time.to_f ) * 100 ),
201
-
202
- method[ 1 ][ :average_time ]
203
- ] unless !rules[ :show_uncalled_methods ] && method[ 1 ][ :times_called ] == 0
204
-
205
- total_percentage += ( ( method[ 1 ][ :time_elapsed ].to_f / total_run_time.to_f ) * 100 )
206
-
207
- total_calls += method[ 1 ][ :times_called ]
208
- total_time_elapsed_total += method[ 1 ][ :time_elapsed_total ]
209
- total_average += method[ 1 ][ :average_time ]
210
-
211
- }
212
-
213
- puts "%-80s %8s %15s %15s %9s %15s" % [ '-' * 80, '-' * 8, '-' * 15, '-' * 15, '-' * 8, '-' * 15 ]
214
-
215
- puts "%-80s %8s %15.6f %15.6f %8.3f%% %15.8f" % [ 'Total:', total_calls, total_time_elapsed_total, total_run_time, total_percentage, total_average ]
216
-
217
- end
218
-
219
-
220
- private
221
-
222
- # Function to hook a method
223
- # == params
224
- # base:: Class or Module
225
- # method_name:: Name of the method
226
- # method_type:: public, private or static
227
- # == returns
228
- def hook_method( base, method_name, method_type )
229
-
230
- # create only one wrapper for each method
231
- unless MobyUtil::Hooking.instance.wrapped_methods.has_key?( "#{ base.name }::#{ method_name }" )
232
-
233
- # evaluate the generated wrapper source code
234
- eval("base.#{ base.class.name.downcase }_eval( \"#{ make_wrapper( base, method_name.to_s, method_type.to_s )}\" )") if [ Class, Module ].include?( base.class )
235
-
236
- end
237
-
238
- nil
239
-
240
- end
241
-
242
- # Function to hook static methods for given Class or Module
243
- # == params
244
- # base:: Target Class or Module
245
- # == returns
246
- def hook_static_methods( _base )
247
-
248
- if [ Class, Module ].include?( _base.class )
249
-
250
- _base.singleton_methods( false ).each { | method_name |
251
-
252
- hook_method( _base, method_name, "static" ) unless @@non_wrappable_methods.include?( method_name )
253
-
254
- }
255
-
256
- end
257
-
258
- nil
259
- end
260
-
261
- # Function to hook instance methods for given Class or Module
262
- # == params
263
- # base:: Target Class or Module
264
- # == returns
265
- def hook_instance_methods( _base )
266
-
267
- if [ Class, Module ].include?( _base.class )
268
-
269
- { :public => _base.public_instance_methods( false ), :private => _base.private_instance_methods( false ), :protected => _base.protected_instance_methods( false ) }.each { | method_type, methods |
270
-
271
- methods.each { | method_name | hook_method( _base, method_name, method_type.to_s ) unless /__wrappee_\d+/i.match( method_name ) }
272
-
273
- }
274
-
275
- end
276
-
277
- nil
278
- end
279
-
280
- # Function to retrieve method path (e.g. Module1::Module2::Class1)
281
- # == params
282
- # base:: Target Class or Module
283
- # == returns
284
- # String:: Method path
285
- def method_path( _base )
286
-
287
- if [ Class, Module ].include?( _base.class )
288
-
289
- _base.name
290
-
291
- else
292
-
293
- _base.class.name
294
-
295
- end
296
-
297
- end
298
-
299
- # Function to generate unique name for wrappee method
300
- # == params
301
- # method_name:: Name of the target method
302
- # == returns
303
- # String:: Unique name for wrappee method
304
- def create_wrappee_name( method_name )
305
-
306
- wrappee_name = "non_pritanble_method_name" if ( wrappee_name = ( /[a-z0-9_]*/i.match( method_name ) ) ).length == 0
307
-
308
- wrappee_name = "__wrappee_#{ @wrappee_count }__#{ wrappee_name }"
309
-
310
- end
311
-
312
- # Function for create source code of wrapper for method
313
- # == params
314
- # base:: Class or Module
315
- # method_name:: Name of the method
316
- # method_type:: public, private or static
317
- # == returns
318
- # String:: source code
319
- def make_wrapper( base, method_name, method_type = nil )
320
-
321
- # method name with namespace
322
- base_and_method_name = "#{ base.name }::#{ method_name }"
323
-
324
- # add method to benchmark table
325
- @benchmark[ base_and_method_name ] = { :time_elapsed => 0 , :times_called => 0, :time_elapsed_total => 0 } if ENV[ 'TDRIVER_BENCHMARK' ].to_s.downcase == 'true'
326
-
327
- # create new name for original method
328
- original_method_name = create_wrappee_name( method_name )
329
-
330
- # add method to wrapper methods list
331
- @wrapped_methods.merge!( base_and_method_name => nil )
332
- @wrappee_count += 1
333
-
334
- case method_type
335
-
336
- when 'public', 'private', 'static'
337
-
338
- source = "
339
- #{
340
- # this is needed if method is static
341
- "class << self" if method_type == 'static'
342
-
343
- }
344
-
345
- # create a copy of original method
346
- alias_method :#{ original_method_name }, :#{ method_name }
347
-
348
- #{
349
-
350
- if method_type == 'static'
351
-
352
- # undefine original version if static method
353
- "self.send( :undef_method, :#{ method_name } )"
354
-
355
- else
356
-
357
- # method visiblity unless method type is static
358
- "#{ method_type }"
359
-
360
- end
361
-
362
-
363
- }
364
-
365
- def #{ method_name }( *args, &block )
366
-
367
- # log method call
368
- $mobyutil_hooking_instance.log( '#{ method_path( base ) }.#{ method_name }', nil )
369
-
370
- #{
371
-
372
- if ENV[ 'TDRIVER_BENCHMARK' ].to_s.downcase == 'true'
373
-
374
- "# store start time for performance measurement
375
- start_time = Time.now
376
-
377
- # Time elapsed in sub calls
378
- $mobyutil_hooking_elapsed_time << 0.0
379
-
380
- begin
381
-
382
- # call original method
383
- result = send(:#{ original_method_name }, *args, &block )
384
-
385
- rescue Exception => exception
386
-
387
- raise exception
388
-
389
- ensure
390
-
391
- # calculate actual elapsed time, including time elapsed in sub calls
392
- elapsed_time = ( ( $mobyutil_hooking_last_call_end_time = Time.now ) - start_time )
393
-
394
- # elapsed time in sub calls
395
- elapsed_time_in_subcalls = $mobyutil_hooking_elapsed_time.pop || 0
396
-
397
- # add elapsed time to caller method
398
- $mobyutil_hooking_elapsed_time[ -1 ] += elapsed_time unless $mobyutil_hooking_elapsed_time.empty?
399
-
400
- # store performance results to benchmark hash
401
- $mobyutil_hooking_instance.update_method_benchmark( '#{ base_and_method_name }', elapsed_time_in_subcalls, elapsed_time )
402
-
403
- end
404
-
405
- # return results
406
- result"
407
-
408
- else
409
-
410
- "# call original method
411
- result = send(:#{ original_method_name }, *args, &block )"
412
-
413
- end
414
-
415
- }
416
-
417
- end
418
-
419
- private :#{ original_method_name }
420
-
421
- #{
422
-
423
- # this is needed if method is static
424
- "end" if method_type == 'static'
425
-
426
- }"
427
-
428
- end
429
-
430
- end
431
-
432
- end # Hooking
433
-
434
- end # MobyUtil