win32-api 1.5.3-universal-mingw32 → 1.6.0-universal-mingw32

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 (358) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +174 -169
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +24 -0
  5. data/README +129 -131
  6. data/Rakefile +185 -182
  7. data/appveyor.yml +42 -0
  8. data/ext/win32/api.c +1092 -1092
  9. data/lib/win32/api.rb +14 -8
  10. data/lib/win32/ruby21_32/win32/api.so +0 -0
  11. data/lib/win32/ruby21_64/win32/api.so +0 -0
  12. data/lib/win32/ruby22_32/win32/api.so +0 -0
  13. data/lib/win32/ruby22_64/win32/api.so +0 -0
  14. data/lib/win32/ruby23_32/win32/api.so +0 -0
  15. data/lib/win32/ruby23_64/win32/api.so +0 -0
  16. data/lib/win32/ruby2_32/win32/api.so +0 -0
  17. data/lib/win32/ruby2_64/win32/api.so +0 -0
  18. data/test/test_win32_api.rb +145 -145
  19. data/vendor/bundle/ruby/2.2.0/bin/devkit +23 -0
  20. data/vendor/bundle/ruby/2.2.0/bin/devkit.bat +6 -0
  21. data/vendor/bundle/ruby/2.2.0/bin/rake +23 -0
  22. data/vendor/bundle/ruby/2.2.0/bin/rake.bat +6 -0
  23. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/CHANGELOG +55 -0
  24. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/LICENSE +339 -0
  25. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/README.md +73 -0
  26. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/Rakefile +8 -0
  27. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/colorize.gemspec +35 -0
  28. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize.rb +12 -0
  29. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize/class_methods.rb +116 -0
  30. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize/instance_methods.rb +135 -0
  31. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/test/test_colorize.rb +161 -0
  32. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Gemfile +4 -0
  33. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/LICENSE.txt +22 -0
  34. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/README.md +34 -0
  35. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Rakefile +1 -0
  36. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Rspec-example-matchers.txt +184 -0
  37. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/bin/devkit +87 -0
  38. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/devkit.gemspec +27 -0
  39. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit.rb +18 -0
  40. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/core.rb +53 -0
  41. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/identity.rb +78 -0
  42. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/ssh_identity.rb +53 -0
  43. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/version.rb +3 -0
  44. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/core_spec.rb +46 -0
  45. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/identity_spec.rb +1 -0
  46. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/ssh_identity_spec.rb +1 -0
  47. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit_spec.rb +5 -0
  48. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/spec_helper.rb +8 -0
  49. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/AUTHORS +3 -0
  50. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/COPYING +339 -0
  51. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Changelog.md +415 -0
  52. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Gemfile +9 -0
  53. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/INSTALL +59 -0
  54. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/LICENSE +7 -0
  55. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/README.rdoc +74 -0
  56. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Rakefile +30 -0
  57. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/TODO +6 -0
  58. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/ansi_colors.rb +38 -0
  59. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/asking_for_arrays.rb +18 -0
  60. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/basic_usage.rb +75 -0
  61. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/color_scheme.rb +32 -0
  62. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/get_character.rb +12 -0
  63. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/limit.rb +12 -0
  64. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/menus.rb +65 -0
  65. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/overwrite.rb +19 -0
  66. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/page_and_wrap.rb +322 -0
  67. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/password.rb +7 -0
  68. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/repeat_entry.rb +21 -0
  69. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/trapping_eof.rb +22 -0
  70. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/using_readline.rb +17 -0
  71. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/highline.gemspec +37 -0
  72. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline.rb +1048 -0
  73. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/color_scheme.rb +134 -0
  74. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/compatibility.rb +16 -0
  75. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/import.rb +41 -0
  76. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/menu.rb +381 -0
  77. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/question.rb +480 -0
  78. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/simulate.rb +48 -0
  79. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/style.rb +192 -0
  80. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/version.rb +4 -0
  81. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/setup.rb +1360 -0
  82. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/highline.css +65 -0
  83. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/images/logo.png +0 -0
  84. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/index.html +58 -0
  85. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/string_methods.rb +32 -0
  86. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_color_scheme.rb +96 -0
  87. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_highline.rb +1402 -0
  88. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_import.rb +52 -0
  89. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_menu.rb +439 -0
  90. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_simulator.rb +23 -0
  91. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_string_highline.rb +38 -0
  92. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_style.rb +578 -0
  93. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/BSDL +22 -0
  94. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/COPYING +57 -0
  95. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/Gemfile +9 -0
  96. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/LEGAL +4 -0
  97. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/README.rdoc +19 -0
  98. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/Rakefile +16 -0
  99. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/benchmarks/bm_yhpg.rb +59 -0
  100. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/benchmarks/helper.rb +8 -0
  101. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert.rb +338 -0
  102. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert/enable_tracepoint_events.rb +82 -0
  103. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert/version.rb +3 -0
  104. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/power_assert.gemspec +23 -0
  105. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/test/helper.rb +10 -0
  106. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/test/test_power_assert.rb +512 -0
  107. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/CONTRIBUTING.rdoc +38 -0
  108. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/History.rdoc +719 -0
  109. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/MIT-LICENSE +21 -0
  110. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/Manifest.txt +154 -0
  111. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/README.rdoc +157 -0
  112. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/Rakefile +82 -0
  113. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/bin/rake +33 -0
  114. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/command_line_usage.rdoc +158 -0
  115. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/Rakefile1 +38 -0
  116. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/Rakefile2 +35 -0
  117. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/a.c +6 -0
  118. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/b.c +6 -0
  119. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/main.c +11 -0
  120. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/glossary.rdoc +42 -0
  121. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/jamis.rb +591 -0
  122. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/proto_rake.rdoc +127 -0
  123. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rake.1 +141 -0
  124. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rakefile.rdoc +624 -0
  125. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rational.rdoc +151 -0
  126. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.4.14.rdoc +23 -0
  127. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.4.15.rdoc +35 -0
  128. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.0.rdoc +53 -0
  129. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.3.rdoc +78 -0
  130. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.4.rdoc +46 -0
  131. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.6.0.rdoc +141 -0
  132. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.0.rdoc +119 -0
  133. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.1.rdoc +59 -0
  134. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.2.rdoc +121 -0
  135. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.3.rdoc +47 -0
  136. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.0.rdoc +114 -0
  137. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.2.rdoc +165 -0
  138. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.3.rdoc +112 -0
  139. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.4.rdoc +147 -0
  140. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.5.rdoc +53 -0
  141. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.6.rdoc +37 -0
  142. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.7.rdoc +55 -0
  143. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.0.rdoc +112 -0
  144. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.1.rdoc +52 -0
  145. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.2.2.rdoc +55 -0
  146. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.2.rdoc +49 -0
  147. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.3.rdoc +102 -0
  148. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.4.rdoc +60 -0
  149. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.5.rdoc +55 -0
  150. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.6.rdoc +64 -0
  151. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.0.rdoc +178 -0
  152. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.1.rdoc +58 -0
  153. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.2.rdoc +53 -0
  154. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.3.rdoc +191 -0
  155. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.1.0.rdoc +61 -0
  156. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake.rb +73 -0
  157. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/application.rb +787 -0
  158. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/backtrace.rb +23 -0
  159. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/clean.rb +76 -0
  160. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/cloneable.rb +16 -0
  161. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/compositepublisher.rb +21 -0
  162. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/ftptools.rb +137 -0
  163. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/sshpublisher.rb +60 -0
  164. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/cpu_counter.rb +120 -0
  165. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/default_loader.rb +14 -0
  166. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/dsl_definition.rb +194 -0
  167. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/early_time.rb +21 -0
  168. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_creation_task.rb +24 -0
  169. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_list.rb +436 -0
  170. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_task.rb +46 -0
  171. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_utils.rb +123 -0
  172. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/invocation_chain.rb +56 -0
  173. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/invocation_exception_mixin.rb +16 -0
  174. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/late_time.rb +17 -0
  175. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/linked_list.rb +111 -0
  176. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/loaders/makefile.rb +53 -0
  177. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/multi_task.rb +13 -0
  178. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/name_space.rb +38 -0
  179. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/packagetask.rb +199 -0
  180. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/phony.rb +15 -0
  181. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/private_reader.rb +20 -0
  182. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/promise.rb +99 -0
  183. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/pseudo_status.rb +29 -0
  184. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rake_module.rb +38 -0
  185. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rake_test_loader.rb +22 -0
  186. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  187. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/scope.rb +42 -0
  188. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task.rb +391 -0
  189. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_argument_error.rb +7 -0
  190. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_arguments.rb +102 -0
  191. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_manager.rb +316 -0
  192. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/tasklib.rb +11 -0
  193. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/testtask.rb +204 -0
  194. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/thread_history_display.rb +48 -0
  195. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/thread_pool.rb +163 -0
  196. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/trace_output.rb +22 -0
  197. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/version.rb +7 -0
  198. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/win32.rb +50 -0
  199. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/rakelib/test_times.rake +25 -0
  200. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/file_creation.rb +34 -0
  201. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/helper.rb +134 -0
  202. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/support/rakefile_definitions.rb +476 -0
  203. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/support/ruby_runner.rb +34 -0
  204. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_private_reader.rb +42 -0
  205. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake.rb +40 -0
  206. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_application.rb +659 -0
  207. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_application_options.rb +468 -0
  208. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_backtrace.rb +119 -0
  209. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_clean.rb +61 -0
  210. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_cpu_counter.rb +68 -0
  211. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_definitions.rb +84 -0
  212. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_directory_task.rb +76 -0
  213. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_dsl.rb +40 -0
  214. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_early_time.rb +31 -0
  215. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_creation_task.rb +56 -0
  216. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_list.rb +687 -0
  217. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_list_path_map.rb +15 -0
  218. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_task.rb +197 -0
  219. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_utils.rb +318 -0
  220. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_ftp_file.rb +74 -0
  221. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_functional.rb +484 -0
  222. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_invocation_chain.rb +64 -0
  223. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_late_time.rb +18 -0
  224. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_linked_list.rb +84 -0
  225. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_makefile_loader.rb +46 -0
  226. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_multi_task.rb +64 -0
  227. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_name_space.rb +57 -0
  228. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_package_task.rb +79 -0
  229. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map.rb +168 -0
  230. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map_explode.rb +34 -0
  231. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map_partial.rb +18 -0
  232. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_pseudo_status.rb +21 -0
  233. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_rake_test_loader.rb +20 -0
  234. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_reduce_compat.rb +26 -0
  235. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_require.rb +40 -0
  236. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_rules.rb +388 -0
  237. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_scope.rb +44 -0
  238. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task.rb +430 -0
  239. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_argument_parsing.rb +119 -0
  240. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_arguments.rb +134 -0
  241. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_manager.rb +178 -0
  242. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_manager_argument_resolution.rb +19 -0
  243. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_with_arguments.rb +172 -0
  244. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_test_task.rb +130 -0
  245. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_thread_pool.rb +145 -0
  246. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_top_level_functions.rb +71 -0
  247. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_win32.rb +72 -0
  248. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_thread_history_display.rb +101 -0
  249. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_trace_output.rb +52 -0
  250. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/COPYING +64 -0
  251. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/GPL +339 -0
  252. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/LGPL +502 -0
  253. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/PSFL +271 -0
  254. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/README.md +101 -0
  255. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/Rakefile +71 -0
  256. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test-unit.rb +34 -0
  257. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit.rb +505 -0
  258. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/assertion-failed-error.rb +25 -0
  259. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/assertions.rb +2218 -0
  260. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/attribute-matcher.rb +26 -0
  261. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/attribute.rb +158 -0
  262. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/auto-runner-loader.rb +17 -0
  263. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/autorunner.rb +536 -0
  264. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/code-snippet-fetcher.rb +58 -0
  265. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector.rb +73 -0
  266. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/descendant.rb +19 -0
  267. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/dir.rb +108 -0
  268. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/load.rb +202 -0
  269. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/objectspace.rb +34 -0
  270. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/xml.rb +249 -0
  271. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/color-scheme.rb +198 -0
  272. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/color.rb +134 -0
  273. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/data.rb +262 -0
  274. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/diff.rb +746 -0
  275. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/error.rb +158 -0
  276. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/exception-handler.rb +82 -0
  277. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/failure.rb +169 -0
  278. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/fault-location-detector.rb +100 -0
  279. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/fixture.rb +295 -0
  280. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/notification.rb +136 -0
  281. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/omission.rb +195 -0
  282. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/pending.rb +154 -0
  283. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/priority.rb +192 -0
  284. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/console.rb +59 -0
  285. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/emacs.rb +8 -0
  286. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/xml.rb +15 -0
  287. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/test-suite-creator.rb +89 -0
  288. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testcase.rb +811 -0
  289. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testresult.rb +132 -0
  290. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testsuite.rb +175 -0
  291. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/console/outputlevel.rb +15 -0
  292. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/console/testrunner.rb +693 -0
  293. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  294. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunner.rb +53 -0
  295. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunnermediator.rb +114 -0
  296. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  297. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/xml/testrunner.rb +224 -0
  298. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/backtracefilter.rb +59 -0
  299. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/method-owner-finder.rb +28 -0
  300. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/observable.rb +90 -0
  301. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/output.rb +31 -0
  302. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/procwrapper.rb +48 -0
  303. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/version.rb +5 -0
  304. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/adder.rb +13 -0
  305. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/subtracter.rb +12 -0
  306. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_adder.rb +20 -0
  307. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_subtracter.rb +20 -0
  308. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_user.rb +23 -0
  309. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test-descendant.rb +178 -0
  310. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test-load.rb +442 -0
  311. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test_dir.rb +406 -0
  312. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test_objectspace.rb +100 -0
  313. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header-label.csv +3 -0
  314. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header-label.tsv +3 -0
  315. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header.csv +3 -0
  316. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header.tsv +3 -0
  317. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/no-header.csv +2 -0
  318. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/no-header.tsv +2 -0
  319. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/plus.csv +3 -0
  320. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/run-test.rb +22 -0
  321. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-assertions.rb +2160 -0
  322. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-attribute-matcher.rb +38 -0
  323. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-attribute.rb +123 -0
  324. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-code-snippet.rb +37 -0
  325. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-color-scheme.rb +82 -0
  326. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-color.rb +47 -0
  327. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-data.rb +303 -0
  328. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-diff.rb +518 -0
  329. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-emacs-runner.rb +60 -0
  330. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-error.rb +26 -0
  331. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-failure.rb +33 -0
  332. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-fault-location-detector.rb +163 -0
  333. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-fixture.rb +713 -0
  334. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-notification.rb +33 -0
  335. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-omission.rb +81 -0
  336. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-pending.rb +70 -0
  337. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-priority.rb +173 -0
  338. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-case.rb +1171 -0
  339. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-result.rb +113 -0
  340. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-suite-creator.rb +97 -0
  341. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-suite.rb +150 -0
  342. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/testunit-test-util.rb +31 -0
  343. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/ui/test_testrunmediator.rb +20 -0
  344. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test-method-owner-finder.rb +38 -0
  345. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test-output.rb +11 -0
  346. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_backtracefilter.rb +52 -0
  347. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_observable.rb +102 -0
  348. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_procwrapper.rb +36 -0
  349. data/vendor/bundle/ruby/2.2.0/specifications/colorize-0.7.7.gemspec +38 -0
  350. data/vendor/bundle/ruby/2.2.0/specifications/devkit-0.1.0.gemspec +46 -0
  351. data/vendor/bundle/ruby/2.2.0/specifications/highline-1.7.8.gemspec +37 -0
  352. data/vendor/bundle/ruby/2.2.0/specifications/power_assert-0.3.0.gemspec +41 -0
  353. data/vendor/bundle/ruby/2.2.0/specifications/rake-11.1.2.gemspec +43 -0
  354. data/vendor/bundle/ruby/2.2.0/specifications/test-unit-3.1.9.gemspec +47 -0
  355. data/win32-api.gemspec +27 -27
  356. metadata +345 -5
  357. data/lib/win32/ruby18/win32/api.so +0 -0
  358. data/lib/win32/ruby19/win32/api.so +0 -0
@@ -0,0 +1,134 @@
1
+ module Test
2
+ module Unit
3
+ class Color
4
+ class Error < StandardError
5
+ end
6
+
7
+ class ParseError < Error
8
+ end
9
+
10
+ class << self
11
+ def parse_256_color(string)
12
+ case string
13
+ when /\A([0-5])([0-5])([0-5])\z/
14
+ red, green, blue = $1, $2, $3
15
+ red.to_i * 36 + green.to_i * 6 + blue.to_i + 16
16
+ else
17
+ message = "must be 'RGB' format and R, G and B " +
18
+ "are in 0-5: #{string.inspect}"
19
+ raise ParseError, message
20
+ end
21
+ end
22
+ end
23
+
24
+ NAMES = ["black", "red", "green", "yellow",
25
+ "blue", "magenta", "cyan", "white"]
26
+
27
+ attr_reader :name
28
+ def initialize(name, options={})
29
+ @name = name
30
+ if options.has_key?(:foreground)
31
+ if options[:foreground].nil?
32
+ @background = false
33
+ else
34
+ @background = !options[:foreground]
35
+ end
36
+ else
37
+ @background = options[:background]
38
+ end
39
+ @intensity = options[:intensity]
40
+ @bold = options[:bold]
41
+ @italic = options[:italic]
42
+ @underline = options[:underline]
43
+ end
44
+
45
+ def foreground?
46
+ not background?
47
+ end
48
+
49
+ def background?
50
+ @background
51
+ end
52
+
53
+ def intensity?
54
+ @intensity
55
+ end
56
+
57
+ def bold?
58
+ @bold
59
+ end
60
+
61
+ def italic?
62
+ @italic
63
+ end
64
+
65
+ def underline?
66
+ @underline
67
+ end
68
+
69
+ def ==(other)
70
+ self.class === other and
71
+ [name, background?, intensity?,
72
+ bold?, italic?, underline?] ==
73
+ [other.name, other.background?, other.intensity?,
74
+ other.bold?, other.italic?, other.underline?]
75
+ end
76
+
77
+ def sequence
78
+ sequence = []
79
+ if @name == "none"
80
+ elsif @name == "reset"
81
+ sequence << "0"
82
+ else
83
+ if NAMES.include?(@name)
84
+ color_parameter = foreground? ? 3 : 4
85
+ color_parameter += 6 if intensity?
86
+ color = NAMES.index(@name)
87
+ sequence << "#{color_parameter}#{color}"
88
+ else
89
+ sequence << (foreground? ? "38" : "48")
90
+ sequence << "5"
91
+ sequence << self.class.parse_256_color(@name).to_s
92
+ end
93
+ end
94
+ sequence << "1" if bold?
95
+ sequence << "3" if italic?
96
+ sequence << "4" if underline?
97
+ sequence
98
+ end
99
+
100
+ def escape_sequence
101
+ "\e[#{sequence.join(';')}m"
102
+ end
103
+
104
+ def +(other)
105
+ MixColor.new([self, other])
106
+ end
107
+ end
108
+
109
+ class MixColor
110
+ attr_reader :colors
111
+ def initialize(colors)
112
+ @colors = colors
113
+ end
114
+
115
+ def sequence
116
+ @colors.inject([]) do |result, color|
117
+ result + color.sequence
118
+ end
119
+ end
120
+
121
+ def escape_sequence
122
+ "\e[#{sequence.join(';')}m"
123
+ end
124
+
125
+ def +(other)
126
+ self.class.new([self, other])
127
+ end
128
+
129
+ def ==(other)
130
+ self.class === other and colors == other.colors
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,262 @@
1
+ module Test
2
+ module Unit
3
+ module Data
4
+ class << self
5
+ def included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ # This method provides Data-Driven-Test functionality.
12
+ #
13
+ # Define test data in the test code.
14
+ #
15
+ # @overload data(label, data)
16
+ # @param [String] label specify test case name.
17
+ # @param data specify test data.
18
+ #
19
+ # @example data(label, data)
20
+ # data("empty string", [true, ""])
21
+ # data("plain string", [false, "hello"])
22
+ # def test_empty?(data)
23
+ # expected, target = data
24
+ # assert_equal(expected, target.empty?)
25
+ # end
26
+ #
27
+ # @overload data(data_set)
28
+ # @param [Hash] data_set specify test data as a Hash that
29
+ # key is test label and value is test data.
30
+ #
31
+ # @example data(data_set)
32
+ # data("empty string" => [true, ""],
33
+ # "plain string" => [false, "hello"])
34
+ # def test_empty?(data)
35
+ # expected, target = data
36
+ # assert_equal(expected, target.empty?)
37
+ # end
38
+ #
39
+ # @overload data(&block)
40
+ # @yieldreturn [Hash] return test data set as a Hash that
41
+ # key is test label and value is test data.
42
+ #
43
+ # @example data(&block)
44
+ # data do
45
+ # data_set = {}
46
+ # data_set["empty string"] = [true, ""]
47
+ # data_set["plain string"] = [false, "hello"]
48
+ # data_set
49
+ # end
50
+ # def test_empty?(data)
51
+ # expected, target = data
52
+ # assert_equal(expected, target.empty?)
53
+ # end
54
+ #
55
+ def data(*arguments, &block)
56
+ n_arguments = arguments.size
57
+ case n_arguments
58
+ when 0
59
+ raise ArgumentError, "no block is given" unless block_given?
60
+ data_set = block
61
+ when 1
62
+ data_set = arguments[0]
63
+ when 2
64
+ data_set = {arguments[0] => arguments[1]}
65
+ else
66
+ message = "wrong number arguments(#{n_arguments} for 1..2)"
67
+ raise ArgumentError, message
68
+ end
69
+ current_data = current_attribute(:data)[:value] || []
70
+ attribute(:data, current_data + [data_set])
71
+ end
72
+
73
+ # This method provides Data-Driven-Test functionality.
74
+ #
75
+ # Load test data from the file. This is shorthand to load
76
+ # test data from file. If you want to load complex file, you
77
+ # can use {#data} with block.
78
+ #
79
+ # @param [String] file_name full path to test data file.
80
+ # File format is automatically detected from filename extension.
81
+ # @raise [ArgumentError] if +file_name+ is not supported file format.
82
+ # @see Loader#load
83
+ #
84
+ # @example Load data from CSV file
85
+ # load_data("/path/to/test-data.csv")
86
+ # def test_empty?(data)
87
+ # assert_equal(data["expected"], data["target"].empty?)
88
+ # end
89
+ #
90
+ def load_data(file_name)
91
+ loader = Loader.new(self)
92
+ loader.load(file_name)
93
+ end
94
+
95
+ class Loader
96
+ # @api private
97
+ def initialize(test_case)
98
+ @test_case = test_case
99
+ end
100
+
101
+ # Load data from file.
102
+ #
103
+ # @param [String] file_name full path to test data file.
104
+ # File format is automatically detected from filename extension.
105
+ # @raise [ArgumentError] if +file_name+ is not supported file format.
106
+ # @see #load_csv
107
+ # @see #load_tsv
108
+ # @api private
109
+ def load(file_name)
110
+ case File.extname(file_name).downcase
111
+ when ".csv"
112
+ load_csv(file_name)
113
+ when ".tsv"
114
+ load_tsv(file_name)
115
+ else
116
+ raise ArgumentError, "unsupported file format: <#{file_name}>"
117
+ end
118
+ end
119
+
120
+ # Load data from CSV file.
121
+ #
122
+ # There are 2 types of CSV file as following examples.
123
+ # First, there is a header on first row and it's first column is "label".
124
+ # Another, there is no header in the file.
125
+ #
126
+ # @example Load data from CSV file with header
127
+ # # test-data.csv:
128
+ # # label,expected,target
129
+ # # empty string,true,""
130
+ # # plain string,false,hello
131
+ # #
132
+ # load_data("/path/to/test-data.csv")
133
+ # def test_empty?(data)
134
+ # assert_equal(data["expected"], data["target"].empty?)
135
+ # end
136
+ #
137
+ # @example Load data from CSV file without header
138
+ # # test-data-without-header.csv:
139
+ # # empty string,true,""
140
+ # # plain string,false,hello
141
+ # #
142
+ # load_data("/path/to/test-data-without-header.csv")
143
+ # def test_empty?(data)
144
+ # expected, target = data
145
+ # assert_equal(expected, target.empty?)
146
+ # end
147
+ #
148
+ # @api private
149
+ def load_csv(file_name)
150
+ require 'csv'
151
+ first_row = true
152
+ header = nil
153
+ CSV.foreach(file_name) do |row|
154
+ if first_row
155
+ first_row = false
156
+ if row.first == "label"
157
+ header = row[1..-1]
158
+ next
159
+ end
160
+ end
161
+
162
+ set_test_data(header, row)
163
+ end
164
+ end
165
+
166
+ # Load data from TSV file.
167
+ #
168
+ # There are 2 types of TSV file as following examples.
169
+ # First, there is a header on first row and it's first column is "label".
170
+ # Another, there is no header in the file.
171
+ #
172
+ # @example Load data from TSV file with header
173
+ # # test-data.tsv:
174
+ # # label expected target
175
+ # # empty string true ""
176
+ # # plain string false hello
177
+ # #
178
+ # load_data("/path/to/test-data.tsv")
179
+ # def test_empty?(data)
180
+ # assert_equal(data["expected"], data["target"].empty?)
181
+ # end
182
+ #
183
+ # @example Load data from TSV file without header
184
+ # # test-data-without-header.tsv:
185
+ # # empty string true ""
186
+ # # plain string false hello
187
+ # #
188
+ # load_data("/path/to/test-data-without-header.tsv")
189
+ # def test_empty?(data)
190
+ # expected, target = data
191
+ # assert_equal(expected, target.empty?)
192
+ # end
193
+ #
194
+ # @api private
195
+ def load_tsv(file_name)
196
+ require "csv"
197
+ if CSV.const_defined?(:VERSION)
198
+ first_row = true
199
+ header = nil
200
+ CSV.foreach(file_name, :col_sep => "\t") do |row|
201
+ if first_row
202
+ first_row = false
203
+ if row.first == "label"
204
+ header = row[1..-1]
205
+ next
206
+ end
207
+ end
208
+
209
+ set_test_data(header, row)
210
+ end
211
+ else
212
+ # for old CSV library
213
+ first_row = true
214
+ header = nil
215
+ CSV.open(file_name, "r", "\t") do |row|
216
+ if first_row
217
+ first_row = false
218
+ if row.first == "label"
219
+ header = row[1..-1]
220
+ next
221
+ end
222
+ end
223
+
224
+ set_test_data(header, row)
225
+ end
226
+ end
227
+ end
228
+
229
+ private
230
+ def normalize_value(value)
231
+ return true if value == "true"
232
+ return false if value == "false"
233
+ begin
234
+ Integer(value)
235
+ rescue ArgumentError
236
+ begin
237
+ Float(value)
238
+ rescue ArgumentError
239
+ value
240
+ end
241
+ end
242
+ end
243
+
244
+ def set_test_data(header, row)
245
+ label = row.shift
246
+ if header
247
+ data = {}
248
+ header.each_with_index do |key, i|
249
+ data[key] = normalize_value(row[i])
250
+ end
251
+ else
252
+ data = row.collect do |cell|
253
+ normalize_value(cell)
254
+ end
255
+ end
256
+ @test_case.data(label, data)
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,746 @@
1
+ # port of Python's difflib.
2
+ #
3
+ # Copyright (c) 2001-2008 Python Software Foundation; All Rights Reserved
4
+ # Copyright (c) 2008-2011 Kouhei Sutou; All Rights Reserved
5
+ #
6
+ # It is free software, and is distributed under the Ruby
7
+ # license and/or the PSF license. See the COPYING file and
8
+ # PSFL file.
9
+
10
+ module Test
11
+ module Unit
12
+ module Diff
13
+ class SequenceMatcher
14
+ def initialize(from, to, &junk_predicate)
15
+ @from = from
16
+ @to = to
17
+ @junk_predicate = junk_predicate
18
+ update_to_indexes
19
+ end
20
+
21
+ def longest_match(from_start, from_end, to_start, to_end)
22
+ best_info = find_best_match_position(from_start, from_end,
23
+ to_start, to_end)
24
+ unless @junks.empty?
25
+ args = [from_start, from_end, to_start, to_end]
26
+ best_info = adjust_best_info_with_junk_predicate(false, best_info,
27
+ *args)
28
+ best_info = adjust_best_info_with_junk_predicate(true, best_info,
29
+ *args)
30
+ end
31
+
32
+ best_info
33
+ end
34
+
35
+ def blocks
36
+ @blocks ||= compute_blocks
37
+ end
38
+
39
+ def operations
40
+ @operations ||= compute_operations
41
+ end
42
+
43
+ def grouped_operations(context_size=nil)
44
+ context_size ||= 3
45
+ _operations = operations.dup
46
+ _operations = [[:equal, 0, 0, 0, 0]] if _operations.empty?
47
+ expand_edge_equal_operations!(_operations, context_size)
48
+
49
+ group_window = context_size * 2
50
+ groups = []
51
+ group = []
52
+ _operations.each do |tag, from_start, from_end, to_start, to_end|
53
+ if tag == :equal and from_end - from_start > group_window
54
+ group << [tag,
55
+ from_start,
56
+ [from_end, from_start + context_size].min,
57
+ to_start,
58
+ [to_end, to_start + context_size].min]
59
+ groups << group
60
+ group = []
61
+ from_start = [from_start, from_end - context_size].max
62
+ to_start = [to_start, to_end - context_size].max
63
+ end
64
+ group << [tag, from_start, from_end, to_start, to_end]
65
+ end
66
+ groups << group unless group.empty?
67
+ groups
68
+ end
69
+
70
+ def ratio
71
+ @ratio ||= compute_ratio
72
+ end
73
+
74
+ private
75
+ def update_to_indexes
76
+ @to_indexes = {}
77
+ @junks = {}
78
+ if @to.is_a?(String)
79
+ each = " "[0].is_a?(Integer) ? :each_byte : :each_char
80
+ else
81
+ each = :each
82
+ end
83
+ i = 0
84
+ @to.__send__(each) do |item|
85
+ @to_indexes[item] ||= []
86
+ @to_indexes[item] << i
87
+ i += 1
88
+ end
89
+
90
+ return if @junk_predicate.nil?
91
+ @to_indexes = @to_indexes.reject do |key, value|
92
+ junk = @junk_predicate.call(key)
93
+ @junks[key] = true if junk
94
+ junk
95
+ end
96
+ end
97
+
98
+ def find_best_match_position(from_start, from_end, to_start, to_end)
99
+ best_from, best_to, best_size = from_start, to_start, 0
100
+ sizes = {}
101
+ from_start.upto(from_end) do |from_index|
102
+ _sizes = {}
103
+ (@to_indexes[@from[from_index]] || []).each do |to_index|
104
+ next if to_index < to_start
105
+ break if to_index > to_end
106
+ size = _sizes[to_index] = (sizes[to_index - 1] || 0) + 1
107
+ if size > best_size
108
+ best_from = from_index - size + 1
109
+ best_to = to_index - size + 1
110
+ best_size = size
111
+ end
112
+ end
113
+ sizes = _sizes
114
+ end
115
+ [best_from, best_to, best_size]
116
+ end
117
+
118
+ def adjust_best_info_with_junk_predicate(should_junk, best_info,
119
+ from_start, from_end,
120
+ to_start, to_end)
121
+ best_from, best_to, best_size = best_info
122
+ while best_from > from_start and best_to > to_start and
123
+ (should_junk ?
124
+ @junks.has_key?(@to[best_to - 1]) :
125
+ !@junks.has_key?(@to[best_to - 1])) and
126
+ @from[best_from - 1] == @to[best_to - 1]
127
+ best_from -= 1
128
+ best_to -= 1
129
+ best_size += 1
130
+ end
131
+
132
+ while best_from + best_size < from_end and
133
+ best_to + best_size < to_end and
134
+ (should_junk ?
135
+ @junks.has_key?(@to[best_to + best_size]) :
136
+ !@junks.has_key?(@to[best_to + best_size])) and
137
+ @from[best_from + best_size] == @to[best_to + best_size]
138
+ best_size += 1
139
+ end
140
+
141
+ [best_from, best_to, best_size]
142
+ end
143
+
144
+ def matches
145
+ @matches ||= compute_matches
146
+ end
147
+
148
+ def compute_matches
149
+ matches = []
150
+ queue = [[0, @from.size, 0, @to.size]]
151
+ until queue.empty?
152
+ from_start, from_end, to_start, to_end = queue.pop
153
+ match = longest_match(from_start, from_end - 1, to_start, to_end - 1)
154
+ match_from_index, match_to_index, size = match
155
+ unless size.zero?
156
+ if from_start < match_from_index and
157
+ to_start < match_to_index
158
+ queue.push([from_start, match_from_index,
159
+ to_start, match_to_index])
160
+ end
161
+ matches << match
162
+ if match_from_index + size < from_end and
163
+ match_to_index + size < to_end
164
+ queue.push([match_from_index + size, from_end,
165
+ match_to_index + size, to_end])
166
+ end
167
+ end
168
+ end
169
+ matches.sort_by do |(from_index, _, _)|
170
+ from_index
171
+ end
172
+ end
173
+
174
+ def compute_blocks
175
+ blocks = []
176
+ current_from_index = current_to_index = current_size = 0
177
+ matches.each do |from_index, to_index, size|
178
+ if current_from_index + current_size == from_index and
179
+ current_to_index + current_size == to_index
180
+ current_size += size
181
+ else
182
+ unless current_size.zero?
183
+ blocks << [current_from_index, current_to_index, current_size]
184
+ end
185
+ current_from_index = from_index
186
+ current_to_index = to_index
187
+ current_size = size
188
+ end
189
+ end
190
+ unless current_size.zero?
191
+ blocks << [current_from_index, current_to_index, current_size]
192
+ end
193
+
194
+ blocks << [@from.size, @to.size, 0]
195
+ blocks
196
+ end
197
+
198
+ def compute_operations
199
+ from_index = to_index = 0
200
+ operations = []
201
+ blocks.each do |match_from_index, match_to_index, size|
202
+ tag = determine_tag(from_index, to_index,
203
+ match_from_index, match_to_index)
204
+ if tag != :equal
205
+ operations << [tag,
206
+ from_index, match_from_index,
207
+ to_index, match_to_index]
208
+ end
209
+
210
+ from_index, to_index = match_from_index + size, match_to_index + size
211
+ if size > 0
212
+ operations << [:equal,
213
+ match_from_index, from_index,
214
+ match_to_index, to_index]
215
+ end
216
+ end
217
+ operations
218
+ end
219
+
220
+ def compute_ratio
221
+ matches = blocks.inject(0) {|result, block| result + block[-1]}
222
+ length = @from.length + @to.length
223
+ if length.zero?
224
+ 1.0
225
+ else
226
+ 2.0 * matches / length
227
+ end
228
+ end
229
+
230
+ def determine_tag(from_index, to_index,
231
+ match_from_index, match_to_index)
232
+ if from_index < match_from_index and to_index < match_to_index
233
+ :replace
234
+ elsif from_index < match_from_index
235
+ :delete
236
+ elsif to_index < match_to_index
237
+ :insert
238
+ else
239
+ :equal
240
+ end
241
+ end
242
+
243
+ def expand_edge_equal_operations!(_operations, context_size)
244
+ tag, from_start, from_end, to_start, to_end = _operations[0]
245
+ if tag == :equal
246
+ _operations[0] = [tag,
247
+ [from_start, from_end - context_size].max,
248
+ from_end,
249
+ [to_start, to_end - context_size].max,
250
+ to_end]
251
+ end
252
+
253
+ tag, from_start, from_end, to_start, to_end = _operations[-1]
254
+ if tag == :equal
255
+ _operations[-1] = [tag,
256
+ from_start,
257
+ [from_end, from_start + context_size].min,
258
+ to_start,
259
+ [to_end, to_start + context_size].min]
260
+ end
261
+ end
262
+ end
263
+
264
+ class Differ
265
+ def initialize(from, to)
266
+ @from = from
267
+ @to = to
268
+ end
269
+
270
+ private
271
+ def tag(mark, contents)
272
+ contents.collect {|content| "#{mark}#{content}"}
273
+ end
274
+ end
275
+
276
+ class UTF8Line
277
+ class << self
278
+ # from http://unicode.org/reports/tr11/
279
+ WIDE_CHARACTERS =
280
+ [0x1100..0x1159, 0x115F..0x115F, 0x2329..0x232A,
281
+ 0x2E80..0x2E99, 0x2E9B..0x2EF3, 0x2F00..0x2FD5,
282
+ 0x2FF0..0x2FFB, 0x3000..0x303E, 0x3041..0x3096,
283
+ 0x3099..0x30FF, 0x3105..0x312D, 0x3131..0x318E,
284
+ 0x3190..0x31B7, 0x31C0..0x31E3, 0x31F0..0x321E,
285
+ 0x3220..0x3243, 0x3250..0x32FE, 0x3300..0x4DB5,
286
+ 0x4E00..0x9FC3, 0xA000..0xA48C, 0xA490..0xA4C6,
287
+ 0xAC00..0xD7A3, 0xF900..0xFA2D, 0xFA30..0xFA6A,
288
+ 0xFA70..0xFAD9, 0xFE10..0xFE19, 0xFE30..0xFE52,
289
+ 0xFE54..0xFE66, 0xFE68..0xFE6B, 0xFF01..0xFF60,
290
+ 0xFFE0..0xFFE6, 0x20000..0x2FFFD, 0x30000..0x3FFFD,
291
+ ]
292
+
293
+ AMBIGUOUS =
294
+ [0x00A1..0x00A1, 0x00A4..0x00A4, 0x00A7..0x00A8,
295
+ 0x00AA..0x00AA, 0x00AD..0x00AE, 0x00B0..0x00B4,
296
+ 0x00B6..0x00BA, 0x00BC..0x00BF, 0x00C6..0x00C6,
297
+ 0x00D0..0x00D0, 0x00D7..0x00D8, 0x00DE..0x00E1,
298
+ 0x00E6..0x00E6, 0x00E8..0x00EA, 0x00EC..0x00ED,
299
+ 0x00F0..0x00F0, 0x00F2..0x00F3, 0x00F7..0x00FA,
300
+ 0x00FC..0x00FC, 0x00FE..0x00FE, 0x0101..0x0101,
301
+ 0x0111..0x0111, 0x0113..0x0113, 0x011B..0x011B,
302
+ 0x0126..0x0127, 0x012B..0x012B, 0x0131..0x0133,
303
+ 0x0138..0x0138, 0x013F..0x0142, 0x0144..0x0144,
304
+ 0x0148..0x014B, 0x014D..0x014D, 0x0152..0x0153,
305
+ 0x0166..0x0167, 0x016B..0x016B, 0x01CE..0x01CE,
306
+ 0x01D0..0x01D0, 0x01D2..0x01D2, 0x01D4..0x01D4,
307
+ 0x01D6..0x01D6, 0x01D8..0x01D8, 0x01DA..0x01DA,
308
+ 0x01DC..0x01DC, 0x0251..0x0251, 0x0261..0x0261,
309
+ 0x02C4..0x02C4, 0x02C7..0x02C7, 0x02C9..0x02CB,
310
+ 0x02CD..0x02CD, 0x02D0..0x02D0, 0x02D8..0x02DB,
311
+ 0x02DD..0x02DD, 0x02DF..0x02DF, 0x0300..0x036F,
312
+ 0x0391..0x03A1, 0x03A3..0x03A9, 0x03B1..0x03C1,
313
+ 0x03C3..0x03C9, 0x0401..0x0401, 0x0410..0x044F,
314
+ 0x0451..0x0451, 0x2010..0x2010, 0x2013..0x2016,
315
+ 0x2018..0x2019, 0x201C..0x201D, 0x2020..0x2022,
316
+ 0x2024..0x2027, 0x2030..0x2030, 0x2032..0x2033,
317
+ 0x2035..0x2035, 0x203B..0x203B, 0x203E..0x203E,
318
+ 0x2074..0x2074, 0x207F..0x207F, 0x2081..0x2084,
319
+ 0x20AC..0x20AC, 0x2103..0x2103, 0x2105..0x2105,
320
+ 0x2109..0x2109, 0x2113..0x2113, 0x2116..0x2116,
321
+ 0x2121..0x2122, 0x2126..0x2126, 0x212B..0x212B,
322
+ 0x2153..0x2154, 0x215B..0x215E, 0x2160..0x216B,
323
+ 0x2170..0x2179, 0x2190..0x2199, 0x21B8..0x21B9,
324
+ 0x21D2..0x21D2, 0x21D4..0x21D4, 0x21E7..0x21E7,
325
+ 0x2200..0x2200, 0x2202..0x2203, 0x2207..0x2208,
326
+ 0x220B..0x220B, 0x220F..0x220F, 0x2211..0x2211,
327
+ 0x2215..0x2215, 0x221A..0x221A, 0x221D..0x2220,
328
+ 0x2223..0x2223, 0x2225..0x2225, 0x2227..0x222C,
329
+ 0x222E..0x222E, 0x2234..0x2237, 0x223C..0x223D,
330
+ 0x2248..0x2248, 0x224C..0x224C, 0x2252..0x2252,
331
+ 0x2260..0x2261, 0x2264..0x2267, 0x226A..0x226B,
332
+ 0x226E..0x226F, 0x2282..0x2283, 0x2286..0x2287,
333
+ 0x2295..0x2295, 0x2299..0x2299, 0x22A5..0x22A5,
334
+ 0x22BF..0x22BF, 0x2312..0x2312, 0x2460..0x24E9,
335
+ 0x24EB..0x254B, 0x2550..0x2573, 0x2580..0x258F,
336
+ 0x2592..0x2595, 0x25A0..0x25A1, 0x25A3..0x25A9,
337
+ 0x25B2..0x25B3, 0x25B6..0x25B7, 0x25BC..0x25BD,
338
+ 0x25C0..0x25C1, 0x25C6..0x25C8, 0x25CB..0x25CB,
339
+ 0x25CE..0x25D1, 0x25E2..0x25E5, 0x25EF..0x25EF,
340
+ 0x2605..0x2606, 0x2609..0x2609, 0x260E..0x260F,
341
+ 0x2614..0x2615, 0x261C..0x261C, 0x261E..0x261E,
342
+ 0x2640..0x2640, 0x2642..0x2642, 0x2660..0x2661,
343
+ 0x2663..0x2665, 0x2667..0x266A, 0x266C..0x266D,
344
+ 0x266F..0x266F, 0x273D..0x273D, 0x2776..0x277F,
345
+ 0xE000..0xF8FF, 0xFE00..0xFE0F, 0xFFFD..0xFFFD,
346
+ 0xE0100..0xE01EF, 0xF0000..0xFFFFD, 0x100000..0x10FFFD,
347
+ ]
348
+
349
+ def wide_character?(character)
350
+ binary_search_ranges(character, WIDE_CHARACTERS) or
351
+ binary_search_ranges(character, AMBIGUOUS)
352
+ end
353
+
354
+ private
355
+ def binary_search_ranges(character, ranges)
356
+ if ranges.size.zero?
357
+ false
358
+ elsif ranges.size == 1
359
+ ranges[0].include?(character)
360
+ else
361
+ half = ranges.size / 2
362
+ range = ranges[half]
363
+ if range.include?(character)
364
+ true
365
+ elsif character < range.begin
366
+ binary_search_ranges(character, ranges[0...half])
367
+ else
368
+ binary_search_ranges(character, ranges[(half + 1)..-1])
369
+ end
370
+ end
371
+ end
372
+ end
373
+
374
+ def initialize(line)
375
+ @line = line
376
+ @characters = @line.unpack("U*")
377
+ end
378
+
379
+ def [](*args)
380
+ result = @characters[*args]
381
+ if result.respond_to?(:pack)
382
+ result.pack("U*")
383
+ else
384
+ result
385
+ end
386
+ end
387
+
388
+ def each(&block)
389
+ @characters.each(&block)
390
+ end
391
+
392
+ def size
393
+ @characters.size
394
+ end
395
+
396
+ def to_s
397
+ @line
398
+ end
399
+
400
+ def compute_width(start, _end)
401
+ width = 0
402
+ start.upto(_end - 1) do |i|
403
+ if self.class.wide_character?(@characters[i])
404
+ width += 2
405
+ else
406
+ width += 1
407
+ end
408
+ end
409
+ width
410
+ end
411
+ end
412
+
413
+ class ReadableDiffer < Differ
414
+ def diff(options={})
415
+ @result = []
416
+ operations.each do |tag, from_start, from_end, to_start, to_end|
417
+ case tag
418
+ when :replace
419
+ diff_lines(from_start, from_end, to_start, to_end)
420
+ when :delete
421
+ tag_deleted(@from[from_start...from_end])
422
+ when :insert
423
+ tag_inserted(@to[to_start...to_end])
424
+ when :equal
425
+ tag_equal(@from[from_start...from_end])
426
+ else
427
+ raise "unknown tag: #{tag}"
428
+ end
429
+ end
430
+ @result
431
+ end
432
+
433
+ private
434
+ def operations
435
+ @operations ||= nil
436
+ if @operations.nil?
437
+ matcher = SequenceMatcher.new(@from, @to)
438
+ @operations = matcher.operations
439
+ end
440
+ @operations
441
+ end
442
+
443
+ def default_ratio
444
+ 0.74
445
+ end
446
+
447
+ def cut_off_ratio
448
+ 0.75
449
+ end
450
+
451
+ def tag(mark, contents)
452
+ contents.each do |content|
453
+ @result << "#{mark}#{content}"
454
+ end
455
+ end
456
+
457
+ def tag_deleted(contents)
458
+ tag("- ", contents)
459
+ end
460
+
461
+ def tag_inserted(contents)
462
+ tag("+ ", contents)
463
+ end
464
+
465
+ def tag_equal(contents)
466
+ tag(" ", contents)
467
+ end
468
+
469
+ def tag_difference(contents)
470
+ tag("? ", contents)
471
+ end
472
+
473
+ def find_diff_line_info(from_start, from_end, to_start, to_end)
474
+ best_ratio = default_ratio
475
+ from_equal_index = to_equal_index = nil
476
+ from_best_index = to_best_index = nil
477
+
478
+ to_start.upto(to_end - 1) do |to_index|
479
+ from_start.upto(from_end - 1) do |from_index|
480
+ if @from[from_index] == @to[to_index]
481
+ from_equal_index ||= from_index
482
+ to_equal_index ||= to_index
483
+ next
484
+ end
485
+
486
+ matcher = SequenceMatcher.new(@from[from_index], @to[to_index],
487
+ &method(:space_character?))
488
+ if matcher.ratio > best_ratio
489
+ best_ratio = matcher.ratio
490
+ from_best_index = from_index
491
+ to_best_index = to_index
492
+ end
493
+ end
494
+ end
495
+
496
+ [best_ratio,
497
+ from_equal_index, to_equal_index,
498
+ from_best_index, to_best_index]
499
+ end
500
+
501
+ def diff_lines(from_start, from_end, to_start, to_end)
502
+ info = find_diff_line_info(from_start, from_end, to_start, to_end)
503
+ best_ratio, from_equal_index, to_equal_index, *info = info
504
+ from_best_index, to_best_index = info
505
+ from_best_index ||= from_start
506
+ to_best_index ||= to_start
507
+
508
+ if best_ratio < cut_off_ratio
509
+ if from_equal_index.nil?
510
+ if to_end - to_start < from_end - from_start
511
+ tag_inserted(@to[to_start...to_end])
512
+ tag_deleted(@from[from_start...from_end])
513
+ else
514
+ tag_deleted(@from[from_start...from_end])
515
+ tag_inserted(@to[to_start...to_end])
516
+ end
517
+ return
518
+ end
519
+ from_best_index = from_equal_index
520
+ to_best_index = to_equal_index
521
+ best_ratio = 1.0
522
+ end
523
+
524
+ _diff_lines(from_start, from_best_index, to_start, to_best_index)
525
+ diff_line(@from[from_best_index], @to[to_best_index])
526
+ _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end)
527
+ end
528
+
529
+ def _diff_lines(from_start, from_end, to_start, to_end)
530
+ if from_start < from_end
531
+ if to_start < to_end
532
+ diff_lines(from_start, from_end, to_start, to_end)
533
+ else
534
+ tag_deleted(@from[from_start...from_end])
535
+ end
536
+ else
537
+ tag_inserted(@to[to_start...to_end])
538
+ end
539
+ end
540
+
541
+ def line_operations(from_line, to_line)
542
+ if !from_line.respond_to?(:force_encoding) and $KCODE == "UTF8"
543
+ from_line = UTF8Line.new(from_line)
544
+ to_line = UTF8Line.new(to_line)
545
+ end
546
+ matcher = SequenceMatcher.new(from_line, to_line,
547
+ &method(:space_character?))
548
+ [from_line, to_line, matcher.operations]
549
+ end
550
+
551
+ def compute_width(line, start, _end)
552
+ if line.respond_to?(:encoding) and
553
+ Encoding.compatible?(Encoding::UTF_8, line.encoding)
554
+ utf8_line = line[start..._end].encode(Encoding::UTF_8)
555
+ width = 0
556
+ utf8_line.each_codepoint do |unicode_codepoint|
557
+ if UTF8Line.wide_character?(unicode_codepoint)
558
+ width += 2
559
+ else
560
+ width += 1
561
+ end
562
+ end
563
+ width
564
+ elsif line.is_a?(UTF8Line)
565
+ line.compute_width(start, _end)
566
+ else
567
+ _end - start
568
+ end
569
+ end
570
+
571
+ def diff_line(from_line, to_line)
572
+ from_tags = ""
573
+ to_tags = ""
574
+ from_line, to_line, _operations = line_operations(from_line, to_line)
575
+ _operations.each do |tag, from_start, from_end, to_start, to_end|
576
+ from_width = compute_width(from_line, from_start, from_end)
577
+ to_width = compute_width(to_line, to_start, to_end)
578
+ case tag
579
+ when :replace
580
+ from_tags << "^" * from_width
581
+ to_tags << "^" * to_width
582
+ when :delete
583
+ from_tags << "-" * from_width
584
+ when :insert
585
+ to_tags << "+" * to_width
586
+ when :equal
587
+ from_tags << " " * from_width
588
+ to_tags << " " * to_width
589
+ else
590
+ raise "unknown tag: #{tag}"
591
+ end
592
+ end
593
+ format_diff_point(from_line, to_line, from_tags, to_tags)
594
+ end
595
+
596
+ def format_diff_point(from_line, to_line, from_tags, to_tags)
597
+ common = [n_leading_characters(from_line, ?\t),
598
+ n_leading_characters(to_line, ?\t)].min
599
+ common = [common,
600
+ n_leading_characters(from_tags[0, common], " "[0])].min
601
+ from_tags = from_tags[common..-1].rstrip
602
+ to_tags = to_tags[common..-1].rstrip
603
+
604
+ tag_deleted([from_line])
605
+ unless from_tags.empty?
606
+ tag_difference(["#{"\t" * common}#{from_tags}"])
607
+ end
608
+ tag_inserted([to_line])
609
+ unless to_tags.empty?
610
+ tag_difference(["#{"\t" * common}#{to_tags}"])
611
+ end
612
+ end
613
+
614
+ def n_leading_characters(string, character)
615
+ n = 0
616
+ while string[n] == character
617
+ n += 1
618
+ end
619
+ n
620
+ end
621
+
622
+ def space_character?(character)
623
+ [" "[0], "\t"[0]].include?(character)
624
+ end
625
+ end
626
+
627
+ class UnifiedDiffer < Differ
628
+ def diff(options={})
629
+ groups = SequenceMatcher.new(@from, @to).grouped_operations
630
+ return [] if groups.empty?
631
+ return [] if same_content?(groups)
632
+
633
+ show_context = options[:show_context]
634
+ show_context = true if show_context.nil?
635
+ result = ["--- #{options[:from_label]}".rstrip,
636
+ "+++ #{options[:to_label]}".rstrip]
637
+ groups.each do |operations|
638
+ result << format_summary(operations, show_context)
639
+ operations.each do |args|
640
+ operation_tag, from_start, from_end, to_start, to_end = args
641
+ case operation_tag
642
+ when :replace
643
+ result.concat(tag("-", @from[from_start...from_end]))
644
+ result.concat(tag("+", @to[to_start...to_end]))
645
+ when :delete
646
+ result.concat(tag("-", @from[from_start...from_end]))
647
+ when :insert
648
+ result.concat(tag("+", @to[to_start...to_end]))
649
+ when :equal
650
+ result.concat(tag(" ", @from[from_start...from_end]))
651
+ end
652
+ end
653
+ end
654
+ result
655
+ end
656
+
657
+ private
658
+ def same_content?(groups)
659
+ return false if groups.size != 1
660
+ group = groups[0]
661
+ return false if group.size != 1
662
+ tag, from_start, from_end, to_start, to_end = group[0]
663
+
664
+ tag == :equal and [from_start, from_end] == [to_start, to_end]
665
+ end
666
+
667
+ def format_summary(operations, show_context)
668
+ _, first_from_start, _, first_to_start, _ = operations[0]
669
+ _, _, last_from_end, _, last_to_end = operations[-1]
670
+ summary = "@@ -%d,%d +%d,%d @@" % [first_from_start + 1,
671
+ last_from_end - first_from_start,
672
+ first_to_start + 1,
673
+ last_to_end - first_to_start,]
674
+ if show_context
675
+ interesting_line = find_interesting_line(first_from_start,
676
+ first_to_start,
677
+ :define_line?)
678
+ summary << " #{interesting_line}" if interesting_line
679
+ end
680
+ summary
681
+ end
682
+
683
+ def find_interesting_line(from_start, to_start, predicate)
684
+ from_index = from_start
685
+ to_index = to_start
686
+ while from_index >= 0 or to_index >= 0
687
+ [@from[from_index], @to[to_index]].each do |line|
688
+ return line if line and __send__(predicate, line)
689
+ end
690
+
691
+ from_index -= 1
692
+ to_index -= 1
693
+ end
694
+ nil
695
+ end
696
+
697
+ def define_line?(line)
698
+ /\A(?:[_a-zA-Z$]|\s*(?:class|module|def)\b)/ =~ line
699
+ end
700
+ end
701
+
702
+ module_function
703
+ def need_fold?(diff)
704
+ /^[-+].{79}/ =~ diff
705
+ end
706
+
707
+ def fold(string)
708
+ string.split(/\r?\n/).collect do |line|
709
+ line.gsub(/(.{78})/, "\\1\n")
710
+ end.join("\n")
711
+ end
712
+
713
+ def folded_readable(from, to, options={})
714
+ readable(fold(from), fold(to), options)
715
+ end
716
+
717
+ def readable(from, to, options={})
718
+ diff(ReadableDiffer, from, to, options)
719
+ end
720
+
721
+ def unified(from, to, options={})
722
+ diff(UnifiedDiffer, from, to, options)
723
+ end
724
+
725
+ def diff(differ_class, from, to, options={})
726
+ if from.respond_to?(:valid_encoding?) and not from.valid_encoding?
727
+ from = from.dup.force_encoding("ASCII-8BIT")
728
+ end
729
+ if to.respond_to?(:valid_encoding?) and not to.valid_encoding?
730
+ to = to.dup.force_encoding("ASCII-8BIT")
731
+ end
732
+ differ = differ_class.new(from.split(/\r?\n/), to.split(/\r?\n/))
733
+ lines = differ.diff(options)
734
+ if Object.const_defined?(:EncodingError)
735
+ begin
736
+ lines.join("\n")
737
+ rescue EncodingError
738
+ lines.collect {|line| line.force_encoding("ASCII-8BIT")}.join("\n")
739
+ end
740
+ else
741
+ lines.join("\n")
742
+ end
743
+ end
744
+ end
745
+ end
746
+ end