striuct 0.3.5.1 → 0.4.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.
Files changed (92) hide show
  1. data/.travis.yml +3 -0
  2. data/.yardopts +1 -1
  3. data/LICENSE +1 -1
  4. data/README.md +7 -3
  5. data/example/example1.rb +5 -4
  6. data/lib/striuct/classmethods/README.md +9 -4
  7. data/lib/striuct/classmethods/adjustment.rb +4 -15
  8. data/lib/striuct/{attributes.rb → classmethods/attributes.rb} +15 -17
  9. data/lib/striuct/classmethods/{prevent_conflicts.rb → conflict_management.rb} +37 -14
  10. data/lib/striuct/classmethods/constructor.rb +2 -4
  11. data/lib/striuct/classmethods/copy.rb +2 -2
  12. data/lib/striuct/classmethods/default.rb +9 -18
  13. data/lib/striuct/classmethods/enum.rb +3 -5
  14. data/lib/striuct/classmethods/inner.rb +6 -10
  15. data/lib/striuct/classmethods/macro.rb +33 -48
  16. data/lib/striuct/classmethods/names.rb +75 -0
  17. data/lib/striuct/classmethods/predicate.rb +128 -0
  18. data/lib/striuct/classmethods/{requiremnets.rb → requirements.rb} +6 -3
  19. data/lib/striuct/classmethods/validation.rb +5 -43
  20. data/lib/striuct/instancemethods/README.md +4 -4
  21. data/lib/striuct/instancemethods/assign.rb +11 -13
  22. data/lib/striuct/instancemethods/cast.rb +5 -8
  23. data/lib/striuct/instancemethods/compare.rb +6 -6
  24. data/lib/striuct/instancemethods/default.rb +28 -6
  25. data/lib/striuct/instancemethods/delegate_class_methods.rb +21 -21
  26. data/lib/striuct/instancemethods/enum.rb +3 -9
  27. data/lib/striuct/instancemethods/getter.rb +47 -0
  28. data/lib/striuct/instancemethods/hashy.rb +2 -6
  29. data/lib/striuct/instancemethods/keyvalidatable.rb +0 -5
  30. data/lib/striuct/instancemethods/lock.rb +35 -43
  31. data/lib/striuct/instancemethods/object.rb +3 -26
  32. data/lib/striuct/instancemethods/requirements.rb +16 -2
  33. data/lib/striuct/instancemethods/safety.rb +1 -1
  34. data/lib/striuct/instancemethods/setter.rb +58 -0
  35. data/lib/striuct/instancemethods/to_s.rb +2 -2
  36. data/lib/striuct/instancemethods/validation.rb +13 -7
  37. data/lib/striuct/instancemethods/values.rb +8 -7
  38. data/lib/striuct/requirements.rb +2 -5
  39. data/lib/striuct/{hashdeepdupulicatable.rb → singleton_class/hashdeepdupulicatable.rb} +2 -2
  40. data/lib/striuct/singleton_class.rb +3 -4
  41. data/striuct.gemspec +7 -4
  42. data/test/test_sglc-constructor.rb +36 -0
  43. data/test/test_subc-c-constructor.rb +88 -0
  44. data/test/{test_striuct-subclass-class-safety_naming.rb → test_subc-c-safety_naming.rb} +6 -5
  45. data/test/test_subc-f-enum.rb +139 -0
  46. data/test/test_subc-f-predicate.rb +647 -0
  47. data/test/{test_striuct-subclass-feature-validation_util.rb → test_subc-f-validation_util.rb} +10 -8
  48. data/test/test_subc-f_name.rb +525 -0
  49. data/test/{test_striuct-subclass-instance-accessor.rb → test_subc-i-accessor.rb} +3 -2
  50. data/test/test_subc-i-assign.rb +49 -0
  51. data/test/test_subc-i-cast.rb +27 -0
  52. data/test/{test_striuct-subclass-instance-default_value.rb → test_subc-i-default_value.rb} +2 -2
  53. data/test/{test_striuct-subclass-instance-hashlike.rb → test_subc-i-hashlike.rb} +0 -9
  54. data/test/{test_striuct-subclass-instance-lock.rb → test_subc-i-lock.rb} +8 -8
  55. data/test/{test_striuct-subclass-instance-to_s_family.rb → test_subc-i-to_s_family.rb} +1 -1
  56. data/test/{test_striuct-subclass-instance-validation_specific_conditions.rb → test_subc-i-validation_specific_conditions.rb} +50 -0
  57. data/test/test_version.rb +14 -0
  58. metadata +124 -80
  59. data/Manifest.txt +0 -97
  60. data/README.ja.old.rdoc +0 -298
  61. data/example/example.old.rdoc +0 -188
  62. data/lib/striuct/classmethods/hashy.rb +0 -22
  63. data/lib/striuct/classmethods/named.rb +0 -126
  64. data/lib/striuct/classmethods.rb +0 -1
  65. data/lib/striuct/instancemethods/inner_accessor.rb +0 -53
  66. data/lib/striuct/instancemethods/subscript.rb +0 -27
  67. data/lib/striuct/instancemethods.rb +0 -1
  68. data/lib/striuct/version.rb +0 -5
  69. data/test/test_striuct-singleton_class-define.rb +0 -19
  70. data/test/test_striuct-subclass-class-constructor.rb +0 -82
  71. data/test/test_striuct-subclass-class-validation.rb +0 -26
  72. data/test/test_striuct-subclass-instance-assign.rb +0 -30
  73. data/test/test_striuct-subclass-instance-enum.rb +0 -93
  74. data/test/test_striuct-subclass-instance-validation_functional_condition.rb +0 -51
  75. data/test/test_striuct-subclass-instance_names.rb +0 -18
  76. data/test/test_striuct-version.rb +0 -11
  77. /data/{History.rdoc → History.old(~0.3.n).rdoc} +0 -0
  78. /data/test/{test_striuct-subclass-class-macro.rb → test_subc-c-add_members.rb} +0 -0
  79. /data/test/{test_striuct-subclass-class-close.rb → test_subc-c-close_member.rb} +0 -0
  80. /data/test/{test_striuct-subclass-class-copy.rb → test_subc-c-copy.rb} +0 -0
  81. /data/test/{test_striuct-subclass-class-freeze.rb → test_subc-c-freeze.rb} +0 -0
  82. /data/test/{test_striuct-subclass-class-inheritable.rb → test_subc-c-inheritable.rb} +0 -0
  83. /data/test/{test_striuct-subclass-feature-alias_member.rb → test_subc-f-alias_member.rb} +0 -0
  84. /data/test/{test_striuct-subclass-feature-to_struct.rb → test_subc-f-to_struct.rb} +0 -0
  85. /data/test/{test_striuct-subclass-instance-adjuster.rb → test_subc-i-adjuster.rb} +0 -0
  86. /data/test/{test_striuct-subclass-instance-basic.rb → test_subc-i-basic.rb} +0 -0
  87. /data/test/{test_striuct-subclass-instance-compare.rb → test_subc-i-compare.rb} +0 -0
  88. /data/test/{test_striuct-subclass-instance-copy.rb → test_subc-i-copy.rb} +0 -0
  89. /data/test/{test_striuct-subclass-instance-freeze.rb → test_subc-i-freeze.rb} +0 -0
  90. /data/test/{test_striuct-subclass-instance-keyvalidatable.rb → test_subc-i-keyvalidatable.rb} +0 -0
  91. /data/test/{test_striuct-subclass-instance-validation_inference.rb → test_subc-i-validation_inference.rb} +0 -0
  92. /data/test/{test_striuct-subclass-instance-validation_with_getter.rb → test_subc-i-validation_with_getter.rb} +0 -0
@@ -5,13 +5,13 @@ class Striuct; module InstanceMethods
5
5
  def initialize(*values)
6
6
  @db, @locks = {}, {}
7
7
  replace_values(*values)
8
- excess = _autonyms.last(size - values.size)
9
- set_defaults(*excess)
8
+ excess_autonyms = _autonyms.last(size - values.size)
9
+ _set_defaults(*excess_autonyms)
10
10
  end
11
11
 
12
12
  # @return [self]
13
13
  def freeze
14
- [@db, @locks].each(&:freeze)
14
+ @db.freeze; @locks.freeze
15
15
  super
16
16
  end
17
17
 
@@ -23,27 +23,4 @@ class Striuct; module InstanceMethods
23
23
 
24
24
  # @endgroup
25
25
 
26
- # @group Default Value
27
-
28
- # @return [self]
29
- def set_defaults(*target_autonyms)
30
- target_autonyms.each do |autonym|
31
- if has_default? autonym
32
- default = default_value_for autonym
33
- self[autonym] = (
34
- if default_type_for(autonym) == :lazy
35
- args = [self, autonym][0, default.arity]
36
- default.call(*args)
37
- else
38
- default
39
- end
40
- )
41
- end
42
- end
43
-
44
- self
45
- end
46
-
47
- # @endgroup
48
-
49
26
  end; end
@@ -1,6 +1,19 @@
1
+ require 'forwardable'
2
+ require 'keyvalidatable'
3
+
4
+ class Striuct; module InstanceMethods
5
+
6
+ extend Forwardable
7
+
8
+ # hide Forwardable's public/protected class_macro
9
+ private_class_method(*Forwardable.instance_methods)
10
+
11
+ include KeyValidatable
12
+
13
+ end; end
14
+
1
15
  require_relative 'delegate_class_methods'
2
16
  require_relative 'keyvalidatable'
3
- require_relative 'inner_accessor'
4
17
  require_relative 'object'
5
18
  require_relative 'compare'
6
19
  require_relative 'to_s'
@@ -9,7 +22,8 @@ require_relative 'cast'
9
22
  require_relative 'default'
10
23
  require_relative 'enum'
11
24
  require_relative 'hashy'
12
- require_relative 'subscript'
25
+ require_relative 'getter'
26
+ require_relative 'setter'
13
27
  require_relative 'assign'
14
28
  require_relative 'lock'
15
29
  require_relative 'validation'
@@ -4,7 +4,7 @@ class Striuct; module InstanceMethods
4
4
 
5
5
  # freezed, fixed familar members, all members passed any condition
6
6
  def secure?
7
- (frozen? || lock?) && self.class.closed? && strict?
7
+ (frozen? || all_locked?) && self.class.closed? && strict?
8
8
  end
9
9
 
10
10
  # @endgroup
@@ -0,0 +1,58 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Setter
4
+
5
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
+ # @return value
7
+ def []=(key, value)
8
+ autonym = autonym_for_key key
9
+ _set autonym, value
10
+ rescue Validation::InvalidWritingError
11
+ $!.set_backtrace([
12
+ "#{$!.backtrace[-1].sub(/[^:]+\z/){''}}in `[#{key.inspect}(#{autonym})]=': #{$!.message}",
13
+ $!.backtrace[-1]
14
+ ])
15
+
16
+ raise
17
+ end
18
+
19
+ alias_method :assign, :[]=
20
+
21
+ private
22
+
23
+ # @param [Symbol] autonym - MUST already converted to native autonym
24
+ # @return value
25
+ def _set(autonym, value)
26
+ raise "can't modify frozen #{self.class}" if frozen?
27
+ raise "can't modify locked member #{autonym}" if locked? autonym
28
+
29
+ if with_adjuster? autonym
30
+ begin
31
+ value = instance_exec value, &adjuster_for(autonym)
32
+ rescue Exception
33
+ raise ::Validation::UnmanagebleError
34
+ end
35
+ end
36
+
37
+ if with_safety_setter?(autonym) and !accept?(autonym, value)
38
+ raise ::Validation::InvalidWritingError,
39
+ "#{value.inspect} is deficient for #{autonym} in #{self.class}"
40
+ end
41
+
42
+ if with_inference? autonym
43
+ self.class.__send__ :_found_family, autonym, value
44
+ end
45
+
46
+ @db[autonym] = value
47
+ rescue ::Validation::InvalidError
48
+ unless /in \[\]=/ =~ caller[1].slice(/([^:]+)\z/)
49
+ $!.backtrace.delete_if{|s|/#{Regexp.escape(File.dirname __FILE__)}/ =~ s}
50
+ $!.backtrace.first.sub!(/([^:]+)\z/){"in `#{autonym}='"}
51
+ end
52
+
53
+ raise
54
+ end
55
+
56
+ # @endgroup
57
+
58
+ end; end
@@ -6,10 +6,10 @@ class Striuct; module InstanceMethods
6
6
  def inspect
7
7
  "#<struct' #{self.class} strict?:#{strict?}".tap {|s|
8
8
  each_pair do |autonym, value|
9
- suffix = (has_default?(autonym) && default?(autonym)) ? '/default' : nil
9
+ suffix = (with_default?(autonym) && default?(autonym)) ? '/default' : nil
10
10
  s << " #{autonym}=#{value.inspect}#{suffix}("
11
11
  s << "valid?:#{valid? autonym}, "
12
- s << "lock?:#{lock? autonym}"
12
+ s << "locked?:#{locked? autonym}"
13
13
  s << '),'
14
14
  end
15
15
 
@@ -2,11 +2,11 @@ class Striuct; module InstanceMethods
2
2
 
3
3
  # @group Validation
4
4
 
5
- # @param [Symbol, String] name
6
- # @param [Object] value - no argument and use own
7
- # passed under any condition
8
- def sufficient?(name, value=self[name])
9
- autonym = autonym_for_name name
5
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
+ # @param value
7
+ # true if passed under any condition
8
+ def accept?(key, value)
9
+ autonym = autonym_for_key key
10
10
  return true unless restrict? autonym
11
11
 
12
12
  begin
@@ -15,8 +15,14 @@ class Striuct; module InstanceMethods
15
15
  false
16
16
  end
17
17
  end
18
-
19
- alias_method :accept?, :sufficient?
18
+
19
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
20
+ # @param value - if no argument and use current assigned value
21
+ # true if passed under any condition
22
+ def sufficient?(key, value=self[key])
23
+ accept? key, value
24
+ end
25
+
20
26
  alias_method :valid?, :sufficient?
21
27
 
22
28
  # all members passed under any condition
@@ -2,18 +2,19 @@ class Striuct; module InstanceMethods
2
2
 
3
3
  # @group Behavior under Values
4
4
 
5
- # @param [Fixnum, Range] _keys
5
+ # @param [Integer, #to_int, Range] _keys
6
6
  # @return [Array]
7
7
  def values_at(*_keys)
8
8
  [].tap {|r|
9
9
  _keys.each do |key|
10
10
  case key
11
- when Fixnum
12
- r << self[key]
11
+ when ->v{v.respond_to? :to_int}
12
+ r << fetch_by_index(key)
13
13
  when Range
14
- key.each do |n|
15
- raise TypeError unless n.instance_of? Fixnum
16
- r << self[n]
14
+ key.each do |idx|
15
+ raise TypeError unless idx.respond_to? :to_int
16
+
17
+ r << fetch_by_index(idx)
17
18
  end
18
19
  else
19
20
  raise TypeError
@@ -29,7 +30,7 @@ class Striuct; module InstanceMethods
29
30
  end
30
31
 
31
32
  values.each_with_index do |value, index|
32
- self[index] = value
33
+ _set autonym_for_index(index), value
33
34
  end
34
35
 
35
36
  self
@@ -1,7 +1,4 @@
1
- require_relative 'version'
2
1
  require_relative 'structs'
3
- require_relative 'attributes'
4
- require_relative 'hashdeepdupulicatable'
5
- require_relative 'classmethods'
6
- require_relative 'instancemethods'
2
+ require_relative 'classmethods/requirements'
3
+ require_relative 'instancemethods/requirements'
7
4
  require_relative 'singleton_class'
@@ -1,4 +1,4 @@
1
- class Striuct
1
+ class Striuct; class << self
2
2
 
3
3
  module HashDeepDupulicatable
4
4
 
@@ -18,4 +18,4 @@ class Striuct
18
18
  private_constant :HashDeepDupulicatable
19
19
  end
20
20
 
21
- end
21
+ end; end
@@ -1,6 +1,4 @@
1
- require_relative 'hashdeepdupulicatable'
2
- require_relative 'classmethods'
3
- require_relative 'instancemethods'
1
+ require_relative 'singleton_class/hashdeepdupulicatable'
4
2
 
5
3
  class Striuct
6
4
 
@@ -60,7 +58,8 @@ class Striuct
60
58
  @autonyms = []
61
59
  @attributes = {}.extend HashDeepDupulicatable # autonym => Attributes
62
60
  @aliases = {} # aliased => autonym
63
- @protect_level = :prevent
61
+ @conflict_management_level =
62
+ ClassMethods::DEFAULT_CONFLICT_MANAGEMENT_LEVEL
64
63
  end
65
64
  end
66
65
 
data/striuct.gemspec CHANGED
@@ -1,10 +1,10 @@
1
- require File.expand_path('../lib/striuct/version', __FILE__)
2
-
3
1
  Gem::Specification.new do |gem|
4
2
  gem.authors = ['Kenichi Kamiya']
5
3
  gem.email = ['kachick1+ruby@gmail.com']
6
4
  gem.summary = %q{Struct++}
7
- gem.description = %q{Validatable, Inheritable... And more Struct++ features :)}
5
+ gem.description = %q{Validatable, Inheritable, Member Aliasing,
6
+ Conflict Management, Default Value, Divide nil with unassign,
7
+ Lock setter of each member, Hash flendly API, ... And more Struct++ features :)}
8
8
  gem.homepage = 'https://github.com/kachick/striuct'
9
9
 
10
10
  gem.files = `git ls-files`.split($\)
@@ -12,13 +12,16 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
13
  gem.name = 'striuct'
14
14
  gem.require_paths = ['lib']
15
- gem.version = Striuct::VERSION.dup # dup for https://github.com/rubygems/rubygems/commit/48f1d869510dcd325d6566df7d0147a086905380#-P0
15
+ gem.version = '0.4.0'
16
16
 
17
17
  gem.required_ruby_version = '>= 1.9.2'
18
18
 
19
19
  gem.add_runtime_dependency 'validation', '~> 0.0.3'
20
+ gem.add_runtime_dependency 'optionalargument', '~> 0.0.3'
20
21
  gem.add_runtime_dependency 'keyvalidatable', '~> 0.0.3'
21
22
 
22
23
  gem.add_development_dependency 'yard', '~> 0.8'
24
+ gem.add_development_dependency 'rake'
25
+ gem.add_development_dependency 'bundler'
23
26
  end
24
27
 
@@ -0,0 +1,36 @@
1
+ require_relative 'helper'
2
+
3
+ class Test_Striuct_Constructor < Test::Unit::TestCase
4
+
5
+ def test_new
6
+ cls = Striuct.new
7
+ assert_not_instance_of Striuct, cls
8
+ assert_instance_of Class, cls
9
+ assert_kind_of Striuct, cls.new
10
+
11
+ cls2 = Striuct.new :name, :age
12
+
13
+ assert_equal cls2.members, [:name, :age]
14
+
15
+ cls3 = Striuct.new :foo do
16
+ member :var
17
+ end
18
+
19
+ assert_equal cls3.members, [:foo, :var]
20
+ end
21
+
22
+ def test_define
23
+ assert_raises RuntimeError do
24
+ Striuct.define do
25
+ end
26
+ end
27
+
28
+ klass = Striuct.define do
29
+ member :foo
30
+ end
31
+
32
+ assert_equal true, klass.closed?
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,88 @@
1
+ require_relative 'helper'
2
+
3
+ class Test_Striuct_Subclass_Class_Constructor < Test::Unit::TestCase
4
+
5
+ User = Striuct.define do
6
+ member :name, AND(String, NOT(''))
7
+ member :age, Fixnum
8
+ end.freeze
9
+
10
+ [:for_values, :new].each do |callee|
11
+ define_method :"test_subclass_#{callee}" do
12
+ user = User.public_send callee
13
+ assert_instance_of User, user
14
+ assert_not_kind_of Class, user
15
+ assert_equal [:name, :age], user.members
16
+ assert_equal [nil, nil], user.values
17
+
18
+ assert_raises Validation::InvalidWritingError do
19
+ User.public_send callee, :SYMBOL
20
+ end
21
+
22
+ assert_raises Validation::InvalidWritingError do
23
+ User.public_send callee, ''
24
+ end
25
+
26
+ user = User.public_send callee, '.'
27
+ assert_instance_of User, user
28
+ assert_not_kind_of Class, user
29
+ assert_equal ['.', nil], user.values
30
+
31
+ assert_raises Validation::InvalidWritingError do
32
+ User.public_send callee, '.', 1.0
33
+ end
34
+
35
+ user = User.public_send callee, '.', 1
36
+ assert_equal ['.', 1], user.values
37
+ end
38
+ end
39
+
40
+ def test_define
41
+ user = User.define{|r|r.age = 1; r.name = 'a'}
42
+ assert_same 1, user.age
43
+
44
+ assert_raises RuntimeError do
45
+ user.age = 1
46
+ end
47
+
48
+ user = User.define{|r|r.age = 1; r.name = 'a'}
49
+ assert_same 1, user.age
50
+ assert_same true, user.all_locked?
51
+ assert_same false, user.frozen?
52
+
53
+ assert_raises RuntimeError do
54
+ User.define{|r|r.age = 1}
55
+ end
56
+
57
+ user = User.define(lock: true){|r|r.age = 1; r.name = 'a'}
58
+ assert_same 1, user.age
59
+ assert_same true, user.all_locked?
60
+ user = User.define(lock: false){|r|r.age = 1; r.name = 'a'}
61
+ assert_same false, user.all_locked?
62
+ assert_equal true, user.strict?
63
+
64
+ assert_raises Validation::InvalidWritingError do
65
+ User.define{|r|r.age = 1; r.name = 'a'; r.name.clear}
66
+ end
67
+
68
+ user = User.define(strict: false){|r|r.age = 1; r.name = 'a'; r.name.clear}
69
+ assert_equal '', user.name
70
+ assert_equal false, user.strict?
71
+ end
72
+
73
+ Sth = Striuct.new :foo, :bar, :hoge
74
+ SampleStruct = Struct.new :foo, :bar, :hoge
75
+
76
+ def test_for_pairs_from_hash
77
+ sth = Sth[hoge: 7, foo: 8]
78
+
79
+ assert_equal [8, nil, 7], sth.values
80
+ end
81
+
82
+ def test_for_pairs_from_struct
83
+ sth = Sth[SampleStruct.new 8, nil, 7]
84
+
85
+ assert_equal [8, nil, 7], sth.values
86
+ end
87
+
88
+ end
@@ -4,21 +4,21 @@ class Test_Striuct_Subclass_Class_SafetyNaming < Test::Unit::TestCase
4
4
 
5
5
  def test_cname?
6
6
  klass = Striuct.new
7
- assert_same false, klass.cname?(Object)
7
+ assert_same false, klass.cname?(BasicObject)
8
8
  assert_same false, klass.cname?('m?')
9
9
  assert_same false, klass.cname?('__foo__')
10
10
  assert_same false, klass.cname?('a b')
11
11
  assert_same false, klass.cname?('object_id')
12
12
  assert_same false, klass.cname?('to_ary')
13
13
  assert_same true, klass.cname?('foo')
14
- klass.__send__ :protect_level, :warning
14
+ klass.__send__ :set_conflict_management_level, :warning
15
15
  assert_same false, klass.cname?('m?')
16
16
  assert_same false, klass.cname?('__foo__')
17
17
  assert_same false, klass.cname?('a b')
18
18
  assert_same false, klass.cname?('object_id')
19
19
  assert_same false, klass.cname?('to_ary')
20
20
  assert_same true, klass.cname?('foo')
21
- klass.__send__ :protect_level, :struct
21
+ klass.__send__ :set_conflict_management_level, :struct
22
22
  assert_same true, klass.cname?('m?')
23
23
  assert_same true, klass.cname?('__foo__')
24
24
  assert_same true, klass.cname?('a b')
@@ -62,8 +62,9 @@ class Test_Striuct_Subclass_Class_SafetyNaming < Test::Unit::TestCase
62
62
  assert_same false, klass.member?('m?')
63
63
 
64
64
  klass.class_eval do
65
- protect_level :struct
66
- member :'m?'
65
+ conflict_management :struct do
66
+ member :'m?'
67
+ end
67
68
  end
68
69
 
69
70
  assert_same true, klass.member?('m?')
@@ -0,0 +1,139 @@
1
+ require_relative 'helper'
2
+
3
+ class Test_Striuct_Subclass_Enum < Test::Unit::TestCase
4
+
5
+ class Subclass < Striuct
6
+ member :foo
7
+ member :bar
8
+
9
+ close_member
10
+ end.freeze
11
+
12
+ FOO = 'Fooo! :)'.freeze
13
+ BAR = 'bar :('.freeze
14
+ INSTANCE = Subclass.new(FOO, BAR).freeze
15
+
16
+ TYPE_PAIRS = {
17
+ class: Subclass,
18
+ instance: INSTANCE
19
+ }.freeze
20
+
21
+ [:each_autonym, :each_member].each do |callee|
22
+ TYPE_PAIRS.each_pair do |type, reciever|
23
+ define_method :"test_#{type}_#{callee}" do
24
+ assert_same(reciever, reciever.public_send(callee) {})
25
+
26
+ enum = reciever.public_send(callee)
27
+ assert_instance_of Enumerator, enum
28
+ assert_same :foo, enum.next
29
+ assert_same :bar, enum.next
30
+ assert_raises StopIteration do
31
+ enum.next
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ [:each_index].each do |callee|
38
+ TYPE_PAIRS.each_pair do |type, reciever|
39
+ define_method :"test_#{type}_#{callee}" do
40
+ assert_same(reciever, reciever.public_send(callee) {})
41
+
42
+ enum = reciever.public_send(callee)
43
+ assert_instance_of Enumerator, enum
44
+ assert_same 0, enum.next
45
+ assert_same 1, enum.next
46
+ assert_raises StopIteration do
47
+ enum.next
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ [:each_autonym_with_index, :each_member_with_index].each do |callee|
54
+ TYPE_PAIRS.each_pair do |type, reciever|
55
+ define_method :"test_#{type}_#{callee}" do
56
+ assert_same(reciever, reciever.public_send(callee) {})
57
+
58
+ enum = reciever.public_send(callee)
59
+ assert_instance_of Enumerator, enum
60
+ assert_equal [:foo, 0], enum.next
61
+ assert_equal [:bar, 1], enum.next
62
+ assert_raises StopIteration do
63
+ enum.next
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ [:each_value, :each].each do |callee|
70
+ {instance: INSTANCE}.each_pair do |type, reciever|
71
+ define_method :"test_#{type}_#{callee}" do
72
+ assert_same(reciever, reciever.public_send(callee) {})
73
+
74
+ enum = reciever.public_send(callee)
75
+ assert_instance_of Enumerator, enum
76
+ assert_same FOO, enum.next
77
+ assert_same BAR, enum.next
78
+ assert_raises StopIteration do
79
+ enum.next
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ [:each_value_with_index, :each_with_index].each do |callee|
86
+ {instance: INSTANCE}.each_pair do |type, reciever|
87
+ define_method :"test_#{type}_#{callee}" do
88
+ assert_same(reciever, reciever.public_send(callee) {})
89
+
90
+ enum = reciever.public_send(callee)
91
+ assert_instance_of Enumerator, enum
92
+ assert_equal [FOO, 0], ret = enum.next
93
+ assert_same FOO, ret.first
94
+ assert_equal [BAR, 1], ret = enum.next
95
+ assert_same BAR, ret.first
96
+ assert_raises StopIteration do
97
+ enum.next
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ [:each_pair].each do |callee|
104
+ {instance: INSTANCE}.each_pair do |type, reciever|
105
+ define_method :"test_#{type}_#{callee}" do
106
+ assert_same(reciever, reciever.public_send(callee) {})
107
+
108
+ enum = reciever.public_send(callee)
109
+ assert_instance_of Enumerator, enum
110
+ assert_equal [:foo, FOO], ret = enum.next
111
+ assert_same FOO, ret.last
112
+ assert_equal [:bar, BAR], ret = enum.next
113
+ assert_same BAR, ret.last
114
+ assert_raises StopIteration do
115
+ enum.next
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ [:each_pair_with_index].each do |callee|
122
+ {instance: INSTANCE}.each_pair do |type, reciever|
123
+ define_method :"test_#{type}_#{callee}" do
124
+ assert_same(reciever, reciever.public_send(callee) {})
125
+
126
+ enum = reciever.public_send(callee)
127
+ assert_instance_of Enumerator, enum
128
+ assert_equal [:foo, FOO, 0], ret = enum.next
129
+ assert_same FOO, ret[1]
130
+ assert_equal [:bar, BAR, 1], ret = enum.next
131
+ assert_same BAR, ret[1]
132
+ assert_raises StopIteration do
133
+ enum.next
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ end