testability-driver 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +2 -2
  2. data/lib/tdriver-devtools/tdriver-devtools.rb +1 -1
  3. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +3 -3
  4. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +6 -1
  5. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +5 -3
  6. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +1 -1
  7. data/lib/tdriver/base/behaviour/factory.rb +225 -225
  8. data/lib/tdriver/base/errors.rb +1 -1
  9. data/lib/tdriver/base/state_object.rb +227 -179
  10. data/lib/tdriver/base/sut/controller.rb +2 -2
  11. data/lib/tdriver/base/sut/factory.rb +190 -182
  12. data/lib/tdriver/base/sut/generic/behaviours/application.rb +69 -25
  13. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +1 -1
  14. data/lib/tdriver/base/sut/generic/behaviours/find.rb +4 -4
  15. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +3 -3
  16. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +350 -165
  17. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +9 -9
  18. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +191 -103
  19. data/lib/tdriver/base/sut/generic/commands/application.rb +1 -1
  20. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +1 -1
  21. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +1 -1
  22. data/lib/tdriver/base/sut/generic/plugin.rb +1 -1
  23. data/lib/tdriver/base/sut/sut.rb +5 -1
  24. data/lib/tdriver/base/test_object/abstract.rb +136 -151
  25. data/lib/tdriver/base/test_object/adapter.rb +293 -82
  26. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +20 -17
  27. data/lib/tdriver/base/test_object/behaviours/test_object.rb +159 -532
  28. data/lib/tdriver/base/test_object/cache.rb +1 -1
  29. data/lib/tdriver/base/test_object/factory.rb +254 -605
  30. data/lib/tdriver/base/test_object/identificator.rb +1 -1
  31. data/lib/tdriver/base/test_object/loader.rb +1 -1
  32. data/lib/tdriver/base/test_object/verification.rb +17 -17
  33. data/lib/tdriver/loader.rb +20 -9
  34. data/lib/tdriver/report/report.rb +5 -0
  35. data/lib/tdriver/report/report_creator.rb +2 -2
  36. data/lib/tdriver/report/report_cucumber_listener.rb +4 -4
  37. data/lib/tdriver/report/report_cucumber_reporter.rb +4 -4
  38. data/lib/tdriver/report/report_execution_statistics.rb +22 -22
  39. data/lib/tdriver/report/report_grouping.rb +2 -2
  40. data/lib/tdriver/report/report_javascript.rb +11 -4
  41. data/lib/tdriver/report/report_test_case_run.rb +2 -2
  42. data/lib/tdriver/report/report_test_run.rb +5 -5
  43. data/lib/tdriver/report/report_test_unit.rb +74 -26
  44. data/lib/tdriver/report/report_writer.rb +70 -13
  45. data/lib/tdriver/tdriver.rb +17 -8
  46. data/lib/tdriver/util/common/array.rb +1 -1
  47. data/lib/tdriver/util/common/crc16.rb +1 -1
  48. data/lib/tdriver/util/common/environment.rb +1 -1
  49. data/lib/tdriver/util/common/file.rb +18 -9
  50. data/lib/tdriver/util/common/gem.rb +1 -1
  51. data/lib/tdriver/util/common/hash.rb +21 -0
  52. data/lib/tdriver/util/common/kernel.rb +1 -1
  53. data/lib/tdriver/util/common/loader.rb +5 -2
  54. data/lib/tdriver/util/common/numeric.rb +54 -3
  55. data/lib/tdriver/util/common/retryable.rb +30 -12
  56. data/lib/tdriver/util/common/stackable.rb +185 -0
  57. data/lib/tdriver/util/common/string.rb +21 -5
  58. data/lib/tdriver/util/{dbaccess/dbaccess.rb → database/access.rb} +4 -1
  59. data/lib/tdriver/util/{dbaccess/dbconnection.rb → database/connection.rb} +3 -0
  60. data/lib/tdriver/util/{dbaccess → database}/error.rb +0 -1
  61. data/lib/tdriver/util/{dbaccess → database}/loader.rb +5 -6
  62. data/lib/tdriver/util/{dynamic_attribute_filter.rb → filters/dynamic_attributes.rb} +1 -1
  63. data/lib/tdriver/util/hooking/hooking.rb +477 -0
  64. data/lib/tdriver/util/loader.rb +35 -29
  65. data/lib/tdriver/util/localisation/error.rb +0 -1
  66. data/lib/tdriver/util/localisation/loader.rb +1 -4
  67. data/lib/tdriver/util/localisation/localisation.rb +30 -27
  68. data/lib/tdriver/util/{common.rb → logger/loader.rb} +2 -4
  69. data/lib/tdriver/util/logger/logger.rb +574 -0
  70. data/lib/tdriver/util/operator_data/loader.rb +4 -3
  71. data/lib/tdriver/util/operator_data/operator_data.rb +5 -5
  72. data/lib/tdriver/util/parameter/parameter.rb +7 -1
  73. data/lib/tdriver/util/parameter/parameter_hash.rb +1 -1
  74. data/lib/tdriver/util/parameter/parameter_template.rb +1 -1
  75. data/lib/tdriver/util/parameter/parameter_user_api.rb +28 -20
  76. data/lib/tdriver/util/parameter/parameter_xml.rb +1 -1
  77. data/lib/tdriver/util/plugin/abstract.rb +1 -1
  78. data/lib/tdriver/util/plugin/service.rb +1 -1
  79. data/lib/tdriver/util/{localisation.rb → recorder/loader.rb} +4 -3
  80. data/lib/tdriver/util/recorder/recorder.rb +66 -0
  81. data/lib/tdriver/util/recorder/scripter.rb +258 -0
  82. data/lib/tdriver/util/{stats.rb → statistics/statistics.rb} +7 -8
  83. data/lib/tdriver/util/user_data/error.rb +0 -1
  84. data/lib/tdriver/util/user_data/loader.rb +1 -2
  85. data/lib/tdriver/util/user_data/user_data.rb +6 -6
  86. data/lib/tdriver/util/video/camera.rb +67 -0
  87. data/lib/tdriver/util/video/camera_linux.rb +139 -0
  88. data/lib/tdriver/util/video/camera_windows.rb +174 -0
  89. data/lib/tdriver/util/video/loader.rb +31 -0
  90. data/lib/tdriver/util/video/video_utils.rb +139 -0
  91. data/lib/tdriver/util/xml/abstraction.rb +56 -5
  92. data/lib/tdriver/util/xml/builder.rb +2 -5
  93. data/lib/tdriver/util/{parameter.rb → xml/comment.rb} +10 -2
  94. data/lib/tdriver/util/xml/loader.rb +32 -22
  95. data/lib/tdriver/util/xml/nil_node.rb +2 -2
  96. data/lib/tdriver/util/xml/parsers/loader.rb +0 -1
  97. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +18 -44
  98. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +9 -13
  99. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +9 -3
  100. data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
  101. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +6 -11
  102. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +2 -122
  103. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +26 -16
  104. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +203 -0
  105. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +1 -2
  106. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +2 -20
  107. data/lib/tdriver/util/xml/xml.rb +52 -20
  108. data/lib/tdriver/verify/verify.rb +238 -81
  109. data/xml/behaviours/generic.xml +12 -10
  110. metadata +156 -180
  111. data/lib/tdriver/base/test_object/factory_new.rb +0 -202
  112. data/lib/tdriver/util/hooking.rb +0 -434
  113. data/lib/tdriver/util/logger.rb +0 -506
  114. data/lib/tdriver/util/recorder.rb +0 -297
  115. data/lib/tdriver/util/video_utils.rb +0 -384
  116. data/lib/tdriver/util/xml/nil_element.rb +0 -89
@@ -53,7 +53,7 @@ module MobyBase
53
53
  end
54
54
 
55
55
  # enable hooking for performance measurement & debug logging
56
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
56
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
57
57
 
58
58
  end
59
59
 
@@ -17,245 +17,293 @@
17
17
  ##
18
18
  ############################################################################
19
19
 
20
-
21
20
  module MobyBase
22
21
 
23
- # Static representation of the state of a TestObject or SUT.
24
- # StateObject are not refreshed or synchronize etc.
25
- class StateObject
22
+ # Static representation of the state of a TestObject or SUT.
23
+ # StateObject are not refreshed or synchronize etc.
24
+ class StateObject
26
25
 
27
- #include MobyBehaviour::TestObjectComposition
28
- include MobyBehaviour::ObjectComposition
26
+ include MobyBehaviour::ObjectComposition
29
27
 
30
- # The test object factory is needed for populating child object accessor methods
31
- #@test_object_factory
28
+ # The test object factory is needed for populating child object accessor methods
29
+ #@test_object_factory
32
30
 
33
- # == description
34
- # attr_accessor
35
- #
36
- # == returns
37
- # Test Object
38
- # description: test object that was used as parent when this object was created. Can also be of type SUT if sut was the parent (ie. application objects)
39
- # example: "@sut"
40
- attr_accessor :parent
31
+ # == description
32
+ # attr_accessor
33
+ #
34
+ # == returns
35
+ # Test Object
36
+ # description: test object that was used as parent when this object was created. Can also be of type SUT if sut was the parent (ie. application objects)
37
+ # example: "@sut"
38
+ attr_accessor :parent
41
39
 
42
- # Creates a new StateObject from XML source data.
43
- #
44
- # === params
45
- # xml_source:: MobyUtil::XML::Element or String. Contains the root element of this state.
46
- # parent:: TestObject, SUT or StateObject. Parent of this state object. Must be of type TestObjectComposition.
47
- # === returns
48
- # StateObject:: New StateObject
49
- def initialize( xml_source, parent = nil )
40
+ # TODO: document me
41
+ attr_reader :type, :name, :id
50
42
 
51
- xml_element = nil
43
+ # Creates a new StateObject from XML source data.
44
+ #
45
+ # === params
46
+ # xml_source:: MobyUtil::XML::Element or String. Contains the root element of this state.
47
+ # parent:: TestObject, SUT or StateObject. Parent of this state object. Must be of type TestObjectComposition.
48
+ # === returns
49
+ # StateObject:: New StateObject
50
+ def initialize( xml_source, parent = nil )
52
51
 
53
- if xml_source.kind_of?( MobyUtil::XML::Element )
52
+ xml_element = nil
54
53
 
55
- xml_element = xml_source
54
+ if xml_source.kind_of?( MobyUtil::XML::Element )
56
55
 
57
- elsif xml_source.kind_of?( String )
56
+ xml_element = xml_source
58
57
 
59
- xml_element = MobyUtil::XML.parse_string(xml_source).root
58
+ elsif xml_source.kind_of?( String )
60
59
 
61
- else
60
+ xml_element = MobyUtil::XML.parse_string(xml_source).root
62
61
 
63
- Kernel::raise ArgumentError.new("The XML source must be a String or MobyUtil::XML::Element, it was of type '#{ xml_source.class.to_s }'.")
62
+ else
64
63
 
65
- end
64
+ Kernel::raise ArgumentError, "The XML source must be a String or MobyUtil::XML::Element, it was of type '#{ xml_source.class.to_s }'"
66
65
 
67
- #@parent = nil
68
- #add_parent( parent ) unless parent.nil?
69
- #@parent = parent unless parent.nil?
66
+ end
70
67
 
71
68
  @parent = parent
72
69
 
73
- self.xml_data= xml_element
70
+ method(:xml_data=).call( xml_element )
74
71
 
75
72
  @child_object_cache = TDriver::TestObjectCache.new
76
73
 
77
- # Create accessor methods for any child state objects.
74
+ # Create accessor methods for any child state objects.
78
75
  TDriver::TestObjectAdapter.create_child_accessors!( xml_element, self )
79
76
 
80
- end
81
-
82
- # Tries to use the missing method id as a child object type and find an object based on it
83
- def method_missing( method_id, *method_arguments )
84
-
85
- hash_rule = method_arguments.first
86
-
87
- hash_rule = Hash.new unless hash_rule.kind_of? Hash
88
-
89
- hash_rule[ :type ] = method_id
90
-
91
- begin
92
-
93
- return child( hash_rule )
94
-
95
- rescue MobyBase::TestObjectNotFoundError, MobyBase::TestObjectNotVisibleError
96
-
97
- hash_rule.delete(:type)
98
-
99
- raise MobyBase::TestObjectNotFoundError.new(
100
- "The state object with id: \"#{ self.id.to_s }\", type: \"#{ self.type.to_s }\" and name: \"#{ self.name.to_s }\" has no child object of type \"#{ method_id.inspect.to_s }\"" <<
101
- ( hash_rule.empty? ? "" : " attributes: #{ hash_rule.inspect },"))
102
- end
103
-
104
- end
105
-
106
-
107
- # Check to StateObject objects for equality (ie. contents, not if they are the same object).
108
- # === param
109
- # other_state_object:: StateObject this object is compared to.
110
- # === returns
111
- # true:: other_state_object is equal to this StateObject.
112
- # false:: other_state_object is not equal to this StateObject.
113
- def eql? (other_state_object)
114
- self == other_state_object
115
- end
77
+ end
78
+
79
+ # Tries to use the missing method id as a child object type and find an object based on it
80
+ def method_missing( method_id, *method_arguments )
81
+
82
+ rules_hash = method_arguments.first
83
+
84
+ rules_hash = Hash.new unless rules_hash.kind_of? Hash
85
+
86
+ rules_hash[ :type ] = method_id
87
+
88
+ begin
89
+
90
+ return child( rules_hash )
91
+
92
+ rescue MobyBase::TestObjectNotFoundError, MobyBase::TestObjectNotVisibleError
93
+
94
+ rules_hash_clone = rules_hash.clone
95
+
96
+ rules_hash_clone.delete( :type )
97
+
98
+ # string representation of used rule hash
99
+ search_attributes_string = rules_hash_clone.collect{ | key, value | ":#{ key } => #{ value.inspect }" }.join( ', ')
100
+
101
+ # construct literal representation of object identifiers
102
+ object_attributes = []
103
+ object_attributes << "id: #{ @id }" if @id
104
+ object_attributes << "type: #{ @type.inspect }" if @type
105
+ object_attributes << "name: #{ @name.inspect }" if @name
106
+
107
+ if search_attributes_string.empty?
108
+
109
+ # do not show any attribute details if none given
110
+ search_attributes_string = ""
111
+
112
+ else
113
+
114
+ # show used attributes
115
+ search_attributes_string = " (attributes #{ search_attributes_string })"
116
+
117
+ end
118
+
119
+ # raise exception
120
+ Kernel::raise MobyBase::TestObjectNotFoundError.new(
121
+ "The state object (#{ object_attributes.join(", ") }) has no child object with type or behaviour method with name #{ method_id.to_s.inspect }#{ search_attributes_string }"
122
+ )
123
+
124
+ end
125
+
126
+ end
127
+
128
+ # Verifies that another StateObject contains the same data as this object.
129
+ # type, id and name must match.
130
+ #
131
+ # == param
132
+ # other_state_object:: StateObject that this object is compared to.
133
+ # == returns
134
+ # true:: The other StateObject contains the same data as this one.
135
+ # false:: The other StateObject does notcontain the same data as this one.
136
+ # == raises
137
+ # nothing
138
+ def ==( test_object )
139
+
140
+ # optimized version
141
+ test_object.instance_of?( MobyBase::StateObject ) && ( @type == test_object.type ) && ( @id == test_object.id ) && ( @name == test_object.name )
142
+
143
+ end
144
+
145
+ # Check to StateObject objects for equality (ie. contents, not if they are the same object).
146
+ # === param
147
+ # other_state_object:: StateObject this object is compared to.
148
+ # === returns
149
+ # true:: other_state_object is equal to this StateObject.
150
+ # false:: other_state_object is not equal to this StateObject.
151
+ def eql? (other_state_object)
116
152
 
153
+ self == other_state_object
117
154
 
118
- # Verifies that another StateObject contains the same data as this object.
119
- # type, id and name must match.
120
- #
121
- # == param
122
- # other_state_object:: StateObject that this object is compared to.
123
- # == returns
124
- # true:: The other StateObject contains the same data as this one.
125
- # false:: The other StateObject does notcontain the same data as this one.
126
- # == raises
127
- # nothing
128
- def == (other_state_object)
129
- return false unless other_state_object.instance_of?( MobyBase::StateObject )
130
- return false unless self.type == other_state_object.type
131
- return false unless self.id == other_state_object.id
132
- return false unless self.name == other_state_object.name
133
- return true
134
- end
155
+ end
135
156
 
136
157
 
137
- # Function to return type of the state object
138
- # === returns
139
- # type:: String value of the type
140
- def type()
141
- @type
142
- end
158
+ # Sets the XML content of this state object. Also sets identification attributes based
159
+ # on the contents of the XML.
160
+ #
161
+ # === params
162
+ # xml_object:: MobyUtil::XML::Element. State as XML.
163
+ def xml_data=( xml_object )
164
+
165
+ @_xml_data = xml_object
166
+
167
+ unused_xpath, @name, @type, @id = TDriver::TestObjectAdapter.get_test_object_identifiers( xml_object )
168
+
169
+ end
170
+
143
171
 
144
- # Function to return name of the state object
145
- # === returns
146
- # name String value of the name
147
- def name()
148
- @name
149
- end
172
+ # Returns a XML element representing this state object.
173
+ #
174
+ # === returns
175
+ # MobyUtil::XML::Element:: XML representation of this state object
176
+ def xml_data
150
177
 
151
- # Function to return id of the state object
152
- # === returns
153
- # id String value of the id
154
- def id()
155
- @object_id
156
- end
178
+ @_xml_data
157
179
 
158
- # Sets the XML content of this state object. Also sets identification attributes based
159
- # on the contents of the XML.
160
- #
161
- # === params
162
- # xml_object:: MobyUtil::XML::Element. State as XML.
163
- def xml_data=( xml_object )
164
- @_xml_data = xml_object
165
- @name = xml_object.attribute( 'name' )
166
- @type = xml_object.attribute( 'type' )
167
- @object_id = xml_object.attribute( 'id' )
168
- end
180
+ end
169
181
 
170
- # Returns a XML element representing this state object.
171
- #
172
- # === returns
173
- # MobyUtil::XML::Element:: XML representation of this state object
174
- def xml_data()
182
+ # Function provides access to parameters of the state object
183
+ # === params
184
+ # name:: String defining the name of the attribute to get
185
+ # === returns
186
+ # String:: Value of the attribute as a string
187
+ # === raises
188
+ # ArgumentError:: name is not a String.
189
+ # AttributeNotFoundError:: if the requested attribute can not be found in the xml data of the object
190
+ def attribute( name )
175
191
 
176
- @_xml_data
192
+ # check argument variable type
193
+ name.check_type( String, "wrong argument type $1 for attribute name (expected $2)" )
194
+
195
+ begin
196
+
197
+ # retrieve attribute(s) from test object; never access ui state xml data directly from behaviour implementation
198
+ TDriver::TestObjectAdapter.test_object_attribute( @_xml_data, name.to_s )
199
+
200
+ rescue MobyBase::AttributeNotFoundError
201
+
202
+ raise MobyBase::AttributeNotFoundError, "Could not find attribute '#{ name.to_s }' for state object of type '#{ type.to_s }'"
203
+
204
+ end
205
+
206
+ end
177
207
 
178
- end
208
+ def get_cached_test_object!( object )
179
209
 
180
- # Function provides access to parameters of the state object
181
- # === params
182
- # name:: String defining the name of the attribute to get
183
- # === returns
184
- # String:: Value of the attribute as a string
185
- # === raises
186
- # ArgumentError:: name is not a String.
187
- # AttributeNotFoundError:: if the requested attribute can not be found in the xml data of the object
188
- def attribute( name )
210
+ if @child_object_cache.has_object?( object )
189
211
 
190
- # store xml_data to temp. variable
191
- _xml_data = @_xml_data
212
+ object = @child_object_cache[ object ]
192
213
 
193
- Kernel::raise ArgumentError.new( "Wrong argument type %s for attribute argument (expected String)" % name.class ) unless name.class == String
214
+ true
194
215
 
195
- Kernel::raise MobyBase::AttributeNotFoundError.new("Could not find attribute '#{ name.to_s }' for state object of type '#{ type.to_s }'.") if (
196
- elements = _xml_data.xpath(
197
- "attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ name.to_s.downcase }']"
198
- )
199
- ).size == 0
216
+ else
200
217
 
201
- elements.first.content.strip
218
+ false
202
219
 
203
- end
220
+ end
204
221
 
205
- def get_cached_test_object!( object )
222
+ end
206
223
 
207
- if @child_object_cache.has_object?( object )
224
+ # Creates a state object for a child object of this state object
225
+ # Associates child object as current object's child.
226
+ # and associates self as child object's parent.
227
+ #
228
+ # NOTE:
229
+ # Subsequent calls to #child always returns reference to same child
230
+ # === params
231
+ # attributes:: Hash object holding information for identifying which child to create, eg. :type => :slider
232
+ # === returns
233
+ # StateObject:: new child state object or reference to existing child
234
+ def child( attributes )
208
235
 
209
- object = @child_object_cache[ object ]
236
+ get_objects( attributes, false )
210
237
 
211
- true
238
+ end
212
239
 
213
- else
240
+ # TODO: document me
241
+ def children( attributes )
214
242
 
215
- false
243
+ get_objects( attributes, true )
244
+
245
+ end
246
+
247
+ # TODO: document me
248
+ def inspect
216
249
 
217
- end
250
+ "#<#{ self.class }:0x#{ ( "%x" % ( self.object_id.to_i << 1 ) )[ 3 .. -1 ] } @id=#{ @id.inspect } @type=\"#{ @type }\" @name=\"#{ @name }\">"
218
251
 
219
- end
252
+ end
220
253
 
221
- # Creates a state object for a child object of this state object
222
- # Associates child object as current object's child.
223
- # and associates self as child object's parent.
224
- #
225
- # NOTE:
226
- # Subsequent calls to #child always returns reference to same child
227
- # === params
228
- # attributes:: Hash object holding information for identifying which child to create, eg. :type => :slider
229
- # === returns
230
- # StateObject:: new child state object or reference to existing child
231
- def child( attributes )
254
+ private
255
+
256
+ def get_objects( attributes, multiple_objects )
257
+
258
+ rules = attributes.clone
232
259
 
233
- identified_object_xml = MobyBase::TestObjectIdentificator.new( attributes ).find_object_data( @_xml_data )
260
+ # strip dynamic attributes from rules hash
261
+ dynamic_attributes = rules.strip_dynamic_attributes!
234
262
 
235
- child_object = StateObject.new( identified_object_xml, self )
263
+ # retrieve application object from sut.xml_data
264
+ matches, unused_rule = TDriver::TestObjectAdapter.get_objects( @_xml_data, rules, true )
236
265
 
237
- # use cached test object if once already retrieved
238
- get_cached_test_object!( child_object ).tap{ | found_in_cache |
266
+ if matches.count == 0
239
267
 
240
- # add child to objects cache
241
- @child_object_cache.add_object( child_object ) unless found_in_cache
268
+ # raise exception if no matches found
269
+ raise MobyBase::TestObjectNotFoundError
242
270
 
243
- }
271
+ elsif matches.count > 1 and multiple_objects == false and dynamic_attributes.has_key?( :__index ) == false
244
272
 
245
- child_object
273
+ # raise exception if multiple maches found
274
+ raise MobyBase::MultipleTestObjectsIdentifiedError, "Multiple objects found with attributes #{ attributes.inspect }"
246
275
 
247
- end
276
+ end
248
277
 
249
- def inspect
278
+ # fetch matches, use index if given
279
+ matches = [ matches[ dynamic_attributes[ :__index ] || 0 ] ] unless multiple_objects
280
+
281
+ # create state objects
282
+ matches = matches.collect{ | object_xml |
283
+
284
+ result = StateObject.new( object_xml, self )
285
+
286
+ # use cached state object if once already retrieved
287
+ get_cached_test_object!( result ).tap{ | found_in_cache |
250
288
 
251
- "#{ self.to_s }\nName: #{ self.name.to_s } Type: #{ self.type.to_s } Id: #{ self.id.to_s }"
289
+ # add child to objects cache
290
+ @child_object_cache.add_object( result ) unless found_in_cache
252
291
 
253
- end
292
+ }
293
+
294
+ # pass result object to array
295
+ result
296
+
297
+ }
254
298
 
255
- # enable hooking for performance measurement & debug logging
256
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
299
+ # return results
300
+ multiple_objects ? matches : matches.first
301
+
302
+ end
257
303
 
304
+ # enable hooking for performance measurement & debug logging
305
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
258
306
 
259
- end # StateObject
307
+ end # StateObject
260
308
 
261
309
  end # MobyBase