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,260 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # Module methods for the modules serving as +NameMagic+ namespaces. A namespace
4
- # for a certain class featuring +NameMagic+ holds "civil registry" of all its
5
- # instances, be they named or nameless. For this purpose, the namespace owns
6
- # +@instances+ hash of pairs <tt>{ instance => name }</tt>, with _nil_ values
7
- # denoting nameless instances. For named instances, the namespace also holds
8
- # references to them in constants in the style <tt>Namespace::Name</tt>. This
9
- # is one of the reasons why instance names in +NameMagic+ must start with
10
- # a capital letter and generally must be usable as constant names. The list of
11
- # instances is accessible via +#instances+ method. Individual instances can be
12
- # queried by +#instance+ method, eg. by their names.
13
- #
14
- # === Life cycle of instances of classes featuring +NameMagic+
15
- #
16
- # +NameMagic+ offers 3 hooks for the instances of its user classes. These hooks
17
- # are closures invoked at the relevant points of the instances' life cycle:
18
- #
19
- # * new instance hook -- when the instance is created
20
- # * name set hook -- when the instance is offered a name
21
- # * name get hook -- when the instance's name is queried
22
- #
23
- # These three hooks are stored in instance variables owned by the namespace,
24
- # accesible by methods +#new_instance_hook, +#name_set_hook+ and
25
- # +#name_get_hook+. If called with a block, these methods also serve to set
26
- # their respective hook closures.
27
- #
28
- # When an instance is first created, unary +new_instance_hook+ is called.
29
- # When an instance is offered a name, +name_set_hook+ is called. It is a
30
- # ternary closure with 3 ordered arguments +name+, +instance+ and +old_name+,
31
- # receiving respectively the name offered, the instance, and the previous
32
- # name of the instance (if any). The return value of the closure will be used
33
- # to actually name the instance. This closure can thus be used to check and
34
- # modify the names before they are actually used. Finally, when the instances'
35
- # name is queried, third closure, unary +name_get_hook+ is applied to modify
36
- # the name output. The purpose of the name get hook is not to really change
37
- # the name upon reading, but mainly to tweak the preferred form or spelling
38
- # where multiple forms of are possible for the same name. (For example, the
39
- # standard form in the +@instances+ hash could be in camel case, such as
40
- # "AcinonyxJubatus", while preferred querying output would be a binomial name
41
- # with whitespaces, "Acinonyx jubatus".)
42
- #
43
- # === Avidity of the instances
44
- #
45
- # After the offered name is checked and modified by the name set hook closure,
46
- # there is one more remaining problem to worry about: Whether the name is
47
- # already used by another instance in the same namespace. If the name is taken,
48
- # the ensuing action depends on whether the instance being named is _avid_.
49
- # Avid instances are so eager to get a name, that they will steal the offered
50
- # name even if it is already in use, making the conflicting instance nameless
51
- # in the process. In +NameMagic+, it turns out to be convenient to make the
52
- # new instances avid by default, unless the name was explicitly supplied to the
53
- # constructor by +:name+ argument, or avidity suppressed by setting +:name_avid
54
- # option to _false_.
55
- #
56
- # Techincally, avid instances are registered as an array kept by the namespace
57
- # under the variable +@avid_instances+.
58
- #
59
- # === Forgetting instances
60
- #
61
- # A namespace can de-register, or forget instances. For this purpose, see
62
- # methods +#forget+, +#__forget__, +#forget_nameless_instances+,
63
- # +#forget_all_instances+.
64
- #
65
- # === Ersatz constant magic
66
- #
67
- # To imitate built-in constant magic of some Ruby classes, +NamespaceMethods+
68
- # provides ersatz method +#const_magic+, that searches all the modules in the
69
- # object space for the pertinent instances newly assigned to constants. Method
70
- # +#const_magic+ is then called before executing almost every public method of
71
- # +NameMagic+, thus keeping the "civil registry" up-to-date. While not exactly
72
- # computationally efficient, it tends to make the user code more readable and
73
- # pays off in most usecases. For efficiency, we are looking forward to the
74
- # +#const_assigned+ hook promised by Ruby core team...
75
- #
76
- # The namespace method versions that _do_ _not_ perform ersatz constant magic
77
- # are generally denoted by underlines: Eg. methods +#__instances__+ and
78
- # +#__forget__+ do not perform constant magic, while +#instances+ and +#forget+
79
- # do.
80
- #
81
- module NameMagic::NamespaceMethods
82
- # Presents the instances registered in this namespace.
83
- #
84
- def instances *args
85
- const_magic
86
- __instances__.keys
87
- end
88
-
89
- # Deprecated method to get full names of the named instances.
90
- #
91
- def instance_names
92
- warn "Method #instance_names is deprecated. Use 'instances._names_' or 'instances.names' instead!"
93
- instances.names false
94
- end
95
-
96
- # Presents namespace-owned +@instances+ hash. The hash consists of pairs
97
- # <code>{ instance => instance_name }</code>. Unnamed instances have +nil+
98
- # assigned to them as their name. (The method does not trigger
99
- # +#const_magic+.)
100
- #
101
- def __instances__
102
- @instances ||= {}
103
- end
104
-
105
- # Avid instances registered in this namespace. ("Avid" means that the
106
- # instance is able to steal (overwrite) a name from another registered
107
- # instance. (The method does not trigger +#const_magic+.)
108
- #
109
- def __avid_instances__
110
- @avid_instances ||= []
111
- end
112
-
113
- # Returns the instance identified by the argument, which can be typically
114
- # a name (string/symbol). If a registered instance is supplied, it will be
115
- # returned unchanged.
116
- #
117
- def instance id, *args
118
- # puts "#instance( #{identifier} )" if DEBUG
119
- # In @instances hash, value 'nil' indicates a nameless instance!
120
- fail TypeError, "'nil' is not an instance identifier!" if id.nil?
121
- ii = instances
122
- return id if ii.include? id # return the instance back
123
- begin # identifier not a registered instance -- treat it as a name
124
- ary = [id, id.to_sym]
125
- ihsh = __instances__
126
- ii.find { |inst| ary.include? ihsh[ inst ] or ary.include? inst.name }
127
- rescue NoMethodError
128
- end or fail NameError, "No instance #{id} in #{self}."
129
- end
130
-
131
- # Searches all the modules in the the object space for constants referring
132
- # to receiver class objects, and names the found instances accordingly.
133
- # Internally, it works by invoking private procedure +#search_all_modules.
134
- # The return value is the remaining number of nameless instances.
135
- #
136
- def const_magic
137
- puts "#{self}#const_magic invoked!" if ::NameMagic::DEBUG
138
- return 0 if nameless_instances.size == 0
139
- search_all_modules
140
- return nameless_instances.size
141
- end
142
-
143
- # Returns those instances, which are nameless (whose name is set to nil).
144
- #
145
- def nameless_instances *args
146
- __instances__.select { |key, val| val.nil? }.keys
147
- end
148
-
149
- # Clears namespace-owned references to a specified instance. (This is
150
- # different from "unnaming" an instance by setting <code>inst.name =
151
- # nil</code>, which makes the instance anonymous, but still registered.)
152
- #
153
- def forget instance_identifier, *args
154
- inst = begin; instance( instance_identifier ); rescue ArgumentError
155
- return nil # nothing to forget
156
- end
157
- ɴ = inst.nil? ? nil : inst.name
158
- namespace.send :remove_const, ɴ if ɴ # clear constant assignment
159
- __instances__.delete( inst ) # remove @instances entry
160
- __avid_instances__.delete( inst ) # remove if any
161
- return inst # return the forgotten instance
162
- end
163
-
164
- # Clears namespace-owned references to an instance, without performing
165
- # #const_magic first. The argument should be a registered instance. Returns
166
- # the instance name, or _false_, if there was no such registered instance.
167
- #
168
- def __forget__( instance, *args )
169
- return false unless __instances__.keys.include? instance
170
- namespace.send :remove_const, instance.name if instance.name
171
- __avid_instances__.delete( instance )
172
- __instances__.delete instance
173
- end
174
-
175
- # Clears namespace-owned references to all the anonymous instances.
176
- #
177
- def forget_nameless_instances
178
- nameless_instances.each { |inst|
179
- __instances__.delete( inst )
180
- __avid_instances__.delete( inst ) # also from avid instances
181
- }
182
- end
183
-
184
- # Clears namespace-owned references to all the instances.
185
- #
186
- def forget_all_instances
187
- __instances__.clear
188
- constants( false ).each { |sym|
189
- namespace.send :remove_const, sym if const_get( sym ).is_a? self
190
- }
191
- end
192
-
193
- # Registers a hook to execute upon instantiation. Expects a unary block, whose
194
- # argument represents the new instance. It is called right after instantiation,
195
- # but before naming the instance. Without a block, it acts as a getter.
196
- #
197
- def new_instance_hook &block
198
- @new_instance_hook = block if block
199
- @new_instance_hook ||= -> instance { instance }
200
- end
201
-
202
- # Registers a hook to execute upon instance naming. Expects a ternary block,
203
- # with arguments name, instance and old_name, representing respectively the
204
- # the requested name, the instance to be named, and the previous name of that
205
- # instance (if any). The output of the block should be the name to actually
206
- # be used. In other words, the hook can be used (among other things) to check
207
- # and/or modify the requested name when christening the instance. It is the
208
- # responsibility of this block to output a symbol that can be used as a Ruby
209
- # constant name. Without a block, this method acts as a getter.
210
- #
211
- def name_set_hook &block
212
- @name_set_hook = block if block
213
- @name_set_hook ||= -> name, instance, old_name=nil { name }
214
- end
215
-
216
- # Registers a hook to execute whenever the instance is asked its name. The
217
- # instance names are objects that are kept in a hash referred to by
218
- # +@instances+ variable owned by the namespace. Normally, +NameMagic#name+
219
- # simply returns the name of the instance, as found in the +@instances+ hash.
220
- # When +name_get_hook+ is defined, this name is transformed by it before being
221
- # returned. Without a block, this method acts as a getter.
222
- #
223
- def name_get_hook &block
224
- @name_get_hook = block if block
225
- @name_get_hook ||= -> name { name }
226
- end
227
-
228
- # Checks whether a name is acceptable as a constant name.
229
- #
230
- def validate_name name
231
- name.to_s.tap do |ɴ| # check if the name starts with 'A'..'Z'
232
- fail NameError, "#{self}-registered name must start with a capital " +
233
- " letter 'A'..'Z' ('#{ɴ}' given)!" unless ( ?A..?Z ) === ɴ[0]
234
- end
235
- end
236
-
237
- private
238
-
239
- # Checks all the constants in some module's namespace, recursively.
240
- #
241
- def search_all_modules
242
- todo = ( nameless_instances + __avid_instances__ ).map( &:object_id ).uniq
243
- ObjectSpace.each_object Module do |ɱ|
244
- ɱ.constants( false ).each do |const_ß|
245
- begin; instance = ɱ.const_get( const_ß ) # Some constants cause
246
- rescue LoadError, StandardError; next end # errors upon loading.
247
- next unless todo.include? instance.object_id
248
- # puts "NameMagic: Anonymous object under #{const_ß}!" if DEBUG
249
- if instance.avid? then # puts "NameMagic: It is avid." if DEBUG
250
- instance.make_not_avid! # Remove from the avid list.
251
- instance.name! const_ß # Name it rudely.
252
- else # puts "NameMagic: It is not avid." if DEBUG
253
- instance.name = const_ß # Name it cautiously.
254
- end
255
- todo.delete instance.object_id # Remove from todo list.
256
- break if todo.empty? # Abandon the loop if done.
257
- end
258
- end
259
- end
260
- end # module NameMagic::NamespaceMethods
data/lib/y_support/try.rb DELETED
@@ -1,133 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'y_support'
4
- require 'y_support/core_ext/array/misc'
5
-
6
- # Provides +Try+ class, and +Object#try+ method that constructs and calls a
7
- # +Consciously::Try+ instance. This +#try+ method has nothing to do with the
8
- # error-swallowing +#try+ method frequently seen elsewhere. On the contrary,
9
- # our +#try+ method _facilitates_ raising and ultimately, correcting errors
10
- # by providing well-formed error messages.
11
- #
12
- # Constructing error messages is labor-intensive. +Consciously::Try+ allows one
13
- # to construct verbose error messages with +#note+ statements inside the block,
14
- # that act as comments at the same time.
15
- #
16
- # "FooBar".try "to do something" do
17
- # note has: "#{size} letters", is: "a #{self.class} instance"
18
- # unless include? "Quux"
19
- # note "Quux", is: "not a part of it"
20
- # try "to append Quux to it" do
21
- # self << "Quux"
22
- # fail "EPIC FAIL"
23
- # end
24
- # end
25
- # end
26
- #
27
- # Should produce an automatic error message like this: "When trying to do
28
- # something, FooBar having 6 letters, being a String instance, Quux being
29
- # not a part of it, RuntimeError occurred: When trying to append Quux to it,
30
- # RuntimeError occurred: EPIC FAIL"
31
- #
32
- module Consciously
33
- class Try < BasicObject
34
- DECORATE = -> str, prefix: '', postfix: '' {
35
- str.to_s.tap { |ς| return ς.empty? ? '' : prefix + ς + postfix }
36
- }
37
- TRANSITIVE = ::Hash.new do |ꜧ, key| "#{key}ing %s" end
38
- .update( is: "being %s",
39
- has: "having %s" )
40
- STATE = ::Hash.new do |ꜧ, key| "#{key} %s" end
41
- .update( is: "%s",
42
- has: "has %s" )
43
-
44
- attr_reader :__obj__, :__txt__, :__bl__, :__facts__
45
-
46
- # This
47
- def initialize( object: nil, text: nil, &block )
48
- @__obj__, @__txt__, @__bl__ = object, text, block
49
- @__facts__ = ::Hash.new do |hsh, key| hsh[key] = [ {} ] end
50
- end
51
-
52
- # The syntax of this method, available inside the #try block, is:
53
- #
54
- # note "Concatenation of Foo and Bar", is: "FooBar", has: "6 letters"
55
- #
56
- def note *subjects, **statements, &block
57
- return Array( subjects ).each { |s| __facts__[s].push_ordered s } if
58
- statements.empty?
59
- subjects << __obj__ if subjects.empty?
60
- Array( subjects ).each { |subj|
61
- statements.each { |verb, obj| __facts__[subj].push_named verb => obj }
62
- }
63
- return statements.first[1]
64
- end
65
-
66
- # Invokes the Try object's block.
67
- #
68
- def __invoke__ *args
69
- begin
70
- instance_exec *args, &__bl__
71
- rescue ::StandardError => err
72
- txt1 = "When trying #{__txt__}"
73
- thing, statements = __describe__
74
- txt2 = DECORATE.( thing, prefix: ' ' )
75
- txt3 = DECORATE.( statements.map { |verb, object|
76
- STATE[verb] % object
77
- }.join( ', ' ),
78
- prefix: ' (', postfix: ')' )
79
- txt4 = DECORATE.( __circumstances__, prefix: ', ' )
80
- txt5 = DECORATE.( "#{err.class} occurred: #{err}", prefix: ', ' )
81
- raise err, txt1 + txt2 + txt3 + txt4 + txt5
82
- end
83
- end
84
-
85
- def try *args, &block
86
- __obj__.try *args, &block
87
- end
88
-
89
- def method_missing sym, *args
90
- __obj__.send sym, *args
91
- end
92
-
93
- def __describe__ obj=__obj__
94
- facts = __facts__[obj].dup
95
- statements = if facts.last.is_a? ::Hash then facts.pop else {} end
96
- fs = facts.join ', '
97
- if statements.empty? then
98
- return fs, statements
99
- else
100
- return facts.empty? ? obj.to_s : fs, statements
101
- end
102
- end
103
-
104
- def __circumstances__
105
- __facts__.reject { |subj, _| subj == __obj__ }.map { |subj, _|
106
- thing, statements = __describe__( subj )
107
- thing + DECORATE.( statements.map { |v, o|
108
- TRANSITIVE[v] % o
109
- }.join( ', ' ),
110
- prefix: ' ' )
111
- }.join( ', ' )
112
- end
113
- end
114
- end
115
-
116
-
117
- class Object
118
- # Try method takes two textual arguments and one block. The first (optional)
119
- # argument is a natural language description of the method's receiver (with
120
- # #to_s of the receiver used by default). The second argument is a natural
121
- # language description of the supplied block's _contract_ -- in other words,
122
- # what the supplied block tries to do. Finally, the block contains the code
123
- # to perform the described risky action. Inside the block, +#note+ method is
124
- # available, which builds up the context information for a good error message,
125
- # should the risky action raise one.
126
- #
127
- def try receiver_NL_description=self, attempt_NL_description, &block
128
- Consciously::Try.new( object: receiver_NL_description,
129
- text: attempt_NL_description,
130
- &block ).__invoke__
131
- end
132
- alias consciously try
133
- end
@@ -1,138 +0,0 @@
1
- #! /usr/bin/ruby
2
- #encoding: utf-8
3
-
4
- fail NotImplementedError # TODO: This part doesn't work yet
5
-
6
- require 'minitest/autorun'
7
-
8
- describe "Algebra" do
9
- before do
10
- require './../lib/y_support/abstract_algebra'
11
- # Define the stupidest monoid:
12
- @monoid = Class.new { include Algebra::Monoid } # make some class
13
- zero = @monoid.new # call arbitrary instance zero
14
- @monoid.class_exec {
15
- # Define the stupidest #add method.
16
- define_method :add do |other|
17
- if self == zero then other
18
- elsif other == zero then self
19
- else self.class.addition_table[[self, other]] end
20
- end
21
- # Define the stupidest addition table.
22
- instance_variable_set :@addition_table,
23
- Hash.new { |ꜧ, k|
24
- ꜧ[k] = if k[0].object_id <= k[1].object_id
25
- new # just make up an instance
26
- else
27
- ꜧ[k[1], k[0]] # swap operands
28
- end
29
- }
30
- }
31
- # And refine the @monoid's singleton class.
32
- @monoid.singleton_class.class_exec { attr_reader :addition_table }
33
- @monoid.define_singleton_method :additive_identity do zero end
34
- end
35
-
36
- describe "Algebra" do
37
- it "should have working Monoid" do
38
- m = @monoid.random # choose an instance
39
-
40
- # #== method
41
- assert m == m
42
-
43
- # closure
44
- # (not tested)
45
-
46
- # associativity
47
- n, o = @monoid.random, @monoid.random
48
- assert ( m + n ) + o == m + ( n + o )
49
-
50
- # identity element
51
- assert m + @monoid.zero == m
52
- assert @monoid.zero + m == m
53
- end
54
-
55
- it "should have working Group" do
56
- g = @group.random
57
-
58
- # (monoid properties not tested)
59
-
60
- # inverse element
61
- assert g + (-g) == @group.zero
62
- assert (-g) + g == @group.zero
63
- end
64
-
65
- it "should define AbelianGroup" do
66
- ag = @abelian_group.random
67
-
68
- # (group properties not tested)
69
-
70
- # commutativity
71
- bh = @abelian_group.random
72
- assert ag + bh == bh + ag
73
- end
74
-
75
- it "should define Ring" do
76
- r = @ring.random
77
-
78
- # (abelian group properties with respect to addition not tested)
79
-
80
- # (multiplication closure not tested)
81
-
82
- # multiplication associativity
83
- s, t = @ring.random, @ring.random
84
- assert r * ( s * t ) == ( r * s ) * t
85
-
86
- # multiplication identity
87
- mi = @ring.one
88
- assert r * mi == r
89
- assert mi * r == r
90
-
91
- # distributivity
92
- assert r * ( s + t ) == ( r * s ) + ( s * t )
93
- end
94
-
95
- it "should define Field" do
96
- f = @field.random
97
-
98
- # (ring properties not tested)
99
-
100
- # multiplicative inverse
101
- mi = @ring.multiplicative_identity
102
- assert f * f.multiplicative_inverse == mi
103
- assert f.multiplicative_inverse * f == mi
104
- end
105
- end
106
-
107
- describe "numerics" do
108
- it "should have patched Integer" do
109
- assert Integer.zero.equal? 0
110
- end
111
-
112
- it "should have patched Float" do
113
- assert Float.zero.equal? 0.0
114
- end
115
-
116
- it "should have patched Rational" do
117
- assert Rational.zero.equal? Rational( 0, 0 )
118
- end
119
-
120
- it "should have patched Complex" do
121
- assert Complex.zero.equal? Complex( 0, 0 )
122
- end
123
- end
124
-
125
- describe "Matrix" do
126
- it "should have Matrix.wildcard_zero public instance method" do
127
- # FIXME
128
- end
129
-
130
- it "should be able to perform #* with nonnumerics in the matrix" do
131
- # FIXME
132
- end
133
-
134
- it "should numeric matrix multiplication still be working normally" do
135
- # FIXME
136
- end
137
- end # context Matrix
138
- end
@@ -1,23 +0,0 @@
1
- #! /usr/bin/ruby
2
-
3
- require 'minitest/autorun'
4
- require 'minitest/benchmark'
5
-
6
- class TestCoreMethods < Minitest::Benchmark
7
- def setup
8
- @arrays = ( 1 .. 11_000 ).map { |n| [ 42 ] * n }
9
- end
10
-
11
- # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]
12
- def bench_size
13
- assert_performance_linear 0.99 do |n| ( [ 0 ] * n ).reduce :+ end
14
- assert_performance_constant 0.99 do |n| 42.times { 42 } end
15
- # assert_performance_linear 0.99 do |n| @arrays[ n ].size end
16
- assert_performance_constant 0.99 do |n| @arrays[ n ].size end
17
- # TODO: For some reason, assert_performance_constant doesn't fail even if
18
- # I artificially introduce eg. quadratic algorithm. All the while, the
19
- # line assert_performance_linear does fail if uncommented (since the perf.
20
- # here is constant).
21
- # TODO: In other words, I'm not very experienced in performance testing yet.
22
- end
23
- end
data/test/try_test.rb DELETED
@@ -1,102 +0,0 @@
1
- #! /usr/bin/ruby
2
-
3
- require 'minitest/autorun'
4
- # require 'y_support/try' # tested component itself
5
- require './../lib/y_support/try'
6
-
7
- describe Consciously do
8
- before do
9
- @try = Consciously::Try.new object: "Dummy", text: "to fire" do
10
- note is: "dummy"
11
- note has: "no care in the world"
12
- n = note "its number", is: 42
13
- raise TypeError, 'foo'
14
- end
15
- end
16
-
17
- it "should have basic functionality" do
18
- assert_equal "to fire", @try.__txt__
19
- assert_equal "Dummy", @try.__obj__
20
- assert_equal 0, @try.__facts__.size # haven't tried anything yet
21
- @try.__facts__["something"]
22
- assert_equal 1, @try.__facts__.size
23
- @try.note is: 'dummy'
24
- @try.note has: 'no care in the world'
25
- assert_equal 2, @try.__facts__.size
26
- assert_equal ["something", "Dummy"], @try.__facts__.keys
27
- assert_equal( [ { is: "dummy", has: "no care in the world" } ],
28
- @try.__facts__["Dummy"] )
29
- assert_equal " hello!", Consciously::Try::DECORATE.( :hello, prefix: ' ', postfix: '!' )
30
- assert_equal( ['Dummy', {is: 'dummy', has: 'no care in the world'}],
31
- @try.__describe__( "Dummy" ) )
32
- end
33
-
34
- describe 'case 1' do
35
- it "should work" do
36
- begin
37
- @try.__invoke__
38
- rescue TypeError => err
39
- expected_msg = "When trying to fire Dummy (dummy, has no care in " +
40
- "the world), its number being 42, TypeError occurred: foo"
41
- assert_equal expected_msg, err.message
42
- else
43
- flunk "Expected TypeError error not raised!"
44
- end
45
- end
46
- end
47
-
48
- describe 'case 2' do
49
- it "should work" do
50
- begin
51
- try "to call constant Nonexistant" do Nonexistant end
52
- rescue NameError => err
53
- expected_msg = 'When trying to call constant Nonexistant, ' +
54
- 'NameError occurred: uninitialized constant Nonexistant'
55
- assert_equal( expected_msg, err.message )
56
- else
57
- flunk "Expected NameError error not raised!"
58
- end
59
- end
60
- end
61
-
62
- describe 'case 3' do
63
- it "should work" do
64
- o = Object.new
65
- class << o
66
- def to_s; "THIS OBJECT" end
67
- def hello!; "hello hello" end
68
- end
69
- # Object's methods must be callable
70
- o.try "to say hello" do hello! end.must_equal "hello hello"
71
- begin
72
- o.try "to call a weird method" do goodbye! end
73
- rescue NoMethodError => err
74
- err.message.must_include "When trying to call a weird method, " +
75
- "NoMethodError occurred: undefined method"
76
- err.message.must_include "goodbye!"
77
- end
78
- end
79
- end
80
-
81
- describe 'case 4' do
82
- it "should work" do
83
- begin
84
- "FooBar".try "to do something" do
85
- note has: "#{size} letters", is: "a #{self.class} instance"
86
- unless include? "Quux"
87
- note "Quux", is: "not a part of it"
88
- try "to append Quux to it" do
89
- self << "Quux"
90
- fail "EPIC FAIL"
91
- end
92
- end
93
- end
94
- rescue => err
95
- err.message.must_equal 'When trying to do something, FooBar having ' +
96
- '6 letters, being a String instance, Quux being not a part of it, ' +
97
- 'RuntimeError occurred: When trying to append Quux to it, ' +
98
- 'RuntimeError occurred: EPIC FAIL'
99
- end
100
- end
101
- end
102
- end