cutedriver-driver 2.0.0.20210120164037

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