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

Sign up to get free protection for your applications and to get access to all the features.
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