ruby_ex 0.1.1
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/AUTHORS +51 -0
- data/ChangeLog +1763 -0
- data/NEWS +3 -0
- data/README +1 -0
- data/Rakefile +8 -0
- data/SPEC.dyn.yml +10 -0
- data/SPEC.gem.yml +269 -0
- data/SPEC.yml +36 -0
- data/src/abstract.rb +253 -0
- data/src/abstract_node.rb +85 -0
- data/src/algorithms.rb +12 -0
- data/src/algorithms/simulated_annealing.rb +142 -0
- data/src/ask.rb +100 -0
- data/src/attributed_class.rb +303 -0
- data/src/cache.rb +350 -0
- data/src/checkout.rb +12 -0
- data/src/choose.rb +271 -0
- data/src/commands.rb +20 -0
- data/src/commands/command.rb +492 -0
- data/src/commands/datas.rb +16 -0
- data/src/commands/datas/composite.rb +31 -0
- data/src/commands/datas/data.rb +65 -0
- data/src/commands/datas/factory.rb +69 -0
- data/src/commands/datas/temp.rb +26 -0
- data/src/commands/factory.rb +67 -0
- data/src/commands/helpers.rb +81 -0
- data/src/commands/pipe.rb +66 -0
- data/src/commands/runners.rb +16 -0
- data/src/commands/runners/exec.rb +50 -0
- data/src/commands/runners/fork.rb +130 -0
- data/src/commands/runners/runner.rb +140 -0
- data/src/commands/runners/system.rb +57 -0
- data/src/commands/seq.rb +32 -0
- data/src/config_file.rb +95 -0
- data/src/const_regexp.rb +57 -0
- data/src/daemon.rb +135 -0
- data/src/diff.rb +665 -0
- data/src/dlogger.rb +62 -0
- data/src/drb/drb_observable.rb +95 -0
- data/src/drb/drb_observable_pool.rb +27 -0
- data/src/drb/drb_service.rb +44 -0
- data/src/drb/drb_undumped_attributes.rb +56 -0
- data/src/drb/drb_undumped_indexed_object.rb +55 -0
- data/src/drb/insecure_protected_methods.rb +101 -0
- data/src/drb_ex.rb +12 -0
- data/src/dumpable_proc.rb +57 -0
- data/src/filetype.rb +229 -0
- data/src/generate_id.rb +44 -0
- data/src/histogram.rb +222 -0
- data/src/hookable.rb +283 -0
- data/src/hooker.rb +54 -0
- data/src/indexed_node.rb +65 -0
- data/src/io_marshal.rb +99 -0
- data/src/ioo.rb +193 -0
- data/src/labeled_node.rb +62 -0
- data/src/logger_observer.rb +24 -0
- data/src/md5sum.rb +70 -0
- data/src/module/autoload_tree.rb +65 -0
- data/src/module/hierarchy.rb +334 -0
- data/src/module/instance_method_visibility.rb +71 -0
- data/src/node.rb +81 -0
- data/src/object_monitor.rb +143 -0
- data/src/object_monitor_activity.rb +34 -0
- data/src/observable.rb +138 -0
- data/src/observable_pool.rb +291 -0
- data/src/orderedhash.rb +252 -0
- data/src/pp_hierarchy.rb +30 -0
- data/src/random_generators.rb +29 -0
- data/src/random_generators/random_generator.rb +33 -0
- data/src/random_generators/ruby.rb +25 -0
- data/src/ruby_ex.rb +124 -0
- data/src/safe_eval.rb +346 -0
- data/src/sendmail.rb +214 -0
- data/src/service_manager.rb +122 -0
- data/src/shuffle.rb +30 -0
- data/src/spring.rb +134 -0
- data/src/spring_set.rb +134 -0
- data/src/symtbl.rb +108 -0
- data/src/synflow.rb +474 -0
- data/src/thread_mutex.rb +11 -0
- data/src/timeout_ex.rb +79 -0
- data/src/trace.rb +26 -0
- data/src/uri/druby.rb +78 -0
- data/src/uri/file.rb +63 -0
- data/src/uri/ftp_ex.rb +36 -0
- data/src/uri/http_ex.rb +41 -0
- data/src/uri/pgsql.rb +136 -0
- data/src/uri/ssh.rb +87 -0
- data/src/uri/svn.rb +113 -0
- data/src/uri_ex.rb +71 -0
- data/src/verbose_object.rb +70 -0
- data/src/yaml/basenode_ext.rb +63 -0
- data/src/yaml/chop_header.rb +24 -0
- data/src/yaml/transform.rb +450 -0
- data/src/yaml/yregexpath.rb +76 -0
- data/test/algorithms/simulated_annealing_test.rb +102 -0
- data/test/check-pkg-ruby_ex.yml +15 -0
- data/test/check-ruby_ex.yml +12 -0
- data/test/resources/autoload_tree/A.rb +11 -0
- data/test/resources/autoload_tree/B.rb +10 -0
- data/test/resources/autoload_tree/foo/C.rb +18 -0
- data/test/resources/foo.txt +6 -0
- data/test/sanity-suite.yml +12 -0
- data/test/sanity/multiple-requires.yml +20 -0
- data/test/sanity/single-requires.yml +24 -0
- data/test/test-unit-setup.rb +6 -0
- data/test/unit-suite.yml +14 -0
- metadata +269 -0
@@ -0,0 +1,50 @@
|
|
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: exec.rb 255 2005-06-01 00:08:46Z ertai $
|
5
|
+
|
6
|
+
require 'commands'
|
7
|
+
|
8
|
+
module Commands
|
9
|
+
|
10
|
+
module Runners
|
11
|
+
|
12
|
+
class Exec < Runner
|
13
|
+
concrete
|
14
|
+
|
15
|
+
def exec ( aCommand, data )
|
16
|
+
Kernel.exec(*aCommand.to_a)
|
17
|
+
end
|
18
|
+
|
19
|
+
end # class Exec
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
test_section __FILE__ do
|
24
|
+
|
25
|
+
class ExecTest < Test::Unit::TestCase
|
26
|
+
|
27
|
+
def setup
|
28
|
+
assert_nothing_raised { @runner = Exec.new }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_0_initialize
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_simple
|
35
|
+
TempPath.new do |tmp|
|
36
|
+
cmd = %Q[ruby -e "File.open('#{tmp}', 'w') { |f| f.puts :foo }"]
|
37
|
+
pid = fork do
|
38
|
+
@runner.run(cmd.to_cmd)
|
39
|
+
end
|
40
|
+
Process.waitpid pid
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end # class ExecTest
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end # module Runners
|
49
|
+
|
50
|
+
end # module Commands
|
@@ -0,0 +1,130 @@
|
|
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: fork.rb 255 2005-06-01 00:08:46Z ertai $
|
5
|
+
|
6
|
+
require 'commands'
|
7
|
+
|
8
|
+
module Commands
|
9
|
+
|
10
|
+
module Runners
|
11
|
+
|
12
|
+
class Fork < Exec
|
13
|
+
concrete
|
14
|
+
|
15
|
+
#
|
16
|
+
# Hooks declaration
|
17
|
+
#
|
18
|
+
|
19
|
+
hook_declare :exception_raised_during_exec
|
20
|
+
hook_declare :already_killed
|
21
|
+
hook_declare :waitpid
|
22
|
+
hook_declare :failure
|
23
|
+
hook_declare :son
|
24
|
+
hook_declare :kill
|
25
|
+
|
26
|
+
#
|
27
|
+
# Methods
|
28
|
+
#
|
29
|
+
|
30
|
+
def run_impl ( aCommand, data )
|
31
|
+
data.pid = Kernel.fork do
|
32
|
+
begin
|
33
|
+
hook_trigger :son, aCommand, data
|
34
|
+
super
|
35
|
+
rescue Exception => ex
|
36
|
+
hook_trigger :exception_raised_during_exec, ex
|
37
|
+
end
|
38
|
+
end
|
39
|
+
hook_trigger :waitpid, data
|
40
|
+
if data.status.nil? or not data.status.exitstatus.zero?
|
41
|
+
hook_trigger :failure, data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def abort ( data )
|
47
|
+
if data.pid
|
48
|
+
begin
|
49
|
+
hook_trigger :kill, data
|
50
|
+
hook_trigger :waitpid, data
|
51
|
+
rescue Errno::ESRCH
|
52
|
+
hook_trigger :already_killed, data.pid
|
53
|
+
end
|
54
|
+
end
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def exception_raised_during_exec ( anException )
|
60
|
+
STDERR.reopen(File.new(1))
|
61
|
+
STDERR.puts anException
|
62
|
+
exit! 127
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def kill ( data )
|
67
|
+
Process.kill('-KILL', -data.pid)
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def raise_on_failures
|
72
|
+
hooker_subscribe FailureHooker.new
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
end # class Fork
|
77
|
+
|
78
|
+
|
79
|
+
class FailureHooker
|
80
|
+
class Error < Exception
|
81
|
+
end
|
82
|
+
def failure ( data )
|
83
|
+
output, error = '', ''
|
84
|
+
output = data.output.read rescue nil
|
85
|
+
error = data.error.read rescue nil
|
86
|
+
output.gsub!(/^/, ' ')
|
87
|
+
error.gsub!(/^/, ' ')
|
88
|
+
|
89
|
+
raise Error, <<end
|
90
|
+
---
|
91
|
+
Command failed:
|
92
|
+
exit: #{data.status.exitstatus}
|
93
|
+
output:
|
94
|
+
#{output}
|
95
|
+
error:
|
96
|
+
#{error}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
test_section __FILE__ do
|
103
|
+
|
104
|
+
class ForkTest < Test::Unit::TestCase
|
105
|
+
|
106
|
+
def setup
|
107
|
+
assert_nothing_raised { @runner = Fork.new }
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_0_initialize
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_simple
|
114
|
+
TempPath.new do |tmp|
|
115
|
+
cmd = %Q[ruby -e "sleep 1
|
116
|
+
File.open('#{tmp}', 'w') { |f| f.puts :foo }"]
|
117
|
+
data = @runner.run(cmd.to_cmd)
|
118
|
+
assert(! tmp.exist?)
|
119
|
+
data.waitpid
|
120
|
+
assert(tmp.exist?)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end # class ForkTest
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end # module Runners
|
129
|
+
|
130
|
+
end # module Commands
|
@@ -0,0 +1,140 @@
|
|
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 255 2005-06-01 00:08:46Z ertai $
|
5
|
+
|
6
|
+
require 'commands'
|
7
|
+
|
8
|
+
module Commands
|
9
|
+
|
10
|
+
module Runners
|
11
|
+
|
12
|
+
class Runner
|
13
|
+
|
14
|
+
abstract
|
15
|
+
|
16
|
+
include Hookable
|
17
|
+
include Hooker
|
18
|
+
|
19
|
+
|
20
|
+
#
|
21
|
+
# Accessors
|
22
|
+
#
|
23
|
+
|
24
|
+
attr_accessor :command_data_factory
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# Hooks declaration
|
29
|
+
#
|
30
|
+
|
31
|
+
hook_declare :display_command
|
32
|
+
hook_declare :data
|
33
|
+
hook_declare :before_open
|
34
|
+
hook_declare :before_chdir
|
35
|
+
hook_declare :before_exec
|
36
|
+
hook_declare :exec
|
37
|
+
|
38
|
+
|
39
|
+
#
|
40
|
+
# Construction methods.
|
41
|
+
#
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@command_data_factory = Datas::Factory.new
|
45
|
+
hooker_subscribe self
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
#
|
50
|
+
# Methods.
|
51
|
+
#
|
52
|
+
|
53
|
+
def run ( aCommand )
|
54
|
+
unless aCommand.is_a? Commands::Command
|
55
|
+
raise ArgumentError, 'Need a Runner::Command'
|
56
|
+
end
|
57
|
+
|
58
|
+
hook_trigger :display_command, aCommand
|
59
|
+
|
60
|
+
data = @command_data_factory.create
|
61
|
+
data.input = aCommand.input unless aCommand.input.nil?
|
62
|
+
data.output = aCommand.output unless aCommand.output.nil?
|
63
|
+
data.error = aCommand.error unless aCommand.error.nil?
|
64
|
+
hook_trigger :data, aCommand, data
|
65
|
+
|
66
|
+
run_impl(aCommand, data)
|
67
|
+
|
68
|
+
data
|
69
|
+
end
|
70
|
+
|
71
|
+
def run_impl ( aCommand, data )
|
72
|
+
hook_trigger :before_open, data
|
73
|
+
STDIN.reopen(data.input.to_io_for_commands) unless data.input.nil?
|
74
|
+
STDOUT.reopen(data.output.to_io_for_commands) unless data.output.nil?
|
75
|
+
STDERR.reopen(data.error.to_io_for_commands) unless data.error.nil?
|
76
|
+
|
77
|
+
hook_trigger :before_chdir, data
|
78
|
+
Dir.chdir(aCommand.dir) unless aCommand.dir.nil?
|
79
|
+
|
80
|
+
hook_trigger :before_exec, aCommand, data
|
81
|
+
hook_trigger :exec, aCommand, data
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def make_verbose
|
86
|
+
hooker_subscribe VerboseHooker.new
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def make_debug
|
92
|
+
hooker_subscribe DebugHooker.new
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Hookers
|
98
|
+
#
|
99
|
+
|
100
|
+
class DebugHooker
|
101
|
+
include Hooker
|
102
|
+
|
103
|
+
def log ( m, *a )
|
104
|
+
STDERR.puts
|
105
|
+
STDERR.puts "#{m}: #{a.inspect}"
|
106
|
+
end
|
107
|
+
|
108
|
+
hook_default_method :log
|
109
|
+
|
110
|
+
end # class DebugHooker
|
111
|
+
|
112
|
+
|
113
|
+
class VerboseHooker
|
114
|
+
include Hooker
|
115
|
+
|
116
|
+
def display_command ( m )
|
117
|
+
STDERR.puts "Running: #{m.to_a.join(' ')}"
|
118
|
+
end
|
119
|
+
|
120
|
+
end # class VerboseHooker
|
121
|
+
|
122
|
+
|
123
|
+
end # class Runner
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
test_section __FILE__ do
|
128
|
+
|
129
|
+
class RunnerTest < Test::Unit::TestCase
|
130
|
+
|
131
|
+
def test_abstract
|
132
|
+
assert_raise(TypeError) { Runner.new }
|
133
|
+
end
|
134
|
+
|
135
|
+
end # class RunnerTest
|
136
|
+
end
|
137
|
+
|
138
|
+
end # module Runners
|
139
|
+
|
140
|
+
end # module Commands
|
@@ -0,0 +1,57 @@
|
|
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: system.rb 255 2005-06-01 00:08:46Z ertai $
|
5
|
+
|
6
|
+
require 'commands'
|
7
|
+
|
8
|
+
module Commands
|
9
|
+
|
10
|
+
module Runners
|
11
|
+
|
12
|
+
class WaitpidHooker
|
13
|
+
include Hooker
|
14
|
+
|
15
|
+
def waitpid ( data )
|
16
|
+
data.waitpid
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# This version wait to reach the end of the command before returns.
|
22
|
+
class System < Fork
|
23
|
+
concrete
|
24
|
+
|
25
|
+
hooker_subscribe WaitpidHooker.new
|
26
|
+
|
27
|
+
end # class System
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
test_section __FILE__ do
|
32
|
+
|
33
|
+
class SystemTest < Test::Unit::TestCase
|
34
|
+
|
35
|
+
def setup
|
36
|
+
assert_nothing_raised { @runner = System.new }
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_0_initialize
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_simple
|
43
|
+
TempPath.new do |tmp|
|
44
|
+
cmd = %Q[ruby -e "sleep 0.5
|
45
|
+
File.open('#{tmp}', 'w') { |f| f.puts :foo }"]
|
46
|
+
@runner.run(cmd.to_cmd)
|
47
|
+
assert(tmp.exist?)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end # class SystemTest
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end # module Runners
|
56
|
+
|
57
|
+
end # module Commands
|
data/src/commands/seq.rb
ADDED
@@ -0,0 +1,32 @@
|
|
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 255 2005-06-01 00:08:46Z ertai $
|
5
|
+
|
6
|
+
require 'commands'
|
7
|
+
|
8
|
+
module Commands
|
9
|
+
|
10
|
+
class Seq < Command
|
11
|
+
|
12
|
+
def initialize ( *cmds )
|
13
|
+
@cmds = cmds
|
14
|
+
end
|
15
|
+
|
16
|
+
def run ( *a )
|
17
|
+
datas = []
|
18
|
+
@cmds.each do |cmd|
|
19
|
+
datas.last.waitpid unless datas.empty?
|
20
|
+
datas << cmd.run(*a)
|
21
|
+
end
|
22
|
+
Datas::Composite.new(datas)
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_sh
|
26
|
+
strs = @cmds.map { |cmd| "(#{cmd.to_sh})" }
|
27
|
+
"(#{strs.join(' ; ')})#{sh_args}"
|
28
|
+
end
|
29
|
+
|
30
|
+
end # class Seq
|
31
|
+
|
32
|
+
end # module Commands
|
data/src/config_file.rb
ADDED
@@ -0,0 +1,95 @@
|
|
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 266 2005-06-01 14:27:18Z ertai $
|
7
|
+
|
8
|
+
|
9
|
+
require 'ruby_ex'
|
10
|
+
require 'pathname'
|
11
|
+
require 'yaml'
|
12
|
+
require 'delegate'
|
13
|
+
|
14
|
+
|
15
|
+
class ConfigFile < SimpleDelegator
|
16
|
+
|
17
|
+
protected :__setobj__
|
18
|
+
|
19
|
+
class FormatError < RuntimeError; end
|
20
|
+
|
21
|
+
attr_reader :default_config
|
22
|
+
|
23
|
+
def initialize(filename, default_config=nil)
|
24
|
+
@filename = Pathname.new(filename)
|
25
|
+
@default_config = default_config.freeze
|
26
|
+
__load__
|
27
|
+
end
|
28
|
+
|
29
|
+
def __load__(&block)
|
30
|
+
config = nil
|
31
|
+
if @filename.exist?
|
32
|
+
@filename.open do |f|
|
33
|
+
f.flock(File::LOCK_EX)
|
34
|
+
config = real_load(f)
|
35
|
+
f.flock(File::LOCK_UN)
|
36
|
+
end
|
37
|
+
block ? block[config] : check_config(config)
|
38
|
+
config.freeze
|
39
|
+
else
|
40
|
+
if $VERBOSE
|
41
|
+
Kernel.warn('warning: use default configuration because no ' +
|
42
|
+
'configuration file has been found')
|
43
|
+
end
|
44
|
+
config = @default_config
|
45
|
+
end
|
46
|
+
__setobj__(config)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Raise a FormatError if the loaded configuration do not fit the format
|
50
|
+
protected
|
51
|
+
def check_config(config)
|
52
|
+
end
|
53
|
+
|
54
|
+
# You can override it to change arguments or Yaml parsing command.
|
55
|
+
protected
|
56
|
+
def real_load(io)
|
57
|
+
YAML::load(io)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end # class ConfigFile
|
62
|
+
|
63
|
+
|
64
|
+
test_section __FILE__ do
|
65
|
+
|
66
|
+
require 'tempfile'
|
67
|
+
|
68
|
+
|
69
|
+
class ConfigFileTest < Test::Unit::TestCase
|
70
|
+
|
71
|
+
def test_config_file
|
72
|
+
tmp_file = nil
|
73
|
+
Tempfile.open('config_file') do |f|
|
74
|
+
f.puts '---'
|
75
|
+
f.puts 'key1: val1'
|
76
|
+
f.puts 'key2: val2'
|
77
|
+
tmp_file = f
|
78
|
+
end
|
79
|
+
raise 'no temp file' if tmp_file.nil?
|
80
|
+
default_config = { 'key1' => 'def1', 'key2' => 'def2' }
|
81
|
+
config_file = ConfigFile.new('/toto', default_config)
|
82
|
+
assert_equal(default_config, config_file.__getobj__)
|
83
|
+
assert_raises(NoMethodError) { config_file.__setobj__(nil) }
|
84
|
+
config_file = ConfigFile.new(tmp_file.path, default_config)
|
85
|
+
assert_equal({ 'key1' => 'val1', 'key2' => 'val2' },
|
86
|
+
config_file.__getobj__)
|
87
|
+
assert(config_file.__getobj__.frozen?)
|
88
|
+
end
|
89
|
+
|
90
|
+
end # class ConfigFileTest
|
91
|
+
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
|