mack 0.8.1 → 0.8.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 (477) hide show
  1. data/CHANGELOG +22 -1
  2. data/bin/mack +3 -0
  3. data/bin/mackery-console +4 -0
  4. data/bin/mackery-server +21 -4
  5. data/lib/gems.rb +15 -0
  6. data/lib/gems/abstract-1.0.0/lib/abstract.rb +75 -0
  7. data/lib/gems/builder-2.1.2/lib/blankslate.rb +113 -0
  8. data/lib/gems/builder-2.1.2/lib/builder.rb +13 -0
  9. data/lib/gems/builder-2.1.2/lib/builder/blankslate.rb +20 -0
  10. data/lib/gems/builder-2.1.2/lib/builder/css.rb +250 -0
  11. data/lib/gems/builder-2.1.2/lib/builder/xchar.rb +115 -0
  12. data/lib/gems/builder-2.1.2/lib/builder/xmlbase.rb +139 -0
  13. data/lib/gems/builder-2.1.2/lib/builder/xmlevents.rb +63 -0
  14. data/lib/gems/builder-2.1.2/lib/builder/xmlmarkup.rb +328 -0
  15. data/lib/gems/configatron-2.1.5/lib/configatron.rb +6 -0
  16. data/lib/gems/configatron-2.1.5/lib/configatron/configatron.rb +52 -0
  17. data/lib/gems/configatron-2.1.5/lib/configatron/errors.rb +7 -0
  18. data/lib/gems/configatron-2.1.5/lib/configatron/kernel.rb +8 -0
  19. data/lib/gems/configatron-2.1.5/lib/configatron/store.rb +224 -0
  20. data/lib/gems/daemons-1.0.10/lib/daemons.rb +283 -0
  21. data/lib/gems/daemons-1.0.10/lib/daemons/application.rb +372 -0
  22. data/lib/gems/daemons-1.0.10/lib/daemons/application_group.rb +152 -0
  23. data/lib/gems/daemons-1.0.10/lib/daemons/cmdline.rb +117 -0
  24. data/lib/gems/daemons-1.0.10/lib/daemons/controller.rb +134 -0
  25. data/lib/gems/daemons-1.0.10/lib/daemons/daemonize.rb +263 -0
  26. data/lib/gems/daemons-1.0.10/lib/daemons/exceptions.rb +28 -0
  27. data/lib/gems/daemons-1.0.10/lib/daemons/monitor.rb +127 -0
  28. data/lib/gems/daemons-1.0.10/lib/daemons/pid.rb +101 -0
  29. data/lib/gems/daemons-1.0.10/lib/daemons/pidfile.rb +111 -0
  30. data/lib/gems/daemons-1.0.10/lib/daemons/pidmem.rb +10 -0
  31. data/lib/gems/flexmock-0.8.3/lib/flexmock.rb +13 -0
  32. data/lib/gems/flexmock-0.8.3/lib/flexmock/argument_matchers.rb +57 -0
  33. data/lib/gems/flexmock-0.8.3/lib/flexmock/argument_types.rb +42 -0
  34. data/lib/gems/flexmock-0.8.3/lib/flexmock/base.rb +24 -0
  35. data/lib/gems/flexmock-0.8.3/lib/flexmock/composite.rb +10 -0
  36. data/lib/gems/flexmock-0.8.3/lib/flexmock/core.rb +218 -0
  37. data/lib/gems/flexmock-0.8.3/lib/flexmock/core_class_methods.rb +83 -0
  38. data/lib/gems/flexmock-0.8.3/lib/flexmock/default_framework_adapter.rb +31 -0
  39. data/lib/gems/flexmock-0.8.3/lib/flexmock/deprecated_methods.rb +62 -0
  40. data/lib/gems/flexmock-0.8.3/lib/flexmock/errors.rb +23 -0
  41. data/lib/gems/flexmock-0.8.3/lib/flexmock/expectation.rb +476 -0
  42. data/lib/gems/flexmock-0.8.3/lib/flexmock/expectation_director.rb +87 -0
  43. data/lib/gems/flexmock-0.8.3/lib/flexmock/mock_container.rb +321 -0
  44. data/lib/gems/flexmock-0.8.3/lib/flexmock/noop.rb +13 -0
  45. data/lib/gems/flexmock-0.8.3/lib/flexmock/ordering.rb +51 -0
  46. data/lib/gems/flexmock-0.8.3/lib/flexmock/partial_mock.rb +291 -0
  47. data/lib/gems/flexmock-0.8.3/lib/flexmock/rails.rb +15 -0
  48. data/lib/gems/flexmock-0.8.3/lib/flexmock/rails/view_mocking.rb +102 -0
  49. data/lib/gems/flexmock-0.8.3/lib/flexmock/recorder.rb +71 -0
  50. data/lib/gems/flexmock-0.8.3/lib/flexmock/rspec.rb +34 -0
  51. data/lib/gems/flexmock-0.8.3/lib/flexmock/test_unit.rb +32 -0
  52. data/lib/gems/flexmock-0.8.3/lib/flexmock/test_unit_integration.rb +53 -0
  53. data/lib/gems/flexmock-0.8.3/lib/flexmock/undefined.rb +50 -0
  54. data/lib/gems/flexmock-0.8.3/lib/flexmock/validators.rb +77 -0
  55. data/lib/gems/genosaurus-1.2.4/lib/genosaurus.rb +233 -0
  56. data/lib/gems/lockfile-1.4.3/bin/rlock +360 -0
  57. data/lib/gems/lockfile-1.4.3/bin/rlock-1.4.3 +360 -0
  58. data/lib/gems/lockfile-1.4.3/lib/lockfile-1.4.3.rb +564 -0
  59. data/lib/gems/lockfile-1.4.3/lib/lockfile.rb +564 -0
  60. data/lib/gems/logging-0.9.4/data/bad_logging_1.rb +13 -0
  61. data/lib/gems/logging-0.9.4/data/bad_logging_2.rb +21 -0
  62. data/lib/gems/logging-0.9.4/data/logging.rb +42 -0
  63. data/lib/gems/logging-0.9.4/data/logging.yaml +63 -0
  64. data/lib/gems/logging-0.9.4/data/simple_logging.rb +13 -0
  65. data/lib/gems/logging-0.9.4/lib/logging.rb +404 -0
  66. data/lib/gems/logging-0.9.4/lib/logging/appender.rb +300 -0
  67. data/lib/gems/logging-0.9.4/lib/logging/appenders/console.rb +62 -0
  68. data/lib/gems/logging-0.9.4/lib/logging/appenders/email.rb +130 -0
  69. data/lib/gems/logging-0.9.4/lib/logging/appenders/file.rb +54 -0
  70. data/lib/gems/logging-0.9.4/lib/logging/appenders/growl.rb +197 -0
  71. data/lib/gems/logging-0.9.4/lib/logging/appenders/io.rb +80 -0
  72. data/lib/gems/logging-0.9.4/lib/logging/appenders/rolling_file.rb +291 -0
  73. data/lib/gems/logging-0.9.4/lib/logging/appenders/syslog.rb +201 -0
  74. data/lib/gems/logging-0.9.4/lib/logging/config/configurator.rb +190 -0
  75. data/lib/gems/logging-0.9.4/lib/logging/config/yaml_configurator.rb +195 -0
  76. data/lib/gems/logging-0.9.4/lib/logging/layout.rb +110 -0
  77. data/lib/gems/logging-0.9.4/lib/logging/layouts/basic.rb +34 -0
  78. data/lib/gems/logging-0.9.4/lib/logging/layouts/pattern.rb +291 -0
  79. data/lib/gems/logging-0.9.4/lib/logging/log_event.rb +49 -0
  80. data/lib/gems/logging-0.9.4/lib/logging/logger.rb +490 -0
  81. data/lib/gems/logging-0.9.4/lib/logging/repository.rb +172 -0
  82. data/lib/gems/logging-0.9.4/lib/logging/root_logger.rb +61 -0
  83. data/lib/gems/logging-0.9.4/lib/logging/stats.rb +278 -0
  84. data/lib/gems/logging-0.9.4/lib/logging/utils.rb +130 -0
  85. data/lib/gems/rack-0.4.0/bin/rackup +172 -0
  86. data/lib/gems/rack-0.4.0/lib/rack.rb +81 -0
  87. data/lib/gems/rack-0.4.0/lib/rack/adapter/camping.rb +22 -0
  88. data/lib/gems/rack-0.4.0/lib/rack/auth/abstract/handler.rb +28 -0
  89. data/lib/gems/rack-0.4.0/lib/rack/auth/abstract/request.rb +37 -0
  90. data/lib/gems/rack-0.4.0/lib/rack/auth/basic.rb +58 -0
  91. data/lib/gems/rack-0.4.0/lib/rack/auth/digest/md5.rb +124 -0
  92. data/lib/gems/rack-0.4.0/lib/rack/auth/digest/nonce.rb +51 -0
  93. data/lib/gems/rack-0.4.0/lib/rack/auth/digest/params.rb +55 -0
  94. data/lib/gems/rack-0.4.0/lib/rack/auth/digest/request.rb +40 -0
  95. data/lib/gems/rack-0.4.0/lib/rack/auth/openid.rb +437 -0
  96. data/lib/gems/rack-0.4.0/lib/rack/builder.rb +56 -0
  97. data/lib/gems/rack-0.4.0/lib/rack/cascade.rb +36 -0
  98. data/lib/gems/rack-0.4.0/lib/rack/commonlogger.rb +61 -0
  99. data/lib/gems/rack-0.4.0/lib/rack/deflater.rb +63 -0
  100. data/lib/gems/rack-0.4.0/lib/rack/directory.rb +158 -0
  101. data/lib/gems/rack-0.4.0/lib/rack/file.rb +116 -0
  102. data/lib/gems/rack-0.4.0/lib/rack/handler.rb +44 -0
  103. data/lib/gems/rack-0.4.0/lib/rack/handler/cgi.rb +57 -0
  104. data/lib/gems/rack-0.4.0/lib/rack/handler/evented_mongrel.rb +8 -0
  105. data/lib/gems/rack-0.4.0/lib/rack/handler/fastcgi.rb +84 -0
  106. data/lib/gems/rack-0.4.0/lib/rack/handler/lsws.rb +52 -0
  107. data/lib/gems/rack-0.4.0/lib/rack/handler/mongrel.rb +78 -0
  108. data/lib/gems/rack-0.4.0/lib/rack/handler/scgi.rb +57 -0
  109. data/lib/gems/rack-0.4.0/lib/rack/handler/webrick.rb +57 -0
  110. data/lib/gems/rack-0.4.0/lib/rack/lint.rb +401 -0
  111. data/lib/gems/rack-0.4.0/lib/rack/lobster.rb +65 -0
  112. data/lib/gems/rack-0.4.0/lib/rack/mock.rb +160 -0
  113. data/lib/gems/rack-0.4.0/lib/rack/recursive.rb +57 -0
  114. data/lib/gems/rack-0.4.0/lib/rack/reloader.rb +64 -0
  115. data/lib/gems/rack-0.4.0/lib/rack/request.rb +209 -0
  116. data/lib/gems/rack-0.4.0/lib/rack/response.rb +166 -0
  117. data/lib/gems/rack-0.4.0/lib/rack/session/abstract/id.rb +140 -0
  118. data/lib/gems/rack-0.4.0/lib/rack/session/cookie.rb +71 -0
  119. data/lib/gems/rack-0.4.0/lib/rack/session/memcache.rb +97 -0
  120. data/lib/gems/rack-0.4.0/lib/rack/session/pool.rb +73 -0
  121. data/lib/gems/rack-0.4.0/lib/rack/showexceptions.rb +344 -0
  122. data/lib/gems/rack-0.4.0/lib/rack/showstatus.rb +105 -0
  123. data/lib/gems/rack-0.4.0/lib/rack/static.rb +38 -0
  124. data/lib/gems/rack-0.4.0/lib/rack/urlmap.rb +48 -0
  125. data/lib/gems/rack-0.4.0/lib/rack/utils.rb +318 -0
  126. data/lib/gems/rcov-0.8.1.2.0/bin/rcov +1327 -0
  127. data/lib/gems/rcov-0.8.1.2.0/ext/rcovrt/callsite.c +242 -0
  128. data/lib/gems/rcov-0.8.1.2.0/ext/rcovrt/extconf.rb +11 -0
  129. data/lib/gems/rcov-0.8.1.2.0/ext/rcovrt/rcovrt.c +329 -0
  130. data/lib/gems/rcov-0.8.1.2.0/lib/rcov.rb +988 -0
  131. data/lib/gems/rcov-0.8.1.2.0/lib/rcov/lowlevel.rb +147 -0
  132. data/lib/gems/rcov-0.8.1.2.0/lib/rcov/rant.rb +87 -0
  133. data/lib/gems/rcov-0.8.1.2.0/lib/rcov/rcovtask.rb +156 -0
  134. data/lib/gems/rcov-0.8.1.2.0/lib/rcov/report.rb +1236 -0
  135. data/lib/gems/rcov-0.8.1.2.0/lib/rcov/version.rb +13 -0
  136. data/lib/gems/rspec-1.1.11/bin/autospec +4 -0
  137. data/lib/gems/rspec-1.1.11/bin/spec +4 -0
  138. data/lib/gems/rspec-1.1.11/lib/autotest/discover.rb +3 -0
  139. data/lib/gems/rspec-1.1.11/lib/autotest/rspec.rb +46 -0
  140. data/lib/gems/rspec-1.1.11/lib/spec.rb +32 -0
  141. data/lib/gems/rspec-1.1.11/lib/spec/adapters.rb +1 -0
  142. data/lib/gems/rspec-1.1.11/lib/spec/adapters/ruby_engine.rb +26 -0
  143. data/lib/gems/rspec-1.1.11/lib/spec/adapters/ruby_engine/mri.rb +8 -0
  144. data/lib/gems/rspec-1.1.11/lib/spec/adapters/ruby_engine/rubinius.rb +8 -0
  145. data/lib/gems/rspec-1.1.11/lib/spec/example.rb +12 -0
  146. data/lib/gems/rspec-1.1.11/lib/spec/example/before_and_after_hooks.rb +93 -0
  147. data/lib/gems/rspec-1.1.11/lib/spec/example/configuration.rb +167 -0
  148. data/lib/gems/rspec-1.1.11/lib/spec/example/errors.rb +30 -0
  149. data/lib/gems/rspec-1.1.11/lib/spec/example/example_group.rb +25 -0
  150. data/lib/gems/rspec-1.1.11/lib/spec/example/example_group_factory.rb +81 -0
  151. data/lib/gems/rspec-1.1.11/lib/spec/example/example_group_methods.rb +368 -0
  152. data/lib/gems/rspec-1.1.11/lib/spec/example/example_matcher.rb +44 -0
  153. data/lib/gems/rspec-1.1.11/lib/spec/example/example_methods.rb +105 -0
  154. data/lib/gems/rspec-1.1.11/lib/spec/example/module_reopening_fix.rb +21 -0
  155. data/lib/gems/rspec-1.1.11/lib/spec/example/pending.rb +18 -0
  156. data/lib/gems/rspec-1.1.11/lib/spec/example/shared_example_group.rb +52 -0
  157. data/lib/gems/rspec-1.1.11/lib/spec/expectations.rb +56 -0
  158. data/lib/gems/rspec-1.1.11/lib/spec/expectations/differs/default.rb +66 -0
  159. data/lib/gems/rspec-1.1.11/lib/spec/expectations/errors.rb +12 -0
  160. data/lib/gems/rspec-1.1.11/lib/spec/expectations/extensions.rb +2 -0
  161. data/lib/gems/rspec-1.1.11/lib/spec/expectations/extensions/object.rb +63 -0
  162. data/lib/gems/rspec-1.1.11/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  163. data/lib/gems/rspec-1.1.11/lib/spec/expectations/handler.rb +52 -0
  164. data/lib/gems/rspec-1.1.11/lib/spec/extensions.rb +4 -0
  165. data/lib/gems/rspec-1.1.11/lib/spec/extensions/class.rb +24 -0
  166. data/lib/gems/rspec-1.1.11/lib/spec/extensions/main.rb +87 -0
  167. data/lib/gems/rspec-1.1.11/lib/spec/extensions/metaclass.rb +7 -0
  168. data/lib/gems/rspec-1.1.11/lib/spec/extensions/object.rb +6 -0
  169. data/lib/gems/rspec-1.1.11/lib/spec/interop/test.rb +12 -0
  170. data/lib/gems/rspec-1.1.11/lib/spec/interop/test/unit/autorunner.rb +6 -0
  171. data/lib/gems/rspec-1.1.11/lib/spec/interop/test/unit/testcase.rb +71 -0
  172. data/lib/gems/rspec-1.1.11/lib/spec/interop/test/unit/testresult.rb +6 -0
  173. data/lib/gems/rspec-1.1.11/lib/spec/interop/test/unit/testsuite_adapter.rb +34 -0
  174. data/lib/gems/rspec-1.1.11/lib/spec/interop/test/unit/ui/console/testrunner.rb +61 -0
  175. data/lib/gems/rspec-1.1.11/lib/spec/matchers.rb +162 -0
  176. data/lib/gems/rspec-1.1.11/lib/spec/matchers/be.rb +221 -0
  177. data/lib/gems/rspec-1.1.11/lib/spec/matchers/be_close.rb +37 -0
  178. data/lib/gems/rspec-1.1.11/lib/spec/matchers/change.rb +148 -0
  179. data/lib/gems/rspec-1.1.11/lib/spec/matchers/eql.rb +43 -0
  180. data/lib/gems/rspec-1.1.11/lib/spec/matchers/equal.rb +43 -0
  181. data/lib/gems/rspec-1.1.11/lib/spec/matchers/exist.rb +22 -0
  182. data/lib/gems/rspec-1.1.11/lib/spec/matchers/has.rb +34 -0
  183. data/lib/gems/rspec-1.1.11/lib/spec/matchers/have.rb +150 -0
  184. data/lib/gems/rspec-1.1.11/lib/spec/matchers/include.rb +77 -0
  185. data/lib/gems/rspec-1.1.11/lib/spec/matchers/match.rb +41 -0
  186. data/lib/gems/rspec-1.1.11/lib/spec/matchers/operator_matcher.rb +79 -0
  187. data/lib/gems/rspec-1.1.11/lib/spec/matchers/raise_error.rb +132 -0
  188. data/lib/gems/rspec-1.1.11/lib/spec/matchers/respond_to.rb +46 -0
  189. data/lib/gems/rspec-1.1.11/lib/spec/matchers/satisfy.rb +47 -0
  190. data/lib/gems/rspec-1.1.11/lib/spec/matchers/simple_matcher.rb +132 -0
  191. data/lib/gems/rspec-1.1.11/lib/spec/matchers/throw_symbol.rb +74 -0
  192. data/lib/gems/rspec-1.1.11/lib/spec/mocks.rb +200 -0
  193. data/lib/gems/rspec-1.1.11/lib/spec/mocks/argument_constraints.rb +165 -0
  194. data/lib/gems/rspec-1.1.11/lib/spec/mocks/argument_expectation.rb +49 -0
  195. data/lib/gems/rspec-1.1.11/lib/spec/mocks/error_generator.rb +84 -0
  196. data/lib/gems/rspec-1.1.11/lib/spec/mocks/errors.rb +10 -0
  197. data/lib/gems/rspec-1.1.11/lib/spec/mocks/extensions.rb +1 -0
  198. data/lib/gems/rspec-1.1.11/lib/spec/mocks/extensions/object.rb +3 -0
  199. data/lib/gems/rspec-1.1.11/lib/spec/mocks/framework.rb +15 -0
  200. data/lib/gems/rspec-1.1.11/lib/spec/mocks/message_expectation.rb +331 -0
  201. data/lib/gems/rspec-1.1.11/lib/spec/mocks/methods.rb +51 -0
  202. data/lib/gems/rspec-1.1.11/lib/spec/mocks/mock.rb +56 -0
  203. data/lib/gems/rspec-1.1.11/lib/spec/mocks/order_group.rb +29 -0
  204. data/lib/gems/rspec-1.1.11/lib/spec/mocks/proxy.rb +224 -0
  205. data/lib/gems/rspec-1.1.11/lib/spec/mocks/space.rb +28 -0
  206. data/lib/gems/rspec-1.1.11/lib/spec/mocks/spec_methods.rb +46 -0
  207. data/lib/gems/rspec-1.1.11/lib/spec/rake/spectask.rb +227 -0
  208. data/lib/gems/rspec-1.1.11/lib/spec/rake/verify_rcov.rb +52 -0
  209. data/lib/gems/rspec-1.1.11/lib/spec/runner.rb +213 -0
  210. data/lib/gems/rspec-1.1.11/lib/spec/runner/backtrace_tweaker.rb +56 -0
  211. data/lib/gems/rspec-1.1.11/lib/spec/runner/class_and_arguments_parser.rb +16 -0
  212. data/lib/gems/rspec-1.1.11/lib/spec/runner/command_line.rb +17 -0
  213. data/lib/gems/rspec-1.1.11/lib/spec/runner/drb_command_line.rb +20 -0
  214. data/lib/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb +59 -0
  215. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/base_formatter.rb +79 -0
  216. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/base_text_formatter.rb +126 -0
  217. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/failing_example_groups_formatter.rb +27 -0
  218. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/failing_examples_formatter.rb +20 -0
  219. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/html_formatter.rb +337 -0
  220. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/nested_text_formatter.rb +65 -0
  221. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/profile_formatter.rb +51 -0
  222. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/progress_bar_formatter.rb +34 -0
  223. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/snippet_extractor.rb +52 -0
  224. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/specdoc_formatter.rb +39 -0
  225. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/story/html_formatter.rb +174 -0
  226. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/story/plain_text_formatter.rb +194 -0
  227. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/story/progress_bar_formatter.rb +42 -0
  228. data/lib/gems/rspec-1.1.11/lib/spec/runner/formatter/text_mate_formatter.rb +16 -0
  229. data/lib/gems/rspec-1.1.11/lib/spec/runner/heckle_runner.rb +72 -0
  230. data/lib/gems/rspec-1.1.11/lib/spec/runner/heckle_runner_unsupported.rb +10 -0
  231. data/lib/gems/rspec-1.1.11/lib/spec/runner/option_parser.rb +205 -0
  232. data/lib/gems/rspec-1.1.11/lib/spec/runner/options.rb +320 -0
  233. data/lib/gems/rspec-1.1.11/lib/spec/runner/reporter.rb +167 -0
  234. data/lib/gems/rspec-1.1.11/lib/spec/runner/spec_parser.rb +71 -0
  235. data/lib/gems/rspec-1.1.11/lib/spec/story.rb +10 -0
  236. data/lib/gems/rspec-1.1.11/lib/spec/story/extensions.rb +3 -0
  237. data/lib/gems/rspec-1.1.11/lib/spec/story/extensions/main.rb +86 -0
  238. data/lib/gems/rspec-1.1.11/lib/spec/story/extensions/regexp.rb +9 -0
  239. data/lib/gems/rspec-1.1.11/lib/spec/story/extensions/string.rb +9 -0
  240. data/lib/gems/rspec-1.1.11/lib/spec/story/given_scenario.rb +14 -0
  241. data/lib/gems/rspec-1.1.11/lib/spec/story/runner.rb +59 -0
  242. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/plain_text_story_runner.rb +48 -0
  243. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/scenario_collector.rb +18 -0
  244. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/scenario_runner.rb +54 -0
  245. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/story_mediator.rb +137 -0
  246. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/story_parser.rb +247 -0
  247. data/lib/gems/rspec-1.1.11/lib/spec/story/runner/story_runner.rb +70 -0
  248. data/lib/gems/rspec-1.1.11/lib/spec/story/scenario.rb +14 -0
  249. data/lib/gems/rspec-1.1.11/lib/spec/story/step.rb +70 -0
  250. data/lib/gems/rspec-1.1.11/lib/spec/story/step_group.rb +89 -0
  251. data/lib/gems/rspec-1.1.11/lib/spec/story/step_mother.rb +38 -0
  252. data/lib/gems/rspec-1.1.11/lib/spec/story/story.rb +39 -0
  253. data/lib/gems/rspec-1.1.11/lib/spec/story/world.rb +128 -0
  254. data/lib/gems/rspec-1.1.11/lib/spec/version.rb +13 -0
  255. data/lib/gems/rspec-1.1.11/plugins/mock_frameworks/flexmock.rb +23 -0
  256. data/lib/gems/rspec-1.1.11/plugins/mock_frameworks/mocha.rb +19 -0
  257. data/lib/gems/rspec-1.1.11/plugins/mock_frameworks/rr.rb +21 -0
  258. data/lib/gems/rspec-1.1.11/plugins/mock_frameworks/rspec.rb +20 -0
  259. data/lib/gems/rspec-1.1.11/rake_tasks/examples.rake +7 -0
  260. data/lib/gems/rspec-1.1.11/rake_tasks/examples_with_rcov.rake +9 -0
  261. data/lib/gems/rspec-1.1.11/rake_tasks/failing_examples_with_html.rake +9 -0
  262. data/lib/gems/rspec-1.1.11/rake_tasks/verify_rcov.rake +7 -0
  263. data/lib/gems/rspec-1.1.11/spec/README.jruby +15 -0
  264. data/lib/gems/rspec-1.1.11/spec/autotest/autotest_helper.rb +6 -0
  265. data/lib/gems/rspec-1.1.11/spec/autotest/autotest_matchers.rb +47 -0
  266. data/lib/gems/rspec-1.1.11/spec/autotest/discover_spec.rb +19 -0
  267. data/lib/gems/rspec-1.1.11/spec/autotest/rspec_spec.rb +150 -0
  268. data/lib/gems/rspec-1.1.11/spec/rspec_suite.rb +6 -0
  269. data/lib/gems/rspec-1.1.11/spec/ruby_forker.rb +13 -0
  270. data/lib/gems/rspec-1.1.11/spec/spec.opts +6 -0
  271. data/lib/gems/rspec-1.1.11/spec/spec/adapters/ruby_engine_spec.rb +16 -0
  272. data/lib/gems/rspec-1.1.11/spec/spec/example/configuration_spec.rb +296 -0
  273. data/lib/gems/rspec-1.1.11/spec/spec/example/example_group_class_definition_spec.rb +48 -0
  274. data/lib/gems/rspec-1.1.11/spec/spec/example/example_group_factory_spec.rb +165 -0
  275. data/lib/gems/rspec-1.1.11/spec/spec/example/example_group_methods_spec.rb +584 -0
  276. data/lib/gems/rspec-1.1.11/spec/spec/example/example_group_spec.rb +683 -0
  277. data/lib/gems/rspec-1.1.11/spec/spec/example/example_matcher_spec.rb +96 -0
  278. data/lib/gems/rspec-1.1.11/spec/spec/example/example_methods_spec.rb +169 -0
  279. data/lib/gems/rspec-1.1.11/spec/spec/example/example_runner_spec.rb +194 -0
  280. data/lib/gems/rspec-1.1.11/spec/spec/example/nested_example_group_spec.rb +71 -0
  281. data/lib/gems/rspec-1.1.11/spec/spec/example/pending_module_spec.rb +145 -0
  282. data/lib/gems/rspec-1.1.11/spec/spec/example/predicate_matcher_spec.rb +21 -0
  283. data/lib/gems/rspec-1.1.11/spec/spec/example/shared_example_group_spec.rb +281 -0
  284. data/lib/gems/rspec-1.1.11/spec/spec/example/subclassing_example_group_spec.rb +25 -0
  285. data/lib/gems/rspec-1.1.11/spec/spec/expectations/differs/default_spec.rb +127 -0
  286. data/lib/gems/rspec-1.1.11/spec/spec/expectations/extensions/object_spec.rb +95 -0
  287. data/lib/gems/rspec-1.1.11/spec/spec/expectations/fail_with_spec.rb +71 -0
  288. data/lib/gems/rspec-1.1.11/spec/spec/extensions/main_spec.rb +71 -0
  289. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/spec_that_fails.rb +10 -0
  290. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/spec_that_passes.rb +10 -0
  291. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/spec_with_errors.rb +10 -0
  292. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/spec_with_options_hash.rb +13 -0
  293. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/test_case_that_fails.rb +10 -0
  294. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/test_case_that_passes.rb +10 -0
  295. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/test_case_with_errors.rb +10 -0
  296. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb +38 -0
  297. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/spec_spec.rb +52 -0
  298. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/test_unit_spec_helper.rb +14 -0
  299. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/testcase_spec.rb +49 -0
  300. data/lib/gems/rspec-1.1.11/spec/spec/interop/test/unit/testsuite_adapter_spec.rb +9 -0
  301. data/lib/gems/rspec-1.1.11/spec/spec/matchers/be_close_spec.rb +39 -0
  302. data/lib/gems/rspec-1.1.11/spec/spec/matchers/be_spec.rb +248 -0
  303. data/lib/gems/rspec-1.1.11/spec/spec/matchers/change_spec.rb +329 -0
  304. data/lib/gems/rspec-1.1.11/spec/spec/matchers/description_generation_spec.rb +153 -0
  305. data/lib/gems/rspec-1.1.11/spec/spec/matchers/eql_spec.rb +28 -0
  306. data/lib/gems/rspec-1.1.11/spec/spec/matchers/equal_spec.rb +28 -0
  307. data/lib/gems/rspec-1.1.11/spec/spec/matchers/exist_spec.rb +57 -0
  308. data/lib/gems/rspec-1.1.11/spec/spec/matchers/handler_spec.rb +150 -0
  309. data/lib/gems/rspec-1.1.11/spec/spec/matchers/has_spec.rb +63 -0
  310. data/lib/gems/rspec-1.1.11/spec/spec/matchers/have_spec.rb +394 -0
  311. data/lib/gems/rspec-1.1.11/spec/spec/matchers/include_spec.rb +64 -0
  312. data/lib/gems/rspec-1.1.11/spec/spec/matchers/match_spec.rb +37 -0
  313. data/lib/gems/rspec-1.1.11/spec/spec/matchers/matcher_methods_spec.rb +78 -0
  314. data/lib/gems/rspec-1.1.11/spec/spec/matchers/mock_constraint_matchers_spec.rb +24 -0
  315. data/lib/gems/rspec-1.1.11/spec/spec/matchers/operator_matcher_spec.rb +191 -0
  316. data/lib/gems/rspec-1.1.11/spec/spec/matchers/raise_error_spec.rb +315 -0
  317. data/lib/gems/rspec-1.1.11/spec/spec/matchers/respond_to_spec.rb +54 -0
  318. data/lib/gems/rspec-1.1.11/spec/spec/matchers/satisfy_spec.rb +36 -0
  319. data/lib/gems/rspec-1.1.11/spec/spec/matchers/simple_matcher_spec.rb +93 -0
  320. data/lib/gems/rspec-1.1.11/spec/spec/matchers/throw_symbol_spec.rb +54 -0
  321. data/lib/gems/rspec-1.1.11/spec/spec/mocks/any_number_of_times_spec.rb +36 -0
  322. data/lib/gems/rspec-1.1.11/spec/spec/mocks/argument_expectation_spec.rb +23 -0
  323. data/lib/gems/rspec-1.1.11/spec/spec/mocks/at_least_spec.rb +97 -0
  324. data/lib/gems/rspec-1.1.11/spec/spec/mocks/at_most_spec.rb +93 -0
  325. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_10260_spec.rb +8 -0
  326. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_10263_spec.rb +24 -0
  327. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_11545_spec.rb +33 -0
  328. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_15719_spec.rb +30 -0
  329. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_496.rb +17 -0
  330. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_7611_spec.rb +19 -0
  331. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_7805_spec.rb +22 -0
  332. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_8165_spec.rb +31 -0
  333. data/lib/gems/rspec-1.1.11/spec/spec/mocks/bug_report_8302_spec.rb +26 -0
  334. data/lib/gems/rspec-1.1.11/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +95 -0
  335. data/lib/gems/rspec-1.1.11/spec/spec/mocks/hash_including_matcher_spec.rb +53 -0
  336. data/lib/gems/rspec-1.1.11/spec/spec/mocks/mock_ordering_spec.rb +84 -0
  337. data/lib/gems/rspec-1.1.11/spec/spec/mocks/mock_space_spec.rb +54 -0
  338. data/lib/gems/rspec-1.1.11/spec/spec/mocks/mock_spec.rb +555 -0
  339. data/lib/gems/rspec-1.1.11/spec/spec/mocks/multiple_return_value_spec.rb +113 -0
  340. data/lib/gems/rspec-1.1.11/spec/spec/mocks/nil_expectation_warning_spec.rb +53 -0
  341. data/lib/gems/rspec-1.1.11/spec/spec/mocks/null_object_mock_spec.rb +54 -0
  342. data/lib/gems/rspec-1.1.11/spec/spec/mocks/once_counts_spec.rb +53 -0
  343. data/lib/gems/rspec-1.1.11/spec/spec/mocks/options_hash_spec.rb +35 -0
  344. data/lib/gems/rspec-1.1.11/spec/spec/mocks/partial_mock_spec.rb +149 -0
  345. data/lib/gems/rspec-1.1.11/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +66 -0
  346. data/lib/gems/rspec-1.1.11/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +130 -0
  347. data/lib/gems/rspec-1.1.11/spec/spec/mocks/precise_counts_spec.rb +52 -0
  348. data/lib/gems/rspec-1.1.11/spec/spec/mocks/record_messages_spec.rb +26 -0
  349. data/lib/gems/rspec-1.1.11/spec/spec/mocks/stub_spec.rb +188 -0
  350. data/lib/gems/rspec-1.1.11/spec/spec/mocks/twice_counts_spec.rb +67 -0
  351. data/lib/gems/rspec-1.1.11/spec/spec/package/bin_spec_spec.rb +22 -0
  352. data/lib/gems/rspec-1.1.11/spec/spec/runner/class_and_argument_parser_spec.rb +23 -0
  353. data/lib/gems/rspec-1.1.11/spec/spec/runner/command_line_spec.rb +141 -0
  354. data/lib/gems/rspec-1.1.11/spec/spec/runner/drb_command_line_spec.rb +97 -0
  355. data/lib/gems/rspec-1.1.11/spec/spec/runner/empty_file.txt +0 -0
  356. data/lib/gems/rspec-1.1.11/spec/spec/runner/examples.txt +2 -0
  357. data/lib/gems/rspec-1.1.11/spec/spec/runner/failed.txt +3 -0
  358. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/base_formatter_spec.rb +112 -0
  359. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +45 -0
  360. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +33 -0
  361. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatted-1.8.4.html +365 -0
  362. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +387 -0
  363. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatted-1.8.5.html +371 -0
  364. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +381 -0
  365. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatted-1.8.6.html +370 -0
  366. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/html_formatter_spec.rb +61 -0
  367. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/nested_text_formatter_spec.rb +318 -0
  368. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/profile_formatter_spec.rb +65 -0
  369. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +155 -0
  370. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/snippet_extractor_spec.rb +18 -0
  371. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +103 -0
  372. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/specdoc_formatter_spec.rb +159 -0
  373. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/story/html_formatter_spec.rb +135 -0
  374. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +600 -0
  375. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/story/progress_bar_formatter_spec.rb +82 -0
  376. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +365 -0
  377. data/lib/gems/rspec-1.1.11/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +370 -0
  378. data/lib/gems/rspec-1.1.11/spec/spec/runner/heckle_runner_spec.rb +78 -0
  379. data/lib/gems/rspec-1.1.11/spec/spec/runner/heckler_spec.rb +13 -0
  380. data/lib/gems/rspec-1.1.11/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +45 -0
  381. data/lib/gems/rspec-1.1.11/spec/spec/runner/option_parser_spec.rb +421 -0
  382. data/lib/gems/rspec-1.1.11/spec/spec/runner/options_spec.rb +450 -0
  383. data/lib/gems/rspec-1.1.11/spec/spec/runner/output_one_time_fixture.rb +7 -0
  384. data/lib/gems/rspec-1.1.11/spec/spec/runner/output_one_time_fixture_runner.rb +8 -0
  385. data/lib/gems/rspec-1.1.11/spec/spec/runner/output_one_time_spec.rb +16 -0
  386. data/lib/gems/rspec-1.1.11/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +62 -0
  387. data/lib/gems/rspec-1.1.11/spec/spec/runner/reporter_spec.rb +238 -0
  388. data/lib/gems/rspec-1.1.11/spec/spec/runner/resources/a_bar.rb +0 -0
  389. data/lib/gems/rspec-1.1.11/spec/spec/runner/resources/a_foo.rb +0 -0
  390. data/lib/gems/rspec-1.1.11/spec/spec/runner/resources/a_spec.rb +1 -0
  391. data/lib/gems/rspec-1.1.11/spec/spec/runner/spec.opts +2 -0
  392. data/lib/gems/rspec-1.1.11/spec/spec/runner/spec_drb.opts +1 -0
  393. data/lib/gems/rspec-1.1.11/spec/spec/runner/spec_parser/spec_parser_fixture.rb +70 -0
  394. data/lib/gems/rspec-1.1.11/spec/spec/runner/spec_parser_spec.rb +85 -0
  395. data/lib/gems/rspec-1.1.11/spec/spec/runner/spec_spaced.opts +2 -0
  396. data/lib/gems/rspec-1.1.11/spec/spec/runner_spec.rb +11 -0
  397. data/lib/gems/rspec-1.1.11/spec/spec/spec_classes.rb +133 -0
  398. data/lib/gems/rspec-1.1.11/spec/spec/story/builders.rb +46 -0
  399. data/lib/gems/rspec-1.1.11/spec/spec/story/extensions/main_spec.rb +161 -0
  400. data/lib/gems/rspec-1.1.11/spec/spec/story/extensions_spec.rb +14 -0
  401. data/lib/gems/rspec-1.1.11/spec/spec/story/given_scenario_spec.rb +27 -0
  402. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/plain_text_story_runner_spec.rb +90 -0
  403. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/scenario_collector_spec.rb +27 -0
  404. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/scenario_runner_spec.rb +214 -0
  405. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/story_mediator_spec.rb +143 -0
  406. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/story_parser_spec.rb +401 -0
  407. data/lib/gems/rspec-1.1.11/spec/spec/story/runner/story_runner_spec.rb +294 -0
  408. data/lib/gems/rspec-1.1.11/spec/spec/story/runner_spec.rb +93 -0
  409. data/lib/gems/rspec-1.1.11/spec/spec/story/scenario_spec.rb +18 -0
  410. data/lib/gems/rspec-1.1.11/spec/spec/story/step_group_spec.rb +157 -0
  411. data/lib/gems/rspec-1.1.11/spec/spec/story/step_mother_spec.rb +84 -0
  412. data/lib/gems/rspec-1.1.11/spec/spec/story/step_spec.rb +272 -0
  413. data/lib/gems/rspec-1.1.11/spec/spec/story/story_helper.rb +2 -0
  414. data/lib/gems/rspec-1.1.11/spec/spec/story/story_spec.rb +84 -0
  415. data/lib/gems/rspec-1.1.11/spec/spec/story/world_spec.rb +423 -0
  416. data/lib/gems/rspec-1.1.11/spec/spec_helper.rb +77 -0
  417. data/lib/gems/rspec-1.1.11/stories/all.rb +5 -0
  418. data/lib/gems/rspec-1.1.11/stories/configuration/before_blocks.story +21 -0
  419. data/lib/gems/rspec-1.1.11/stories/configuration/stories.rb +7 -0
  420. data/lib/gems/rspec-1.1.11/stories/example_groups/autogenerated_docstrings +45 -0
  421. data/lib/gems/rspec-1.1.11/stories/example_groups/example_group_with_should_methods +17 -0
  422. data/lib/gems/rspec-1.1.11/stories/example_groups/nested_groups +17 -0
  423. data/lib/gems/rspec-1.1.11/stories/example_groups/output +25 -0
  424. data/lib/gems/rspec-1.1.11/stories/example_groups/stories.rb +7 -0
  425. data/lib/gems/rspec-1.1.11/stories/helper.rb +6 -0
  426. data/lib/gems/rspec-1.1.11/stories/interop/examples_and_tests_together +30 -0
  427. data/lib/gems/rspec-1.1.11/stories/interop/stories.rb +7 -0
  428. data/lib/gems/rspec-1.1.11/stories/interop/test_case_with_should_methods +17 -0
  429. data/lib/gems/rspec-1.1.11/stories/mock_framework_integration/stories.rb +7 -0
  430. data/lib/gems/rspec-1.1.11/stories/mock_framework_integration/use_flexmock.story +9 -0
  431. data/lib/gems/rspec-1.1.11/stories/pending_stories/README +3 -0
  432. data/lib/gems/rspec-1.1.11/stories/resources/helpers/cmdline.rb +9 -0
  433. data/lib/gems/rspec-1.1.11/stories/resources/helpers/story_helper.rb +16 -0
  434. data/lib/gems/rspec-1.1.11/stories/resources/matchers/smart_match.rb +37 -0
  435. data/lib/gems/rspec-1.1.11/stories/resources/spec/before_blocks_example.rb +32 -0
  436. data/lib/gems/rspec-1.1.11/stories/resources/spec/example_group_with_should_methods.rb +12 -0
  437. data/lib/gems/rspec-1.1.11/stories/resources/spec/simple_spec.rb +8 -0
  438. data/lib/gems/rspec-1.1.11/stories/resources/spec/spec_with_flexmock.rb +18 -0
  439. data/lib/gems/rspec-1.1.11/stories/resources/steps/running_rspec.rb +50 -0
  440. data/lib/gems/rspec-1.1.11/stories/resources/stories/failing_story.rb +15 -0
  441. data/lib/gems/rspec-1.1.11/stories/resources/test/spec_and_test_together.rb +57 -0
  442. data/lib/gems/rspec-1.1.11/stories/resources/test/test_case_with_should_methods.rb +30 -0
  443. data/lib/gems/rspec-1.1.11/stories/stories/multiline_steps.story +23 -0
  444. data/lib/gems/rspec-1.1.11/stories/stories/steps/multiline_steps.rb +13 -0
  445. data/lib/gems/rspec-1.1.11/stories/stories/stories.rb +6 -0
  446. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/builder.js +136 -0
  447. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/controls.js +972 -0
  448. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/dragdrop.js +976 -0
  449. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/effects.js +1117 -0
  450. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/prototype.js +4140 -0
  451. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/rspec.js +149 -0
  452. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/scriptaculous.js +58 -0
  453. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/slider.js +276 -0
  454. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/sound.js +55 -0
  455. data/lib/gems/rspec-1.1.11/story_server/prototype/javascripts/unittest.js +568 -0
  456. data/lib/gems/rspec-1.1.11/story_server/prototype/lib/server.rb +24 -0
  457. data/lib/gems/rspec-1.1.11/story_server/prototype/stories.html +176 -0
  458. data/lib/gems/rspec-1.1.11/story_server/prototype/stylesheets/rspec.css +136 -0
  459. data/lib/gems/rspec-1.1.11/story_server/prototype/stylesheets/test.css +90 -0
  460. data/lib/mack/boot/configuration.rb +2 -0
  461. data/lib/mack/boot/console.rb +2 -0
  462. data/lib/mack/boot/gems.rb +6 -1
  463. data/lib/mack/boot/logging.rb +1 -1
  464. data/lib/mack/controller/request.rb +2 -55
  465. data/lib/mack/controller/request/date_time_parameter.rb +37 -0
  466. data/lib/mack/controller/request/parameters.rb +31 -0
  467. data/lib/mack/core_extensions/gem_kernel.rb +30 -0
  468. data/lib/mack/core_extensions/kernel.rb +31 -14
  469. data/lib/mack/routing/route_map.rb +19 -18
  470. data/lib/mack/routing/route_object.rb +14 -3
  471. data/lib/mack/routing/routes.rb +4 -0
  472. data/lib/mack/runner.rb +11 -0
  473. data/lib/mack/version.rb +1 -1
  474. data/lib/mack_app.rb +1 -26
  475. data/lib/mack_core.rb +2 -50
  476. data/lib/mack_tasks.rb +1 -32
  477. metadata +669 -90
@@ -0,0 +1,147 @@
1
+ # rcov Copyright (c) 2004-2006 Mauricio Fernandez <mfp@acm.org>
2
+ #
3
+ # See LEGAL and LICENSE for licensing information.
4
+
5
+ require 'rcov/version'
6
+
7
+ module Rcov
8
+
9
+ # RCOV__ performs the low-level tracing of the execution, gathering code
10
+ # coverage information in the process. The C core made available through the
11
+ # rcovrt extension will be used if possible. Otherwise the functionality
12
+ # will be emulated using set_trace_func, but this is very expensive and
13
+ # will fail if other libraries (e.g. breakpoint) change the trace_func.
14
+ #
15
+ # Do not use this module; it is very low-level and subject to frequent
16
+ # changes. Rcov::CodeCoverageAnalyzer offers a much more convenient and
17
+ # stable interface.
18
+ module RCOV__
19
+ COVER = {}
20
+ CALLSITES = {}
21
+ DEFSITES = {}
22
+ pure_ruby_impl_needed = true
23
+ unless defined? $rcov_do_not_use_rcovrt
24
+ begin
25
+ require 'rcovrt'
26
+ abi = [0,0,0]
27
+ begin
28
+ abi = RCOV__.ABI
29
+ raise if abi[0] != RCOVRT_ABI[0] || abi[1] < RCOVRT_ABI[1]
30
+ pure_ruby_impl_needed = false
31
+ rescue
32
+ $stderr.puts <<-EOF
33
+ The rcovrt extension I found was built for a different version of rcov.
34
+ The required ABI is: #{RCOVRT_ABI.join(".")}
35
+ Your current rcovrt extension is: #{abi.join(".")}
36
+
37
+ Please delete rcovrt.{so,bundle,dll,...} and install the required one.
38
+ EOF
39
+ raise LoadError
40
+ end
41
+ rescue LoadError
42
+ $stderr.puts <<-EOF
43
+
44
+ Since the rcovrt extension couldn't be loaded, rcov will run in pure-Ruby
45
+ mode, which is about two orders of magnitude slower.
46
+
47
+ If you're on win32, you can find a pre-built extension (usable with recent
48
+ One Click Installer and mswin32 builds) at http://eigenclass.org/hiki.rb?rcov .
49
+
50
+ EOF
51
+ end
52
+ end
53
+
54
+ if pure_ruby_impl_needed
55
+ methods = %w[install_coverage_hook remove_coverage_hook reset_coverage
56
+ install_callsite_hook remove_callsite_hook reset_callsite
57
+ generate_coverage_info generate_callsite_info]
58
+ sklass = class << self; self end
59
+ (methods & sklass.instance_methods).each do |meth|
60
+ sklass.class_eval{ remove_method meth }
61
+ end
62
+
63
+ @coverage_hook_activated = @callsite_hook_activated = false
64
+
65
+ def self.install_coverage_hook # :nodoc:
66
+ install_common_hook
67
+ @coverage_hook_activated = true
68
+ end
69
+
70
+ def self.install_callsite_hook # :nodoc:
71
+ install_common_hook
72
+ @callsite_hook_activated = true
73
+ end
74
+
75
+ def self.install_common_hook # :nodoc:
76
+ set_trace_func lambda {|event, file, line, id, binding, klass|
77
+ next unless SCRIPT_LINES__.has_key? file
78
+ case event
79
+ when 'call'
80
+ if @callsite_hook_activated
81
+ receiver = eval("self", binding)
82
+ klass = class << klass; self end unless klass === receiver
83
+ begin
84
+ DEFSITES[[klass.to_s, id.to_s]] = [file, line]
85
+ rescue Exception
86
+ end
87
+ caller_arr = self.format_backtrace_array(caller[1,1])
88
+ begin
89
+ hash = CALLSITES[[klass.to_s, id.to_s]] ||= {}
90
+ hash[caller_arr] ||= 0
91
+ hash[caller_arr] += 1
92
+ #puts "#{event} #{file} #{line} #{klass.inspect} " +
93
+ # "#{klass.object_id} #{id} #{eval('self', binding)}"
94
+ rescue Exception
95
+ end
96
+ end
97
+ when 'c-call', 'c-return', 'class'
98
+ return
99
+ end
100
+ if @coverage_hook_activated
101
+ COVER[file] ||= Array.new(SCRIPT_LINES__[file].size, 0)
102
+ COVER[file][line - 1] ||= 0
103
+ COVER[file][line - 1] += 1
104
+ end
105
+ }
106
+ end
107
+
108
+ def self.remove_coverage_hook # :nodoc:
109
+ @coverage_hook_activated = false
110
+ set_trace_func(nil) if !@callsite_hook_activated
111
+ end
112
+
113
+ def self.remove_callsite_hook # :nodoc:
114
+ @callsite_hook_activated = false
115
+ set_trace_func(nil) if !@coverage_hook_activated
116
+ end
117
+
118
+ def self.reset_coverage # :nodoc:
119
+ COVER.replace({})
120
+ end
121
+
122
+ def self.reset_callsite # :nodoc:
123
+ CALLSITES.replace({})
124
+ DEFSITES.replace({})
125
+ end
126
+
127
+ def self.generate_coverage_info # :nodoc:
128
+ Marshal.load(Marshal.dump(COVER))
129
+ end
130
+
131
+ def self.generate_callsite_info # :nodoc:
132
+ [CALLSITES, DEFSITES]
133
+ end
134
+
135
+ def self.format_backtrace_array(backtrace)
136
+ backtrace.map do |line|
137
+ md = /^([^:]*)(?::(\d+)(?::in `(.*)'))?/.match(line)
138
+ raise "Bad backtrace format" unless md
139
+ [nil, md[3] ? md[3].to_sym : nil, md[1], (md[2] || '').to_i]
140
+ end
141
+ end
142
+ end
143
+ end # RCOV__
144
+
145
+ end # Rcov
146
+
147
+ # vi: set sw=2:
@@ -0,0 +1,87 @@
1
+
2
+ require 'rant/rantlib'
3
+
4
+ module Rant # :nodoc:
5
+ module Generators # :nodoc:
6
+ class Rcov # :nodoc:
7
+ def self.rant_gen(app, ch, args, &block)
8
+ if !args || args.empty?
9
+ self.new(app, ch, &block)
10
+ elsif args.size == 1
11
+ name, pre = app.normalize_task_arg(args.first, ch)
12
+ self.new(app, ch, name, pre, &block)
13
+ else
14
+ app.abort_at(ch,
15
+ "Rcov takes only one additional argument, " +
16
+ "which should be like one given to the `task' command.")
17
+ end
18
+ end
19
+
20
+ attr_accessor :verbose
21
+ attr_accessor :libs
22
+ attr_accessor :test_dirs
23
+ attr_accessor :pattern
24
+ attr_accessor :test_files
25
+ attr_accessor :rcov_opts
26
+ # Directory where to put the generated XHTML reports
27
+ attr_accessor :output_dir
28
+
29
+ def initialize(app, cinf, name = :rcov, prerequisites = [], &block)
30
+ @rac = app
31
+ @name = name
32
+ @pre = prerequisites
33
+ #@block = block
34
+ @verbose = nil
35
+ cf = cinf[:file]
36
+ @libs = []
37
+ libdir = File.join(File.dirname(File.expand_path(cf)), 'lib')
38
+ @libs << libdir if test(?d, libdir)
39
+ @rcov_opts = ["--text-report"]
40
+ @test_dirs = []
41
+ @pattern = nil
42
+ @test_files = nil
43
+ yield self if block_given?
44
+ @pattern = "test*.rb" if @pattern.nil? && @test_files.nil?
45
+ @output_dir ||= "coverage"
46
+
47
+ @pre ||= []
48
+ # define the task
49
+ app.task(:__caller__ => cinf, @name => @pre) { |t|
50
+ args = []
51
+ if @libs && !@libs.empty?
52
+ args << "-I#{@libs.join File::PATH_SEPARATOR}"
53
+ end
54
+ if rcov_path = ENV['RCOVPATH']
55
+ args << rcov_path
56
+ else
57
+ args << "-S" << "rcov"
58
+ end
59
+ args.concat rcov_opts
60
+ args << "-o" << @output_dir
61
+ if test(?d, "test")
62
+ @test_dirs << "test"
63
+ elsif test(?d, "tests")
64
+ @test_dirs << "tests"
65
+ end
66
+ args.concat filelist
67
+ app.context.sys.ruby args
68
+ }
69
+ end
70
+
71
+ def filelist
72
+ return @rac.sys[@rac.var['TEST']] if @rac.var['TEST']
73
+ filelist = @test_files || []
74
+ if filelist.empty?
75
+ if @test_dirs && !@test_dirs.empty?
76
+ @test_dirs.each { |dir|
77
+ filelist.concat(@rac.sys[File.join(dir, @pattern)])
78
+ }
79
+ else
80
+ filelist.concat(@rac.sys[@pattern]) if @pattern
81
+ end
82
+ end
83
+ filelist
84
+ end
85
+ end # class Rcov
86
+ end # module Generators
87
+ end # module Rant
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Define a task library for performing code coverage analysis of unit tests
4
+ # using rcov.
5
+
6
+ require 'rake'
7
+ require 'rake/tasklib'
8
+
9
+ module Rcov
10
+
11
+ # Create a task that runs a set of tests through rcov, generating code
12
+ # coverage reports.
13
+ #
14
+ # Example:
15
+ #
16
+ # require 'rcov/rcovtask'
17
+ #
18
+ # Rcov::RcovTask.new do |t|
19
+ # t.libs << "test"
20
+ # t.test_files = FileList['test/test*.rb']
21
+ # t.verbose = true
22
+ # end
23
+ #
24
+ # If rake is invoked with a "TEST=filename" command line option,
25
+ # then the list of test files will be overridden to include only the
26
+ # filename specified on the command line. This provides an easy way
27
+ # to run just one test.
28
+ #
29
+ # If rake is invoked with a "RCOVOPTS=options" command line option,
30
+ # then the given options are passed to rcov.
31
+ #
32
+ # If rake is invoked with a "RCOVPATH=path/to/rcov" command line option,
33
+ # then the given rcov executable will be used; otherwise the one in your
34
+ # PATH will be used.
35
+ #
36
+ # Examples:
37
+ #
38
+ # rake rcov # run tests normally
39
+ # rake rcov TEST=just_one_file.rb # run just one test file.
40
+ # rake rcov RCOVOPTS="-p" # run in profile mode
41
+ # rake rcov RCOVOPTS="-T" # generate text report
42
+ #
43
+ class RcovTask < Rake::TaskLib
44
+
45
+ # Name of test task. (default is :rcov)
46
+ attr_accessor :name
47
+
48
+ # List of directories to added to $LOAD_PATH before running the
49
+ # tests. (default is 'lib')
50
+ attr_accessor :libs
51
+
52
+ # True if verbose test output desired. (default is false)
53
+ attr_accessor :verbose
54
+
55
+ # Request that the tests be run with the warning flag set.
56
+ # E.g. warning=true implies "ruby -w" used to run the tests.
57
+ attr_accessor :warning
58
+
59
+ # Glob pattern to match test files. (default is 'test/test*.rb')
60
+ attr_accessor :pattern
61
+
62
+ # Array of commandline options to pass to ruby when running the rcov loader.
63
+ attr_accessor :ruby_opts
64
+
65
+ # Array of commandline options to pass to rcov. An explicit
66
+ # RCOVOPTS=opts on the command line will override this. (default
67
+ # is <tt>["--text-report"]</tt>)
68
+ attr_accessor :rcov_opts
69
+
70
+ # Output directory for the XHTML report.
71
+ attr_accessor :output_dir
72
+
73
+ # Explicitly define the list of test files to be included in a
74
+ # test. +list+ is expected to be an array of file names (a
75
+ # FileList is acceptable). If both +pattern+ and +test_files+ are
76
+ # used, then the list of test files is the union of the two.
77
+ def test_files=(list)
78
+ @test_files = list
79
+ end
80
+
81
+ # Create a testing task.
82
+ def initialize(name=:rcov)
83
+ @name = name
84
+ @libs = ["lib"]
85
+ @pattern = nil
86
+ @test_files = nil
87
+ @verbose = false
88
+ @warning = false
89
+ @rcov_opts = ["--text-report"]
90
+ @ruby_opts = []
91
+ @output_dir = "coverage"
92
+ yield self if block_given?
93
+ @pattern = 'test/test*.rb' if @pattern.nil? && @test_files.nil?
94
+ define
95
+ end
96
+
97
+ # Create the tasks defined by this task lib.
98
+ def define
99
+ lib_path = @libs.join(File::PATH_SEPARATOR)
100
+ actual_name = Hash === name ? name.keys.first : name
101
+ unless Rake.application.last_comment
102
+ desc "Analyze code coverage with tests" +
103
+ (@name==:rcov ? "" : " for #{actual_name}")
104
+ end
105
+ task @name do
106
+ run_code = ''
107
+ RakeFileUtils.verbose(@verbose) do
108
+ run_code =
109
+ case rcov_path
110
+ when nil, ''
111
+ "-S rcov"
112
+ else %!"#{rcov_path}"!
113
+ end
114
+ ruby_opts = @ruby_opts.clone
115
+ ruby_opts.push( "-I#{lib_path}" )
116
+ ruby_opts.push run_code
117
+ ruby_opts.push( "-w" ) if @warning
118
+ ruby ruby_opts.join(" ") + " " + option_list +
119
+ %[ -o "#{@output_dir}" ] +
120
+ file_list.collect { |fn| %["#{fn}"] }.join(' ')
121
+ end
122
+ end
123
+
124
+ desc "Remove rcov products for #{actual_name}"
125
+ task paste("clobber_", actual_name) do
126
+ rm_r @output_dir rescue nil
127
+ end
128
+
129
+ clobber_task = paste("clobber_", actual_name)
130
+ task :clobber => [clobber_task]
131
+
132
+ task actual_name => clobber_task
133
+ self
134
+ end
135
+
136
+ def rcov_path # :nodoc:
137
+ ENV['RCOVPATH']
138
+ end
139
+
140
+ def option_list # :nodoc:
141
+ ENV['RCOVOPTS'] || @rcov_opts.join(" ") || ""
142
+ end
143
+
144
+ def file_list # :nodoc:
145
+ if ENV['TEST']
146
+ FileList[ ENV['TEST'] ]
147
+ else
148
+ result = []
149
+ result += @test_files.to_a if @test_files
150
+ result += FileList[ @pattern ].to_a if @pattern
151
+ FileList[result]
152
+ end
153
+ end
154
+ end
155
+ end
156
+
@@ -0,0 +1,1236 @@
1
+ # rcov Copyright (c) 2004-2006 Mauricio Fernandez <mfp@acm.org>
2
+ # See LEGAL and LICENSE for additional licensing information.
3
+
4
+ require 'pathname'
5
+ module Rcov
6
+
7
+ # Try to fix bugs in the REXML shipped with Ruby 1.8.6
8
+ # They affect Mac OSX 10.5.1 users and motivates endless bug reports.
9
+ begin
10
+ require 'rexml/formatters/transitive'
11
+ require 'rexml/formatter/pretty'
12
+ rescue LoadError
13
+ end
14
+
15
+ if RUBY_VERSION == "1.8.6" && defined? REXML::Formatters::Transitive
16
+ class REXML::Document
17
+ remove_method :write rescue nil
18
+ def write( output=$stdout, indent=-1, trans=false, ie_hack=false )
19
+ if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
20
+ output = Output.new( output, xml_decl.encoding )
21
+ end
22
+ formatter = if indent > -1
23
+ #if trans
24
+ REXML::Formatters::Transitive.new( indent )
25
+ #else
26
+ # REXML::Formatters::Pretty.new( indent, ie_hack )
27
+ #end
28
+ else
29
+ REXML::Formatters::Default.new( ie_hack )
30
+ end
31
+ formatter.write( self, output )
32
+ end
33
+ end
34
+
35
+ class REXML::Formatters::Transitive
36
+ remove_method :write_element rescue nil
37
+ def write_element( node, output )
38
+ output << "<#{node.expanded_name}"
39
+
40
+ node.attributes.each_attribute do |attr|
41
+ output << " "
42
+ attr.write( output )
43
+ end unless node.attributes.empty?
44
+
45
+ if node.children.empty?
46
+ output << "/>"
47
+ else
48
+ output << ">"
49
+ # If compact and all children are text, and if the formatted output
50
+ # is less than the specified width, then try to print everything on
51
+ # one line
52
+ skip = false
53
+ @level += @indentation
54
+ node.children.each { |child|
55
+ write( child, output )
56
+ }
57
+ @level -= @indentation
58
+ output << "</#{node.expanded_name}>"
59
+ end
60
+ output << "\n"
61
+ output << ' '*@level
62
+ end
63
+ end
64
+ end
65
+
66
+ class Formatter # :nodoc:
67
+ require 'pathname'
68
+ ignore_files = [
69
+ /\A#{Regexp.escape(Pathname.new(Config::CONFIG["libdir"]).cleanpath.to_s)}/,
70
+ /\btc_[^.]*.rb/,
71
+ /_test\.rb\z/,
72
+ /\btest\//,
73
+ /\bvendor\//,
74
+ /\A#{Regexp.escape(__FILE__)}\z/]
75
+ DEFAULT_OPTS = {:ignore => ignore_files, :sort => :name, :sort_reverse => false,
76
+ :output_threshold => 101, :dont_ignore => [],
77
+ :callsite_analyzer => nil, :comments_run_by_default => false}
78
+ def initialize(opts = {})
79
+ options = DEFAULT_OPTS.clone.update(opts)
80
+ @files = {}
81
+ @ignore_files = options[:ignore]
82
+ @dont_ignore_files = options[:dont_ignore]
83
+ @sort_criterium = case options[:sort]
84
+ when :loc : lambda{|fname, finfo| finfo.num_code_lines}
85
+ when :coverage : lambda{|fname, finfo| finfo.code_coverage}
86
+ else lambda{|fname, finfo| fname}
87
+ end
88
+ @sort_reverse = options[:sort_reverse]
89
+ @output_threshold = options[:output_threshold]
90
+ @callsite_analyzer = options[:callsite_analyzer]
91
+ @comments_run_by_default = options[:comments_run_by_default]
92
+ @callsite_index = nil
93
+
94
+ @mangle_filename = Hash.new{|h,base|
95
+ h[base] = Pathname.new(base).cleanpath.to_s.gsub(%r{^\w:[/\\]}, "").gsub(/\./, "_").gsub(/[\\\/]/, "-") + ".html"
96
+ }
97
+ end
98
+
99
+ def add_file(filename, lines, coverage, counts)
100
+ old_filename = filename
101
+ filename = normalize_filename(filename)
102
+ SCRIPT_LINES__[filename] = SCRIPT_LINES__[old_filename]
103
+ if @ignore_files.any?{|x| x === filename} &&
104
+ !@dont_ignore_files.any?{|x| x === filename}
105
+ return nil
106
+ end
107
+ if @files[filename]
108
+ @files[filename].merge(lines, coverage, counts)
109
+ else
110
+ @files[filename] = FileStatistics.new(filename, lines, counts,
111
+ @comments_run_by_default)
112
+ end
113
+ end
114
+
115
+ def normalize_filename(filename)
116
+ File.expand_path(filename).gsub(/^#{Regexp.escape(Dir.getwd)}\//, '')
117
+ end
118
+
119
+ def mangle_filename(base)
120
+ @mangle_filename[base]
121
+ end
122
+
123
+ def each_file_pair_sorted(&b)
124
+ return sorted_file_pairs unless block_given?
125
+ sorted_file_pairs.each(&b)
126
+ end
127
+
128
+ def sorted_file_pairs
129
+ pairs = @files.sort_by do |fname, finfo|
130
+ @sort_criterium.call(fname, finfo)
131
+ end.select{|_, finfo| 100 * finfo.code_coverage < @output_threshold}
132
+ @sort_reverse ? pairs.reverse : pairs
133
+ end
134
+
135
+ def total_coverage
136
+ lines = 0
137
+ total = 0.0
138
+ @files.each do |k,f|
139
+ total += f.num_lines * f.total_coverage
140
+ lines += f.num_lines
141
+ end
142
+ return 0 if lines == 0
143
+ total / lines
144
+ end
145
+
146
+ def code_coverage
147
+ lines = 0
148
+ total = 0.0
149
+ @files.each do |k,f|
150
+ total += f.num_code_lines * f.code_coverage
151
+ lines += f.num_code_lines
152
+ end
153
+ return 0 if lines == 0
154
+ total / lines
155
+ end
156
+
157
+ def num_code_lines
158
+ lines = 0
159
+ @files.each{|k, f| lines += f.num_code_lines }
160
+ lines
161
+ end
162
+
163
+ def num_lines
164
+ lines = 0
165
+ @files.each{|k, f| lines += f.num_lines }
166
+ lines
167
+ end
168
+
169
+ private
170
+ def cross_references_for(filename, lineno)
171
+ return nil unless @callsite_analyzer
172
+ @callsite_index ||= build_callsite_index
173
+ @callsite_index[normalize_filename(filename)][lineno]
174
+ end
175
+
176
+ def reverse_cross_references_for(filename, lineno)
177
+ return nil unless @callsite_analyzer
178
+ @callsite_reverse_index ||= build_reverse_callsite_index
179
+ @callsite_reverse_index[normalize_filename(filename)][lineno]
180
+ end
181
+
182
+ def build_callsite_index
183
+ index = Hash.new{|h,k| h[k] = {}}
184
+ @callsite_analyzer.analyzed_classes.each do |classname|
185
+ @callsite_analyzer.analyzed_methods(classname).each do |methname|
186
+ defsite = @callsite_analyzer.defsite(classname, methname)
187
+ index[normalize_filename(defsite.file)][defsite.line] =
188
+ @callsite_analyzer.callsites(classname, methname)
189
+ end
190
+ end
191
+ index
192
+ end
193
+
194
+ def build_reverse_callsite_index
195
+ index = Hash.new{|h,k| h[k] = {}}
196
+ @callsite_analyzer.analyzed_classes.each do |classname|
197
+ @callsite_analyzer.analyzed_methods(classname).each do |methname|
198
+ callsites = @callsite_analyzer.callsites(classname, methname)
199
+ defsite = @callsite_analyzer.defsite(classname, methname)
200
+ callsites.each_pair do |callsite, count|
201
+ next unless callsite.file
202
+ fname = normalize_filename(callsite.file)
203
+ (index[fname][callsite.line] ||= []) << [classname, methname, defsite, count]
204
+ end
205
+ end
206
+ end
207
+ index
208
+ end
209
+
210
+ class XRefHelper < Struct.new(:file, :line, :klass, :mid, :count) # :nodoc:
211
+ end
212
+
213
+ def _get_defsites(ref_blocks, filename, lineno, linetext, label, &format_call_ref)
214
+ if @do_cross_references and
215
+ (rev_xref = reverse_cross_references_for(filename, lineno))
216
+ refs = rev_xref.map do |classname, methodname, defsite, count|
217
+ XRefHelper.new(defsite.file, defsite.line, classname, methodname, count)
218
+ end.sort_by{|r| r.count}.reverse
219
+ ref_blocks << [refs, label, format_call_ref]
220
+ end
221
+ end
222
+
223
+ def _get_callsites(ref_blocks, filename, lineno, linetext, label, &format_called_ref)
224
+ if @do_callsites and
225
+ (refs = cross_references_for(filename, lineno))
226
+ refs = refs.sort_by{|k,count| count}.map do |ref, count|
227
+ XRefHelper.new(ref.file, ref.line, ref.calling_class, ref.calling_method, count)
228
+ end.reverse
229
+ ref_blocks << [refs, label, format_called_ref]
230
+ end
231
+ end
232
+ end
233
+
234
+ class TextSummary < Formatter # :nodoc:
235
+ def execute
236
+ puts summary
237
+ end
238
+
239
+ def summary
240
+ "%.1f%% %d file(s) %d Lines %d LOC" % [code_coverage * 100,
241
+ @files.size, num_lines, num_code_lines]
242
+ end
243
+ end
244
+
245
+ class TextReport < TextSummary # :nodoc:
246
+ def execute
247
+ print_lines
248
+ print_header
249
+ print_lines
250
+ each_file_pair_sorted do |fname, finfo|
251
+ name = fname.size < 52 ? fname : "..." + fname[-48..-1]
252
+ print_info(name, finfo.num_lines, finfo.num_code_lines,
253
+ finfo.code_coverage)
254
+ end
255
+ print_lines
256
+ print_info("Total", num_lines, num_code_lines, code_coverage)
257
+ print_lines
258
+ puts summary
259
+ end
260
+
261
+ def print_info(name, lines, loc, coverage)
262
+ puts "|%-51s | %5d | %5d | %5.1f%% |" % [name, lines, loc, 100 * coverage]
263
+ end
264
+
265
+ def print_lines
266
+ puts "+----------------------------------------------------+-------+-------+--------+"
267
+ end
268
+
269
+ def print_header
270
+ puts "| File | Lines | LOC | COV |"
271
+ end
272
+ end
273
+
274
+ class FullTextReport < Formatter # :nodoc:
275
+ DEFAULT_OPTS = {:textmode => :coverage}
276
+ def initialize(opts = {})
277
+ options = DEFAULT_OPTS.clone.update(opts)
278
+ @textmode = options[:textmode]
279
+ @color = options[:color]
280
+ super(options)
281
+ end
282
+
283
+ def execute
284
+ each_file_pair_sorted do |filename, fileinfo|
285
+ puts "=" * 80
286
+ puts filename
287
+ puts "=" * 80
288
+ lines = SCRIPT_LINES__[filename]
289
+ unless lines
290
+ # try to get the source code from the global code coverage
291
+ # analyzer
292
+ re = /#{Regexp.escape(filename)}\z/
293
+ if $rcov_code_coverage_analyzer and
294
+ (data = $rcov_code_coverage_analyzer.data_matching(re))
295
+ lines = data[0]
296
+ end
297
+ end
298
+ (lines || []).each_with_index do |line, i|
299
+ case @textmode
300
+ when :counts
301
+ puts "%-70s| %6d" % [line.chomp[0,70], fileinfo.counts[i]]
302
+ when :gcc
303
+ puts "%s:%d:%s" % [filename, i+1, line.chomp] unless fileinfo.coverage[i]
304
+ when :coverage
305
+ if @color
306
+ prefix = fileinfo.coverage[i] ? "\e[32;40m" : "\e[31;40m"
307
+ puts "#{prefix}%s\e[37;40m" % line.chomp
308
+ else
309
+ prefix = fileinfo.coverage[i] ? " " : "!! "
310
+ puts "#{prefix}#{line}"
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+
318
+ class TextCoverageDiff < Formatter # :nodoc:
319
+ FORMAT_VERSION = [0, 1, 0]
320
+ DEFAULT_OPTS = {:textmode => :coverage_diff,
321
+ :coverage_diff_mode => :record,
322
+ :coverage_diff_file => "coverage.info",
323
+ :diff_cmd => "diff", :comments_run_by_default => true}
324
+ def SERIALIZER
325
+ # mfp> this was going to be YAML but I caught it failing at basic
326
+ # round-tripping, turning "\n" into "" and corrupting the data, so
327
+ # it must be Marshal for now
328
+ Marshal
329
+ end
330
+
331
+ def initialize(opts = {})
332
+ options = DEFAULT_OPTS.clone.update(opts)
333
+ @textmode = options[:textmode]
334
+ @color = options[:color]
335
+ @mode = options[:coverage_diff_mode]
336
+ @state_file = options[:coverage_diff_file]
337
+ @diff_cmd = options[:diff_cmd]
338
+ @gcc_output = options[:gcc_output]
339
+ super(options)
340
+ end
341
+
342
+ def execute
343
+ case @mode
344
+ when :record
345
+ record_state
346
+ when :compare
347
+ compare_state
348
+ else
349
+ raise "Unknown TextCoverageDiff mode: #{mode.inspect}."
350
+ end
351
+ end
352
+
353
+ def record_state
354
+ state = {}
355
+ each_file_pair_sorted do |filename, fileinfo|
356
+ state[filename] = {:lines => SCRIPT_LINES__[filename],
357
+ :coverage => fileinfo.coverage.to_a,
358
+ :counts => fileinfo.counts}
359
+ end
360
+ File.open(@state_file, "w") do |f|
361
+ self.SERIALIZER.dump([FORMAT_VERSION, state], f)
362
+ end
363
+ rescue
364
+ $stderr.puts <<-EOF
365
+ Couldn't save coverage data to #{@state_file}.
366
+ EOF
367
+ end # '
368
+
369
+ require 'tempfile'
370
+ def compare_state
371
+ return unless verify_diff_available
372
+ begin
373
+ format, prev_state = File.open(@state_file){|f| self.SERIALIZER.load(f) }
374
+ rescue
375
+ $stderr.puts <<-EOF
376
+ Couldn't load coverage data from #{@state_file}.
377
+ EOF
378
+ return # '
379
+ end
380
+ if !(Array === format) or
381
+ FORMAT_VERSION[0] != format[0] || FORMAT_VERSION[1] < format[1]
382
+ $stderr.puts <<-EOF
383
+ Couldn't load coverage data from #{@state_file}.
384
+ The file is saved in the format #{format.inspect[0..20]}.
385
+ This rcov executable understands #{FORMAT_VERSION.inspect}.
386
+ EOF
387
+ return # '
388
+ end
389
+ each_file_pair_sorted do |filename, fileinfo|
390
+ old_data = Tempfile.new("#{mangle_filename(filename)}-old")
391
+ new_data = Tempfile.new("#{mangle_filename(filename)}-new")
392
+ if prev_state.has_key? filename
393
+ old_code, old_cov = prev_state[filename].values_at(:lines, :coverage)
394
+ old_code.each_with_index do |line, i|
395
+ prefix = old_cov[i] ? " " : "!! "
396
+ old_data.write "#{prefix}#{line}"
397
+ end
398
+ else
399
+ old_data.write ""
400
+ end
401
+ old_data.close
402
+ SCRIPT_LINES__[filename].each_with_index do |line, i|
403
+ prefix = fileinfo.coverage[i] ? " " : "!! "
404
+ new_data.write "#{prefix}#{line}"
405
+ end
406
+ new_data.close
407
+
408
+ diff = `#{@diff_cmd} -u "#{old_data.path}" "#{new_data.path}"`
409
+ new_uncovered_hunks = process_unified_diff(filename, diff)
410
+ old_data.close!
411
+ new_data.close!
412
+ display_hunks(filename, new_uncovered_hunks)
413
+ end
414
+ end
415
+
416
+ def display_hunks(filename, hunks)
417
+ return if hunks.empty?
418
+ puts
419
+ puts "=" * 80
420
+ puts <<EOF
421
+ !!!!! Uncovered code introduced in #{filename}
422
+
423
+ EOF
424
+ hunks.each do |offset, lines|
425
+ if @gcc_output
426
+ lines.each_with_index do |line,i|
427
+ lineno = offset + i
428
+ flag = (/^!! / !~ line) ? "-" : ":"
429
+ prefix = "#{filename}#{flag}#{lineno}#{flag}"
430
+ puts "#{prefix}#{line[3..-1]}"
431
+ end
432
+ elsif @color
433
+ puts "### #{filename}:#{offset}"
434
+ lines.each do |line|
435
+ prefix = (/^!! / !~ line) ? "\e[32;40m" : "\e[31;40m"
436
+ puts "#{prefix}#{line[3..-1].chomp}\e[37;40m"
437
+ end
438
+ else
439
+ puts "### #{filename}:#{offset}"
440
+ puts lines
441
+ end
442
+ end
443
+ end
444
+
445
+ def verify_diff_available
446
+ old_stderr = STDERR.dup
447
+ old_stdout = STDOUT.dup
448
+ # TODO: should use /dev/null or NUL(?), but I don't want to add the
449
+ # win32 check right now
450
+ new_stderr = Tempfile.new("rcov_check_diff")
451
+ STDERR.reopen new_stderr.path
452
+ STDOUT.reopen new_stderr.path
453
+
454
+ retval = system "#{@diff_cmd} --version"
455
+ unless retval
456
+ old_stderr.puts <<EOF
457
+
458
+ The '#{@diff_cmd}' executable seems not to be available.
459
+ You can specify which diff executable should be used with --diff-cmd.
460
+ If your system doesn't have one, you might want to use Diff::LCS's:
461
+ gem install diff-lcs
462
+ and use --diff-cmd=ldiff.
463
+ EOF
464
+ return false
465
+ end
466
+ true
467
+ ensure
468
+ STDOUT.reopen old_stdout
469
+ STDERR.reopen old_stderr
470
+ new_stderr.close!
471
+ end
472
+
473
+ HUNK_HEADER = /@@ -\d+,\d+ \+(\d+),(\d+) @@/
474
+ def process_unified_diff(filename, diff)
475
+ current_hunk = []
476
+ current_hunk_start = 0
477
+ keep_current_hunk = false
478
+ state = :init
479
+ interesting_hunks = []
480
+ diff.each_with_index do |line, i|
481
+ #puts "#{state} %5d #{line}" % i
482
+ case state
483
+ when :init
484
+ if md = HUNK_HEADER.match(line)
485
+ current_hunk = []
486
+ current_hunk_start = md[1].to_i
487
+ state = :body
488
+ end
489
+ when :body
490
+ case line
491
+ when HUNK_HEADER
492
+ new_start = $1.to_i
493
+ if keep_current_hunk
494
+ interesting_hunks << [current_hunk_start, current_hunk]
495
+ end
496
+ current_hunk_start = new_start
497
+ current_hunk = []
498
+ keep_current_hunk = false
499
+ when /^-/
500
+ # ignore
501
+ when /^\+!! /
502
+ keep_current_hunk = true
503
+ current_hunk << line[1..-1]
504
+ else
505
+ current_hunk << line[1..-1]
506
+ end
507
+ end
508
+ end
509
+ if keep_current_hunk
510
+ interesting_hunks << [current_hunk_start, current_hunk]
511
+ end
512
+
513
+ interesting_hunks
514
+ end
515
+ end
516
+
517
+
518
+ class HTMLCoverage < Formatter # :nodoc:
519
+ include XX::XHTML
520
+ include XX::XMLish
521
+ require 'fileutils'
522
+ JAVASCRIPT_PROLOG = <<-EOS
523
+
524
+ // <![CDATA[
525
+ function toggleCode( id ) {
526
+ if ( document.getElementById )
527
+ elem = document.getElementById( id );
528
+ else if ( document.all )
529
+ elem = eval( "document.all." + id );
530
+ else
531
+ return false;
532
+
533
+ elemStyle = elem.style;
534
+
535
+ if ( elemStyle.display != "block" ) {
536
+ elemStyle.display = "block"
537
+ } else {
538
+ elemStyle.display = "none"
539
+ }
540
+
541
+ return true;
542
+ }
543
+
544
+ // Make cross-references hidden by default
545
+ document.writeln( "<style type=\\"text/css\\">span.cross-ref { display: none }</style>" )
546
+ // ]]>
547
+ EOS
548
+
549
+ CSS_PROLOG = <<-EOS
550
+ span.cross-ref-title {
551
+ font-size: 140%;
552
+ }
553
+ span.cross-ref a {
554
+ text-decoration: none;
555
+ }
556
+ span.cross-ref {
557
+ background-color:#f3f7fa;
558
+ border: 1px dashed #333;
559
+ margin: 1em;
560
+ padding: 0.5em;
561
+ overflow: hidden;
562
+ }
563
+ a.crossref-toggle {
564
+ text-decoration: none;
565
+ }
566
+ span.marked0 {
567
+ background-color: rgb(185, 210, 200);
568
+ display: block;
569
+ }
570
+ span.marked1 {
571
+ background-color: rgb(190, 215, 205);
572
+ display: block;
573
+ }
574
+ span.inferred0 {
575
+ background-color: rgb(175, 200, 200);
576
+ display: block;
577
+ }
578
+ span.inferred1 {
579
+ background-color: rgb(180, 205, 205);
580
+ display: block;
581
+ }
582
+ span.uncovered0 {
583
+ background-color: rgb(225, 110, 110);
584
+ display: block;
585
+ }
586
+ span.uncovered1 {
587
+ background-color: rgb(235, 120, 120);
588
+ display: block;
589
+ }
590
+ span.overview {
591
+ border-bottom: 8px solid black;
592
+ }
593
+ div.overview {
594
+ border-bottom: 8px solid black;
595
+ }
596
+ body {
597
+ font-family: verdana, arial, helvetica;
598
+ }
599
+
600
+ div.footer {
601
+ font-size: 68%;
602
+ margin-top: 1.5em;
603
+ }
604
+
605
+ h1, h2, h3, h4, h5, h6 {
606
+ margin-bottom: 0.5em;
607
+ }
608
+
609
+ h5 {
610
+ margin-top: 0.5em;
611
+ }
612
+
613
+ .hidden {
614
+ display: none;
615
+ }
616
+
617
+ div.separator {
618
+ height: 10px;
619
+ }
620
+ /* Commented out for better readability, esp. on IE */
621
+ /*
622
+ table tr td, table tr th {
623
+ font-size: 68%;
624
+ }
625
+
626
+ td.value table tr td {
627
+ font-size: 11px;
628
+ }
629
+ */
630
+
631
+ table.percent_graph {
632
+ height: 12px;
633
+ border: #808080 1px solid;
634
+ empty-cells: show;
635
+ }
636
+
637
+ table.percent_graph td.covered {
638
+ height: 10px;
639
+ background: #00f000;
640
+ }
641
+
642
+ table.percent_graph td.uncovered {
643
+ height: 10px;
644
+ background: #e00000;
645
+ }
646
+
647
+ table.percent_graph td.NA {
648
+ height: 10px;
649
+ background: #eaeaea;
650
+ }
651
+
652
+ table.report {
653
+ border-collapse: collapse;
654
+ width: 100%;
655
+ }
656
+
657
+ table.report td.heading {
658
+ background: #dcecff;
659
+ border: #d0d0d0 1px solid;
660
+ font-weight: bold;
661
+ text-align: center;
662
+ }
663
+
664
+ table.report td.heading:hover {
665
+ background: #c0ffc0;
666
+ }
667
+
668
+ table.report td.text {
669
+ border: #d0d0d0 1px solid;
670
+ }
671
+
672
+ table.report td.value,
673
+ table.report td.lines_total,
674
+ table.report td.lines_code {
675
+ text-align: right;
676
+ border: #d0d0d0 1px solid;
677
+ }
678
+ table.report tr.light {
679
+ background-color: rgb(240, 240, 245);
680
+ }
681
+ table.report tr.dark {
682
+ background-color: rgb(230, 230, 235);
683
+ }
684
+ EOS
685
+
686
+ DEFAULT_OPTS = {:color => false, :fsr => 30, :destdir => "coverage",
687
+ :callsites => false, :cross_references => false,
688
+ :validator_links => true, :charset => nil
689
+ }
690
+ def initialize(opts = {})
691
+ options = DEFAULT_OPTS.clone.update(opts)
692
+ super(options)
693
+ @dest = options[:destdir]
694
+ @color = options[:color]
695
+ @fsr = options[:fsr]
696
+ @do_callsites = options[:callsites]
697
+ @do_cross_references = options[:cross_references]
698
+ @span_class_index = 0
699
+ @show_validator_links = options[:validator_links]
700
+ @charset = options[:charset]
701
+ end
702
+
703
+ def execute
704
+ return if @files.empty?
705
+ FileUtils.mkdir_p @dest
706
+ create_index(File.join(@dest, "index.html"))
707
+ each_file_pair_sorted do |filename, fileinfo|
708
+ create_file(File.join(@dest, mangle_filename(filename)), fileinfo)
709
+ end
710
+ end
711
+
712
+ private
713
+
714
+ def blurb
715
+ xmlish_ {
716
+ p_ {
717
+ t_{ "Generated using the " }
718
+ a_(:href => "http://eigenclass.org/hiki.rb?rcov") {
719
+ t_{ "rcov code coverage analysis tool for Ruby" }
720
+ }
721
+ t_{ " version #{Rcov::VERSION}." }
722
+ }
723
+ }.pretty
724
+ end
725
+
726
+ def output_color_table?
727
+ true
728
+ end
729
+
730
+ def default_color
731
+ "rgb(240, 240, 245)"
732
+ end
733
+
734
+ def default_title
735
+ "C0 code coverage information"
736
+ end
737
+
738
+ def format_overview(*file_infos)
739
+ table_text = xmlish_ {
740
+ table_(:class => "report") {
741
+ thead_ {
742
+ tr_ {
743
+ ["Name", "Total lines", "Lines of code", "Total coverage",
744
+ "Code coverage"].each do |heading|
745
+ td_(:class => "heading") { heading }
746
+ end
747
+ }
748
+ }
749
+ tbody_ {
750
+ color_class_index = 1
751
+ color_classes = %w[light dark]
752
+ file_infos.each do |f|
753
+ color_class_index += 1
754
+ color_class_index %= color_classes.size
755
+ tr_(:class => color_classes[color_class_index]) {
756
+ td_ {
757
+ case f.name
758
+ when "TOTAL":
759
+ t_ { "TOTAL" }
760
+ else
761
+ a_(:href => mangle_filename(f.name)){ t_ { f.name } }
762
+ end
763
+ }
764
+ [[f.num_lines, "lines_total"],
765
+ [f.num_code_lines, "lines_code"]].each do |value, css_class|
766
+ td_(:class => css_class) { tt_{ value } }
767
+ end
768
+ [[f.total_coverage, "coverage_total"],
769
+ [f.code_coverage, "coverage_code"]].each do |value, css_class|
770
+ value *= 100
771
+ td_ {
772
+ table_(:cellpadding => "0", :cellspacing => "0", :align => "right") {
773
+ tr_ {
774
+ td_ {
775
+ tt_(:class => css_class) { "%3.1f%%" % value }
776
+ x_ "&nbsp;"
777
+ }
778
+ ivalue = value.round
779
+ td_ {
780
+ table_(:class => "percent_graph", :cellpadding => "0",
781
+ :cellspacing => "0", :width => "100") {
782
+ tr_ {
783
+ td_(:class => "covered", :width => ivalue.to_s)
784
+ td_(:class => "uncovered", :width => (100-ivalue).to_s)
785
+ }
786
+ }
787
+ }
788
+ }
789
+ }
790
+ }
791
+ end
792
+ }
793
+ end
794
+ }
795
+ }
796
+ }
797
+ table_text.pretty
798
+ end
799
+
800
+ class SummaryFileInfo # :nodoc:
801
+ def initialize(obj); @o = obj end
802
+ %w[num_lines num_code_lines code_coverage total_coverage].each do |m|
803
+ define_method(m){ @o.send(m) }
804
+ end
805
+ def name; "TOTAL" end
806
+ end
807
+
808
+ def create_index(destname)
809
+ files = [SummaryFileInfo.new(self)] + each_file_pair_sorted.map{|k,v| v}
810
+ title = default_title
811
+ output = xhtml_ { html_ {
812
+ head_ {
813
+ if @charset
814
+ meta_("http-equiv".to_sym => "Content-Type",
815
+ :content => "text/html;charset=#{@charset}")
816
+ end
817
+ title_{ title }
818
+ style_(:type => "text/css") { t_{ "body { background-color: #{default_color}; }" } }
819
+ style_(:type => "text/css") { CSS_PROLOG }
820
+ script_(:type => "text/javascript") { h_{ JAVASCRIPT_PROLOG } }
821
+ }
822
+ body_ {
823
+ h3_{
824
+ t_{ title }
825
+ }
826
+ p_ {
827
+ t_{ "Generated on #{Time.new.to_s} with " }
828
+ a_(:href => Rcov::UPSTREAM_URL){ "rcov #{Rcov::VERSION}" }
829
+ }
830
+ p_ { "Threshold: #{@output_threshold}%" } if @output_threshold != 101
831
+ hr_
832
+ x_{ format_overview(*files) }
833
+ hr_
834
+ x_{ blurb }
835
+
836
+ if @show_validator_links
837
+ p_ {
838
+ a_(:href => "http://validator.w3.org/check/referer") {
839
+ img_(:src => "http://www.w3.org/Icons/valid-xhtml11",
840
+ :alt => "Valid XHTML 1.1!", :height => "31", :width => "88")
841
+ }
842
+ a_(:href => "http://jigsaw.w3.org/css-validator/check/referer") {
843
+ img_(:style => "border:0;width:88px;height:31px",
844
+ :src => "http://jigsaw.w3.org/css-validator/images/vcss",
845
+ :alt => "Valid CSS!")
846
+ }
847
+ }
848
+ end
849
+ }
850
+ } }
851
+ lines = output.pretty.to_a
852
+ lines.unshift lines.pop if /DOCTYPE/ =~ lines[-1]
853
+ File.open(destname, "w") do |f|
854
+ f.puts lines
855
+ end
856
+ end
857
+
858
+ def format_lines(file)
859
+ result = ""
860
+ last = nil
861
+ end_of_span = ""
862
+ format_line = "%#{file.num_lines.to_s.size}d"
863
+ file.num_lines.times do |i|
864
+ line = file.lines[i].chomp
865
+ marked = file.coverage[i]
866
+ count = file.counts[i]
867
+ spanclass = span_class(file, marked, count)
868
+ if spanclass != last
869
+ result += end_of_span
870
+ case spanclass
871
+ when nil
872
+ end_of_span = ""
873
+ else
874
+ result += %[<span class="#{spanclass}">]
875
+ end_of_span = "</span>"
876
+ end
877
+ end
878
+ result += %[<a name="line#{i+1}"></a>] + (format_line % (i+1)) +
879
+ " " + create_cross_refs(file.name, i+1, CGI.escapeHTML(line)) + "\n"
880
+ last = spanclass
881
+ end
882
+ result += end_of_span
883
+ "<pre>#{result}</pre>"
884
+ end
885
+
886
+ def create_cross_refs(filename, lineno, linetext)
887
+ return linetext unless @callsite_analyzer && @do_callsites
888
+ ref_blocks = []
889
+ _get_defsites(ref_blocks, filename, lineno, "Calls", linetext) do |ref|
890
+ if ref.file
891
+ where = "at #{normalize_filename(ref.file)}:#{ref.line}"
892
+ else
893
+ where = "(C extension/core)"
894
+ end
895
+ CGI.escapeHTML("%7d %s" %
896
+ [ref.count, "#{ref.klass}##{ref.mid} " + where])
897
+ end
898
+ _get_callsites(ref_blocks, filename, lineno, "Called by", linetext) do |ref|
899
+ r = "%7d %s" % [ref.count,
900
+ "#{normalize_filename(ref.file||'C code')}:#{ref.line} " +
901
+ "in '#{ref.klass}##{ref.mid}'"]
902
+ CGI.escapeHTML(r)
903
+ end
904
+
905
+ create_cross_reference_block(linetext, ref_blocks)
906
+ end
907
+
908
+ def create_cross_reference_block(linetext, ref_blocks)
909
+ return linetext if ref_blocks.empty?
910
+ ret = ""
911
+ @cross_ref_idx ||= 0
912
+ @known_files ||= sorted_file_pairs.map{|fname, finfo| normalize_filename(fname)}
913
+ ret << %[<a class="crossref-toggle" href="#" onclick="toggleCode('XREF-#{@cross_ref_idx+=1}'); return false;">#{linetext}</a>]
914
+ ret << %[<span class="cross-ref" id="XREF-#{@cross_ref_idx}">]
915
+ ret << "\n"
916
+ ref_blocks.each do |refs, toplabel, label_proc|
917
+ unless !toplabel || toplabel.empty?
918
+ ret << %!<span class="cross-ref-title">#{toplabel}</span>\n!
919
+ end
920
+ refs.each do |dst|
921
+ dstfile = normalize_filename(dst.file) if dst.file
922
+ dstline = dst.line
923
+ label = label_proc.call(dst)
924
+ if dst.file && @known_files.include?(dstfile)
925
+ ret << %[<a href="#{mangle_filename(dstfile)}#line#{dstline}">#{label}</a>]
926
+ else
927
+ ret << label
928
+ end
929
+ ret << "\n"
930
+ end
931
+ end
932
+ ret << "</span>"
933
+ end
934
+
935
+ def span_class(sourceinfo, marked, count)
936
+ @span_class_index ^= 1
937
+ case marked
938
+ when true
939
+ "marked#{@span_class_index}"
940
+ when :inferred
941
+ "inferred#{@span_class_index}"
942
+ else
943
+ "uncovered#{@span_class_index}"
944
+ end
945
+ end
946
+
947
+ def create_file(destfile, fileinfo)
948
+ #$stderr.puts "Generating #{destfile.inspect}"
949
+ body = format_overview(fileinfo) + format_lines(fileinfo)
950
+ title = fileinfo.name + " - #{default_title}"
951
+ do_ctable = output_color_table?
952
+ output = xhtml_ { html_ {
953
+ head_ {
954
+ if @charset
955
+ meta_("http-equiv".to_sym => "Content-Type",
956
+ :content => "text/html;charset=#{@charset}")
957
+ end
958
+ title_{ title }
959
+ style_(:type => "text/css") { t_{ "body { background-color: #{default_color}; }" } }
960
+ style_(:type => "text/css") { CSS_PROLOG }
961
+ script_(:type => "text/javascript") { h_ { JAVASCRIPT_PROLOG } }
962
+ style_(:type => "text/css") { h_ { colorscale } }
963
+ }
964
+ body_ {
965
+ h3_{ t_{ default_title } }
966
+ p_ {
967
+ t_{ "Generated on #{Time.new.to_s} with " }
968
+ a_(:href => Rcov::UPSTREAM_URL){ "rcov #{Rcov::VERSION}" }
969
+ }
970
+ hr_
971
+ if do_ctable
972
+ # this kludge needed to ensure .pretty doesn't mangle it
973
+ x_ { <<EOS
974
+ <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
975
+ </span><span class='marked1'>and this: this line is also marked as covered.
976
+ </span><span class='inferred0'>Lines considered as run by rcov, but not reported by Ruby, look like this,
977
+ </span><span class='inferred1'>and this: these lines were inferred by rcov (using simple heuristics).
978
+ </span><span class='uncovered0'>Finally, here&apos;s a line marked as not executed.
979
+ </span></pre>
980
+ EOS
981
+ }
982
+ end
983
+ x_{ body }
984
+ hr_
985
+ x_ { blurb }
986
+
987
+ if @show_validator_links
988
+ p_ {
989
+ a_(:href => "http://validator.w3.org/check/referer") {
990
+ img_(:src => "http://www.w3.org/Icons/valid-xhtml10",
991
+ :alt => "Valid XHTML 1.0!", :height => "31", :width => "88")
992
+ }
993
+ a_(:href => "http://jigsaw.w3.org/css-validator/check/referer") {
994
+ img_(:style => "border:0;width:88px;height:31px",
995
+ :src => "http://jigsaw.w3.org/css-validator/images/vcss",
996
+ :alt => "Valid CSS!")
997
+ }
998
+ }
999
+ end
1000
+ }
1001
+ } }
1002
+ # .pretty needed to make sure DOCTYPE is in a separate line
1003
+ lines = output.pretty.to_a
1004
+ lines.unshift lines.pop if /DOCTYPE/ =~ lines[-1]
1005
+ File.open(destfile, "w") do |f|
1006
+ f.puts lines
1007
+ end
1008
+ end
1009
+
1010
+ def colorscale
1011
+ colorscalebase =<<EOF
1012
+ span.run%d {
1013
+ background-color: rgb(%d, %d, %d);
1014
+ display: block;
1015
+ }
1016
+ EOF
1017
+ cscale = ""
1018
+ 101.times do |i|
1019
+ if @color
1020
+ r, g, b = hsv2rgb(220-(2.2*i).to_i, 0.3, 1)
1021
+ r = (r * 255).to_i
1022
+ g = (g * 255).to_i
1023
+ b = (b * 255).to_i
1024
+ else
1025
+ r = g = b = 255 - i
1026
+ end
1027
+ cscale << colorscalebase % [i, r, g, b]
1028
+ end
1029
+ cscale
1030
+ end
1031
+
1032
+ # thanks to kig @ #ruby-lang for this one
1033
+ def hsv2rgb(h,s,v)
1034
+ return [v,v,v] if s == 0
1035
+ h = h/60.0
1036
+ i = h.floor
1037
+ f = h-i
1038
+ p = v * (1-s)
1039
+ q = v * (1-s*f)
1040
+ t = v * (1-s*(1-f))
1041
+ case i
1042
+ when 0
1043
+ r = v
1044
+ g = t
1045
+ b = p
1046
+ when 1
1047
+ r = q
1048
+ g = v
1049
+ b = p
1050
+ when 2
1051
+ r = p
1052
+ g = v
1053
+ b = t
1054
+ when 3
1055
+ r = p
1056
+ g = q
1057
+ b = v
1058
+ when 4
1059
+ r = t
1060
+ g = p
1061
+ b = v
1062
+ when 5
1063
+ r = v
1064
+ g = p
1065
+ b = q
1066
+ end
1067
+ [r,g,b]
1068
+ end
1069
+ end
1070
+
1071
+ class HTMLProfiling < HTMLCoverage # :nodoc:
1072
+
1073
+ DEFAULT_OPTS = {:destdir => "profiling"}
1074
+ def initialize(opts = {})
1075
+ options = DEFAULT_OPTS.clone.update(opts)
1076
+ super(options)
1077
+ @max_cache = {}
1078
+ @median_cache = {}
1079
+ end
1080
+
1081
+ def default_title
1082
+ "Bogo-profile information"
1083
+ end
1084
+
1085
+ def default_color
1086
+ if @color
1087
+ "rgb(179,205,255)"
1088
+ else
1089
+ "rgb(255, 255, 255)"
1090
+ end
1091
+ end
1092
+
1093
+ def output_color_table?
1094
+ false
1095
+ end
1096
+
1097
+ def span_class(sourceinfo, marked, count)
1098
+ full_scale_range = @fsr # dB
1099
+ nz_count = sourceinfo.counts.select{|x| x && x != 0}
1100
+ nz_count << 1 # avoid div by 0
1101
+ max = @max_cache[sourceinfo] ||= nz_count.max
1102
+ #avg = @median_cache[sourceinfo] ||= 1.0 *
1103
+ # nz_count.inject{|a,b| a+b} / nz_count.size
1104
+ median = @median_cache[sourceinfo] ||= 1.0 * nz_count.sort[nz_count.size/2]
1105
+ max ||= 2
1106
+ max = 2 if max == 1
1107
+ if marked == true
1108
+ count = 1 if !count || count == 0
1109
+ idx = 50 + 1.0 * (500/full_scale_range) * Math.log(count/median) /
1110
+ Math.log(10)
1111
+ idx = idx.to_i
1112
+ idx = 0 if idx < 0
1113
+ idx = 100 if idx > 100
1114
+ "run#{idx}"
1115
+ else
1116
+ nil
1117
+ end
1118
+ end
1119
+ end
1120
+
1121
+ class RubyAnnotation < Formatter # :nodoc:
1122
+ DEFAULT_OPTS = { :destdir => "coverage" }
1123
+ def initialize(opts = {})
1124
+ options = DEFAULT_OPTS.clone.update(opts)
1125
+ super(options)
1126
+ @dest = options[:destdir]
1127
+ @do_callsites = true
1128
+ @do_cross_references = true
1129
+
1130
+ @mangle_filename = Hash.new{|h,base|
1131
+ h[base] = Pathname.new(base).cleanpath.to_s.gsub(%r{^\w:[/\\]}, "").gsub(/\./, "_").gsub(/[\\\/]/, "-") + ".rb"
1132
+ }
1133
+ end
1134
+
1135
+ def execute
1136
+ return if @files.empty?
1137
+ FileUtils.mkdir_p @dest
1138
+ each_file_pair_sorted do |filename, fileinfo|
1139
+ create_file(File.join(@dest, mangle_filename(filename)), fileinfo)
1140
+ end
1141
+ end
1142
+
1143
+ private
1144
+
1145
+ def format_lines(file)
1146
+ result = ""
1147
+ format_line = "%#{file.num_lines.to_s.size}d"
1148
+ file.num_lines.times do |i|
1149
+ line = file.lines[i].chomp
1150
+ marked = file.coverage[i]
1151
+ count = file.counts[i]
1152
+ result << create_cross_refs(file.name, i+1, line, marked) + "\n"
1153
+ end
1154
+ result
1155
+ end
1156
+
1157
+ def create_cross_refs(filename, lineno, linetext, marked)
1158
+ return linetext unless @callsite_analyzer && @do_callsites
1159
+ ref_blocks = []
1160
+ _get_defsites(ref_blocks, filename, lineno, linetext, ">>") do |ref|
1161
+ if ref.file
1162
+ ref.file.sub!(%r!^./!, '')
1163
+ where = "at #{mangle_filename(ref.file)}:#{ref.line}"
1164
+ else
1165
+ where = "(C extension/core)"
1166
+ end
1167
+ "#{ref.klass}##{ref.mid} " + where + ""
1168
+ end
1169
+ _get_callsites(ref_blocks, filename, lineno, linetext, "<<") do |ref| # "
1170
+ ref.file.sub!(%r!^./!, '')
1171
+ "#{mangle_filename(ref.file||'C code')}:#{ref.line} " +
1172
+ "in #{ref.klass}##{ref.mid}"
1173
+ end
1174
+
1175
+ create_cross_reference_block(linetext, ref_blocks, marked)
1176
+ end
1177
+
1178
+ def create_cross_reference_block(linetext, ref_blocks, marked)
1179
+ codelen = 75
1180
+ if ref_blocks.empty?
1181
+ if marked
1182
+ return "%-#{codelen}s #o" % linetext
1183
+ else
1184
+ return linetext
1185
+ end
1186
+ end
1187
+ ret = ""
1188
+ @cross_ref_idx ||= 0
1189
+ @known_files ||= sorted_file_pairs.map{|fname, finfo| normalize_filename(fname)}
1190
+ ret << "%-#{codelen}s # " % linetext
1191
+ ref_blocks.each do |refs, toplabel, label_proc|
1192
+ unless !toplabel || toplabel.empty?
1193
+ ret << toplabel << " "
1194
+ end
1195
+ refs.each do |dst|
1196
+ dstfile = normalize_filename(dst.file) if dst.file
1197
+ dstline = dst.line
1198
+ label = label_proc.call(dst)
1199
+ if dst.file && @known_files.include?(dstfile)
1200
+ ret << "[[" << label << "]], "
1201
+ else
1202
+ ret << label << ", "
1203
+ end
1204
+ end
1205
+ end
1206
+
1207
+ ret
1208
+ end
1209
+
1210
+ def create_file(destfile, fileinfo)
1211
+ #$stderr.puts "Generating #{destfile.inspect}"
1212
+ body = format_lines(fileinfo)
1213
+ File.open(destfile, "w") do |f|
1214
+ f.puts body
1215
+ f.puts footer(fileinfo)
1216
+ end
1217
+ end
1218
+
1219
+ def footer(fileinfo)
1220
+ s = "# Total lines : %d\n" % fileinfo.num_lines
1221
+ s << "# Lines of code : %d\n" % fileinfo.num_code_lines
1222
+ s << "# Total coverage : %3.1f%%\n" % [ fileinfo.total_coverage*100 ]
1223
+ s << "# Code coverage : %3.1f%%\n\n" % [ fileinfo.code_coverage*100 ]
1224
+ # prevents false positives on Emacs
1225
+ s << "# Local " "Variables:\n" "# mode: " "rcov-xref\n" "# End:\n"
1226
+ end
1227
+ end
1228
+
1229
+
1230
+ end # Rcov
1231
+
1232
+ # vi: set sw=4:
1233
+ # Here is Emacs setting. DO NOT REMOVE!
1234
+ # Local Variables:
1235
+ # ruby-indent-level: 4
1236
+ # End: