testability-driver 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+