testability-driver 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. data/README +1 -0
  2. data/bin/start_app_perf +199 -0
  3. data/bin/tdriver-devtools +3 -0
  4. data/config/sut_parameters.rb +39 -0
  5. data/ext/extconf.rb +67 -0
  6. data/ext/native_extensions.c +70 -0
  7. data/lib/matti.rb +30 -0
  8. data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +223 -0
  9. data/lib/tdriver-devtools/behaviour/old/xml/example/impl.rb_invalid +194 -0
  10. data/lib/tdriver-devtools/behaviour/old/xml/generate_behaviour_xml.rb +95 -0
  11. data/lib/tdriver-devtools/behaviour/old/xml/lib/tdriver_generator.rb +722 -0
  12. data/lib/tdriver-devtools/behaviour/old/xml/qdoc_generator.rb +321 -0
  13. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.method.template +43 -0
  14. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.module.template +54 -0
  15. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument.template +7 -0
  16. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument_type.template +7 -0
  17. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.exception.template +5 -0
  18. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.line.template +2 -0
  19. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.template +5 -0
  20. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.method.template +23 -0
  21. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.template +14 -0
  22. data/lib/tdriver-devtools/behaviour/old/xml/update +3 -0
  23. data/lib/tdriver-devtools/behaviour/xml/generate.rb +88 -0
  24. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +1924 -0
  25. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.default.template +1 -0
  26. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.template +3 -0
  27. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument_type.template +4 -0
  28. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.exception.template +4 -0
  29. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.arguments.template +4 -0
  30. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.deprecated.template +3 -0
  31. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.exceptions.template +3 -0
  32. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.info.template +1 -0
  33. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.returns.template +3 -0
  34. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.tables.template +3 -0
  35. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.template +12 -0
  36. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.returns.template +5 -0
  37. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.item.template +1 -0
  38. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.row.template +2 -0
  39. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.template +8 -0
  40. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.template +14 -0
  41. data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +245 -0
  42. data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +964 -0
  43. data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +68 -0
  44. data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +1865 -0
  45. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +1 -0
  46. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +3 -0
  47. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +4 -0
  48. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +4 -0
  49. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +4 -0
  50. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +3 -0
  51. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +3 -0
  52. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +1 -0
  53. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +3 -0
  54. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +3 -0
  55. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +12 -0
  56. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +5 -0
  57. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +1 -0
  58. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +2 -0
  59. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +7 -0
  60. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +14 -0
  61. data/lib/tdriver-devtools/behaviour/xml_generator/update +3 -0
  62. data/lib/tdriver-devtools/doc/behaviour_xml/QtExampleGestureBehaviour.xml +138 -0
  63. data/lib/tdriver-devtools/doc/behaviour_xml/created.rid +1 -0
  64. data/lib/tdriver-devtools/doc/behaviour_xml/tdriver.hash +1 -0
  65. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_hold.feature.xml +9 -0
  66. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_tap.feature.xml +9 -0
  67. data/lib/tdriver-devtools/doc/generate.rb +892 -0
  68. data/lib/tdriver-devtools/doc/update +1 -0
  69. data/lib/tdriver-devtools/doc/xslt/html.rb +7 -0
  70. data/lib/tdriver-devtools/doc/xslt/template.xsl +1861 -0
  71. data/lib/tdriver-devtools/doc/xslt/update +3 -0
  72. data/lib/tdriver-devtools/plugin/placeholder.txt +1 -0
  73. data/lib/tdriver-devtools/tdriver-devtools.rb +404 -0
  74. data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +233 -0
  75. data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +194 -0
  76. data/lib/tdriver-devtools/tests/feature_tests/generate.rb +82 -0
  77. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +468 -0
  78. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_attribute.template +5 -0
  79. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_method.template +5 -0
  80. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_attribute.template +5 -0
  81. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_method.template +5 -0
  82. data/lib/tdriver-devtools/tests/feature_tests/update +3 -0
  83. data/lib/tdriver.rb +26 -0
  84. data/lib/tdriver/base/behaviour/behaviour.rb +32 -0
  85. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +94 -0
  86. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +262 -0
  87. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +111 -0
  88. data/lib/tdriver/base/behaviour/factory.rb +380 -0
  89. data/lib/tdriver/base/behaviour/loader.rb +28 -0
  90. data/lib/tdriver/base/command_data/command_data.rb +51 -0
  91. data/lib/tdriver/base/command_data/loader.rb +25 -0
  92. data/lib/tdriver/base/errors.rb +131 -0
  93. data/lib/tdriver/base/loader.rb +38 -0
  94. data/lib/tdriver/base/state_object.rb +270 -0
  95. data/lib/tdriver/base/sut/adapter.rb +28 -0
  96. data/lib/tdriver/base/sut/controller.rb +119 -0
  97. data/lib/tdriver/base/sut/factory.rb +287 -0
  98. data/lib/tdriver/base/sut/generic/behaviours/application.rb +243 -0
  99. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +67 -0
  100. data/lib/tdriver/base/sut/generic/behaviours/find.rb +96 -0
  101. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +346 -0
  102. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +1268 -0
  103. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +182 -0
  104. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +119 -0
  105. data/lib/tdriver/base/sut/generic/commands/application.rb +219 -0
  106. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +82 -0
  107. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +58 -0
  108. data/lib/tdriver/base/sut/generic/plugin.rb +96 -0
  109. data/lib/tdriver/base/sut/loader.rb +35 -0
  110. data/lib/tdriver/base/sut/sut.rb +67 -0
  111. data/lib/tdriver/base/test_object/abstract.rb +179 -0
  112. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +94 -0
  113. data/lib/tdriver/base/test_object/behaviours/test_object.rb +787 -0
  114. data/lib/tdriver/base/test_object/factory.rb +618 -0
  115. data/lib/tdriver/base/test_object/identificator.rb +511 -0
  116. data/lib/tdriver/base/test_object/loader.rb +37 -0
  117. data/lib/tdriver/env.rb +21 -0
  118. data/lib/tdriver/loader.rb +36 -0
  119. data/lib/tdriver/matti.rb +35 -0
  120. data/lib/tdriver/report/error_recovery/tdriver_custom_error_recovery.rb +83 -0
  121. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +158 -0
  122. data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +98 -0
  123. data/lib/tdriver/report/report.rb +47 -0
  124. data/lib/tdriver/report/report_api.rb +207 -0
  125. data/lib/tdriver/report/report_combine.rb +86 -0
  126. data/lib/tdriver/report/report_crash_file_capture.rb +167 -0
  127. data/lib/tdriver/report/report_creator.rb +571 -0
  128. data/lib/tdriver/report/report_cucumber.rb +158 -0
  129. data/lib/tdriver/report/report_cucumber_listener.rb +337 -0
  130. data/lib/tdriver/report/report_cucumber_reporter.rb +335 -0
  131. data/lib/tdriver/report/report_data_presentation.rb +152 -0
  132. data/lib/tdriver/report/report_data_table.rb +64 -0
  133. data/lib/tdriver/report/report_execution_statistics.rb +284 -0
  134. data/lib/tdriver/report/report_file_capture.rb +159 -0
  135. data/lib/tdriver/report/report_grouping.rb +539 -0
  136. data/lib/tdriver/report/report_junit_xml.rb +147 -0
  137. data/lib/tdriver/report/report_rspec.rb +108 -0
  138. data/lib/tdriver/report/report_test_case_run.rb +621 -0
  139. data/lib/tdriver/report/report_test_run.rb +1286 -0
  140. data/lib/tdriver/report/report_test_unit.rb +175 -0
  141. data/lib/tdriver/report/report_writer.rb +1405 -0
  142. data/lib/tdriver/tdriver.rb +158 -0
  143. data/lib/tdriver/util/common.rb +24 -0
  144. data/lib/tdriver/util/common/array.rb +39 -0
  145. data/lib/tdriver/util/common/crc16.rb +100 -0
  146. data/lib/tdriver/util/common/environment.rb +153 -0
  147. data/lib/tdriver/util/common/error.rb +39 -0
  148. data/lib/tdriver/util/common/file.rb +315 -0
  149. data/lib/tdriver/util/common/gem.rb +108 -0
  150. data/lib/tdriver/util/common/kernel.rb +189 -0
  151. data/lib/tdriver/util/common/loader.rb +39 -0
  152. data/lib/tdriver/util/common/retryable.rb +98 -0
  153. data/lib/tdriver/util/common/string.rb +77 -0
  154. data/lib/tdriver/util/dbaccess/dbaccess.rb +188 -0
  155. data/lib/tdriver/util/dbaccess/dbconnection.rb +41 -0
  156. data/lib/tdriver/util/dbaccess/error.rb +35 -0
  157. data/lib/tdriver/util/dbaccess/loader.rb +29 -0
  158. data/lib/tdriver/util/dynamic_attribute_filter.rb +182 -0
  159. data/lib/tdriver/util/hooking.rb +434 -0
  160. data/lib/tdriver/util/loader.rb +65 -0
  161. data/lib/tdriver/util/localisation.rb +24 -0
  162. data/lib/tdriver/util/localisation/error.rb +32 -0
  163. data/lib/tdriver/util/localisation/loader.rb +28 -0
  164. data/lib/tdriver/util/localisation/localisation.rb +479 -0
  165. data/lib/tdriver/util/logger.rb +377 -0
  166. data/lib/tdriver/util/operator_data/error.rb +29 -0
  167. data/lib/tdriver/util/operator_data/loader.rb +26 -0
  168. data/lib/tdriver/util/operator_data/operator_data.rb +93 -0
  169. data/lib/tdriver/util/other/config.rb +221 -0
  170. data/lib/tdriver/util/parameter.rb +24 -0
  171. data/lib/tdriver/util/parameter/error.rb +45 -0
  172. data/lib/tdriver/util/parameter/loader.rb +37 -0
  173. data/lib/tdriver/util/parameter/parameter.rb +285 -0
  174. data/lib/tdriver/util/parameter/parameter_hash.rb +101 -0
  175. data/lib/tdriver/util/parameter/parameter_template.rb +120 -0
  176. data/lib/tdriver/util/parameter/parameter_user_api.rb +84 -0
  177. data/lib/tdriver/util/parameter/parameter_xml.rb +247 -0
  178. data/lib/tdriver/util/plugin/abstract.rb +60 -0
  179. data/lib/tdriver/util/plugin/error.rb +25 -0
  180. data/lib/tdriver/util/plugin/loader.rb +28 -0
  181. data/lib/tdriver/util/plugin/service.rb +200 -0
  182. data/lib/tdriver/util/recorder.rb +292 -0
  183. data/lib/tdriver/util/stats.rb +90 -0
  184. data/lib/tdriver/util/user_data/error.rb +29 -0
  185. data/lib/tdriver/util/user_data/loader.rb +26 -0
  186. data/lib/tdriver/util/user_data/user_data.rb +103 -0
  187. data/lib/tdriver/util/video_rec.rb +264 -0
  188. data/lib/tdriver/util/xml/abstraction.rb +47 -0
  189. data/lib/tdriver/util/xml/builder.rb +54 -0
  190. data/lib/tdriver/util/xml/document.rb +32 -0
  191. data/lib/tdriver/util/xml/element.rb +32 -0
  192. data/lib/tdriver/util/xml/error.rb +46 -0
  193. data/lib/tdriver/util/xml/loader.rb +46 -0
  194. data/lib/tdriver/util/xml/nil_element.rb +89 -0
  195. data/lib/tdriver/util/xml/nodeset.rb +32 -0
  196. data/lib/tdriver/util/xml/parsers/libxml/libxml.rb +140 -0
  197. data/lib/tdriver/util/xml/parsers/loader.rb +22 -0
  198. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +111 -0
  199. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +54 -0
  200. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +58 -0
  201. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +58 -0
  202. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +147 -0
  203. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +42 -0
  204. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +187 -0
  205. data/lib/tdriver/util/xml/xml.rb +170 -0
  206. data/lib/tdriver/verify/verify.rb +687 -0
  207. data/lib/tdriver/verify/verify.rb_org +630 -0
  208. data/lib/tdriver/version.rb +21 -0
  209. data/xml/behaviours/generic.xml +495 -0
  210. data/xml/defaults/generic.xml +97 -0
  211. data/xml/defaults/sut_generic.xml +36 -0
  212. data/xml/parameters/tdriver_parameters.xml +23 -0
  213. data/xml/templates/generic.xml +227 -0
  214. metadata +327 -0
@@ -0,0 +1,5 @@
1
+
2
+ <howto description="$HOWTO_DESCRIPTION">
3
+ $HOWTO_CODE
4
+ </howto>
5
+
@@ -0,0 +1,23 @@
1
+
2
+ <method name="$METHOD_NAME">
3
+
4
+ <description>$METHOD_DESCRIPTION</description>
5
+ <example>$METHOD_EXAMPLE</example>
6
+
7
+ <arguments>
8
+ $METHOD_ARGUMENTS
9
+ </arguments>
10
+
11
+ <exceptions>
12
+ $METHOD_EXCEPTIONS
13
+ </exceptions>
14
+
15
+ <howtos>
16
+ $METHOD_HOWTOS
17
+ </howtos>
18
+
19
+ <info>
20
+ $METHOD_INFO
21
+ </info>
22
+
23
+ </method>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <behaviours plugin="$REQUIRED_PLUGIN">
3
+
4
+ <behaviour name="$BEHAVIOUR_NAME" object_type="$OBJECT_TYPE" sut_type="$SUT_TYPE" input_type="$INPUT_TYPE" version="$VERSION">
5
+
6
+ <module name="$MODULE_NAME" />
7
+
8
+ <methods>
9
+ $BEHAVIOUR_METHODS
10
+ </methods>
11
+
12
+ </behaviour>
13
+
14
+ </behaviours>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env sh
2
+ rm -rf doc
3
+ ruby generate_behaviour_xml.rb example/
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ ############################################################################
3
+ ##
4
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5
+ ## All rights reserved.
6
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
7
+ ##
8
+ ## This file is part of Testability Driver.
9
+ ##
10
+ ## If you have questions regarding the use of this file, please contact
11
+ ## Nokia at testabilitydriver@nokia.com .
12
+ ##
13
+ ## This library is free software; you can redistribute it and/or
14
+ ## modify it under the terms of the GNU Lesser General Public
15
+ ## License version 2.1 as published by the Free Software Foundation
16
+ ## and appearing in the file LICENSE.LGPL included in the packaging
17
+ ## of this file.
18
+ ##
19
+ ############################################################################
20
+ require 'rdoc/rdoc'
21
+
22
+ module RDoc
23
+
24
+ class RDoc
25
+
26
+ # install custom generator to RDoc
27
+ def install_generator( name, module_name, filename )
28
+
29
+ GENERATORS[ name.to_s.downcase ] = Generator.new( filename, module_name.intern , name.to_s.downcase )
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ if $source.nil? and ARGV.count < 1
38
+
39
+ abort "Usage: #{ $0 } SOURCE_FILES [DESTINATION_FOLDER]"
40
+
41
+ else
42
+
43
+ $source = File.expand_path( $source || ARGV[ 0 ] )
44
+
45
+ $destination = File.expand_path( $destination || ARGV[ 1 ] || 'behaviour_xml' )
46
+
47
+ abort("File or folder %s not found" % $source ) unless File.exist?( $source )
48
+
49
+ end
50
+
51
+ begin
52
+
53
+ RDoc::RDoc.new.tap{ | rdoc |
54
+
55
+ rdoc.install_generator(
56
+ 'tdriver_behaviour_xml',
57
+ 'TDriverBehaviourGenerator',
58
+ File.expand_path( File.join( File.dirname( __FILE__ ), 'rdoc_behaviour_xml_generator.rb' ) )
59
+ )
60
+
61
+
62
+ current_dir = Dir.pwd
63
+
64
+ Dir.chdir( File.expand_path( $destination ) )
65
+
66
+ rdoc.document(
67
+ [
68
+ '--inline-source',
69
+ '--op', $destination,
70
+ '--fmt', 'tdriver_behaviour_xml',
71
+ '--force-update',
72
+ '--one-file',
73
+ ] << $source
74
+ )
75
+
76
+ # delete creater.rid timestamp file
77
+ File.delete('created.rid')
78
+
79
+ Dir.chdir( current_dir )
80
+
81
+ }
82
+
83
+ rescue RDoc::RDocError => exception
84
+
85
+ abort exception.message
86
+
87
+ end
88
+
@@ -0,0 +1,1924 @@
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
+ module Generators
21
+
22
+ abort("RDoc not available/loaded") unless defined?( RDoc )
23
+
24
+ class TDriverBehaviourGenerator
25
+
26
+ def initialize( options )
27
+
28
+ @templates = {}
29
+
30
+ @found_modules_and_methods = {}
31
+
32
+ @created_files = {}
33
+
34
+ load_templates
35
+
36
+ @options = options
37
+
38
+ @already_processed_files = []
39
+
40
+ @current_module_tests = []
41
+
42
+ @current_module = nil
43
+
44
+ @output = { :files => [], :classes => [], :modules => [], :attributes => [], :methods => [], :aliases => [], :constants => [], :requires => [], :includes => []}
45
+
46
+ @errors = []
47
+
48
+ end
49
+
50
+ def help( topic )
51
+
52
+ case topic
53
+
54
+ when 'description'
55
+ <<-EXAMPLE
56
+ # == description
57
+ # This method returns "String" as return value
58
+ def my_method( arguments )
59
+ return "string"
60
+ end
61
+ EXAMPLE
62
+
63
+ when 'returns'
64
+ <<-EXAMPLE
65
+ # == returns
66
+ # String
67
+ # description: example description
68
+ # example: "string"
69
+ #
70
+ def my_method( arguments )
71
+ return "string"
72
+ end
73
+ EXAMPLE
74
+
75
+ when 'arguments'
76
+ <<-EXAMPLE
77
+ # == arguments
78
+ # arg1
79
+ # Integer
80
+ # description: first argument can integer
81
+ # example: 10
82
+ # String
83
+ # description: ... or string
84
+ # example: "Hello"
85
+ #
86
+ # arg2
87
+ # Array
88
+ # description: MyArray
89
+ # example: [1,2,3]
90
+ # default: []
91
+ #
92
+ # *arg3
93
+ # Array
94
+ # description: MyMultipleArray
95
+ # example: ['a','b','c']
96
+ # default: []
97
+ #
98
+ # &block
99
+ # Proc
100
+ # description: MyMultipleArray
101
+ # example: ['a','b','c']
102
+ # default: []
103
+ def my_method( arg1, arg2, *arg3, &block )
104
+ # ...
105
+ end
106
+ EXAMPLE
107
+
108
+ when 'attr_argument'
109
+ <<-EXAMPLE
110
+ # == arguments
111
+ # value
112
+ # Integer
113
+ # description: first argument can integer
114
+ # example: 10
115
+ attr_writer :my_attribute
116
+
117
+ or
118
+
119
+ # == arguments
120
+ # value
121
+ # Integer
122
+ # description: first argument can integer
123
+ # example: 10
124
+ # String
125
+ # description: ... or string
126
+ # example: "Hello"
127
+ attr_writer :my_attribute # ... when input value can be either Integer or String
128
+ EXAMPLE
129
+
130
+
131
+ when 'exceptions'
132
+ <<-EXAMPLE
133
+ # == exceptions
134
+ # RuntimeError
135
+ # description: example exception #1
136
+ #
137
+ # ArgumentError
138
+ # description: example exception #2
139
+ def my_method
140
+
141
+ # ...
142
+
143
+ end
144
+ EXAMPLE
145
+
146
+ when 'behaviour_description'
147
+ <<-EXAMPLE
148
+ # == description
149
+ # This module contains demonstration implementation containing tags for documentation generation using gesture as an example
150
+ module MyBehaviour
151
+
152
+ # ...
153
+
154
+ end
155
+ EXAMPLE
156
+
157
+ when 'behaviour_name'
158
+ <<-EXAMPLE
159
+ # == behaviour
160
+ # MyPlatformSpecificBehaviour
161
+ module MyBehaviour
162
+
163
+ # ...
164
+
165
+ end
166
+ EXAMPLE
167
+
168
+ when 'behaviour_object_types'
169
+ <<-EXAMPLE
170
+ # == objects
171
+ # *
172
+ module MyBehaviour
173
+
174
+ # apply behaviour to any test object, except SUT
175
+
176
+ end
177
+
178
+ or
179
+
180
+ # == objects
181
+ # sut
182
+ module MyBehaviour
183
+
184
+ # apply behaviour only to SUT object
185
+
186
+ end
187
+
188
+ # == objects
189
+ # *;sut
190
+ module MyBehaviour
191
+
192
+ # apply behaviour to any test object, including SUT
193
+
194
+ end
195
+
196
+ or
197
+
198
+ # == objects
199
+ # MyObject
200
+ module MyBehaviour
201
+
202
+ # apply behaviour only to objects which type is 'MyObject'
203
+
204
+ end
205
+
206
+ or
207
+
208
+ # == objects
209
+ # MyObject;OtherObject
210
+ module MyBehaviour
211
+
212
+ # apply behaviour only to objects which type is 'MyObject' or 'OtherObject'
213
+ # if more object types needed use ';' as separator.
214
+
215
+ end
216
+
217
+
218
+ EXAMPLE
219
+
220
+ when 'behaviour_version'
221
+ <<-EXAMPLE
222
+ # == sut_version
223
+ # *
224
+ module MyBehaviour
225
+
226
+ # any sut version
227
+
228
+ end
229
+
230
+ or
231
+
232
+ # == sut_version
233
+ # 1.0
234
+ module MyBehaviour
235
+
236
+ # apply behaviour only to sut with version 1.0
237
+
238
+ end
239
+ EXAMPLE
240
+
241
+ when 'behaviour_input_type'
242
+ <<-EXAMPLE
243
+ # == input_type
244
+ # *
245
+ module MyBehaviour
246
+
247
+ # any input type
248
+
249
+ end
250
+
251
+ or
252
+
253
+ # == input_type
254
+ # touch
255
+ module MyBehaviour
256
+
257
+ # apply behaviour only to sut which input type is 'touch'
258
+
259
+ end
260
+
261
+ or
262
+
263
+ # == input_type
264
+ # touch;key
265
+ module MyBehaviour
266
+
267
+ # apply behaviour only to sut which input type is 'touch' or 'key'
268
+ # if more types needed use ';' as separator.
269
+
270
+ end
271
+
272
+ EXAMPLE
273
+
274
+ when 'behaviour_sut_type'
275
+ <<-EXAMPLE
276
+ # == sut_type
277
+ # *
278
+ module MyBehaviour
279
+
280
+ # any input type
281
+
282
+ end
283
+
284
+ or
285
+
286
+ # == sut_type
287
+ # XX
288
+ module MyBehaviour
289
+
290
+ # apply behaviour only to sut which sut type is 'XX'
291
+
292
+ end
293
+
294
+ or
295
+
296
+ # == sut_type
297
+ # XX;YY
298
+ module MyBehaviour
299
+
300
+ # apply behaviour only to sut which sut type is 'XX' or 'YY'
301
+ # if more types needed use ';' as separator.
302
+
303
+ end
304
+ EXAMPLE
305
+
306
+ when 'behaviour_requires'
307
+ <<-EXAMPLE
308
+ # == requires
309
+ # *
310
+ module MyBehaviour
311
+
312
+ # when no plugins required (TDriver internal/generic SUT behaviour)
313
+
314
+ end
315
+
316
+ or
317
+
318
+ # == requires
319
+ # testability-driver-my-plugin
320
+ module MyBehaviour
321
+
322
+ # when plugin 'testability-driver-my-plugin' is required
323
+
324
+ end
325
+ EXAMPLE
326
+
327
+ when 'table_format'
328
+
329
+ <<-EXAMPLE
330
+ # == tables
331
+ # table_name
332
+ # title: My table 1
333
+ # |header1|header2|header3|
334
+ # |1.1|1.2|1.3|
335
+ # |2.1|2.2|2.3|
336
+ # |3.1|3.2|3.3|
337
+ #
338
+ # another_table_name
339
+ # title: My table 2
340
+ # |id|value|
341
+ # |0|true|
342
+ # |1|false|
343
+ def my_method
344
+
345
+ # ...
346
+
347
+ end
348
+ EXAMPLE
349
+
350
+ when 'default_argument_value_already_given'
351
+ <<-EXAMPLE
352
+ # == arguments
353
+ # value
354
+ # Integer
355
+ # description: first argument can integer
356
+ # example: 10
357
+ # default: 1
358
+ # String
359
+ # description: ... or string
360
+ # example: "Hello"
361
+ # default: "a"
362
+ def my_method( value = 1 )
363
+
364
+ # ...
365
+
366
+ end
367
+ EXAMPLE
368
+
369
+ when 'default_value_mandatory_argument'
370
+
371
+ <<-EXAMPLE
372
+ # == arguments
373
+ # value
374
+ # Integer
375
+ # description: first argument can integer
376
+ # example: 10
377
+ # default: 1
378
+ def my_method( value )
379
+
380
+ # ...
381
+
382
+ end
383
+ EXAMPLE
384
+
385
+
386
+ else
387
+
388
+ 'Unknown help topic "%s"' % topic
389
+
390
+ end
391
+
392
+ end
393
+
394
+ def self.for( options )
395
+
396
+ new( options )
397
+
398
+ end
399
+
400
+ def load_templates
401
+
402
+ Dir.glob( File.join( File.dirname( File.expand_path( __FILE__ ) ), 'templates', '*.template' ) ).each{ | file |
403
+
404
+ name = File.basename( file ).gsub( '.template', '' )
405
+
406
+ @templates[ name ] = open( file, 'r' ).read
407
+
408
+ }
409
+
410
+ end
411
+
412
+ def generate( files )
413
+
414
+ # process files
415
+ files.each{ | file |
416
+
417
+ process_file( file ) unless @already_processed_files.include?( file.file_absolute_name )
418
+
419
+
420
+ }
421
+
422
+ # TODO: some other format for writing the hash to file...
423
+ #open("#{ $output_results_name }.hash", "w" ){ | file | file << @found_modules_and_methods.inspect }
424
+
425
+ end
426
+
427
+ def process_file( file )
428
+
429
+ @module_path = []
430
+
431
+ @current_file = file
432
+
433
+ process_modules( file.modules )
434
+
435
+ end
436
+
437
+ def process_modules( modules )
438
+
439
+ modules.each{ | _module |
440
+
441
+ unless @already_processed_files.include?( _module.full_name )
442
+
443
+ @module_path.push( _module.name )
444
+
445
+ process_module( _module )
446
+
447
+ @module_path.pop
448
+
449
+ end
450
+
451
+ }
452
+
453
+ end
454
+
455
+ def process_methods( methods )
456
+
457
+ @processing = "method"
458
+
459
+ results = []
460
+
461
+ methods.each{ | method |
462
+
463
+ results << process_method( method )
464
+
465
+ }
466
+
467
+ Hash[ results ]
468
+
469
+ end
470
+
471
+ def process_method_arguments_section( source, params_array )
472
+
473
+ result = []
474
+
475
+ current_argument = nil
476
+
477
+ current_argument_type = nil
478
+
479
+ current_section = nil
480
+
481
+ argument_index = -1
482
+
483
+ arguments_found = 0
484
+
485
+ source.lines.to_a.each_with_index{ | line, index |
486
+
487
+ # remove cr/lf
488
+ line.chomp!
489
+
490
+ # remove trailing whitespaces
491
+ line.rstrip!
492
+
493
+ # count nesting depth
494
+ line.match( /^(\s*)/ )
495
+
496
+ nesting = $1.size
497
+
498
+ # remove leading whitespaces
499
+ line.lstrip!
500
+
501
+ if nesting == 0
502
+
503
+ line =~ /^([*|&]{0,1}\w+(\#\w+?)*)$/i
504
+
505
+ unless $1.nil?
506
+
507
+ # argument name
508
+ current_argument = $1
509
+
510
+ arguments_found += 1 unless line.include?( "#" )
511
+
512
+ current_section = nil
513
+
514
+ current_argument_type = nil
515
+
516
+ result << { current_argument => { :argument_type_order => [], :types => {} } }
517
+
518
+ argument_index += 1
519
+
520
+ end
521
+
522
+ else
523
+
524
+ # is line content class name? (argument variable type)
525
+ line =~ /^(.*)$/i
526
+
527
+ if !$1.nil? && ( 65..90 ).include?( $1[0] ) && nesting == 1 # "Array", "String", "Integer"
528
+
529
+ #Kernel.const_get( $1 ) rescue abort( "Line %s: \"%s\" is not valid argument variable type. (e.g. OK: \"String\", \"Array\", \"Fixnum\" etc) " % [ index +1, $1 ] )
530
+
531
+ current_argument_type = $1
532
+
533
+ result[ argument_index ][ current_argument ][ :argument_type_order ] << $1
534
+
535
+ result[ argument_index ][ current_argument ][ :types ][ current_argument_type ] = {}
536
+
537
+ #result[ argument_index ][ current_argument ][ current_argument_type ] = {}
538
+
539
+ current_section = nil
540
+
541
+ else
542
+
543
+ raise_error("Unable add argument details (line %s: \"%s\") for \"%s\" due to argument variable type must be defined first.\nPlease note that argument type must start with capital letter (e.g. OK: \"String\" NOK: \"string\")" % [ index + 1, line, current_argument ] ) if current_argument_type.nil?
544
+
545
+ line =~ /^(.*?)\:{1}($|[\r\n\t\s]{1})(.*)$/i
546
+
547
+ if $1.nil?
548
+
549
+ raise_error("Unable add argument details (line %s: \"%s\") for \"%s\" due to section name not defined. Sections names are written in lowercase with trailing colon and whitespace (e.g. OK: \"example: 10\", NOK: \"example:10\")" % [ index +1, line, current_argument]) if $1.nil? && current_section.nil?
550
+
551
+ # remove leading & trailing whitespaces
552
+ section_content = line.strip
553
+
554
+ else
555
+
556
+ current_section = $1
557
+
558
+ if result[ argument_index ][ current_argument ][ :types ].has_key?( current_argument_type )
559
+
560
+ #unless result[ argument_index ][ current_argument ][ current_argument_type ].has_key?( current_section )
561
+ unless result[ argument_index ][ current_argument ][ :types ][ current_argument_type ].has_key?( current_section )
562
+
563
+ #result[ argument_index ][ current_argument ][ current_argument_type ][ current_section ] = ""
564
+ result[ argument_index ][ current_argument ][ :types ][ current_argument_type ][ current_section ] = ""
565
+
566
+ end
567
+
568
+
569
+ end
570
+
571
+ section_content = $3.strip
572
+
573
+ end
574
+
575
+ raise_error("Unable add argument details due to argument not defined. Argument name must start from pos 1 of comment. (e.g. \"# my_variable\" NOK: \"# my_variable\", \"#myvariable\")") if current_argument.nil?
576
+
577
+ if result[ argument_index ][ current_argument ][ :types ].has_key?( current_argument_type )
578
+
579
+ if result[ argument_index ][ current_argument ][ :types ][ current_argument_type ].has_key?( current_section )
580
+
581
+
582
+ # add one leading whitespace if current_section value is not empty
583
+ #section_content = " " + section_content unless result[ argument_index ][ current_argument ][ current_argument_type ][ current_section ].empty?
584
+ section_content = " " + section_content unless result[ argument_index ][ current_argument ][ :types ][ current_argument_type ][ current_section ].empty?
585
+
586
+ # store section_content to current_section
587
+ #result[ argument_index ][ current_argument ][ current_argument_type ][ current_section ] << section_content
588
+ result[ argument_index ][ current_argument ][ :types ][ current_argument_type ][ current_section ] << section_content
589
+
590
+ end
591
+
592
+ end
593
+
594
+ end
595
+
596
+ end
597
+
598
+ }
599
+
600
+ order = []
601
+
602
+ params_array = params_array.collect{ | o | [ o.first, Hash[:default, o[1], :optional, o.last] ] }
603
+
604
+ params_hash = Hash[ params_array ]
605
+
606
+ default_value_already_set = []
607
+
608
+ params_array.each{ | param |
609
+
610
+ if ( item = result.select{ | arg | arg.keys.include?( param.first ) }).empty?
611
+
612
+ raise_error("Error: Argument '#{ param.first }' is implemented but not documented in '#{ @current_method.name }' ($MODULE).\nNote that documented argument and variable name must be identical.", [ 'writer', 'accessor' ].include?( @processing ) ? 'attr_argument' : 'arguments' ) unless param.first.to_s.include?("#")
613
+
614
+ order << { param.first => {} }
615
+
616
+ else
617
+
618
+ arg = item.first
619
+ arg_name = arg.keys.first
620
+
621
+ # apply overriding default argument value from documentation
622
+ arg[ arg_name ][ :argument_type_order ].each{ | type_name |
623
+
624
+ type_hash = arg[ arg_name ][ :types ][ type_name ]
625
+
626
+ unless type_hash["default"].nil?
627
+
628
+ if arg[ arg_name ][ :default ].nil?
629
+
630
+ if params_hash[ arg_name ][ :optional ] == false
631
+
632
+ raise_error("Error: Default value given for mandatory argument #{ arg_name } (type: #{ type_name }).", 'default_value_mandatory_argument' )
633
+
634
+ else
635
+
636
+ arg[ arg_name ][ :default ] = type_hash["default"]
637
+
638
+ end
639
+
640
+ else
641
+ raise_error("Error: Default value already given for #{ arg_name } (type: #{ type_name }).", 'default_argument_value_already_given' )
642
+ end
643
+
644
+ end
645
+ }
646
+
647
+ # if optional parameter and no overriding value defined, add one from implementation
648
+ if arg[ arg_name ][:default].nil?
649
+
650
+ arg[ arg_name ][ :default ] = params_hash[ arg_name ][ :default ] if params_hash[ arg_name ][ :optional ] == true
651
+
652
+ end
653
+
654
+ order << arg
655
+
656
+ end
657
+
658
+ }
659
+
660
+ # collect all argument names and add block arguments if any
661
+ found_keys = order.collect{ | pair | pair.keys }.flatten
662
+
663
+ # collect all documented argument names
664
+ documented_arguments = result.collect{ | arg | arg.keys }.flatten
665
+
666
+ unimplemented_arguments = ( documented_arguments - found_keys )
667
+
668
+ unless [ :attributes ].include?( @processing )
669
+
670
+ unless unimplemented_arguments.empty?
671
+
672
+ unimplemented_arguments.each{ | argument |
673
+
674
+ raise_error("Error: Argument '#{ argument }' is documented but not implemented in '#{ @current_method.name }' ($MODULE).\nNote that documented argument and variable name must be identical.", [ :attributes ].include?( @processing ) ? 'attr_argument' : 'arguments' )
675
+
676
+ }
677
+
678
+ # remove unimplemented argument documentation
679
+ result = result.select{ | documented_argument |
680
+
681
+ # always add block parameters
682
+ unimplemented_arguments.include?( documented_argument.to_a.flatten.first ) == false || documented_argument.to_a.flatten.first.include?("#")
683
+
684
+ }
685
+
686
+ end
687
+
688
+ end
689
+
690
+ # add missing/undocumented arguments to order list
691
+ missing = result.collect{ | value | order << value unless found_keys.include?( value.keys.first ) }
692
+
693
+ [ order, arguments_found ]
694
+
695
+ end
696
+
697
+ def process_table( source )
698
+
699
+ result = []
700
+
701
+ table_name = nil
702
+ header_columns = 0
703
+
704
+ source.lines.to_a.each_with_index{ | line, index |
705
+
706
+ # remove cr/lf
707
+ line.chomp!
708
+
709
+ # remove trailing whitespaces
710
+ line.rstrip!
711
+
712
+ # count nesting depth
713
+ line.match( /^(\s*)/ )
714
+
715
+ nesting = $1.size
716
+
717
+ #puts "%s,%s: %s" % [ index, nesting, line ]
718
+
719
+ # new table
720
+ if nesting == 0
721
+
722
+ # break if for some reason first character is "="
723
+ return result if line[0].chr == "="
724
+
725
+ unless line.empty?
726
+
727
+ line =~ /^(\w+)/i
728
+
729
+ result << { "name" => $1, "content" => [] }
730
+
731
+ table_name = $1.to_s
732
+
733
+ else
734
+
735
+ table_name = nil
736
+
737
+ end
738
+
739
+ else
740
+
741
+ line.lstrip!
742
+
743
+ if line[0].chr == '|'
744
+
745
+ unless table_name.nil?
746
+
747
+ if line[-1].chr != '|'
748
+
749
+ raise_error( "Malformed custom table #{ result.last[ "name" ]}, line '#{ line }' ($MODULE). Line must start and end with '|' character.", "table_format" )
750
+
751
+ else
752
+
753
+ line[0] = ""
754
+ line[-1] = ""
755
+
756
+ columns = line.split("|")
757
+
758
+ unless result.last[ "content" ].empty?
759
+
760
+ raise_error( "Malformed custom table #{ result.last[ "name" ]}, line '#{ line }' ($MODULE). Number of columns (#{ columns.count }) does not match with header (#{ header_columns })", "table_format" ) if columns.count != header_columns
761
+
762
+ else
763
+
764
+ header_columns = columns.count
765
+
766
+ end
767
+
768
+ result.last[ "content" ] << columns
769
+
770
+ end
771
+
772
+ else
773
+
774
+ raise_error( "Malformed custom table #{ result.last[ "name" ]} ($MODULE). Table name is missing.", "table_format" )
775
+
776
+ end
777
+
778
+ else
779
+
780
+ unless line.empty?
781
+
782
+ line =~ /^(.*?)\:{1}($|[\r\n\t\s]{1})(.*)$/i
783
+
784
+ if $1.to_s.empty?
785
+
786
+ raise_error( "Malformed custom table #{ result.last[ "name" ]}, line '#{ line }' ($MODULE). Table section name (e.g title) is missing.", "table_format" )
787
+
788
+ else
789
+
790
+ result.last[ $1.to_s ] = ( $3 || "" ).strip
791
+
792
+ end
793
+
794
+ else
795
+
796
+ table_name = nil
797
+
798
+ end
799
+
800
+ end
801
+
802
+ end
803
+
804
+ }
805
+
806
+ result
807
+
808
+ end
809
+
810
+ def process_formatted_section( source )
811
+
812
+ result = []
813
+
814
+ current_argument_type = nil
815
+
816
+ current_section = nil
817
+
818
+ argument_index = -1
819
+
820
+ constants_to_classes = { "nil" => "NilClass", "true" => "TrueClass", "false" => "FalseClass" }
821
+
822
+ source.lines.to_a.each_with_index{ | line, index |
823
+
824
+ # remove cr/lf
825
+ line.chomp!
826
+
827
+ # remove trailing whitespaces
828
+ line.rstrip!
829
+
830
+ # count nesting depth
831
+ line.match( /^(\s*)/ )
832
+
833
+ nesting = $1.size
834
+
835
+ # remove leading whitespaces
836
+ line.lstrip!
837
+
838
+ if nesting == 0
839
+
840
+ # convert constants nil, true, false to real class names
841
+ line = constants_to_classes[ line.downcase ] if constants_to_classes.include?( line.downcase )
842
+
843
+ line =~ /^(.+)/i
844
+
845
+ if !$1.nil? && (65..90).include?( $1[0] )
846
+
847
+ #Kernel.const_get( $1 ) rescue abort( "Line %s: \"%s\" is not valid argument variable type. (e.g. OK: \"String\", \"Array\", \"Fixnum\" etc) " % [ index + 1, $1 ] ) if verify_type
848
+
849
+ # argument type
850
+ current_argument_type = $1 || ""
851
+
852
+ current_section = nil
853
+
854
+ result << { current_argument_type => {} }
855
+
856
+ argument_index += 1
857
+
858
+ end
859
+
860
+ else
861
+
862
+ raise_error("Unable add value details (line %s: \"%s\") for %s due to detail type must be defined first.\nPlease note that return value and exception type must start with capital letter (e.g. OK: \"String\" NOK: \"string\")" % [ index + 1, line, current_argument_type ] ) if current_argument_type.nil?
863
+
864
+ line =~ /^(.*?)\:{1}($|[\r\n\t\s]{1})(.*)$/i
865
+
866
+ if $1.nil?
867
+
868
+ raise_error("Unable add value details (line %s: \"%s\") for %s due to section name not defined. Sections names are written in lowercase with trailing colon and whitespace (e.g. OK: \"example: 10\", NOK: \"example:10\")" % [ index +1, line, current_argument_type ]) if $1.nil? && current_section.nil?
869
+
870
+ # remove leading & trailing whitespaces
871
+ section_content = line.strip
872
+
873
+ else
874
+
875
+ current_section = $1
876
+
877
+ if result[ argument_index ].has_key?( current_argument_type )
878
+
879
+ unless result[ argument_index ][ current_argument_type ].has_key?( current_section )
880
+
881
+ result[ argument_index ][ current_argument_type ][ current_section ] = ""
882
+
883
+ end
884
+
885
+ end
886
+
887
+ section_content = ( $3 || "" ).strip
888
+
889
+ end
890
+
891
+ if current_argument_type.nil?
892
+
893
+ raise_error("Unable add return value details due to variable type not defined. Argument type must be defined at pos 1 of comment. (e.g. \"# Integer\" NOK: \"# Integer\", \"#Integer\")")
894
+
895
+ else
896
+
897
+ # add one leading whitespace if current_section value is not empty
898
+ section_content = " " + section_content unless result[ argument_index ][ current_argument_type ][ current_section ].empty?
899
+
900
+ # store section_content to current_section
901
+ result[ argument_index ][ current_argument_type ][ current_section ] << section_content
902
+
903
+ end
904
+
905
+ end
906
+
907
+
908
+ }
909
+
910
+ result
911
+
912
+ end
913
+
914
+ =begin
915
+ def store_to_results( module_name, name, type, params )
916
+
917
+ unless @found_modules_and_methods.has_key?( module_name )
918
+
919
+ @found_modules_and_methods[ module_name ] = []
920
+
921
+ end
922
+
923
+ #p params.select{ | param | param.last == false }
924
+ #p params.select{ | param | param.last == true }
925
+
926
+ #exit
927
+
928
+ count = "%s;%s" % [ params.count, params.select{ | param | param.last == true }.count ]
929
+
930
+ @found_modules_and_methods[ module_name ] << "%s#%s#%s" % [ name, type, count ] #{ :name => name, :type => type }
931
+
932
+ end
933
+ =end
934
+
935
+ def process_arguments( arguments )
936
+
937
+ return [] if arguments.to_s.empty?
938
+
939
+ arguments = arguments[ 1 .. -2 ] if arguments[0].chr == "(" and arguments[-1].chr ==")"
940
+
941
+ arguments.strip!
942
+
943
+ # tokenize string
944
+ tokenizer = RubyLex.new( arguments )
945
+
946
+ # get first token
947
+ token = tokenizer.token
948
+
949
+ # set previous token to nil by default
950
+ previous_token = nil
951
+
952
+ args = []
953
+
954
+ capture = true
955
+ capture_depth = []
956
+ capture_default = false
957
+
958
+ default_value = []
959
+
960
+ # loop while tokens available
961
+ while token
962
+
963
+ if [ RubyToken::TkLBRACE, RubyToken::TkLPAREN, RubyToken::TkLBRACK ].include?( token.class )
964
+
965
+ default_value << token.text if capture_default
966
+
967
+ capture_depth << token
968
+
969
+ capture = false
970
+
971
+ elsif [ RubyToken::TkRBRACE, RubyToken::TkRPAREN, RubyToken::TkRBRACK ].include?( token.class )
972
+
973
+ default_value << token.text if capture_default
974
+
975
+ capture_depth.pop
976
+
977
+ capture = true if capture_depth.empty?
978
+
979
+ # argument name
980
+ elsif capture == true
981
+
982
+ # argument name, or part of argument default value
983
+ if token.kind_of?( RubyToken::TkIDENTIFIER ) and ![ RubyToken::TkDOT, RubyToken::TkCOLON2 ].include?( previous_token.class )
984
+
985
+ args << [ token.name, nil, false ]
986
+
987
+ # &blocks and *arguments are handled as optional parameters
988
+ if [ RubyToken::TkBITAND, RubyToken::TkMULT ].include?( previous_token.class )
989
+ #args.last[ 1 ] = previous_token.text
990
+
991
+ args.last[ 0 ] = previous_token.text + args.last[ 0 ]
992
+ args.last[ -1 ] = true
993
+
994
+ end
995
+
996
+ default_value = []
997
+ capture_default = false
998
+
999
+ elsif token.kind_of?( RubyToken::TkCOMMA )
1000
+
1001
+ capture_default = false
1002
+
1003
+ # detect optional argument
1004
+ elsif token.kind_of?( RubyToken::TkASSIGN )
1005
+
1006
+ capture_default = true
1007
+
1008
+ # mark arguments as optional
1009
+ args.last[ -1 ] = true
1010
+
1011
+ else
1012
+
1013
+ default_value << token.text if capture_default && ![ RubyToken::TkSPACE, RubyToken::TkNL ].include?( token.class )
1014
+
1015
+ end
1016
+
1017
+ else
1018
+
1019
+ default_value << token.text if capture_default && ![ RubyToken::TkSPACE, RubyToken::TkNL ].include?( token.class )
1020
+
1021
+ end
1022
+
1023
+ unless default_value.empty?
1024
+
1025
+ args.last[ 1 ] = default_value.join("")
1026
+
1027
+ end
1028
+
1029
+ # store previous token
1030
+ previous_token = token
1031
+
1032
+ # get next token
1033
+ token = tokenizer.token
1034
+
1035
+ end
1036
+
1037
+ args
1038
+
1039
+ end
1040
+
1041
+ def process_undocumented_method_arguments( params )
1042
+
1043
+ params.collect{ | param |
1044
+
1045
+ hash = {}
1046
+ hash[ :types ] = {}
1047
+ hash[ :default ] = param[1] if param[-1] == true
1048
+
1049
+ { param.first.to_s => hash }
1050
+
1051
+ }
1052
+
1053
+ end
1054
+
1055
+ def process_method( method )
1056
+
1057
+ results = []
1058
+
1059
+ method_header = nil
1060
+
1061
+ # if this tag ("== nodoc") is found in method description, it should not be added to documentation
1062
+ no_doc = false
1063
+
1064
+ if ( method.visibility == :public && @module_path.first =~ /MobyBehaviour/ )
1065
+
1066
+ params = method.kind_of?( RDoc::Attr ) ? [] : process_arguments( method.params )
1067
+
1068
+ @current_method = method
1069
+
1070
+ method_header = process_comment( method.comment )
1071
+
1072
+ ## TODO: remember to verify that there are documentation for each argument!
1073
+ ## TODO: verify that there is a tag for visualizer example
1074
+
1075
+ arguments_found = 0
1076
+
1077
+ method_header = Hash[ method_header.collect{ | key, value |
1078
+
1079
+ if key == :nodoc
1080
+
1081
+ no_doc = true
1082
+
1083
+ end
1084
+
1085
+ if key == :arguments
1086
+
1087
+ value, arguments_found = process_method_arguments_section( value, params )
1088
+
1089
+ end
1090
+
1091
+ if key == :returns
1092
+
1093
+ value = process_formatted_section( value )
1094
+
1095
+ end
1096
+
1097
+ if key == :exceptions
1098
+
1099
+ value = process_formatted_section( value )
1100
+
1101
+ end
1102
+
1103
+ if key == :tables
1104
+
1105
+ value = process_table( value )
1106
+
1107
+ end
1108
+
1109
+ [ key, value ]
1110
+
1111
+ }]
1112
+
1113
+ method_header[ :__arguments_found ] = arguments_found
1114
+
1115
+ # if no description found for arguments, add argument names to method_header hash
1116
+ if ( params.count > 0 ) && ( method_header[ :arguments ].nil? || method_header[:arguments].empty? )
1117
+
1118
+ #p params.count,
1119
+ method_header[:arguments] = process_undocumented_method_arguments( params )
1120
+
1121
+ end
1122
+
1123
+ method_name = method.name.clone
1124
+
1125
+ type = "method"
1126
+
1127
+ if method.kind_of?( RDoc::Attr )
1128
+
1129
+ case method.rw
1130
+
1131
+ when "R"
1132
+ type = "reader"
1133
+ #store_to_results( @module_path.join("::"), method.name, type )
1134
+ when "W"
1135
+ type = "writer"
1136
+ method_name << "="
1137
+ #store_to_results( @module_path.join("::"), method.name + "=", type )
1138
+ when "RW"
1139
+ type = "accessor"
1140
+ #method_name << ";#{ method_name }="
1141
+ #store_to_results( @module_path.join("::"), method.name + "=", type )
1142
+
1143
+ else
1144
+
1145
+ raise_error( "Unknown attribute format for '#{ method.name }' ($MODULE). Expected 'R' (attr_reader), 'W' (attr_writer) or 'RW' (attr_accessor), got: '#{ method.rw }'" )
1146
+
1147
+ end
1148
+
1149
+ #store_to_results( @module_path.join("::"), method.name, type )
1150
+
1151
+ method_header.merge!( :__type => type )
1152
+
1153
+ else
1154
+
1155
+ method_header.merge!( :__type => "method" )
1156
+
1157
+ end
1158
+
1159
+ #p params
1160
+
1161
+ #sleep 0.3
1162
+
1163
+ method_header.merge!(
1164
+ :__arguments_implemented => params.count ,
1165
+ :__arguments_optional => params.select{ | param | param.last == true }.count
1166
+ )
1167
+
1168
+ #store_to_results( @module_path.join("::"), method.name, type, params )
1169
+
1170
+ #no_doc ? nil :
1171
+ [ method_name, method_header ]
1172
+
1173
+ else
1174
+
1175
+ nil
1176
+
1177
+ end
1178
+
1179
+ end
1180
+
1181
+ # verify if
1182
+ def has_method?( target, method_name )
1183
+
1184
+ target.method_list.select{ | method |
1185
+
1186
+ method.name == method_name
1187
+
1188
+ }.count > 0
1189
+
1190
+ end
1191
+
1192
+ def encode_string( string )
1193
+
1194
+ return "" if string.nil?
1195
+
1196
+ result = "%s" % string
1197
+
1198
+ result.gsub!( /\&/, '&amp;' )
1199
+ result.gsub!( /\</, '&lt;' )
1200
+ result.gsub!( /\>/, '&gt;' )
1201
+ result.gsub!( /\"/, '&quot;' )
1202
+ result.gsub!( /\'/, '&apos;' )
1203
+
1204
+ result
1205
+
1206
+ end
1207
+
1208
+ def process_attributes( attributes )
1209
+
1210
+ @processing = :attributes
1211
+
1212
+ results = []
1213
+
1214
+ attributes.each{ | attribute |
1215
+
1216
+ results << process_method( attribute )
1217
+
1218
+ }
1219
+
1220
+ Hash[ results ]
1221
+
1222
+ end
1223
+
1224
+ def process_comment( comment )
1225
+
1226
+ header = {}
1227
+
1228
+ current_section = nil
1229
+
1230
+ return header if comment.nil? || comment.empty?
1231
+
1232
+ comment.each_line{ | line |
1233
+
1234
+ # remove '#' char from beginning of line
1235
+ line.slice!( 0 )
1236
+
1237
+ # if next character is whitespace assume that this is valid comment line
1238
+ # NOTE: that if linefeed is required use "#<#32><#10>"
1239
+ if [ 32 ].include?( line[ 0 ] )
1240
+
1241
+ # remove first character
1242
+ line.slice!( 0 )
1243
+
1244
+ # if line is a section header
1245
+ if line[ 0..2 ] == "== "
1246
+
1247
+ # remove section header indicator string ("== ")
1248
+ line.slice!( 0..2 )
1249
+
1250
+ # remove cr/lf
1251
+ line.gsub!( /[\n\r]/, "" )
1252
+
1253
+ current_section = line.to_sym
1254
+
1255
+ header[ current_section ] = "nodoc" if line.to_s == "nodoc"
1256
+
1257
+ else
1258
+
1259
+ unless current_section.nil?
1260
+
1261
+ # remove cr/lf
1262
+ # NOTE: if crlf is required use '\n'
1263
+ line.gsub!( /[\n\r]/, "" )
1264
+
1265
+ # store to header hash
1266
+ if header.has_key?( current_section )
1267
+
1268
+ header[ current_section ] << "\n" << ( line.rstrip )
1269
+
1270
+ else
1271
+
1272
+ header[ current_section ] = line.rstrip
1273
+
1274
+ end
1275
+
1276
+ else
1277
+
1278
+ #puts "[nodoc?] %s" % line
1279
+
1280
+ end
1281
+
1282
+ end
1283
+
1284
+ else
1285
+
1286
+ #puts "[nodoc] %s" % line
1287
+
1288
+ end
1289
+
1290
+ }
1291
+
1292
+ header
1293
+
1294
+ end
1295
+
1296
+ def apply_macros!( source, macros )
1297
+
1298
+ macros.each_pair{ | key, value |
1299
+
1300
+ while result = /(\$#{ key }\b)/.match( source )
1301
+
1302
+ source = source[0..result.begin(0)-1] + value.to_s + source[result.end(0)..-1]
1303
+
1304
+ end
1305
+
1306
+ }
1307
+
1308
+ source
1309
+
1310
+ end
1311
+
1312
+ def raise_error( text, topic = nil )
1313
+
1314
+ type = ( @processing == "method" ) ? "method" : "attribute"
1315
+
1316
+ text.gsub!( '$TYPE', type )
1317
+
1318
+ text.gsub!( '$MODULE', @current_module.full_name )
1319
+
1320
+ text = "=========================================================================================================\n" <<
1321
+ "File: #{ @module_in_files.join(", ") }\n" << text << "\n\nExample:\n\n"
1322
+
1323
+ text << help( topic ) unless topic.nil?
1324
+
1325
+ warn( text << "\n" )
1326
+
1327
+ end
1328
+
1329
+ def generate_return_values_element( header, feature )
1330
+
1331
+ return "" if ( [ 'writer' ].include?( feature.last[ :__type ] ) )
1332
+
1333
+ return if feature.last[ :returns ].nil? || feature.last[ :returns ].empty?
1334
+
1335
+ if feature.last[ :returns ].nil?
1336
+
1337
+ raise_error("Error: $TYPE '#{ feature.first }' ($MODULE) doesn't have return value type(s) defined", 'returns' )
1338
+
1339
+ end
1340
+
1341
+ count = 0
1342
+
1343
+ # generate return value types template
1344
+ returns = feature.last[ :returns ].collect{ | return_types |
1345
+
1346
+ return_types.collect{ | returns |
1347
+
1348
+ count += 1
1349
+
1350
+ # apply types to returns template
1351
+ apply_macros!( @templates["behaviour.xml.returns"].clone, {
1352
+ "RETURN_VALUE_TYPE" => encode_string( returns.first ),
1353
+ "RETURN_VALUE_DESCRIPTION" => encode_string( returns.last["description"] ),
1354
+ "RETURN_VALUE_EXAMPLE" => encode_string( returns.last["example"] ),
1355
+ }
1356
+ )
1357
+
1358
+ }.join
1359
+
1360
+ }.join
1361
+
1362
+ if count > 0
1363
+
1364
+ apply_macros!( @templates["behaviour.xml.method.returns"].clone, {
1365
+
1366
+ "METHOD_RETURNS" => returns
1367
+
1368
+ }
1369
+ )
1370
+
1371
+ else
1372
+
1373
+ ""
1374
+
1375
+ end
1376
+
1377
+ end
1378
+
1379
+ def generate_exceptions_element( header, feature )
1380
+
1381
+ return "" if ( feature.last[:__type] != 'method' )
1382
+
1383
+ #if feature.last[ :exceptions ].nil?
1384
+ # raise_error("Error: $TYPE '#{ feature.first }' ($MODULE) doesn't have exceptions(s) defined", 'exceptions' )
1385
+ #end
1386
+
1387
+ return "" if feature.last[ :exceptions ].nil? || feature.last[ :exceptions ].empty?
1388
+
1389
+ count = 0
1390
+
1391
+ # generate exceptions template
1392
+ exceptions = feature.last[ :exceptions ].collect{ | exceptions |
1393
+
1394
+ exceptions.collect{ | exception |
1395
+
1396
+ count += 1
1397
+
1398
+ # apply types to exception template
1399
+ apply_macros!( @templates["behaviour.xml.exception"].clone, {
1400
+ "EXCEPTION_NAME" => encode_string( exception.first ),
1401
+ "EXCEPTION_DESCRIPTION" => encode_string( exception.last["description"] )
1402
+ }
1403
+ )
1404
+
1405
+ }.join
1406
+
1407
+ }.join
1408
+
1409
+ if count > 0
1410
+
1411
+ apply_macros!( @templates["behaviour.xml.method.exceptions"].clone, {
1412
+
1413
+ "METHOD_EXCEPTIONS" => exceptions
1414
+
1415
+ }
1416
+ )
1417
+
1418
+ else
1419
+
1420
+ ""
1421
+
1422
+ end
1423
+
1424
+ end
1425
+
1426
+ def generate_arguments_element( header, feature )
1427
+
1428
+ return "" if ( feature.last[:__type] == 'reader' )
1429
+
1430
+ argument_types = { "*" => "multi", "&" => "block" }
1431
+ argument_types.default = "normal"
1432
+
1433
+ #return "" if ( @processing == :attributes && feature.last[:__type] == 'R' )
1434
+
1435
+ feature.last[ :__type ]
1436
+
1437
+ if feature.last[ :arguments ].nil? and feature.last[ :__arguments_found ] > 0
1438
+
1439
+ note = ". Note that also attribute writer requires input value defined as argument." if [ 'writer', 'accessor' ].include?( @processing )
1440
+
1441
+ raise_error("Error: $TYPE '#{ feature.first }' ($MODULE) doesn't have arguments(s) defined#{ note }", [ 'writer', 'accessor' ].include?( @processing ) ? 'attr_argument' : 'arguments' )
1442
+
1443
+ end
1444
+
1445
+ # generate arguments xml
1446
+ arguments = ( feature.last[:arguments] || {} ).collect{ | arg |
1447
+
1448
+ # generate argument types template
1449
+ arg.collect{ | argument |
1450
+
1451
+ argument_type = argument_types[ argument.first[0].chr ]
1452
+ argument_name = "%s" % argument.first
1453
+ argument_name[0]="" if argument_types.has_key?( argument_name[0].chr )
1454
+
1455
+ argument_type = "block_argument" if argument_type == "block" && argument_name.include?( "#" )
1456
+
1457
+ default_value_set = false
1458
+ default_value = nil
1459
+
1460
+ if argument.last.has_key?( :argument_type_order )
1461
+
1462
+ argument_types_in_order = argument.last[:argument_type_order].collect{ | type |
1463
+ [ type, argument.last[:types][ type ] ]
1464
+ }
1465
+
1466
+ else
1467
+
1468
+ argument_types_in_order = argument.last[ :types ]
1469
+
1470
+ end
1471
+
1472
+ argument_types_in_order ||= []
1473
+
1474
+ # in case of argument is not documented at all...
1475
+ if argument_types_in_order.empty?
1476
+
1477
+ # set optional flag if default value given
1478
+ unless argument.last[:default].nil?
1479
+
1480
+ default_value = argument.last[:default]
1481
+ default_value_set = true
1482
+
1483
+ end
1484
+
1485
+ end
1486
+
1487
+ types_xml = argument_types_in_order.collect{ | type |
1488
+
1489
+ unless argument.last[:default].nil?
1490
+
1491
+ # show warning if default value for optional argument is already set
1492
+ #raise_error( "Error: Default value for optional argument '%s' ($MODULE) is already set! ('%s' --> '%s')" % [ argument.first, default_value, type.last["default"] ] ) if default_value_set == true
1493
+
1494
+ default_value = argument.last[:default]
1495
+ default_value_set = true
1496
+
1497
+ end
1498
+
1499
+ =begin
1500
+ unless type.last["default"].nil?
1501
+
1502
+ # show warning if default value for optional argument is already set
1503
+ #raise_error( "Error: Default value for optional argument '%s' ($MODULE) is already set! ('%s' --> '%s')" % [ argument.first, default_value, type.last["default"] ] ) if default_value_set == true
1504
+
1505
+
1506
+ default_value = type.last["default"]
1507
+ default_value_set = true
1508
+
1509
+ end
1510
+ =end
1511
+
1512
+ if type.last["description"].nil?
1513
+
1514
+ raise_error("Warning: Argument description for '%s' ($MODULE) is empty." % [ argument.first ], 'argument' )
1515
+
1516
+ end
1517
+
1518
+ if type.last["example"].nil?
1519
+
1520
+ raise_error("Warning: Argument '%s' ($MODULE) example is empty." % [ argument.first ])
1521
+
1522
+ end
1523
+
1524
+ apply_macros!( @templates["behaviour.xml.argument_type"].clone, {
1525
+
1526
+ "ARGUMENT_TYPE" => encode_string( argument_type == 'block' ? "Proc" : type.first ),
1527
+ "ARGUMENT_DESCRIPTION" => encode_string( type.last["description"] ),
1528
+ "ARGUMENT_EXAMPLE" => encode_string( type.last["example"] ),
1529
+
1530
+ }
1531
+ )
1532
+
1533
+ }.join
1534
+
1535
+ if argument_type == "multi"
1536
+
1537
+ default_value = "[]"
1538
+ default_value_set = true
1539
+
1540
+ end
1541
+
1542
+ if default_value_set
1543
+
1544
+ default_value = apply_macros!( @templates["behaviour.xml.argument.default"].clone, {
1545
+ "ARGUMENT_DEFAULT_VALUE" => encode_string( default_value || "" )
1546
+ }
1547
+ )
1548
+
1549
+ else
1550
+
1551
+ default_value = ""
1552
+
1553
+ end
1554
+
1555
+ # apply types to arguments template
1556
+ apply_macros!( @templates["behaviour.xml.argument"].clone, {
1557
+ "ARGUMENT_NAME" => encode_string( argument_name ),
1558
+ "ARGUMENT_TYPE" => encode_string( argument_type ),
1559
+ "ARGUMENT_TYPES" => types_xml,
1560
+ "ARGUMENT_DEFAULT_VALUE" => default_value.to_s,
1561
+ "ARGUMENT_OPTIONAL" => encode_string( ["multi", "block", "block_argument"].include?( argument_type ) ? "true" : default_value_set.to_s )
1562
+ }
1563
+ )
1564
+
1565
+ }.join
1566
+
1567
+ }.join
1568
+
1569
+ apply_macros!( @templates["behaviour.xml.method.arguments"].clone, {
1570
+
1571
+ "ARGUMENTS_IMPLEMENTED" => feature.last[ :__arguments_implemented ] || "0",
1572
+ "ARGUMENT_OPTIONAL_COUNT" => feature.last[ :__arguments_optional ] || "0",
1573
+ "METHOD_ARGUMENTS" => arguments
1574
+
1575
+ }
1576
+ )
1577
+
1578
+
1579
+ end
1580
+
1581
+ def generate_tables_element( header, features )
1582
+
1583
+ tables = []
1584
+
1585
+ unless features.last[:tables].nil? #[:tables]
1586
+
1587
+ #p features.last[:tables]
1588
+ #p features.last[:tables]["content"]
1589
+
1590
+ #return "" if features.last[:tables]["content"] == []
1591
+
1592
+ tables = features.last[:tables].collect{ | table |
1593
+
1594
+ header = table[ "content" ].first.collect{ | header_item |
1595
+ apply_macros!( @templates["behaviour.xml.table.item"].clone, {
1596
+ "ITEM" => encode_string( header_item )
1597
+ }
1598
+ )
1599
+ }
1600
+
1601
+ rows = table[ "content" ][ 1 .. -1 ].collect{ | row |
1602
+
1603
+ row_items = row.collect{ | row_item |
1604
+
1605
+ apply_macros!( @templates["behaviour.xml.table.item"].clone, {
1606
+ "ITEM" => encode_string( row_item )
1607
+ }
1608
+ )
1609
+ }
1610
+
1611
+ apply_macros!( @templates["behaviour.xml.table.row"].clone, {
1612
+
1613
+ "TABLE_ROW_ITEMS" => row_items.join("")
1614
+
1615
+ }
1616
+ )
1617
+
1618
+ }
1619
+
1620
+ apply_macros!( @templates["behaviour.xml.table"].clone, {
1621
+ "TABLE_NAME" => encode_string( table[ "name" ] ),
1622
+ "TABLE_TITLE" => encode_string( table[ "title" ] || "" ),
1623
+ "TABLE_DESCRIPTION" => encode_string( table[ "description" ] || "" ),
1624
+ "TABLE_HEADER_ITEMS" => header.join(""),
1625
+ "TABLE_ROWS" => rows.join("")
1626
+ }
1627
+ )
1628
+ }
1629
+
1630
+ end
1631
+
1632
+ if tables.count > 0
1633
+
1634
+ apply_macros!( @templates["behaviour.xml.method.tables"].clone, {
1635
+
1636
+ "METHOD_TABLES" => tables.join("")
1637
+
1638
+ }
1639
+ )
1640
+
1641
+ else
1642
+
1643
+ ""
1644
+
1645
+ end
1646
+
1647
+ end
1648
+
1649
+ def generate_deprecated_element( header, feature, &block )
1650
+
1651
+ if feature.last.has_key?( :deprecated )
1652
+
1653
+ yield
1654
+
1655
+ apply_macros!( @templates["behaviour.xml.method.deprecated"].clone, {
1656
+ "DEPRECATED_IN_VERSION_NUMBER" => encode_string( feature.last[:deprecated] )
1657
+ }
1658
+ )
1659
+
1660
+ else
1661
+
1662
+ ""
1663
+
1664
+ end
1665
+
1666
+ end
1667
+
1668
+ def generate_info_element( header, feature )
1669
+
1670
+ if feature.last.has_key?( :info )
1671
+
1672
+ apply_macros!( @templates["behaviour.xml.method.info"].clone, {
1673
+ "METHOD_INFO" => encode_string( feature.last[:info] )
1674
+ }
1675
+ )
1676
+
1677
+ else
1678
+
1679
+ ""
1680
+
1681
+ end
1682
+
1683
+ end
1684
+
1685
+ def generate_methods_element( header, features )
1686
+
1687
+ # collect method and attribute templates
1688
+ methods = features.collect{ | feature_set |
1689
+
1690
+ feature_set.collect{ | feature |
1691
+
1692
+ @processing = feature.last[:__type]
1693
+
1694
+ # TODO: tarkista lähdekoodista että onko argument optional vai ei
1695
+ # TODO: tarkista että onko kaikki argumentit dokumentoitu
1696
+
1697
+ arguments = generate_arguments_element( header, feature )
1698
+
1699
+ returns = generate_return_values_element( header, feature )
1700
+
1701
+ exceptions = generate_exceptions_element( header, feature )
1702
+
1703
+ tables = generate_tables_element( header, feature )
1704
+
1705
+ info = generate_info_element( header, feature )
1706
+
1707
+ deprecated = generate_deprecated_element( header, feature ){
1708
+
1709
+ arguments = ""
1710
+ returns = ""
1711
+ exceptions = ""
1712
+ tables = ""
1713
+
1714
+ }
1715
+
1716
+ if feature.last[:description].nil?
1717
+
1718
+ raise_error("Warning: $TYPE description for '#{ feature.first }' ($MODULE) is empty.", 'description')
1719
+
1720
+ end
1721
+
1722
+ # generate method template
1723
+ apply_macros!( @templates["behaviour.xml.method"].clone, {
1724
+ "METHOD_NAME" => encode_string( feature.first ),
1725
+ "METHOD_TYPE" => encode_string( feature.last[:__type] || "unknown" ),
1726
+ "NODOC" => feature.last.has_key?(:nodoc).to_s,
1727
+ "METHOD_DEPRECATED" => deprecated,
1728
+ "METHOD_DESCRIPTION" => encode_string( feature.last[:description] ),
1729
+ "METHOD_ARGUMENTS" => arguments,
1730
+ "METHOD_RETURNS" => returns,
1731
+ "METHOD_EXCEPTIONS" => exceptions,
1732
+ "METHOD_TABLES" => tables,
1733
+ "METHOD_INFO" => info # feature.last[:info]
1734
+ }
1735
+ )
1736
+
1737
+ }.join
1738
+
1739
+ }.join
1740
+
1741
+
1742
+ end
1743
+
1744
+ def generate_behaviour_element( header, methods )
1745
+
1746
+ # verify that behaviour description is defined
1747
+ unless header.has_key?(:description)
1748
+
1749
+ raise_error("Warning: Behaviour description for $MODULE is empty.", 'behaviour_description' ) unless methods.empty?
1750
+
1751
+ end
1752
+
1753
+ # verify that behaviour name is defined
1754
+ unless header.has_key?(:behaviour)
1755
+
1756
+ raise_error("Warning: Behaviour name for $MODULE is not defined.", 'behaviour_name' ) unless methods.empty?
1757
+
1758
+ end
1759
+
1760
+ # verify that behaviour object type(s) is defined
1761
+ unless header.has_key?(:objects)
1762
+
1763
+ raise_error("Warning: Behaviour object type(s) for $MODULE is not defined.", 'behaviour_object_types' ) unless methods.empty?
1764
+
1765
+ end
1766
+
1767
+ # verify that behaviour sut type(s) is defined
1768
+ unless header.has_key?(:sut_type)
1769
+
1770
+ raise_error("Warning: Behaviour SUT type for $MODULE is not defined.", 'behaviour_sut_type' ) unless methods.empty?
1771
+
1772
+ end
1773
+
1774
+ # verify that behaviour input type(s) is defined
1775
+ unless header.has_key?(:input_type)
1776
+
1777
+ raise_error("Warning: Behaviour input type for $MODULE is not defined.", 'behaviour_input_type' ) unless methods.empty?
1778
+
1779
+ end
1780
+
1781
+ # verify that behaviour sut version(s) is defined
1782
+ unless header.has_key?(:sut_version)
1783
+
1784
+ raise_error("Warning: Behaviour SUT version for $MODULE is not defined.", 'behaviour_version' ) unless methods.empty?
1785
+
1786
+ end
1787
+
1788
+ # verify that behaviour sut version(s) is defined
1789
+ unless header.has_key?(:requires)
1790
+
1791
+ raise_error("Warning: Required plugin name is not defined for $MODULE.", 'behaviour_requires' ) unless methods.empty?
1792
+
1793
+ end
1794
+
1795
+ # apply header
1796
+ text = apply_macros!( @templates["behaviour.xml"].clone, {
1797
+ "REQUIRED_PLUGIN" => encode_string( header[:requires] ),
1798
+ "BEHAVIOUR_NAME" => encode_string( header[:behaviour] ),
1799
+ "BEHAVIOUR_METHODS" => methods,
1800
+ "OBJECT_TYPE" => encode_string( header[:objects] ),
1801
+ "SUT_TYPE" => encode_string( header[:sut_type] ),
1802
+ "INPUT_TYPE" => encode_string( header[:input_type] ),
1803
+ "VERSION" => encode_string( header[:sut_version] ),
1804
+ "MODULE_NAME" => encode_string( @module_path.join("::") )
1805
+ }
1806
+ )
1807
+
1808
+ # remove extra linefeeds
1809
+ text.gsub!( /^[\n]+/, "\n" )
1810
+
1811
+ text.gsub!( /^(\s)*$/, "" )
1812
+
1813
+ text
1814
+
1815
+ end
1816
+
1817
+ def generate_behaviour( header, *features )
1818
+
1819
+ methods = generate_methods_element( header, features )
1820
+
1821
+ generate_behaviour_element( header, methods )
1822
+
1823
+ end
1824
+
1825
+ def process_module( _module )
1826
+
1827
+ @already_processed_files << _module.full_name
1828
+
1829
+ # skip if not a behaviour module
1830
+ return if /^MobyBehaviour.*/ !~ _module.full_name.to_s
1831
+
1832
+ module_header = process_comment( _module.comment )
1833
+
1834
+ # store information where module is stored
1835
+ @module_in_files = _module.in_files.collect{ | file | file.file_absolute_name }
1836
+
1837
+ #unless module_header.empty?
1838
+
1839
+ @current_module = _module
1840
+
1841
+ # process methods
1842
+ methods = process_methods( _module.method_list )
1843
+
1844
+ # process attributes
1845
+ attributes = process_attributes( _module.attributes )
1846
+
1847
+ print " ... %s" % module_header[:behaviour]
1848
+
1849
+ xml = generate_behaviour( module_header, methods, attributes )
1850
+
1851
+ xml_file_name = '%s.%s' % [ module_header[:behaviour], 'xml' ]
1852
+
1853
+ begin
1854
+
1855
+ if xml_file_name != '.xml'
1856
+
1857
+ if @created_files.has_key?( xml_file_name )
1858
+
1859
+ xml_file_name = '%s_duplicate_name.%s' % [ module_header[:behaviour], 'xml' ]
1860
+
1861
+ warn("Warning! One of the behaviour modules is already using name '#{ module_header[:behaviour] }', saving as #{ xml_file_name }")
1862
+
1863
+ sleep 1
1864
+
1865
+ end
1866
+
1867
+ @created_files[ xml_file_name ] = {}
1868
+
1869
+ open( xml_file_name, 'w'){ | file | file << xml }
1870
+
1871
+ puts ".xml"
1872
+
1873
+ else
1874
+
1875
+ if methods.count > 0
1876
+
1877
+ xml_file_name = ( @module_path[1..-1].join("") ) + '.xml'
1878
+
1879
+ warn("Warning: #{ @module_path.join("::") } does not have behaviour (module) description defined, saving as %s " % xml_file_name )
1880
+ sleep 2
1881
+
1882
+ if @created_files.has_key?( xml_file_name )
1883
+
1884
+ warn("Warning! One of the behaviour modules is already using name '#{ module_header[:behaviour] }'")
1885
+
1886
+ xml_file_name = ( @module_path[1..-1].join("") ) + '_duplicate_name.xml'
1887
+
1888
+ sleep 1
1889
+
1890
+ end
1891
+
1892
+ @created_files[ xml_file_name ] = {}
1893
+
1894
+ open( xml_file_name, 'w'){ | file | file << xml }
1895
+
1896
+ else
1897
+
1898
+ warn("Skip: #{ @module_path.join("::") } does not have any public methods") unless @module_path.join("::") == "MobyBehaviour"
1899
+
1900
+ end
1901
+
1902
+ #p xml
1903
+
1904
+ #warn("Skip: #{ @module_path.join("::") } XML not saved due to missing behaviour name/description ") #in #{ @module_in_files.join(", ") }")
1905
+
1906
+ end
1907
+
1908
+ rescue Exception => exception
1909
+
1910
+ warn("Warning: Error writing file %s (%s: %s)" % [ xml_file_name, exception.class, exception.message ] )
1911
+
1912
+ end
1913
+
1914
+ #end
1915
+
1916
+ # process if any child modules
1917
+ process_modules( _module.modules ) unless _module.modules.empty?
1918
+
1919
+ end
1920
+
1921
+ end
1922
+
1923
+ end
1924
+