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.
Files changed (54) hide show
  1. data/.corvid/Gemfile +28 -0
  2. data/.corvid/features.yml +4 -0
  3. data/.corvid/plugins.yml +4 -0
  4. data/.corvid/stats_cfg.rb +13 -0
  5. data/.corvid/todo_cfg.rb +15 -0
  6. data/.corvid/versions.yml +2 -0
  7. data/.simplecov +6 -3
  8. data/CHANGELOG.md +45 -2
  9. data/Gemfile +6 -3
  10. data/Gemfile.lock +34 -37
  11. data/Guardfile +10 -4
  12. data/RELEASE.md +2 -0
  13. data/Rakefile +1 -1
  14. data/golly-utils.gemspec +19 -10
  15. data/lib/golly-utils/attr_declarative.rb +120 -49
  16. data/lib/golly-utils/callbacks.rb +211 -19
  17. data/lib/golly-utils/child_process.rb +28 -8
  18. data/lib/golly-utils/delegator.rb +14 -3
  19. data/lib/golly-utils/ruby_ext/classes_and_types.rb +120 -0
  20. data/lib/golly-utils/ruby_ext/enumerable.rb +16 -0
  21. data/lib/golly-utils/ruby_ext/env_helpers.rb +17 -0
  22. data/lib/golly-utils/ruby_ext/kernel.rb +18 -0
  23. data/lib/golly-utils/ruby_ext/options.rb +28 -0
  24. data/lib/golly-utils/ruby_ext/pretty_error_messages.rb +1 -1
  25. data/lib/golly-utils/singleton.rb +130 -0
  26. data/lib/golly-utils/testing/dynamic_fixtures.rb +268 -0
  27. data/lib/golly-utils/testing/file_helpers.rb +117 -0
  28. data/lib/golly-utils/testing/helpers_base.rb +20 -0
  29. data/lib/golly-utils/testing/rspec/arrays.rb +85 -0
  30. data/lib/golly-utils/testing/rspec/base.rb +9 -0
  31. data/lib/golly-utils/testing/rspec/deferrable_specs.rb +111 -0
  32. data/lib/golly-utils/testing/rspec/files.rb +262 -0
  33. data/lib/golly-utils/{test/spec → testing/rspec}/within_time.rb +17 -7
  34. data/lib/golly-utils/version.rb +2 -1
  35. data/test/bootstrap/all.rb +8 -1
  36. data/test/bootstrap/spec.rb +1 -1
  37. data/test/bootstrap/unit.rb +1 -1
  38. data/test/spec/child_process_spec.rb +1 -1
  39. data/test/spec/testing/dynamic_fixtures_spec.rb +131 -0
  40. data/test/spec/testing/rspec/arrays_spec.rb +33 -0
  41. data/test/spec/testing/rspec/files_spec.rb +300 -0
  42. data/test/unit/attr_declarative_test.rb +79 -13
  43. data/test/unit/callbacks_test.rb +103 -5
  44. data/test/unit/delegator_test.rb +25 -1
  45. data/test/unit/ruby_ext/classes_and_types_test.rb +103 -0
  46. data/test/unit/ruby_ext/enumerable_test.rb +12 -0
  47. data/test/unit/ruby_ext/options_test.rb +29 -0
  48. data/test/unit/singleton_test.rb +59 -0
  49. metadata +100 -10
  50. data/Gemfile.corvid +0 -27
  51. data/lib/golly-utils/ruby_ext.rb +0 -2
  52. data/lib/golly-utils/ruby_ext/subclasses.rb +0 -17
  53. data/lib/golly-utils/test/spec/deferrable_specs.rb +0 -85
  54. 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{ 12 }
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.horse{ 'hehe' }
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{ 777 }
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{ 12 }
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
- class Dynamic < Abc
45
- $cow= 123
46
- cow{ $cow }
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
- def test_class_declarations_arent_evaluated_until_needed
49
- a= Dynamic.new
50
- $cow= 456
51
- assert_equal 456, a.cow
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
@@ -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
@@ -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 test_respond_to
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