golly-utils 0.0.1 → 0.6.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.
- 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
|