golly-utils 0.0.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.corvid/Gemfile +28 -0
- data/.corvid/features.yml +4 -0
- data/.corvid/plugins.yml +4 -0
- data/.corvid/stats_cfg.rb +13 -0
- data/.corvid/todo_cfg.rb +15 -0
- data/.corvid/versions.yml +2 -0
- data/.simplecov +6 -3
- data/CHANGELOG.md +45 -2
- data/Gemfile +6 -3
- data/Gemfile.lock +34 -37
- data/Guardfile +10 -4
- data/RELEASE.md +2 -0
- data/Rakefile +1 -1
- data/golly-utils.gemspec +19 -10
- data/lib/golly-utils/attr_declarative.rb +120 -49
- data/lib/golly-utils/callbacks.rb +211 -19
- data/lib/golly-utils/child_process.rb +28 -8
- data/lib/golly-utils/delegator.rb +14 -3
- data/lib/golly-utils/ruby_ext/classes_and_types.rb +120 -0
- data/lib/golly-utils/ruby_ext/enumerable.rb +16 -0
- data/lib/golly-utils/ruby_ext/env_helpers.rb +17 -0
- data/lib/golly-utils/ruby_ext/kernel.rb +18 -0
- data/lib/golly-utils/ruby_ext/options.rb +28 -0
- data/lib/golly-utils/ruby_ext/pretty_error_messages.rb +1 -1
- data/lib/golly-utils/singleton.rb +130 -0
- data/lib/golly-utils/testing/dynamic_fixtures.rb +268 -0
- data/lib/golly-utils/testing/file_helpers.rb +117 -0
- data/lib/golly-utils/testing/helpers_base.rb +20 -0
- data/lib/golly-utils/testing/rspec/arrays.rb +85 -0
- data/lib/golly-utils/testing/rspec/base.rb +9 -0
- data/lib/golly-utils/testing/rspec/deferrable_specs.rb +111 -0
- data/lib/golly-utils/testing/rspec/files.rb +262 -0
- data/lib/golly-utils/{test/spec → testing/rspec}/within_time.rb +17 -7
- data/lib/golly-utils/version.rb +2 -1
- data/test/bootstrap/all.rb +8 -1
- data/test/bootstrap/spec.rb +1 -1
- data/test/bootstrap/unit.rb +1 -1
- data/test/spec/child_process_spec.rb +1 -1
- data/test/spec/testing/dynamic_fixtures_spec.rb +131 -0
- data/test/spec/testing/rspec/arrays_spec.rb +33 -0
- data/test/spec/testing/rspec/files_spec.rb +300 -0
- data/test/unit/attr_declarative_test.rb +79 -13
- data/test/unit/callbacks_test.rb +103 -5
- data/test/unit/delegator_test.rb +25 -1
- data/test/unit/ruby_ext/classes_and_types_test.rb +103 -0
- data/test/unit/ruby_ext/enumerable_test.rb +12 -0
- data/test/unit/ruby_ext/options_test.rb +29 -0
- data/test/unit/singleton_test.rb +59 -0
- metadata +100 -10
- data/Gemfile.corvid +0 -27
- data/lib/golly-utils/ruby_ext.rb +0 -2
- data/lib/golly-utils/ruby_ext/subclasses.rb +0 -17
- data/lib/golly-utils/test/spec/deferrable_specs.rb +0 -85
- data/test/unit/ruby_ext/subclasses_test.rb +0 -24
@@ -5,32 +5,63 @@ require 'golly-utils/attr_declarative'
|
|
5
5
|
class AttrDeclarativeTest < MiniTest::Unit::TestCase
|
6
6
|
|
7
7
|
class Abc
|
8
|
-
include GollyUtils::AttrDeclarative
|
9
8
|
attr_declarative :cow
|
10
|
-
attr_declarative :horse, default: 246
|
9
|
+
attr_declarative :horse, :horse2, default: 246
|
10
|
+
attr_declarative :important, required: true
|
11
|
+
attr_declarative :boolean_style?
|
12
|
+
attr_declarative :bang_style!
|
11
13
|
end
|
12
14
|
|
13
15
|
def test_acts_like_attribute
|
14
16
|
a= Abc.new
|
15
17
|
assert_nil a.cow
|
16
|
-
a.cow
|
18
|
+
a.cow= 12
|
17
19
|
assert_equal 12, a.cow
|
18
20
|
end
|
19
21
|
|
20
22
|
def test_default
|
21
23
|
a= Abc.new
|
22
24
|
assert_equal 246, a.horse
|
23
|
-
a.
|
25
|
+
assert_equal 246, a.horse2
|
26
|
+
a.horse= 'hehe'
|
24
27
|
assert_equal 'hehe', a.horse
|
28
|
+
assert_equal 246, a.horse2
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_boolean_style_attribute
|
32
|
+
a= Abc.new
|
33
|
+
a.boolean_style= true
|
34
|
+
assert_equal true, a.boolean_style?
|
35
|
+
a.boolean_style= false
|
36
|
+
assert_equal false, a.boolean_style?
|
37
|
+
refute a.respond_to? :boolean_style # reader has ?, writer has =
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_bang_style_attribute
|
41
|
+
a= Abc.new
|
42
|
+
a.bang_style= 123
|
43
|
+
assert_equal 123, a.bang_style!
|
44
|
+
refute a.respond_to? :bang_style # reader has !, writer has =
|
45
|
+
end
|
46
|
+
|
47
|
+
class SpecialNames < Abc
|
48
|
+
boolean_style? true
|
49
|
+
bang_style! 987
|
50
|
+
end
|
51
|
+
def test_boolean_style_declared_at_class_level
|
52
|
+
assert_equal true, SpecialNames.new.boolean_style?
|
53
|
+
end
|
54
|
+
def test_bang_style_declared_at_class_level
|
55
|
+
assert_equal 987, SpecialNames.new.bang_style!
|
25
56
|
end
|
26
57
|
|
27
58
|
class Abc2 < Abc
|
28
|
-
cow
|
59
|
+
cow 777
|
29
60
|
end
|
30
61
|
def test_subclasses_can_change_defaults
|
31
62
|
a= Abc2.new
|
32
63
|
assert_equal 777, a.cow
|
33
|
-
a.cow
|
64
|
+
a.cow= 12
|
34
65
|
assert_equal 12, a.cow
|
35
66
|
assert_equal 777, Abc2.new.cow
|
36
67
|
assert_nil Abc.new.cow
|
@@ -39,16 +70,51 @@ class AttrDeclarativeTest < MiniTest::Unit::TestCase
|
|
39
70
|
class Abc3 < Abc2; end
|
40
71
|
def test_subclasses_inherit_parents_declarations
|
41
72
|
assert_equal 777, Abc3.new.cow
|
73
|
+
assert_nil Abc.new.cow
|
42
74
|
end
|
43
75
|
|
44
|
-
|
45
|
-
|
46
|
-
|
76
|
+
def test_instances_setting_to_nil
|
77
|
+
assert_nil Abc.new.tap{|x| x.cow= nil}.cow
|
78
|
+
assert_nil Abc2.new.tap{|x| x.cow= nil}.cow
|
79
|
+
assert_nil Abc3.new.tap{|x| x.cow= nil}.cow
|
47
80
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
81
|
+
|
82
|
+
class Abc4 < Abc
|
83
|
+
cow nil
|
84
|
+
important 666
|
85
|
+
end
|
86
|
+
def test_subclass_with_nil_default
|
87
|
+
assert_nil Abc.new.cow
|
88
|
+
assert_equal 777, Abc3.new.cow
|
89
|
+
assert_nil Abc4.new.cow
|
90
|
+
end
|
91
|
+
|
92
|
+
class Seikima
|
93
|
+
attr_declarative ok: 'sweet'
|
94
|
+
end
|
95
|
+
def test_quik_syntax
|
96
|
+
assert_equal 'sweet', Seikima.new.ok
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_required_fields_fail_when_undefined
|
100
|
+
e= assert_raises(RuntimeError){ Abc.new.important }
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_error_msg_when_required_field_missing_mentions_subclass_name
|
104
|
+
e= assert_raises(RuntimeError){ Abc2.new.important }
|
105
|
+
assert_match /Abc2/, e.message
|
52
106
|
end
|
53
107
|
|
108
|
+
def test_required_fields_works_as_normal_once_defined
|
109
|
+
assert_equal 666, Abc4.new.important
|
110
|
+
x= Abc.new
|
111
|
+
x.important= 135
|
112
|
+
assert_equal 135, x.important
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_required_fields_can_be_set_to_nil
|
116
|
+
x= Abc.new
|
117
|
+
x.important= nil
|
118
|
+
assert_nil x.important
|
119
|
+
end
|
54
120
|
end
|
data/test/unit/callbacks_test.rb
CHANGED
@@ -14,18 +14,16 @@ class CallbacksTest < MiniTest::Unit::TestCase
|
|
14
14
|
include GollyUtils::Callbacks
|
15
15
|
define_callback :base
|
16
16
|
def self.record(v); CallbacksTest::VALUES << v end
|
17
|
-
def self.run
|
17
|
+
def self.run(*args)
|
18
18
|
o= self.new
|
19
|
-
o.run
|
19
|
+
o.run(*args)
|
20
20
|
CallbacksTest::VALUES
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
class Omg < Base
|
25
25
|
define_callback :wow
|
26
|
-
def run
|
27
|
-
run_callback :wow
|
28
|
-
end
|
26
|
+
def run; run_callback :wow end
|
29
27
|
end
|
30
28
|
def test_none; assert_equal [], Omg.run; end
|
31
29
|
|
@@ -73,4 +71,104 @@ class CallbacksTest < MiniTest::Unit::TestCase
|
|
73
71
|
assert_equal 135, Fail.what
|
74
72
|
end
|
75
73
|
|
74
|
+
class Args < Base
|
75
|
+
base{ |i| record (i || 0)+5 }
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_run_callback_with_args
|
79
|
+
Args.new.run_callback :base, args: [4]
|
80
|
+
assert_equal [9], VALUES
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_run_callbacks_with_args_array
|
84
|
+
Args.new.run_callbacks :base, args: [3]
|
85
|
+
assert_equal [8], VALUES
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_run_callbacks_with_args_nonarray
|
89
|
+
Args.new.run_callbacks :base, args: 13
|
90
|
+
flunk "Failure expected."
|
91
|
+
rescue => e
|
92
|
+
assert_match /array/i, e.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_run_callback_fails_with_unrecognisable_options
|
96
|
+
Args.new.run_callback :base, stuff: [3]
|
97
|
+
flunk "Failure expected."
|
98
|
+
rescue => e
|
99
|
+
assert_match /stuff/, e.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_run_callbacks_fails_with_unrecognisable_options
|
103
|
+
Args.new.run_callbacks :base, stuff: [3]
|
104
|
+
flunk "Failure expected."
|
105
|
+
rescue => e
|
106
|
+
assert_match /stuff/, e.to_s
|
107
|
+
end
|
108
|
+
|
109
|
+
module TestModule
|
110
|
+
include GollyUtils::Callbacks
|
111
|
+
define_callback :from_mod
|
112
|
+
end
|
113
|
+
|
114
|
+
module TestModule2
|
115
|
+
include TestModule
|
116
|
+
define_callback :from_mod2
|
117
|
+
end
|
118
|
+
|
119
|
+
class WithMod
|
120
|
+
include TestModule
|
121
|
+
define_callback :bru
|
122
|
+
def self.record(v); CallbacksTest::VALUES << v end
|
123
|
+
def self.run(*args)
|
124
|
+
o= self.new
|
125
|
+
o.run_callback :from_mod
|
126
|
+
CallbacksTest::VALUES
|
127
|
+
end
|
128
|
+
from_mod{ record 357 }
|
129
|
+
end
|
130
|
+
def test_with_module; assert_equal [357], WithMod.run; end
|
131
|
+
|
132
|
+
def test_callbacks_class_method
|
133
|
+
assert_equal [:base], Base.callbacks
|
134
|
+
assert_equal [:base, :wow], Omg.callbacks
|
135
|
+
assert_equal [:base, :wow], Omg2.callbacks
|
136
|
+
assert_equal [:base, :dude, :sweet, :wow], Sweet.callbacks
|
137
|
+
end
|
138
|
+
def test_callbacks_module_method
|
139
|
+
assert_equal [:from_mod], TestModule.callbacks
|
140
|
+
assert_equal [:from_mod, :from_mod2], TestModule2.callbacks
|
141
|
+
end
|
142
|
+
def test_callbacks_class_with_module
|
143
|
+
assert_equal [:bru, :from_mod], WithMod.callbacks
|
144
|
+
end
|
145
|
+
|
146
|
+
class Context
|
147
|
+
attr_reader :good
|
148
|
+
def make_good; @good= 'good' end
|
149
|
+
end
|
150
|
+
class ContextCallback
|
151
|
+
include GollyUtils::Callbacks
|
152
|
+
define_callback :go
|
153
|
+
go { make_good }
|
154
|
+
end
|
155
|
+
def test_callback_with_context
|
156
|
+
ctx= Context.new
|
157
|
+
cc= ContextCallback.new
|
158
|
+
cc.run_callback :go, context: ctx
|
159
|
+
assert_equal 'good', ctx.good
|
160
|
+
end
|
161
|
+
|
162
|
+
class ContextCallback2 < ContextCallback
|
163
|
+
attr_reader :local_too
|
164
|
+
def hit_local_too; @local_too= 'yes' end
|
165
|
+
go { hit_local_too }
|
166
|
+
end
|
167
|
+
def test_callback_with_context_can_access_local_too
|
168
|
+
ctx= Context.new
|
169
|
+
cc= ContextCallback2.new
|
170
|
+
cc.run_callback :go, context: ctx
|
171
|
+
assert_equal 'good', ctx.good
|
172
|
+
assert_equal 'yes', cc.local_too
|
173
|
+
end
|
76
174
|
end
|
data/test/unit/delegator_test.rb
CHANGED
@@ -8,6 +8,10 @@ class DelegatorTest < MiniTest::Unit::TestCase
|
|
8
8
|
def a; 1; end
|
9
9
|
def c; 10; end
|
10
10
|
def add(a,b,c) a+b+c end
|
11
|
+
protected
|
12
|
+
def prot; 666; end
|
13
|
+
private
|
14
|
+
def pri; -1; end
|
11
15
|
end
|
12
16
|
|
13
17
|
class B
|
@@ -37,7 +41,7 @@ class DelegatorTest < MiniTest::Unit::TestCase
|
|
37
41
|
assert_equal [10,20], nd(na,nb,delegate_to: :all).c
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
44
|
+
def test_respond_to_checks_delegatable
|
41
45
|
d= nd(na,nb)
|
42
46
|
assert d.respond_to?(:a)
|
43
47
|
assert d.respond_to?(:b)
|
@@ -45,6 +49,13 @@ class DelegatorTest < MiniTest::Unit::TestCase
|
|
45
49
|
assert !d.respond_to?(:x)
|
46
50
|
end
|
47
51
|
|
52
|
+
def test_respond_to_checks_internal
|
53
|
+
d= nd(na,nb)
|
54
|
+
refute d.respond_to?(:xxx)
|
55
|
+
d.instance_eval 'def xxx; end'
|
56
|
+
assert d.respond_to?(:xxx)
|
57
|
+
end
|
58
|
+
|
48
59
|
def test_caching
|
49
60
|
[true,false].each do |cache|
|
50
61
|
a= na
|
@@ -96,4 +107,17 @@ class DelegatorTest < MiniTest::Unit::TestCase
|
|
96
107
|
assert_raises(NoMethodError){ d.b }
|
97
108
|
assert_raises(NoMethodError){ d.add }
|
98
109
|
end
|
110
|
+
|
111
|
+
def test_protected_methods_not_allowed_by_default
|
112
|
+
assert_raises(NoMethodError){ nd(na).prot }
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_protected_methods_allowed_when_enabled
|
116
|
+
assert_equal 666, nd(na, allow_protected: true).prot
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_private_methods_not_allowed
|
120
|
+
assert_raises(NoMethodError){ nd(na).pri }
|
121
|
+
assert_raises(NoMethodError){ nd(na, allow_protected: true).pri }
|
122
|
+
end
|
99
123
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative '../../bootstrap/unit'
|
3
|
+
require 'golly-utils/ruby_ext/classes_and_types'
|
4
|
+
|
5
|
+
class ClassesAndTypesTest < MiniTest::Unit::TestCase
|
6
|
+
class A; end
|
7
|
+
class B < A; end
|
8
|
+
class C < A; end
|
9
|
+
class B1 < B; end
|
10
|
+
class B2 < B; end
|
11
|
+
|
12
|
+
def assert_arrays(exp,act)
|
13
|
+
v= [exp,act].map{|a| a.sort_by(&:to_s) }
|
14
|
+
assert_equal *v
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_subclasses_all
|
18
|
+
assert_arrays [B,C,B1,B2], A.subclasses(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_subclasses_leaf_nodes_only
|
22
|
+
assert_arrays [C,B1,B2], A.subclasses
|
23
|
+
end
|
24
|
+
|
25
|
+
#---------------------------------------------------------------------------------------------------------------------
|
26
|
+
|
27
|
+
def test_superclasses_on_instance
|
28
|
+
assert_equal [B1,B,A,Object,BasicObject], B1.new.superclasses
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_superclasses_on_class
|
32
|
+
assert_equal [B1,B,A,Object,BasicObject], B1.superclasses
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_superclasses_on_ruby_internals
|
36
|
+
assert_equal [NilClass,Object,BasicObject], nil.superclasses
|
37
|
+
assert_equal [TrueClass,Object,BasicObject], true.superclasses
|
38
|
+
end
|
39
|
+
|
40
|
+
class BO < BasicObject; end
|
41
|
+
def test_superclasses_on_basic_object_subclass
|
42
|
+
assert_equal [BO,BasicObject], BO.superclasses
|
43
|
+
#assert_equal [BO,BasicObject], BO.new.superclasses
|
44
|
+
end
|
45
|
+
|
46
|
+
#---------------------------------------------------------------------------------------------------------------------
|
47
|
+
|
48
|
+
def test_validate_type_passes_when_exact_match
|
49
|
+
B.new.validate_type! B
|
50
|
+
B.new.validate_type! A
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_validate_type_passes_with_name
|
54
|
+
B.new.validate_type! 'hehe', B
|
55
|
+
B.new.validate_type! :hehe, A
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_validate_type_passes_when_any_match
|
59
|
+
B.new.validate_type! B, String
|
60
|
+
B.new.validate_type! String, A
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_validate_type_allows_primatives
|
64
|
+
true.validate_type! true
|
65
|
+
false.validate_type! false
|
66
|
+
nil.validate_type! nil
|
67
|
+
nil.validate_type! NilClass
|
68
|
+
nil.validate_type! nil, B
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_validate_type_fail
|
72
|
+
assert_raises(TypeValidationError){ B.new.validate_type! String }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_validate_type_fail_with_name
|
76
|
+
assert_raises(TypeValidationError){ B.new.validate_type! 'hehe', String }
|
77
|
+
assert_raises(TypeValidationError){ B.new.validate_type! :hehe, String }
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_validate_type_fail_uses_name_in_errmsg
|
81
|
+
3.validate_type! 'hehe', String
|
82
|
+
raise "Error expected."
|
83
|
+
rescue => e
|
84
|
+
assert_match /for hehe/, e.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
#---------------------------------------------------------------------------------------------------------------------
|
88
|
+
|
89
|
+
def test_validate_lvar_type!
|
90
|
+
hehe= 123
|
91
|
+
:hehe.validate_lvar_type!{ Fixnum }
|
92
|
+
:hehe.validate_lvar_type!{ [nil,Fixnum] }
|
93
|
+
assert_raises(TypeValidationError){ :hehe.validate_lvar_type!{ String }}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_validate_lvar_type_uses_name_in_errmsg
|
97
|
+
hehe= 'no'
|
98
|
+
:hehe.validate_lvar_type!{ Fixnum }
|
99
|
+
raise "Error expected."
|
100
|
+
rescue => e
|
101
|
+
assert_match /for hehe/, e.to_s
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative '../../bootstrap/unit'
|
3
|
+
require 'golly-utils/ruby_ext/enumerable'
|
4
|
+
|
5
|
+
class EnumerableTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_frequency_map
|
8
|
+
x= [1, 4, 'a', 4, :b, :b, :b].frequency_map
|
9
|
+
assert_equal({1=>1, 4=>2, 'a'=>1, b:3}, x)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative '../../bootstrap/unit'
|
3
|
+
require 'golly-utils/ruby_ext/options'
|
4
|
+
|
5
|
+
class OptionsTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_nop_when_all_keys_valid
|
8
|
+
{a:1,b:2}.validate_option_keys :a, :b
|
9
|
+
{a:1,b:2}.validate_option_keys :a, :b, :c
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_nop_when_hash_empty
|
13
|
+
{}.validate_option_keys :a, :b
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_error_when_extra_keys
|
17
|
+
assert_raises(RuntimeError){ {a:1,b:2}.validate_option_keys :a }
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_error_msg_contains_all_invalid_key_names
|
21
|
+
{aaa:1,'bbb' => 2, x:5}.validate_option_keys :x
|
22
|
+
flunk 'Error expected.'
|
23
|
+
rescue => e
|
24
|
+
assert_match /:aaa/, e.to_s
|
25
|
+
assert_match /"bbb"/, e.to_s
|
26
|
+
refute_match /x/, e.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|