ruby-ext 0.2.2 → 0.2.3

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 (101) hide show
  1. data/.git/COMMIT_EDITMSG +1 -1
  2. data/.git/index +0 -0
  3. data/.git/logs/HEAD +3 -0
  4. data/.git/logs/refs/heads/master +3 -0
  5. data/.git/logs/refs/remotes/origin/master +3 -0
  6. data/.git/objects/3a/5fe0dc6aaa6e41eb8dd865fa7d7100f4e68ced +0 -0
  7. data/.git/objects/49/3774d80093f4ec3c6c3bfad21e1c8c9eaf41ec +0 -0
  8. data/.git/objects/52/94913c6107b381d1378279e58551fa2be7cecb +0 -0
  9. data/.git/objects/57/ab6c10ddf4eff75d98b5770a2c2bf573b692cd +0 -0
  10. data/.git/objects/61/beeaa4bc6790a469babafbdc7395e9e19dcb5d +0 -0
  11. data/.git/objects/62/3a67b104c04e24316da21f3e229e1bc2ba9d31 +0 -0
  12. data/.git/objects/6d/1da4d8a2949a1a9714d5f9979c7ee9613d7cfd +0 -0
  13. data/.git/objects/7f/2c583d1fdcc5313140c57778be8b0d45824be9 +0 -0
  14. data/.git/objects/9f/e2acc9bded3dc0d29b1dfc7dc1b3bed5d72c8f +0 -0
  15. data/.git/objects/e1/3f643da891453763504616e4f5a8195b8ffdb9 +0 -0
  16. data/.git/objects/ee/69f9fad83c5b0668b62622037094e989d3c394 +0 -0
  17. data/.git/refs/heads/master +1 -1
  18. data/.git/refs/remotes/origin/master +1 -1
  19. data/Rakefile +2 -2
  20. data/lib/ruby_ext/should.rb +14 -0
  21. data/old/README +860 -0
  22. data/old/lib/RubyExt/ClassLoader.rb +142 -0
  23. data/old/lib/RubyExt/ExtraBlankSlate.rb +14 -0
  24. data/old/lib/RubyExt/ImportAll.rb +9 -0
  25. data/old/lib/RubyExt/Localization/Module.rb +12 -0
  26. data/old/lib/RubyExt/Localization/Object.rb +19 -0
  27. data/old/lib/RubyExt/Localization/require.rb +3 -0
  28. data/old/lib/RubyExt/Localization.rb +28 -0
  29. data/old/lib/RubyExt/Log.config.sample +57 -0
  30. data/old/lib/RubyExt/Log.rb +59 -0
  31. data/old/lib/RubyExt/Path.rb +91 -0
  32. data/old/lib/RubyExt/Resource/file_system_provider.rb +273 -0
  33. data/old/lib/RubyExt/StateMashine.rb +176 -0
  34. data/old/lib/RubyExt/array.rb +24 -0
  35. data/old/lib/RubyExt/class.rb +0 -0
  36. data/old/lib/RubyExt/debug.rb +71 -0
  37. data/old/lib/RubyExt/false_class.rb +5 -0
  38. data/old/lib/RubyExt/kernel.rb +3 -0
  39. data/old/lib/RubyExt/module.rb +26 -0
  40. data/old/lib/RubyExt/nil_class.rb +5 -0
  41. data/old/lib/RubyExt/observable.rb +25 -0
  42. data/old/lib/RubyExt/require.rb +1 -0
  43. data/old/lib/RubyExt/require_base.rb +1 -0
  44. data/old/lib/RubyExt/resource.rb +172 -0
  45. data/old/lib/RubyExt/true_class.rb +5 -0
  46. data/old/rakefile +52 -0
  47. data/old/require.rb +3 -0
  48. data/old/require_base.rb +3 -0
  49. data/old/spec/RubyExt/ForClassLoader/ClassA.rb +4 -0
  50. data/old/spec/RubyExt/ForClassLoader/LoadCount.rb +1 -0
  51. data/old/spec/RubyExt/ForClassLoader/ModuleA/ClassB.rb +3 -0
  52. data/old/spec/RubyExt/ForClassLoader/ModuleA/ClassInsideAnonymousClass.rb +3 -0
  53. data/old/spec/RubyExt/ForClassLoader/ModuleA/InfinityLoop.rb +3 -0
  54. data/old/spec/RubyExt/ForClassLoader/ModuleA/ModuleB/ClassC.rb +3 -0
  55. data/old/spec/RubyExt/ForClassLoader/ModuleA/SameName/SomeClass.rb +2 -0
  56. data/old/spec/RubyExt/ForClassLoader/ModuleA/SameName.rb +2 -0
  57. data/old/spec/RubyExt/ForClassLoader/Scope/ScopeA1.rb +3 -0
  58. data/old/spec/RubyExt/ForClassLoader/Scope/ScopeB1.rb +5 -0
  59. data/old/spec/RubyExt/ForKernel/Raise2.rb +5 -0
  60. data/old/spec/RubyExt/ForKernel/RaiseWithoutSelf.rb +9 -0
  61. data/old/spec/RubyExt/ForLocalization/NS/A.rb +3 -0
  62. data/old/spec/RubyExt/ForLocalization/NS/A.ru.localization.yaml +2 -0
  63. data/old/spec/RubyExt/ForLocalization/NS/B.rb +22 -0
  64. data/old/spec/RubyExt/ForLocalization/NS/B.ru.localization.yaml +3 -0
  65. data/old/spec/RubyExt/ForLocalization/NS.ru.localization.yaml +2 -0
  66. data/old/spec/RubyExt/ForModule/NS1/A.data +1 -0
  67. data/old/spec/RubyExt/ForModule/NS1/A.rb +1 -0
  68. data/old/spec/RubyExt/ForModule/NS1/A2.rb +1 -0
  69. data/old/spec/RubyExt/ForModule/NS1/B.rb +2 -0
  70. data/old/spec/RubyExt/ForModule/NS1/B2.rb +1 -0
  71. data/old/spec/RubyExt/ForModule/NS1.data +1 -0
  72. data/old/spec/RubyExt/ForModule/NS2/A.data +1 -0
  73. data/old/spec/RubyExt/ForModule/NS2/A.rb +3 -0
  74. data/old/spec/RubyExt/ForModule/NS2/B.rb +3 -0
  75. data/old/spec/RubyExt/ForModule/NS2/M.data +1 -0
  76. data/old/spec/RubyExt/ForModule/NS2/M.rb +3 -0
  77. data/old/spec/RubyExt/ForResource/ChangedClass.rb +1 -0
  78. data/old/spec/RubyExt/ForResource/ChangedClass.res/Text.txt +0 -0
  79. data/old/spec/RubyExt/ForResource/ChangedClass.txt +0 -0
  80. data/old/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.rb +3 -0
  81. data/old/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.resource +1 -0
  82. data/old/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ClassExistOnlyInProviderA.rb +3 -0
  83. data/old/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.rb +3 -0
  84. data/old/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.resource +1 -0
  85. data/old/spec/RubyExt/ForResource/ResourceExtension.rb +1 -0
  86. data/old/spec/RubyExt/ForResource/ResourceExtension.res/Data.yaml +2 -0
  87. data/old/spec/RubyExt/ForResource/ResourceTest/Test.rb +11 -0
  88. data/old/spec/RubyExt/ForResource/ResourceTest/Test.res/Data.txt +1 -0
  89. data/old/spec/RubyExt/ForResource/ResourceTest/Test.res/txt +1 -0
  90. data/old/spec/array_spec.rb +27 -0
  91. data/old/spec/class_loader_spec.rb +94 -0
  92. data/old/spec/import_all_spec.rb +21 -0
  93. data/old/spec/kernel_spec.rb +29 -0
  94. data/old/spec/localization_spec.rb +49 -0
  95. data/old/spec/module_spec.rb +14 -0
  96. data/old/spec/object_spec.rb +8 -0
  97. data/old/spec/observable_spec.rb +44 -0
  98. data/old/spec/path_spec.rb +169 -0
  99. data/old/spec/resource_spec.rb +136 -0
  100. data/old/spec/state_machine_spec.rb +201 -0
  101. metadata +93 -2
@@ -0,0 +1,14 @@
1
+ require 'RubyExt/require_base'
2
+ require 'spec'
3
+
4
+ module RubyExt
5
+ it "resources" do
6
+ ForModule::NS1::B["data"].should == "A.data"
7
+ ForModule::NS1::B2["data"].should == "NS1.data"
8
+ end
9
+
10
+ it "resources, should aslo inherit resources from included modules" do
11
+ ForModule::NS2::B["data"].should == "M.data"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ require 'RubyExt/require_base'
2
+ require 'spec'
3
+
4
+ module RubyExt
5
+ describe "Object" do
6
+
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ require 'RubyExt/require_base'
2
+ require 'spec'
3
+
4
+ module RubyExt
5
+ describe "Observable" do
6
+ class AnObservable
7
+ include Observable
8
+ end
9
+
10
+ it "Method without Parameters" do
11
+ mock = mock("Observer")
12
+ obs = AnObservable.new
13
+ obs.add_observer mock
14
+ mock.should_receive(:update).with(2)
15
+ obs.notify_observers :update, 2
16
+ end
17
+
18
+ # it "Method without Parameters" do
19
+ # mock = mock("Observer")
20
+ # obs = AnObservable.new
21
+ # obs.add_observer(mock, :method => :custom_update, :filter => lambda{|o| o == 2})
22
+ # mock.should_receive(:custom_update).with(2)
23
+ # obs.notify_observers 2
24
+ # obs.notify_observers 4
25
+ # end
26
+ #
27
+ # it "With Block" do
28
+ # mock = mock("Observer")
29
+ # mock.should_receive(:got)
30
+ # obs = AnObservable.new
31
+ # obs.add_observer{mock.got}
32
+ # obs.notify_observers
33
+ # end
34
+ #
35
+ # it "With Block and Filter" do
36
+ # mock = mock("Observer")
37
+ # obs = AnObservable.new
38
+ # obs.add_observer(:filter => lambda{|o| o == 2}){|o| mock.got o}
39
+ # mock.should_receive(:got).with(2)
40
+ # obs.notify_observers 2
41
+ # obs.notify_observers 4
42
+ # end
43
+ end
44
+ end
@@ -0,0 +1,169 @@
1
+ require 'RubyExt/require_base'
2
+ require 'spec'
3
+
4
+ module RubyExt
5
+ describe "Path" do
6
+ it '+' do
7
+ (Path.new('/aa')+'bb').should == Path.new('/aa/bb')
8
+ (Path.new('aa')+'bb').should == Path.new('aa/bb')
9
+ (Path.new('/aa')+Path.new('bb')).should == Path.new('/aa/bb')
10
+ end
11
+
12
+ it "Invaalid path" do
13
+ lambda{Path.new '//aa'}.should raise_error
14
+ lambda{Path.new '//'}.should raise_error
15
+ lambda{Path.new '/aa//bb'}.should raise_error
16
+ lambda{Path.new 'aa//bb'}.should raise_error
17
+ end
18
+
19
+ it "simple?" do
20
+ Path.new('aa').should be_simple
21
+ Path.new('/aa').should be_simple
22
+ Path.new('').should be_simple
23
+ Path.new('/').should be_simple
24
+
25
+ Path.new('aa/bb').should_not be_simple
26
+ Path.new('/aa/bb').should_not be_simple
27
+ end
28
+
29
+ it "should bbe cconvertaabble to String" do
30
+ Path.new('aa').to_s.class.should == String
31
+ end
32
+
33
+ it 'bbaase operaations' do
34
+ Path.new('/').empty?.should be_true
35
+ Path.new('aa').absolute?.should be_false
36
+ Path.new('/aa').absolute?.should be_true
37
+ end
38
+
39
+ it 'first && last' do
40
+ path = Path.new("/aa/bb/cc")
41
+ path.first.should == Path.new('/aa')
42
+ path.last.should == Path.new('/cc')
43
+
44
+ path = Path.new("/")
45
+ path.should == path.first
46
+ path.should == path.last
47
+
48
+ path = Path.new("aa/bb/cc")
49
+ Path.new('aa').should == path.first
50
+ Path.new('cc').should == path.last
51
+
52
+ path = Path.new("")
53
+ path.should == path.first
54
+ path.should == path.last
55
+ end
56
+
57
+ it 'first_name & last_name' do
58
+ path = Path.new("/aa/bb/cc")
59
+ path.last_name.should == 'cc'
60
+ path.first_name.should == 'aa'
61
+
62
+ path = Path.new("/")
63
+ path.last_name.should == nil
64
+ path.first_name.should == nil
65
+
66
+ path = Path.new("aa/bb/cc")
67
+ path.last_name.should == 'cc'
68
+ path.first_name.should == 'aa'
69
+
70
+ path = Path.new("")
71
+ path.last_name.should == nil
72
+ path.first_name.should == nil
73
+ end
74
+
75
+ it "next & previous" do
76
+ path = Path.new("/aa/bb/cc")
77
+
78
+ path.previous.should == Path.new('/aa/bb')
79
+ path.previous.previous.previous.should == Path.new("/")
80
+ path.previous.previous.previous.previous.should == nil
81
+
82
+ path.next.should == Path.new('/bb/cc')
83
+ path.next.next.next.should == nil
84
+
85
+ path = Path.new("aa/bb/cc")
86
+
87
+ path.previous.should == Path.new('aa/bb')
88
+ path.previous.previous.previous.should == Path.new
89
+ path.previous.previous.previous.previous.should == nil
90
+
91
+ path.next.should == Path.new('bb/cc')
92
+ path.next.next.next.should == nil
93
+ end
94
+
95
+ it 'aabbsolute path' do
96
+ path = Path.new("/aa/bb/cc")
97
+
98
+ str = ''
99
+ path.each do |p|
100
+ str << p.to_s
101
+ end
102
+ str.should == 'aabbcc'
103
+
104
+ path.size.should == 3
105
+
106
+ Path.new("/bb/cc").should == "/bb/cc"
107
+
108
+ path.after('aa').should == '/bb/cc'
109
+ path.after('bb').should == '/cc'
110
+ path.after('cc').should == '/'
111
+ path.before('aa').should == '/'
112
+ path.before('bb').should == '/aa'
113
+ path.before('cc').should == '/aa/bb'
114
+ end
115
+
116
+ it 'should cconvert to relative' do
117
+ Path.new("aa").should == Path.new("/aa").to_relative
118
+ end
119
+
120
+ it 'should cconvert to String' do
121
+ Path.new("/").to_s.should == "/"
122
+ Path.new("").to_s.should == ""
123
+ end
124
+
125
+ it 'should define ==' do
126
+ Path.new("aa/bb").should_not == Path.new("aa")
127
+ end
128
+
129
+ it "cconstrucctors should works" do
130
+ Path.new("")
131
+ Path.new("/")
132
+ end
133
+
134
+ it "should aappend to end aand staart" do
135
+ path = Path.new("")
136
+ path = path.add(Path.new("aa"))
137
+ path.should == Path.new("aa")
138
+
139
+ path = Path.new("bb")
140
+ path = path.add(Path.new("aa"))
141
+ path.should == Path.new("bb/aa")
142
+
143
+ path = Path.new("/")
144
+ path = path.add(Path.new("aa"))
145
+ path.should == Path.new("/aa")
146
+ end
147
+
148
+ it "relative path" do
149
+ path = Path.new("aa/bb/cc")
150
+
151
+ path.size.should == 3
152
+
153
+ str = ''
154
+ path.each do |p|
155
+ str << p.to_s
156
+ end
157
+ str.should == 'aabbcc'
158
+
159
+ Path.new("bb/cc").should == "bb/cc"
160
+
161
+ path.after('aa').should == 'bb/cc'
162
+ path.after('bb').should == 'cc'
163
+ path.after('cc').should == ''
164
+ path.before('aa').should == ''
165
+ path.before('bb').should == 'aa'
166
+ path.before('cc').should == 'aa/bb'
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,136 @@
1
+ require 'RubyExt/require_base'
2
+ require 'fileutils'
3
+ require 'spec'
4
+ Thread.abort_on_exception=true
5
+
6
+ module RubyExt
7
+ describe "Resource" do
8
+
9
+ before :all do
10
+ dir = "#{File.dirname(__FILE__)}/RubyExt/ForResource/ProviderChaining"
11
+ Resource.add_resource_provider RubyExt::FileSystemProvider.new(lambda{["#{dir}/ProviderABaseDir"]})
12
+ Resource.add_resource_provider RubyExt::FileSystemProvider.new(lambda{["#{dir}/ProviderBBaseDir"]})
13
+ end
14
+
15
+ it "class get, set, exist, delete" do
16
+ Resource.class_set("RubyExt::ForResource::ClassTest",
17
+ "class ClassTest; end", File.dirname(__FILE__))
18
+
19
+ Resource.class_exist?("RubyExt::ForResource::ClassTest").
20
+ should be_true
21
+
22
+ Resource.class_get("RubyExt::ForResource::ClassTest").
23
+ should == "class ClassTest; end"
24
+
25
+ Resource.class_delete("RubyExt::ForResource::ClassTest")
26
+ Resource.class_exist?("RubyExt::ForResource::ClassTest").
27
+ should be_false
28
+
29
+ end
30
+
31
+ it "namespace" do
32
+ Resource.class_exist?("RubyExt::ForResource").should be_true
33
+ end
34
+
35
+ it "resource get, set, delete, exist" do
36
+ dir = "#{File.dirname(__FILE__)}/RubyExt/ForResource/ResourceTest"
37
+ FileUtils.remove_dir(dir) if File.exist? dir
38
+
39
+ FileUtils.mkdir dir
40
+ File.write("#{dir}/Test.rb", "class Test; end")
41
+ File.write("#{dir}/Test.txt", "Test.txt")
42
+ FileUtils.mkdir "#{dir}/Test.res"
43
+ File.write("#{dir}/Test.res/Data.txt", "Data.txt")
44
+
45
+ Resource.resource_get(RubyExt::ForResource::ResourceTest::Test, "txt").
46
+ should == "Test.txt"
47
+ Resource.resource_get(RubyExt::ForResource::ResourceTest::Test, "Data.txt").
48
+ should == "Data.txt"
49
+
50
+ Resource.resource_exist?(RubyExt::ForResource::ResourceTest::Test, "txt").
51
+ should be_true
52
+ Resource.resource_exist?(RubyExt::ForResource::ResourceTest::Test, "Data.txt").
53
+ should be_true
54
+
55
+ Resource.resource_delete(RubyExt::ForResource::ResourceTest::Test, "txt")
56
+ Resource.resource_delete(RubyExt::ForResource::ResourceTest::Test, "Data.txt")
57
+ Resource.resource_exist?(RubyExt::ForResource::ResourceTest::Test, "txt").
58
+ should be_false
59
+ Resource.resource_exist?(RubyExt::ForResource::ResourceTest::Test, "Data.txt").
60
+ should be_false
61
+
62
+
63
+ Resource.resource_set(RubyExt::ForResource::ResourceTest::Test, "txt",
64
+ "Test.txt")
65
+ Resource.resource_set(RubyExt::ForResource::ResourceTest::Test, "Data.txt",
66
+ "Data.txt")
67
+ Resource.resource_get(RubyExt::ForResource::ResourceTest::Test, "txt").
68
+ should == "Test.txt"
69
+ Resource.resource_get(RubyExt::ForResource::ResourceTest::Test, "Data.txt").
70
+ should == "Data.txt"
71
+ end
72
+
73
+ it "Class to Path" do
74
+ lambda{Resource.class_to_virtual_file("A::B::C").should =~ /A\/B\/C/}.should raise_error(/doesn't exist!/)
75
+ Resource.class_to_virtual_file("RubyExt::ForResource::ResourceTest::Test").should =~
76
+ /RubyExt\/ForResource\/ResourceTest\/Test/
77
+ end
78
+
79
+ it "change listeners" do
80
+ class CustomObserver
81
+ attr_reader :classes, :resources
82
+
83
+ def initialize
84
+ @classes, @resources = [], []
85
+ end
86
+
87
+ def update_resource type, klass, resource
88
+ if type == :class
89
+ @classes << klass
90
+ else
91
+ @classes << klass
92
+ @resources << resource
93
+ end
94
+ end
95
+ end
96
+
97
+ obs = CustomObserver.new
98
+ Resource.add_observer obs
99
+
100
+ begin
101
+ FileSystemProvider.start_watching(1, [File.dirname __FILE__])
102
+
103
+ sleep 0.1
104
+ base = "#{File.dirname(__FILE__)}/RubyExt/ForResource"
105
+ File.write("#{base}/ChangedClass.rb", "class ChangedClass; end")
106
+ File.write("#{base}/ChangedClass.txt", "")
107
+ File.write("#{base}/ChangedClass.res/Text.txt", "")
108
+ sleep 1.5
109
+ ensure
110
+ FileSystemProvider.stop_watching
111
+ end
112
+
113
+ obs.classes.size.should == 3
114
+ obs.classes.all?{|k| k == ForResource::ChangedClass}.should be_true
115
+
116
+ obs.resources.size.should == 2
117
+ obs.resources.should include("txt")
118
+ obs.resources.should include("Text.txt")
119
+ end
120
+
121
+ it "ResourceProvider Chaining" do
122
+ Resource.class_get("ChainTest").should == %{\
123
+ class ChainTest;
124
+ # "ProviderB"
125
+ end}
126
+ Resource.resource_get(ChainTest, "resource").should == "ProviderB"
127
+ end
128
+
129
+ it "ResourceExtension" do
130
+ require "RubyExt/require"
131
+ Resource.resource_set RubyExt::ForResource::ResourceExtension, "Data.yaml", {:value => true}
132
+ res = Resource.resource_get RubyExt::ForResource::ResourceExtension, "Data.yaml"
133
+ res.should == {:value => true}
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,201 @@
1
+ require 'RubyExt/require'
2
+ require 'spec'
3
+
4
+ module RubyExt
5
+ describe "State Mashine" do
6
+ class Meta < StateMashine
7
+ initial_state :Creation
8
+ transitions [:Creation, :create, :View],
9
+ [:View, :edit, :Edit],
10
+ [:Edit, :save, :View],
11
+ [:Edit, :cancel, :View],
12
+ [:View, :delete, :Deleted]
13
+ end
14
+
15
+ class BareMeta < StateMashine
16
+ initial_state :Created
17
+ transitions [:Created, :delete, :Deleted]
18
+ end
19
+
20
+ class MetadataTest < StateMashine
21
+ transitions [:s1, :fun, :s2], [:s3, :fun, :s4]
22
+ end
23
+
24
+ before :each do
25
+ @state = Meta.new
26
+ end
27
+
28
+ it "Initial State" do
29
+ @state.should == :Creation
30
+ end
31
+
32
+ it "Exceptions in event processing should cause rollback in state change" do
33
+ @state.on_event :Creation, :create do
34
+ raise
35
+ end
36
+ lambda{@state.event :create}.should raise_error
37
+ @state.state.should == :Creation
38
+ end
39
+
40
+ it "Should properly process events inside another event (from error)" do
41
+ @state.on_event :Creation, :create do
42
+ @state.event :edit
43
+ end
44
+ @state.event :create
45
+ @state.state.should == :Edit
46
+ end
47
+
48
+ it "Transfer function" do
49
+ @state.event :create
50
+ @state.should == :View
51
+ end
52
+
53
+ it "==" do
54
+ state2 = Meta.new
55
+ @state.should == state2
56
+ @state.should == :Creation
57
+ end
58
+
59
+ it "before & after" do
60
+ @state.on_entry :View, :entry
61
+ @state.on_exit :View, :_exit
62
+
63
+ mock = mock("Events")
64
+ @state.object = mock
65
+
66
+ mock.should_receive(:entry).twice
67
+ @state.event :create
68
+ mock.should_receive(:_exit)
69
+ @state.event :edit
70
+
71
+ @state.event :cancel
72
+ @state.on_entry :View, nil
73
+ @state.on_exit :View, nil
74
+
75
+ @state.event :edit
76
+ end
77
+
78
+ it "on_event" do
79
+ mock = mock("Events")
80
+ mock.should_receive :create
81
+ @state.on_event :Creation, :create do
82
+ mock.create
83
+ end
84
+ @state.event :create
85
+ end
86
+
87
+ it "should also use block as action" do
88
+ mock = mock("Events")
89
+ @state.on_entry :View do
90
+ mock.entry
91
+ end
92
+
93
+ mock.should_receive(:entry)
94
+ @state.event :create
95
+ end
96
+
97
+ it "Invalid method" do
98
+ lambda{@state.event :invalid}.should raise_error(/There is no :invalid Event in :Creation State/)
99
+ end
100
+
101
+ it "Invalid state" do
102
+ lambda{@state.event :delete}.should raise_error(/There is no :delete Event in :Creation State!/)
103
+ end
104
+
105
+ it "Bare State" do
106
+ s = BareMeta.new
107
+ s.state = :Deleted
108
+ end
109
+
110
+ # (Waiting) - begin -> (Action) - begin -> (NestedAction) - begin n-times -> (NestedAction)
111
+ # <- end - <- end - < end n-times -
112
+ # <- cancel -
113
+ it "Custom Recursive State" do
114
+ class NestedAction
115
+ def initialize
116
+ @nesting_level = 0
117
+ end
118
+
119
+ def begin
120
+ @nesting_level += 1
121
+ :NestedAction
122
+ end
123
+
124
+ def end
125
+ if @nesting_level == 0
126
+ return :Action
127
+ else
128
+ @nesting_level -= 1
129
+ return :NestedAction
130
+ end
131
+ end
132
+
133
+ def cancel
134
+ @nesting_level = 0
135
+ return :Waiting
136
+ end
137
+
138
+ # Not required, can be omited
139
+ def state state
140
+ case state
141
+ when :Action
142
+ @nesting_level = 0
143
+ return :Action
144
+ else nil
145
+ end
146
+ end
147
+ end
148
+
149
+ class CustomState < StateMashine
150
+ initial_state :Waiting
151
+ transitions [:Waiting, :begin, :Action],
152
+ [:Action, :end, :Waiting],
153
+ [:Action, :begin, :NestedAction]
154
+ custom_state :NestedAction, NestedAction
155
+ end
156
+
157
+ sm = CustomState.new
158
+ sm.event :begin
159
+ sm.state.should == :Action
160
+ sm.event :begin
161
+ sm.state.should == :NestedAction
162
+
163
+ # Nested :begin/:end
164
+ sm.event :begin
165
+ sm.state.should == :NestedAction
166
+ sm.event :begin
167
+ sm.state.should == :NestedAction
168
+
169
+ sm.event :end
170
+ sm.state.should == :NestedAction
171
+ sm.event :end
172
+ sm.state.should == :NestedAction
173
+ lambda{sm.event :invalid}.should raise_error(/There is no :invalid Event in :NestedAction State/)
174
+
175
+ sm.event :end
176
+ sm.state.should == :Action
177
+
178
+ # Nested :cancel
179
+ sm.event :begin
180
+ sm.state.should == :NestedAction
181
+ sm.event :begin
182
+ sm.state.should == :NestedAction
183
+ sm.event :cancel
184
+ sm.state.should == :Waiting
185
+
186
+ # Correct working after :cancel
187
+ sm.event :begin
188
+ sm.state.should == :Action
189
+ sm.event :begin
190
+ sm.state.should == :NestedAction
191
+ sm.event :end
192
+ sm.state.should == :Action
193
+
194
+ # Should also works with "state= ..."
195
+ sm.event :begin
196
+ sm.state.should == :NestedAction
197
+ sm.state = :Action
198
+ sm.state.should == :Action
199
+ end
200
+ end
201
+ end