vcs 0.1 → 0.2.148

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 (132) hide show
  1. data/Rakefile +17 -3
  2. data/bin/vcs +57 -34
  3. data/doc/jamis.rb +564 -0
  4. data/ruby_ex/abstract.rb +254 -0
  5. data/ruby_ex/abstract_node.rb +85 -0
  6. data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
  7. data/ruby_ex/array_each_pair.rb +18 -0
  8. data/ruby_ex/ask.rb +101 -0
  9. data/ruby_ex/attributed_class.rb +302 -0
  10. data/ruby_ex/cache.rb +373 -0
  11. data/ruby_ex/checkout.rb +12 -0
  12. data/ruby_ex/choose.rb +271 -0
  13. data/ruby_ex/commands.rb +18 -0
  14. data/ruby_ex/commands/command.rb +401 -0
  15. data/ruby_ex/commands/datas.rb +16 -0
  16. data/ruby_ex/commands/datas/data.rb +33 -0
  17. data/ruby_ex/commands/datas/factory.rb +66 -0
  18. data/ruby_ex/commands/factory.rb +66 -0
  19. data/ruby_ex/commands/helpers.rb +67 -0
  20. data/ruby_ex/commands/pipe.rb +64 -0
  21. data/ruby_ex/commands/runners.rb +17 -0
  22. data/ruby_ex/commands/runners/exec.rb +49 -0
  23. data/ruby_ex/commands/runners/fork.rb +97 -0
  24. data/ruby_ex/commands/runners/runner.rb +107 -0
  25. data/ruby_ex/commands/seq.rb +27 -0
  26. data/ruby_ex/config_file.rb +96 -0
  27. data/ruby_ex/const_regexp.rb +59 -0
  28. data/ruby_ex/daemon.rb +134 -0
  29. data/ruby_ex/diff.rb +667 -0
  30. data/ruby_ex/dlogger.rb +62 -0
  31. data/ruby_ex/drb/dispatcher.rb +252 -0
  32. data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
  33. data/ruby_ex/drb/drb_observable.rb +97 -0
  34. data/ruby_ex/drb/drb_observable_pool.rb +27 -0
  35. data/ruby_ex/drb/drb_service.rb +43 -0
  36. data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
  37. data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
  38. data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
  39. data/ruby_ex/drb/session_client_test.rb +40 -0
  40. data/ruby_ex/drb/session_manager.rb +246 -0
  41. data/ruby_ex/drb/session_server.rb +53 -0
  42. data/ruby_ex/dtime.rb +143 -0
  43. data/ruby_ex/dumpable_proc.rb +63 -0
  44. data/ruby_ex/exception.rb +32 -0
  45. data/ruby_ex/filetype.rb +229 -0
  46. data/ruby_ex/fileutils_ex.rb +44 -0
  47. data/ruby_ex/fold.rb +58 -0
  48. data/ruby_ex/generate_id.rb +44 -0
  49. data/ruby_ex/hookable.rb +262 -0
  50. data/ruby_ex/hooker.rb +54 -0
  51. data/ruby_ex/inactive_timeout.rb +137 -0
  52. data/ruby_ex/indexed_node.rb +66 -0
  53. data/ruby_ex/io_marshal.rb +100 -0
  54. data/ruby_ex/ioo.rb +194 -0
  55. data/ruby_ex/labeled_node.rb +63 -0
  56. data/ruby_ex/logger_observer.rb +23 -0
  57. data/ruby_ex/md5sum.rb +66 -0
  58. data/ruby_ex/mktemp.rb +208 -0
  59. data/ruby_ex/module/attr_once.rb +36 -0
  60. data/ruby_ex/module/autoload_tree.rb +75 -0
  61. data/ruby_ex/module/hierarchy.rb +335 -0
  62. data/ruby_ex/module/instance_method_visibility.rb +73 -0
  63. data/ruby_ex/module_ex.rb +11 -0
  64. data/ruby_ex/node.rb +80 -0
  65. data/ruby_ex/object_monitor.rb +145 -0
  66. data/ruby_ex/object_monitor_activity.rb +33 -0
  67. data/ruby_ex/observable.rb +140 -0
  68. data/ruby_ex/observable_pool.rb +293 -0
  69. data/ruby_ex/orderedhash.rb +252 -0
  70. data/ruby_ex/pathname_ex.rb +152 -0
  71. data/ruby_ex/pp_hierarchy.rb +29 -0
  72. data/ruby_ex/pseudo_cache.rb +190 -0
  73. data/ruby_ex/queue.rb +56 -0
  74. data/ruby_ex/random_generators.rb +25 -0
  75. data/ruby_ex/random_generators/random_generator.rb +31 -0
  76. data/ruby_ex/random_generators/ruby.rb +23 -0
  77. data/ruby_ex/safe_eval.rb +348 -0
  78. data/ruby_ex/sendmail.rb +215 -0
  79. data/ruby_ex/service_manager.rb +121 -0
  80. data/ruby_ex/session/administrable.rb +120 -0
  81. data/ruby_ex/session/client.rb +153 -0
  82. data/ruby_ex/session/const.rb +18 -0
  83. data/ruby_ex/session/dispatcher.rb +184 -0
  84. data/ruby_ex/session/error.rb +21 -0
  85. data/ruby_ex/session/fetchable.rb +57 -0
  86. data/ruby_ex/session/fetcher.rb +62 -0
  87. data/ruby_ex/session/hookable.rb +26 -0
  88. data/ruby_ex/session/profile.rb +110 -0
  89. data/ruby_ex/session/server.rb +582 -0
  90. data/ruby_ex/session/test/administrable_test.rb +337 -0
  91. data/ruby_ex/session/test/basic_test.rb +523 -0
  92. data/ruby_ex/session/test/dispatcher_test.rb +409 -0
  93. data/ruby_ex/session/test/fetchable_test.rb +119 -0
  94. data/ruby_ex/session/test/sub_server_test.rb +188 -0
  95. data/ruby_ex/shuffle.rb +30 -0
  96. data/ruby_ex/spring.rb +136 -0
  97. data/ruby_ex/spring_set.rb +137 -0
  98. data/ruby_ex/string_ex.rb +28 -0
  99. data/ruby_ex/symtbl.rb +106 -0
  100. data/ruby_ex/synflow.rb +474 -0
  101. data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
  102. data/ruby_ex/thread_mutex.rb +10 -0
  103. data/ruby_ex/timeout_ex.rb +81 -0
  104. data/ruby_ex/top_down.rb +73 -0
  105. data/ruby_ex/trace.rb +26 -0
  106. data/ruby_ex/uri/druby.rb +81 -0
  107. data/ruby_ex/uri/file.rb +65 -0
  108. data/ruby_ex/uri/ftp_ex.rb +37 -0
  109. data/ruby_ex/uri/http_ex.rb +43 -0
  110. data/ruby_ex/uri/ssh.rb +92 -0
  111. data/ruby_ex/uri/svn.rb +118 -0
  112. data/ruby_ex/uri_ex.rb +45 -0
  113. data/ruby_ex/verbose_object.rb +30 -0
  114. data/ruby_ex/version.rb +66 -0
  115. data/ruby_ex/yaml/basenode_ext.rb +63 -0
  116. data/ruby_ex/yaml/chop_header.rb +23 -0
  117. data/ruby_ex/yaml/transform.rb +449 -0
  118. data/ruby_ex/yaml/yregexpath.rb +76 -0
  119. data/src/changelog.rb +28 -18
  120. data/src/conflict.rb +20 -0
  121. data/src/diff.rb +18 -0
  122. data/src/diffstat.rb +9 -3
  123. data/src/last_changed_date.rb +18 -0
  124. data/src/mail.rb +33 -65
  125. data/src/message.rb +15 -9
  126. data/src/mycommit.rb +29 -14
  127. data/src/news.rb +24 -3
  128. data/src/status.rb +17 -0
  129. data/src/svn.rb +2 -2
  130. data/src/vcs.rb +24 -3
  131. metadata +124 -5
  132. data/lrdetools.rb +0 -12
@@ -0,0 +1,107 @@
1
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
+ # License:: GNU General Public License (GPL).
4
+ # Revision:: $Id: runner.rb 221 2005-05-09 12:40:57Z ertai $
5
+
6
+ module Commands
7
+
8
+ module Runners
9
+
10
+ class Runner
11
+
12
+ abstract
13
+
14
+ include Hookable
15
+ include Hooker
16
+
17
+
18
+ #
19
+ # Hooks declaration
20
+ #
21
+
22
+ hook_declare :display_command
23
+ hook_declare :data
24
+ hook_declare :before_open
25
+ hook_declare :before_chdir
26
+ hook_declare :before_exec
27
+ hook_declare :exec
28
+
29
+
30
+ #
31
+ # Construction methods.
32
+ #
33
+
34
+ def initialize
35
+ @command_data_factory = Datas::Factory.new
36
+ hooker_subscribe self
37
+ # hooker_subscribe VerboseHooker.new
38
+ end
39
+
40
+
41
+ #
42
+ # Methods.
43
+ #
44
+
45
+ def run ( aCommand )
46
+ unless aCommand.is_a? Commands::Command
47
+ raise ArgumentError, 'Need a Runner::Command'
48
+ end
49
+
50
+ hook_trigger :display_command, aCommand
51
+
52
+ data = @command_data_factory.create
53
+ data.input = aCommand.input
54
+ data.output = aCommand.output
55
+ data.error = aCommand.error
56
+ hook_trigger :data, aCommand, data
57
+
58
+ run_impl(aCommand, data)
59
+
60
+ data
61
+ end
62
+
63
+ def run_impl ( aCommand, data )
64
+ hook_trigger :before_open, data
65
+ STDIN.reopen(data.input.to_io) unless data.input.nil?
66
+ STDOUT.reopen(data.output.to_io) unless data.output.nil?
67
+ STDERR.reopen(data.error.to_io) unless data.error.nil?
68
+
69
+ hook_trigger :before_chdir, data
70
+ Dir.chdir(aCommand.dir) unless aCommand.dir.nil?
71
+
72
+ hook_trigger :before_exec, aCommand, data
73
+ hook_trigger :exec, aCommand, data
74
+ end
75
+
76
+ class VerboseHooker
77
+ include Hooker
78
+
79
+ def log ( m, *a )
80
+ STDERR.puts
81
+ STDERR.puts "#{m}: #{a.inspect}"
82
+ end
83
+
84
+ hook_default_method :log
85
+
86
+ end # class VerboseHooker
87
+
88
+
89
+ end # class Runner
90
+
91
+
92
+
93
+ if $0 == __FILE__
94
+ require 'test/unit'
95
+
96
+ class RunnerTest < Test::Unit::TestCase
97
+
98
+ def test_abstract
99
+ assert_raise(TypeError) { Runner.new }
100
+ end
101
+
102
+ end # class RunnerTest
103
+ end
104
+
105
+ end # module Runners
106
+
107
+ end # module Commands
@@ -0,0 +1,27 @@
1
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
+ # License:: GNU General Public License (GPL).
4
+ # Revision:: $Id: seq.rb 221 2005-05-09 12:40:57Z ertai $
5
+
6
+ module Commands
7
+
8
+ class Seq < Command
9
+
10
+ def initialize ( *cmds )
11
+ @cmds = cmds
12
+ end
13
+
14
+ def run ( *a )
15
+ @cmds.each do |cmd|
16
+ cmd.run(*a)
17
+ end
18
+ end
19
+
20
+ def to_sh
21
+ strs = @cmds.map { |cmd| "(#{cmd.to_sh})" }
22
+ "(#{strs.join(' ; ')})#{sh_args}"
23
+ end
24
+
25
+ end # class Seq
26
+
27
+ end # module Commands
@@ -0,0 +1,96 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: config_file.rb 186 2005-04-03 00:07:45Z ertai $
7
+
8
+
9
+ require 'pathname'
10
+ require 'yaml'
11
+ require 'delegate'
12
+
13
+
14
+ class ConfigFile < SimpleDelegator
15
+
16
+ protected :__setobj__
17
+
18
+ class FormatError < RuntimeError; end
19
+
20
+ attr_reader :default_config
21
+
22
+ def initialize(filename, default_config=nil)
23
+ @filename = Pathname.new(filename)
24
+ @default_config = default_config.freeze
25
+ __load__
26
+ end
27
+
28
+ def __load__(&block)
29
+ config = nil
30
+ if @filename.exist?
31
+ @filename.open do |f|
32
+ f.flock(File::LOCK_EX)
33
+ config = real_load(f)
34
+ f.flock(File::LOCK_UN)
35
+ end
36
+ block ? block[config] : check_config(config)
37
+ config.freeze
38
+ else
39
+ if $VERBOSE
40
+ Kernel.warn('warning: use default configuration because no ' +
41
+ 'configuration file has been found')
42
+ end
43
+ config = @default_config
44
+ end
45
+ __setobj__(config)
46
+ end
47
+
48
+ # Raise a FormatError if the loaded configuration do not fit the format
49
+ protected
50
+ def check_config(config)
51
+ end
52
+
53
+ # You can override it to change arguments or Yaml parsing command.
54
+ protected
55
+ def real_load(io)
56
+ YAML::load(io)
57
+ end
58
+
59
+
60
+ end # class ConfigFile
61
+
62
+
63
+ if (not defined? CONFIG_FILE_TESTED) and (defined? TEST_MODE or __FILE__ == $0)
64
+ CONFIG_FILE_TESTED = true
65
+
66
+ require 'test/unit/ui/console/testrunner'
67
+ require 'tempfile'
68
+
69
+
70
+ class ConfigFileTest < Test::Unit::TestCase
71
+
72
+ def test_config_file
73
+ tmp_file = nil
74
+ Tempfile.open('config_file') do |f|
75
+ f.puts '---'
76
+ f.puts 'key1: val1'
77
+ f.puts 'key2: val2'
78
+ tmp_file = f
79
+ end
80
+ raise 'no temp file' if tmp_file.nil?
81
+ default_config = { 'key1' => 'def1', 'key2' => 'def2' }
82
+ config_file = ConfigFile.new('/toto', default_config)
83
+ assert_equal(default_config, config_file.__getobj__)
84
+ assert_raises(NoMethodError) { config_file.__setobj__(nil) }
85
+ config_file = ConfigFile.new(tmp_file.path, default_config)
86
+ assert_equal({ 'key1' => 'val1', 'key2' => 'val2' },
87
+ config_file.__getobj__)
88
+ assert(config_file.__getobj__.frozen?)
89
+ end
90
+
91
+ end # class ConfigFileTest
92
+
93
+
94
+ end
95
+
96
+
@@ -0,0 +1,59 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: const_regexp.rb 83 2004-12-16 13:06:42Z polrop $
7
+
8
+
9
+ module ConstRegexp
10
+
11
+ RB_INST_VAR = /^@[A-Za-z_][A-Za-z0-9_]*$/
12
+ RB_CLASS_VAR = /^@@[A-Za-z_][A-Za-z0-9_]*$/ #FIXME: concat with RB_INST_VAR
13
+ RB_LOCAL_VAR = /^[a-z_][A-Za-z0-9_]*$/
14
+ RB_METHOD = /^[a-z_][A-Za-z0-9_]*[=?!]?$/
15
+ RB_REGEXP = /^\/([^\\]|\\.)*\/$/
16
+ RB_CONST = /^[A-Z][a-zA-Z0-9_]*$/
17
+
18
+ CRYPTED_STRING = /^[A-Za-z0-9.\/]{13}$/
19
+
20
+ DRB_URI = /^([^:]+):\/\/([^:]+):(\d+)$/
21
+
22
+
23
+
24
+ end # module ConstRegexp
25
+
26
+
27
+ #
28
+ # Unit test suite
29
+ #
30
+ if defined? TEST_MODE or $0 == __FILE__
31
+
32
+
33
+ require 'test/unit/ui/yaml/testrunner'
34
+
35
+
36
+ class ConstRegexpTest < Test::Unit::TestCase
37
+
38
+ include ConstRegexp
39
+
40
+ #
41
+ # Tests
42
+ #
43
+ def test_rb_regexp
44
+ assert_match(RB_REGEXP, '//')
45
+ assert_no_match(RB_REGEXP, '')
46
+ assert_match(RB_REGEXP, '/\//')
47
+ assert_match(RB_REGEXP, '/\/\//')
48
+ assert_match(RB_REGEXP, '/reg\/e/')
49
+ assert_no_match(RB_REGEXP, '/\\/')
50
+ assert_match(RB_REGEXP, '/\\\\/')
51
+ assert_match(RB_REGEXP, '/\e/')
52
+ assert_no_match(RB_REGEXP, '/\/')
53
+ end
54
+
55
+ end # class ConstRegexpTest
56
+
57
+
58
+ end
59
+
@@ -0,0 +1,134 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: daemon.rb 144 2005-01-30 14:12:16Z polrop $
7
+
8
+
9
+ require 'pathname'
10
+ require 'singleton'
11
+
12
+ require 'observable'
13
+ require 'observable_pool'
14
+ require 'service_manager'
15
+
16
+
17
+ class Daemon
18
+ include Singleton
19
+ include ServiceManager
20
+ include Observable
21
+ include ObservablePool
22
+
23
+ module Notification
24
+
25
+ START = :daemon_notification_start
26
+ STOP = :daemon_notification_stop
27
+ WORKDIR = :daemon_notification_workdir
28
+ CONFIG = :daemon_notification_config
29
+ CLEAN_WORKDIR = :daemon_notification_clean_workdir
30
+ DETACH = :daemon_notification_detach
31
+ SIGNAL_TRAPS = :daemon_notification_signal_traps
32
+ RELOAD_CONFIG = :daemon_notification_reload_config
33
+
34
+ end # module Notification
35
+
36
+ def initialize
37
+ @config = nil
38
+ @workdir = Pathname.new('')
39
+ @detached = false
40
+ add_observable(self)
41
+ @logger = nil
42
+ end
43
+
44
+ def config=(config)
45
+ unless config.nil? or config.respond_to?(:__load__)
46
+ raise(NoMethodError, 'configuration class need to respond to `load\'')
47
+ end
48
+ @config = config
49
+ changed
50
+ notify_observers(Notification::CONFIG, @config)
51
+ @config
52
+ end
53
+
54
+ attr_reader :config
55
+
56
+ def workdir=(workdir)
57
+ unless workdir.to_s.empty?
58
+ unless File.directory?(workdir)
59
+ raise(ArgumentError, "`#{workdir}' - not a directory")
60
+ end
61
+ Dir.chdir(workdir)
62
+ end
63
+ @workdir = Pathname.new(workdir)
64
+ changed
65
+ notify_observers(Notification::WORKDIR, @workdir)
66
+ @workdir
67
+ end
68
+
69
+ attr_reader :workdir
70
+
71
+ def clean_workdir
72
+ @workdir.each_entry do |p|
73
+ next if p.to_s =~ /^\./
74
+ (@workdir + p).rmtree
75
+ end
76
+ changed
77
+ notify_observers(Notification::CLEAN_WORKDIR)
78
+ nil
79
+ end
80
+
81
+ def detach
82
+ return if @detached
83
+ @detached = true
84
+ if pid = fork # father
85
+ exit
86
+ else # son
87
+ Dir.chdir(@workdir.to_s.empty? ? '/' : @workdir.to_s)
88
+ Process.setsid
89
+ STDIN.close
90
+ STDOUT.close
91
+ STDERR.close
92
+ end
93
+ changed
94
+ notify_observers(Notification::DETACH)
95
+ nil
96
+ end
97
+
98
+ def detached?
99
+ @detached
100
+ end
101
+
102
+ def logger=(logger)
103
+ delete_global_observer(@logger) unless @logger.nil?
104
+ @logger = logger
105
+ add_global_observer(@logger)
106
+ changed
107
+ notify_observers(Notification::START)
108
+ end
109
+
110
+ attr_reader :logger
111
+
112
+ def stop_daemon
113
+ stop_services
114
+ changed
115
+ notify_observers(Notification::STOP)
116
+ exit
117
+ end
118
+
119
+ def reload_config
120
+ unless @config.nil?
121
+ @config.__load__
122
+ changed
123
+ notify_observers(Notification::RELOAD_CONFIG)
124
+ @config
125
+ end
126
+ end
127
+
128
+ def start_daemon(*args)
129
+ end
130
+
131
+ end # class Daemon
132
+
133
+
134
+ #FIXME: test me somehow
@@ -0,0 +1,667 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: diff.rb 186 2005-04-03 00:07:45Z ertai $
7
+
8
+
9
+ module Diff
10
+
11
+ def diff(other, recursive=true)
12
+ gen_diff(other, recursive) {|a, b| a == b}
13
+ end
14
+
15
+ def gen_diff(other, recursive=true, &comp)
16
+ result = {
17
+ :similar => {},
18
+ :different => {},
19
+ :missing => {},
20
+ :additional => {}
21
+ }
22
+ if not other.is_a?(self.class)
23
+ result[:different] = {:self => self.class, :other => other.class}
24
+ return result
25
+ end
26
+ self.each_pair do |k, v|
27
+ if other.has_key?(k)
28
+ if comp[v, other[k]]
29
+ result[:similar][k] = v
30
+ else
31
+ if recursive and v.respond_to?(:gen_diff)
32
+ diff_result = v.gen_diff(other[k], recursive, &comp)
33
+ else
34
+ diff_result = {:self => v, :other => other[k]}
35
+ end
36
+ result[:different][k] = diff_result unless diff_result.no_diff?
37
+ end
38
+ else
39
+ result[:additional][k] = v
40
+ end
41
+ end
42
+ other.each_pair do |k, v|
43
+ if not self.has_key?(k)
44
+ result[:missing][k] = v
45
+ end
46
+ end
47
+ result
48
+ end
49
+
50
+ def no_diff?
51
+ self[:different] == {} and self[:missing] == {} and self[:additional] == {}
52
+ end
53
+
54
+ end # module Diff
55
+
56
+
57
+ class Array
58
+
59
+ include Diff
60
+
61
+ def each_pair
62
+ for i in 0...length do
63
+ yield(i, self[i])
64
+ end
65
+ end
66
+
67
+ def has_index?(i)
68
+ 0 <= i and i < length
69
+ end
70
+
71
+ alias has_key? has_index?
72
+
73
+ end # class Array
74
+
75
+
76
+ class Hash
77
+
78
+ include Diff
79
+
80
+ def no_diff?
81
+ self[:different] == {} and self[:missing] == {} and self[:additional] == {}
82
+ end
83
+
84
+ end # class Hash
85
+
86
+
87
+ #
88
+ # Unit test suite
89
+ #
90
+ if defined? TEST_MODE or $0 == __FILE__
91
+
92
+
93
+ #FIXME: Tidy me because some of my test are duplicated.
94
+
95
+
96
+ require 'test/unit/ui/yaml/testrunner'
97
+
98
+
99
+ class DiffTest < Test::Unit::TestCase
100
+
101
+ #
102
+ # Setup
103
+ #
104
+ class A < Array ; end
105
+ class H < Hash ; end
106
+
107
+ #
108
+ # Tests
109
+ #
110
+ def test_empty
111
+ h = []
112
+ other_h = []
113
+ result_h = h.diff(h)
114
+ assert_equal(true, result_h.no_diff?)
115
+ assert_equal({}, result_h[:similar])
116
+ end
117
+
118
+ def test_simple_similar
119
+ other_h = h = [ 'toto' => 'tata' ]
120
+ result_h = {
121
+ :additional => {},
122
+ :missing => {},
123
+ :similar => { 0 => { 'toto' => 'tata' } },
124
+ :different => {}
125
+ }
126
+ assert_equal(result_h, h.diff(other_h))
127
+ end
128
+
129
+ def test_simple_additional
130
+ h = [ 'toto' => 'tata' ]
131
+ other_h = []
132
+ result_h = {
133
+ :additional => { 0 => { 'toto' => 'tata' } },
134
+ :missing => {},
135
+ :similar => {},
136
+ :different => {}
137
+ }
138
+ assert_equal(result_h, h.diff(other_h))
139
+ end
140
+
141
+ def test_simple_missing
142
+ h = []
143
+ other_h = [ 'toto' => 'tata' ]
144
+ result_h = {
145
+ :additional => {},
146
+ :missing => { 0 => { 'toto' => 'tata' } },
147
+ :similar => {},
148
+ :different => {}
149
+ }
150
+ assert_equal(result_h, h.diff(other_h))
151
+ end
152
+
153
+ def test_simple_different
154
+ h = [ 'tutu' ]
155
+ other_h = [ 'tata' ]
156
+ result_h = {
157
+ :additional => {},
158
+ :missing => {},
159
+ :similar => {},
160
+ :different => {0 => {:self => 'tutu', :other => 'tata'}},
161
+ }
162
+ assert_equal(result_h, h.diff(other_h))
163
+ end
164
+
165
+ def test_several_similar
166
+ other_h = h = [ 'toto', 'tata']
167
+ result_h = {
168
+ :additional => {},
169
+ :missing => {},
170
+ :similar => {0 => 'toto', 1 => 'tata'},
171
+ :different => {}
172
+ }
173
+ assert_equal(result_h, h.diff(other_h))
174
+ end
175
+
176
+ def test_several_additional
177
+ h = [ 'toto', 'tata' ]
178
+ other_h = []
179
+ result_h = {
180
+ :additional => {0 => 'toto', 1 => 'tata'},
181
+ :missing => {},
182
+ :similar => {},
183
+ :different => {}
184
+ }
185
+ assert_equal(result_h, h.diff(other_h))
186
+ end
187
+
188
+ def test_several_missing
189
+ h = []
190
+ other_h = [ 'toto', 'tata' ]
191
+ result_h = {
192
+ :additional => {},
193
+ :missing => {0 => 'toto', 1 => 'tata'},
194
+ :similar => {},
195
+ :different => {}
196
+ }
197
+ assert_equal(result_h, h.diff(other_h))
198
+ end
199
+
200
+ def test_several_different
201
+ h = [ 'foo', 'tutu' ]
202
+ other_h = [ 'bar', 'tata' ]
203
+ result_h = {
204
+ :additional => {},
205
+ :missing => {},
206
+ :similar => {},
207
+ :different => {
208
+ 0 => {:self => 'foo', :other => 'bar'},
209
+ 1 => {:self => 'tutu', :other => 'tata'},
210
+ }
211
+ }
212
+ assert_equal(result_h, h.diff(other_h))
213
+ end
214
+
215
+ def test_simple_missing_missing
216
+ h = []
217
+ other_h = []
218
+ h[0] = 'toto'
219
+ other_h[1] = 'foo'
220
+ result_h = {
221
+ :additional => {},
222
+ :missing => {1 => 'foo'},
223
+ :similar => {},
224
+ :different => {0 => {:self => 'toto', :other => nil}}
225
+ }
226
+ assert_equal(result_h, h.diff(other_h))
227
+ end
228
+
229
+ def test_simple_additional_similar
230
+ h = [ 'foo', 'toto' ]
231
+ other_h = [ 'foo' ]
232
+ result_h = {
233
+ :additional => {1 => 'toto'},
234
+ :missing => {},
235
+ :similar => {0 => 'foo'},
236
+ :different => {}
237
+ }
238
+ assert_equal(result_h, h.diff(other_h))
239
+ end
240
+
241
+ def test_simple_additional_different
242
+ h = [ 'toto', 'tata' ]
243
+ other_h = [ 'foo' ]
244
+ result_h = {
245
+ :additional => {1 => 'tata'},
246
+ :missing => {},
247
+ :similar => {},
248
+ :different => {0 => { :self => 'toto', :other => 'foo' } }
249
+ }
250
+ assert_equal(result_h, h.diff(other_h))
251
+ end
252
+
253
+ def test_simple_missing_similar
254
+ h = [ 'foo' ]
255
+ other_h = [ 'foo', 'toto' ]
256
+ result_h = {
257
+ :additional => {},
258
+ :missing => {1 => 'toto'},
259
+ :similar => {0 => 'foo'},
260
+ :different => {}
261
+ }
262
+ assert_equal(result_h, h.diff(other_h))
263
+ end
264
+
265
+ def test_simple_missing_different
266
+ h = ['foo']
267
+ other_h = ['bor', 'toto']
268
+ result_h = {
269
+ :additional => {},
270
+ :missing => {1 => 'toto'},
271
+ :similar => {},
272
+ :different => {0 => {:self => 'foo', :other => 'bor'}}
273
+ }
274
+ assert_equal(result_h, h.diff(other_h))
275
+ end
276
+
277
+ def test_simple_similar_different
278
+ h = ['bar', 'toto']
279
+ other_h = ['bor', 'toto']
280
+ result_h = {
281
+ :additional => {},
282
+ :missing => {},
283
+ :similar => {1 => 'toto'},
284
+ :different => {0 => {:self => 'bar', :other => 'bor'}}
285
+ }
286
+ assert_equal(result_h, h.diff(other_h))
287
+ end
288
+
289
+ def test_nested_similar_different
290
+ h = [['toto', 'bar'], 'tata']
291
+ other_h = [['toto', 'bor'], 'tata']
292
+ result_h = {
293
+ :additional => {},
294
+ :missing => {},
295
+ :similar => {1 => 'tata'},
296
+ :different => {0 => {
297
+ :additional => {},
298
+ :missing => {},
299
+ :similar => {0 => 'toto'},
300
+ :different => {1 => {:self => 'bar', :other => 'bor'}}
301
+ }
302
+ }
303
+ }
304
+ assert_equal(result_h, h.diff(other_h))
305
+ end
306
+
307
+ def test_nested_different_different
308
+ h = [['toto', 'bar'], 'tata']
309
+ other_h = [['toto', 'bor'], 'tutu']
310
+ result_h = {
311
+ :additional => {},
312
+ :missing => {},
313
+ :similar => {},
314
+ :different => {
315
+ 0 => {
316
+ :additional => {},
317
+ :missing => {},
318
+ :similar => {0 => 'toto'},
319
+ :different => {1 => {:self => 'bar', :other => 'bor'}}
320
+ },
321
+ 1 => {:self => 'tata', :other => 'tutu'}
322
+ }
323
+ }
324
+ assert_equal(result_h, h.diff(other_h))
325
+ end
326
+
327
+ def test_similar_different_additional
328
+ h = ['goo', 'wrong', 'add']
329
+ other_h = ['goo', 'bar']
330
+ result_h = {
331
+ :additional => {2 => 'add'},
332
+ :missing => {},
333
+ :similar => {0 => 'goo'},
334
+ :different => {1 => {:self => 'wrong', :other => 'bar'}}
335
+ }
336
+ assert_equal(result_h, h.diff(other_h))
337
+ end
338
+
339
+ def test_diff_class
340
+ h = ['bar', 'tata']
341
+ other_h = {0 => 'bar', 1 => 'tata'}
342
+ result_h = {
343
+ :additional => {},
344
+ :missing => {},
345
+ :similar => {},
346
+ :different => {:self => Array, :other => Hash}
347
+ }
348
+ assert_equal(result_h, h.diff(other_h))
349
+ end
350
+
351
+ def test_diff_inherited_class
352
+ h = A.new(['bar', 'tata'])
353
+ other_h = {0 => 'bar', 1 => 'tata'}
354
+ result_h = {
355
+ :additional => {},
356
+ :missing => {},
357
+ :similar => {},
358
+ :different => {:self => A, :other => Hash}
359
+ }
360
+ assert_equal(result_h, h.diff(other_h))
361
+ end
362
+
363
+ def test_array_in_hash
364
+ h = {'toto' => 'tata', 'foo' => ['goo', 'wrong', 'add']}
365
+ other_h = {'toto' => 'tata', 'foo' => ['goo', 'bar']}
366
+ result_h = {
367
+ :additional => {},
368
+ :missing => {},
369
+ :similar => {'toto' => 'tata'},
370
+ :different => {'foo' => {
371
+ :additional => {2 => 'add'},
372
+ :missing => {},
373
+ :similar => {0 => 'goo'},
374
+ :different => {1 => {:self => 'wrong', :other => 'bar'}}
375
+ }
376
+ }
377
+ }
378
+ assert_equal(result_h, h.diff(other_h))
379
+ end
380
+
381
+ def test_no_recursion
382
+ h = [['toto', 'bar'], 'tata']
383
+ other_h = [['toto', 'bor'], 'tutu']
384
+ result_h = {
385
+ :additional => {},
386
+ :missing => {},
387
+ :similar => {},
388
+ :different => {0 => {
389
+ :self => ['toto', 'bar'],
390
+ :other => ['toto', 'bor']
391
+ },
392
+ 1 => {
393
+ :self => 'tata',
394
+ :other => 'tutu'
395
+ }
396
+ }
397
+ }
398
+ assert_equal(result_h, h.diff(other_h,false))
399
+ end
400
+
401
+ def test_other_comp_fun
402
+ h = [['false']]
403
+ other_h = [[false]]
404
+ result_h = {
405
+ :additional => {},
406
+ :missing => {},
407
+ :similar => { 0 => ['false']},
408
+ :different => {}
409
+ }
410
+ assert_equal(result_h, h.gen_diff(other_h, true) {|a, b| a.to_s == b.to_s})
411
+ end
412
+
413
+ def test_empty2
414
+ other_h = h = {}
415
+ diff_h = h.diff(h)
416
+ assert_equal(true, diff_h.no_diff?)
417
+ assert_equal({}, diff_h[:similar])
418
+ end
419
+
420
+ def test_simple_similar2
421
+ other_h = h = { 'toto' => 'tata' }
422
+ result_h = {
423
+ :additional => {},
424
+ :missing => {},
425
+ :similar => { 'toto' => 'tata' },
426
+ :different => {}
427
+ }
428
+ assert_equal(result_h, h.diff(other_h))
429
+ end
430
+
431
+ def test_simple_additional2
432
+ h = { 'toto' => 'tata' }
433
+ other_h = {}
434
+ result_h = {
435
+ :additional => { 'toto' => 'tata' },
436
+ :missing => {},
437
+ :similar => {},
438
+ :different => {}
439
+ }
440
+ assert_equal(result_h, h.diff(other_h))
441
+ end
442
+
443
+ def test_simple_missing2
444
+ h = {}
445
+ other_h = { 'toto' => 'tata' }
446
+ result_h = {
447
+ :additional => {},
448
+ :missing => { 'toto' => 'tata' },
449
+ :similar => {},
450
+ :different => {}
451
+ }
452
+ assert_equal(result_h, h.diff(other_h))
453
+ end
454
+
455
+ def test_simple_different2
456
+ h = { 'toto' => 'tutu' }
457
+ other_h = { 'toto' => 'tata' }
458
+ result_h = {
459
+ :additional => {},
460
+ :missing => {},
461
+ :similar => {},
462
+ :different => { 'toto' => { :self => 'tutu', :other => 'tata' } }
463
+ }
464
+ assert_equal(result_h, h.diff(other_h))
465
+ end
466
+
467
+ def test_several_similar2
468
+ other_h = h = { 'toto' => 'tata', 'foo' => 'bar' }
469
+ result_h = {
470
+ :additional => {},
471
+ :missing => {},
472
+ :similar => { 'toto' => 'tata', 'foo' => 'bar' },
473
+ :different => {}
474
+ }
475
+ diff = h.diff(other_h)
476
+ assert_equal(result_h, diff)
477
+ assert_equal(true, diff.no_diff?)
478
+ end
479
+
480
+ def test_several_additional2
481
+ h = { 'toto' => 'tata', 'foo' => 'bar' }
482
+ other_h = {}
483
+ result_h = {
484
+ :additional => { 'toto' => 'tata', 'foo' => 'bar' },
485
+ :missing => {},
486
+ :similar => {},
487
+ :different => {}
488
+ }
489
+ assert_equal(result_h, h.diff(other_h))
490
+ end
491
+
492
+ def test_several_missing2
493
+ h = {}
494
+ other_h = { 'toto' => 'tata', 'foo' => 'bar' }
495
+ result_h = {
496
+ :additional => {},
497
+ :missing => { 'toto' => 'tata', 'foo' => 'bar' },
498
+ :similar => {},
499
+ :different => {}
500
+ }
501
+ assert_equal(result_h, h.diff(other_h))
502
+ end
503
+
504
+ def test_several_different2
505
+ h = { 'toto' => 'tutu', 'foo' => 'bor' }
506
+ other_h = { 'toto' => 'tata', 'foo' => 'bar' }
507
+ result_h = {
508
+ :additional => {},
509
+ :missing => {},
510
+ :similar => {},
511
+ :different => {
512
+ 'toto' => { :self => 'tutu', :other => 'tata' },
513
+ 'foo' => { :self => 'bor', :other => 'bar' },
514
+ }
515
+ }
516
+ assert_equal(result_h, h.diff(other_h))
517
+ end
518
+
519
+ def test_simple_missing_missing2
520
+ h = { 'toto' => 'tata' }
521
+ other_h = { 'foo' => 'bar' }
522
+ result_h = {
523
+ :additional => { 'toto' => 'tata' },
524
+ :missing => { 'foo' => 'bar' },
525
+ :similar => {},
526
+ :different => {}
527
+ }
528
+ assert_equal(result_h, h.diff(other_h))
529
+ end
530
+
531
+ def test_simple_additional_similar2
532
+ h = { 'toto' => 'tata', 'foo' => 'bar' }
533
+ other_h = { 'foo' => 'bar' }
534
+ result_h = {
535
+ :additional => { 'toto' => 'tata' },
536
+ :missing => {},
537
+ :similar => { 'foo' => 'bar' },
538
+ :different => {}
539
+ }
540
+ diff = h.diff(other_h)
541
+ assert_equal(result_h, diff)
542
+ assert_equal(false, diff.no_diff?)
543
+ end
544
+
545
+ def test_simple_additional_different2
546
+ h = { 'toto' => 'tata', 'foo' => 'bar' }
547
+ other_h = { 'foo' => 'bor' }
548
+ result_h = {
549
+ :additional => { 'toto' => 'tata' },
550
+ :missing => {},
551
+ :similar => {},
552
+ :different => { 'foo' => { :self => 'bar', :other => 'bor' } }
553
+ }
554
+ assert_equal(result_h, h.diff(other_h))
555
+ end
556
+
557
+ def test_simple_missing_similar2
558
+ h = { 'foo' => 'bar' }
559
+ other_h = { 'foo' => 'bar', 'toto' => 'tata' }
560
+ result_h = {
561
+ :additional => {},
562
+ :missing => { 'toto' => 'tata' },
563
+ :similar => { 'foo' => 'bar' },
564
+ :different => {}
565
+ }
566
+ assert_equal(result_h, h.diff(other_h))
567
+ end
568
+
569
+ def test_simple_missing_different2
570
+ h = { 'foo' => 'bar' }
571
+ other_h = { 'foo' => 'bor', 'toto' => 'tata' }
572
+ result_h = {
573
+ :additional => {},
574
+ :missing => { 'toto' => 'tata' },
575
+ :similar => {},
576
+ :different => { 'foo' => { :self => 'bar', :other => 'bor' } }
577
+ }
578
+ assert_equal(result_h, h.diff(other_h))
579
+ end
580
+
581
+ def test_simple_similar_different2
582
+ h = { 'foo' => 'bar', 'toto' => 'tata' }
583
+ other_h = { 'foo' => 'bor', 'toto' => 'tata' }
584
+ result_h = {
585
+ :additional => {},
586
+ :missing => {},
587
+ :similar => { 'toto' => 'tata' },
588
+ :different => { 'foo' => { :self => 'bar', :other => 'bor' } }
589
+ }
590
+ assert_equal(result_h, h.diff(other_h))
591
+ end
592
+
593
+ def test_nested_similar_different2
594
+ h = {'foo' => {'toto' => 'tata', 'foo' => 'bar'}, 'toto' => 'tata'}
595
+ other_h = {'foo' => {'toto' => 'tata', 'foo' => 'bor'}, 'toto' => 'tata'}
596
+ result_h = {
597
+ :additional => {},
598
+ :missing => {},
599
+ :similar => {'toto' => 'tata'},
600
+ :different => {'foo' => {
601
+ :additional => {},
602
+ :missing => {},
603
+ :similar => {'toto' => 'tata'},
604
+ :different => {'foo' => {:self => 'bar', :other => 'bor'}}
605
+ }
606
+ }
607
+ }
608
+ assert_equal(result_h, h.diff(other_h))
609
+ end
610
+
611
+ def test_diff_class2
612
+ h = {0 => 'bar', 1 => 'tata'}
613
+ other_h = ['bar', 'tata']
614
+ result_h = {
615
+ :additional => {},
616
+ :missing => {},
617
+ :similar => {},
618
+ :different => {:self => Hash, :other => Array}
619
+ }
620
+ assert_equal(result_h, h.diff(other_h))
621
+ end
622
+
623
+ def test_diff_inherited_class2
624
+ h = H.new(0 => 'bar', 1 => 'tata')
625
+ other_h = ['bar', 'tata']
626
+ result_h = {
627
+ :additional => {},
628
+ :missing => {},
629
+ :similar => {},
630
+ :different => {:self => H, :other => Array}
631
+ }
632
+ assert_equal(result_h, h.diff(other_h))
633
+ end
634
+
635
+ def test_no_recursion2
636
+ h = {'foo' => {'toto' => 'tata', 'foo' => 'bar'}, 'toto' => 'tata'}
637
+ other_h = {'foo' => {'toto' => 'tata', 'foo' => 'bor'}, 'toto' => 'tata'}
638
+ result_h = {
639
+ :additional => {},
640
+ :missing => {},
641
+ :similar => {'toto' => 'tata'},
642
+ :different => {'foo' => {
643
+ :self => {'toto' => 'tata', 'foo' => 'bar'},
644
+ :other => {'toto' => 'tata', 'foo' => 'bor'}
645
+ }
646
+ }
647
+ }
648
+ assert_equal(result_h, h.diff(other_h, false))
649
+ end
650
+
651
+ def test_other_comp_fun2
652
+ h = {'foo' => {'toto' => 'false', 'foo' => '0'}}
653
+ other_h = {'foo' => {'toto' => false, 'foo' => 0}}
654
+ result_h = {
655
+ :additional => {},
656
+ :missing => {},
657
+ :similar => {'foo' => {'toto' => 'false', 'foo' => '0'}},
658
+ :different => {}
659
+ }
660
+ assert_equal(result_h, h.gen_diff(other_h, true) {|a, b| a.to_s == b.to_s})
661
+ end
662
+
663
+ end # class DiffTest
664
+
665
+
666
+ end
667
+