testability-driver 1.2.1 → 1.3.0
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.
- data/bin/tdriver-devtools +0 -0
- data/ext/native_extensions.c +165 -6
- data/lib/tdriver-devtools/behaviour/old/xml/update +0 -0
- data/lib/tdriver-devtools/behaviour/xml/generate.rb +0 -0
- data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +15 -1
- data/lib/tdriver-devtools/doc/update +0 -0
- data/lib/tdriver-devtools/doc/xslt/template.xsl +24 -14
- data/lib/tdriver-devtools/doc/xslt/update +0 -0
- data/lib/tdriver-devtools/tdriver-devtools.rb +0 -0
- data/lib/tdriver-devtools/tests/feature_tests/update +0 -0
- data/lib/tdriver/base/behaviour/{behaviour.rb → abstract.rb} +3 -6
- data/lib/tdriver/base/behaviour/behaviours/object_abstract.rb +107 -0
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +2 -2
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +47 -37
- data/lib/tdriver/base/behaviour/factory.rb +260 -382
- data/lib/tdriver/base/behaviour/loader.rb +22 -4
- data/lib/tdriver/base/controller/abstraction.rb +56 -0
- data/lib/tdriver/base/controller/loader.rb +21 -0
- data/lib/tdriver/base/loader.rb +3 -1
- data/lib/tdriver/base/sut/controller.rb +91 -74
- data/lib/tdriver/base/sut/factory.rb +8 -8
- data/lib/tdriver/base/sut/generic/behaviours/agent.rb +77 -0
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +116 -96
- data/lib/tdriver/base/sut/generic/commands/agent.rb +43 -0
- data/lib/tdriver/base/sut/sut.rb +10 -8
- data/lib/tdriver/base/test_object/abstract.rb +25 -24
- data/lib/tdriver/base/test_object/adapter.rb +67 -44
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +79 -20
- data/lib/tdriver/base/test_object/factory.rb +45 -15
- data/lib/tdriver/base/test_object/xml/adapter.rb +80 -57
- data/lib/tdriver/env.rb +0 -0
- data/lib/tdriver/loader.rb +0 -0
- data/lib/tdriver/matti.rb +0 -0
- data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +1 -0
- data/lib/tdriver/report/report.rb +2 -1
- data/lib/tdriver/report/report_crash_file_capture.rb +12 -0
- data/lib/tdriver/report/report_creator.rb +6 -2
- data/lib/tdriver/report/report_execution_statistics.rb +27 -11
- data/lib/tdriver/report/report_graph_generator.rb +59 -0
- data/lib/tdriver/report/report_test_case_run.rb +34 -2
- data/lib/tdriver/report/report_writer.rb +12 -0
- data/lib/tdriver/tdriver.rb +12 -1
- data/lib/tdriver/util/agent/loader.rb +22 -0
- data/lib/tdriver/util/agent/service.rb +107 -0
- data/lib/tdriver/util/common/crc16.rb +17 -10
- data/lib/tdriver/util/common/hash.rb +4 -1
- data/lib/tdriver/util/common/kernel.rb +11 -0
- data/lib/tdriver/util/common/numeric.rb +48 -0
- data/lib/tdriver/util/common/object.rb +5 -2
- data/lib/tdriver/util/common/string.rb +8 -1
- data/lib/tdriver/util/filters/attribute_filter.rb +121 -0
- data/lib/tdriver/util/filters/loader.rb +29 -0
- data/lib/tdriver/util/fixture/loader.rb +22 -0
- data/lib/tdriver/util/fixture/service.rb +157 -0
- data/lib/tdriver/util/loader.rb +8 -2
- data/lib/tdriver/util/logger/logger.rb +12 -6
- data/lib/tdriver/util/other/config.rb +0 -0
- data/lib/tdriver/util/parameter/parameter.rb +221 -152
- data/lib/tdriver/util/plugin/error.rb +0 -0
- data/lib/tdriver/util/video/camera_linux.rb +36 -22
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +3 -13
- data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +13 -8
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +51 -9
- data/lib/tdriver/util/xml/xml.rb +4 -2
- data/lib/tdriver/verify/verify.rb +280 -621
- data/lib/tdriver/version.rb +1 -1
- data/xml/behaviours/generic.xml +34 -0
- data/xml/templates/generic.xml +20 -3
- metadata +168 -240
- data/lib/tdriver-devtools/tests/feature_tests/output/application_closable_0x3f.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/application_close.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/application_environment.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/application_executable_name.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/application_uid.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/created.rid +0 -1
- data/lib/tdriver-devtools/tests/feature_tests/output/find_find.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/flash_behaviour_flash.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/flash_behaviour_flash_images.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_application.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_capture_screen.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_child.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_clear_verify_blocks.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_connect.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_controller_execution_order.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_controller_execution_order_0x3d.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_current_application_id.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_disconnect.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_dump_count.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_freeze.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_frozen.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_application_id.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_object.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_operator_data.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_ui_dump.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_user_information.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_input.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_parameter.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_press_key.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_received_data.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh.feature +0 -20
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_timeout.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_tries.feature +0 -15
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_ui_dump.feature +0 -20
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_run.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_sent_data.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_state.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_translate.feature +0 -30
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_ui_type.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_ui_version.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_unfreeze.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_update.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_verify_always.feature +0 -20
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_verify_blocks.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_x_path.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data_0x3d.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data_crc.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_down.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_status.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_up.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_reset.feature +0 -10
- data/lib/tdriver-devtools/tests/feature_tests/output/verification_test_object_exists_0x3f.feature +0 -15
- data/lib/tdriver/base/behaviour/factory_new.rb +0 -409
- data/lib/tdriver/base/test_object/identificator.rb +0 -518
- data/lib/tdriver/util/filters/dynamic_attributes.rb +0 -189
@@ -17,7 +17,7 @@
|
|
17
17
|
##
|
18
18
|
############################################################################
|
19
19
|
|
20
|
-
# deprecated: use
|
20
|
+
# deprecated: use TDriver::BehaviourFactory instead
|
21
21
|
|
22
22
|
=begin
|
23
23
|
module MobyBehaviour
|
@@ -72,7 +72,7 @@ module MobyBehaviour
|
|
72
72
|
|
73
73
|
sut = ( sut = self ).kind_of?( MobyBase::SUT ) ? sut : sut.sut
|
74
74
|
|
75
|
-
|
75
|
+
TDriver::BehaviourFactory.apply_behaviour( { :sut_type => [ '*', sut.ui_type ], :version => [ '*', sut.ui_version ] }.merge( rules ).merge( { :object => self } ) )
|
76
76
|
|
77
77
|
end
|
78
78
|
|
@@ -67,7 +67,15 @@ module MobyBehaviour
|
|
67
67
|
#
|
68
68
|
def behaviours( return_indexes = false )
|
69
69
|
|
70
|
-
|
70
|
+
if return_indexes
|
71
|
+
|
72
|
+
@object_behaviours
|
73
|
+
|
74
|
+
else
|
75
|
+
|
76
|
+
TDriver::BehaviourFactory.collect_behaviours( :index => @object_behaviours ).collect{ | behaviour | behaviour[ :name ] }.uniq.compact.sort
|
77
|
+
|
78
|
+
end
|
71
79
|
|
72
80
|
end
|
73
81
|
|
@@ -79,11 +87,21 @@ module MobyBehaviour
|
|
79
87
|
# example: ["application?", "close", "closable?", "describe"]
|
80
88
|
def object_methods
|
81
89
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
90
|
+
TDriver::BehaviourFactory.collect_behaviours( :index => @object_behaviours ).inject( [] ){ | result, behaviour |
|
91
|
+
|
92
|
+
# append method names to result array
|
93
|
+
result.concat(
|
94
|
+
|
95
|
+
behaviour[ :methods ].keys.collect{ | key |
|
96
|
+
|
97
|
+
# make sure that method name is returned in type of string
|
98
|
+
key.to_s
|
99
|
+
|
100
|
+
}
|
101
|
+
|
102
|
+
)
|
103
|
+
|
104
|
+
}.uniq.compact.sort
|
87
105
|
|
88
106
|
end
|
89
107
|
|
@@ -134,52 +152,44 @@ module MobyBehaviour
|
|
134
152
|
#
|
135
153
|
def describe_method( method_name, print = true, return_result = false )
|
136
154
|
|
137
|
-
# verify that method_name is type of Symbol or String
|
138
|
-
method_name.check_type( [ Symbol, String ], "
|
139
|
-
|
140
|
-
# convert to symbol if method_name is a string
|
141
|
-
method_name = method_name.to_sym if method_name.kind_of?( String )
|
155
|
+
# verify that method_name is type of Symbol or String and convert it to Symbol
|
156
|
+
method_name = method_name.check_type( [ Symbol, String ], "wrong argument type $1 for method name (expected $2)" ).to_s
|
142
157
|
|
143
|
-
|
144
|
-
|
158
|
+
# verify that print argument is boolean
|
159
|
+
print = print.check_type( [ TrueClass, FalseClass ], "wrong argument type $1 for verbose output (expected $2)" ).true?
|
145
160
|
|
146
161
|
# return result not printed out to stdout
|
147
|
-
return_result = true
|
162
|
+
return_result = true if print.false?
|
148
163
|
|
149
|
-
|
164
|
+
behaviours = TDriver::BehaviourFactory.collect_behaviours( :index => @object_behaviours ).select{ | behaviour |
|
150
165
|
|
151
|
-
|
166
|
+
behaviour[ :methods ].keys.include?( method_name )
|
152
167
|
|
153
|
-
|
168
|
+
}.compact.last
|
154
169
|
|
155
|
-
|
156
|
-
|
157
|
-
result_hash = { :description => method_details[ :description ], :example => method_details[ :example ] }
|
158
|
-
break;
|
159
|
-
end
|
160
|
-
|
161
|
-
}
|
170
|
+
# verify that method was found
|
171
|
+
behaviours.not_blank "Test object type of #{ @type } does not have method #{ method_name.inspect }"
|
162
172
|
|
163
|
-
|
173
|
+
result = {
|
174
|
+
:name => method_name,
|
175
|
+
:description => behaviours[ :methods ][ method_name ][ :description ],
|
176
|
+
:example => behaviours[ :methods ][ method_name ][ :example ]
|
177
|
+
}
|
164
178
|
|
165
|
-
|
179
|
+
if print
|
166
180
|
|
167
|
-
|
181
|
+
result = [ :name, :description, :example ].inject( "" ){ | tmp_result, key |
|
168
182
|
|
169
|
-
|
170
|
-
tmp_hash = result_hash[ key ]
|
171
|
-
result << "\n#{ key.to_s.capitalize }:\n#{ tmp_hash }\n"
|
172
|
-
}
|
183
|
+
tmp_result << "\n#{ key.to_s.capitalize }:\n#{ result[ key ] }\n"
|
173
184
|
|
174
|
-
|
185
|
+
}
|
175
186
|
|
176
|
-
|
187
|
+
puts result
|
177
188
|
|
178
|
-
|
189
|
+
end
|
179
190
|
|
180
|
-
|
181
|
-
|
182
|
-
( return_result ? result : nil )
|
191
|
+
# result
|
192
|
+
return_result ? result : nil
|
183
193
|
|
184
194
|
end
|
185
195
|
|
@@ -17,488 +17,366 @@
|
|
17
17
|
##
|
18
18
|
############################################################################
|
19
19
|
|
20
|
-
module
|
20
|
+
module TDriver
|
21
21
|
|
22
|
-
# TODO: document BehaviourFactory class
|
23
22
|
class BehaviourFactory
|
24
|
-
|
25
|
-
include Singleton
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
@@behaviours = []
|
30
|
-
@@behaviours_cache = {}
|
31
|
-
@@modules_cache = {}
|
32
|
-
|
33
|
-
@@plugin_cache = []
|
34
|
-
|
35
|
-
# behaviour xml files path
|
36
|
-
@@path = File.join( MobyUtil::FileHelper.tdriver_home, '/behaviours/*.xml' )
|
37
|
-
|
38
|
-
parse_behaviour_files(
|
39
|
-
|
40
|
-
load_behaviours( @@path )
|
41
|
-
|
42
|
-
)
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
public
|
47
|
-
|
48
|
-
def to_xml( rules = {} )
|
49
|
-
|
50
|
-
@_method_index = nil
|
51
|
-
|
52
|
-
rules.default = [ '*' ]
|
53
|
-
|
54
|
-
rules.each_pair{ | key, value |
|
55
|
-
|
56
|
-
rules[ key ] = [ value ] if value.kind_of?( String )
|
57
|
-
|
58
|
-
}
|
59
|
-
|
60
|
-
MobyUtil::XML.build{
|
61
|
-
|
62
|
-
behaviours{
|
24
|
+
class << self
|
63
25
|
|
64
|
-
|
26
|
+
public
|
65
27
|
|
66
|
-
|
28
|
+
# initialize behaviours factory
|
29
|
+
def init( options )
|
67
30
|
|
68
|
-
|
31
|
+
# verify that argument is type of hash
|
32
|
+
options.check_type Hash, 'wrong argument type $1 for TDriver::BehaviourFactory#init options argument (expected $2)'
|
69
33
|
|
70
|
-
|
34
|
+
# load behaviour configuration files
|
35
|
+
load_behaviours(
|
71
36
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
( !( rules[ :input_type ] & behaviour[ :input_type ] ).empty? ) &&
|
76
|
-
( !( rules[ :object_type ] & behaviour[ :object_type ] ).empty? ) &&
|
77
|
-
( !( rules[ :version ] & behaviour[ :version ] ).empty? )
|
78
|
-
|
79
|
-
)
|
80
|
-
|
81
|
-
behaviour( :name => @@behaviours[ @_method_index ][ :name ], :object_type => @@behaviours[ @_method_index ][ :object_type ].join(";") ){
|
82
|
-
object_methods{
|
83
|
-
@@behaviours[ @_method_index ][ :methods ].each { | key, value |
|
84
|
-
object_method( :name => key.to_s ) {
|
85
|
-
description( value[:description] )
|
86
|
-
example( value[:example] )
|
87
|
-
}
|
88
|
-
}
|
89
|
-
}
|
90
|
-
}
|
37
|
+
options.require_key( :path, 'required key $1 not found from TDriver::BehaviourFactory#init options argument' )
|
38
|
+
|
39
|
+
)
|
91
40
|
|
92
41
|
end
|
42
|
+
|
43
|
+
# reset class configuration
|
44
|
+
def reset
|
93
45
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
}.to_xml
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
def get_behaviour_at_index( index )
|
103
|
-
|
104
|
-
result = @@behaviours[ index ]
|
105
|
-
|
106
|
-
if result.nil?
|
107
|
-
|
108
|
-
Kernel::raise RuntimeError.new( "No behaviour at index #{ index }" )
|
46
|
+
# reset default values
|
47
|
+
initialize_class
|
48
|
+
|
49
|
+
end
|
109
50
|
|
110
|
-
|
51
|
+
# TODO: document me
|
52
|
+
def apply_behaviour( rule )
|
53
|
+
|
54
|
+
# verify that rule is given as hash
|
55
|
+
rule.check_type Hash, 'wrong argument type $1 for TDriver::BehaviourFactory#apply_behaviour rule argument (expected $2)'
|
111
56
|
|
112
|
-
|
57
|
+
# empty collected indexes variable
|
58
|
+
collected_indexes = []
|
59
|
+
|
60
|
+
# retrieve object from hash
|
61
|
+
_object = rule[ :object ]
|
113
62
|
|
114
|
-
|
63
|
+
# generate cache key, drop :object value from hash
|
64
|
+
cache_key = rule.reject{ | key, value | key == :object }.hash
|
115
65
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@@modules_cache.clear
|
123
|
-
|
124
|
-
end
|
66
|
+
# retrieve behaviour from cache if found
|
67
|
+
if @behaviours_cache.has_key?( cache_key )
|
68
|
+
|
69
|
+
behaviours = @behaviours_cache[ cache_key ]
|
70
|
+
|
71
|
+
else
|
125
72
|
|
126
|
-
|
73
|
+
# collect behaviours that meets given rules
|
74
|
+
behaviours = collect_behaviours( rule )
|
127
75
|
|
128
|
-
|
129
|
-
|
76
|
+
# store behaviour collection to cache for future reuse
|
77
|
+
@behaviours_cache[ cache_key ] = behaviours
|
130
78
|
|
131
|
-
|
79
|
+
end
|
132
80
|
|
133
|
-
|
81
|
+
# iterate through each collected behaviour
|
82
|
+
behaviours.each do | behaviour |
|
134
83
|
|
135
|
-
|
136
|
-
|
84
|
+
begin
|
85
|
+
|
86
|
+
# retrieve module from hash
|
87
|
+
_module = behaviour[ :module ]
|
137
88
|
|
138
|
-
|
139
|
-
get_object_behaviours( rules ).each{ | behaviour_index |
|
89
|
+
unless _module.kind_of?( Module )
|
140
90
|
|
141
|
-
|
91
|
+
# retrieve behaviour module
|
92
|
+
_module = MobyUtil::KernelHelper.get_constant( _module.to_s )
|
142
93
|
|
143
|
-
|
144
|
-
|
94
|
+
# store pointer to module (implementation) back to hash
|
95
|
+
behaviour[ :module ] = _module
|
145
96
|
|
146
|
-
|
97
|
+
end
|
147
98
|
|
148
|
-
|
149
|
-
|
99
|
+
# extend target object with behaviour module
|
100
|
+
_object.extend( _module )
|
150
101
|
|
151
|
-
|
102
|
+
# store behaviour indexes
|
103
|
+
collected_indexes << behaviour[ :index ]
|
152
104
|
|
153
|
-
|
154
|
-
@@modules_cache[ name ] = MobyUtil::KernelHelper.get_constant( name )
|
105
|
+
rescue NameError
|
155
106
|
|
156
|
-
|
107
|
+
raise NameError, "Implementation for #{ behaviour[ :name ] } behaviour does not exist. (#{ _module })"
|
108
|
+
|
109
|
+
rescue
|
110
|
+
|
111
|
+
raise RuntimeError, "Error while applying #{ behaviour[ :name ] } (#{ _module }) behaviour to target object due to #{ $!.message } (#{ $!.class })"
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end # behaviours.each
|
157
116
|
|
158
|
-
|
117
|
+
# retrieve objects behaviour index array if already set
|
118
|
+
collected_indexes = _object.instance_variable_get( :@object_behaviours ) | collected_indexes if _object.instance_variable_defined?( :@object_behaviours )
|
159
119
|
|
160
|
-
|
120
|
+
# add behaviour information to test object
|
121
|
+
_object.instance_variable_set( :@object_behaviours, collected_indexes )
|
122
|
+
|
123
|
+
end
|
161
124
|
|
162
|
-
|
125
|
+
# TODO: document me
|
126
|
+
def collect_behaviours( rule )
|
163
127
|
|
128
|
+
# retrieve enabled plugins from PluginService
|
129
|
+
enabled_plugins = TDriver::PluginService.enabled_plugins
|
164
130
|
|
165
|
-
|
131
|
+
# default value for rule if not defined
|
132
|
+
rule.default = [ '*' ]
|
166
133
|
|
167
|
-
|
134
|
+
# store as local variable for less AST lookups
|
135
|
+
_index = rule.fetch( :index ){ [] }
|
136
|
+
_object_type = rule[ :object_type ]
|
137
|
+
_input_type = rule[ :input_type ]
|
138
|
+
_env = rule[ :env ]
|
139
|
+
_version = rule[ :version ]
|
168
140
|
|
169
|
-
|
141
|
+
@behaviours.select do | behaviour |
|
170
142
|
|
171
|
-
|
172
|
-
|
143
|
+
# skip if required plugin is not registered or enabled; compare requires array and enabled_plugins array
|
144
|
+
next unless ( behaviour[ :requires ] - enabled_plugins ).empty?
|
173
145
|
|
174
|
-
|
146
|
+
# match other rules if no exact index given
|
147
|
+
if _index.empty?
|
175
148
|
|
176
|
-
|
149
|
+
case rule[ :name ]
|
150
|
+
|
151
|
+
when behaviour[ :name ]
|
152
|
+
|
153
|
+
# exact match with name
|
154
|
+
true
|
155
|
+
|
156
|
+
when ['*']
|
177
157
|
|
178
|
-
|
158
|
+
# compare rules and behaviour attributes
|
159
|
+
!( _object_type & behaviour[ :object_type ] ).empty? &&
|
160
|
+
!( _input_type & behaviour[ :input_type ] ).empty? &&
|
161
|
+
!( _env & behaviour[ :env ] ).empty? &&
|
162
|
+
!( _version & behaviour[ :version ] ).empty?
|
179
163
|
|
180
|
-
|
164
|
+
else
|
165
|
+
|
166
|
+
false
|
181
167
|
|
182
|
-
|
168
|
+
end
|
183
169
|
|
184
|
-
|
170
|
+
else
|
185
171
|
|
186
|
-
|
172
|
+
# index given
|
173
|
+
true if Array( _index ).include?( behaviour[ :index ] )
|
187
174
|
|
188
|
-
|
175
|
+
end
|
189
176
|
|
190
|
-
|
177
|
+
end # behaviours.select
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
# remove me when migration ready
|
182
|
+
def apply_behaviour!( *args )
|
191
183
|
|
192
|
-
|
184
|
+
warn_caller '$1:$2 warning: deprecated method apply_behaviour!; please use TDriver::BehaviourFactory.apply_behaviour instead'
|
193
185
|
|
194
|
-
|
186
|
+
apply_behaviour( *args )
|
195
187
|
|
196
|
-
|
188
|
+
end
|
197
189
|
|
198
|
-
|
190
|
+
# TODO: document me
|
191
|
+
def to_xml( rule )
|
199
192
|
|
200
|
-
|
193
|
+
MobyUtil::XML.build{ | xml |
|
201
194
|
|
202
|
-
|
195
|
+
# root element
|
196
|
+
xml.behaviours{
|
203
197
|
|
204
|
-
|
198
|
+
# iterate each behaviour that meets the rule
|
199
|
+
collect_behaviours( rule ).each{ | behaviour |
|
205
200
|
|
206
|
-
|
201
|
+
# behaviour element
|
202
|
+
xml.behaviour( :name => behaviour[ :name ], :object_type => behaviour[ :object_type ].sort.join(";") ){
|
207
203
|
|
208
|
-
|
204
|
+
# behaviour methods element
|
205
|
+
xml.object_methods{
|
209
206
|
|
210
|
-
|
207
|
+
behaviour[ :methods ].each_pair{ | key, value |
|
211
208
|
|
212
|
-
|
209
|
+
xml.object_method( :name => key.to_s ){
|
213
210
|
|
214
|
-
|
211
|
+
xml.description value[ :description ]
|
212
|
+
xml.example value[ :example ]
|
215
213
|
|
216
|
-
|
214
|
+
} # object_method
|
217
215
|
|
218
|
-
|
216
|
+
} # methods.each_pair
|
219
217
|
|
220
|
-
|
218
|
+
} # object_methods
|
221
219
|
|
222
|
-
|
220
|
+
} # behaviour
|
223
221
|
|
224
|
-
|
222
|
+
} # behaviours.each
|
225
223
|
|
226
|
-
|
224
|
+
} # root
|
227
225
|
|
228
|
-
|
229
|
-
next if behaviours[ :xml ].empty?
|
226
|
+
}.to_xml
|
230
227
|
|
231
|
-
|
232
|
-
document = MobyUtil::XML.parse_string( behaviours[ :xml ] )
|
228
|
+
end
|
233
229
|
|
234
|
-
|
230
|
+
# TODO: document me
|
231
|
+
def reset_cache
|
235
232
|
|
236
|
-
|
233
|
+
# reset behaviour cache
|
234
|
+
@behaviours_cache = {}
|
237
235
|
|
238
236
|
end
|
239
237
|
|
240
|
-
|
241
|
-
document.root.xpath( "/behaviours" ).each{ | behaviours_element |
|
238
|
+
private
|
242
239
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
# process each behaviour element
|
247
|
-
behaviours_element.xpath( "behaviour" ).each{ | node |
|
248
|
-
|
249
|
-
# retrieve behaviour attributes & module node
|
250
|
-
attributes = node.attributes
|
251
|
-
|
252
|
-
name = attributes[ "name" ].to_s
|
253
|
-
object_type = attributes[ "object_type" ].to_s
|
254
|
-
input_type = attributes[ "input_type" ].to_s
|
255
|
-
sut_type = attributes[ "sut_type" ].to_s
|
256
|
-
version = attributes[ "version" ].to_s
|
257
|
-
|
258
|
-
env = ( attributes[ "env" ] || '*' ).to_s
|
240
|
+
# private methods and variables
|
241
|
+
def initialize_class
|
259
242
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
input_type.not_empty "Behaviour element does not have target object input type (input_type) attribute defined, please see #{ name } in behaviour XML files", RuntimeError
|
268
|
-
|
269
|
-
sut_type.not_empty "Behaviour element does not have target object sut type (sut_type) attribute defined, please see #{ name } in behaviour XML files", RuntimeError
|
243
|
+
# behaviours container
|
244
|
+
@behaviours = []
|
245
|
+
|
246
|
+
# behaviour cache; re-collecting behaviours is not required for similar target objects
|
247
|
+
@behaviours_cache = {}
|
248
|
+
|
249
|
+
end
|
270
250
|
|
271
|
-
|
251
|
+
# load and parse behaviours files
|
252
|
+
def load_behaviours( path )
|
272
253
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
254
|
+
# behaviour xml files path
|
255
|
+
Dir.glob( File.join( path, '*.xml' ) ){ | filename |
|
256
|
+
|
257
|
+
begin
|
258
|
+
|
259
|
+
# read file contents
|
260
|
+
content = MobyUtil::FileHelper.get_file( filename )
|
279
261
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
node.xpath( 'methods/method' ).each{ | method |
|
286
|
-
|
287
|
-
# retrieve method description & example and store to methods hash
|
288
|
-
methods_hash[ method.attribute( "name" ).to_s.to_sym ] = {
|
289
|
-
:description => method.at_xpath( 'description/text()' ).to_s,
|
290
|
-
:example => method.at_xpath( 'example/text()' ).to_s
|
291
|
-
}
|
292
|
-
|
293
|
-
}
|
294
|
-
|
295
|
-
# create and store beahaviour hash
|
296
|
-
@@behaviours << {
|
297
|
-
|
298
|
-
:name => name,
|
299
|
-
:requires => root_attributes[ "plugin" ].to_s.split(";"),
|
300
|
-
:object_type => object_type.split(";"),
|
301
|
-
:input_type => input_type.split(";"),
|
302
|
-
#:sut_type => sut_type.split(";"),
|
303
|
-
:version => version.split(";"),
|
304
|
-
:env => env.split(";"),
|
305
|
-
|
306
|
-
:module => {
|
307
|
-
:file => module_file,
|
308
|
-
:name => module_name
|
309
|
-
},
|
310
|
-
|
311
|
-
:methods => methods_hash
|
312
|
-
|
313
|
-
}
|
262
|
+
# skip when empty file
|
263
|
+
next if content.empty?
|
264
|
+
|
265
|
+
# parse behaviour xml and process each behaviours element
|
266
|
+
MobyUtil::XML.parse_string( content ).root.xpath( '/behaviours' ).each do | behaviours |
|
314
267
|
|
268
|
+
# retrieve root attributes
|
269
|
+
root_attributes = behaviours.attributes
|
315
270
|
|
316
|
-
|
271
|
+
# process each behaviour element
|
272
|
+
behaviours.xpath( './behaviour' ).each do | behaviour |
|
317
273
|
|
318
|
-
|
274
|
+
# retrieve behaviour attributes - set default values if not found from element
|
275
|
+
attributes = behaviour.attributes.default_values(
|
276
|
+
'name' => '',
|
277
|
+
'object_type' => '',
|
278
|
+
'input_type' => '',
|
279
|
+
'sut_type' => '',
|
280
|
+
'version' => '',
|
281
|
+
'env' => '*'
|
282
|
+
)
|
319
283
|
|
320
|
-
|
284
|
+
# verify that behaviour attributes are not empty
|
285
|
+
attributes.each_pair do | key, value |
|
321
286
|
|
322
|
-
|
323
|
-
document.root.xpath( "/behaviours/behaviour" ).each{ | node |
|
287
|
+
value.not_empty "behaviour element attribute #{ key.inspect } is not defined or empty", RuntimeError
|
324
288
|
|
325
|
-
|
326
|
-
attributes = node.attributes
|
289
|
+
end
|
327
290
|
|
328
|
-
|
329
|
-
|
330
|
-
input_type = attributes[ "input_type" ].to_s
|
331
|
-
sut_type = attributes[ "sut_type" ].to_s
|
332
|
-
version = attributes[ "version" ].to_s
|
291
|
+
# retrieve implementation/module name
|
292
|
+
module_name = behaviour.at_xpath( 'module/@name' ).to_s
|
333
293
|
|
334
|
-
|
294
|
+
# verify that module name is defined
|
295
|
+
module_name.not_empty "behaviour #{ attributes[ "name" ].inspect } does not have module name defined or is empty", RuntimeError
|
335
296
|
|
336
|
-
|
337
|
-
|
338
|
-
# verify that all required attributes and nodes are found in behaviour xml node
|
339
|
-
name.not_empty("Behaviour element does not have name (name) attribute defined, please see behaviour XML files", RuntimeError)
|
340
|
-
|
341
|
-
object_type.not_empty("Behaviour element does not have target object type (object_type) attribute defined, please see #{ name } in behaviour XML files", RuntimeError)
|
297
|
+
# store behaviour
|
298
|
+
@behaviours << {
|
342
299
|
|
343
|
-
|
300
|
+
:index => @behaviours.count,
|
301
|
+
|
302
|
+
:name => attributes[ 'name' ],
|
303
|
+
:object_type => attributes[ 'object_type' ].split(';'),
|
304
|
+
:input_type => attributes[ 'input_type' ].split(';'),
|
305
|
+
:version => attributes[ 'version' ].split(';'),
|
306
|
+
:env => attributes[ 'env' ].split(';'),
|
307
|
+
|
308
|
+
:requires => root_attributes[ 'plugin' ].to_s.split(';'),
|
309
|
+
|
310
|
+
:module => module_name,
|
311
|
+
:file => behaviour.at_xpath( 'module/text()' ).to_s, # optional
|
312
|
+
|
313
|
+
:methods => Hash[
|
314
|
+
# collect method details from behaviour
|
315
|
+
behaviour.xpath( 'methods/method' ).collect{ | method |
|
316
|
+
[
|
317
|
+
method.attribute( 'name' ),
|
318
|
+
{
|
319
|
+
:description => method.at_xpath( 'description/text()' ).to_s,
|
320
|
+
:example => method.at_xpath( 'example/text()' ).to_s
|
321
|
+
}
|
322
|
+
]
|
323
|
+
}
|
324
|
+
]
|
325
|
+
|
326
|
+
}
|
327
|
+
|
328
|
+
end # behaviour.each
|
329
|
+
|
330
|
+
end # behaviours.each
|
331
|
+
|
332
|
+
rescue MobyUtil::FileNotFoundError
|
333
|
+
|
334
|
+
raise
|
335
|
+
|
336
|
+
rescue MobyUtil::XML::ParseError
|
337
|
+
|
338
|
+
raise MobyUtil::XML::ParseError, "Error while parsing behaviours file #{ behaviours[ :filename ] } due to #{ $!.message }"
|
344
339
|
|
345
|
-
|
340
|
+
rescue
|
346
341
|
|
347
|
-
|
342
|
+
raise RuntimeError, "Error while processing behaviours file #{ filename } due to #{ $!.message }"
|
348
343
|
|
349
|
-
|
344
|
+
end
|
350
345
|
|
351
|
-
#
|
352
|
-
module_attributes = module_node.attributes
|
353
|
-
module_file = module_attributes[ "file" ].to_s # optional
|
354
|
-
module_name = module_attributes[ "name" ].to_s
|
355
|
-
|
356
|
-
#Kernel::raise RuntimeError.new( "Behaviour implementation module name not defined for #{ name } in XML") if module_name.empty?
|
357
|
-
module_name.not_empty("Behaviour does not have implementation module name defined, please see #{ name } in behaviour XML files", RuntimeError)
|
358
|
-
|
359
|
-
methods_hash = {}
|
360
|
-
|
361
|
-
# create hash of methods
|
362
|
-
node.xpath( 'methods/method' ).each{ | method |
|
363
|
-
|
364
|
-
# retrieve method description & example and store to methods hash
|
365
|
-
methods_hash[ method.attribute( "name" ).to_s.to_sym ] = {
|
366
|
-
:description => method.at_xpath( 'description/text()' ).to_s,
|
367
|
-
:example => method.at_xpath( 'example/text()' ).to_s
|
368
|
-
}
|
369
|
-
|
370
|
-
}
|
371
|
-
|
372
|
-
# create and store beahaviour hash
|
373
|
-
@@behaviours << {
|
374
|
-
|
375
|
-
:name => name,
|
376
|
-
:requires => root_attributes[ "plugin" ].to_s.split(";"),
|
377
|
-
:object_type => object_type.split(";"),
|
378
|
-
:input_type => input_type.split(";"),
|
379
|
-
#:sut_type => sut_type.split(";"),
|
380
|
-
:version => version.split(";"),
|
381
|
-
:env => env.split(";"),
|
382
|
-
|
383
|
-
:module => {
|
384
|
-
:file => module_file,
|
385
|
-
:name => module_name
|
386
|
-
},
|
387
|
-
|
388
|
-
:methods => methods_hash
|
389
|
-
|
390
|
-
}
|
391
|
-
|
392
|
-
}
|
346
|
+
} # Dir.glob
|
393
347
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
=begin
|
401
|
-
def get_object_behaviours( rules )
|
402
|
-
|
403
|
-
# calculate hash for behaviour rules / hash value will be used to identify similar objects
|
404
|
-
behaviour_hash = Hash[ rules.select{ | key, value | key != :object } ].hash
|
405
|
-
|
406
|
-
if @@behaviours_cache.has_key?( behaviour_hash )
|
407
|
-
|
408
|
-
# retrieve behaviour module indexes from cache
|
409
|
-
@@behaviours_cache[ behaviour_hash ]
|
410
|
-
|
411
|
-
else
|
412
|
-
|
413
|
-
rules.default = [ '*' ]
|
414
|
-
|
415
|
-
extended_modules = []
|
416
|
-
|
417
|
-
@@behaviours.each_with_index{ | behaviour, index |
|
348
|
+
end # behaviours
|
349
|
+
|
350
|
+
end # self
|
351
|
+
|
352
|
+
# initialize behaviour factory
|
353
|
+
initialize_class
|
418
354
|
|
419
|
-
|
355
|
+
# enable hooking for performance measurement & debug logging
|
356
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
420
357
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
( !( rules[ :object_type ] & behaviour[ :object_type ] ).empty? ) &&
|
425
|
-
( !( rules[ :input_type ] & behaviour[ :input_type ] ).empty? ) &&
|
426
|
-
( !( rules[ :env ] & behaviour[ :env ] ).empty? ) &&
|
427
|
-
( !( rules[ :version ] & behaviour[ :version ] ).empty? ) ) )
|
428
|
-
|
429
|
-
# retrieve list of extended modules
|
430
|
-
extended_modules << index
|
431
|
-
|
432
|
-
end
|
433
|
-
|
434
|
-
}
|
435
|
-
|
436
|
-
# store behaviour module indexes to cache
|
437
|
-
@@behaviours_cache[ behaviour_hash ] = extended_modules
|
438
|
-
|
439
|
-
end
|
440
|
-
|
441
|
-
end
|
442
|
-
=end
|
443
|
-
|
444
|
-
def get_object_behaviours( rule )
|
445
|
-
|
446
|
-
# calculate hash for behaviour rule / hash value will be used to identify similar objects
|
447
|
-
@@behaviours_cache.fetch( rule.delete_keys( :object ).hash ){ | behaviour_hash |
|
448
|
-
|
449
|
-
rule.default = [ '*' ]
|
450
|
-
|
451
|
-
@@behaviours_cache[ behaviour_hash ] = @@behaviours.each_with_index.collect{ | behaviour, index |
|
452
|
-
|
453
|
-
case rule[ :name ]
|
454
|
-
|
455
|
-
when behaviour[ :name ]
|
456
|
-
|
457
|
-
index
|
458
|
-
|
459
|
-
when [ '*' ]
|
460
|
-
|
461
|
-
index if (
|
462
|
-
!( rule[ :object_type ] & behaviour[ :object_type ] ).empty? &&
|
463
|
-
!( rule[ :input_type ] & behaviour[ :input_type ] ).empty? &&
|
464
|
-
!( rule[ :env ] & behaviour[ :env ] ).empty? &&
|
465
|
-
!( rule[ :version ] & behaviour[ :version ] ).empty?
|
466
|
-
)
|
467
|
-
|
468
|
-
else
|
469
|
-
|
470
|
-
nil
|
471
|
-
|
472
|
-
end
|
473
|
-
|
474
|
-
}.compact
|
358
|
+
end # BehaviourFactory
|
359
|
+
|
360
|
+
end # TDriver
|
475
361
|
|
476
|
-
|
362
|
+
# backwards compatibility; e.g. if visualizer is too old
|
363
|
+
module MobyBase
|
477
364
|
|
478
|
-
|
365
|
+
# TODO: document me
|
366
|
+
class BehaviourFactory
|
479
367
|
|
480
|
-
|
368
|
+
class << self
|
481
369
|
|
482
|
-
|
370
|
+
def instance
|
483
371
|
|
484
|
-
|
485
|
-
|
372
|
+
warn_caller "$1:$2 warning: deprecated class MobyBase::BehaviourFactory; please use TDriver::BehaviourFactory instead"
|
373
|
+
|
374
|
+
TDriver::BehaviourFactory
|
486
375
|
|
487
|
-
|
488
|
-
true
|
376
|
+
end
|
489
377
|
|
490
|
-
else
|
491
|
-
|
492
|
-
# return false
|
493
|
-
false
|
494
|
-
|
495
378
|
end
|
496
379
|
|
497
|
-
end
|
498
|
-
|
499
|
-
# enable hooking for performance measurement & debug logging
|
500
|
-
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
501
|
-
|
502
|
-
end # BehaviourGenerator
|
380
|
+
end # BehaviourFactory
|
503
381
|
|
504
382
|
end # MobyBase
|