testability-driver 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/config/sut_parameters.rb +21 -8
- data/config/tdriver_custom_error_recovery.rb +83 -0
- data/ext/extconf.rb +3 -2
- data/ext/native_extensions.c +60 -2
- data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +2 -105
- data/lib/tdriver/base/behaviour/factory.rb +154 -89
- data/lib/tdriver/base/behaviour/factory_new.rb +409 -0
- data/lib/tdriver/base/errors.rb +3 -3
- data/lib/tdriver/base/state_object.rb +85 -22
- data/lib/tdriver/base/sut/adapter.rb +26 -0
- data/lib/tdriver/base/sut/controller.rb +1 -1
- data/lib/tdriver/base/sut/generic/behaviours/application.rb +89 -118
- data/lib/tdriver/base/sut/generic/behaviours/find.rb +67 -62
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +296 -187
- data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +7 -7
- data/lib/tdriver/base/sut/generic/commands/application.rb +366 -295
- data/lib/tdriver/base/sut/sut.rb +19 -3
- data/lib/tdriver/base/test_object/abstract.rb +41 -21
- data/lib/tdriver/base/test_object/adapter.rb +62 -9
- data/lib/tdriver/base/test_object/behaviours/syncronization.rb +10 -6
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +84 -47
- data/lib/tdriver/base/test_object/factory.rb +124 -68
- data/lib/tdriver/base/test_object/loader.rb +3 -4
- data/lib/tdriver/base/test_object/verification.rb +3 -3
- data/lib/tdriver/base/test_object/xml/adapter.rb +734 -0
- data/lib/tdriver/loader.rb +12 -0
- data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +3 -2
- data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +14 -14
- data/lib/tdriver/report/report.rb +4 -8
- data/lib/tdriver/report/report_api.rb +9 -0
- data/lib/tdriver/report/report_crash_file_capture.rb +4 -4
- data/lib/tdriver/report/report_creator.rb +57 -35
- data/lib/tdriver/report/report_cucumber.rb +1 -1
- data/lib/tdriver/report/report_cucumber_listener.rb +5 -158
- data/lib/tdriver/report/report_cucumber_reporter.rb +7 -161
- data/lib/tdriver/report/report_execution_statistics.rb +4 -4
- data/lib/tdriver/report/report_file_capture.rb +5 -5
- data/lib/tdriver/report/report_grouping.rb +24 -22
- data/lib/tdriver/report/report_junit_xml.rb +5 -5
- data/lib/tdriver/report/report_test_case_run.rb +31 -22
- data/lib/tdriver/report/report_test_run.rb +107 -104
- data/lib/tdriver/report/report_writer.rb +150 -83
- data/lib/tdriver/tdriver.rb +147 -103
- data/lib/tdriver/util/common/boolean.rb +51 -0
- data/lib/tdriver/util/common/crc16.rb +110 -68
- data/lib/tdriver/util/common/hash.rb +63 -7
- data/lib/tdriver/util/common/kernel.rb +46 -1
- data/lib/tdriver/util/common/loader.rb +1 -0
- data/lib/tdriver/util/common/object.rb +20 -8
- data/lib/tdriver/util/common/string.rb +21 -2
- data/lib/tdriver/util/logger/logger.rb +4 -4
- data/lib/tdriver/util/parameter/loader.rb +2 -19
- data/lib/tdriver/util/parameter/parameter.rb +874 -177
- data/lib/tdriver/util/plugin/service.rb +1 -1
- data/lib/tdriver/util/recorder/recorder.rb +7 -1
- data/lib/tdriver/util/xml/abstraction.rb +13 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +63 -10
- data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +8 -2
- data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +16 -3
- data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +36 -32
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +19 -22
- data/lib/tdriver/util/xml/xml.rb +147 -32
- data/lib/tdriver/verify/verify.rb +1112 -289
- data/lib/tdriver/version.rb +1 -1
- data/xml/templates/generic.xml +14 -2
- metadata +51 -24
- data/lib/tdriver/util/parameter/parameter_hash.rb +0 -104
- data/lib/tdriver/util/parameter/parameter_new.rb +0 -869
- data/lib/tdriver/util/parameter/parameter_template.rb +0 -120
- data/lib/tdriver/util/parameter/parameter_user_api.rb +0 -116
- data/lib/tdriver/util/parameter/parameter_xml.rb +0 -261
@@ -252,7 +252,7 @@ module TDriver
|
|
252
252
|
rescue
|
253
253
|
|
254
254
|
# raise all other exceptions as PluginError
|
255
|
-
raise PluginError, "Error occured during calling #{ method_name } method for #{ plugin_name } (#{ $!.class }: #{ $!.message })"
|
255
|
+
raise MobyUtil::PluginError, "Error occured during calling #{ method_name } method for #{ plugin_name } (#{ $!.class }: #{ $!.message })"
|
256
256
|
|
257
257
|
end
|
258
258
|
|
@@ -53,7 +53,13 @@ module MobyUtil
|
|
53
53
|
|
54
54
|
app.stop_recording
|
55
55
|
|
56
|
-
MobyUtil::Scripter.new( sut.id, object_identificators ).write_fragment(
|
56
|
+
MobyUtil::Scripter.new( sut.id, object_identificators ).write_fragment(
|
57
|
+
|
58
|
+
#MobyBase::StateObject.new( :source_data => xml_source ),
|
59
|
+
sut.state_object( xml_source ),
|
60
|
+
app.name
|
61
|
+
|
62
|
+
)
|
57
63
|
|
58
64
|
end
|
59
65
|
|
@@ -26,12 +26,24 @@ module MobyUtil
|
|
26
26
|
attr_accessor :xml
|
27
27
|
|
28
28
|
# TODO: document me
|
29
|
-
def initialize( xml = nil )
|
29
|
+
def initialize( xml = nil, options = {} )
|
30
|
+
|
31
|
+
@options = options
|
32
|
+
|
33
|
+
@cache = Hash.new{ | hash, key | hash[ key ] = {} }
|
30
34
|
|
31
35
|
@xml = xml
|
32
36
|
|
33
37
|
end
|
34
38
|
|
39
|
+
# TODO: document me
|
40
|
+
def clone!
|
41
|
+
|
42
|
+
# create a clone of self object, also xml object is cloned; note that all references (e.g. parent) will be disconnected
|
43
|
+
self.class.new( @xml.clone )
|
44
|
+
|
45
|
+
end
|
46
|
+
|
35
47
|
# TODO: document me
|
36
48
|
def comment?
|
37
49
|
|
@@ -23,40 +23,93 @@ module MobyUtil
|
|
23
23
|
|
24
24
|
module Nokogiri
|
25
25
|
|
26
|
+
module Cache
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# TODO: document me
|
31
|
+
def initialize_cache
|
32
|
+
|
33
|
+
@cache = Hash.new{ | hash, key | hash[ key ] = {} }
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: document me
|
38
|
+
def clear_cache
|
39
|
+
|
40
|
+
@cache.clear
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO: document me
|
45
|
+
def cache( key, value )
|
46
|
+
|
47
|
+
yield
|
48
|
+
|
49
|
+
# JKo: disable xml caching for now, need more investigation why tests starts to fail
|
50
|
+
=begin
|
51
|
+
if @options[ :cache_enabled ] == true
|
52
|
+
|
53
|
+
@cache[ key ].fetch( value ){
|
54
|
+
|
55
|
+
@cache[ key ][ value ] = yield
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
else
|
60
|
+
|
61
|
+
yield
|
62
|
+
|
63
|
+
end
|
64
|
+
=end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# TODO: document me
|
69
|
+
def no_cache( *args )
|
70
|
+
|
71
|
+
yield
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
26
77
|
module Abstraction
|
27
78
|
|
79
|
+
include Cache
|
80
|
+
|
28
81
|
# TODO: Documentation
|
29
82
|
def empty?
|
30
83
|
|
31
|
-
@xml.nil?
|
84
|
+
cache( :is_nil, :value ){ @xml.nil? }
|
32
85
|
|
33
86
|
end
|
34
87
|
|
35
88
|
# TODO: Documentation
|
36
89
|
def name
|
37
90
|
|
38
|
-
@xml.name
|
91
|
+
cache( :name, :value ){ @xml.name }
|
39
92
|
|
40
93
|
end
|
41
94
|
|
42
95
|
# TODO: Documentation
|
43
96
|
def nil?
|
44
97
|
|
45
|
-
@xml.nil?
|
98
|
+
cache( :is_nil, :value ){ @xml.nil? }
|
46
99
|
|
47
100
|
end
|
48
101
|
|
49
102
|
# TODO: Documentation
|
50
103
|
def size
|
51
104
|
|
52
|
-
@xml.size
|
105
|
+
cache( :size, :value ){ @xml.size }
|
53
106
|
|
54
107
|
end
|
55
108
|
|
56
109
|
# TODO: Documentation
|
57
110
|
def to_s
|
58
111
|
|
59
|
-
@xml.to_s
|
112
|
+
cache( :to_s, :value ){ @xml.to_s }
|
60
113
|
|
61
114
|
end
|
62
115
|
|
@@ -69,23 +122,23 @@ module MobyUtil
|
|
69
122
|
|
70
123
|
when ::Nokogiri::XML::Element
|
71
124
|
|
72
|
-
XML::Element.new( object )
|
125
|
+
XML::Element.new( object, @options )
|
73
126
|
|
74
127
|
when ::Nokogiri::XML::NodeSet
|
75
128
|
|
76
|
-
XML::Nodeset.new( object )
|
129
|
+
XML::Nodeset.new( object, @options )
|
77
130
|
|
78
131
|
when ::Nokogiri::XML::Text
|
79
132
|
|
80
|
-
XML::Text.new( object )
|
133
|
+
XML::Text.new( object, @options )
|
81
134
|
|
82
135
|
when ::Nokogiri::XML::Attr
|
83
136
|
|
84
|
-
XML::Attribute.new( object )
|
137
|
+
XML::Attribute.new( object, @options )
|
85
138
|
|
86
139
|
when ::Nokogiri::XML::Comment
|
87
140
|
|
88
|
-
XML::Comment.new( object )
|
141
|
+
XML::Comment.new( object, @options )
|
89
142
|
|
90
143
|
when ::NilClass
|
91
144
|
|
@@ -30,13 +30,19 @@ module MobyUtil
|
|
30
30
|
# TODO: document me
|
31
31
|
def value
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
cache( :value, :value ){
|
34
|
+
|
35
|
+
@xml.value
|
36
|
+
|
37
|
+
}
|
38
|
+
|
35
39
|
end
|
36
40
|
|
37
41
|
# TODO: document me
|
38
42
|
def value=( content )
|
39
43
|
|
44
|
+
clear_cache
|
45
|
+
|
40
46
|
@xml.value = content
|
41
47
|
|
42
48
|
end
|
@@ -28,16 +28,29 @@ module MobyUtil
|
|
28
28
|
include Node
|
29
29
|
|
30
30
|
# TODO: document me
|
31
|
-
def
|
31
|
+
def initialize( xml, options = {} )
|
32
32
|
|
33
|
-
|
33
|
+
@options = options
|
34
34
|
|
35
|
+
initialize_cache
|
36
|
+
|
37
|
+
@xml = parse( xml )
|
38
|
+
|
35
39
|
end
|
36
40
|
|
37
41
|
# TODO: document me
|
38
42
|
def root
|
43
|
+
|
44
|
+
cache( :root, :value ){ node_object( @xml.root ) }
|
45
|
+
|
46
|
+
end
|
39
47
|
|
40
|
-
|
48
|
+
private
|
49
|
+
|
50
|
+
# TODO: document me
|
51
|
+
def parse( xml_string )
|
52
|
+
|
53
|
+
::Nokogiri::XML.parse( xml_string, nil, 'UTF-8', ::Nokogiri::XML::ParseOptions::STRICT )
|
41
54
|
|
42
55
|
end
|
43
56
|
|
@@ -30,13 +30,15 @@ module MobyUtil
|
|
30
30
|
# TODO: document me
|
31
31
|
def []( value )
|
32
32
|
|
33
|
-
@xml[ value ]
|
33
|
+
cache( __method__, value ){ @xml[ value ] }
|
34
34
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# TODO: document me
|
38
38
|
def []=( name, value )
|
39
39
|
|
40
|
+
clear_cache
|
41
|
+
|
40
42
|
@xml[ name ] = value
|
41
43
|
|
42
44
|
end
|
@@ -44,8 +46,8 @@ module MobyUtil
|
|
44
46
|
# TODO: document me
|
45
47
|
def ==( object )
|
46
48
|
|
47
|
-
@xml.content == object.xml.content
|
48
|
-
|
49
|
+
cache( __method__, object.object_id ){ @xml.content == object.xml.content }
|
50
|
+
|
49
51
|
end
|
50
52
|
|
51
53
|
# aliases for ==
|
@@ -54,13 +56,15 @@ module MobyUtil
|
|
54
56
|
# TODO: document me
|
55
57
|
def <=>( object )
|
56
58
|
|
57
|
-
@xml <=> object.xml
|
59
|
+
cache( __method__, object.object_id ){ @xml <=> object.xml }
|
58
60
|
|
59
61
|
end
|
60
62
|
|
61
63
|
# TODO: document me
|
62
64
|
def add_previous_sibling( other )
|
63
65
|
|
66
|
+
clear_cache
|
67
|
+
|
64
68
|
@xml.add_previous_sibling( other.xml )
|
65
69
|
|
66
70
|
end
|
@@ -68,44 +72,40 @@ module MobyUtil
|
|
68
72
|
# TODO: document me
|
69
73
|
def attribute( attr_name )
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
value.to_s
|
74
|
-
|
75
|
-
end
|
75
|
+
cache( :attribute, attr_name ){ _attribute( @xml.attribute( attr_name ) ) }
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
79
|
# TODO: document me
|
80
80
|
def attributes
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
cache( :attributes, :value ){
|
83
|
+
# return hash of attributes
|
84
|
+
Hash[ @xml.attribute_nodes.collect{ | node |
|
85
|
+
[ node.node_name, node.value.to_s ] }
|
86
|
+
]
|
87
|
+
}
|
88
88
|
|
89
89
|
end
|
90
90
|
|
91
91
|
# TODO: document me
|
92
92
|
def blank?
|
93
93
|
|
94
|
-
@xml.blank?
|
94
|
+
cache( :is_blank, :value ){ @xml.blank? }
|
95
95
|
|
96
96
|
end
|
97
97
|
|
98
98
|
# TODO: document me
|
99
99
|
def children
|
100
100
|
|
101
|
-
node_object( @xml.children )
|
101
|
+
cache( :children, :value ){ node_object( @xml.children ) }
|
102
102
|
|
103
103
|
end
|
104
104
|
|
105
105
|
# TODO: document me
|
106
106
|
def content
|
107
107
|
|
108
|
-
@xml.content
|
108
|
+
cache( :content, :value ){ @xml.content }
|
109
109
|
|
110
110
|
end
|
111
111
|
|
@@ -119,7 +119,7 @@ module MobyUtil
|
|
119
119
|
# iterate each attribute
|
120
120
|
@xml.each{ | element |
|
121
121
|
|
122
|
-
yield( node_object( element ) )
|
122
|
+
yield( cache( :each, element ){ node_object( element ) } )
|
123
123
|
|
124
124
|
}
|
125
125
|
|
@@ -130,7 +130,7 @@ module MobyUtil
|
|
130
130
|
# TODO: document me
|
131
131
|
def inner_html
|
132
132
|
|
133
|
-
@xml.inner_html
|
133
|
+
cache( :inner_html, :value ){ @xml.inner_html }
|
134
134
|
|
135
135
|
end
|
136
136
|
|
@@ -139,21 +139,23 @@ module MobyUtil
|
|
139
139
|
|
140
140
|
# TODO: document me
|
141
141
|
def to_s
|
142
|
-
|
143
|
-
@xml.to_s
|
142
|
+
|
143
|
+
cache( :to_s, :value ){ @xml.to_s }
|
144
144
|
|
145
145
|
end
|
146
146
|
|
147
147
|
# TODO: document me
|
148
148
|
def parent
|
149
149
|
|
150
|
-
node_object( @xml.parent )
|
150
|
+
cache( :parent, :value ){ node_object( @xml.parent ) }
|
151
151
|
|
152
152
|
end
|
153
153
|
|
154
154
|
# TODO: document me
|
155
155
|
def remove
|
156
156
|
|
157
|
+
clear_cache
|
158
|
+
|
157
159
|
@xml.remove
|
158
160
|
|
159
161
|
self
|
@@ -163,6 +165,8 @@ module MobyUtil
|
|
163
165
|
# TODO: document me
|
164
166
|
def replace( other )
|
165
167
|
|
168
|
+
clear_cache
|
169
|
+
|
166
170
|
@xml.replace( other.xml )
|
167
171
|
|
168
172
|
self
|
@@ -172,23 +176,23 @@ module MobyUtil
|
|
172
176
|
# TODO: document me
|
173
177
|
def xpath( xpath_query, *args, &block )
|
174
178
|
|
175
|
-
node_object(
|
176
|
-
|
177
|
-
@xml.xpath( xpath_query, *args, &block )
|
178
|
-
|
179
|
-
)
|
179
|
+
cache( :xpath, xpath_query ){ node_object( @xml.xpath( xpath_query, *args, &block ) ) }
|
180
180
|
|
181
181
|
end
|
182
182
|
|
183
183
|
# TODO: document me
|
184
184
|
def at_xpath( xpath_query, *args, &block )
|
185
185
|
|
186
|
-
node_object(
|
186
|
+
cache( :at_xpath, xpath_query ){ node_object( @xml.at_xpath( xpath_query, *args, &block ) ) }
|
187
187
|
|
188
|
-
|
189
|
-
|
190
|
-
)
|
188
|
+
end
|
191
189
|
|
190
|
+
private
|
191
|
+
|
192
|
+
def _attribute( value )
|
193
|
+
|
194
|
+
value.to_s unless value.nil?
|
195
|
+
|
192
196
|
end
|
193
197
|
|
194
198
|
# enable hooking for performance measurement & debug logging
|
@@ -25,23 +25,23 @@ module MobyUtil
|
|
25
25
|
|
26
26
|
module Nodeset # behaviour
|
27
27
|
|
28
|
-
include Abstraction
|
28
|
+
include Abstraction
|
29
29
|
|
30
30
|
def []( node )
|
31
31
|
|
32
|
-
node_object( @xml[ node ] )
|
32
|
+
cache( :at_index, node ){ node_object( @xml[ node ] ) }
|
33
33
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def first
|
37
37
|
|
38
|
-
node_object( @xml.first )
|
38
|
+
cache( :first, :vaue ){ node_object( @xml.first ) }
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def last
|
43
43
|
|
44
|
-
node_object( @xml.last )
|
44
|
+
cache( :last, :value ){ node_object( @xml.last ) }
|
45
45
|
|
46
46
|
end
|
47
47
|
|
@@ -49,7 +49,7 @@ module MobyUtil
|
|
49
49
|
|
50
50
|
@xml.each{ | node |
|
51
51
|
|
52
|
-
yield( node_object( node ) )
|
52
|
+
yield( cache( :each, node ){ node_object( node ) } )
|
53
53
|
|
54
54
|
}
|
55
55
|
|
@@ -61,7 +61,7 @@ module MobyUtil
|
|
61
61
|
|
62
62
|
@xml.each_with_index{ | node, index |
|
63
63
|
|
64
|
-
yield( node_object( node ), index )
|
64
|
+
yield( cache( :each, node ){ node_object( node ) }, index )
|
65
65
|
|
66
66
|
}
|
67
67
|
|
@@ -72,12 +72,13 @@ module MobyUtil
|
|
72
72
|
def collect( &block )
|
73
73
|
|
74
74
|
_collect( &block )
|
75
|
-
#nodeset_object( _collect( &block ) )
|
76
75
|
|
77
76
|
end
|
78
77
|
|
79
78
|
def collect!( &block )
|
80
79
|
|
80
|
+
clear_cache
|
81
|
+
|
81
82
|
@xml = _collect( &block )
|
82
83
|
|
83
84
|
self
|
@@ -86,13 +87,13 @@ module MobyUtil
|
|
86
87
|
|
87
88
|
def compact
|
88
89
|
|
89
|
-
nodeset_object( @xml.compact )
|
90
|
+
cache( :compact, :value ){ nodeset_object( @xml.compact ) }
|
90
91
|
|
91
92
|
end
|
92
93
|
|
93
94
|
def compact!
|
94
95
|
|
95
|
-
@xml = @xml.compact
|
96
|
+
@xml = cache( :compact_, :value ){ @xml.compact }
|
96
97
|
|
97
98
|
self
|
98
99
|
|
@@ -106,6 +107,8 @@ module MobyUtil
|
|
106
107
|
|
107
108
|
def sort!( &block )
|
108
109
|
|
110
|
+
clear_cache
|
111
|
+
|
109
112
|
@xml = _sort( &block )
|
110
113
|
|
111
114
|
self
|
@@ -114,29 +117,27 @@ module MobyUtil
|
|
114
117
|
|
115
118
|
def empty?
|
116
119
|
|
117
|
-
@xml.empty?
|
120
|
+
cache( :is_empty, :value ){ @xml.empty? }
|
118
121
|
|
119
122
|
end
|
120
123
|
|
121
124
|
def length
|
122
125
|
|
123
|
-
@xml.length
|
126
|
+
cache( :length, :value ){ @xml.length }
|
124
127
|
|
125
128
|
end
|
126
129
|
|
127
130
|
|
128
131
|
def to_a
|
129
132
|
|
130
|
-
@xml.collect{ | node |
|
131
|
-
|
132
|
-
node_object( node )
|
133
|
-
|
134
|
-
}
|
133
|
+
cache( :to_a, :value ){ @xml.collect{ | node | node_object( node ) } }
|
135
134
|
|
136
135
|
end
|
137
136
|
|
138
137
|
def delete( node )
|
139
138
|
|
139
|
+
clear_cache
|
140
|
+
|
140
141
|
@xml.each do | nodeset_node |
|
141
142
|
|
142
143
|
if ( node.xml.content == nodeset_node.content )
|
@@ -160,11 +161,7 @@ module MobyUtil
|
|
160
161
|
|
161
162
|
def _collect( &block )
|
162
163
|
|
163
|
-
@xml.collect{ | node |
|
164
|
-
|
165
|
-
yield( node_object( node ) )
|
166
|
-
|
167
|
-
}
|
164
|
+
@xml.collect{ | node | yield( cache( :each, node ){ node_object( node ) } ) }
|
168
165
|
|
169
166
|
end
|
170
167
|
|
@@ -174,7 +171,7 @@ module MobyUtil
|
|
174
171
|
|
175
172
|
if block_given?
|
176
173
|
|
177
|
-
yield( node_object( node_a ), node_object( node_b ) )
|
174
|
+
yield( cache( :each, node_a ){ node_object( node_a ) }, cache( :each, node_b ){ node_object( node_b ) } )
|
178
175
|
|
179
176
|
else
|
180
177
|
|