testability-driver 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/bin/tdriver-devtools +0 -0
  2. data/ext/native_extensions.c +165 -6
  3. data/lib/tdriver-devtools/behaviour/old/xml/update +0 -0
  4. data/lib/tdriver-devtools/behaviour/xml/generate.rb +0 -0
  5. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +15 -1
  6. data/lib/tdriver-devtools/doc/update +0 -0
  7. data/lib/tdriver-devtools/doc/xslt/template.xsl +24 -14
  8. data/lib/tdriver-devtools/doc/xslt/update +0 -0
  9. data/lib/tdriver-devtools/tdriver-devtools.rb +0 -0
  10. data/lib/tdriver-devtools/tests/feature_tests/update +0 -0
  11. data/lib/tdriver/base/behaviour/{behaviour.rb → abstract.rb} +3 -6
  12. data/lib/tdriver/base/behaviour/behaviours/object_abstract.rb +107 -0
  13. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +2 -2
  14. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +47 -37
  15. data/lib/tdriver/base/behaviour/factory.rb +260 -382
  16. data/lib/tdriver/base/behaviour/loader.rb +22 -4
  17. data/lib/tdriver/base/controller/abstraction.rb +56 -0
  18. data/lib/tdriver/base/controller/loader.rb +21 -0
  19. data/lib/tdriver/base/loader.rb +3 -1
  20. data/lib/tdriver/base/sut/controller.rb +91 -74
  21. data/lib/tdriver/base/sut/factory.rb +8 -8
  22. data/lib/tdriver/base/sut/generic/behaviours/agent.rb +77 -0
  23. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +116 -96
  24. data/lib/tdriver/base/sut/generic/commands/agent.rb +43 -0
  25. data/lib/tdriver/base/sut/sut.rb +10 -8
  26. data/lib/tdriver/base/test_object/abstract.rb +25 -24
  27. data/lib/tdriver/base/test_object/adapter.rb +67 -44
  28. data/lib/tdriver/base/test_object/behaviours/test_object.rb +79 -20
  29. data/lib/tdriver/base/test_object/factory.rb +45 -15
  30. data/lib/tdriver/base/test_object/xml/adapter.rb +80 -57
  31. data/lib/tdriver/env.rb +0 -0
  32. data/lib/tdriver/loader.rb +0 -0
  33. data/lib/tdriver/matti.rb +0 -0
  34. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +1 -0
  35. data/lib/tdriver/report/report.rb +2 -1
  36. data/lib/tdriver/report/report_crash_file_capture.rb +12 -0
  37. data/lib/tdriver/report/report_creator.rb +6 -2
  38. data/lib/tdriver/report/report_execution_statistics.rb +27 -11
  39. data/lib/tdriver/report/report_graph_generator.rb +59 -0
  40. data/lib/tdriver/report/report_test_case_run.rb +34 -2
  41. data/lib/tdriver/report/report_writer.rb +12 -0
  42. data/lib/tdriver/tdriver.rb +12 -1
  43. data/lib/tdriver/util/agent/loader.rb +22 -0
  44. data/lib/tdriver/util/agent/service.rb +107 -0
  45. data/lib/tdriver/util/common/crc16.rb +17 -10
  46. data/lib/tdriver/util/common/hash.rb +4 -1
  47. data/lib/tdriver/util/common/kernel.rb +11 -0
  48. data/lib/tdriver/util/common/numeric.rb +48 -0
  49. data/lib/tdriver/util/common/object.rb +5 -2
  50. data/lib/tdriver/util/common/string.rb +8 -1
  51. data/lib/tdriver/util/filters/attribute_filter.rb +121 -0
  52. data/lib/tdriver/util/filters/loader.rb +29 -0
  53. data/lib/tdriver/util/fixture/loader.rb +22 -0
  54. data/lib/tdriver/util/fixture/service.rb +157 -0
  55. data/lib/tdriver/util/loader.rb +8 -2
  56. data/lib/tdriver/util/logger/logger.rb +12 -6
  57. data/lib/tdriver/util/other/config.rb +0 -0
  58. data/lib/tdriver/util/parameter/parameter.rb +221 -152
  59. data/lib/tdriver/util/plugin/error.rb +0 -0
  60. data/lib/tdriver/util/video/camera_linux.rb +36 -22
  61. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +3 -13
  62. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +13 -8
  63. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +51 -9
  64. data/lib/tdriver/util/xml/xml.rb +4 -2
  65. data/lib/tdriver/verify/verify.rb +280 -621
  66. data/lib/tdriver/version.rb +1 -1
  67. data/xml/behaviours/generic.xml +34 -0
  68. data/xml/templates/generic.xml +20 -3
  69. metadata +168 -240
  70. data/lib/tdriver-devtools/tests/feature_tests/output/application_closable_0x3f.feature +0 -10
  71. data/lib/tdriver-devtools/tests/feature_tests/output/application_close.feature +0 -15
  72. data/lib/tdriver-devtools/tests/feature_tests/output/application_environment.feature +0 -10
  73. data/lib/tdriver-devtools/tests/feature_tests/output/application_executable_name.feature +0 -10
  74. data/lib/tdriver-devtools/tests/feature_tests/output/application_uid.feature +0 -10
  75. data/lib/tdriver-devtools/tests/feature_tests/output/created.rid +0 -1
  76. data/lib/tdriver-devtools/tests/feature_tests/output/find_find.feature +0 -15
  77. data/lib/tdriver-devtools/tests/feature_tests/output/flash_behaviour_flash.feature +0 -10
  78. data/lib/tdriver-devtools/tests/feature_tests/output/flash_behaviour_flash_images.feature +0 -15
  79. data/lib/tdriver-devtools/tests/feature_tests/output/sut_application.feature +0 -15
  80. data/lib/tdriver-devtools/tests/feature_tests/output/sut_capture_screen.feature +0 -10
  81. data/lib/tdriver-devtools/tests/feature_tests/output/sut_child.feature +0 -10
  82. data/lib/tdriver-devtools/tests/feature_tests/output/sut_clear_verify_blocks.feature +0 -10
  83. data/lib/tdriver-devtools/tests/feature_tests/output/sut_connect.feature +0 -10
  84. data/lib/tdriver-devtools/tests/feature_tests/output/sut_controller_execution_order.feature +0 -10
  85. data/lib/tdriver-devtools/tests/feature_tests/output/sut_controller_execution_order_0x3d.feature +0 -10
  86. data/lib/tdriver-devtools/tests/feature_tests/output/sut_current_application_id.feature +0 -15
  87. data/lib/tdriver-devtools/tests/feature_tests/output/sut_disconnect.feature +0 -10
  88. data/lib/tdriver-devtools/tests/feature_tests/output/sut_dump_count.feature +0 -15
  89. data/lib/tdriver-devtools/tests/feature_tests/output/sut_freeze.feature +0 -10
  90. data/lib/tdriver-devtools/tests/feature_tests/output/sut_frozen.feature +0 -10
  91. data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_application_id.feature +0 -10
  92. data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_object.feature +0 -10
  93. data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_operator_data.feature +0 -10
  94. data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_ui_dump.feature +0 -15
  95. data/lib/tdriver-devtools/tests/feature_tests/output/sut_get_user_information.feature +0 -10
  96. data/lib/tdriver-devtools/tests/feature_tests/output/sut_input.feature +0 -15
  97. data/lib/tdriver-devtools/tests/feature_tests/output/sut_parameter.feature +0 -15
  98. data/lib/tdriver-devtools/tests/feature_tests/output/sut_press_key.feature +0 -10
  99. data/lib/tdriver-devtools/tests/feature_tests/output/sut_received_data.feature +0 -10
  100. data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh.feature +0 -20
  101. data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_timeout.feature +0 -15
  102. data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_tries.feature +0 -15
  103. data/lib/tdriver-devtools/tests/feature_tests/output/sut_refresh_ui_dump.feature +0 -20
  104. data/lib/tdriver-devtools/tests/feature_tests/output/sut_run.feature +0 -10
  105. data/lib/tdriver-devtools/tests/feature_tests/output/sut_sent_data.feature +0 -10
  106. data/lib/tdriver-devtools/tests/feature_tests/output/sut_state.feature +0 -10
  107. data/lib/tdriver-devtools/tests/feature_tests/output/sut_translate.feature +0 -30
  108. data/lib/tdriver-devtools/tests/feature_tests/output/sut_ui_type.feature +0 -10
  109. data/lib/tdriver-devtools/tests/feature_tests/output/sut_ui_version.feature +0 -10
  110. data/lib/tdriver-devtools/tests/feature_tests/output/sut_unfreeze.feature +0 -10
  111. data/lib/tdriver-devtools/tests/feature_tests/output/sut_update.feature +0 -10
  112. data/lib/tdriver-devtools/tests/feature_tests/output/sut_verify_always.feature +0 -20
  113. data/lib/tdriver-devtools/tests/feature_tests/output/sut_verify_blocks.feature +0 -10
  114. data/lib/tdriver-devtools/tests/feature_tests/output/sut_x_path.feature +0 -10
  115. data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data.feature +0 -10
  116. data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data_0x3d.feature +0 -10
  117. data/lib/tdriver-devtools/tests/feature_tests/output/sut_xml_data_crc.feature +0 -10
  118. data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_down.feature +0 -10
  119. data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_status.feature +0 -10
  120. data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_power_up.feature +0 -10
  121. data/lib/tdriver-devtools/tests/feature_tests/output/switchbox_behaviour_reset.feature +0 -10
  122. data/lib/tdriver-devtools/tests/feature_tests/output/verification_test_object_exists_0x3f.feature +0 -15
  123. data/lib/tdriver/base/behaviour/factory_new.rb +0 -409
  124. data/lib/tdriver/base/test_object/identificator.rb +0 -518
  125. data/lib/tdriver/util/filters/dynamic_attributes.rb +0 -189
@@ -17,7 +17,7 @@
17
17
  ##
18
18
  ############################################################################
19
19
 
20
- # deprecated: use MobyUtil::BehaviourFactory instead
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
- MobyBase::BehaviourFactory.instance.apply_behaviour!( { :sut_type => [ '*', sut.ui_type ], :version => [ '*', sut.ui_version ] }.merge( rules ).merge( { :object => self } ) )
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
- return_indexes ? @object_behaviours : @object_behaviours.collect{ | index | MobyBase::BehaviourFactory.instance.get_behaviour_at_index( index )[ :name ] }.uniq.compact.sort
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
- [].tap{ | methods |
83
- @object_behaviours.each{ | index |
84
- MobyBase::BehaviourFactory.instance.get_behaviour_at_index( index )[ :methods ].keys.each{ | key | methods << key.to_s }
85
- }
86
- }.uniq.compact.sort
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 ], "Wrong argument type $1 for method name (expected $2)" )
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
- # print result to stdout if argument not boolean
144
- print = true unless [ TrueClass, FalseClass ].include?( print.class )
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 unless print
162
+ return_result = true if print.false?
148
163
 
149
- result_hash = nil
164
+ behaviours = TDriver::BehaviourFactory.collect_behaviours( :index => @object_behaviours ).select{ | behaviour |
150
165
 
151
- @object_behaviours.each{ | index |
166
+ behaviour[ :methods ].keys.include?( method_name )
152
167
 
153
- behaviour = MobyBase::BehaviourFactory.instance.get_behaviour_at_index( index )
168
+ }.compact.last
154
169
 
155
- if behaviour[ :methods ].keys.include? method_name
156
- method_details = behaviour[:methods][ method_name ]
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
- Kernel::raise ArgumentError.new( "Test object type of %s does not have method %s" % [ self.type, method_name ] ) if result_hash.nil?
173
+ result = {
174
+ :name => method_name,
175
+ :description => behaviours[ :methods ][ method_name ][ :description ],
176
+ :example => behaviours[ :methods ][ method_name ][ :example ]
177
+ }
164
178
 
165
- if print
179
+ if print
166
180
 
167
- result = ""
181
+ result = [ :name, :description, :example ].inject( "" ){ | tmp_result, key |
168
182
 
169
- [ :description, :example ].each{ | key |
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
- puts result
185
+ }
175
186
 
176
- else
187
+ puts result
177
188
 
178
- result = result_hash
189
+ end
179
190
 
180
- end
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 MobyBase
20
+ module TDriver
21
21
 
22
- # TODO: document BehaviourFactory class
23
22
  class BehaviourFactory
24
-
25
- include Singleton
26
23
 
27
- def initialize
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
- @@behaviours.each_index{ | index |
26
+ public
65
27
 
66
- @_method_index = index
28
+ # initialize behaviours factory
29
+ def init( options )
67
30
 
68
- behaviour = @@behaviours[ @_method_index ]
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
- if ( ( rules[ :name ] == behaviour[ :name ] ) ||
34
+ # load behaviour configuration files
35
+ load_behaviours(
71
36
 
72
- ( rules[ :name ] == [ '*' ] ) &&
73
-
74
- # ( !( rules[ :sut_type ] & behaviour[ :sut_type ] ).empty? ) &&
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
- else
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
- result
57
+ # empty collected indexes variable
58
+ collected_indexes = []
59
+
60
+ # retrieve object from hash
61
+ _object = rule[ :object ]
113
62
 
114
- end
63
+ # generate cache key, drop :object value from hash
64
+ cache_key = rule.reject{ | key, value | key == :object }.hash
115
65
 
116
- end
117
-
118
- # TODO: document me
119
- def reset_modules_cache
120
-
121
- # reset modules cache hash; needed if new behaviour plugins loaded later than when initializing TDriver/SUT
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
- def apply_behaviour!( rules = {} )
73
+ # collect behaviours that meets given rules
74
+ behaviours = collect_behaviours( rule )
127
75
 
128
- # merge user-defined rules on top of default rules set
129
- #rules = { :sut_type => ['*'], :object_type => ['*'], :input_type => ['*'], :version => ['*'] }.merge!( rules )
76
+ # store behaviour collection to cache for future reuse
77
+ @behaviours_cache[ cache_key ] = behaviours
130
78
 
131
- raise ArgumentError, 'Target object not defined in rules hash' if rules[ :object ].nil?
79
+ end
132
80
 
133
- rules.default = ['*']
81
+ # iterate through each collected behaviour
82
+ behaviours.each do | behaviour |
134
83
 
135
- # retrieve enabled plugins from PluginService
136
- enabled_plugins = TDriver::PluginService.enabled_plugins
84
+ begin
85
+
86
+ # retrieve module from hash
87
+ _module = behaviour[ :module ]
137
88
 
138
- # apply behaviours to target object
139
- get_object_behaviours( rules ).each{ | behaviour_index |
89
+ unless _module.kind_of?( Module )
140
90
 
141
- behaviour_data = @@behaviours[ behaviour_index ]
91
+ # retrieve behaviour module
92
+ _module = MobyUtil::KernelHelper.get_constant( _module.to_s )
142
93
 
143
- # skip if required plugin is not registered or enabled; compare requires array and enabled_plugins array
144
- next unless ( behaviour_data[ :requires ] - enabled_plugins ).empty?
94
+ # store pointer to module (implementation) back to hash
95
+ behaviour[ :module ] = _module
145
96
 
146
- begin
97
+ end
147
98
 
148
- # retrieve behaviour module from cache and extend target object
149
- rules[ :object ].extend(
99
+ # extend target object with behaviour module
100
+ _object.extend( _module )
150
101
 
151
- @@modules_cache.fetch( behaviour_data[ :module ][ :name ] ){ | name |
102
+ # store behaviour indexes
103
+ collected_indexes << behaviour[ :index ]
152
104
 
153
- # ... or store to cache for the next time if not found
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
- rescue NameError
120
+ # add behaviour information to test object
121
+ _object.instance_variable_set( :@object_behaviours, collected_indexes )
122
+
123
+ end
161
124
 
162
- raise NameError, "Implementation for behaviour #{ behaviour_data[ :name ] } does not exist. (#{ behaviour_data[ :module ][ :name ] })"
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
- rescue
131
+ # default value for rule if not defined
132
+ rule.default = [ '*' ]
166
133
 
167
- raise RuntimeError, "Error while applying #{ behaviour_data[ :name ] } (#{ behaviour_data[ :module ][ :name ] }) behaviour to target object. Reason: #{ $!.message } (#{ $!.class })"
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
- end
141
+ @behaviours.select do | behaviour |
170
142
 
171
- # add behaviour information to test object
172
- rules[ :object ].instance_exec{
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
- @object_behaviours.push( behaviour_index ) unless @object_behaviours.include?( behaviour_index )
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
- end
164
+ else
165
+
166
+ false
181
167
 
182
- private
168
+ end
183
169
 
184
- def load_behaviours( behaviour_files )
170
+ else
185
171
 
186
- behaviours_data = []
172
+ # index given
173
+ true if Array( _index ).include?( behaviour[ :index ] )
187
174
 
188
- @file_name = ""
175
+ end
189
176
 
190
- begin
177
+ end # behaviours.select
178
+
179
+ end
180
+
181
+ # remove me when migration ready
182
+ def apply_behaviour!( *args )
191
183
 
192
- Dir.glob( behaviour_files ).each{ | behaviour |
184
+ warn_caller '$1:$2 warning: deprecated method apply_behaviour!; please use TDriver::BehaviourFactory.apply_behaviour instead'
193
185
 
194
- @file_name = behaviour
186
+ apply_behaviour( *args )
195
187
 
196
- behaviours_data << { :filename => @file_name, :xml => MobyUtil::FileHelper.get_file( @file_name ) }
188
+ end
197
189
 
198
- }
190
+ # TODO: document me
191
+ def to_xml( rule )
199
192
 
200
- rescue MobyUtil::EmptyFilenameError
193
+ MobyUtil::XML.build{ | xml |
201
194
 
202
- raise EmptyFilenameError, "Unable to load behaviours xml file due to filename is empty or nil"
195
+ # root element
196
+ xml.behaviours{
203
197
 
204
- rescue MobyUtil::FileNotFoundError
198
+ # iterate each behaviour that meets the rule
199
+ collect_behaviours( rule ).each{ | behaviour |
205
200
 
206
- raise
201
+ # behaviour element
202
+ xml.behaviour( :name => behaviour[ :name ], :object_type => behaviour[ :object_type ].sort.join(";") ){
207
203
 
208
- rescue IOError
204
+ # behaviour methods element
205
+ xml.object_methods{
209
206
 
210
- raise IOError, "Error occured while loading behaviours xml file %s. Reason: %s" % [ @file_name, $!.message ]
207
+ behaviour[ :methods ].each_pair{ | key, value |
211
208
 
212
- rescue
209
+ xml.object_method( :name => key.to_s ){
213
210
 
214
- raise RuntimeError, "Error occured while parsing behaviours xml file %s. Reason: %s (%s)" % [ @file_name, $!.message, $!.class ]
211
+ xml.description value[ :description ]
212
+ xml.example value[ :example ]
215
213
 
216
- end
214
+ } # object_method
217
215
 
218
- behaviours_data
216
+ } # methods.each_pair
219
217
 
220
- end
218
+ } # object_methods
221
219
 
222
- def parse_behaviour_files( behaviour_files )
220
+ } # behaviour
223
221
 
224
- behaviour_files.each{ | behaviours |
222
+ } # behaviours.each
225
223
 
226
- begin
224
+ } # root
227
225
 
228
- # skip parsing the xml if string is empty
229
- next if behaviours[ :xml ].empty?
226
+ }.to_xml
230
227
 
231
- # parse behaviour xml
232
- document = MobyUtil::XML.parse_string( behaviours[ :xml ] )
228
+ end
233
229
 
234
- rescue
230
+ # TODO: document me
231
+ def reset_cache
235
232
 
236
- raise MobyUtil::XML::ParseError, "Error occured while parsing behaviour XML file #{ behaviours[ :filename ] }. Error: #{ $!.message }"
233
+ # reset behaviour cache
234
+ @behaviours_cache = {}
237
235
 
238
236
  end
239
237
 
240
- # process each behaviours element
241
- document.root.xpath( "/behaviours" ).each{ | behaviours_element |
238
+ private
242
239
 
243
- # retrieve root attributes
244
- root_attributes = behaviours_element.attributes
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
- module_node = node.xpath( 'module' ).first
261
-
262
- # verify that all required attributes and nodes are found in behaviour xml node
263
- name.not_empty "Behaviour element does not have name (name) attribute defined, please see behaviour XML files", RuntimeError
264
-
265
- object_type.not_empty "Behaviour element does not have target object type (object_type) attribute defined, please see #{ name } in behaviour XML files", RuntimeError
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
- version.not_empty "Behaviour element does not have target object SUT version (version) attribute defined, please see #{ name } in behaviour XML files", RuntimeError
251
+ # load and parse behaviours files
252
+ def load_behaviours( path )
272
253
 
273
- module_node.not_nil "Behaviour does not have implementation module element defined, please see #{ name } in behaviour XML files", RuntimeError
274
-
275
- # retrieve module name & implementation filename
276
- module_attributes = module_node.attributes
277
- module_file = module_attributes[ "file" ].to_s # optional
278
- module_name = module_attributes[ "name" ].to_s
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
- module_name.not_empty "Behaviour does not have implementation module name defined, please see #{ name } in behaviour XML files", RuntimeError
281
-
282
- methods_hash = {}
283
-
284
- # create hash of methods
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
- =begin
284
+ # verify that behaviour attributes are not empty
285
+ attributes.each_pair do | key, value |
321
286
 
322
- # parse retrieve behaviour definitions
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
- # retrieve behaviour attributes & module node
326
- attributes = node.attributes
289
+ end
327
290
 
328
- name = attributes[ "name" ].to_s
329
- object_type = attributes[ "object_type" ].to_s
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
- env = ( attributes[ "env" ] || '*' ).to_s
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
- module_node = node.xpath( 'module' ).first
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
- 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)
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
- 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)
340
+ rescue
346
341
 
347
- version.not_empty("Behaviour element does not have target object SUT version (version) attribute defined, please see #{ name } in behaviour XML files", RuntimeError)
342
+ raise RuntimeError, "Error while processing behaviours file #{ filename } due to #{ $!.message }"
348
343
 
349
- module_node.not_nil("Behaviour does not have implementation module element defined, please see #{ name } in behaviour XML files", RuntimeError)
344
+ end
350
345
 
351
- # retrieve module name & implementation filename
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
- =end
395
-
396
- }
397
-
398
- end
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
- if ( ( rules[ :name ] == behaviour[ :name ] ) ||
355
+ # enable hooking for performance measurement & debug logging
356
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
420
357
 
421
- ( rules[ :name ] == [ '*' ] &&
422
-
423
- # ( !( rules[ :sut_type ] & behaviour[ :sut_type ] ).empty? ) &&
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
- end
365
+ # TODO: document me
366
+ class BehaviourFactory
479
367
 
480
- def get_behaviour_from_cache( target, sut_type, object_type, sut_version, input_type )
368
+ class << self
481
369
 
482
- if @_behaviour_cache.has_key?( object_type )
370
+ def instance
483
371
 
484
- # apply modules to target object
485
- @_behaviour_cache[ object_type ].each{ | module_name | target.instance_eval( "self.extend(#{ module_name })" ) }
372
+ warn_caller "$1:$2 warning: deprecated class MobyBase::BehaviourFactory; please use TDriver::BehaviourFactory instead"
373
+
374
+ TDriver::BehaviourFactory
486
375
 
487
- # return true
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