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.
Files changed (108) hide show
  1. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +1 -1
  2. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +11 -7
  3. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +8 -0
  4. data/lib/tdriver/base/behaviour/factory.rb +229 -209
  5. data/lib/tdriver/base/errors.rb +3 -0
  6. data/lib/tdriver/base/state_object.rb +11 -20
  7. data/lib/tdriver/base/sut/controller.rb +4 -4
  8. data/lib/tdriver/base/sut/factory.rb +205 -170
  9. data/lib/tdriver/base/sut/generic/behaviours/application.rb +256 -174
  10. data/lib/tdriver/base/sut/generic/behaviours/find.rb +17 -11
  11. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +57 -66
  12. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +578 -497
  13. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +41 -15
  14. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +48 -19
  15. data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
  16. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +25 -13
  17. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +16 -10
  18. data/lib/tdriver/base/sut/generic/plugin.rb +9 -3
  19. data/lib/tdriver/base/sut/sut.rb +41 -33
  20. data/lib/tdriver/base/test_object/abstract.rb +26 -3
  21. data/lib/tdriver/base/test_object/adapter.rb +399 -0
  22. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +56 -14
  23. data/lib/tdriver/base/test_object/behaviours/test_object.rb +663 -197
  24. data/lib/tdriver/base/test_object/cache.rb +132 -0
  25. data/lib/tdriver/base/test_object/factory.rb +677 -426
  26. data/lib/tdriver/base/test_object/factory_new.rb +202 -0
  27. data/lib/tdriver/base/test_object/identificator.rb +24 -17
  28. data/lib/tdriver/base/test_object/loader.rb +9 -3
  29. data/lib/tdriver/base/test_object/verification.rb +181 -0
  30. data/lib/tdriver/loader.rb +1 -1
  31. data/lib/tdriver/report/report.rb +2 -0
  32. data/lib/tdriver/report/report_api.rb +4 -4
  33. data/lib/tdriver/report/report_creator.rb +29 -3
  34. data/lib/tdriver/report/report_data_presentation.rb +7 -3
  35. data/lib/tdriver/report/report_execution_statistics.rb +80 -21
  36. data/lib/tdriver/report/report_javascript.rb +192 -0
  37. data/lib/tdriver/report/report_test_case_run.rb +22 -0
  38. data/lib/tdriver/report/report_test_run.rb +62 -55
  39. data/lib/tdriver/report/report_writer.rb +57 -56
  40. data/lib/tdriver/tdriver.rb +14 -41
  41. data/lib/tdriver/util/common/error.rb +1 -0
  42. data/lib/tdriver/util/common/exceptions.rb +12 -0
  43. data/lib/tdriver/util/common/file.rb +12 -6
  44. data/lib/tdriver/util/common/gem.rb +2 -1
  45. data/lib/tdriver/util/common/hash.rb +152 -0
  46. data/lib/tdriver/util/common/kernel.rb +49 -34
  47. data/lib/tdriver/util/common/loader.rb +21 -17
  48. data/lib/tdriver/util/common/numeric.rb +39 -0
  49. data/lib/tdriver/util/common/object.rb +115 -0
  50. data/lib/tdriver/util/common/string.rb +55 -2
  51. data/lib/tdriver/util/dbaccess/dbaccess.rb +194 -161
  52. data/lib/tdriver/util/dynamic_attribute_filter.rb +6 -0
  53. data/lib/tdriver/util/hooking.rb +2 -2
  54. data/lib/tdriver/util/loader.rb +2 -2
  55. data/lib/tdriver/util/localisation/localisation.rb +277 -18
  56. data/lib/tdriver/util/logger.rb +142 -13
  57. data/lib/tdriver/util/parameter/parameter_hash.rb +8 -5
  58. data/lib/tdriver/util/parameter/parameter_xml.rb +18 -2
  59. data/lib/tdriver/util/recorder.rb +17 -12
  60. data/lib/tdriver/util/user_data/user_data.rb +3 -2
  61. data/lib/tdriver/util/{video_rec.rb → video_utils.rb} +136 -16
  62. data/lib/tdriver/util/xml/abstraction.rb +7 -0
  63. data/lib/tdriver/util/xml/attribute.rb +32 -0
  64. data/lib/tdriver/util/xml/loader.rb +8 -2
  65. data/lib/tdriver/util/xml/nil_node.rb +95 -0
  66. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +46 -7
  67. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +19 -9
  68. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +1 -1
  69. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +13 -1
  70. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +6 -0
  71. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +27 -15
  72. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +57 -0
  73. data/lib/tdriver/util/xml/text.rb +32 -0
  74. data/lib/tdriver/util/xml/xml.rb +35 -22
  75. data/lib/tdriver/version.rb +1 -1
  76. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +41 -34
  77. data/lib/tdriver-devtools/doc/generate.rb +31 -6
  78. data/lib/tdriver-devtools/doc/xslt/template.xsl +46 -25
  79. data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
  80. data/lib/tdriver-devtools/tests/feature_tests/update +1 -1
  81. data/lib/tdriver.rb +0 -3
  82. data/xml/behaviours/generic.xml +1 -1
  83. data/xml/defaults/generic.xml +4 -90
  84. data/xml/templates/generic.xml +33 -25
  85. metadata +21 -29
  86. data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +0 -245
  87. data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +0 -964
  88. data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +0 -68
  89. data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +0 -1865
  90. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +0 -1
  91. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +0 -3
  92. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +0 -4
  93. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +0 -4
  94. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +0 -4
  95. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +0 -3
  96. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +0 -3
  97. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +0 -1
  98. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +0 -3
  99. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +0 -3
  100. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +0 -12
  101. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +0 -5
  102. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +0 -1
  103. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +0 -2
  104. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +0 -7
  105. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +0 -14
  106. data/lib/tdriver-devtools/behaviour/xml_generator/update +0 -3
  107. data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +0 -233
  108. data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +0 -194
@@ -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
- # Following line to prevent Object#id Warnings
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
- Kernel::raise ArgumentError.new( "Wrong argument type '%s' (Expected Hash)" % sut_attributes.class ) unless sut_attributes.kind_of?( Hash )
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
- # if given arguments is type of Symbol expect is as SUT id
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
- # if given arguments is type of Symbol expect is as SUT id
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
- if ARGV.include?( '--debug_exceptions' ) || TDriver.parameter[ :debug_exceptions, 'false' ].to_s.downcase == 'true'
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
@@ -17,6 +17,7 @@
17
17
  ##
18
18
  ############################################################################
19
19
 
20
+ # TODO: move custom errors to exceptions.rb
20
21
  module MobyUtil
21
22
 
22
23
  # template for custom error classes
@@ -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 ArgumentError.new( "File not found %s" % [ path ] ) if !File.directory?( path ) && !File.file?( path ) && require_files.empty?
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
- Kernel::raise ArgumentError.new("Given path is empty") if path.empty?
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
- Kernel::raise ArgumentError.new( "Source and destination argument must be type of String" ) unless source.kind_of?( String ) && destination.kind_of?( String )
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( "Source file does not exist (#{ source })" ) unless File.exist?( source )
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 required as first argument" ) unless parameters.count > 0
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
- ret_str = "\n"
120
+ result = "\n"
121
121
 
122
122
  begin
123
123
 
124
+ # split with colon
124
125
  call_stack = backtrace.to_s.split(':')
125
- #puts "call_stack:" << backtrace.to_s
126
-
127
- line_number = 0
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
- if (call_stack.size() == 2)
138
- file_path = call_stack[0]
131
+
132
+ # TODO: document me
133
+ if ( call_stack.size == 2 )
134
+
135
+ file_path = call_stack[ 0 ]
136
+
139
137
  else
140
- (call_stack.size()-2).times do |index|
141
- file_path << call_stack[index].to_s << ":"
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
- file_path.slice!(file_path.size()-1) # remove the trailing colon
145
+
146
+ # remove the trailing colon
147
+ file_path.slice!(-1)
148
+
144
149
  end
145
- #puts "file path: " << file_path.to_s
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
- File.open(File.expand_path(file_path.to_s), "r") { |source|
159
+ # expand file path and name
160
+ filename = File.expand_path( file_path.to_s )
154
161
 
155
- lines = source.readlines
156
- #puts "lines.size:" << lines.size
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
- if (line_number == (start_line + index))
164
- ret_str << "=> "
165
- else
166
- ret_str << " "
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
- #puts "exception:" << e.inspect
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 ret_str
194
+ # return result string
195
+ result
181
196
 
182
197
  end
183
198