lspace 0.1.pre.1 → 0.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.
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe LSpace do
4
+ describe "eventmachine integration" do
5
+ before do
6
+ $foo = :fail
7
+ end
8
+
9
+ it "should preserve LSpace in deferrable callbacks" do
10
+ d = Class.new{ include EM::Deferrable }.new
11
+ LSpace.update(:foo => 2) do
12
+ d.callback do
13
+ $foo = LSpace[:foo]
14
+ end
15
+ end
16
+ d.succeed
17
+ $foo.should == 2
18
+ end
19
+
20
+ it "should preserve LSpace in deferrable errbacks" do
21
+ d = Class.new{ include EM::Deferrable }.new
22
+ LSpace.update(:foo => 2) do
23
+ d.errback do
24
+ $foo = LSpace[:foo]
25
+ end
26
+ end
27
+ d.fail
28
+ $foo.should == 2
29
+ end
30
+
31
+ it "should preserve LSpace in EM::defer operation" do
32
+ EM::run do
33
+ LSpace.update(:foo => 4) do
34
+ EM::defer(lambda{
35
+ $foo = LSpace[:foo]
36
+ }, proc{
37
+ EM::stop
38
+ })
39
+ end
40
+ end
41
+ $foo.should == 4
42
+ end
43
+
44
+ it "should preserve LSpace in EM::defer callback" do
45
+ EM::run do
46
+ LSpace.update(:foo => 4) do
47
+ EM::defer(lambda{
48
+ nil
49
+ }, proc{
50
+ $foo = LSpace[:foo]
51
+ EM::stop
52
+ })
53
+ end
54
+ end
55
+ $foo.should == 4
56
+ end
57
+
58
+ it "should preserve LSpace in EM.next_tick" do
59
+ EM::run do
60
+ EM::next_tick do
61
+ LSpace.update :foo => 5 do
62
+ EM::next_tick do
63
+ $foo = LSpace[:foo]
64
+ EM::stop
65
+ end
66
+ end
67
+ end
68
+
69
+ EM::next_tick do
70
+ LSpace[:foo].should_not == 5
71
+ end
72
+ end
73
+ $foo.should == 5
74
+ end
75
+
76
+ it "should preserve LSpace in all connection callbacks" do
77
+ $server = []
78
+ $client = []
79
+ server = Module.new do
80
+ def setup_lspace
81
+ LSpace[:foo] = :server
82
+ end
83
+
84
+ def post_init
85
+ $server << [:post_init, LSpace[:foo], LSpace[:bar]]
86
+ end
87
+
88
+ def receive_data(data)
89
+ $server << [:receive_data, LSpace[:foo], LSpace[:bar]]
90
+ send_data(data)
91
+ close_connection_after_writing
92
+ end
93
+
94
+ def unbind
95
+ $server << [:unbind, LSpace[:foo], LSpace[:bar]]
96
+ end
97
+ end
98
+
99
+ client = Module.new do
100
+ def setup_lspace
101
+ LSpace[:foo] = :client
102
+ end
103
+
104
+ def post_init
105
+ $client << [:post_init, LSpace[:foo], LSpace[:bar]]
106
+ send_data("Hi world\n")
107
+ end
108
+
109
+ def receive_data(data)
110
+ data.should == "Hi world\n"
111
+ $client << [:receive_data, LSpace[:foo], LSpace[:bar]]
112
+ end
113
+
114
+ def unbind
115
+ $client << [:unbind, LSpace[:foo], LSpace[:bar]]
116
+ EM::stop
117
+ end
118
+ end
119
+
120
+ LSpace.update(:bar => :baz) do
121
+ EM::run do
122
+ EM::start_server '0.0.0.0', 9345, server
123
+ EM::connect '127.0.0.1', 9345, client
124
+ end
125
+ end
126
+
127
+ $client.should == [[:post_init, :client, :baz], [:receive_data, :client, :baz], [:unbind, :client, :baz]]
128
+ $server.should == [[:post_init, :server, :baz], [:receive_data, :server, :baz], [:unbind, :server, :baz]]
129
+ end
130
+ end
131
+ end
@@ -1,89 +1,150 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LSpace do
4
- it "should act like a hash" do
5
- LSpace[:foo] = 1
6
- LSpace[:foo].should == 1
4
+ before do
5
+ @lspace = LSpace.new({:foo => 1}, nil)
7
6
  end
8
7
 
9
- it "should isolate changes to nested spaces" do
10
- LSpace[:foo] = 2
8
+ describe "#[]" do
9
+ it "should act like a hash" do
10
+ @lspace[:foo].should == 1
11
+ end
11
12
 
12
- LSpace.new do
13
- LSpace[:foo] = 1
14
- LSpace[:foo].should == 1
13
+ it "should fall back to the parent" do
14
+ lspace2 = LSpace.new({:bar => 2}, @lspace)
15
+ lspace2[:foo].should == 1
15
16
  end
16
17
 
17
- LSpace[:foo].should == 2
18
+ it "should use the child in preference to the parent" do
19
+ lspace2 = LSpace.new({:foo => 2}, @lspace)
20
+ lspace2[:foo].should == 2
21
+ end
18
22
  end
19
23
 
20
- it "should fallback to outer spaces" do
21
- LSpace[:bar] = 1
22
- LSpace.new do
23
- LSpace[:bar].should == 1
24
+ describe "#[]=" do
25
+ it "should act like a hash" do
26
+ @lspace[:foo] = 7
27
+ @lspace[:foo].should == 7
24
28
  end
25
- end
26
29
 
27
- it "should be isolated between different threads" do
28
- LSpace[:foo] = 1
29
- Thread.new{ LSpace[:foo].should == nil }.join
30
+ it "should not affect the parent" do
31
+ lspace2 = LSpace.new({}, @lspace)
32
+ lspace2[:foo] = 7
33
+ @lspace[:foo].should == 1
34
+ end
30
35
  end
31
36
 
32
- it "should be isolated between different fibers" do
33
- LSpace[:foo] = 1
34
- Fiber.new{ LSpace[:foo].should == nil }.resume
35
- end
37
+ describe "#around_filter" do
38
+ before do
39
+ @entered = 0
40
+ @returned = 0
36
41
 
37
- it "should allow preserving spaces" do
38
- p = LSpace.new(:foo => 1){ proc{ LSpace[:foo] }.in_lspace }
39
- p.call.should == 1
40
- end
42
+ @lspace.around_filter do |&block|
43
+ @entered += 1
44
+ begin
45
+ block.call
46
+ ensure
47
+ @returned += 1
48
+ end
49
+ end
50
+ end
41
51
 
42
- it "should allow resuming spaces in different threads" do
43
- p = LSpace.new(:foo => 1){ proc{ LSpace[:foo] }.in_lspace }
44
- Thread.new{ p.call.should == 1 }.join
45
- end
52
+ it "should be run when the LSpace is entered" do
53
+ LSpace.enter @lspace do
54
+ @entered.should == 1
55
+ @returned.should == 0
56
+ end
57
+ @returned.should == 1
58
+ end
59
+
60
+ it "should not be run when the LSpace is re-entered" do
61
+ LSpace.enter @lspace do
62
+ LSpace.enter @lspace do
63
+ @entered.should == 1
64
+ end
65
+ end
66
+ end
67
+
68
+ it "should not be re-run when a child of the LSpace is entered" do
69
+ lspace2 = LSpace.new({}, @lspace)
70
+
71
+ LSpace.enter @lspace do
72
+ lspace2.enter do
73
+ @entered.should == 1
74
+ end
75
+ end
76
+ end
46
77
 
47
- it "should allow resuming spaces in different fibers" do
48
- p = LSpace.new(:foo => 1){ LSpace.preserve{ LSpace[:foo] } }
49
- Fiber.new{ p.call.should == 1 }.resume
78
+ it "should apply around_filters from first to last" do
79
+ called = []
80
+ @lspace.around_filter do |&block|
81
+ called << :first
82
+ block.call
83
+ end
84
+ @lspace.around_filter do |&block|
85
+ called << :last
86
+ block.call
87
+ end
88
+
89
+ LSpace.enter @lspace do
90
+ called.should == [:first, :last]
91
+ end
92
+ end
93
+
94
+ it "should apply around_filters from parents before children" do
95
+ called = []
96
+ @lspace.around_filter do |&block|
97
+ called << :first
98
+ block.call
99
+ end
100
+ lspace2 = LSpace.new({}, @lspace)
101
+ lspace2.around_filter do |&block|
102
+ called << :last
103
+ block.call
104
+ end
105
+
106
+ LSpace.enter lspace2 do
107
+ called.should == [:first, :last]
108
+ end
109
+ end
50
110
  end
51
111
 
52
- it "should clean up lspace after resuming" do
53
- p = LSpace.new(:foo => 1){ proc{ LSpace[:foo] }.in_lspace }
54
- p.call.should == 1
55
- LSpace[:foo].should == nil
112
+ describe "#enter" do
113
+ it "should delegate to LSpace" do
114
+ LSpace.should_receive(:enter).once.with(@lspace)
115
+ @lspace.enter do
116
+ 5 + 5
117
+ end
118
+ end
56
119
  end
57
120
 
58
- it "should resume the entire nested lspace" do
59
- p = LSpace.new(:foo => 1) {
60
- LSpace.new(:bar => 2) {
61
- LSpace.new(:baz => 3) {
62
- lambda &LSpace.preserve{ LSpace[:foo] + LSpace[:bar] + LSpace[:baz] }
63
- }
64
- }
65
- }
121
+ describe "#wrap" do
122
+ it "should cause the LSpace to be entered when the block is called" do
123
+ @lspace.wrap{ LSpace.current.should == @lspace }.call
124
+ end
66
125
 
67
- p.call.should == 6
68
- end
126
+ it "should revert the changed LSpace at the end of the block" do
127
+ lspace = LSpace.current
128
+ @lspace.wrap{ LSpace.current.should == @lspace }.call
129
+ LSpace.current.should == lspace
130
+ end
69
131
 
70
- it "should return to enclosing lspace after re-entering new lspace" do
71
- LSpace.new(:baz => 1) do
72
- p = LSpace.new(:baz => 2){ proc{ LSpace[:baz] }.in_lspace }
73
- p.call.should == 2
74
- LSpace[:baz].should == 1
132
+ it "should be possible to call the block on a different thread" do
133
+ todo = @lspace.wrap{ LSpace.current.should == @lspace }
134
+ Thread.new{ todo.call }.join
75
135
  end
76
136
  end
77
137
 
78
- it "should clean up lspaces properly even if an exception is raised" do
79
- LSpace.new(:baz => 1) do
80
- begin
81
- LSpace.new(:baz => 1) do
82
- raise "OOPS"
83
- end
84
- rescue => e
85
- LSpace[:baz].should == 1
86
- end
138
+ describe "#hierarchy" do
139
+ it "should return [self] if there is no parent" do
140
+ @lspace.hierarchy.should == [@lspace]
141
+ end
142
+
143
+ it "should return the full list if there are parents" do
144
+ l1 = LSpace.new({}, @lspace)
145
+ l2 = LSpace.new({}, l1)
146
+
147
+ l2.hierarchy.should == [l2, l1, @lspace]
87
148
  end
88
149
  end
89
150
  end
@@ -1,7 +1,10 @@
1
1
  require_relative '../lib/lspace'
2
+ require_relative '../lib/lspace/eventmachine'
3
+ require 'pry-rescue/rspec'
4
+
2
5
  RSpec.configure do |c|
3
6
  c.around(:each) do |example|
4
- LSpace.new do
7
+ LSpace.clean do
5
8
  example.run
6
9
  end
7
10
  end
metadata CHANGED
@@ -1,16 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.pre.1
5
- prerelease: 4
4
+ version: '0.1'
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Conrad Irwin
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-22 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: pry-rescue
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: eventmachine
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
14
62
  description: Provides the convenience of global variables, without the safety concerns.
15
63
  email: conrad.irwin@gmail.com
16
64
  executables: []
@@ -20,10 +68,14 @@ files:
20
68
  - LICENSE.MIT
21
69
  - README.md
22
70
  - lib/lspace.rb
71
+ - lib/lspace/class_methods.rb
23
72
  - lib/lspace/core_ext.rb
24
73
  - lib/lspace/eventmachine.rb
25
74
  - lib/lspace/thread.rb
26
75
  - lspace.gemspec
76
+ - spec/class_method_spec.rb
77
+ - spec/core_ext_spec.rb
78
+ - spec/eventmachine_spec.rb
27
79
  - spec/lspace_spec.rb
28
80
  - spec/spec_helper.rb
29
81
  homepage: http://github.com/ConradIrwin/lspace
@@ -41,9 +93,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
41
93
  required_rubygems_version: !ruby/object:Gem::Requirement
42
94
  none: false
43
95
  requirements:
44
- - - ! '>'
96
+ - - ! '>='
45
97
  - !ruby/object:Gem::Version
46
- version: 1.3.1
98
+ version: '0'
47
99
  requirements: []
48
100
  rubyforge_project:
49
101
  rubygems_version: 1.8.24