core_ex 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +39 -1
- data/SPEC.dyn.yml +6 -6
- data/SPEC.gemspec +13 -0
- data/SPEC.yml +3 -3
- data/lib/core_ex/dependencies_ext/constant_load_path.rb +23 -0
- data/lib/core_ex/embedded_tests.rb +29 -23
- data/lib/core_ex/enumerable.rb +10 -18
- data/lib/core_ex/exception.rb +24 -21
- data/lib/core_ex/file_utils.rb +51 -0
- data/lib/core_ex/module/attr_once.rb +41 -0
- data/lib/core_ex/module/import.rb +28 -0
- data/lib/core_ex/module/mix_in_with_args.rb +267 -0
- data/lib/core_ex/object/instance_eval_with_args.rb +56 -0
- data/lib/core_ex/object/singleton_class.rb +78 -0
- data/lib/core_ex/object/the_first_time.rb +32 -0
- data/lib/core_ex/pathname.rb +268 -164
- data/lib/core_ex/proc.rb +77 -0
- data/lib/core_ex/rakefile_base.rf +93 -51
- data/lib/core_ex/require.rb +43 -384
- data/lib/core_ex/string.rb +52 -41
- data/lib/core_ex/time.rb +26 -41
- data/lib/core_ex/try_dup.rb +68 -0
- data/lib/core_ex/yaml.rb +103 -100
- data/lib/core_ex.rb +246 -35
- data/lib/{core_ex/dtime.rb → d_time.rb} +36 -22
- data/lib/{core_ex/dumpable_proc.rb → dumpable_proc.rb} +1 -2
- data/lib/{core_ex/pathlist.rb → path_list.rb} +111 -63
- data/lib/{core_ex/temp_path.rb → temp_path.rb} +55 -41
- data/lib/{core_ex/test/unit/ui/yaml/testrunner.rb → test/unit/u_i/yaml/test_runner.rb} +7 -10
- data/lib/{core_ex/version.rb → version.rb} +4 -7
- data/lib/yaml_extension.rb +78 -0
- data/test/check-core_ex.yml +6 -8
- data/test/check-pkg-core_ex.yml +3 -6
- data/test/sanity/multiple-requires.yml +41 -17
- data/test/sanity/single-requires.yml +36 -20
- data/test/sanity-suite.yml +5 -7
- data/test/test-unit-setup.rb +11 -3
- data/test/unit-suite.yml +8 -9
- metadata +35 -13
- data/lib/core_ex/attr_once.rb +0 -36
- data/lib/core_ex/fileutils.rb +0 -44
data/NEWS
CHANGED
@@ -1,4 +1,42 @@
|
|
1
|
-
= New in 0.
|
1
|
+
= New in 0.3, 2005-09-15:
|
2
|
+
|
3
|
+
* Architecture:
|
4
|
+
- Need activesupport ~> 1.1.1.
|
5
|
+
- No more custom require/load/autoload.
|
6
|
+
- Many changes to be closer of the activesupport dependency system.
|
7
|
+
- No more use the auto_require feature of rubygems.
|
8
|
+
- Add an automated vendor directory support.
|
9
|
+
- No more use `ask' but HighLine in Rakefiles.
|
10
|
+
|
11
|
+
* Module:
|
12
|
+
- mix_in_with_args.rb: Provides `mixin' which is like `include' but
|
13
|
+
can receive arguments. A module can aslo be setup by two blocks
|
14
|
+
`setup' and `teardown'. Which are run in the class context,
|
15
|
+
before and after the real inclusion.
|
16
|
+
- import.rb: Allow to write MyFavoriteModule.import! to load or require
|
17
|
+
a module managed by Dependencies of activesupport.
|
18
|
+
|
19
|
+
* Object:
|
20
|
+
- instance_eval_with_args.rb:
|
21
|
+
Makes the instance_eval method of Object support arguments.
|
22
|
+
- the_first_time.rb: This method takes a block. It ensures that the
|
23
|
+
code will be run only once. You can use this method only once
|
24
|
+
per file.
|
25
|
+
- singleton_class.rb: Provides an access to the singleton class of
|
26
|
+
an object. Also provides singleton_class_eval,
|
27
|
+
undef_singleton_method, define_singleton_method.
|
28
|
+
|
29
|
+
* Yaml:
|
30
|
+
- Better option handling in yaml extensions.
|
31
|
+
- Inlines little hashs and arrays (with the Inline option set to true).
|
32
|
+
|
33
|
+
* PathList:
|
34
|
+
- Improves PathList#each, and support aliases in Yaml.
|
35
|
+
- Many other improvements.
|
36
|
+
|
37
|
+
* TempPath: Add TempPath.fork_init that initialize a child of a fork.
|
38
|
+
|
39
|
+
= New in 0.2, 2005-06-24:
|
2
40
|
|
3
41
|
* Yaml:
|
4
42
|
Great improvement of the Yaml extension, new Yaml types are now
|
data/SPEC.dyn.yml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:OpenStruct
|
2
2
|
table:
|
3
|
-
:date: "Thu, 23 Jun 2005"
|
4
|
-
:version: !ruby/object:Version
|
5
|
-
build: 0
|
6
|
-
major: 0
|
7
|
-
minor: 2
|
8
|
-
revision: 307
|
9
3
|
:url: svn://svn.feydakins.org/ruby_ex/trunk/core_ex
|
10
4
|
:version_id: ''
|
5
|
+
:version: !ruby/object:Version
|
6
|
+
build: 1
|
7
|
+
major: 0
|
8
|
+
minor: 3
|
9
|
+
revision: 356
|
10
|
+
:date: "Fri, 16 Sep 2005"
|
data/SPEC.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{core_ex}
|
3
|
+
s.version = "0.3.1"
|
4
|
+
s.date = %q{2005-09-16}
|
5
|
+
s.summary = %q{CoreEx is a proposal for a standard library extension.}
|
6
|
+
s.email = ["nicolas.despres@gmail.com", "ertai@feydakins.org"]
|
7
|
+
s.homepage = %q{http://api.feydakins.org/core_ex}
|
8
|
+
s.rubyforge_project = %q{core_ex}
|
9
|
+
s.description = %q{CoreEx is designed to provides a simple but quite useful extension of the standard library of Ruby. So some classes and modules like Pathname, Time, Enumerable, Exception, FileUtils, String, and YAML are extended. There is also some new features like attr_once, DTime, TempPath, Version, embedded_tests, filelist (almost from rake), a common Rakefile, and an extension of the require system.}
|
10
|
+
s.authors = ["Nicolas Despr\350s", "Nicolas Pouillard"]
|
11
|
+
s.files = ["lib/core_ex.rb", "lib/d_time.rb", "lib/dumpable_proc.rb", "lib/path_list.rb", "lib/temp_path.rb", "lib/version.rb", "lib/yaml_extension.rb", "lib/core_ex/embedded_tests.rb", "lib/core_ex/enumerable.rb", "lib/core_ex/exception.rb", "lib/core_ex/file_utils.rb", "lib/core_ex/pathname.rb", "lib/core_ex/proc.rb", "lib/core_ex/rakefile_base.rf", "lib/core_ex/require.rb", "lib/core_ex/string.rb", "lib/core_ex/time.rb", "lib/core_ex/try_dup.rb", "lib/core_ex/yaml.rb", "lib/core_ex/dependencies_ext/constant_load_path.rb", "lib/core_ex/module/attr_once.rb", "lib/core_ex/module/import.rb", "lib/core_ex/module/mix_in_with_args.rb", "lib/core_ex/object/instance_eval_with_args.rb", "lib/core_ex/object/singleton_class.rb", "lib/core_ex/object/the_first_time.rb", "lib/test/unit/u_i/yaml/test_runner.rb", "test/check-core_ex.yml", "test/check-pkg-core_ex.yml", "test/resources", "test/sanity", "test/sanity-suite.yml", "test/test-unit-setup.rb", "test/unit-suite.yml", "test/resources/require", "test/resources/use-from-gems.rb", "test/resources/yaml_testrunner", "test/resources/require/test_require", "test/resources/require/test_require_rb.rb", "test/resources/require/test_require_so.so", "test/resources/yaml_testrunner/unit_test.rb", "test/sanity/multiple-requires.yml", "test/sanity/single-requires.yml", "AUTHORS", "NEWS", "Rakefile", "README", "SPEC.dyn.yml", "SPEC.gemspec", "SPEC.yml"]
|
12
|
+
s.add_dependency(%q<activesupport>, ["~> 1.1.1"])
|
13
|
+
end
|
data/SPEC.yml
CHANGED
@@ -29,14 +29,14 @@ rdoc_files: !filelist
|
|
29
29
|
- README
|
30
30
|
- AUTHORS
|
31
31
|
- NEWS
|
32
|
-
- lib
|
33
|
-
- lib/core_ex/**/*.rb
|
32
|
+
- lib/**/*.rb
|
34
33
|
|
35
34
|
pkg_files: !filelist
|
36
35
|
- lib/**/*.r[bf]
|
37
36
|
- test/**/*
|
38
37
|
- '[A-Z]*'
|
39
38
|
|
40
|
-
|
39
|
+
dependencies:
|
40
|
+
activesupport: [~> 1.1.1, 5161/activesupport-1.1.1.tgz]
|
41
41
|
|
42
42
|
ttk_version: ~> 0.3.0
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
|
+
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
|
+
# License:: Gnu General Public License.
|
4
|
+
# Revision:: $Id: constant_load_path.rb 336 2005-09-06 20:32:49Z ertai $
|
5
|
+
|
6
|
+
module CoreEx
|
7
|
+
|
8
|
+
module DependenciesExt
|
9
|
+
|
10
|
+
module ConstantLoadPath
|
11
|
+
attr_reader :root
|
12
|
+
def to_path
|
13
|
+
root.to_path
|
14
|
+
end
|
15
|
+
end # module ConstantLoadPath
|
16
|
+
|
17
|
+
end # module DependenciesExt
|
18
|
+
|
19
|
+
end # module CoreEx
|
20
|
+
|
21
|
+
test_section __FILE__ do
|
22
|
+
|
23
|
+
end
|
@@ -1,37 +1,43 @@
|
|
1
1
|
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
2
|
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
3
|
# License:: Gnu General Public License.
|
4
|
-
# Revision:: $Id: embedded_tests.rb
|
4
|
+
# Revision:: $Id: embedded_tests.rb 345 2005-09-09 01:40:37Z ertai $
|
5
5
|
|
6
|
-
require 'set'
|
7
6
|
|
8
|
-
module
|
7
|
+
module CoreEx
|
9
8
|
|
10
|
-
|
11
|
-
@@files = Set.new
|
9
|
+
module EmbeddedTests
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@@test_mode = aRegexp
|
17
|
-
end
|
11
|
+
@@embedded_test_mode = nil
|
12
|
+
@@embedded_test_files = Set.new
|
13
|
+
@@embedded_test_blocks = []
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
def embedded_test_mode ( aRegexp )
|
16
|
+
raise 'No block needed' if block_given?
|
17
|
+
require 'test/unit'
|
18
|
+
@@embedded_test_mode = aRegexp
|
19
|
+
end
|
20
|
+
|
21
|
+
def embedded_test_mode?
|
22
|
+
!! @@embedded_test_mode
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_section ( __file__, &block )
|
26
|
+
__file__ = ::Pathname.new(__file__).expand_path
|
27
|
+
if block_given? and __file__.to_s =~ @@embedded_test_mode
|
28
|
+
unless @@embedded_test_files.include?(__file__)
|
29
|
+
@@embedded_test_blocks << block
|
30
|
+
@@embedded_test_files << __file__
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
if block_given? and __file__.to_s =~ @@test_mode
|
26
|
-
unless @@files.include?(__file__)
|
35
|
+
def run_embedded_test_sections
|
36
|
+
@@embedded_test_blocks.each do |block|
|
27
37
|
Kernel.instance_eval(&block)
|
28
|
-
@@files << __file__
|
29
38
|
end
|
30
39
|
end
|
31
|
-
end
|
32
40
|
|
33
|
-
end # module
|
41
|
+
end # module EmbeddedTests
|
34
42
|
|
35
|
-
|
36
|
-
test_mode EMBEDDED_TEST_MODE
|
37
|
-
end
|
43
|
+
end # module CoreEx
|
data/lib/core_ex/enumerable.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
2
|
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
3
|
# License:: Gnu General Public License.
|
4
|
-
# Revision:: $Id: enumerable.rb
|
4
|
+
# Revision:: $Id: enumerable.rb 334 2005-09-04 14:29:40Z ertai $
|
5
|
+
|
6
|
+
|
7
|
+
module CoreEx
|
8
|
+
# This empty module is just here to represent the feature of this file
|
9
|
+
module Enumerable
|
10
|
+
end # module Enumerable
|
11
|
+
end # module CoreEx
|
5
12
|
|
6
|
-
require 'core_ex'
|
7
13
|
|
8
14
|
module Enumerable
|
9
15
|
|
@@ -24,12 +30,12 @@ module Enumerable
|
|
24
30
|
|
25
31
|
def sum
|
26
32
|
fold(0) { |accu, x| accu + x }
|
27
|
-
end
|
33
|
+
end
|
28
34
|
|
29
35
|
|
30
36
|
def prod
|
31
37
|
fold(1) { |accu, x| accu * x }
|
32
|
-
end
|
38
|
+
end
|
33
39
|
|
34
40
|
|
35
41
|
# Basically, do the same as each_with_index but yield the arguments in
|
@@ -59,23 +65,9 @@ end # class Object
|
|
59
65
|
|
60
66
|
|
61
67
|
|
62
|
-
class String
|
63
|
-
|
64
|
-
def rec_fold ( init, &block )
|
65
|
-
if include? "\n"
|
66
|
-
super
|
67
|
-
else
|
68
|
-
block[init, self]
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end # class String
|
73
|
-
|
74
|
-
|
75
68
|
|
76
69
|
test_section __FILE__ do
|
77
70
|
|
78
|
-
require 'set'
|
79
71
|
require 'generator'
|
80
72
|
|
81
73
|
class EnumerableTest < Test::Unit::TestCase
|
data/lib/core_ex/exception.rb
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
# Copyright:: Copyright (c) 2004 Nicolas Despres. All rights reserved.
|
2
2
|
# Author:: Nicolas Despres <polrop@lrde.epita.fr>.
|
3
3
|
# License:: Gnu General Public License.
|
4
|
-
# Revision:: $Id: exception.rb
|
4
|
+
# Revision:: $Id: exception.rb 334 2005-09-04 14:29:40Z ertai $
|
5
5
|
|
6
|
+
module CoreEx
|
6
7
|
|
7
|
-
|
8
|
+
module Exception
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
#FIXME: write a ruby_pp which print exception backtrace exactly as ruby does
|
11
|
+
# by cuting long and repetitive backtrace.
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def long_pp
|
14
|
+
str = short_pp + "\n"
|
15
|
+
backtrace[1..-1].each { |x| str += " from #{x}\n" } if backtrace
|
16
|
+
str.chomp!
|
17
|
+
str
|
18
|
+
end
|
19
|
+
|
20
|
+
def short_pp
|
21
|
+
if backtrace.nil?
|
22
|
+
tiny_pp
|
23
|
+
else
|
24
|
+
"#{backtrace[0]}: #{tiny_pp}"
|
25
|
+
end
|
26
|
+
end
|
18
27
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
"#{backtrace[0]}: #{tiny_pp}"
|
28
|
+
def tiny_pp
|
29
|
+
exc_name = inspect.sub(/^#<(\w+):.+$/, '\1')
|
30
|
+
"#{self} (#{exc_name})"
|
24
31
|
end
|
25
|
-
end
|
26
32
|
|
27
|
-
|
28
|
-
exc_name = inspect.sub(/^#<(\w+):.+$/, '\1')
|
29
|
-
"#{self} (#{exc_name})"
|
30
|
-
end
|
33
|
+
end # module Exception
|
31
34
|
|
32
|
-
end #
|
35
|
+
end # module CoreEx
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
|
+
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
|
+
# License:: Gnu General Public License.
|
4
|
+
# Revision:: $Id: file_utils.rb 334 2005-09-04 14:29:40Z ertai $
|
5
|
+
|
6
|
+
|
7
|
+
module CoreEx
|
8
|
+
|
9
|
+
module FileUtils
|
10
|
+
|
11
|
+
module RemoveDir
|
12
|
+
|
13
|
+
def setup
|
14
|
+
alias_method :remove_dir_without_chmod, :remove_dir
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove_dir (dir, force = false) #:nodoc:
|
18
|
+
dir = dir.sub(%r</\z>, '')
|
19
|
+
first_time_p = true
|
20
|
+
begin
|
21
|
+
Dir.foreach(dir) do |file|
|
22
|
+
next if /\A\.\.?\z/ =~ file
|
23
|
+
path = "#{dir}/#{file.untaint}"
|
24
|
+
if File.symlink?(path)
|
25
|
+
remove_file path, force
|
26
|
+
elsif File.directory?(path)
|
27
|
+
remove_dir path, force
|
28
|
+
else
|
29
|
+
remove_file path, force
|
30
|
+
end
|
31
|
+
end
|
32
|
+
begin
|
33
|
+
Dir.rmdir dir
|
34
|
+
rescue Errno::ENOENT
|
35
|
+
raise unless force
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
if first_time_p
|
39
|
+
first_time_p = false
|
40
|
+
File.chmod 0777, dir
|
41
|
+
retry
|
42
|
+
end
|
43
|
+
raise
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end # module RemoveDir
|
48
|
+
|
49
|
+
end # module FileUtils
|
50
|
+
|
51
|
+
end # module CoreEx
|
@@ -0,0 +1,41 @@
|
|
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
|
+
# Revision:: $Id: attr_once.rb 333 2005-09-04 14:17:17Z ertai $
|
5
|
+
|
6
|
+
|
7
|
+
module CoreEx
|
8
|
+
|
9
|
+
module Module
|
10
|
+
|
11
|
+
module AttrOnce
|
12
|
+
# You can use this method as you use attr_reader. Must be used only with
|
13
|
+
# immutable object.
|
14
|
+
#
|
15
|
+
# This method is imported from the Date implementation. It provides a way
|
16
|
+
# to compute only once the value of getter. Basically, the first time, the
|
17
|
+
# getter is used, its result is computed and stored in an attribute with the
|
18
|
+
# same name. The second times only the attribute is returned.
|
19
|
+
def attr_once(*ids)
|
20
|
+
for id in ids
|
21
|
+
module_eval <<-"end;", __FILE__, __LINE__
|
22
|
+
alias_method :__#{id.to_i}__, :#{id.to_s}
|
23
|
+
private :__#{id.to_i}__
|
24
|
+
def #{id.to_s}(*args, &block)
|
25
|
+
if defined? @__#{id.to_i}__
|
26
|
+
@__#{id.to_i}__
|
27
|
+
elsif ! self.frozen?
|
28
|
+
@__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block)
|
29
|
+
else
|
30
|
+
__#{id.to_i}__(*args, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end;
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end # module AttrOnce
|
38
|
+
|
39
|
+
end # module Module
|
40
|
+
|
41
|
+
end # module CoreEx
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
|
+
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
|
+
# License:: Gnu General Public License.
|
4
|
+
# Revision:: $Id: import.rb 336 2005-09-06 20:32:49Z ertai $
|
5
|
+
|
6
|
+
|
7
|
+
module CoreEx
|
8
|
+
|
9
|
+
module Module
|
10
|
+
|
11
|
+
module Import
|
12
|
+
|
13
|
+
def require_or_load ( *args )
|
14
|
+
return true if args.empty?
|
15
|
+
Dependency.require_or_load(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :import!, :require_or_load
|
19
|
+
|
20
|
+
end # module Import
|
21
|
+
|
22
|
+
end # module Module
|
23
|
+
|
24
|
+
end # module CoreEx
|
25
|
+
|
26
|
+
test_section __FILE__ do
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
|
2
|
+
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
3
|
+
# License:: Gnu General Public License.
|
4
|
+
# Revision:: $Id: mix_in_with_args.rb 355 2005-09-15 23:18:43Z ertai $
|
5
|
+
|
6
|
+
|
7
|
+
class Module
|
8
|
+
|
9
|
+
mattr_accessor :blocks
|
10
|
+
self.blocks ||= {}
|
11
|
+
|
12
|
+
mattr_accessor :mix_in_initialized
|
13
|
+
self.mix_in_initialized ||= Set.new
|
14
|
+
|
15
|
+
# Register the setup block
|
16
|
+
def setup ( &block )
|
17
|
+
blocks[[:setup, self]] = block unless block.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Register the teardown block
|
21
|
+
def teardown ( &block )
|
22
|
+
blocks[[:teardown, self]] = block unless block.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def call_block ( kind, aModule, *args )
|
26
|
+
if block = blocks[[kind, aModule]]
|
27
|
+
if defined? CoreEx::Object::InstanceEvalWithArgs and
|
28
|
+
::Object.include? CoreEx::Object::InstanceEvalWithArgs
|
29
|
+
instance_eval_with_args(*args, &block)
|
30
|
+
else
|
31
|
+
if args.empty?
|
32
|
+
module_eval(&block)
|
33
|
+
else
|
34
|
+
raise
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
private :call_block
|
40
|
+
|
41
|
+
alias_method :include_without_setup_call, :include
|
42
|
+
|
43
|
+
def include ( *someModules )
|
44
|
+
someModules.each do |aModule|
|
45
|
+
mixin aModule
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def mixin ( aModule, *args )
|
50
|
+
pair = [self, aModule]
|
51
|
+
return if mix_in_initialized.include? pair
|
52
|
+
call_block(:setup, aModule, *args)
|
53
|
+
include_without_setup_call aModule
|
54
|
+
extend aModule::ClassMethods if aModule.const_defined? :ClassMethods
|
55
|
+
call_block(:teardown, aModule, *args)
|
56
|
+
mix_in_initialized << pair
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :make, :mixin
|
61
|
+
alias_method :have, :mixin
|
62
|
+
|
63
|
+
end # class Module
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
module CoreEx
|
68
|
+
|
69
|
+
module Module
|
70
|
+
|
71
|
+
# have PrettyInspect
|
72
|
+
# mixin Taggable
|
73
|
+
# make Taggable, :anOption => aValue
|
74
|
+
#
|
75
|
+
# Nothing here because we can't bootstrap this feature
|
76
|
+
module MixInWithArgs
|
77
|
+
|
78
|
+
module Assertions
|
79
|
+
|
80
|
+
attr_accessor :klass
|
81
|
+
|
82
|
+
def assert_mixin ( aModule, args=[], comment='' )
|
83
|
+
assert_nothing_raised(comment+" mixin") do
|
84
|
+
@module.module_eval { mixin(aModule, *args) }
|
85
|
+
end
|
86
|
+
assert @module.include?(aModule)
|
87
|
+
assert_kind_of aModule, @module.new, comment if @module.is_a? Class
|
88
|
+
end
|
89
|
+
|
90
|
+
end # module Assertions
|
91
|
+
|
92
|
+
end # module MixInWithArgs
|
93
|
+
|
94
|
+
|
95
|
+
test_section __FILE__ do
|
96
|
+
|
97
|
+
begin
|
98
|
+
require 'ruby_ex'
|
99
|
+
require 'mocks'
|
100
|
+
|
101
|
+
class TestMixInWithArgs < ::Test::Unit::TestCase
|
102
|
+
include Mocks::Assertions
|
103
|
+
include MixInWithArgs::Assertions
|
104
|
+
|
105
|
+
MOCK_OBJECT = Mocks::Object.new
|
106
|
+
|
107
|
+
module Taggable
|
108
|
+
def tag ( *a, &b )
|
109
|
+
MOCK_OBJECT.tag(*a, &b)
|
110
|
+
end
|
111
|
+
setup do |*a|
|
112
|
+
MOCK_OBJECT.setup(*a)
|
113
|
+
MOCK_OBJECT.tag_defined(method_defined?(:tag))
|
114
|
+
remove_method :tag if method_defined? :tag
|
115
|
+
MOCK_OBJECT.tag_defined(method_defined?(:tag))
|
116
|
+
MOCK_OBJECT.self_is = self
|
117
|
+
end
|
118
|
+
teardown do |*a|
|
119
|
+
MOCK_OBJECT.teardown(*a)
|
120
|
+
MOCK_OBJECT.tag_defined(method_defined?(:tag))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
module Cleanable
|
125
|
+
def clean ( *a, &b )
|
126
|
+
MOCK_OBJECT.clean(*a, &b)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
module SetupWithoutArgs
|
131
|
+
setup do
|
132
|
+
MOCK_OBJECT.self_is = self
|
133
|
+
end
|
134
|
+
end # module SetupWithoutArgs
|
135
|
+
|
136
|
+
module SetupFixedArgs
|
137
|
+
setup do |x, y, z|
|
138
|
+
MOCK_OBJECT.setup(x, y, z)
|
139
|
+
MOCK_OBJECT.self_is = self
|
140
|
+
end
|
141
|
+
end # module SetupFixedArgs
|
142
|
+
|
143
|
+
module WithClassMethods
|
144
|
+
module ClassMethods
|
145
|
+
def m
|
146
|
+
MOCK_OBJECT.m self
|
147
|
+
end
|
148
|
+
end # module ClassMethods
|
149
|
+
def i
|
150
|
+
MOCK_OBJECT.i self
|
151
|
+
end
|
152
|
+
setup { MOCK_OBJECT.setup self }
|
153
|
+
end # module WithClassMethods
|
154
|
+
|
155
|
+
class WithTag
|
156
|
+
def tag ( *a )
|
157
|
+
MOCK_OBJECT.old_tag(*a)
|
158
|
+
end
|
159
|
+
end # class WithTag
|
160
|
+
|
161
|
+
def setup
|
162
|
+
@module = Class.new
|
163
|
+
@mock_object = MOCK_OBJECT
|
164
|
+
end
|
165
|
+
|
166
|
+
def teardown
|
167
|
+
@mock_object.mock_clear
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_cleanable
|
171
|
+
assert_mixin Cleanable
|
172
|
+
assert_empty_mock
|
173
|
+
assert_nothing_raised { @module.new.clean(:foo, 42) }
|
174
|
+
assert_mock_calls [[:clean, [:foo, 42]]]
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_taggable
|
178
|
+
assert_mixin Taggable, [:foo => :bar]
|
179
|
+
assert_nothing_raised { @module.new.tag(:foo, 42) }
|
180
|
+
assert_mock_calls [[:setup, {:foo => :bar}],
|
181
|
+
[:tag_defined, false],
|
182
|
+
[:tag_defined, false],
|
183
|
+
[:self_is=, @module],
|
184
|
+
[:teardown, {:foo => :bar}],
|
185
|
+
[:tag_defined, true],
|
186
|
+
[:tag, [:foo, 42]]]
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_setup_without_args
|
190
|
+
assert_mixin SetupWithoutArgs
|
191
|
+
assert_nothing_raised { @module.new }
|
192
|
+
assert_mock_calls [[:self_is=, @module]]
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_setup_fixed_args
|
196
|
+
assert_mixin SetupFixedArgs, [1, 2, 3]
|
197
|
+
assert_nothing_raised { @module.new }
|
198
|
+
assert_mock_calls [[:setup, [1, 2, 3]], [:self_is=, @module]]
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_with_include
|
202
|
+
m = ::Module.new
|
203
|
+
m.module_eval "
|
204
|
+
class A
|
205
|
+
include Taggable
|
206
|
+
end
|
207
|
+
class B
|
208
|
+
include Cleanable
|
209
|
+
end
|
210
|
+
class C
|
211
|
+
mixin SetupFixedArgs, 1, 2, 3
|
212
|
+
include SetupWithoutArgs
|
213
|
+
end
|
214
|
+
"
|
215
|
+
assert_nothing_raised do
|
216
|
+
@a, @b, @c = m::A.new, m::B.new, m::C.new
|
217
|
+
@a.tag
|
218
|
+
@b.clean
|
219
|
+
end
|
220
|
+
assert_mock_calls [
|
221
|
+
[:setup],
|
222
|
+
[:tag_defined, false],
|
223
|
+
[:tag_defined, false],
|
224
|
+
[:self_is=, m::A],
|
225
|
+
[:teardown],
|
226
|
+
[:tag_defined, true],
|
227
|
+
[:setup, [1, 2, 3]],
|
228
|
+
[:self_is=, m::C],
|
229
|
+
[:self_is=, m::C],
|
230
|
+
[:tag], [:clean]
|
231
|
+
]
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_with_class_methods
|
235
|
+
assert_mixin WithClassMethods
|
236
|
+
assert_nothing_raised do
|
237
|
+
@object = @module.new
|
238
|
+
@object.i
|
239
|
+
@module.m
|
240
|
+
end
|
241
|
+
assert_mock_calls [[:setup, @module], [:i, @object], [:m, @module]]
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_already_tagged
|
245
|
+
@module = WithTag
|
246
|
+
assert_nothing_raised { @module.new.tag }
|
247
|
+
assert_mixin Taggable
|
248
|
+
assert_nothing_raised { @module.new.tag }
|
249
|
+
assert_mock_calls [[:old_tag], [:setup],
|
250
|
+
[:tag_defined, true],
|
251
|
+
[:tag_defined, false],
|
252
|
+
[:self_is=, @module],
|
253
|
+
[:teardown],
|
254
|
+
[:tag_defined, true],
|
255
|
+
[:tag]]
|
256
|
+
end
|
257
|
+
|
258
|
+
end # class TestMixInWithArgs
|
259
|
+
|
260
|
+
rescue LoadError
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
end # module Module
|
266
|
+
|
267
|
+
end # module CoreEx
|