striuct 0.3.0 → 0.3.1

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 (68) hide show
  1. data/.gitignore +32 -0
  2. data/.travis.yml +6 -0
  3. data/Gemfile +12 -0
  4. data/History.rdoc +5 -0
  5. data/Manifest.txt +53 -25
  6. data/README.md +97 -0
  7. data/Rakefile +7 -21
  8. data/examples/README.rb +25 -0
  9. data/{example → examples}/example1.rb +1 -1
  10. data/{example → examples}/example2.rb +1 -1
  11. data/{example → examples}/see_trace.rb +4 -0
  12. data/lib/striuct/{containable/eigen → classmethods}/basic.rb +13 -5
  13. data/lib/striuct/classmethods/constants.rb +23 -0
  14. data/lib/striuct/{containable/eigen → classmethods}/constructor.rb +20 -14
  15. data/lib/striuct/{containable/eigen → classmethods}/handy.rb +19 -20
  16. data/lib/striuct/{containable/eigen → classmethods}/inner.rb +10 -32
  17. data/lib/striuct/{containable/eigen → classmethods}/macro.rb +37 -7
  18. data/lib/striuct/classmethods/requiremnets.rb +7 -0
  19. data/lib/striuct/{containable/eigen → classmethods}/safety.rb +6 -6
  20. data/lib/striuct/classmethods.rb +1 -0
  21. data/lib/striuct/{containable → instancemethods}/basic.rb +6 -6
  22. data/lib/striuct/{containable → instancemethods}/handy.rb +3 -3
  23. data/lib/striuct/{containable → instancemethods}/hashlike.rb +12 -6
  24. data/lib/striuct/{containable → instancemethods}/inner.rb +9 -8
  25. data/lib/striuct/instancemethods/requirements.rb +6 -0
  26. data/lib/striuct/{containable → instancemethods}/safety.rb +2 -2
  27. data/lib/striuct/instancemethods/singleton_class.rb +19 -0
  28. data/lib/striuct/instancemethods.rb +1 -0
  29. data/lib/striuct/requirements.rb +6 -0
  30. data/lib/striuct/singleton_class.rb +93 -0
  31. data/lib/striuct/specificcontainer.rb +17 -0
  32. data/lib/striuct/structs.rb +7 -0
  33. data/lib/striuct/version.rb +3 -2
  34. data/lib/striuct.rb +4 -9
  35. data/striuct.gemspec +24 -0
  36. data/test/{test_helper.rb → helper.rb} +3 -0
  37. data/test/test_striuct.rb +23 -1409
  38. data/test/test_striuct_define.rb +19 -0
  39. data/test/test_striuct_subclass_adjuster.rb +95 -0
  40. data/test/test_striuct_subclass_alias_member.rb +54 -0
  41. data/test/test_striuct_subclass_assign.rb +30 -0
  42. data/test/test_striuct_subclass_classlock.rb +36 -0
  43. data/test/test_striuct_subclass_classmethods.rb +87 -0
  44. data/test/test_striuct_subclass_cloning.rb +36 -0
  45. data/test/test_striuct_subclass_default_value.rb +129 -0
  46. data/test/test_striuct_subclass_for_pairs.rb +13 -0
  47. data/test/test_striuct_subclass_freeze.rb +19 -0
  48. data/test/test_striuct_subclass_functional_condition.rb +51 -0
  49. data/test/test_striuct_subclass_getter_validation.rb +33 -0
  50. data/test/test_striuct_subclass_hashlike.rb +153 -0
  51. data/test/test_striuct_subclass_inference.rb +51 -0
  52. data/test/test_striuct_subclass_inheritable.rb +58 -0
  53. data/test/test_striuct_subclass_instance.rb +289 -0
  54. data/test/test_striuct_subclass_lock.rb +40 -0
  55. data/test/test_striuct_subclass_safetynaming.rb +72 -0
  56. data/test/test_striuct_subclass_specific_conditions.rb +247 -0
  57. data/test/test_striuct_subclass_to_struct.rb +25 -0
  58. data/test/test_striuct_version.rb +9 -0
  59. metadata +106 -68
  60. data/.gemtest +0 -0
  61. data/README.rdoc +0 -63
  62. data/example/example.rb +0 -17
  63. data/lib/striuct/abstract.rb +0 -74
  64. data/lib/striuct/containable/classutil.rb +0 -22
  65. data/lib/striuct/containable/eigen.rb +0 -29
  66. data/lib/striuct/containable.rb +0 -38
  67. /data/{example/benchmarks.rb → benchmarks/basics.rb} +0 -0
  68. /data/{example → examples}/example.old.rdoc +0 -0
@@ -0,0 +1,19 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctDefine < Test::Unit::TestCase
4
+
5
+ def test_define
6
+ assert_raises RuntimeError do
7
+ Striuct.define do
8
+ end
9
+ end
10
+
11
+ klass = Striuct.define do
12
+ member :foo
13
+ end
14
+
15
+ assert_equal true, klass.closed?
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,95 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctAdjusterOld < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new do
6
+ member :age, Numeric, &->arg{Integer arg}
7
+ end
8
+
9
+ def setup
10
+ @sth = Sth.new
11
+ assert_same nil, @sth.age
12
+ end
13
+
14
+ def test_procedure
15
+ @sth.age = 10
16
+ assert_same 10, @sth.age
17
+ @sth.age = 10.0
18
+ assert_same 10, @sth.age
19
+
20
+ assert_raises Validation::UnmanagebleError do
21
+ @sth.age = '10.0'
22
+ end
23
+
24
+ @sth.age = '10'
25
+ assert_same 10, @sth.age
26
+ end
27
+
28
+ end
29
+
30
+
31
+ class TestStriuctAdjuster < Test::Unit::TestCase
32
+
33
+ class MyClass
34
+ def self.parse(v)
35
+ raise unless /\A[a-z]+\z/ =~ v
36
+ new
37
+ end
38
+ end
39
+
40
+ Sth = Striuct.define do
41
+ member :chomped, AND(Symbol, /[^\n]\z/), &WHEN(String, ->v{v.chomp.to_sym})
42
+ member :no_reduced, Symbol, &->v{v.to_sym}
43
+ member :reduced, Symbol, &INJECT(->v{v.to_s}, ->v{v.to_sym})
44
+ member :integer, Integer, &PARSE(Integer)
45
+ member :myobj, ->v{v.instance_of? MyClass}, &PARSE(MyClass)
46
+ end
47
+
48
+ def test_WHEN
49
+ sth = Sth.new
50
+
51
+ assert_raises Validation::InvalidWritingError do
52
+ sth.chomped = :"a\n"
53
+ end
54
+
55
+ sth.chomped = "a\n"
56
+
57
+ assert_equal :a, sth.chomped
58
+
59
+ sth.chomped = :b
60
+ assert_equal :b, sth.chomped
61
+ end
62
+
63
+ def test_INJECT
64
+ sth = Sth.new
65
+
66
+ assert_raises Validation::UnmanagebleError do
67
+ sth.no_reduced = 1
68
+ end
69
+
70
+ sth.reduced = 1
71
+
72
+ assert_equal :'1', sth.reduced
73
+ end
74
+
75
+ def test_PARSE
76
+ sth = Sth.new
77
+
78
+ assert_raises Validation::UnmanagebleError do
79
+ sth.integer = '1.0'
80
+ end
81
+
82
+ sth.integer = '1'
83
+
84
+ assert_equal 1, sth.integer
85
+
86
+ assert_raises Validation::UnmanagebleError do
87
+ sth.myobj = '1'
88
+ end
89
+
90
+ sth.myobj = 'a'
91
+
92
+ assert_kind_of MyClass, sth.myobj
93
+ end
94
+
95
+ end
@@ -0,0 +1,54 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctAliasMember < Test::Unit::TestCase
4
+
5
+ class Sth < Striuct.new
6
+ member :foo, String
7
+
8
+ member :bar, Integer do |v|
9
+ v
10
+ end
11
+
12
+ member :hoge, Symbol
13
+ default :hoge, :'Z'
14
+ alias_member :abc, :bar
15
+ default :abc, 8
16
+ end
17
+
18
+ def test_alias_member
19
+ sth = Sth.new 'A'
20
+ assert_equal [:foo, :bar, :hoge], sth.members
21
+ assert_equal [:foo, :bar, :hoge], sth.autonyms
22
+ assert_equal({abc: :bar}, sth.aliases)
23
+ assert_equal [:foo, :bar, :hoge, :abc], sth.all_members
24
+
25
+ assert_equal 8, sth[:abc]
26
+ flavor = Sth.__send__(:flavor_for, :abc)
27
+ assert_kind_of Proc, flavor
28
+ assert_same flavor, Sth.__send__(:flavor_for, :bar)
29
+ assert_equal 8, sth.abc
30
+ sth.abc = 5
31
+ assert_equal 5, sth.bar
32
+ sth[:abc] = 6
33
+ assert_equal 6, sth.bar
34
+
35
+ assert_raises Validation::InvalidWritingError do
36
+ sth[:abc] = 'a'
37
+ end
38
+
39
+ assert_raises Validation::InvalidWritingError do
40
+ sth.abc = 'a'
41
+ end
42
+
43
+ assert_raises Validation::InvalidWritingError do
44
+ sth.bar = 'a'
45
+ end
46
+
47
+ assert_raises ArgumentError do
48
+ Sth.class_eval do
49
+ member :abc
50
+ end
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctAssign < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new do
6
+ member :foo
7
+ end
8
+
9
+ def test_unassign
10
+ sth = Sth.new
11
+ assert_equal false, sth.assign?(:foo)
12
+ sth.foo = nil
13
+ assert_equal true, sth.assign?(:foo)
14
+ sth.unassign :foo
15
+ assert_equal false, sth.assign?(:foo)
16
+ sth.foo = nil
17
+ assert_equal true, sth.assign?(:foo)
18
+ sth.clear_at 0
19
+ assert_equal false, sth.assign?(:foo)
20
+
21
+ assert_raises NameError do
22
+ sth.unassign :var
23
+ end
24
+
25
+ assert_raises IndexError do
26
+ sth.unassign 1
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctClassLock < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new do
6
+ member :foo
7
+ end
8
+
9
+ def test_class_lock
10
+ sth = Sth.new
11
+
12
+ assert_equal true, sth.member?(:foo)
13
+
14
+ Sth.class_eval do
15
+ member :bar
16
+ end
17
+
18
+ assert_equal true, sth.member?(:bar)
19
+ assert_equal [:foo, :bar], sth.members
20
+
21
+ assert_equal false, Sth.closed?
22
+
23
+ Sth.__send__ :close
24
+
25
+ assert_equal true, Sth.closed?
26
+
27
+ assert_raises RuntimeError do
28
+ Sth.class_eval do
29
+ member :var2
30
+ end
31
+ end
32
+
33
+ assert_equal false, sth.member?(:var2)
34
+ end
35
+
36
+ end
@@ -0,0 +1,87 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctSubclassClassMethods < Test::Unit::TestCase
4
+
5
+ class User < Striuct.new
6
+ member :id, Integer
7
+ member :last_name, /\A\w+\z/
8
+ member :family_name, /\A\w+\z/
9
+ member :address, /\A((\w+) ?)+\z/
10
+ member :age, ->age{(20..140).include? age}
11
+ end
12
+
13
+ User2 = Striuct.define do
14
+ member :name, AND(String, NOT(''))
15
+ member :age, Fixnum
16
+ end
17
+
18
+ def test_builder
19
+ klass = Striuct.new
20
+ assert_kind_of Striuct, klass.new
21
+
22
+ klass = Striuct.new :name, :age
23
+
24
+ assert_equal klass.members, [:name, :age]
25
+
26
+ klass = Striuct.new :foo do
27
+ member :var
28
+ end
29
+
30
+ assert_equal klass.members, [:foo, :var]
31
+ assert_equal User.members, [:id, :last_name, :family_name, :address, :age]
32
+ end
33
+
34
+ def test_define
35
+ user = User2.define{|r|r.age = 1; r.name = 'a'}
36
+ assert_same 1, user.age
37
+
38
+ assert_raises RuntimeError do
39
+ user.age = 1
40
+ end
41
+
42
+ user = User2.define{|r|r.age = 1; r.name = 'a'}
43
+ assert_same 1, user.age
44
+ assert_same true, user.lock?
45
+ assert_same false, user.frozen?
46
+
47
+ assert_raises RuntimeError do
48
+ User2.define{|r|r.age = 1}
49
+ end
50
+
51
+ user = User2.define(lock: true){|r|r.age = 1; r.name = 'a'}
52
+ assert_same 1, user.age
53
+ assert_same true, user.lock?
54
+ user = User2.define(lock: false){|r|r.age = 1; r.name = 'a'}
55
+ assert_same false, user.lock?
56
+ assert_equal true, user.strict?
57
+
58
+ assert_raises Validation::InvalidWritingError do
59
+ User2.define{|r|r.age = 1; r.name = 'a'; r.name.clear}
60
+ end
61
+
62
+ user = User2.define(strict: false){|r|r.age = 1; r.name = 'a'; r.name.clear}
63
+ assert_equal '', user.name
64
+ assert_equal false, user.strict?
65
+ end
66
+
67
+ def test_restrict?
68
+ klass = Striuct.new :foo do
69
+ member :var, //
70
+ member :hoge
71
+ member :moge, nil
72
+ end
73
+
74
+ assert_equal false, klass.restrict?(:foo)
75
+ assert_equal true, klass.restrict?(:var)
76
+ assert_equal false, klass.restrict?(:hoge)
77
+ assert_equal true, klass.restrict?(:moge)
78
+ end
79
+
80
+ def test_add_members
81
+ klass = Striuct.new :foo do
82
+ add_members :aaa, 'bbb', :ccc
83
+ end
84
+
85
+ assert_equal [:foo, :aaa, :bbb, :ccc], klass.members
86
+ end
87
+ end
@@ -0,0 +1,36 @@
1
+ $VERBOSE = true
2
+ require_relative 'helper'
3
+
4
+ class TestStriuctCloning < Test::Unit::TestCase
5
+
6
+ class Sth < Striuct.new
7
+ member :sth
8
+ end
9
+
10
+ def setup
11
+ @sth = Sth.new
12
+ end
13
+
14
+ def test_clone
15
+ sth2 = @sth.dup
16
+ @sth.sth = 1
17
+ assert_equal false, (@sth.sth == sth2.sth)
18
+
19
+ sth2 = @sth.clone
20
+ @sth.sth = 2
21
+ assert_equal false, (@sth.sth == sth2.sth)
22
+ end
23
+
24
+ def test_class_dup
25
+ klass = Sth.dup
26
+ Sth.__send__ :member, :dummy1
27
+ assert_equal false, klass.member?(:dummy1)
28
+ end
29
+
30
+ def test_class_clone
31
+ klass = Sth.clone
32
+ Sth.__send__ :member, :dummy2
33
+ assert_equal false, klass.member?(:dummy2)
34
+ end
35
+
36
+ end
@@ -0,0 +1,129 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctDefaultValue < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new do
6
+ member :lank, OR(Bignum, Fixnum)
7
+ default :lank, 1
8
+ end
9
+
10
+ def test_default
11
+ sth = Sth.new 2
12
+ assert_equal 2, sth.lank
13
+ sth = Sth.new
14
+ assert_equal 1, sth.lank
15
+ assert_equal true, sth.default?(:lank)
16
+ sth.lank = 2
17
+ assert_equal false, sth.default?(:lank)
18
+ end
19
+
20
+ def test_define_default
21
+ assert_raises NameError do
22
+ Sth.class_eval do
23
+ default :anything, 10
24
+ end
25
+ end
26
+
27
+ klass = Striuct.define do
28
+ member :lank2, Integer
29
+ default :lank2, '10'
30
+ end
31
+
32
+ assert_raises Validation::InvalidWritingError do
33
+ klass.new
34
+ end
35
+
36
+ scope = self
37
+ seef = nil
38
+ klass = Striuct.define do
39
+ member :lank, Integer
40
+
41
+ scope.assert_raises ArgumentError do
42
+ default :lank, &->own, name, exess{rand}
43
+ end
44
+
45
+ scope.assert_raises ArgumentError do
46
+ default :lank, '10', &->own, name{rand}
47
+ end
48
+
49
+ scope.assert_raises ArgumentError do
50
+ default :lank, '10', &->own{rand}
51
+ end
52
+
53
+ scope.assert_raises ArgumentError do
54
+ default :lank, '10', &->{rand}
55
+ end
56
+
57
+ default :lank, &->own, name{(seef = own); rand}
58
+ end
59
+
60
+ assert_raises Validation::InvalidWritingError do
61
+ klass.new
62
+ end
63
+
64
+ klass = Striuct.define do
65
+ member :lank, Integer
66
+ default :lank, &->own, name{(seef = own); 10 - name.length}
67
+ end
68
+
69
+ assert_equal 6, klass.new.lank
70
+ assert_equal seef, klass.new
71
+ end
72
+
73
+ end
74
+
75
+ class TestStriuctDefaultValueinMemberMacro < Test::Unit::TestCase
76
+
77
+ Sth = Striuct.new do
78
+ member :lank, OR(Bignum, Fixnum), default: 1
79
+ end
80
+
81
+ def test_default
82
+ sth = Sth.new 2
83
+ assert_equal 2, sth.lank
84
+ sth = Sth.new
85
+ assert_equal 1, sth.lank
86
+ assert_equal true, sth.default?(:lank)
87
+ sth.lank = 2
88
+ assert_equal false, sth.default?(:lank)
89
+ end
90
+
91
+ def test_define_default
92
+ assert_raises NameError do
93
+ Sth.class_eval do
94
+ default :anything, 10
95
+ end
96
+ end
97
+
98
+ klass = Striuct.define do
99
+ member :lank2, Integer, default: '10'
100
+ end
101
+
102
+ assert_raises Validation::InvalidWritingError do
103
+ klass.new
104
+ end
105
+
106
+ scope = self
107
+ seef = nil
108
+ klass = Striuct.define do
109
+
110
+ scope.assert_raises ArgumentError do
111
+ member :lank, Integer, default: '10', default_proc: ->own,name{rand}
112
+ end
113
+
114
+ member :lank, Integer, default_proc: ->own,name{(seef = own); rand}
115
+ end
116
+
117
+ assert_raises Validation::InvalidWritingError do
118
+ klass.new
119
+ end
120
+
121
+ klass = Striuct.define do
122
+ member :lank, Integer, default_proc: ->own,name{(seef = own); 10 - name.length}
123
+ end
124
+
125
+ assert_equal 6, klass.new.lank
126
+ assert_equal seef, klass.new
127
+ end
128
+
129
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctForPairs < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new :foo, :bar, :hoge
6
+
7
+ def test_for_pairs
8
+ sth = Sth[hoge: 7, foo: 8]
9
+
10
+ assert_equal [8, nil, 7], sth.values
11
+ end
12
+
13
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctFreeze < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.new :foo
6
+
7
+ def test_freeze
8
+ sth = Sth.new
9
+ sth.freeze
10
+
11
+ assert_raises RuntimeError do
12
+ sth.foo = 8
13
+ end
14
+
15
+ assert_equal true, sth.frozen?
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,51 @@
1
+ require_relative 'helper'
2
+
3
+ class TestStriuctFunctionalCondition < Test::Unit::TestCase
4
+
5
+ Sthlambda = Striuct.new do
6
+ member :lank, ->lank{lanks.include? lank}
7
+ member :lanks
8
+ default :lanks, 1..30
9
+ end
10
+
11
+ def test_lambda
12
+ sth = Sthlambda.new
13
+ sth.lank = 2
14
+ assert_equal 2, sth.lank
15
+
16
+ assert_raises Validation::InvalidWritingError do
17
+ sth.lank = 31
18
+ end
19
+ end
20
+
21
+ max = 9
22
+
23
+ SthProc = Striuct.new do
24
+ member :lank, Proc.new{|n|(3..max) === n}
25
+ end
26
+
27
+ def test_Proc
28
+ sth = SthProc.new
29
+ sth.lank = 8
30
+ assert_equal 8, sth.lank
31
+
32
+ assert_raises Validation::InvalidWritingError do
33
+ sth.lank = 2
34
+ end
35
+ end
36
+
37
+ SthMethod = Striuct.new do
38
+ member :lank, 7.method(:<)
39
+ end
40
+
41
+ def test_Method
42
+ sth = SthMethod.new
43
+ sth.lank = 8
44
+ assert_equal 8, sth.lank
45
+
46
+ assert_raises Validation::InvalidWritingError do
47
+ sth.lank = 6
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'helper'
2
+
3
+ class TestGetterValidation < Test::Unit::TestCase
4
+
5
+ Sth = Striuct.define do
6
+ member :plus_getter, /./, getter_validation: true
7
+ member :only_getter, /./, getter_validation: true,
8
+ setter_validation: false
9
+ end
10
+
11
+ def test_getter_validation
12
+ sth = Sth.new
13
+
14
+ assert_raises Validation::InvalidWritingError do
15
+ sth.plus_getter = ''
16
+ end
17
+
18
+ sth.plus_getter = 'abc'
19
+ assert_equal 'abc', sth.plus_getter
20
+ sth.plus_getter.clear
21
+
22
+ assert_raises Validation::InvalidReadingError do
23
+ sth.plus_getter
24
+ end
25
+
26
+ sth.only_getter = ''
27
+
28
+ assert_raises Validation::InvalidReadingError do
29
+ sth.only_getter
30
+ end
31
+ end
32
+
33
+ end