y_support 2.1.18 → 2.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/y_support/all.rb +2 -32
  3. data/lib/y_support/core_ext/array.rb +2 -2
  4. data/lib/y_support/core_ext/class.rb +2 -2
  5. data/lib/y_support/core_ext/enumerable.rb +2 -2
  6. data/lib/y_support/core_ext/hash/misc.rb +23 -10
  7. data/lib/y_support/core_ext/hash.rb +2 -2
  8. data/lib/y_support/core_ext/module/misc.rb +9 -0
  9. data/lib/y_support/core_ext/module.rb +2 -2
  10. data/lib/y_support/core_ext/numeric.rb +2 -2
  11. data/lib/y_support/core_ext/object/inspection.rb +8 -2
  12. data/lib/y_support/core_ext/object.rb +3 -3
  13. data/lib/y_support/core_ext/string/misc.rb +9 -12
  14. data/lib/y_support/core_ext/string.rb +2 -2
  15. data/lib/y_support/core_ext/symbol.rb +2 -2
  16. data/lib/y_support/core_ext.rb +1 -1
  17. data/lib/y_support/flex_coerce/class_methods.rb +49 -0
  18. data/lib/y_support/flex_coerce/flex_proxy.rb +121 -0
  19. data/lib/y_support/flex_coerce/module_methods.rb +37 -0
  20. data/lib/y_support/flex_coerce.rb +24 -0
  21. data/lib/y_support/kde.rb +1 -1
  22. data/lib/y_support/literate.rb +253 -0
  23. data/lib/y_support/local_object.rb +1 -1
  24. data/lib/y_support/name_magic/array_methods.rb +48 -0
  25. data/lib/y_support/name_magic/class_methods.rb +205 -161
  26. data/lib/y_support/name_magic/hash_methods.rb +33 -0
  27. data/lib/y_support/name_magic/namespace.rb +449 -0
  28. data/lib/y_support/name_magic.rb +358 -100
  29. data/lib/y_support/null_object.rb +1 -1
  30. data/lib/y_support/respond_to.rb +1 -1
  31. data/lib/y_support/stdlib_ext/matrix/misc.rb +2 -2
  32. data/lib/y_support/stdlib_ext/matrix.rb +2 -2
  33. data/lib/y_support/stdlib_ext.rb +1 -1
  34. data/lib/y_support/typing/array.rb +1 -1
  35. data/lib/y_support/typing/enumerable.rb +1 -1
  36. data/lib/y_support/typing/hash.rb +1 -1
  37. data/lib/y_support/typing/module.rb +1 -1
  38. data/lib/y_support/typing/object/typing.rb +17 -15
  39. data/lib/y_support/typing/object.rb +1 -1
  40. data/lib/y_support/typing.rb +14 -10
  41. data/lib/y_support/unicode.rb +1 -1
  42. data/lib/y_support/version.rb +1 -1
  43. data/lib/y_support/x.rb +2 -1
  44. data/test/flex_coerce_test.rb +134 -0
  45. data/test/literate_test.rb +231 -0
  46. data/test/misc_test.rb +49 -27
  47. data/test/name_magic_test.rb +907 -60
  48. data/test/typing_test.rb +7 -7
  49. metadata +14 -13
  50. data/lib/y_support/abstract_algebra.rb +0 -234
  51. data/lib/y_support/name_magic/array.rb +0 -38
  52. data/lib/y_support/name_magic/hash.rb +0 -31
  53. data/lib/y_support/name_magic/namespace_methods.rb +0 -260
  54. data/lib/y_support/try.rb +0 -133
  55. data/test/abstract_algebra_test.rb +0 -138
  56. data/test/performance_test_example.rb +0 -23
  57. data/test/try_test.rb +0 -102
@@ -1,6 +1,8 @@
1
1
  require 'active_support/core_ext/object/blank'
2
- require File.dirname( __FILE__ ) + '/../../core_ext/object/inspection'
3
- require File.dirname( __FILE__ ) + '/../../core_ext/string/misc'
2
+ # require File.dirname( __FILE__ ) + '/../../core_ext/object/inspection'
3
+ # require File.dirname( __FILE__ ) + '/../../core_ext/string/misc'
4
+ require_relative '../../core_ext/object/inspection'
5
+ require_relative '../../core_ext/string/misc'
4
6
 
5
7
  class Object
6
8
  # === Typing by declaration
@@ -46,7 +48,7 @@ class Object
46
48
  # the receiver (using +#instance_exec+ method). If no block is given, it is
47
49
  # checked, whether the object is truey.
48
50
  #
49
- def aT what_is_receiver=insp, how_comply=nil, &b
51
+ def aT what_is_receiver=y_inspect, how_comply=nil, &b
50
52
  return tap { fail TypeError unless self } unless b
51
53
  return self if b.( self )
52
54
  m = "%s fails " + ( how_comply ? "to #{how_comply}" : "its check" )
@@ -62,7 +64,7 @@ class Object
62
64
  # inside the singleton class of the receiver (using #instance_exec method). If
63
65
  # no block is given, it is checked, whether the object is falsey.
64
66
  #
65
- def aT_not what_is_receiver=insp, how_comply=nil, &b
67
+ def aT_not what_is_receiver=y_inspect, how_comply=nil, &b
66
68
  return tap { fail TypeError if self } unless b
67
69
  return self unless b.( self )
68
70
  m = how_comply ? "%s must not #{how_comply}" : "%s fails its check"
@@ -72,7 +74,7 @@ class Object
72
74
  # Fails with +TypeError+ unless the receiver is of the prescribed class. Second
73
75
  # optional argument customizes the error message (receiver description).
74
76
  #
75
- def aT_kind_of klass, what_is_receiver=insp
77
+ def aT_kind_of klass, what_is_receiver=y_inspect
76
78
  return self if is_a? klass
77
79
  fail TypeError, "%s not a #{klass}".X!( what_is_receiver )
78
80
  end
@@ -82,7 +84,7 @@ class Object
82
84
  # given class, or is a descendant of that class. Second optional argument
83
85
  # customizes the error message (receiver description).
84
86
  #
85
- def aT_complies klass, what_is_receiver=insp
87
+ def aT_complies klass, what_is_receiver=y_inspect
86
88
  return self if class_complies? klass
87
89
  fail TypeError, "%s does not comply with #{klass}".X!( what_is_receiver )
88
90
  end
@@ -91,7 +93,7 @@ class Object
91
93
  # Fails with +TypeError+ unless the receiver responds to the given method.
92
94
  # Second optional argument customizes the error message (receiver description).
93
95
  #
94
- def aT_respond_to method_name, what_is_receiver=insp
96
+ def aT_respond_to method_name, what_is_receiver=y_inspect
95
97
  return self if respond_to? method_name
96
98
  fail TypeError,
97
99
  "%s does not respond to '#{method_name}'".X!( what_is_receiver )
@@ -102,9 +104,9 @@ class Object
102
104
  # equal to the argument. Two more optional arguments customize the error
103
105
  # message (receiver description and the description of the other object).
104
106
  #
105
- def aT_equal other, what_is_receiver=insp, what_is_other=nil
107
+ def aT_equal other, what_is_receiver=y_inspect, what_is_other=nil
106
108
  return self if self == other
107
- wo = what_is_other || "the prescribed value (#{other.insp})"
109
+ wo = what_is_other || "the prescribed value (#{other.y_inspect})"
108
110
  fail TypeError, "%s must be equal to %s".X!( [ what_is_receiver, wo ] )
109
111
  end
110
112
 
@@ -112,37 +114,37 @@ class Object
112
114
  # differs from to the argument. Two more optional arguments customize the error
113
115
  # message (receiver description and the description of the other object).
114
116
  #
115
- def aT_not_equal other, what_is_receiver=insp, what_is_other=nil
117
+ def aT_not_equal other, what_is_receiver=y_inspect, what_is_other=nil
116
118
  return self unless self == other
117
- wo = what_is_other || "the prescribed value (#{other.insp})"
119
+ wo = what_is_other || "the prescribed value (#{other.y_inspect})"
118
120
  fail TypeError, "%s must not == %s".X!( [ what_is_receiver, wo ] )
119
121
  end
120
122
 
121
123
  # Fails with +TypeError+ unless activesupport's +#blank+ returns true for
122
124
  # the receiver.
123
125
  #
124
- def aT_blank what_is_receiver=insp
126
+ def aT_blank what_is_receiver=y_inspect
125
127
  tap { blank? or fail TypeError, "%s not blank".X!( what_is_receiver ) }
126
128
  end
127
129
 
128
130
  # Fails with +TypeError+ unless activesupport's +#present+ returns true for
129
131
  # the receiver.
130
132
  #
131
- def aT_present what_is_receiver=insp
133
+ def aT_present what_is_receiver=y_inspect
132
134
  tap { present? or fail TypeError, "%s not present".X!( what_is_receiver ) }
133
135
  end
134
136
 
135
137
  # Fails with +ArgumentError+ unless the +ActiveSupport+ method +#blank+ returns
136
138
  # true for the receiver.
137
139
  #
138
- def aA_blank what_is_receiver=insp
140
+ def aA_blank what_is_receiver=y_inspect
139
141
  tap { blank? or fail ArgumentError, "%s not blank".X!( what_is_receiver ) }
140
142
  end
141
143
 
142
144
  # Fails with +ArgumentError+ unless the +ActiveSupport+ method #present returns
143
145
  # true for the receiver.
144
146
  #
145
- def aA_present what_is_receiver=insp
147
+ def aA_present what_is_receiver=y_inspect
146
148
  tap {
147
149
  present? or fail ArgumentError, "%s not present".X!( what_is_receiver )
148
150
  }
@@ -1 +1 @@
1
- require File.dirname( __FILE__ ) + '/object/typing'
1
+ require_relative 'object/typing'
@@ -1,21 +1,25 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'y_support'
3
+ require_relative '../y_support'
4
4
 
5
5
  # Typing library.
6
6
  #
7
- # Apart from typing objects <em>by class and ancestry</em> (+#kind_of?+),
8
- # y_support typing library provides support for typing <em>by declaration</em>,
9
- # and for runtime assertions.
7
+ # A collection of helper methods mainly for argument validation. We often want
8
+ # to validate that arguments are of certain class, or that they fulfill some
9
+ # other criteria, and raise sufficiently informative error messages when not.
10
+ # I've been also experimenting with what I call "typing by declaration", that
11
+ # is, when a class declares compliance with another class without actually
12
+ # being its descendant, but this idea is still experimental. Basically,
13
+ # 'y_support/typing' remains a library of runtime assertions.
10
14
 
11
15
  directories_to_look_in = [ :typing ]
12
16
 
13
- # The fololowing code looks into the specified directory(ies) and requires
17
+ # The following code looks into the specified directory(ies) and requires
14
18
  # all the files in it (them).
15
19
  #
16
- directories_to_look_in.each do |part|
17
- Dir["#{File.dirname( __FILE__ )}/#{part}/*/typing.rb"].sort.each { |path|
18
- dir = File.dirname( path ).match( "y_support/#{part}" ).post_match
19
- require "y_support/#{part}#{dir}/typing"
20
- }
20
+ directories_to_look_in.each do |name|
21
+ Dir["#{File.dirname( __FILE__ )}/#{name}/*/typing.rb"].sort.each do |path|
22
+ dir = File.dirname( path ).match( "y_support/#{name}" ).post_match
23
+ require_relative "#{name}#{dir}/typing"
24
+ end
21
25
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'y_support'
3
+ require_relative '../y_support'
4
4
 
5
5
  # +y_support/unicode+ defines a small number of Unicode 1-character aliases to
6
6
  # make code more concise.
@@ -1,4 +1,4 @@
1
1
  module YSupport
2
- VERSION = "2.1.18"
2
+ VERSION = "2.4.4"
3
3
  DEBUG = false
4
4
  end
data/lib/y_support/x.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'y_support'
1
+ require 'gtk2'
2
+ require_relative '../y_support'
2
3
 
3
4
  # Assets related to X windows control.
4
5
  #
@@ -0,0 +1,134 @@
1
+ #! /usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ require 'minitest/autorun'
5
+ require_relative '../lib/y_support/flex_coerce'
6
+
7
+ describe "user class that defines no coercion whatsoever" do
8
+ before do
9
+ @c = Class.new do include FlexCoerce end
10
+ end
11
+
12
+ it "must be extended by FlexCoerce::ClassMethods" do
13
+ @c.singleton_class.ancestors.must_include FlexCoerce::ClassMethods
14
+ end
15
+
16
+ it "must have a parametrized subclass of FlexProxy" do
17
+ assert @c.FlexProxy < FlexCoerce::FlexProxy
18
+ @c.FlexProxy.host_class.must_equal @c
19
+ end
20
+
21
+ describe "object of that class" do
22
+ before do
23
+ @object = @c.new
24
+ end
25
+
26
+ it "should provide to the user class #coerce method returning a proxy" do
27
+ o1, o2 = @object.coerce 42
28
+ o1.must_be_kind_of FlexCoerce::FlexProxy
29
+ o2.must_equal @object
30
+ end
31
+
32
+ it "should raise TypeError for all operators and binary methods" do
33
+ -> { 42 + @object }.must_raise TypeError
34
+ -> { 42 - @object }.must_raise TypeError
35
+ -> { 42 * @object }.must_raise TypeError
36
+ -> { 42 / @object }.must_raise TypeError
37
+ -> { 42 % @object }.must_raise TypeError
38
+ -> { 42.div @object }.must_raise TypeError
39
+ -> { 42.divmod @object }.must_raise TypeError
40
+ -> { 42.fdiv @object }.must_raise TypeError
41
+ -> { 42 ** @object }.must_raise TypeError
42
+ -> { 42 & @object }.must_raise TypeError
43
+ -> { 42 | @object }.must_raise TypeError
44
+ -> { 42 ^ @object }.must_raise TypeError
45
+ -> { 42 > @object }.must_raise TypeError
46
+ -> { 42 >= @object }.must_raise TypeError
47
+ -> { 42 < @object }.must_raise TypeError
48
+ -> { 42 <= @object }.must_raise TypeError
49
+ -> { 42 <=> @object }.must_raise TypeError
50
+ # Operator #=== is too liberal to call #coerce.
51
+ -> { @object.coerce( 42 ).first === @object }.must_raise TypeError
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "user class that allows Numeric#* and nothing else" do
57
+ before do
58
+ @c = Class.new do
59
+ include FlexCoerce
60
+ def + number; 10 + number end
61
+ def - number; 10 - number end
62
+ def * number; 10 * number end
63
+ def / number; 10 / number end
64
+ end
65
+
66
+ @c.define_coercion Fixnum, method: :* do |left_operand, right_operand|
67
+ right_operand * left_operand
68
+ end
69
+ end
70
+
71
+ it "must have coercion table with :* entry" do
72
+ @c.coercion_table.keys.must_equal [ :* ]
73
+ table_entry = @c.FlexProxy.new( 42 ).host_class.coercion_table[ :* ]
74
+ table_entry.size.must_equal 1
75
+ table_entry.find { |type, closure| type === 42 }.must_be_kind_of Array
76
+ assert table_entry.find { |type, _| type == :foobar }.nil?
77
+ end
78
+
79
+ describe "object of that class" do
80
+ before do
81
+ @object = @c.new
82
+ end
83
+
84
+ it "is defined to behave as number 10 with 4 basic operators" do
85
+ ( @object + 2 ).must_equal 12
86
+ ( @object - 2 ).must_equal 8
87
+ ( @object * 2 ).must_equal 20
88
+ ( @object / 2 ).must_equal 5
89
+ end
90
+
91
+ it "must have working coercion with Fixnum#*, but not other classes" do
92
+ ( 2 * @object ).must_equal 20
93
+ ( 3 * @object ).must_equal 30
94
+ -> { 3.0 * @object }.must_raise TypeError
95
+ end
96
+
97
+ it "should not define coercion for other operators" do
98
+ -> { 42 + @object }.must_raise TypeError
99
+ -> { 42 - @object }.must_raise TypeError
100
+ -> { 42 / @object }.must_raise TypeError
101
+ -> { 42 % @object }.must_raise TypeError
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "class that includes FlexCoerce via another module" do
107
+ before do
108
+ m = Module.new do include FlexCoerce end
109
+ @c = Class.new do
110
+ include m
111
+ def + arg; 10 + arg end
112
+ end
113
+ end
114
+
115
+ it "should still allow defining coercion" do
116
+ @c.methods.must_include :define_coercion
117
+ end
118
+
119
+ describe "object of such class" do
120
+ before do
121
+ @c.define_coercion Integer, method: :+ do |operand_1, operand_2|
122
+ operand_2 + operand_1
123
+ end
124
+ @object = @c.new
125
+ end
126
+
127
+ it "should function as expected" do
128
+ ( 1 + @c.new ).must_equal 11
129
+ end
130
+ end
131
+ end
132
+
133
+
134
+
@@ -0,0 +1,231 @@
1
+ #! /usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ require 'minitest/autorun'
5
+ # require 'y_support/literate' # tested component itself
6
+ require './../lib/y_support/literate'
7
+
8
+ describe Literate::Attempt do
9
+ before do
10
+ @str = "lorem ipsum dolor sit amet"
11
+ @txt = "split the sentence into words"
12
+ # A simple attempt block.
13
+ @a = Literate::Attempt.new subject: @str, text: @txt do
14
+ note is: "natural language sentence"
15
+ split ' '
16
+ end
17
+ # More verbose attempt block.
18
+ chosen_word = 3
19
+ @b = Literate::Attempt.new subject: @str, text: @txt do
20
+ » is: "natural language sentence"
21
+ » has: "#{size} characters"
22
+ words = split ' '
23
+ » "number of words", is: words.size
24
+ » "chosen word", is: words[ chosen_word ]
25
+ words
26
+ end
27
+ end
28
+
29
+ it "should have 4 basic properties" do
30
+ @a.__text__.must_equal @txt
31
+ @a.__subject__.must_equal @str
32
+ @a.__block__.must_be_kind_of Proc
33
+ @a.__knowledge_base__.must_be_empty
34
+ # Fact list is empty because the block hasn't been run yet.
35
+ # Let's run the block:
36
+ @a.__run__
37
+ # Now the fact list includes the comment made in the block.
38
+ @a.__knowledge_base__.size.must_equal 1
39
+ end
40
+
41
+ describe "#__run__" do
42
+ it "must run the attempt's block" do
43
+ expected_result = "lorem", "ipsum", "dolor", "sit", "amet"
44
+ @a.__run__.must_equal expected_result
45
+ end
46
+ end
47
+
48
+ describe "Object#try method" do
49
+ before do
50
+ error = false
51
+ @error_switch = -> arg { error = arg }
52
+ @text = "to split into words"
53
+ @block = proc do
54
+ note is: "a string with several words"
55
+ fail error if error
56
+ split ' '
57
+ end
58
+ end
59
+
60
+ it "must execute the block allowing subject's methods" do
61
+ "hello world".try( @text, &@block )
62
+ .must_equal [ "hello", "world" ]
63
+ @error_switch.( TypeError )
64
+ -> { "hello world".try @text, &@block }.must_raise TypeError
65
+ @error_switch.( NameError )
66
+ -> { "hello world".try @text, &@block }.must_raise NameError
67
+ end
68
+
69
+ it "must allow Literate::Attempt#comment inside the block" do
70
+ begin
71
+ @error_switch.( TypeError )
72
+ "hello world".try @text, &@block
73
+ rescue => error
74
+ # Proof that Literate::Attemp#comment activated.
75
+ m = error.message
76
+ m.must_include "When trying to split into words"
77
+ m.must_include "a string with several words"
78
+ else
79
+ flunk "Error expected but nothing raised!"
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "#note" do
85
+ it "must write entries into @__knowledge_base__" do
86
+ @a.__run__
87
+ x = { @str => [ is: "natural language sentence" ] }
88
+ @a.__knowledge_base__.must_equal x
89
+ end
90
+
91
+ it "must write entries into @__knowledge_base__" do
92
+ @b.__run__
93
+ x = { @str => [ is: "natural language sentence",
94
+ has: "26 characters" ],
95
+ "number of words" => [ is: 5 ],
96
+ "chosen word" => [ is: "sit" ] }
97
+ @b.__knowledge_base__ .must_equal x
98
+ end
99
+ end
100
+
101
+ describe "#__describe__" do
102
+ it "must produce description of the main subject" do
103
+ @a.__run__
104
+ @a.__describe__( @a.__subject__ )
105
+ .must_equal [ "lorem ipsum dolor sit amet",
106
+ { is: "natural language sentence" } ]
107
+ @b.__run__
108
+ @b.__describe__( @a.__subject__ )
109
+ .must_equal [ "lorem ipsum dolor sit amet",
110
+ { is: "natural language sentence",
111
+ has: "26 characters" } ]
112
+ end
113
+ end
114
+
115
+ describe "#__circumstances__" do
116
+ it "..." do
117
+ @a.__run__
118
+ @a.__circumstances__.must_equal ""
119
+ @b.__run__
120
+ @b.__circumstances__
121
+ .must_equal "number of words being 5, " +
122
+ "chosen word being sit"
123
+ end
124
+ end
125
+ end
126
+
127
+ describe "usecase 1: name validator" do
128
+ before do
129
+ @name_validator = Object.new
130
+ @name_validator.define_singleton_method :validate do |name|
131
+ name.to_s.try "to validate the requested name" do
132
+ note "rejecting non-capitalized names"
133
+ fail NameError unless ( ?A..?Z ) === self[0]
134
+ note "rejecting names with spaces"
135
+ fail NameError unless split( ' ' ).size == 1
136
+ end
137
+ return name
138
+ end
139
+ end
140
+
141
+ it "should validate good names" do
142
+ @name_validator.validate( :Fred ).must_equal :Fred
143
+ @name_validator.validate( "Su_san" ).must_equal "Su_san"
144
+ end
145
+
146
+ it "should reject bad names with a good error message" do
147
+ expected_message =
148
+ "When trying to validate the requested name, rejecting " +
149
+ "non-capitalized names: NameError!"
150
+ begin
151
+ @name_validator.validate( :fred )
152
+ rescue => error
153
+ error.message.must_equal expected_message
154
+ end
155
+ end
156
+ end
157
+
158
+ # describe 'case 1' do
159
+ # it "should work" do
160
+ # # begin
161
+ # # @a.__run__
162
+ # # rescue TypeError => err
163
+ # # expected_msg = "When trying concatenation of an array " +
164
+ # # "with 2 elements, TypeError occurred: " +
165
+ # # "Lorem ipsum dolor sit amet!"
166
+ # # # Make sure the last 45 characters is OK.
167
+ # # assert_equal expected_msg[-45..-1], err.message[-45..-1]
168
+ # # # # Make sure that whole message is as expected.
169
+ # # # assert_equal expected_msg, err.message
170
+ # # else
171
+ # # flunk "Expected TypeError error not raised!"
172
+ # # end
173
+ # end
174
+ # end
175
+
176
+ # describe 'case 2' do
177
+ # it "should work" do
178
+ # begin
179
+ # try "to call constant Nothing" do Nothing end
180
+ # rescue NameError => err
181
+ # expected_msg = 'When trying to call constant Nothing, ' +
182
+ # 'NameError occurred: uninitialized constant Nothing'
183
+ # assert_equal( expected_msg, err.message )
184
+ # else
185
+ # flunk "Expected NameError error not raised!"
186
+ # end
187
+ # end
188
+ # end
189
+
190
+ # describe 'case 3' do
191
+ # it "should work" do
192
+ # o = Object.new
193
+ # class << o
194
+ # def to_s; "THIS OBJECT" end
195
+ # def hello!; "hello hello" end
196
+ # end
197
+ # # Object's methods must be callable
198
+ # o.try "to say hello" do hello! end.must_equal "hello hello"
199
+ # begin
200
+ # o.try "to call a weird method" do goodbye! end
201
+ # rescue NoMethodError => err
202
+ # err.message.must_include "When trying to call a weird " +
203
+ # "method, NoMethodError occurred: undefined method"
204
+ # err.message.must_include "goodbye!"
205
+ # end
206
+ # end
207
+ # end
208
+
209
+ # describe 'case 4' do
210
+ # it "should work" do
211
+ # begin
212
+ # "FooBar".try "to do something" do
213
+ # comment has: "#{size} letters",
214
+ # is: "a #{self.class} instance"
215
+ # unless include? "Quux"
216
+ # comment "Quux", is: "not a part of it"
217
+ # try "to append Quux to it" do
218
+ # self << "Quux"
219
+ # fail "EPIC FAIL"
220
+ # end
221
+ # end
222
+ # end
223
+ # rescue => err
224
+ # err.message.must_equal "When trying to do something, " +
225
+ # "FooBar having 6 letters, being a String instance, " +
226
+ # "Quux being not a part of it, RuntimeError occurred: " +
227
+ # "When trying to append Quux to it, RuntimeError " +
228
+ # "occurred: EPIC FAIL"
229
+ # end
230
+ # end
231
+ # end
data/test/misc_test.rb CHANGED
@@ -29,6 +29,13 @@ describe Object do
29
29
  o.bar.ancestors[1].must_equal( m )
30
30
  o.bar.mother.must_equal( o )
31
31
  end
32
+
33
+ it "should have #insp method to facilitate inspection" do
34
+ module Quux; class Foo; def to_s; "bar" end end end
35
+ Quux::Foo.new.y_inspect.must_equal "Quux::Foo:bar"
36
+ Quux::Foo.new.y_inspect( :full ).must_equal "#<Quux::Foo:bar>"
37
+ Quux::Foo.new.y_inspect( :short ).must_equal "Foo:bar"
38
+ end
32
39
  end
33
40
 
34
41
 
@@ -52,7 +59,8 @@ describe Module do
52
59
  m.const_reset! :Foo, 43
53
60
  m::Foo.must_equal 43
54
61
  m.module_exec do
55
- def a; 42 end
62
+ selector :a
63
+ def initialize; @a = 42 end
56
64
  chain b: :a, &:to_s
57
65
  end
58
66
  Class.new do include m end.new.b.must_equal "42"
@@ -65,6 +73,14 @@ describe Class do
65
73
  require './../lib/y_support/core_ext/class'
66
74
  end
67
75
 
76
+ it "has #selector alias for #attr_reader method" do
77
+ o = Class.new do
78
+ selector :a
79
+ def initialize a; @a = a end
80
+ end.new( 42 )
81
+ o.a.must_equal( 42 )
82
+ end
83
+
68
84
  it "has #parametrize method" do
69
85
  a = Class.new
70
86
  -> { a.foo }.must_raise NoMethodError
@@ -174,32 +190,38 @@ describe Hash do
174
190
  test = { a: 11, b: 22 }
175
191
  assert_equal( { a: 11, b: 22 }, test.default!( defaults ) )
176
192
  test = { a: 11, c: 22 }
177
- assert_equal( { a: 11, b: nil, c: 22 }, test.default!( defaults ) )
178
- end
179
-
180
- it "should have #with_keys and #modify_keys" do
181
- assert_equal( {"a" => :b, "c" => :d}, {a: :b, c: :d}.with_keys( &:to_s ) )
182
- assert_equal( {"a1" => 1, "c2" => 2}, {a: 1, c: 2}.modify_keys { |k, v|
183
- k.to_s + v.to_s } )
184
- assert_equal( {"a1" => 1, "c2" => 2}, {a: 1, c: 2}.modify_keys {|p|
185
- p[0].to_s + p[1].to_s } )
186
- assert_equal( {2 => 1, 4 => 2}, {1 => 1, 2 => 2}.modify_keys { |k, v|
187
- k + v } )
188
- assert_equal( {2 => 1, 4 => 2}, {1 => 1, 2 => 2}.modify_keys { |p|
189
- p[0] + p[1] } )
190
- end
191
-
192
- it "should have #with_values and #modify_values" do
193
- assert_equal( { a: "b", c: "d" }, {a: :b, c: :d}.with_values( &:to_s ) )
194
- assert_equal( {a: "ab", c: "cd"}, {a: :b, c: :d}.modify_values { |k, v|
195
- k.to_s + v.to_s } )
196
- assert_equal( {a: "ab", c: "cd"}, {a: :b, c: :d}.modify_values { |p|
197
- p[0].to_s + p[1].to_s } )
198
- hh = { a: 1, b: 2 }
199
- hh.with_values! &:to_s
200
- assert_equal ["1", "2"], hh.values
201
- hh.modify_values! &:join
202
- assert_equal ["a1", "b2"], hh.values
193
+ { a: 11, b: nil, c: 22 }.must_equal test.default! defaults
194
+ end
195
+
196
+ it "should have #with_keys and #with_keys!" do
197
+ test = { "a" => :b, "c" => :d }
198
+ test.with_keys( &:to_sym ).must_equal( { a: :b, c: :d } )
199
+ test.must_equal( { "a" => :b, "c" => :d } )
200
+ test.with_keys! &:to_sym
201
+ test.must_equal( { a: :b, c: :d } )
202
+ end
203
+
204
+ it "should have #change_keys" do
205
+ test = { a: 1, c: 2 }
206
+ test.change_keys { |k, v| k.to_s + v.to_s }
207
+ .must_equal( { "a1" => 1, "c2" => 2 } )
208
+ end
209
+
210
+ it "should have #with_values and #with_values!" do
211
+ test = { a: :b, c: :d }
212
+ test.with_values( &:to_s ).must_equal( { a: "b", c: "d" } )
213
+ test.must_equal( { a: :b, c: :d } )
214
+ test.with_values!( &:to_s )
215
+ test.must_equal( { a: "b", c: "d" } )
216
+ end
217
+
218
+ it "should have #change_values and #change_values!" do
219
+ test = { a: :b, c: :d }
220
+ test.modify_values do |k, v| k.to_s + v.to_s end
221
+ .must_equal( {a: "ab", c: "cd"} )
222
+ test.must_equal( { a: :b, c: :d } )
223
+ test.modify_values! { |k, v| k.to_s + v.to_s }
224
+ test.must_equal( {a: "ab", c: "cd"} )
203
225
  end
204
226
 
205
227
  it "should have #modify" do