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.
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