y_support 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/lib/y_support/all.rb +40 -0
  8. data/lib/y_support/core_ext/array/misc.rb +45 -0
  9. data/lib/y_support/core_ext/array.rb +1 -0
  10. data/lib/y_support/core_ext/enumerable/misc.rb +32 -0
  11. data/lib/y_support/core_ext/enumerable.rb +1 -0
  12. data/lib/y_support/core_ext/hash/misc.rb +90 -0
  13. data/lib/y_support/core_ext/hash.rb +1 -0
  14. data/lib/y_support/core_ext/module/misc.rb +43 -0
  15. data/lib/y_support/core_ext/module.rb +2 -0
  16. data/lib/y_support/core_ext/numeric/misc.rb +13 -0
  17. data/lib/y_support/core_ext/numeric.rb +1 -0
  18. data/lib/y_support/core_ext/object/misc.rb +31 -0
  19. data/lib/y_support/core_ext/object.rb +1 -0
  20. data/lib/y_support/core_ext/string/misc.rb +80 -0
  21. data/lib/y_support/core_ext/string.rb +1 -0
  22. data/lib/y_support/core_ext/symbol/misc.rb +19 -0
  23. data/lib/y_support/core_ext/symbol.rb +1 -0
  24. data/lib/y_support/core_ext.rb +5 -0
  25. data/lib/y_support/inert_recorder.rb +51 -0
  26. data/lib/y_support/local_object.rb +39 -0
  27. data/lib/y_support/misc.rb +28 -0
  28. data/lib/y_support/name_magic.rb +373 -0
  29. data/lib/y_support/null_object.rb +96 -0
  30. data/lib/y_support/respond_to.rb +32 -0
  31. data/lib/y_support/stdlib_ext/matrix/misc.rb +134 -0
  32. data/lib/y_support/stdlib_ext/matrix.rb +2 -0
  33. data/lib/y_support/stdlib_ext.rb +3 -0
  34. data/lib/y_support/typing/array/typing.rb +17 -0
  35. data/lib/y_support/typing/array.rb +1 -0
  36. data/lib/y_support/typing/enumerable/typing.rb +75 -0
  37. data/lib/y_support/typing/enumerable.rb +1 -0
  38. data/lib/y_support/typing/hash/typing.rb +76 -0
  39. data/lib/y_support/typing/hash.rb +1 -0
  40. data/lib/y_support/typing/module/typing.rb +42 -0
  41. data/lib/y_support/typing/module.rb +1 -0
  42. data/lib/y_support/typing/object/typing.rb +178 -0
  43. data/lib/y_support/typing/object.rb +1 -0
  44. data/lib/y_support/typing.rb +43 -0
  45. data/lib/y_support/unicode.rb +76 -0
  46. data/lib/y_support/version.rb +3 -0
  47. data/lib/y_support.rb +33 -0
  48. data/test/inert_recorder_test.rb +34 -0
  49. data/test/local_object_test.rb +37 -0
  50. data/test/misc_test/test_module/fixture_class.rb +8 -0
  51. data/test/misc_test.rb +289 -0
  52. data/test/name_magic_test.rb +57 -0
  53. data/test/null_object_test.rb +50 -0
  54. data/test/respond_to_test.rb +46 -0
  55. data/test/typing_test.rb +213 -0
  56. data/test/unicode_test.rb +39 -0
  57. data/y_support.gemspec +22 -0
  58. metadata +137 -0
@@ -0,0 +1,75 @@
1
+ #encoding: utf-8
2
+
3
+ module Enumerable
4
+ # Fails with TypeError unless all the members of the collection comply with
5
+ # the supplied block criterion. Optional arguments customize the error
6
+ # message. First optional argument describes the collection element, the
7
+ # second one describes the tested duck type. If the criterion block takes
8
+ # at least one argument, the receiver elemnts are passed to it (#all?
9
+ # method). If the criterion block takes no arguments (arity 0), it is
10
+ # gradually executed inside the elements (using #instance_exec method).
11
+ # If no block is given, all members are required to be truey.
12
+ #
13
+ def aT_all what_is_collection_element=nil, how_comply=nil, &b
14
+ e = what_is_collection_element || "collection element"
15
+ if block_given?
16
+ m = "Each #{e} must %s!" %
17
+ ( how_comply ? how_comply : "comply with the given duck type" )
18
+ raise TErr, m unless ( b.arity == 0 ?
19
+ all? { |e| e.instance_exec( &b ) } :
20
+ all? { |e| b.( e ) } )
21
+ else
22
+ m = "No #{e} must be nil or false!"
23
+ raise TErr, m unless all? { |e| e }
24
+ end
25
+ return self
26
+ end
27
+
28
+ # Fails with TypeError unless all collection members are #kind_of? the
29
+ # class supplied as argument. Second optional argument (collection element
30
+ # description) customizes the error message.
31
+ #
32
+ def aT_all_kind_of klass, what_is_collection_element=nil
33
+ e = what_is_collection_element || "collection element"
34
+ m = "Each #{e} must be kind of #{klass}!"
35
+ raise TErr, m unless all? { |e| e.kind_of? klass }
36
+ return self
37
+ end
38
+
39
+ # Fails with TypeError unless all collection members declare compliance with
40
+ # compliance with the class supplied as argument. Second optional argument
41
+ # (collection element description) customizes the error message.
42
+ #
43
+ def aT_all_comply klass, what_is_collection_element=nil
44
+ e = what_is_collection_element || "collection element"
45
+ m = "Each #{e} must declare compliance to #{klass}!"
46
+ raise TErr, m unless all? { |e| e.class_complies? klass }
47
+ return self
48
+ end
49
+
50
+ # Fails with TypeError unless all the collection members declare compliance
51
+ # with Numeric. Second optional argument (collection element description)
52
+ # customizes the error message.
53
+ #
54
+ def aT_all_numeric what_is_collection_element=nil
55
+ e = what_is_collection_element || "collection element"
56
+ m = "Each #{e} must declare compliance with Numeric!"
57
+ raise TErr, m unless all? { |e| e.class_complies? Numeric }
58
+ return self
59
+ end
60
+
61
+ # Fails with TypeError unless all the collection members are included int the
62
+ # collection supplied as argument. Second optional argument (collection
63
+ # element description) customizes the error message.
64
+ #
65
+ def aT_subset_of other_collection, what_is_receiver_collection=nil,
66
+ what_is_other_collection=nil
67
+ rc = what_is_receiver_collection ?
68
+ what_is_receiver_collection.to_s.capitalize : "collection"
69
+ oc = what_is_other_collection ? what_is_other_collection.to_s.capitalize :
70
+ "the specified collection"
71
+ m = "The #{rc} must be a subset of #{oc}"
72
+ raise TErr, m unless all? { |e| other_collection.include? e }
73
+ return self
74
+ end
75
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/enumerable/typing'
@@ -0,0 +1,76 @@
1
+ #encoding: utf-8
2
+
3
+ class Hash
4
+ # Merges the synonymous hash keys into a single key - useful for argument
5
+ # validation. Returns nil if neither main key, nor synonyms are found.
6
+ # Returns false (no merging) if the main key was found, but no synonym keys.
7
+ # Returns true (yes merging) if any of the synonym keys is found and
8
+ # renamed/merged to the main key. Value collisions in synonym keys (detected
9
+ # by #==) raise ArgumentError.
10
+ #
11
+ def merge_synonym_keys!( key, *synonyms )
12
+ synonyms.reduce has_key?( key ) ? false : nil do |acc, syn|
13
+ next acc unless has_key? syn
14
+ if acc.nil? then
15
+ self[key] = self[syn]
16
+ delete syn
17
+ next true
18
+ end
19
+ if self[key] == self[syn] then
20
+ delete syn
21
+ next true
22
+ else
23
+ raise TErr, "Value collision between #{key} and its synonym #{syn}!"
24
+ end
25
+ end
26
+ end
27
+
28
+ # This method uses #merge_synonym_keys! method first and then returns the
29
+ # value under the key. The first argument is the main key. Synonyms may be
30
+ # supplied as a named argument :syn!. (Bang indicates that the synonym keys
31
+ # will be merged with the main key, modifying the hash.)
32
+ #
33
+ def may_have key, options={}
34
+ merge_synonym_keys!( key, *options[:syn!] ).nil?
35
+ return self[key]
36
+ end
37
+
38
+ # This method behaves similarly to #may_have, with the difference that it
39
+ # does not return the value of the key, only true / false to indicate whether
40
+ # the key or any synonym has been found.
41
+ #
42
+ def has? key, options={}
43
+ !merge_synonym_keys!( key, *options[:syn!] ).nil?
44
+ end
45
+
46
+ # This enforcer method (aka. runtime assertion) raises TypeError when:
47
+ # 1. Neither the required key nor any of its synonyms are present.
48
+ # 2. The supplied criterion block, if any, returns false when applied
49
+ # to the value of the key in question. If the block takes an argument
50
+ # (or more arguments), the value is passed in. If the block takes no
51
+ # arguments (arity 0), it is executed inside the singleton class of the
52
+ # receiver (using #instance_exec method).
53
+ #
54
+ def aT_has key, options={}, &b
55
+ raise TErr, "Key '#{key}' absent!" unless has? key, options
56
+ # Now validate self[key] using the supplied block
57
+ if block_given?
58
+ m = "Value for #{key} fails its duck type!"
59
+ raise TErr, m unless ( b.arity == 0 ? self[key].instance_exec( &b ) :
60
+ b.( self[key] ) )
61
+ end
62
+ return self[key]
63
+ end
64
+ alias :must_have :aT_has
65
+
66
+ # This method behaves exactly like #aT_has, but with the difference, that
67
+ # it raises ArgumentError instead of TypeError
68
+ #
69
+ def aE_has key, options={}, &b
70
+ begin
71
+ options.empty? ? aT_has( key, &b ) : aT_has( key, options, &b )
72
+ rescue TypeError => e
73
+ raise AErr, e.message
74
+ end
75
+ end
76
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/hash/typing'
@@ -0,0 +1,42 @@
1
+ #encoding: utf-8
2
+
3
+ class Module
4
+ # === Support for typing by declaration
5
+
6
+ # Compliance inquirer (declared compliance + ancestors).
7
+ #
8
+ def complies?( other_module )
9
+ other_module.aT_kind_of Module, "other module"
10
+ compliance.include? other_module
11
+ end
12
+
13
+ # Declared complience inquirer.
14
+ #
15
+ def declares_compliance?( other_module )
16
+ other_module.aT_kind_of Module, "other module"
17
+ declared_compliance.include? other_module
18
+ end
19
+
20
+ # Compliance (declared compliance + ancestors).
21
+ #
22
+ def compliance
23
+ ( declared_compliance + ancestors ).uniq
24
+ end
25
+
26
+ # Declared compliance getter.
27
+ #
28
+ def declared_compliance
29
+ ( ( @declared_compliance || [] ) + ancestors.map { |a|
30
+ a.instance_variable_get( :@declared_compliance ) || []
31
+ }.reduce( [], :+ ) ).uniq
32
+ end
33
+
34
+ # Declaration of module / class compliance.
35
+ #
36
+ def declare_compliance! other_module
37
+ other_module.aT_kind_of Module, "other module"
38
+ return false if declared_compliance.include? other_module
39
+ ( @declared_compliance ||= [] ) << other_module
40
+ return true
41
+ end
42
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/module/typing'
@@ -0,0 +1,178 @@
1
+ #encoding: utf-8
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+
5
+ class Object
6
+ # === Support for typing by declaration
7
+
8
+ # Class compliance inquirer (declared compliance + class ancestors).
9
+ #
10
+ def class_complies?( klass )
11
+ singleton_class_or_class.complies? klass
12
+ end
13
+
14
+ # Declared class compliance.
15
+ #
16
+ def class_declares_compliance?( klass )
17
+ singleton_class_or_class.declares_compliance? klass
18
+ end
19
+
20
+ # Class compliance (declared class compliance + ancestors).
21
+ #
22
+ def class_compliance
23
+ singleton_class_or_class.compliance
24
+ end
25
+
26
+ # Declared class compliance.
27
+ #
28
+ def declared_class_compliance
29
+ singleton_class_or_class.declared_compliance
30
+ end
31
+
32
+ # Declaration of class compliance.
33
+ #
34
+ def declare_class_compliance!( klass )
35
+ singleton_class_or_class.declare_compliance! klass
36
+ end
37
+
38
+ # === Duck typing support (aka. runtime assertions)
39
+
40
+ # This method takes a block and fails with TypeError, unless the receiver
41
+ # fullfills the block criterion. Optional arguments customize customize
42
+ # the error message. First optional argument describes the receiver, the
43
+ # second one describes the tested duck type. If the criterion block takes
44
+ # at least one argument, the receiver is passed to it. If the criterion block
45
+ # takes no arguments (arity 0), it is executed inside the singleton class of
46
+ # the receiver (using #instance_exec method). If no block is given, it is
47
+ # checked, whether the object is truey.
48
+ #
49
+ def aT what_is_receiver=nil, how_comply=nil, &b
50
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
51
+ "#{self.class} instance #{object_id}"
52
+ if block_given?
53
+ m = "#{r} fails #{how_comply ? 'to %s' % how_comply : 'its duck type'}!"
54
+ raise TErr, m unless ( b.arity == 0 ) ? instance_exec( &b ) : b.( self )
55
+ else
56
+ raise TErr, m unless self
57
+ end
58
+ return self
59
+ end
60
+
61
+ # This method takes a block and fails with TypeError, unless the receiver
62
+ # causes the supplied block <em>to return falsey value</em>. Optional arguments
63
+ # customize customize the error message. First optional argument describes the
64
+ # receiver, the second one describes the tested duck type. If the criterion
65
+ # block takes at least one argument (or more arguments), the receiver is passed
66
+ # to it. If the criterion block takes no arguments (arity 0), it is executed
67
+ # inside the singleton class of the receiver (using #instance_exec method). If
68
+ # no block is given, it is checked, whether the object is falsey.
69
+ #
70
+ def aT_not what_is_receiver=nil, how_comply=nil, &b
71
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
72
+ "#{self.class} instance #{object_id}"
73
+ if block_given?
74
+ m = how_comply ? "#{r} must not #{how_comply}!" :
75
+ "#{r} fails its duck type!"
76
+ raise TErr, m if ( b.arity == 0 ) ? instance_exec( &b ) : b.( self )
77
+ else
78
+ m = "#{r} is not falsey!"
79
+ raise TErr, m if self
80
+ end
81
+ return self
82
+ end
83
+
84
+ # Fails with TypeError unless the receiver is of the prescribed class. Second
85
+ # optional argument customizes the error message (receiver description).
86
+ #
87
+ def aT_kind_of klass, what_is_receiver=nil
88
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
89
+ "#{self.class} instance #{object_id}"
90
+ m = "#{r} is not a kind of #{klass}!"
91
+ raise TErr, m unless kind_of? klass
92
+ return self
93
+ end
94
+ alias :aT_is_a :aT_kind_of
95
+
96
+ # Fails with TypeError unless the receiver declares compliance with the
97
+ # given class, or is a descendant of that class. Second optional argument
98
+ # customizes the error message (receiver description).
99
+ #
100
+ def aT_class_complies klass, what_is_receiver=nil
101
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
102
+ "#{self.class} instance #{object_id}"
103
+ m = "#{r} does not comply or declare compliance with #{klass}!"
104
+ raise TErr, m unless class_complies? klass
105
+ return self
106
+ end
107
+
108
+ # Fails with TypeError unless the receiver responds to the given
109
+ # method. Second optional argument customizes the error message (receiver
110
+ # description).
111
+ #
112
+ def aT_respond_to method_name, what_is_receiver=nil
113
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
114
+ "#{self.class} instance #{object_id}"
115
+ m = "#{r} does not respond to method '#{method_name}'!"
116
+ raise TErr, m unless respond_to? method_name
117
+ return self
118
+ end
119
+ alias :aT_responds_to :aT_respond_to
120
+
121
+ # Fails with TypeError unless the receiver, according to #== method, is
122
+ # equal to the argument. Two more optional arguments customize the error
123
+ # message (receiver description and the description of the other object).
124
+ #
125
+ def aT_equal other, what_is_receiver=nil, what_is_other=nil
126
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
127
+ "#{self.class} instance #{object_id}"
128
+ o = what_is_other || "the prescribed value (#{other.class})"
129
+ m = "#{r} is not equal (==) to #{o}!"
130
+ raise TErr, m unless self == other
131
+ return self
132
+ end
133
+
134
+ # Fails with TypeError unless the receiver, according to #== method, differs
135
+ # from to the argument. Two more optional arguments customize the error
136
+ # message (receiver description and the description of the other object).
137
+ #
138
+ def aT_not_equal other, what_is_receiver=nil, what_is_other=nil
139
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
140
+ "#{self.class} instance #{object_id}"
141
+ o = what_is_other || "the prescribed value (#{other.class})"
142
+ m = "#{r} fails to differ from #{o}!"
143
+ raise TErr, m if self == other
144
+ return self
145
+ end
146
+
147
+ # Fails with TypeError unless the ActiveSupport method #blank returns true
148
+ # for the receiver.
149
+ #
150
+ def aT_blank what_is_receiver=nil
151
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
152
+ "#{self.class} instance #{object_id}"
153
+ m = "#{r} fails to be #blank?!"
154
+ raise TErr, m unless blank?
155
+ return self
156
+ end
157
+
158
+ # Fails with TypeError unless the ActiveSupport method #present returns true
159
+ # for the receiver.
160
+ #
161
+ def aT_present what_is_receiver=nil
162
+ r = what_is_receiver ? what_is_receiver.to_s.capitalize :
163
+ "#{self.class} instance #{object_id}"
164
+ m = "#{r} fails to be #present?!"
165
+ raise TErr, m unless present?
166
+ return self
167
+ end
168
+
169
+ private
170
+
171
+ def singleton_class_or_class
172
+ begin
173
+ self.singleton_class
174
+ rescue TypeError
175
+ self.class
176
+ end
177
+ end
178
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/object/typing'
@@ -0,0 +1,43 @@
1
+ #encoding: utf-8
2
+
3
+ require 'y_support'
4
+
5
+ # Typing library.
6
+ #
7
+ # Apart from Ruby default way of typing objects <em>by class and ancestry</em>,
8
+ # exemplified eg. by built-in #kind_of?, alias #is_a? inquirers, y_support
9
+ # typing library provides support for typing <em>by declaration</em>, and
10
+ # runtime assertions for <em>duck type</em> examination.
11
+ #
12
+ # 1. Using method <b>declare_compliance</b>, a module (class) can explicitly
13
+ # declare, that it provides an interface compliant with another module (class).
14
+ # Corresponding inquirer methods are <b>declared_compliance</b> (returns a list
15
+ # of modules, to which the receiver declares compliance, or implicitly complies
16
+ # by ancestry), and <b>declares_compliance?( other_module )</b>, which tells,
17
+ # whether the receiver complies with a specific module. An object always
18
+ # implicitly complies with its class and ancestry.
19
+ #
20
+ # 2. Duck type examination is supported by a collection of runtime assertions.
21
+ # These start with <b>tE_...</b>, meaning "enforce ... by raising TypeError".
22
+ #
23
+ class Object
24
+ # Alias for ArgumentError
25
+ #
26
+ AErr = ArgumentError
27
+
28
+ # Alias for TypeError
29
+ #
30
+ TErr = TypeError
31
+ end
32
+
33
+ directories_to_look_in = [ :typing ]
34
+
35
+ # The fololowing code looks into the specified directory(ies) and requires
36
+ # all the files in it (them).
37
+ #
38
+ directories_to_look_in.each do |part|
39
+ Dir["#{File.dirname( __FILE__ )}/#{part}/*/typing.rb"].sort.each { |path|
40
+ dir = File.dirname( path ).match( "y_support/#{part}" ).post_match
41
+ require "y_support/#{part}#{dir}/typing"
42
+ }
43
+ end
@@ -0,0 +1,76 @@
1
+ #encoding: utf-8
2
+
3
+ require 'y_support'
4
+
5
+ # This library sets forth 4 standard abbreviations of Ruby keywords:
6
+ #
7
+ # * <b>ç</b> – class (c with cedilla, U00E7, compose seq. [c, comma])
8
+ # * <b>ⓒ</b> – singleton class (copyright sign, U00A9, compose seq. [(, c, )])
9
+ # * <b>λ</b> – lambda (Greek character lambda)
10
+ # * <b>Λ</b> – proc (Greek character capital lambda)
11
+ #
12
+ # It is also encouraged that other on-letter Unicode abbreviations are
13
+ # used especially for local variables:
14
+ #
15
+ # * <b>ɱ</b> – module (m with hook, U2C6E, compose seq. [m, j])
16
+ # * <b>ꜧ</b> – hash (latin small letter heng, UA727, compose seq. [h, j])
17
+ # * <b>ᴀ</b> – array (small capital A, U1D00, compose seq. [a, `])
18
+ # * <b>ß</b> – symbol (German sharp s, U00DF, compose seq. [s, s])
19
+ # * <b>ς</b> – string (Greek final sigma, U03C2, compose seq. [*, w])
20
+ # * <b>w</b> – abbreviation for "with"
21
+ # * <b>wo</b> – abbreviation for "without"
22
+ #
23
+ # There are, however, no defined methods using these in YSupport. In other
24
+ # words, using these additional abbreviations is completely up to the goodwill
25
+ # of the developer.
26
+ #
27
+ # ==== Note on compose sequences
28
+ #
29
+ # Each compose sequence has to be preceded by pressing the <compose> key.
30
+ # The compose sequences comply with the standard Kragen's .XCompose file
31
+ # (https://github.com/kragen/xcompose). In some cases, the needed characters
32
+ # are not in Kragen's file and need to be defined manually.
33
+ #
34
+ class Object
35
+ alias :ç :class
36
+ alias :ⓒ :singleton_class
37
+ alias :© :singleton_class
38
+
39
+ # Square root (proxy for Math.sqrt(x)).
40
+ #
41
+ def √( number ); Math.sqrt( number ) end
42
+
43
+ # Sum. The argument is expected to be a collection; block can be specified.
44
+ # Basically same as chaining .reduce( :+ ) to the end; Σ() notation can be
45
+ # more readable at times.
46
+ #
47
+ def ∑( collection )
48
+ collection.reduce { |acc, element|
49
+ acc + ( block_given? ? yield( element ) : element )
50
+ }
51
+ end
52
+ alias :Σ :∑
53
+
54
+ # Product. The argument is expected to be a collection; block can be specified.
55
+ # Basically same as chaining .reduce( :* ) to the end; Π() notation can be
56
+ # more readable at times.
57
+ #
58
+ def ∏( collection )
59
+ collection.reduce { |acc, element|
60
+ acc * ( block_given? ? yield( element ) : element )
61
+ }
62
+ end
63
+ alias :Π :∏
64
+ end
65
+
66
+ class Module
67
+ alias :ç_variable_set :class_variable_set
68
+ alias :ç_variable_get :class_variable_get
69
+ alias :ç_variable_defined? :class_variable_defined?
70
+ alias :remove_ç_variable :remove_class_variable
71
+ end
72
+
73
+ module Kernel
74
+ alias :λ :lambda
75
+ alias :Λ :proc
76
+ end
@@ -0,0 +1,3 @@
1
+ module YSupport
2
+ VERSION = "1.0.0"
3
+ end
data/lib/y_support.rb ADDED
@@ -0,0 +1,33 @@
1
+ #encoding: utf-8
2
+
3
+ require "y_support/version"
4
+
5
+ # What follows is a commented-out list of interesting StdLibs. They may
6
+ # or may no be required in various parts of y_support.
7
+ #
8
+ # require 'matrix' # in stdlib_ext/matrix/misc.rb
9
+ # require 'mathn'
10
+ # require 'set'
11
+ # require 'csv'
12
+
13
+ # What follows is a commented-out list of interesting ActiveSupport parts.
14
+ # These may or may not be required in various parts of y_support.
15
+ #
16
+ # require 'active_support/core_ext/module/delegation'
17
+ # require 'active_support/core_ext/object/blank' # in object/misc.rb, string/misc.rb
18
+ # require 'active_support/core_ext/object/duplicable'
19
+ # require 'active_support/core_ext/string/starts_ends_with'
20
+ # require 'active_support/core_ext/string/strip'
21
+ # require 'active_support/core_ext/string/inflections' # in autoreq; module/misc.rb
22
+ # require 'active_support/core_ext/integer/multiple'
23
+ # require 'active_support/core_ext/integer/inflections'
24
+ # require 'active_support/core_ext/enumerable'
25
+ # require 'active_support/core_ext/array/extract_options'
26
+ # require 'active_support/core_ext/hash/conversions' # such as #to_xml
27
+ # require 'active_support/core_ext/hash/reverse_merge' # aliased in hash/misc.rb
28
+ # require 'active_support/core_ext/hash/deep_merge'
29
+ # require 'active_support/core_ext/hash/diff'
30
+ # require 'active_support/core_ext/hash/except'
31
+ # require 'active_support/core_ext/hash/keys'
32
+ # require 'active_support/core_ext/hash/slice'
33
+ # require 'active_support/core_ext/hash/indifferent_access'
@@ -0,0 +1,34 @@
1
+ #! /usr/bin/ruby
2
+ #encoding: utf-8
3
+
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+
7
+ class YSupportTest < Test::Unit::TestCase
8
+ context "Object" do
9
+ setup do
10
+ require 'y_support/inert_recorder'
11
+ end
12
+
13
+ should "have #InertRecorder() constructor" do
14
+ assert_equal InertRecorder, InertRecorder( :bull ).class
15
+ end
16
+ end # context Object
17
+
18
+ context "InertRecorder" do
19
+ setup do
20
+ require 'y_support/inert_recorder'
21
+ end
22
+
23
+ should "InertRecorder exist and comply" do
24
+ n = InertRecorder.new
25
+ assert_equal [true, false], [n.present?, n.blank?]
26
+ assert_respond_to InertRecorder.new, :arbitrary_message
27
+ n = InertRecorder.new :x, :y
28
+ n.arbitrary_message( :a, :b ) { "hello" }
29
+ assert_equal [:x, :y], n.init_args
30
+ assert_equal [ :arbitrary_message, [:a, :b] ], n.recorded_messages[0][0..1]
31
+ assert_equal "hello", n.recorded_messages[0][2].call
32
+ end
33
+ end # context InertRecorder
34
+ end # class InertRecorderTest
@@ -0,0 +1,37 @@
1
+ #! /usr/bin/ruby
2
+ #encoding: utf-8
3
+
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+
7
+ class LocalObjectTest < Test::Unit::TestCase
8
+ context "Object" do
9
+ setup do
10
+ require 'y_support/local_object'
11
+ end
12
+
13
+ should "have constructor #LocalObject, alias #L!" do
14
+ assert_equal LocalObject, LocalObject().class
15
+ assert_equal LocalObject, L!.class
16
+ end
17
+
18
+ should "have #local_object?, alias #ℓ?" do
19
+ assert_equal false, Object.new.local_object?
20
+ assert_equal false, Object.new.ℓ?
21
+ end
22
+ end # context Object
23
+
24
+ context "LocalObject" do
25
+ setup do
26
+ require 'y_support/local_object'
27
+ end
28
+
29
+ should "exist and comply" do
30
+ n = LocalObject.new 'whatever'
31
+ assert ! n.ℓ?
32
+ assert n.ℓ? 'whatever'
33
+ assert_equal 'whatever', n.signature
34
+ assert_equal 'whatever', n.σ
35
+ end
36
+ end # context LocalObject
37
+ end # class LocalObjectTest
@@ -0,0 +1,8 @@
1
+ class MiscTest
2
+ module TestModule
3
+ class FixtureClass
4
+ def hello; "world" end
5
+ end
6
+ end
7
+ end
8
+