activeldap 1.2.2 → 1.2.3

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 (241) hide show
  1. data/CHANGES +24 -0
  2. data/README +9 -3
  3. data/Rakefile +24 -50
  4. data/examples/al-admin/Rakefile +6 -0
  5. data/examples/al-admin/app/controllers/application_controller.rb +9 -2
  6. data/examples/al-admin/config/environment.rb +9 -3
  7. data/examples/al-admin/config/initializers/fast_gettext.rb +3 -0
  8. data/examples/al-admin/config/session_secret.txt +1 -1
  9. data/lib/active_ldap.rb +6 -19
  10. data/lib/active_ldap/adapter/base.rb +22 -20
  11. data/lib/active_ldap/adapter/jndi.rb +2 -3
  12. data/lib/active_ldap/adapter/jndi_connection.rb +2 -2
  13. data/lib/active_ldap/adapter/ldap.rb +9 -4
  14. data/lib/active_ldap/adapter/net_ldap.rb +5 -4
  15. data/lib/active_ldap/base.rb +1 -1
  16. data/lib/active_ldap/get_text.rb +2 -2
  17. data/lib/active_ldap/get_text_fallback.rb +39 -32
  18. data/lib/active_ldap/get_text_support.rb +4 -2
  19. data/lib/active_ldap/operations.rb +3 -2
  20. data/lib/active_ldap/validations.rb +11 -21
  21. data/po/en/active-ldap.po +9 -9
  22. data/po/ja/active-ldap.po +18 -18
  23. data/test/run-test.rb +7 -1
  24. data/test/test_adapter.rb +1 -0
  25. data/test/test_base.rb +8 -1
  26. data/test/test_load.rb +2 -1
  27. data/test/test_user.rb +3 -4
  28. data/test/test_validation.rb +20 -23
  29. metadata +34 -228
  30. data/data/locale/en/LC_MESSAGES/active-ldap.mo +0 -0
  31. data/data/locale/ja/LC_MESSAGES/active-ldap.mo +0 -0
  32. data/examples/al-admin/config/initializers/gettext.rb +0 -1
  33. data/examples/al-admin/lib/tasks/gettext.rake +0 -36
  34. data/examples/al-admin/locale/en/LC_MESSAGES/al-admin.mo +0 -0
  35. data/examples/al-admin/locale/ja/LC_MESSAGES/al-admin.mo +0 -0
  36. data/examples/al-admin/locale/nl/LC_MESSAGES/al-admin.mo +0 -0
  37. data/examples/al-admin/po/al-admin.pot +0 -344
  38. data/examples/al-admin/public/images/active-ldap.png +0 -0
  39. data/examples/al-admin/vendor/locale_rails/.gitignore +0 -6
  40. data/examples/al-admin/vendor/locale_rails/COPYING +0 -56
  41. data/examples/al-admin/vendor/locale_rails/ChangeLog +0 -35
  42. data/examples/al-admin/vendor/locale_rails/README.rdoc +0 -62
  43. data/examples/al-admin/vendor/locale_rails/Rakefile +0 -73
  44. data/examples/al-admin/vendor/locale_rails/lib/locale_rails.rb +0 -18
  45. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/action_controller.rb +0 -15
  46. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/action_controller/base.rb +0 -82
  47. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/action_controller/caching.rb +0 -51
  48. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/action_controller/test_process.rb +0 -44
  49. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/action_view.rb +0 -53
  50. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/i18n.rb +0 -67
  51. data/examples/al-admin/vendor/locale_rails/lib/locale_rails/version.rb +0 -4
  52. data/examples/al-admin/vendor/locale_rails/sample/README +0 -22
  53. data/examples/al-admin/vendor/locale_rails/sample/Rakefile +0 -10
  54. data/examples/al-admin/vendor/locale_rails/sample/app/controllers/application.rb +0 -42
  55. data/examples/al-admin/vendor/locale_rails/sample/app/controllers/samples_controller.rb +0 -30
  56. data/examples/al-admin/vendor/locale_rails/sample/app/helpers/application_helper.rb +0 -3
  57. data/examples/al-admin/vendor/locale_rails/sample/app/views/layouts/samples.html.erb +0 -20
  58. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/_part.html.erb +0 -68
  59. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/_part_nl.html.erb +0 -2
  60. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/cached_action.html.erb +0 -6
  61. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/index.html.erb +0 -33
  62. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/index.pt.html.erb +0 -16
  63. data/examples/al-admin/vendor/locale_rails/sample/app/views/samples/index_uz_UZ.html.erb +0 -16
  64. data/examples/al-admin/vendor/locale_rails/sample/config/boot.rb +0 -109
  65. data/examples/al-admin/vendor/locale_rails/sample/config/environment.rb +0 -25
  66. data/examples/al-admin/vendor/locale_rails/sample/config/environments/development.rb +0 -17
  67. data/examples/al-admin/vendor/locale_rails/sample/config/environments/production.rb +0 -24
  68. data/examples/al-admin/vendor/locale_rails/sample/config/environments/test.rb +0 -22
  69. data/examples/al-admin/vendor/locale_rails/sample/config/initializers/inflections.rb +0 -10
  70. data/examples/al-admin/vendor/locale_rails/sample/config/initializers/mime_types.rb +0 -5
  71. data/examples/al-admin/vendor/locale_rails/sample/config/initializers/new_rails_defaults.rb +0 -17
  72. data/examples/al-admin/vendor/locale_rails/sample/config/locales/en.yml +0 -2
  73. data/examples/al-admin/vendor/locale_rails/sample/config/locales/ja.yml +0 -2
  74. data/examples/al-admin/vendor/locale_rails/sample/config/routes.rb +0 -13
  75. data/examples/al-admin/vendor/locale_rails/sample/db/schema.rb +0 -10
  76. data/examples/al-admin/vendor/locale_rails/sample/public/404.html +0 -30
  77. data/examples/al-admin/vendor/locale_rails/sample/public/422.html +0 -30
  78. data/examples/al-admin/vendor/locale_rails/sample/public/500.html +0 -33
  79. data/examples/al-admin/vendor/locale_rails/sample/public/dispatch.cgi +0 -10
  80. data/examples/al-admin/vendor/locale_rails/sample/public/dispatch.fcgi +0 -24
  81. data/examples/al-admin/vendor/locale_rails/sample/public/dispatch.rb +0 -10
  82. data/examples/al-admin/vendor/locale_rails/sample/public/favicon.ico +0 -0
  83. data/examples/al-admin/vendor/locale_rails/sample/public/images/rails.png +0 -0
  84. data/examples/al-admin/vendor/locale_rails/sample/public/javascripts/application.js +0 -2
  85. data/examples/al-admin/vendor/locale_rails/sample/public/javascripts/controls.js +0 -963
  86. data/examples/al-admin/vendor/locale_rails/sample/public/javascripts/dragdrop.js +0 -972
  87. data/examples/al-admin/vendor/locale_rails/sample/public/javascripts/effects.js +0 -1120
  88. data/examples/al-admin/vendor/locale_rails/sample/public/javascripts/prototype.js +0 -4221
  89. data/examples/al-admin/vendor/locale_rails/sample/public/robots.txt +0 -5
  90. data/examples/al-admin/vendor/locale_rails/sample/public/stylesheets/locale.css +0 -81
  91. data/examples/al-admin/vendor/locale_rails/sample/public/stylesheets/scaffold.css +0 -74
  92. data/examples/al-admin/vendor/locale_rails/sample/script/about +0 -4
  93. data/examples/al-admin/vendor/locale_rails/sample/script/console +0 -3
  94. data/examples/al-admin/vendor/locale_rails/sample/script/dbconsole +0 -3
  95. data/examples/al-admin/vendor/locale_rails/sample/script/destroy +0 -3
  96. data/examples/al-admin/vendor/locale_rails/sample/script/generate +0 -3
  97. data/examples/al-admin/vendor/locale_rails/sample/script/performance/benchmarker +0 -3
  98. data/examples/al-admin/vendor/locale_rails/sample/script/performance/profiler +0 -3
  99. data/examples/al-admin/vendor/locale_rails/sample/script/performance/request +0 -3
  100. data/examples/al-admin/vendor/locale_rails/sample/script/plugin +0 -3
  101. data/examples/al-admin/vendor/locale_rails/sample/script/process/inspector +0 -3
  102. data/examples/al-admin/vendor/locale_rails/sample/script/process/reaper +0 -3
  103. data/examples/al-admin/vendor/locale_rails/sample/script/process/spawner +0 -3
  104. data/examples/al-admin/vendor/locale_rails/sample/script/runner +0 -3
  105. data/examples/al-admin/vendor/locale_rails/sample/script/server +0 -3
  106. data/examples/al-admin/vendor/locale_rails/sample/test/performance/browsing_test.rb +0 -9
  107. data/examples/al-admin/vendor/locale_rails/sample/test/test_helper.rb +0 -38
  108. data/examples/al-admin/vendor/locale_rails/test/README +0 -243
  109. data/examples/al-admin/vendor/locale_rails/test/Rakefile +0 -10
  110. data/examples/al-admin/vendor/locale_rails/test/app/controllers/application_controller.rb +0 -10
  111. data/examples/al-admin/vendor/locale_rails/test/app/controllers/articles_controller.rb +0 -17
  112. data/examples/al-admin/vendor/locale_rails/test/app/helpers/application_helper.rb +0 -3
  113. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/index.html.erb +0 -1
  114. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/index_de.html.erb +0 -1
  115. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/index_fr_FR.html.erb +0 -1
  116. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/index_ja.html.erb +0 -1
  117. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/list.html.erb +0 -1
  118. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/show.html.erb +0 -0
  119. data/examples/al-admin/vendor/locale_rails/test/app/views/articles/show.js.rjs +0 -0
  120. data/examples/al-admin/vendor/locale_rails/test/config/boot.rb +0 -110
  121. data/examples/al-admin/vendor/locale_rails/test/config/environment.rb +0 -42
  122. data/examples/al-admin/vendor/locale_rails/test/config/environments/development.rb +0 -17
  123. data/examples/al-admin/vendor/locale_rails/test/config/environments/production.rb +0 -28
  124. data/examples/al-admin/vendor/locale_rails/test/config/environments/test.rb +0 -35
  125. data/examples/al-admin/vendor/locale_rails/test/config/initializers/backtrace_silencers.rb +0 -7
  126. data/examples/al-admin/vendor/locale_rails/test/config/initializers/inflections.rb +0 -10
  127. data/examples/al-admin/vendor/locale_rails/test/config/initializers/mime_types.rb +0 -5
  128. data/examples/al-admin/vendor/locale_rails/test/config/initializers/new_rails_defaults.rb +0 -19
  129. data/examples/al-admin/vendor/locale_rails/test/config/initializers/session_store.rb +0 -15
  130. data/examples/al-admin/vendor/locale_rails/test/config/locales/en.yml +0 -5
  131. data/examples/al-admin/vendor/locale_rails/test/config/routes.rb +0 -46
  132. data/examples/al-admin/vendor/locale_rails/test/db/schema.rb +0 -0
  133. data/examples/al-admin/vendor/locale_rails/test/public/404.html +0 -30
  134. data/examples/al-admin/vendor/locale_rails/test/public/422.html +0 -30
  135. data/examples/al-admin/vendor/locale_rails/test/public/500.html +0 -30
  136. data/examples/al-admin/vendor/locale_rails/test/public/favicon.ico +0 -0
  137. data/examples/al-admin/vendor/locale_rails/test/public/images/rails.png +0 -0
  138. data/examples/al-admin/vendor/locale_rails/test/public/index.html +0 -275
  139. data/examples/al-admin/vendor/locale_rails/test/public/javascripts/application.js +0 -2
  140. data/examples/al-admin/vendor/locale_rails/test/public/javascripts/controls.js +0 -963
  141. data/examples/al-admin/vendor/locale_rails/test/public/javascripts/dragdrop.js +0 -973
  142. data/examples/al-admin/vendor/locale_rails/test/public/javascripts/effects.js +0 -1128
  143. data/examples/al-admin/vendor/locale_rails/test/public/javascripts/prototype.js +0 -4320
  144. data/examples/al-admin/vendor/locale_rails/test/public/robots.txt +0 -5
  145. data/examples/al-admin/vendor/locale_rails/test/script/about +0 -4
  146. data/examples/al-admin/vendor/locale_rails/test/script/console +0 -3
  147. data/examples/al-admin/vendor/locale_rails/test/script/dbconsole +0 -3
  148. data/examples/al-admin/vendor/locale_rails/test/script/destroy +0 -3
  149. data/examples/al-admin/vendor/locale_rails/test/script/generate +0 -3
  150. data/examples/al-admin/vendor/locale_rails/test/script/performance/benchmarker +0 -3
  151. data/examples/al-admin/vendor/locale_rails/test/script/performance/profiler +0 -3
  152. data/examples/al-admin/vendor/locale_rails/test/script/plugin +0 -3
  153. data/examples/al-admin/vendor/locale_rails/test/script/runner +0 -3
  154. data/examples/al-admin/vendor/locale_rails/test/script/server +0 -3
  155. data/examples/al-admin/vendor/locale_rails/test/test/functional/articles_controller_test.rb +0 -161
  156. data/examples/al-admin/vendor/locale_rails/test/test/performance/browsing_test.rb +0 -9
  157. data/examples/al-admin/vendor/locale_rails/test/test/test_helper.rb +0 -38
  158. data/po/active-ldap.pot +0 -4010
  159. data/test-unit/COPYING +0 -56
  160. data/test-unit/GPL +0 -340
  161. data/test-unit/History.txt +0 -223
  162. data/test-unit/Manifest.txt +0 -87
  163. data/test-unit/PSFL +0 -271
  164. data/test-unit/README.txt +0 -60
  165. data/test-unit/Rakefile +0 -40
  166. data/test-unit/TODO +0 -5
  167. data/test-unit/bin/testrb +0 -5
  168. data/test-unit/images/color-diff.png +0 -0
  169. data/test-unit/lib/test/unit.rb +0 -328
  170. data/test-unit/lib/test/unit/assertionfailederror.rb +0 -25
  171. data/test-unit/lib/test/unit/assertions.rb +0 -1334
  172. data/test-unit/lib/test/unit/attribute.rb +0 -125
  173. data/test-unit/lib/test/unit/autorunner.rb +0 -360
  174. data/test-unit/lib/test/unit/collector.rb +0 -36
  175. data/test-unit/lib/test/unit/collector/descendant.rb +0 -23
  176. data/test-unit/lib/test/unit/collector/dir.rb +0 -108
  177. data/test-unit/lib/test/unit/collector/load.rb +0 -144
  178. data/test-unit/lib/test/unit/collector/objectspace.rb +0 -34
  179. data/test-unit/lib/test/unit/color-scheme.rb +0 -106
  180. data/test-unit/lib/test/unit/color.rb +0 -96
  181. data/test-unit/lib/test/unit/diff.rb +0 -740
  182. data/test-unit/lib/test/unit/error.rb +0 -130
  183. data/test-unit/lib/test/unit/exceptionhandler.rb +0 -39
  184. data/test-unit/lib/test/unit/failure.rb +0 -136
  185. data/test-unit/lib/test/unit/fixture.rb +0 -176
  186. data/test-unit/lib/test/unit/notification.rb +0 -129
  187. data/test-unit/lib/test/unit/omission.rb +0 -191
  188. data/test-unit/lib/test/unit/pending.rb +0 -150
  189. data/test-unit/lib/test/unit/priority.rb +0 -180
  190. data/test-unit/lib/test/unit/runner/console.rb +0 -52
  191. data/test-unit/lib/test/unit/runner/emacs.rb +0 -8
  192. data/test-unit/lib/test/unit/runner/tap.rb +0 -8
  193. data/test-unit/lib/test/unit/testcase.rb +0 -478
  194. data/test-unit/lib/test/unit/testresult.rb +0 -89
  195. data/test-unit/lib/test/unit/testsuite.rb +0 -110
  196. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +0 -14
  197. data/test-unit/lib/test/unit/ui/console/testrunner.rb +0 -466
  198. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +0 -63
  199. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +0 -92
  200. data/test-unit/lib/test/unit/ui/testrunner.rb +0 -28
  201. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +0 -77
  202. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +0 -41
  203. data/test-unit/lib/test/unit/util/backtracefilter.rb +0 -42
  204. data/test-unit/lib/test/unit/util/method-owner-finder.rb +0 -28
  205. data/test-unit/lib/test/unit/util/observable.rb +0 -90
  206. data/test-unit/lib/test/unit/util/output.rb +0 -31
  207. data/test-unit/lib/test/unit/util/procwrapper.rb +0 -48
  208. data/test-unit/lib/test/unit/version.rb +0 -7
  209. data/test-unit/sample/adder.rb +0 -13
  210. data/test-unit/sample/subtracter.rb +0 -12
  211. data/test-unit/sample/test_adder.rb +0 -20
  212. data/test-unit/sample/test_subtracter.rb +0 -20
  213. data/test-unit/sample/test_user.rb +0 -23
  214. data/test-unit/test/collector/test-descendant.rb +0 -133
  215. data/test-unit/test/collector/test-load.rb +0 -442
  216. data/test-unit/test/collector/test_dir.rb +0 -406
  217. data/test-unit/test/collector/test_objectspace.rb +0 -100
  218. data/test-unit/test/run-test.rb +0 -15
  219. data/test-unit/test/test-attribute.rb +0 -86
  220. data/test-unit/test/test-color-scheme.rb +0 -69
  221. data/test-unit/test/test-color.rb +0 -47
  222. data/test-unit/test/test-diff.rb +0 -518
  223. data/test-unit/test/test-emacs-runner.rb +0 -60
  224. data/test-unit/test/test-fixture.rb +0 -287
  225. data/test-unit/test/test-notification.rb +0 -33
  226. data/test-unit/test/test-omission.rb +0 -81
  227. data/test-unit/test/test-pending.rb +0 -70
  228. data/test-unit/test/test-priority.rb +0 -119
  229. data/test-unit/test/test-testcase.rb +0 -544
  230. data/test-unit/test/test_assertions.rb +0 -1197
  231. data/test-unit/test/test_error.rb +0 -26
  232. data/test-unit/test/test_failure.rb +0 -33
  233. data/test-unit/test/test_testresult.rb +0 -113
  234. data/test-unit/test/test_testsuite.rb +0 -129
  235. data/test-unit/test/testunit-test-util.rb +0 -14
  236. data/test-unit/test/ui/test_testrunmediator.rb +0 -20
  237. data/test-unit/test/util/test-method-owner-finder.rb +0 -38
  238. data/test-unit/test/util/test-output.rb +0 -11
  239. data/test-unit/test/util/test_backtracefilter.rb +0 -41
  240. data/test-unit/test/util/test_observable.rb +0 -102
  241. data/test-unit/test/util/test_procwrapper.rb +0 -36
@@ -1,96 +0,0 @@
1
- module Test
2
- module Unit
3
- class Color
4
- NAMES = ["black", "red", "green", "yellow",
5
- "blue", "magenta", "cyan", "white"]
6
-
7
- attr_reader :name
8
- def initialize(name, options={})
9
- @name = name
10
- @foreground = options[:foreground]
11
- @foreground = true if @foreground.nil?
12
- @intensity = options[:intensity]
13
- @bold = options[:bold]
14
- @italic = options[:italic]
15
- @underline = options[:underline]
16
- end
17
-
18
- def foreground?
19
- @foreground
20
- end
21
-
22
- def intensity?
23
- @intensity
24
- end
25
-
26
- def bold?
27
- @bold
28
- end
29
-
30
- def italic?
31
- @italic
32
- end
33
-
34
- def underline?
35
- @underline
36
- end
37
-
38
- def ==(other)
39
- self.class === other and
40
- [name, foreground?, intensity?,
41
- bold?, italic?, underline?] ==
42
- [other.name, other.foreground?, other.intensity?,
43
- other.bold?, other.italic?, other.underline?]
44
- end
45
-
46
- def sequence
47
- sequence = []
48
- if @name == "none"
49
- elsif @name == "reset"
50
- sequence << "0"
51
- else
52
- foreground_parameter = foreground? ? 3 : 4
53
- foreground_parameter += 6 if intensity?
54
- sequence << "#{foreground_parameter}#{NAMES.index(@name)}"
55
- end
56
- sequence << "1" if bold?
57
- sequence << "3" if italic?
58
- sequence << "4" if underline?
59
- sequence
60
- end
61
-
62
- def escape_sequence
63
- "\e[#{sequence.join(';')}m"
64
- end
65
-
66
- def +(other)
67
- MixColor.new([self, other])
68
- end
69
- end
70
-
71
- class MixColor
72
- attr_reader :colors
73
- def initialize(colors)
74
- @colors = colors
75
- end
76
-
77
- def sequence
78
- @colors.inject([]) do |result, color|
79
- result + color.sequence
80
- end
81
- end
82
-
83
- def escape_sequence
84
- "\e[#{sequence.join(';')}m"
85
- end
86
-
87
- def +(other)
88
- self.class.new([self, other])
89
- end
90
-
91
- def ==(other)
92
- self.class === other and colors == other.colors
93
- end
94
- end
95
- end
96
- end
@@ -1,740 +0,0 @@
1
- # port of Python's difflib.
2
- #
3
- # Copyright (c) 2001-2008 Python Software Foundation; All Rights Reserved
4
- # Copyright (c) 2008-2010 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, to_index, match_size)|
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
- result = 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
- differ = differ_class.new(from.split(/\r?\n/), to.split(/\r?\n/))
727
- lines = differ.diff(options)
728
- if Object.const_defined?(:EncodingError)
729
- begin
730
- lines.join("\n")
731
- rescue EncodingError
732
- lines.collect {|line| line.force_encoding("ASCII-8BIT")}.join("\n")
733
- end
734
- else
735
- lines.join("\n")
736
- end
737
- end
738
- end
739
- end
740
- end