testability-driver 0.9.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +1 -1
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +11 -7
- data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +8 -0
- data/lib/tdriver/base/behaviour/factory.rb +229 -209
- data/lib/tdriver/base/errors.rb +3 -0
- data/lib/tdriver/base/state_object.rb +11 -20
- data/lib/tdriver/base/sut/controller.rb +4 -4
- data/lib/tdriver/base/sut/factory.rb +205 -170
- data/lib/tdriver/base/sut/generic/behaviours/application.rb +256 -174
- data/lib/tdriver/base/sut/generic/behaviours/find.rb +17 -11
- data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +57 -66
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +578 -497
- data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +41 -15
- data/lib/tdriver/base/sut/generic/behaviours/verification.rb +48 -19
- data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
- data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +25 -13
- data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +16 -10
- data/lib/tdriver/base/sut/generic/plugin.rb +9 -3
- data/lib/tdriver/base/sut/sut.rb +41 -33
- data/lib/tdriver/base/test_object/abstract.rb +26 -3
- data/lib/tdriver/base/test_object/adapter.rb +399 -0
- data/lib/tdriver/base/test_object/behaviours/syncronization.rb +56 -14
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +663 -197
- data/lib/tdriver/base/test_object/cache.rb +132 -0
- data/lib/tdriver/base/test_object/factory.rb +677 -426
- data/lib/tdriver/base/test_object/factory_new.rb +202 -0
- data/lib/tdriver/base/test_object/identificator.rb +24 -17
- data/lib/tdriver/base/test_object/loader.rb +9 -3
- data/lib/tdriver/base/test_object/verification.rb +181 -0
- data/lib/tdriver/loader.rb +1 -1
- data/lib/tdriver/report/report.rb +2 -0
- data/lib/tdriver/report/report_api.rb +4 -4
- data/lib/tdriver/report/report_creator.rb +29 -3
- data/lib/tdriver/report/report_data_presentation.rb +7 -3
- data/lib/tdriver/report/report_execution_statistics.rb +80 -21
- data/lib/tdriver/report/report_javascript.rb +192 -0
- data/lib/tdriver/report/report_test_case_run.rb +22 -0
- data/lib/tdriver/report/report_test_run.rb +62 -55
- data/lib/tdriver/report/report_writer.rb +57 -56
- data/lib/tdriver/tdriver.rb +14 -41
- data/lib/tdriver/util/common/error.rb +1 -0
- data/lib/tdriver/util/common/exceptions.rb +12 -0
- data/lib/tdriver/util/common/file.rb +12 -6
- data/lib/tdriver/util/common/gem.rb +2 -1
- data/lib/tdriver/util/common/hash.rb +152 -0
- data/lib/tdriver/util/common/kernel.rb +49 -34
- data/lib/tdriver/util/common/loader.rb +21 -17
- data/lib/tdriver/util/common/numeric.rb +39 -0
- data/lib/tdriver/util/common/object.rb +115 -0
- data/lib/tdriver/util/common/string.rb +55 -2
- data/lib/tdriver/util/dbaccess/dbaccess.rb +194 -161
- data/lib/tdriver/util/dynamic_attribute_filter.rb +6 -0
- data/lib/tdriver/util/hooking.rb +2 -2
- data/lib/tdriver/util/loader.rb +2 -2
- data/lib/tdriver/util/localisation/localisation.rb +277 -18
- data/lib/tdriver/util/logger.rb +142 -13
- data/lib/tdriver/util/parameter/parameter_hash.rb +8 -5
- data/lib/tdriver/util/parameter/parameter_xml.rb +18 -2
- data/lib/tdriver/util/recorder.rb +17 -12
- data/lib/tdriver/util/user_data/user_data.rb +3 -2
- data/lib/tdriver/util/{video_rec.rb → video_utils.rb} +136 -16
- data/lib/tdriver/util/xml/abstraction.rb +7 -0
- data/lib/tdriver/util/xml/attribute.rb +32 -0
- data/lib/tdriver/util/xml/loader.rb +8 -2
- data/lib/tdriver/util/xml/nil_node.rb +95 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +46 -7
- data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +19 -9
- data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +1 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +13 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +6 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +27 -15
- data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +57 -0
- data/lib/tdriver/util/xml/text.rb +32 -0
- data/lib/tdriver/util/xml/xml.rb +35 -22
- data/lib/tdriver/version.rb +1 -1
- data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +41 -34
- data/lib/tdriver-devtools/doc/generate.rb +31 -6
- data/lib/tdriver-devtools/doc/xslt/template.xsl +46 -25
- data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
- data/lib/tdriver-devtools/tests/feature_tests/update +1 -1
- data/lib/tdriver.rb +0 -3
- data/xml/behaviours/generic.xml +1 -1
- data/xml/defaults/generic.xml +4 -90
- data/xml/templates/generic.xml +33 -25
- metadata +21 -29
- data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +0 -245
- data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +0 -964
- data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +0 -68
- data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +0 -1865
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +0 -12
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +0 -5
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +0 -2
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +0 -7
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +0 -14
- data/lib/tdriver-devtools/behaviour/xml_generator/update +0 -3
- data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +0 -233
- data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +0 -194
data/lib/tdriver/tdriver.rb
CHANGED
|
@@ -25,11 +25,16 @@
|
|
|
25
25
|
#
|
|
26
26
|
# Please see class documentation for more info
|
|
27
27
|
|
|
28
|
+
# initializing TDriver
|
|
29
|
+
$TDRIVER_INITIALIZED = false
|
|
30
|
+
|
|
31
|
+
# unicode support
|
|
28
32
|
$KCODE = 'u'
|
|
29
33
|
|
|
30
|
-
#
|
|
34
|
+
# prevent Object#id Warnings
|
|
31
35
|
Object.send( :undef_method, :id ) if Object.respond_to?( :id )
|
|
32
36
|
|
|
37
|
+
# load all required components
|
|
33
38
|
require File.expand_path( File.join( File.dirname( __FILE__ ), 'loader' ) )
|
|
34
39
|
|
|
35
40
|
module TDriver
|
|
@@ -49,15 +54,10 @@ module TDriver
|
|
|
49
54
|
# Object:: Object that SutFactory returns
|
|
50
55
|
# === example
|
|
51
56
|
# @sut = TDriver.connect_sut(:Id =>'sut_qt') # for qt, id in configuration file sut_qt
|
|
52
|
-
def self.connect_sut( sut_attributes = {} )
|
|
53
|
-
|
|
54
|
-
# if given arguments is type of Symbol expect is as SUT id
|
|
55
|
-
sut_attributes = { :Id => sut_attributes } if sut_attributes.kind_of? Symbol
|
|
57
|
+
def self.connect_sut( sut_attributes = {} )
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
Kernel::raise ArgumentError.new( "Sut id not given!" ) unless sut_attributes.has_key?( :Id )
|
|
59
|
+
MobyBase::SUTFactory.instance.make( sut_attributes )
|
|
59
60
|
|
|
60
|
-
MobyBase::SUTFactory.instance.make( sut_attributes[ :Id ] )
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# Function to disconnect SUT object.
|
|
@@ -73,13 +73,7 @@ module TDriver
|
|
|
73
73
|
# @sut = TDriver.disconnect_sut(:Id =>'sut_qt') # for qt, should be connected already
|
|
74
74
|
def self.disconnect_sut( sut_attributes = {} )
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
sut_attributes = { :Id => sut_attributes } if sut_attributes.kind_of? Symbol
|
|
78
|
-
|
|
79
|
-
Kernel::raise ArgumentError.new( "Wrong argument type '%s' (Expected Hash)" % sut_attributes.class ) unless sut_attributes.kind_of?( Hash )
|
|
80
|
-
Kernel::raise ArgumentError.new( "Sut id not given!" ) unless sut_attributes.has_key?( :Id )
|
|
81
|
-
|
|
82
|
-
MobyBase::SUTFactory.instance.disconnect_sut( sut_attributes[ :Id ] )
|
|
76
|
+
MobyBase::SUTFactory.instance.disconnect_sut( sut_attributes )
|
|
83
77
|
|
|
84
78
|
end
|
|
85
79
|
|
|
@@ -94,13 +88,7 @@ module TDriver
|
|
|
94
88
|
# @sut = TDriver.reboot_sut(:Id =>'sut_qt') # for Qt, should be connected already
|
|
95
89
|
def self.reboot_sut( sut_attributes = {} )
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
sut_attributes = { :Id => sut_attributes } if sut_attributes.kind_of? Symbol
|
|
99
|
-
|
|
100
|
-
Kernel::raise ArgumentError.new( "Wrong argument type '%s' (Expected Hash)" % sut_attributes.class ) unless sut_attributes.kind_of?( Hash )
|
|
101
|
-
Kernel::raise ArgumentError.new( "Sut id not given!" ) unless sut_attributes.has_key?( :Id )
|
|
102
|
-
|
|
103
|
-
MobyBase::SUTFactory.instance.reboot_sut( sut_attributes[ :Id ] )
|
|
91
|
+
MobyBase::SUTFactory.instance.reboot_sut( sut_attributes )
|
|
104
92
|
|
|
105
93
|
end
|
|
106
94
|
|
|
@@ -134,25 +122,10 @@ module TDriver
|
|
|
134
122
|
# enable hooking for performance measurement & debug logging
|
|
135
123
|
MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
|
|
136
124
|
|
|
137
|
-
|
|
138
125
|
end # TDriver
|
|
139
126
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
# for debugging to see every occured exception
|
|
143
|
-
def Kernel::raise( *args )
|
|
144
|
-
|
|
145
|
-
exception = args.first || $!
|
|
146
|
-
|
|
147
|
-
backtrace = caller.collect{ | line | " %s" % line }.join("\n")
|
|
148
|
-
|
|
149
|
-
puts "%s: %s\nBacktrace: \n%s\n\n" % [ exception.class, exception.message, backtrace ]
|
|
150
|
-
|
|
151
|
-
super
|
|
152
|
-
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# Enable logging engine
|
|
127
|
+
# enable logging engine
|
|
158
128
|
MobyUtil::Logger.instance.enable_logging()
|
|
129
|
+
|
|
130
|
+
# initialization done, everything is ready
|
|
131
|
+
$TDRIVER_INITIALIZED = true
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# place all custom TDriver exception classes here
|
|
2
|
+
class MobyStandardError < StandardError
|
|
3
|
+
|
|
4
|
+
# Construct a new error, optionally passing in a message
|
|
5
|
+
def initialize ( message = nil )
|
|
6
|
+
super( message )
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# file not found error
|
|
12
|
+
class FileNotFoundError < MobyStandardError; end;
|
|
@@ -60,7 +60,7 @@ module MobyUtil
|
|
|
60
60
|
|
|
61
61
|
require_files = Dir.glob( MobyUtil::FileHelper.fix_path( path ) )
|
|
62
62
|
|
|
63
|
-
Kernel::raise
|
|
63
|
+
Kernel::raise RuntimeError.new( "File not found %s" % [ path ] ) if !File.directory?( path ) && !File.file?( path ) && require_files.empty?
|
|
64
64
|
|
|
65
65
|
# load each module found from given folder
|
|
66
66
|
require_files.each { | module_name |
|
|
@@ -81,7 +81,8 @@ module MobyUtil
|
|
|
81
81
|
# String:: String presentation of fixed path
|
|
82
82
|
def self.fix_path( path )
|
|
83
83
|
|
|
84
|
-
Kernel::raise ArgumentError.new( "Invalid argument format %s (Expected: %s)" % [ path.class, "String" ] ) unless path.kind_of?( String )
|
|
84
|
+
#Kernel::raise ArgumentError.new( "Invalid argument format %s (Expected: %s)" % [ path.class, "String" ] ) unless path.kind_of?( String )
|
|
85
|
+
path.check_type( String, "Wrong argument type $1 for file path (expected $2)" )
|
|
85
86
|
|
|
86
87
|
# replace back-/slashes to File::SEPARATOR
|
|
87
88
|
path.gsub( /[\\\/]/, File::SEPARATOR ).to_s
|
|
@@ -113,8 +114,11 @@ module MobyUtil
|
|
|
113
114
|
# ArgumentError:: Given path is empty
|
|
114
115
|
def self.is_relative_path?( path )
|
|
115
116
|
|
|
116
|
-
Kernel::raise ArgumentError.new("Unexpected argument type '%s' for path (Expected: %s)" % [ path.class, 'String' ] ) unless path.kind_of?( String )
|
|
117
|
-
|
|
117
|
+
#Kernel::raise ArgumentError.new("Unexpected argument type '%s' for path (Expected: %s)" % [ path.class, 'String' ] ) unless path.kind_of?( String )
|
|
118
|
+
path.check_type( String, "Wrong argument type $1 for file path (expected $2)" )
|
|
119
|
+
|
|
120
|
+
#Kernel::raise ArgumentError.new("Given path is empty") if path.empty?
|
|
121
|
+
path.not_empty( "Filepath must not be empty string" )
|
|
118
122
|
|
|
119
123
|
dirname = File.dirname( path )
|
|
120
124
|
|
|
@@ -236,7 +240,9 @@ module MobyUtil
|
|
|
236
240
|
# IOError:: Error occured while creating folder
|
|
237
241
|
def self.copy_file( source, destination, verbose = false, overwrite = true, create_folders = true, &block )
|
|
238
242
|
|
|
239
|
-
|
|
243
|
+
source.check_type( String, "Wrong argument type $1 for source file (expected $2)" )
|
|
244
|
+
|
|
245
|
+
destination.check_type( String, "Wrong argument type $1 for destination file (expected $2)" )
|
|
240
246
|
|
|
241
247
|
sources = []
|
|
242
248
|
|
|
@@ -273,7 +279,7 @@ module MobyUtil
|
|
|
273
279
|
# create destination folder if it doesn't exist and create_folders flag is enabled
|
|
274
280
|
MobyUtil::FileHelper.mkdir_path( destination_folder ) if create_folders
|
|
275
281
|
|
|
276
|
-
Kernel::raise RuntimeError.new( "
|
|
282
|
+
Kernel::raise RuntimeError.new( "Unable to copy %s to %s due to source file does not exist" % [ source, destination ] ) unless File.exist?( source )
|
|
277
283
|
|
|
278
284
|
File.copy(
|
|
279
285
|
|
|
@@ -58,6 +58,7 @@ module MobyUtil
|
|
|
58
58
|
if MobyUtil::EnvironmentHelper.windows?
|
|
59
59
|
|
|
60
60
|
File.open( 'nmake.bat', 'w') { |f| f.write "SET ERRORLEVEL=0" }
|
|
61
|
+
File.open( 'make.bat', 'w') { |f| f.write "SET ERRORLEVEL=0" }
|
|
61
62
|
File.open( 'extconf.dll', 'w' ) {}
|
|
62
63
|
|
|
63
64
|
else
|
|
@@ -90,7 +91,7 @@ module MobyUtil
|
|
|
90
91
|
# TODO: document
|
|
91
92
|
def self.install( *parameters, &block )
|
|
92
93
|
|
|
93
|
-
Kernel::raise ArgumentError.new( "Target folder
|
|
94
|
+
Kernel::raise ArgumentError.new( "Target folder must be specified as first argument" ) if parameters.empty?
|
|
94
95
|
|
|
95
96
|
yield( *parameters )
|
|
96
97
|
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
##
|
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
4
|
+
## All rights reserved.
|
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
|
6
|
+
##
|
|
7
|
+
## This file is part of Testability Driver.
|
|
8
|
+
##
|
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
|
11
|
+
##
|
|
12
|
+
## This library is free software; you can redistribute it and/or
|
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
|
16
|
+
## of this file.
|
|
17
|
+
##
|
|
18
|
+
############################################################################
|
|
19
|
+
|
|
20
|
+
# extend Ruby Hash class functionality
|
|
21
|
+
class Hash
|
|
22
|
+
|
|
23
|
+
def not_empty( message = "Hash must not be empty", exception = ArgumentError )
|
|
24
|
+
|
|
25
|
+
raise exception.new( message ) if self.empty?
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Verify that received object contains one of given keys. Raises exception is key not found.
|
|
30
|
+
def require_key( keys, message = "None of key(s) $1 found from hash" )
|
|
31
|
+
|
|
32
|
+
# create array of types
|
|
33
|
+
keys_array = keys.kind_of?( Array ) ? keys : [ keys ]
|
|
34
|
+
|
|
35
|
+
found = false
|
|
36
|
+
|
|
37
|
+
verbose_keys_list = keys_array.each_with_index.collect{ | key, index |
|
|
38
|
+
|
|
39
|
+
found = true if self.has_key?( key )
|
|
40
|
+
|
|
41
|
+
# result string, separate types if multiple types given
|
|
42
|
+
"#{ ( ( index > 0 ) ? ( index + 1 < keys_array.count ? ", " : " or " ) : "" ) }#{ key.inspect }"
|
|
43
|
+
|
|
44
|
+
}.join
|
|
45
|
+
|
|
46
|
+
# raise exception if type did not match
|
|
47
|
+
unless found
|
|
48
|
+
|
|
49
|
+
# convert macros
|
|
50
|
+
[ verbose_keys_list ].each_with_index{ | param, index | message.gsub!( "$#{ index + 1 }", param.to_s ) }
|
|
51
|
+
|
|
52
|
+
# raise the exception
|
|
53
|
+
raise ArgumentError.new( message )
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
self
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Verify that received object contains all of given keys. Raises exception is key not found.
|
|
62
|
+
def require_keys( keys, message = "Required key(s) $1 not found from hash" )
|
|
63
|
+
|
|
64
|
+
# create array of types
|
|
65
|
+
keys_array = keys.kind_of?( Array ) ? keys : [ keys ]
|
|
66
|
+
|
|
67
|
+
found = true
|
|
68
|
+
|
|
69
|
+
verbose_keys_list = keys_array.each_with_index.collect{ | key, index |
|
|
70
|
+
|
|
71
|
+
found = false unless self.has_key?( key )
|
|
72
|
+
|
|
73
|
+
# result string, separate types if multiple types given
|
|
74
|
+
"#{ ( ( index > 0 ) ? ( index + 1 < keys_array.count ? ", " : " and " ) : "" ) }#{ key.inspect }"
|
|
75
|
+
|
|
76
|
+
}.join
|
|
77
|
+
|
|
78
|
+
# raise exception if type did not match
|
|
79
|
+
unless found
|
|
80
|
+
|
|
81
|
+
# convert macros
|
|
82
|
+
[ verbose_keys_list ].each_with_index{ | param, index | message.gsub!( "$#{ index + 1 }", param.to_s ) }
|
|
83
|
+
|
|
84
|
+
# raise the exception
|
|
85
|
+
raise ArgumentError.new( message )
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
self
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# collect given keypairs from hash
|
|
94
|
+
def collect_keys( *keys )
|
|
95
|
+
|
|
96
|
+
Hash[ self.select{ | key, value | true if keys.include?( key ) } ]
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# store keys and values to hash if not already defined
|
|
101
|
+
def default_values( hash )
|
|
102
|
+
|
|
103
|
+
hash.each_pair{ | key, value |
|
|
104
|
+
|
|
105
|
+
self[ key ] = value unless has_key?( key )
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
self
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# store key and avalue to hash if not already defined
|
|
114
|
+
def default_value( key, value )
|
|
115
|
+
|
|
116
|
+
self[ key ] = value unless has_key?( key )
|
|
117
|
+
|
|
118
|
+
self
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def strip_dynamic_attributes!
|
|
123
|
+
|
|
124
|
+
# remove dynamic attributes from hash and return as result
|
|
125
|
+
Hash[
|
|
126
|
+
|
|
127
|
+
# iterate through each hash key
|
|
128
|
+
select{ | key, value |
|
|
129
|
+
|
|
130
|
+
# dynamic attribute name has "__" prefix
|
|
131
|
+
if key.to_s =~ /^__/
|
|
132
|
+
|
|
133
|
+
# remove dynamic attribute key from hash
|
|
134
|
+
delete( key )
|
|
135
|
+
|
|
136
|
+
# add to hash
|
|
137
|
+
true
|
|
138
|
+
|
|
139
|
+
else
|
|
140
|
+
|
|
141
|
+
# do not add to hash
|
|
142
|
+
false
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
end # strip_dynamic_attributes!
|
|
151
|
+
|
|
152
|
+
end
|
|
@@ -117,67 +117,82 @@ module MobyUtil
|
|
|
117
117
|
# RuntimeError:: from_file is not correctly formed, the file cannot be loaded or the line cannot be found.
|
|
118
118
|
def self.find_source( backtrace )
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
result = "\n"
|
|
121
121
|
|
|
122
122
|
begin
|
|
123
123
|
|
|
124
|
+
# split with colon
|
|
124
125
|
call_stack = backtrace.to_s.split(':')
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
line_number =
|
|
128
|
-
if (call_stack.size() == 2)
|
|
129
|
-
line_number = call_stack[1].to_i
|
|
130
|
-
|
|
131
|
-
else
|
|
132
|
-
line_number = call_stack[call_stack.size()-2].to_i
|
|
133
|
-
end
|
|
134
|
-
#puts "line number: " << line_number.to_s
|
|
126
|
+
|
|
127
|
+
# TODO: document me
|
|
128
|
+
line_number = ( call_stack.size == 2 ? call_stack[ 1 ].to_i : call_stack[ call_stack.size - 2 ] ).to_i
|
|
135
129
|
|
|
136
130
|
file_path = ""
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
|
|
132
|
+
# TODO: document me
|
|
133
|
+
if ( call_stack.size == 2 )
|
|
134
|
+
|
|
135
|
+
file_path = call_stack[ 0 ]
|
|
136
|
+
|
|
139
137
|
else
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
|
|
139
|
+
# TODO: document me
|
|
140
|
+
( call_stack.size - 2 ).times do | index |
|
|
141
|
+
|
|
142
|
+
file_path << "%s:" % call_stack[ index ]
|
|
143
|
+
|
|
142
144
|
end
|
|
143
|
-
|
|
145
|
+
|
|
146
|
+
# remove the trailing colon
|
|
147
|
+
file_path.slice!(-1)
|
|
148
|
+
|
|
144
149
|
end
|
|
145
|
-
|
|
146
|
-
|
|
150
|
+
|
|
151
|
+
# TODO: document me
|
|
147
152
|
lines_to_read = line_number >= 2 ? 3 : line_number
|
|
148
153
|
#puts "lines to read: " << lines_to_read.to_s
|
|
149
154
|
|
|
155
|
+
# TODO: document me
|
|
150
156
|
start_line = line_number #- (lines_to_read <= 1 ? 0 : 1)
|
|
151
157
|
#puts "start line:" << start_line.to_s
|
|
152
158
|
|
|
153
|
-
|
|
159
|
+
# expand file path and name
|
|
160
|
+
filename = File.expand_path( file_path.to_s )
|
|
154
161
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
Kernel::raise RuntimeError.new("Only \"#{lines.size.to_s}\" lines exist in the source file.")if start_line > lines.size
|
|
158
|
-
|
|
159
|
-
lines_to_read = (lines.size - start_line + 1) < 3 ? (lines.size - start_line + 1) : lines_to_read
|
|
162
|
+
# open source file
|
|
163
|
+
File.open( filename, "r") { | source |
|
|
160
164
|
|
|
165
|
+
# read lines
|
|
166
|
+
lines = source.readlines
|
|
167
|
+
|
|
168
|
+
# raise exception if line number is larger than total number of lines
|
|
169
|
+
Kernel::raise RuntimeError.new(
|
|
170
|
+
|
|
171
|
+
"Unable to fetch line %s from source file %s due to it is out of range (total lines: %s)" % [ start_line, filename, lines.size ]
|
|
172
|
+
|
|
173
|
+
) if start_line > lines.size
|
|
174
|
+
|
|
175
|
+
# TODO: document me
|
|
176
|
+
lines_to_read = ( lines.size - start_line + 1 ) < 3 ? ( lines.size - start_line + 1 ) : lines_to_read
|
|
177
|
+
|
|
161
178
|
# the array is zero based, first line is at position 0
|
|
162
|
-
lines_to_read.times do |index|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
ret_str << lines[start_line + index - 1]
|
|
179
|
+
lines_to_read.times do | index |
|
|
180
|
+
|
|
181
|
+
# add "=>" to line which failed
|
|
182
|
+
result << ( ( line_number == ( start_line + index ) ) ? "=> " : " " ) + lines[ start_line + index - 1 ]
|
|
183
|
+
|
|
169
184
|
end
|
|
170
185
|
|
|
171
186
|
}
|
|
172
187
|
|
|
173
188
|
rescue Exception => e
|
|
174
189
|
|
|
175
|
-
|
|
176
|
-
ret_str << "Unable to load source lines.\n" << e.inspect
|
|
190
|
+
result << "Unable to load source lines.\n#{ e.inspect }"
|
|
177
191
|
|
|
178
192
|
end
|
|
179
193
|
|
|
180
|
-
return
|
|
194
|
+
# return result string
|
|
195
|
+
result
|
|
181
196
|
|
|
182
197
|
end
|
|
183
198
|
|