testability-driver 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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