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.
- data/Rakefile +17 -3
- data/bin/vcs +57 -34
- data/doc/jamis.rb +564 -0
- data/ruby_ex/abstract.rb +254 -0
- data/ruby_ex/abstract_node.rb +85 -0
- data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
- data/ruby_ex/array_each_pair.rb +18 -0
- data/ruby_ex/ask.rb +101 -0
- data/ruby_ex/attributed_class.rb +302 -0
- data/ruby_ex/cache.rb +373 -0
- data/ruby_ex/checkout.rb +12 -0
- data/ruby_ex/choose.rb +271 -0
- data/ruby_ex/commands.rb +18 -0
- data/ruby_ex/commands/command.rb +401 -0
- data/ruby_ex/commands/datas.rb +16 -0
- data/ruby_ex/commands/datas/data.rb +33 -0
- data/ruby_ex/commands/datas/factory.rb +66 -0
- data/ruby_ex/commands/factory.rb +66 -0
- data/ruby_ex/commands/helpers.rb +67 -0
- data/ruby_ex/commands/pipe.rb +64 -0
- data/ruby_ex/commands/runners.rb +17 -0
- data/ruby_ex/commands/runners/exec.rb +49 -0
- data/ruby_ex/commands/runners/fork.rb +97 -0
- data/ruby_ex/commands/runners/runner.rb +107 -0
- data/ruby_ex/commands/seq.rb +27 -0
- data/ruby_ex/config_file.rb +96 -0
- data/ruby_ex/const_regexp.rb +59 -0
- data/ruby_ex/daemon.rb +134 -0
- data/ruby_ex/diff.rb +667 -0
- data/ruby_ex/dlogger.rb +62 -0
- data/ruby_ex/drb/dispatcher.rb +252 -0
- data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
- data/ruby_ex/drb/drb_observable.rb +97 -0
- data/ruby_ex/drb/drb_observable_pool.rb +27 -0
- data/ruby_ex/drb/drb_service.rb +43 -0
- data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
- data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
- data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
- data/ruby_ex/drb/session_client_test.rb +40 -0
- data/ruby_ex/drb/session_manager.rb +246 -0
- data/ruby_ex/drb/session_server.rb +53 -0
- data/ruby_ex/dtime.rb +143 -0
- data/ruby_ex/dumpable_proc.rb +63 -0
- data/ruby_ex/exception.rb +32 -0
- data/ruby_ex/filetype.rb +229 -0
- data/ruby_ex/fileutils_ex.rb +44 -0
- data/ruby_ex/fold.rb +58 -0
- data/ruby_ex/generate_id.rb +44 -0
- data/ruby_ex/hookable.rb +262 -0
- data/ruby_ex/hooker.rb +54 -0
- data/ruby_ex/inactive_timeout.rb +137 -0
- data/ruby_ex/indexed_node.rb +66 -0
- data/ruby_ex/io_marshal.rb +100 -0
- data/ruby_ex/ioo.rb +194 -0
- data/ruby_ex/labeled_node.rb +63 -0
- data/ruby_ex/logger_observer.rb +23 -0
- data/ruby_ex/md5sum.rb +66 -0
- data/ruby_ex/mktemp.rb +208 -0
- data/ruby_ex/module/attr_once.rb +36 -0
- data/ruby_ex/module/autoload_tree.rb +75 -0
- data/ruby_ex/module/hierarchy.rb +335 -0
- data/ruby_ex/module/instance_method_visibility.rb +73 -0
- data/ruby_ex/module_ex.rb +11 -0
- data/ruby_ex/node.rb +80 -0
- data/ruby_ex/object_monitor.rb +145 -0
- data/ruby_ex/object_monitor_activity.rb +33 -0
- data/ruby_ex/observable.rb +140 -0
- data/ruby_ex/observable_pool.rb +293 -0
- data/ruby_ex/orderedhash.rb +252 -0
- data/ruby_ex/pathname_ex.rb +152 -0
- data/ruby_ex/pp_hierarchy.rb +29 -0
- data/ruby_ex/pseudo_cache.rb +190 -0
- data/ruby_ex/queue.rb +56 -0
- data/ruby_ex/random_generators.rb +25 -0
- data/ruby_ex/random_generators/random_generator.rb +31 -0
- data/ruby_ex/random_generators/ruby.rb +23 -0
- data/ruby_ex/safe_eval.rb +348 -0
- data/ruby_ex/sendmail.rb +215 -0
- data/ruby_ex/service_manager.rb +121 -0
- data/ruby_ex/session/administrable.rb +120 -0
- data/ruby_ex/session/client.rb +153 -0
- data/ruby_ex/session/const.rb +18 -0
- data/ruby_ex/session/dispatcher.rb +184 -0
- data/ruby_ex/session/error.rb +21 -0
- data/ruby_ex/session/fetchable.rb +57 -0
- data/ruby_ex/session/fetcher.rb +62 -0
- data/ruby_ex/session/hookable.rb +26 -0
- data/ruby_ex/session/profile.rb +110 -0
- data/ruby_ex/session/server.rb +582 -0
- data/ruby_ex/session/test/administrable_test.rb +337 -0
- data/ruby_ex/session/test/basic_test.rb +523 -0
- data/ruby_ex/session/test/dispatcher_test.rb +409 -0
- data/ruby_ex/session/test/fetchable_test.rb +119 -0
- data/ruby_ex/session/test/sub_server_test.rb +188 -0
- data/ruby_ex/shuffle.rb +30 -0
- data/ruby_ex/spring.rb +136 -0
- data/ruby_ex/spring_set.rb +137 -0
- data/ruby_ex/string_ex.rb +28 -0
- data/ruby_ex/symtbl.rb +106 -0
- data/ruby_ex/synflow.rb +474 -0
- data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
- data/ruby_ex/thread_mutex.rb +10 -0
- data/ruby_ex/timeout_ex.rb +81 -0
- data/ruby_ex/top_down.rb +73 -0
- data/ruby_ex/trace.rb +26 -0
- data/ruby_ex/uri/druby.rb +81 -0
- data/ruby_ex/uri/file.rb +65 -0
- data/ruby_ex/uri/ftp_ex.rb +37 -0
- data/ruby_ex/uri/http_ex.rb +43 -0
- data/ruby_ex/uri/ssh.rb +92 -0
- data/ruby_ex/uri/svn.rb +118 -0
- data/ruby_ex/uri_ex.rb +45 -0
- data/ruby_ex/verbose_object.rb +30 -0
- data/ruby_ex/version.rb +66 -0
- data/ruby_ex/yaml/basenode_ext.rb +63 -0
- data/ruby_ex/yaml/chop_header.rb +23 -0
- data/ruby_ex/yaml/transform.rb +449 -0
- data/ruby_ex/yaml/yregexpath.rb +76 -0
- data/src/changelog.rb +28 -18
- data/src/conflict.rb +20 -0
- data/src/diff.rb +18 -0
- data/src/diffstat.rb +9 -3
- data/src/last_changed_date.rb +18 -0
- data/src/mail.rb +33 -65
- data/src/message.rb +15 -9
- data/src/mycommit.rb +29 -14
- data/src/news.rb +24 -3
- data/src/status.rb +17 -0
- data/src/svn.rb +2 -2
- data/src/vcs.rb +24 -3
- metadata +124 -5
- 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
|
+
|
data/ruby_ex/daemon.rb
ADDED
|
@@ -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
|
data/ruby_ex/diff.rb
ADDED
|
@@ -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
|
+
|