striuct 0.0.11.1 → 0.1.7
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/History.rdoc +128 -35
- data/Manifest.txt +21 -6
- data/README.ja.rdoc +142 -83
- data/README.rdoc +130 -73
- data/Rakefile +5 -3
- data/example/benchmarks.rb +56 -0
- data/{example.rb → example/example.rb} +81 -70
- data/example/see_trace.rb +28 -0
- data/lib/striuct/abstract.rb +74 -0
- data/lib/striuct/conditions.rb +228 -0
- data/lib/striuct/frame.rb +8 -0
- data/lib/striuct/subclassable/basic.rb +135 -0
- data/lib/striuct/{classutil.rb → subclassable/classutil.rb} +5 -5
- data/lib/striuct/subclassable/eigen/basic.rb +38 -0
- data/lib/striuct/subclassable/eigen/constructor.rb +58 -0
- data/lib/striuct/subclassable/eigen/frame.rb +39 -0
- data/lib/striuct/subclassable/eigen/handy.rb +92 -0
- data/lib/striuct/subclassable/eigen/inner.rb +224 -0
- data/lib/striuct/subclassable/eigen/macro.rb +108 -0
- data/lib/striuct/subclassable/eigen/safety.rb +56 -0
- data/lib/striuct/subclassable/frame.rb +33 -0
- data/lib/striuct/subclassable/handy.rb +57 -0
- data/lib/striuct/subclassable/hashlike.rb +133 -0
- data/lib/striuct/subclassable/inner.rb +108 -0
- data/lib/striuct/subclassable/safety.rb +72 -0
- data/lib/striuct/subclassable/yaml.rb +14 -0
- data/lib/striuct/version.rb +2 -2
- data/lib/striuct.rb +3 -2
- data/test/test_striuct.rb +649 -20
- metadata +55 -24
- data/lib/striuct/core.rb +0 -56
- data/lib/striuct/import.rb +0 -95
- data/lib/striuct/subclass.rb +0 -262
- data/lib/striuct/subclass_eigen.rb +0 -428
- data/test/test_helper_import.rb +0 -4
- data/test/test_striuct_import.rb +0 -42
data/test/test_striuct.rb
CHANGED
@@ -10,7 +10,10 @@ class User < Striuct.new
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class TestStriuctSubclassEigen < Test::Unit::TestCase
|
13
|
-
User2 = Striuct.
|
13
|
+
User2 = Striuct.define do
|
14
|
+
member :name, AND(String, NOT(''))
|
15
|
+
member :age, Fixnum
|
16
|
+
end
|
14
17
|
|
15
18
|
def test_builder
|
16
19
|
klass = Striuct.new
|
@@ -29,24 +32,41 @@ class TestStriuctSubclassEigen < Test::Unit::TestCase
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def test_define
|
32
|
-
user = User2.define{|r|r.age = 1; r.name = ''}
|
35
|
+
user = User2.define{|r|r.age = 1; r.name = 'a'}
|
33
36
|
assert_same 1, user.age
|
34
37
|
|
35
38
|
assert_raises RuntimeError do
|
36
39
|
user.age = 1
|
37
40
|
end
|
38
41
|
|
39
|
-
user = User2.define
|
42
|
+
user = User2.define{|r|r.age = 1; r.name = 'a'}
|
40
43
|
assert_same 1, user.age
|
44
|
+
assert_same true, user.lock?
|
45
|
+
assert_same false, user.frozen?
|
41
46
|
|
42
47
|
assert_raises RuntimeError do
|
43
48
|
User2.define{|r|r.age = 1}
|
44
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 Striuct::ConditionError 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?
|
45
65
|
end
|
46
66
|
|
47
|
-
def
|
48
|
-
assert_equal false, User.
|
49
|
-
assert_equal true, User.
|
67
|
+
def test_sufficient?
|
68
|
+
assert_equal false, User.sufficient?(:age, 19)
|
69
|
+
assert_equal true, User.sufficient?(:age, 20)
|
50
70
|
end
|
51
71
|
|
52
72
|
def test_restrict?
|
@@ -128,11 +148,11 @@ class TestStriuctSubclassInstance2 < Test::Unit::TestCase
|
|
128
148
|
end
|
129
149
|
|
130
150
|
def test_strict?
|
131
|
-
assert_same @user.
|
151
|
+
assert_same @user.sufficient?(:last_name), true
|
132
152
|
assert_same @user.strict?, true
|
133
|
-
assert_same @user.
|
153
|
+
assert_same @user.sufficient?(:last_name), true
|
134
154
|
@user.last_name.clear
|
135
|
-
assert_same @user.
|
155
|
+
assert_same @user.sufficient?(:last_name), false
|
136
156
|
assert_same @user.strict?, false
|
137
157
|
end
|
138
158
|
end
|
@@ -173,8 +193,39 @@ class TestStriuctSubclassInstance3 < Test::Unit::TestCase
|
|
173
193
|
def test_each_member
|
174
194
|
assert_same @user, @user.each_member{}
|
175
195
|
assert_kind_of Enumerator, enum = @user.each_member
|
176
|
-
assert_equal enum.next
|
177
|
-
assert_equal enum.next
|
196
|
+
assert_equal :id, enum.next
|
197
|
+
assert_equal :last_name, enum.next
|
198
|
+
assert_equal :family_name, enum.next
|
199
|
+
assert_equal :address, enum.next
|
200
|
+
assert_equal :age, enum.next
|
201
|
+
assert_raises StopIteration do
|
202
|
+
enum.next
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_each_index
|
207
|
+
assert_same @user, @user.each_index{}
|
208
|
+
assert_kind_of Enumerator, enum = @user.each_index
|
209
|
+
assert_equal 0, enum.next
|
210
|
+
assert_equal 1, enum.next
|
211
|
+
assert_equal 2, enum.next
|
212
|
+
assert_equal 3, enum.next
|
213
|
+
assert_equal 4, enum.next
|
214
|
+
assert_raises StopIteration do
|
215
|
+
enum.next
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_each_with_index
|
220
|
+
assert_same @user, @user.each_with_index{}
|
221
|
+
assert_kind_of Enumerator, enum = @user.each_with_index
|
222
|
+
|
223
|
+
r = []
|
224
|
+
@user.each_with_index do |value, index|
|
225
|
+
r << [value, index]
|
226
|
+
end
|
227
|
+
|
228
|
+
assert_equal [@user.each_value.to_a, @user.each_index.to_a].transpose, r
|
178
229
|
end
|
179
230
|
|
180
231
|
def test_values
|
@@ -264,14 +315,16 @@ class TestStriuctCloning < Test::Unit::TestCase
|
|
264
315
|
assert_equal false, (@sth.sth == sth2.sth)
|
265
316
|
end
|
266
317
|
|
267
|
-
def
|
318
|
+
def test_class_dup
|
268
319
|
klass = Sth.dup
|
269
320
|
Sth.__send__ :member, :dummy1
|
270
|
-
assert_equal false, klass.member?(:
|
271
|
-
|
321
|
+
assert_equal false, klass.member?(:dummy1)
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_class_clone
|
272
325
|
klass = Sth.clone
|
273
326
|
Sth.__send__ :member, :dummy2
|
274
|
-
assert_equal false, klass.member?(:
|
327
|
+
assert_equal false, klass.member?(:dummy2)
|
275
328
|
end
|
276
329
|
end
|
277
330
|
|
@@ -304,7 +357,7 @@ end
|
|
304
357
|
|
305
358
|
class TestStriuctDefaultValue < Test::Unit::TestCase
|
306
359
|
Sth = Striuct.new do
|
307
|
-
member :lank,
|
360
|
+
member :lank, OR(Bignum, Fixnum)
|
308
361
|
default :lank, 1
|
309
362
|
end
|
310
363
|
|
@@ -324,13 +377,46 @@ class TestStriuctDefaultValue < Test::Unit::TestCase
|
|
324
377
|
default :anything, 10
|
325
378
|
end
|
326
379
|
end
|
327
|
-
|
380
|
+
|
381
|
+
klass = Striuct.define do
|
382
|
+
member :lank2, Integer
|
383
|
+
default :lank2, '10'
|
384
|
+
end
|
385
|
+
|
328
386
|
assert_raises Striuct::ConditionError do
|
329
|
-
|
330
|
-
|
331
|
-
|
387
|
+
klass.new
|
388
|
+
end
|
389
|
+
|
390
|
+
scope = self
|
391
|
+
seef = nil
|
392
|
+
klass = Striuct.define do
|
393
|
+
member :lank, Integer
|
394
|
+
scope.assert_raises ArgumentError do
|
395
|
+
default :lank, '10', &->own, name{rand}
|
396
|
+
end
|
397
|
+
|
398
|
+
scope.assert_raises ArgumentError do
|
399
|
+
default :lank, '10', &->own{rand}
|
400
|
+
end
|
401
|
+
|
402
|
+
scope.assert_raises ArgumentError do
|
403
|
+
default :lank, '10', &->{rand}
|
332
404
|
end
|
405
|
+
|
406
|
+
default :lank, &->own, name{(seef = own); rand}
|
407
|
+
end
|
408
|
+
|
409
|
+
assert_raises Striuct::ConditionError do
|
410
|
+
klass.new
|
411
|
+
end
|
412
|
+
|
413
|
+
klass = Striuct.define do
|
414
|
+
member :lank, Integer
|
415
|
+
default :lank, &->own, name{(seef = own); 10 - name.length}
|
333
416
|
end
|
417
|
+
|
418
|
+
assert_equal 6, klass.new.lank
|
419
|
+
assert_equal seef, klass.new
|
334
420
|
end
|
335
421
|
end
|
336
422
|
|
@@ -394,10 +480,18 @@ class TestStriuctAssign < Test::Unit::TestCase
|
|
394
480
|
assert_equal true, sth.assign?(:foo)
|
395
481
|
sth.unassign :foo
|
396
482
|
assert_equal false, sth.assign?(:foo)
|
483
|
+
sth.foo = nil
|
484
|
+
assert_equal true, sth.assign?(:foo)
|
485
|
+
sth.clear_at 0
|
486
|
+
assert_equal false, sth.assign?(:foo)
|
397
487
|
|
398
488
|
assert_raises NameError do
|
399
489
|
sth.unassign :var
|
400
490
|
end
|
491
|
+
|
492
|
+
assert_raises IndexError do
|
493
|
+
sth.unassign 1
|
494
|
+
end
|
401
495
|
end
|
402
496
|
end
|
403
497
|
|
@@ -473,18 +567,21 @@ class TestStriuctSafetyNaming < Test::Unit::TestCase
|
|
473
567
|
assert_same false, klass.cname?('__foo__')
|
474
568
|
assert_same false, klass.cname?('a b')
|
475
569
|
assert_same false, klass.cname?('object_id')
|
570
|
+
assert_same false, klass.cname?('to_ary')
|
476
571
|
assert_same true, klass.cname?('foo')
|
477
572
|
klass.__send__ :protect_level, :warning
|
478
573
|
assert_same false, klass.cname?('m?')
|
479
574
|
assert_same false, klass.cname?('__foo__')
|
480
575
|
assert_same false, klass.cname?('a b')
|
481
576
|
assert_same false, klass.cname?('object_id')
|
577
|
+
assert_same false, klass.cname?('to_ary')
|
482
578
|
assert_same true, klass.cname?('foo')
|
483
579
|
klass.__send__ :protect_level, :struct
|
484
580
|
assert_same true, klass.cname?('m?')
|
485
581
|
assert_same true, klass.cname?('__foo__')
|
486
582
|
assert_same true, klass.cname?('a b')
|
487
583
|
assert_same true, klass.cname?('object_id')
|
584
|
+
assert_same true, klass.cname?('to_ary')
|
488
585
|
assert_same true, klass.cname?('foo')
|
489
586
|
end
|
490
587
|
|
@@ -578,3 +675,535 @@ class TestStriuctInference < Test::Unit::TestCase
|
|
578
675
|
assert_equal 2, sth.m
|
579
676
|
end
|
580
677
|
end
|
678
|
+
|
679
|
+
class TestStriuctLoadPairs < Test::Unit::TestCase
|
680
|
+
Sth = Striuct.new :foo, :bar, :hoge
|
681
|
+
|
682
|
+
def test_load_pairs
|
683
|
+
sth = Sth[hoge: 7, foo: 8]
|
684
|
+
|
685
|
+
assert_equal [8, nil, 7], sth.values
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
class TestStriuctObject < Test::Unit::TestCase
|
690
|
+
Sth = Striuct.new :foo, :bar, :hoge
|
691
|
+
|
692
|
+
def test_hash
|
693
|
+
sth1 = Sth[hoge: 7, foo: 8]
|
694
|
+
sth2 = Sth[hoge: 7, foo: 8]
|
695
|
+
assert_equal true, sth1.eql?(sth2)
|
696
|
+
assert_equal true, sth2.eql?(sth1)
|
697
|
+
assert_equal sth1.hash, sth2.hash
|
698
|
+
assert_equal true, {sth1 => 1}.has_key?(sth2)
|
699
|
+
assert_equal true, {sth2 => 1}.has_key?(sth1)
|
700
|
+
assert_equal 1, {sth1 => 1}[sth2]
|
701
|
+
assert_equal 1, {sth2 => 1}[sth1]
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
class TestStriuctHashLike < Test::Unit::TestCase
|
706
|
+
Sth = Striuct.new :foo, :bar, :hoge
|
707
|
+
|
708
|
+
def test_empty?
|
709
|
+
sth = Sth[hoge: 7, foo: 8]
|
710
|
+
assert_equal false, sth.empty?
|
711
|
+
sth.each_member{|name|sth[name] = nil}
|
712
|
+
assert_equal false, sth.empty?
|
713
|
+
sth.each_member{|name|sth.unassign name}
|
714
|
+
assert_equal true, sth.empty?
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_has_value?
|
718
|
+
sth = Sth[hoge: 7, foo: 8]
|
719
|
+
assert_equal true, sth.value?(7)
|
720
|
+
assert_equal true, sth.value?(8)
|
721
|
+
assert_equal false, sth.value?(9)
|
722
|
+
assert_equal false, sth.value?(nil)
|
723
|
+
end
|
724
|
+
|
725
|
+
def test_select!
|
726
|
+
sth = Sth[hoge: 7, foo: 8]
|
727
|
+
sth2, sth3 = sth.dup, sth.dup
|
728
|
+
|
729
|
+
assert_kind_of Enumerator, enum = sth.select!
|
730
|
+
assert_equal [:foo, 8], enum.next
|
731
|
+
assert_equal [:bar, nil], enum.next
|
732
|
+
assert_equal [:hoge, 7], enum.next
|
733
|
+
assert_raises StopIteration do
|
734
|
+
enum.next
|
735
|
+
end
|
736
|
+
|
737
|
+
assert_equal nil, sth2.select!{|k, v|true}
|
738
|
+
assert_equal sth3, sth3.select!{|k, v|k == :hoge && v == 7}
|
739
|
+
assert_equal nil, sth3.foo
|
740
|
+
assert_equal true, sth3.assign?(:hoge)
|
741
|
+
assert_equal false, sth3.assign?(:foo)
|
742
|
+
assert_equal 7, sth3.hoge
|
743
|
+
end
|
744
|
+
|
745
|
+
def test_keep_if
|
746
|
+
sth = Sth[hoge: 7, foo: 8]
|
747
|
+
sth2, sth3 = sth.dup, sth.dup
|
748
|
+
|
749
|
+
assert_kind_of Enumerator, enum = sth.keep_if
|
750
|
+
assert_equal [:foo, 8], enum.next
|
751
|
+
assert_equal [:bar, nil], enum.next
|
752
|
+
assert_equal [:hoge, 7], enum.next
|
753
|
+
assert_raises StopIteration do
|
754
|
+
enum.next
|
755
|
+
end
|
756
|
+
|
757
|
+
assert_equal sth2, sth2.keep_if{|k, v|true}
|
758
|
+
assert_equal sth3, sth3.keep_if{|k, v|k == :hoge && v == 7}
|
759
|
+
assert_equal nil, sth3.foo
|
760
|
+
assert_equal true, sth3.assign?(:hoge)
|
761
|
+
assert_equal false, sth3.assign?(:foo)
|
762
|
+
assert_equal 7, sth3.hoge
|
763
|
+
end
|
764
|
+
|
765
|
+
def test_reject!
|
766
|
+
sth = Sth[hoge: 7, foo: 8]
|
767
|
+
sth2, sth3 = sth.dup, sth.dup
|
768
|
+
|
769
|
+
assert_kind_of Enumerator, enum = sth.reject!
|
770
|
+
assert_equal [:foo, 8], enum.next
|
771
|
+
assert_equal [:bar, nil], enum.next
|
772
|
+
assert_equal [:hoge, 7], enum.next
|
773
|
+
assert_raises StopIteration do
|
774
|
+
enum.next
|
775
|
+
end
|
776
|
+
|
777
|
+
enum.rewind
|
778
|
+
assert_equal [:foo, 8], enum.next
|
779
|
+
|
780
|
+
assert_equal nil, sth2.reject!{|k, v|false}
|
781
|
+
assert_equal sth3, sth3.reject!{|k, v|k == :hoge && v == 7}
|
782
|
+
assert_equal nil, sth3.hoge
|
783
|
+
assert_equal false, sth3.assign?(:hoge)
|
784
|
+
assert_equal true, sth3.assign?(:foo)
|
785
|
+
assert_equal 8, sth3.foo
|
786
|
+
end
|
787
|
+
|
788
|
+
def test_delete_if
|
789
|
+
sth = Sth[hoge: 7, foo: 8]
|
790
|
+
sth2, sth3 = sth.dup, sth.dup
|
791
|
+
|
792
|
+
assert_kind_of Enumerator, enum = sth.delete_if
|
793
|
+
|
794
|
+
assert_equal [:foo, 8], enum.next
|
795
|
+
assert_equal [:bar, nil], enum.next
|
796
|
+
assert_equal [:hoge, 7], enum.next
|
797
|
+
assert_raises StopIteration do
|
798
|
+
enum.next
|
799
|
+
end
|
800
|
+
|
801
|
+
assert_equal sth2, sth2.delete_if{|k, v|false}
|
802
|
+
assert_equal sth3, sth3.delete_if{|k, v|k == :hoge && v == 7}
|
803
|
+
assert_equal nil, sth3.hoge
|
804
|
+
assert_equal false, sth3.assign?(:hoge)
|
805
|
+
assert_equal true, sth3.assign?(:foo)
|
806
|
+
assert_equal 8, sth3.foo
|
807
|
+
end
|
808
|
+
|
809
|
+
def test_assoc
|
810
|
+
sth = Sth[hoge: 7, foo: 8]
|
811
|
+
|
812
|
+
assert_equal [:foo, 8], sth.assoc(:foo)
|
813
|
+
assert_equal [:bar, nil], sth.assoc(:bar)
|
814
|
+
assert_equal [:hoge, 7], sth.assoc(:hoge)
|
815
|
+
|
816
|
+
assert_raises NameError do
|
817
|
+
sth.assoc(:dummy)
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
821
|
+
def test_rassoc
|
822
|
+
sth = Sth[hoge: 7, foo: 7]
|
823
|
+
|
824
|
+
assert_equal [:foo, 7], sth.rassoc(7)
|
825
|
+
assert_equal [:bar, nil], sth.rassoc(nil)
|
826
|
+
assert_equal nil, sth.rassoc(9)
|
827
|
+
end
|
828
|
+
|
829
|
+
def test_flatten
|
830
|
+
sth = Sth[hoge: 7, foo: 8, bar: [1, 2]]
|
831
|
+
assert_equal [:foo, 8, :bar, [1, 2], :hoge, 7], sth.flatten
|
832
|
+
assert_equal [:foo, 8, :bar, [1, 2], :hoge, 7], sth.flatten(1)
|
833
|
+
assert_equal [:foo, 8, :bar, 1, 2, :hoge, 7], sth.flatten(2)
|
834
|
+
assert_equal [:foo, 8, :bar, 1, 2, :hoge, 7], sth.flatten(3)
|
835
|
+
assert_equal [:foo, 8, :bar, 1, 2, :hoge, 7], sth.flatten(-1)
|
836
|
+
end
|
837
|
+
|
838
|
+
def test_select
|
839
|
+
sth = Sth[hoge: 7, foo: 8]
|
840
|
+
|
841
|
+
assert_kind_of Enumerator, enum = sth.select
|
842
|
+
|
843
|
+
assert_equal Sth[hoge: 7], sth.select{|k, v|k == :hoge}
|
844
|
+
end
|
845
|
+
|
846
|
+
def test_reject
|
847
|
+
sth = Sth[hoge: 7, foo: 8]
|
848
|
+
|
849
|
+
assert_kind_of Enumerator, enum = sth.reject
|
850
|
+
|
851
|
+
assert_equal Sth[foo: 8], sth.reject{|k, v|k == :hoge}
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
|
856
|
+
class TestStriuctAliasMember < Test::Unit::TestCase
|
857
|
+
class Sth < Striuct.new
|
858
|
+
member :foo, String
|
859
|
+
|
860
|
+
member :bar, Integer do |v|
|
861
|
+
v
|
862
|
+
end
|
863
|
+
|
864
|
+
member :hoge, Symbol
|
865
|
+
default :hoge, :'Z'
|
866
|
+
alias_member :abc, :bar
|
867
|
+
default :abc, 8
|
868
|
+
end
|
869
|
+
|
870
|
+
def test_alias_member
|
871
|
+
sth = Sth.new 'A'
|
872
|
+
assert_equal [:foo, :bar, :hoge], sth.members
|
873
|
+
|
874
|
+
assert_equal 8, sth[:abc]
|
875
|
+
flavor = Sth.__send__(:flavor_for, :abc)
|
876
|
+
assert_kind_of Proc, flavor
|
877
|
+
assert_same flavor, Sth.__send__(:flavor_for, :bar)
|
878
|
+
assert_equal 8, sth.abc
|
879
|
+
sth.abc = 5
|
880
|
+
assert_equal 5, sth.bar
|
881
|
+
sth[:abc] = 6
|
882
|
+
assert_equal 6, sth.bar
|
883
|
+
|
884
|
+
assert_raises Striuct::ConditionError do
|
885
|
+
sth[:abc] = 'a'
|
886
|
+
end
|
887
|
+
|
888
|
+
assert_raises Striuct::ConditionError do
|
889
|
+
sth.abc = 'a'
|
890
|
+
end
|
891
|
+
|
892
|
+
assert_raises Striuct::ConditionError do
|
893
|
+
sth.bar = 'a'
|
894
|
+
end
|
895
|
+
|
896
|
+
assert_raises ArgumentError do
|
897
|
+
Sth.class_eval do
|
898
|
+
member :abc
|
899
|
+
end
|
900
|
+
end
|
901
|
+
end
|
902
|
+
end
|
903
|
+
|
904
|
+
class TestStriuctSpecificConditions < Test::Unit::TestCase
|
905
|
+
Sth = Striuct.define do
|
906
|
+
member :list_only_int, generics(Integer)
|
907
|
+
member :true_or_false, boolean
|
908
|
+
member :like_str, stringable
|
909
|
+
member :has_x, CAN(:x)
|
910
|
+
member :has_x_and_y, CAN(:x, :y)
|
911
|
+
member :one_of_member, member_of([1, 3])
|
912
|
+
member :has_ignore, AND(1..5, 3..10)
|
913
|
+
member :all_pass, OR(1..5, 3..10)
|
914
|
+
member :catch_name_error, CATCH(NameError){|v|v.no_name!}
|
915
|
+
member :no_exception, STILL(->v{v.class})
|
916
|
+
member :not_integer, NOT(Integer)
|
917
|
+
end
|
918
|
+
|
919
|
+
def test_not
|
920
|
+
sth = Sth.new
|
921
|
+
|
922
|
+
obj = Object.new
|
923
|
+
|
924
|
+
sth.not_integer = obj
|
925
|
+
assert_same obj, sth.not_integer
|
926
|
+
|
927
|
+
assert_raises Striuct::ConditionError do
|
928
|
+
sth.not_integer = 1
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
|
933
|
+
def test_still
|
934
|
+
sth = Sth.new
|
935
|
+
|
936
|
+
obj = Object.new
|
937
|
+
|
938
|
+
sth.no_exception = obj
|
939
|
+
assert_same obj, sth.no_exception
|
940
|
+
sth.no_exception = false
|
941
|
+
|
942
|
+
obj.singleton_class.class_eval do
|
943
|
+
undef_method :class
|
944
|
+
end
|
945
|
+
|
946
|
+
assert_raises Striuct::ConditionError do
|
947
|
+
sth.no_exception = obj
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
951
|
+
def test_catch
|
952
|
+
sth = Sth.new
|
953
|
+
|
954
|
+
obj = Object.new
|
955
|
+
|
956
|
+
sth.catch_name_error = obj
|
957
|
+
assert_same obj, sth.catch_name_error
|
958
|
+
sth.catch_name_error = false
|
959
|
+
|
960
|
+
obj.singleton_class.class_eval do
|
961
|
+
def no_name!
|
962
|
+
end
|
963
|
+
end
|
964
|
+
|
965
|
+
assert_raises Striuct::ConditionError do
|
966
|
+
sth.catch_name_error = obj
|
967
|
+
end
|
968
|
+
end
|
969
|
+
|
970
|
+
def test_or
|
971
|
+
sth = Sth.new
|
972
|
+
|
973
|
+
assert_raises Striuct::ConditionError do
|
974
|
+
sth.all_pass = 11
|
975
|
+
end
|
976
|
+
|
977
|
+
sth.all_pass = 1
|
978
|
+
assert_equal 1, sth.all_pass
|
979
|
+
sth.all_pass = 4
|
980
|
+
assert_equal 4, sth.all_pass
|
981
|
+
assert_equal true, sth.valid?(:all_pass)
|
982
|
+
end
|
983
|
+
|
984
|
+
def test_and
|
985
|
+
sth = Sth.new
|
986
|
+
|
987
|
+
assert_raises Striuct::ConditionError do
|
988
|
+
sth.has_ignore = 1
|
989
|
+
end
|
990
|
+
|
991
|
+
assert_raises Striuct::ConditionError do
|
992
|
+
sth.has_ignore = 2
|
993
|
+
end
|
994
|
+
|
995
|
+
sth.has_ignore = 3
|
996
|
+
assert_equal 3, sth.has_ignore
|
997
|
+
assert_equal true, sth.valid?(:has_ignore)
|
998
|
+
|
999
|
+
assert_raises Striuct::ConditionError do
|
1000
|
+
sth.has_ignore = []
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
def test_member_of
|
1005
|
+
sth = Sth.new
|
1006
|
+
|
1007
|
+
assert_raises Striuct::ConditionError do
|
1008
|
+
sth.one_of_member = 4
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
sth.one_of_member = 3
|
1012
|
+
assert_equal 3, sth.one_of_member
|
1013
|
+
assert_equal true, sth.valid?(:one_of_member)
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
def test_generics
|
1017
|
+
sth = Sth.new
|
1018
|
+
|
1019
|
+
assert_raises Striuct::ConditionError do
|
1020
|
+
sth.list_only_int = [1, '2']
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
sth.list_only_int = [1, 2]
|
1024
|
+
assert_equal [1, 2], sth.list_only_int
|
1025
|
+
assert_equal true, sth.valid?(:list_only_int)
|
1026
|
+
sth.list_only_int = []
|
1027
|
+
assert_equal [], sth.list_only_int
|
1028
|
+
assert_equal true, sth.valid?(:list_only_int)
|
1029
|
+
sth.list_only_int << '2'
|
1030
|
+
assert_equal false, sth.valid?(:list_only_int)
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
def test_boolean
|
1034
|
+
sth = Sth.new
|
1035
|
+
|
1036
|
+
assert_raises Striuct::ConditionError do
|
1037
|
+
sth.true_or_false = nil
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
assert_equal false, sth.valid?(:true_or_false)
|
1041
|
+
|
1042
|
+
sth.true_or_false = true
|
1043
|
+
assert_equal true, sth.true_or_false
|
1044
|
+
assert_equal true, sth.valid?(:true_or_false)
|
1045
|
+
sth.true_or_false = false
|
1046
|
+
assert_equal false, sth.true_or_false
|
1047
|
+
assert_equal true, sth.valid?(:true_or_false)
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
def test_stringable
|
1051
|
+
sth = Sth.new
|
1052
|
+
obj = Object.new
|
1053
|
+
|
1054
|
+
assert_raises Striuct::ConditionError do
|
1055
|
+
sth.like_str = obj
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
sth.like_str = 'str'
|
1059
|
+
assert_equal true, sth.valid?(:like_str)
|
1060
|
+
sth.like_str = :sym
|
1061
|
+
assert_equal true, sth.valid?(:like_str)
|
1062
|
+
|
1063
|
+
obj.singleton_class.class_eval do
|
1064
|
+
def to_str
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
sth.like_str = obj
|
1069
|
+
assert_equal true, sth.valid?(:like_str)
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
def test_responsible_arg1
|
1073
|
+
sth = Sth.new
|
1074
|
+
obj = Object.new
|
1075
|
+
|
1076
|
+
assert_raises Striuct::ConditionError do
|
1077
|
+
sth.has_x = obj
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
obj.singleton_class.class_eval do
|
1081
|
+
def x
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
sth.has_x = obj
|
1086
|
+
assert_equal obj, sth.has_x
|
1087
|
+
assert_equal true, sth.valid?(:has_x)
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
def test_responsible_arg2
|
1091
|
+
sth = Sth.new
|
1092
|
+
obj = Object.new
|
1093
|
+
|
1094
|
+
assert_raises Striuct::ConditionError do
|
1095
|
+
sth.has_x_and_y = obj
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
obj.singleton_class.class_eval do
|
1099
|
+
def x
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
assert_raises Striuct::ConditionError do
|
1104
|
+
sth.has_x_and_y = obj
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
obj.singleton_class.class_eval do
|
1108
|
+
def y
|
1109
|
+
end
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
sth.has_x_and_y = obj
|
1113
|
+
assert_equal obj, sth.has_x_and_y
|
1114
|
+
assert_equal true, sth.valid?(:has_x_and_y)
|
1115
|
+
end
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
|
1119
|
+
class TestStriuctLock < Test::Unit::TestCase
|
1120
|
+
Sth = Striuct.new :foo, :bar
|
1121
|
+
Sth.__send__ :close
|
1122
|
+
|
1123
|
+
def test_lock
|
1124
|
+
sth = Sth.new
|
1125
|
+
assert_equal false, sth.lock?(:foo)
|
1126
|
+
assert_equal false, sth.lock?(:bar)
|
1127
|
+
assert_equal false, sth.secure?
|
1128
|
+
sth.lock :bar
|
1129
|
+
assert_equal true, sth.lock?(:bar)
|
1130
|
+
assert_equal false, sth.secure?
|
1131
|
+
|
1132
|
+
assert_raises RuntimeError do
|
1133
|
+
sth.bar = 1
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
sth.__send__ :unlock, :bar
|
1137
|
+
|
1138
|
+
assert_equal false, sth.lock?(:bar)
|
1139
|
+
|
1140
|
+
sth.bar = 1
|
1141
|
+
assert_equal 1, sth.bar
|
1142
|
+
|
1143
|
+
sth.lock
|
1144
|
+
assert_equal true, sth.lock?(:foo)
|
1145
|
+
assert_equal true, sth.lock?(:bar)
|
1146
|
+
assert_equal true, sth.lock?
|
1147
|
+
|
1148
|
+
assert_raises RuntimeError do
|
1149
|
+
sth.foo = 1
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
assert_equal true, sth.secure?
|
1153
|
+
end
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
class TestStriuctInherit < Test::Unit::TestCase
|
1157
|
+
Sth = Striuct.define do
|
1158
|
+
member :foo, String
|
1159
|
+
member :bar, OR(nil, Fixnum)
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
class SubSth < Sth
|
1163
|
+
member :hoge, OR(nil, 1..3)
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
class SubSubSth < SubSth
|
1167
|
+
member :rest, AND(/\d/, Symbol)
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
def test_inherit
|
1171
|
+
assert_equal [*Sth.members, :hoge], SubSth.members
|
1172
|
+
sth = Sth.new
|
1173
|
+
substh = SubSth.new
|
1174
|
+
|
1175
|
+
assert_raises Striuct::ConditionError do
|
1176
|
+
substh.bar = 'str'
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
assert_raises Striuct::ConditionError do
|
1180
|
+
substh.hoge = 4
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
assert_raises NoMethodError do
|
1184
|
+
sth.hoge = 3
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
assert_raises NoMethodError do
|
1188
|
+
substh.rest = :a4
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
subsubsth = SubSubSth.new
|
1192
|
+
|
1193
|
+
assert_raises Striuct::ConditionError do
|
1194
|
+
subsubsth.rest = 4
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
subsubsth.rest = :a4
|
1198
|
+
|
1199
|
+
assert_equal :a4, subsubsth[:rest]
|
1200
|
+
|
1201
|
+
assert_equal true, Sth.__send__(:closed?)
|
1202
|
+
assert_equal false, SubSth.__send__(:closed?)
|
1203
|
+
SubSth.__send__(:close)
|
1204
|
+
assert_equal true, SubSth.__send__(:closed?)
|
1205
|
+
assert_equal false, SubSubSth.__send__(:closed?)
|
1206
|
+
SubSubSth.__send__(:close)
|
1207
|
+
assert_equal true, SubSubSth.__send__(:closed?)
|
1208
|
+
end
|
1209
|
+
end
|