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