core 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ = Core
2
+
3
+ Basic helpers used by other kinda projects.
4
+
5
+ == Installation
6
+
7
+ $ sudo gem install core --source http://gemcutter.org
8
+
9
+ == Usage
10
+
11
+ Still very alpha, documentation will come later.
@@ -0,0 +1,20 @@
1
+ require "rake/testtask"
2
+
3
+ begin
4
+ require "hanna/rdoctask"
5
+ rescue LoadError
6
+ require "rake/rdoctask"
7
+ end
8
+
9
+ task :default => [:test]
10
+
11
+ Rake::TestTask.new do |t|
12
+ t.test_files = Dir["test/*_test.rb"]
13
+ end
14
+
15
+ Rake::RDocTask.new do |t|
16
+ t.title = "Core Documentation"
17
+ t.main = "README.rdoc"
18
+ t.rdoc_files.include("README.rdoc", "lib/**/*.rb")
19
+ t.rdoc_dir = "doc"
20
+ end
@@ -0,0 +1,12 @@
1
+ require File.join(File.dirname(__FILE__), 'core', 'module')
2
+ require File.join(File.dirname(__FILE__), 'core', 'object')
3
+ ruby_files = Dir.glob(File.join(File.dirname(__FILE__), 'core', '*.rb'))
4
+ ruby_files.each { |file| require file }
5
+
6
+ module Kinda #:nodoc:
7
+ # Basic helpers used by other kinda projects
8
+ module Core
9
+ include Accessor
10
+ include Forwardable
11
+ end
12
+ end
@@ -0,0 +1,114 @@
1
+ module Kinda #:nodoc:
2
+ module Core #:nodoc:
3
+ # Improves the Ruby buit-in accessor methods
4
+ module Accessor
5
+ ClassMethods = inheritable_extend do
6
+ def __attr_reader__(*attributes, with_filter, &block)
7
+ attributes.each do |attribute|
8
+ if attribute.is_a?(Hash)
9
+ attribute, source = attribute.first
10
+ else
11
+ source = "@#{attribute}"
12
+ end
13
+ proc = if with_filter || !block
14
+ Proc.new do |*args|
15
+ return send("#{attribute}=", *args) unless args.empty?
16
+ value = if source[0] == '@'
17
+ instance_variable_get(source)
18
+ else
19
+ [*source].inject(self) do |object, symbol|
20
+ object.send(symbol)
21
+ end
22
+ end
23
+ block ? instance_exec(value, &block) : value
24
+ end
25
+ else
26
+ block
27
+ end
28
+ send(:define_method, attribute, &proc)
29
+ end
30
+ end
31
+
32
+ private :__attr_reader__
33
+
34
+ # attr_reader(:name, :age, :size)
35
+ # attr_reader(:name => :@name) is the default behaviour but you can use:
36
+ # attr_reader (:name => @the_name) to use a different instance variable
37
+ # attr_reader(:name => :first_name) or even an another attribute.
38
+ # More interesting, you can delegate to another object:
39
+ # attr_reader(:name => [:father, :name])
40
+ # attr_reader(:name => [:mother, :husband, :name])
41
+ def attr_reader(*attributes, &block)
42
+ __attr_reader__(*attributes, false, &block)
43
+ end
44
+
45
+ def attr_reader_with_filter(*attributes, &block)
46
+ __attr_reader__(*attributes, true, &block)
47
+ end
48
+
49
+ def __attr_writer__(*attributes, with_filter, &block)
50
+ attributes.each do |attribute|
51
+ if attribute.is_a?(Hash)
52
+ attribute, target = attribute.first
53
+ else
54
+ target = "@#{attribute}"
55
+ end
56
+ proc = if with_filter || !block
57
+ Proc.new do |value|
58
+ value = instance_exec(value, &block) if block
59
+ if target[0] == '@'
60
+ instance_variable_set(target, value)
61
+ else
62
+ [*target][0..-2].inject(self) do |object, symbol|
63
+ object.send(symbol)
64
+ end.send("#{[*target].last}=", value)
65
+ end
66
+ end
67
+ else
68
+ block
69
+ end
70
+ send(:define_method, "#{attribute}=", &proc)
71
+ end
72
+ end
73
+
74
+ private :__attr_writer__
75
+
76
+ def attr_writer(*attributes, &block)
77
+ __attr_writer__(*attributes, false, &block)
78
+ end
79
+
80
+ def attr_writer_with_filter(*attributes, &block)
81
+ __attr_writer__(*attributes, true, &block)
82
+ end
83
+
84
+ def attr_accessor(*attributes, &block)
85
+ attr_reader(*attributes, &block)
86
+ attr_writer(*attributes, &block)
87
+ end
88
+
89
+ def attr_accessor_with_filter(*attributes, &block)
90
+ attr_reader_with_filter(*attributes, &block)
91
+ attr_writer_with_filter(*attributes, &block)
92
+ end
93
+
94
+ def attr(attribute, writable=false)
95
+ attr_reader(attribute)
96
+ attr_writer(attribute) if writable
97
+ end
98
+
99
+ def attr_reader_with_default(attribute, default_value)
100
+ attr_reader_with_filter(attribute) do |value|
101
+ value.nil? ? default_value : value
102
+ end
103
+ end
104
+
105
+ def attr_accessor_with_default(attribute, default_value)
106
+ attr_reader_with_default(attribute, default_value)
107
+ attr_writer(attribute)
108
+ end
109
+ end
110
+
111
+ delegate_to_class ClassMethods.public_instance_methods
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,85 @@
1
+ require 'forwardable'
2
+
3
+ module Kinda
4
+ module Core
5
+ module Forwardable
6
+ ClassMethods = inheritable_extend do
7
+ include ::Forwardable
8
+
9
+ # Add a nice way to specify a different method for the accessor:
10
+ # delegate :remove => [:book, :delete]
11
+ # delegate [:add, :remove] => [:book, :<<, :delete]
12
+ def instance_delegate(hash)
13
+ hash.each do |delegate_methods, accessor|
14
+ accessor_methods = [*accessor]
15
+ accessor_object = accessor_methods.shift
16
+ [*delegate_methods].each do |delegate_method|
17
+ accessor_method = accessor_methods.shift || delegate_method
18
+ def_instance_delegator(accessor_object, accessor_method, delegate_method)
19
+ end
20
+ end
21
+ end
22
+
23
+ alias_method :delegate, :instance_delegate
24
+
25
+ # Create both reader and writer delegate
26
+ # Same usage than the simple "delegate" method except the following form
27
+ # in case the getter and setter symbols are different:
28
+ # delegate_attr :title => [:book, [:read_title, :write_title]]
29
+ def delegate_attr_accessor(hash, kind=(:accessor), with_filter=false, &block)
30
+ hash.each do |delegate_methods, accessor|
31
+ accessor_methods = [*accessor]
32
+ accessor_object = accessor_methods.shift
33
+ [*delegate_methods].each do |delegate_method|
34
+ accessor_method = accessor_methods.shift || delegate_method
35
+ accessor_getter, accessor_setter = case kind
36
+ when :accessor
37
+ getter, setter = [*accessor_method]
38
+ setter ||= getter
39
+ [getter, setter]
40
+ when :reader
41
+ [accessor_method, nil]
42
+ when :writer
43
+ [nil, accessor_method]
44
+ end
45
+ if accessor_getter
46
+ __attr_reader__({ delegate_method => [accessor_object, accessor_getter] },
47
+ with_filter, &block)
48
+ end
49
+ if accessor_setter
50
+ __attr_writer__({ delegate_method => [accessor_object, accessor_setter] },
51
+ with_filter, &block)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ alias_method :delegate_attr, :delegate_attr_accessor
58
+
59
+ def delegate_attr_accessor_with_filter(hash, &block)
60
+ delegate_attr_accessor(hash, :accessor, true, &block)
61
+ end
62
+
63
+ alias_method :delegate_attr_with_filter, :delegate_attr_accessor_with_filter
64
+
65
+ def delegate_attr_reader(hash, &block)
66
+ delegate_attr_accessor(hash, :reader, false, &block)
67
+ end
68
+
69
+ def delegate_attr_reader_with_filter(hash, &block)
70
+ delegate_attr_accessor(hash, :reader, true, &block)
71
+ end
72
+
73
+ def delegate_attr_writer(hash, &block)
74
+ delegate_attr_accessor(hash, :writer, false, &block)
75
+ end
76
+
77
+ def delegate_attr_writer_with_filter(hash, &block)
78
+ delegate_attr_accessor(hash, :writer, true, &block)
79
+ end
80
+ end
81
+
82
+ delegate_to_class ClassMethods.public_instance_methods
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,19 @@
1
+ module Kinda
2
+ module Core
3
+ # Thomas Sawyer's Functor Class slightly modified for Ruby 1.9
4
+ # http://facets.rubyforge.org/apidoc/api/core/classes/Functor.html
5
+ class Functor < BasicObject
6
+ def initialize(&proc)
7
+ @proc = proc
8
+ end
9
+
10
+ def to_proc
11
+ @proc
12
+ end
13
+
14
+ def method_missing(method_name, *args, &block)
15
+ @proc.call(method_name, *args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Kinda
2
+ module Core
3
+ module HashExtension
4
+ def delete_value(value)
5
+ delete_if { |k, v| v == value }
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ class Hash #:nodoc:
12
+ include Kinda::Core::HashExtension
13
+ end
@@ -0,0 +1,20 @@
1
+ module Kinda
2
+ module Core
3
+ def inspect(*args)
4
+ if %w[Bignum Class Complex Date DateTime FalseClass Fixnum Float
5
+ Integer NilClass Numeric Range Rational Regexp String Symbol
6
+ Time TrueClass].include?(self.class.name)
7
+ super()
8
+ else
9
+ result = '#<'
10
+ result += "#{self.class}:#{object_hexid}"
11
+ items = args.map do |arg|
12
+ "#{arg}=#{send(arg).inspect}" if respond_to?(arg)
13
+ end.compact
14
+ result += ' ' + items.join(', ') if !items.empty?
15
+ result += '>'
16
+ result
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ module Kinda
2
+ module Core
3
+ module ModuleExtension
4
+ def self.included(klass)
5
+ klass.alias_method_chain :append_features, :inheritable_extensions
6
+ end
7
+
8
+ def alias_method_chain(target, feature)
9
+ # Strip out punctuation on predicates or bang methods since
10
+ # e.g. target?_without_feature is not a valid method name.
11
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
12
+ yield(aliased_target, punctuation) if block_given?
13
+
14
+ with_method, without_method =
15
+ "#{aliased_target}_with_#{feature}#{punctuation}",
16
+ "#{aliased_target}_without_#{feature}#{punctuation}"
17
+
18
+ alias_method without_method, target
19
+ alias_method target, with_method
20
+
21
+ case
22
+ when public_method_defined?(without_method)
23
+ public target
24
+ when protected_method_defined?(without_method)
25
+ protected target
26
+ when private_method_defined?(without_method)
27
+ private target
28
+ end
29
+ end
30
+
31
+ def container
32
+ space = name[0...(name.rindex( '::' ) || 0)]
33
+ space.empty? ? Object : eval(space)
34
+ end
35
+
36
+ def extensions
37
+ singleton_class.ancestors.take_while { |mod| !mod.is_a?(Class) }
38
+ end
39
+
40
+ def inheritable_extend(*mods, &block)
41
+ if block
42
+ mod = Module.new
43
+ mod.extend extensions
44
+ mod.module_eval(&block)
45
+ mods << mod
46
+ end
47
+ extend *mods
48
+ (@inheritable_extensions ||= []).unshift(*mods.reverse).uniq!
49
+ mod
50
+ end
51
+
52
+ def append_features_with_inheritable_extensions(target)
53
+ append_features_without_inheritable_extensions(target)
54
+ if @inheritable_extensions
55
+ target.extend *@inheritable_extensions
56
+ target.inheritable_extend *@inheritable_extensions.reverse
57
+ end
58
+ end
59
+
60
+ # delegate_to_class :singleton_method_added => :method_added
61
+ # delegate_to_class [:attr_reader, :attr_writer]
62
+ # delegate_to_class ClassMethods.instance_methods
63
+ def delegate_to_class(*sources)
64
+ sources, target = sources.first.first if sources.first.is_a?(Hash)
65
+ [*sources].flatten.each do |source|
66
+ define_method(source) do |*args, &block|
67
+ singleton_class_send(target || source, *args, &block)
68
+ end
69
+ end
70
+ end
71
+
72
+ def self_and_ancestors
73
+ result = ancestors
74
+ result.unshift self unless result.first == self
75
+ result
76
+ end
77
+
78
+ def ancestors_without_self
79
+ result = ancestors
80
+ result.first == self ? result.drop(1) : result
81
+ end
82
+
83
+ def ancestor
84
+ ancestors_without_self.first
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ class Module #:nodoc:
91
+ include Kinda::Core::ModuleExtension
92
+ end
93
+
@@ -0,0 +1,64 @@
1
+ module Kinda
2
+ module Core
3
+ module ObjectExtension
4
+ def self.included(klass)
5
+ klass.alias_method_chain :extend, :flexible_arguments
6
+ end
7
+
8
+ def object_hexid
9
+ "0x" + ('%.x' % (self.__id__ * 2))
10
+ end
11
+
12
+ def singleton_class
13
+ class << self; self; end
14
+ end
15
+
16
+ def singleton_class_eval(&block)
17
+ singleton_class.class_eval(&block)
18
+ end
19
+
20
+ def singleton_class_send(method_name, *args, &block)
21
+ singleton_class_eval { send(method_name, *args, &block) }
22
+ end
23
+
24
+ def to_class
25
+ kind_of?(Module) ? self : singleton_class
26
+ end
27
+
28
+ alias_method :to_module, :to_class
29
+
30
+ def extend_with_flexible_arguments(*modules)
31
+ mods = modules.flatten
32
+ extend_without_flexible_arguments(*mods) unless mods.empty?
33
+ end
34
+
35
+ def tap
36
+ return super if block_given?
37
+ Functor.new { |method, *args| self.send(method, *args); self }
38
+ end
39
+
40
+ def try(method_name, *args, &block)
41
+ send(method_name, *args, &block) if respond_to?(method_name)
42
+ end
43
+
44
+ def receiver
45
+ self
46
+ end
47
+
48
+ alias_method :__instance_exec__, :instance_exec
49
+
50
+ def parse_arguments(args, *defaults)
51
+ args = args.dup
52
+ options = args.last.is_a?(Hash) ? args.pop : {}
53
+ raise ArgumentError, "Too many arguments (#{args.size} for #{defaults.size})" if
54
+ args.size > defaults.size
55
+ defaults.drop(args.size).each { |default| args << default }
56
+ args << options
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ class Object #:nodoc:
63
+ include Kinda::Core::ObjectExtension
64
+ end
@@ -0,0 +1,78 @@
1
+ module Kinda
2
+ module Core
3
+ module This
4
+ module ProcExtension
5
+ def call_with_this(this, *args, &block)
6
+ binding_self = binding.eval('self')
7
+ binding_self.push_this(this)
8
+ call(*args, &block)
9
+ ensure
10
+ binding_self.pop_this
11
+ end
12
+ end
13
+
14
+ ###
15
+
16
+ def call_with_this(proc, *args, &block)
17
+ return unless proc
18
+ binding_self = proc.binding.eval('self')
19
+ raise "Object #{binding_self.inspect} doesn't respond to Kinda::Core::This methods " +
20
+ "(proc=#{proc.inspect})" unless binding_self.respond_to?(:push_this)
21
+ begin
22
+ binding_self.push_this(self)
23
+ proc.call(*args, &block)
24
+ ensure
25
+ binding_self.pop_this
26
+ end
27
+ end
28
+
29
+ def push_this(object)
30
+ (@these ||= []).push(object)
31
+ end
32
+
33
+ def pop_this
34
+ @these.pop if @these
35
+ end
36
+
37
+ def this
38
+ (@these && @these.last) || self
39
+ end
40
+
41
+ def this_eval(&block)
42
+ this.instance_eval(&block)
43
+ end
44
+
45
+ attr_reader :contextual_methods
46
+
47
+ def contextual_method(*methods)
48
+ methods.each do |method|
49
+ (@contextual_methods ||= []) << method.to_sym
50
+ end
51
+ end
52
+
53
+ def contextual_method?(method)
54
+ to_class.self_and_ancestors.each do |ancestor|
55
+ return true if ancestor.contextual_methods &&
56
+ ancestor.contextual_methods.include?(method.to_sym)
57
+ end
58
+ false
59
+ end
60
+
61
+ def method_missing(method_name, *args, &block)
62
+ if this != self && this.contextual_method?(method_name)
63
+ this.send(method_name, *args, &block)
64
+ else
65
+ super
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ class Object #:nodoc:
73
+ include Kinda::Core::This
74
+ end
75
+
76
+ class Proc #:nodoc:
77
+ include Kinda::Core::This::ProcExtension
78
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'core')
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ ruby_files = Dir.glob(File.join(File.dirname(__FILE__), '*_test.rb'))
5
+ ruby_files.each { |file| require file }
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-core'
8
+
9
+ class AccessorTest < Test::Unit::TestCase
10
+ def setup
11
+ @human_class = Class.new do
12
+ include Kinda::Core
13
+ end
14
+ @human = @human_class.new
15
+ end
16
+
17
+ def test_attribute_defined_at_class_level
18
+ @human_class.class_eval do
19
+ attr_accessor :name
20
+ end
21
+ assert_nil @human.name
22
+ @human.name = 'Dave'
23
+ assert_equal 'Dave', @human.name
24
+ @human.name 'Fred'
25
+ assert_equal 'Fred', @human.name
26
+ end
27
+
28
+ def test_attribute_defined_at_instance_level
29
+ @human.attr_accessor :name
30
+ assert_nil @human.name
31
+ @human.name = 'Dave'
32
+ assert_equal 'Dave', @human.name
33
+ @human.name 'Fred'
34
+ assert_equal 'Fred', @human.name
35
+ @other_human = @human_class.new
36
+ assert_raise NoMethodError do
37
+ @other_human.name
38
+ end
39
+ end
40
+
41
+ def test_attribute_with_block_defined_at_class_level
42
+ @human_class.class_eval do
43
+ attr_reader :name do |capitalize=false|
44
+ capitalize ? @the_name.capitalize : @the_name
45
+ end
46
+ attr_writer :name do |value|
47
+ @the_name = value
48
+ end
49
+ end
50
+ assert_equal nil, @human.name
51
+ @human.name = 'Dave'
52
+ assert_equal 'Dave', @human.name
53
+ @human.name = 'fred'
54
+ assert_equal 'Fred', @human.name(true)
55
+ end
56
+
57
+ def test_attribute_with_filter_defined_at_class_level
58
+ @human_class.class_eval do
59
+ attr_accessor :nickname
60
+
61
+ attr_reader_with_filter :name do |value|
62
+ value || nickname || 'Mike'
63
+ end
64
+ attr_writer_with_filter :name do |value|
65
+ value.capitalize
66
+ end
67
+ end
68
+ assert_equal 'Mike', @human.name
69
+ @human.nickname = 'Mikey'
70
+ assert_equal 'Mikey', @human.name
71
+ @human.name = 'dave'
72
+ assert_equal 'Dave', @human.name
73
+ @human.name 'FRED'
74
+ assert_equal 'Fred', @human.name
75
+ end
76
+
77
+ def test_attribute_redirection
78
+ @human.attr_accessor :name => :@the_name
79
+ assert_nil @human.name
80
+ @human.name = 'Dave'
81
+ assert_equal 'Dave', @human.name
82
+ assert_equal 'Dave', @human.instance_variable_get(:@the_name)
83
+ @human.name = 'Fred'
84
+ assert_equal 'Fred', @human.name
85
+ @human.attr_accessor :last_name => :name
86
+ assert_equal 'Fred', @human.last_name
87
+ @human.last_name = 'Mike'
88
+ assert_equal 'Mike', @human.last_name
89
+ assert_equal 'Mike', @human.name
90
+ end
91
+
92
+ def test_attribute_delegation
93
+ @child = @human_class.new
94
+ @father = @human_class.new
95
+ @child.attr_accessor :father
96
+ @child.father = @father
97
+ assert_equal @father, @child.father
98
+ @father.attr_accessor :name
99
+ @father.name = 'Dave'
100
+ @child.attr_accessor :name => [:father, :name]
101
+ assert_equal 'Dave', @child.name
102
+ @child.name = 'Fred'
103
+ assert_equal 'Fred', @child.name
104
+ assert_equal 'Fred', @father.name
105
+ end
106
+
107
+ def test_attribute_double_delegation
108
+ @child = @human_class.new
109
+ @mother = @human_class.new
110
+ @husband = @human_class.new
111
+ @child.attr_accessor :mother
112
+ @child.mother = @mother
113
+ @mother.attr_accessor :husband
114
+ @mother.husband = @husband
115
+ assert_equal @husband, @child.mother.husband
116
+ @husband.attr_accessor :name
117
+ @husband.name = 'Dave'
118
+ @child.attr_accessor :name => [:mother, :husband, :name]
119
+ assert_equal 'Dave', @child.name
120
+ @child.name = 'Fred'
121
+ assert_equal 'Fred', @child.name
122
+ assert_equal 'Fred', @husband.name
123
+ end
124
+
125
+ def test_attribute_with_default
126
+ @human.attr_accessor_with_default :name, 'Bart'
127
+ assert_equal 'Bart', @human.name
128
+ @human.name = 'Dave'
129
+ assert_equal 'Dave', @human.name
130
+ end
131
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-core'
8
+
9
+ class ForwardableTest < Test::Unit::TestCase
10
+ def setup
11
+ @human_class = Class.new do
12
+ include Kinda::Core
13
+ end
14
+ @human = @human_class.new
15
+ end
16
+
17
+ def test_delegate_attribute
18
+ @child = @human_class.new
19
+ @father = @human_class.new
20
+ @child.attr_accessor :father
21
+ @child.father = @father
22
+ assert_equal @father, @child.father
23
+ @father.attr_accessor :name
24
+ @father.name = 'Dave'
25
+ @child.delegate_attr :name => :father
26
+ assert_equal 'Dave', @child.name
27
+ @child.name = 'Fred'
28
+ assert_equal 'Fred', @child.name
29
+ assert_equal 'Fred', @father.name
30
+ end
31
+
32
+ def test_delegate_attribute_with_filter
33
+ @child = @human_class.new
34
+ @father = @human_class.new
35
+ @child.attr_accessor :father
36
+ @child.father = @father
37
+ assert_equal @father, @child.father
38
+ @father.attr_accessor :name
39
+ @father.name = 'Dave'
40
+ @child.delegate_attr_reader_with_filter :name => :father do |value|
41
+ value + ' junior'
42
+ end
43
+ assert_equal 'Dave junior', @child.name
44
+ @child.delegate_attr_writer_with_filter :name => :father do |value|
45
+ value.capitalize
46
+ end
47
+ @child.name = 'fred'
48
+ assert_equal 'Fred junior', @child.name
49
+ assert_equal 'Fred', @father.name
50
+ end
51
+ end
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-core'
8
+
9
+ class ModuleTest < Test::Unit::TestCase
10
+ def meth
11
+ 'meth'
12
+ end
13
+
14
+ def meth_with_upcase
15
+ meth_without_upcase.upcase
16
+ end
17
+
18
+ alias_method_chain :meth, :upcase
19
+
20
+ def test_alias_method_chain
21
+ assert_equal 'METH', meth
22
+ end
23
+
24
+ $meth2 = []
25
+
26
+ module A
27
+ module ClassMethods1
28
+ def meth1
29
+ 'meth1'
30
+ end
31
+ end
32
+
33
+ module ClassMethods2
34
+ def meth2
35
+ $meth2 << 'ClassMethods2.meth2'
36
+ end
37
+ end
38
+
39
+ inheritable_extend ClassMethods1, ClassMethods2
40
+ end
41
+
42
+ module B
43
+ include A
44
+
45
+ ClassMethods3 = inheritable_extend do
46
+ $meth1 = meth1
47
+
48
+ def meth3
49
+ 'meth3'
50
+ end
51
+ end
52
+
53
+ module ClassMethods4
54
+ def meth2
55
+ super
56
+ $meth2 << 'ClassMethods4.meth2'
57
+ end
58
+ end
59
+
60
+ inheritable_extend ClassMethods4
61
+ end
62
+
63
+ class X
64
+ include B
65
+ end
66
+
67
+ def test_container
68
+ assert_equal ModuleTest::A, ModuleTest::A::ClassMethods1.container
69
+ assert_equal ModuleTest::B, ModuleTest::B::ClassMethods3.container
70
+ end
71
+
72
+ def test_extensions
73
+ assert_equal [ModuleTest::B::ClassMethods4, ModuleTest::B::ClassMethods3,
74
+ ModuleTest::A::ClassMethods2, ModuleTest::A::ClassMethods1], X.extensions
75
+ end
76
+
77
+ def test_inheritable_extend
78
+ assert_equal 'meth1', $meth1
79
+ X.meth2
80
+ assert_equal ["ClassMethods2.meth2", "ClassMethods4.meth2"], $meth2
81
+ assert_equal 'meth1', X.meth1
82
+ assert_equal 'meth3', X.meth3
83
+ end
84
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-core'
8
+
9
+ class ObjectTest < Test::Unit::TestCase
10
+ def test_tap
11
+ assert_equal 'Hello', 'Hello'.tap { |str| assert_equal 'HELLO', str.upcase }
12
+ assert_equal 'Hello', 'Hello'.tap.upcase
13
+ end
14
+
15
+ def test_try
16
+ assert_equal nil, 'Hello'.try(:undefined)
17
+ assert_equal 'HELLO', 'Hello'.try(:upcase)
18
+ assert_equal 'hello', 'Hello'.try(:upcase).try(:downcase)
19
+ end
20
+
21
+ def test_parse_arguments
22
+ assert_equal [1, 2, {}], parse_arguments([], 1, 2)
23
+ assert_equal [3, 4, {}], parse_arguments([3, 4], 1, 2)
24
+ assert_raise(ArgumentError) { parse_arguments([3, 4, 5], 1, 2) }
25
+ assert_equal [1, 2, {:a => 'c', :b => 'd'}], parse_arguments([:a => 'c', :b => 'd'], 1, 2)
26
+ assert_equal [3, 2, {:a => 'c', :b => 'd'}], parse_arguments([3, :a => 'c', :b => 'd'], 1, 2)
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-core'
8
+
9
+ class ThisTest < Test::Unit::TestCase
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Vila
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-12 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Basic helpers used by other kinda projects
17
+ email: mvila@3base.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - Rakefile
26
+ - lib/core.rb
27
+ - lib/kinda-core.rb
28
+ - lib/core/accessor.rb
29
+ - lib/core/forwardable.rb
30
+ - lib/core/functor.rb
31
+ - lib/core/hash.rb
32
+ - lib/core/inspect.rb
33
+ - lib/core/module.rb
34
+ - lib/core/object.rb
35
+ - lib/core/this.rb
36
+ - README.rdoc
37
+ has_rdoc: true
38
+ homepage: http://github.com/kinda/core
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.9.1
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project: kinda-core
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Basic helpers used by other kinda projects
65
+ test_files:
66
+ - test/__all__.rb
67
+ - test/accessor_test.rb
68
+ - test/forwardable_test.rb
69
+ - test/module_test.rb
70
+ - test/object_test.rb
71
+ - test/this_test.rb