strelka 0.0.1.pre129 → 0.0.1.pre148

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/IDEAS.rdoc +26 -32
  2. data/Manifest.txt +27 -12
  3. data/README.rdoc +29 -33
  4. data/Rakefile +2 -1
  5. data/bin/leash +2 -1
  6. data/contrib/hoetemplate/README.rdoc.erb +18 -0
  7. data/contrib/hoetemplate/data/{file_name → project}/apps/file_name_app +0 -0
  8. data/contrib/hoetemplate/data/{file_name → project}/templates/layout.tmpl.erb +0 -0
  9. data/contrib/hoetemplate/data/{file_name → project}/templates/top.tmpl.erb +0 -0
  10. data/examples/config.yml +3 -0
  11. data/examples/gen-config.rb +48 -0
  12. data/examples/sessions-demo.rb +43 -0
  13. data/lib/strelka/app/errors.rb +59 -17
  14. data/lib/strelka/app/filters.rb +3 -1
  15. data/lib/strelka/app/negotiation.rb +5 -3
  16. data/lib/strelka/app/parameters.rb +33 -31
  17. data/lib/strelka/app/plugins.rb +14 -8
  18. data/lib/strelka/app/restresources.rb +3 -1
  19. data/lib/strelka/app/routing.rb +9 -7
  20. data/lib/strelka/app/sessions.rb +175 -0
  21. data/lib/strelka/app/templating.rb +6 -3
  22. data/lib/strelka/app.rb +19 -11
  23. data/lib/strelka/behavior/plugin.rb +4 -2
  24. data/lib/strelka/constants.rb +9 -0
  25. data/lib/strelka/cookie.rb +357 -0
  26. data/lib/strelka/cookieset.rb +117 -0
  27. data/lib/strelka/httprequest/acceptparams.rb +12 -10
  28. data/lib/strelka/httprequest/negotiation.rb +4 -2
  29. data/lib/strelka/httprequest/session.rb +71 -0
  30. data/lib/strelka/httprequest.rb +19 -7
  31. data/lib/strelka/httpresponse/negotiation.rb +17 -15
  32. data/lib/strelka/httpresponse/session.rb +101 -0
  33. data/lib/strelka/httpresponse.rb +26 -4
  34. data/lib/strelka/logging.rb +3 -1
  35. data/lib/strelka/mixins.rb +174 -2
  36. data/lib/strelka/{app/paramvalidator.rb → paramvalidator.rb} +25 -22
  37. data/lib/strelka/{app/defaultrouter.rb → router/default.rb} +6 -4
  38. data/lib/strelka/{app/exclusiverouter.rb → router/exclusive.rb} +6 -4
  39. data/lib/strelka/{app/router.rb → router.rb} +9 -7
  40. data/lib/strelka/session/default.rb +209 -0
  41. data/lib/strelka/session.rb +178 -0
  42. data/lib/strelka.rb +6 -4
  43. data/spec/lib/constants.rb +3 -1
  44. data/spec/lib/helpers.rb +7 -0
  45. data/spec/strelka/app/errors_spec.rb +32 -52
  46. data/spec/strelka/app/filters_spec.rb +3 -1
  47. data/spec/strelka/app/negotiation_spec.rb +3 -1
  48. data/spec/strelka/app/parameters_spec.rb +5 -3
  49. data/spec/strelka/app/plugins_spec.rb +5 -3
  50. data/spec/strelka/app/restresources_spec.rb +3 -1
  51. data/spec/strelka/app/routing_spec.rb +6 -4
  52. data/spec/strelka/app/sessions_spec.rb +109 -0
  53. data/spec/strelka/app/templating_spec.rb +3 -1
  54. data/spec/strelka/app_spec.rb +11 -2
  55. data/spec/strelka/cookie_spec.rb +194 -0
  56. data/spec/strelka/cookieset_spec.rb +159 -0
  57. data/spec/strelka/exceptions_spec.rb +3 -1
  58. data/spec/strelka/httprequest/acceptparams_spec.rb +3 -1
  59. data/spec/strelka/httprequest/negotiation_spec.rb +3 -1
  60. data/spec/strelka/httprequest/session_spec.rb +43 -0
  61. data/spec/strelka/httprequest_spec.rb +28 -1
  62. data/spec/strelka/httpresponse/negotiation_spec.rb +3 -3
  63. data/spec/strelka/httpresponse_spec.rb +13 -0
  64. data/spec/strelka/logging_spec.rb +3 -1
  65. data/spec/strelka/mixins_spec.rb +125 -1
  66. data/spec/strelka/{app/paramvalidator_spec.rb → paramvalidator_spec.rb} +4 -4
  67. data/spec/strelka/{app/defaultrouter_spec.rb → router/default_spec.rb} +6 -4
  68. data/spec/strelka/{app/exclusiverouter_spec.rb → router/exclusive_spec.rb} +6 -4
  69. data/spec/strelka/{app/router_spec.rb → router_spec.rb} +9 -7
  70. data/spec/strelka/session/default_spec.rb +210 -0
  71. data/spec/strelka/session_spec.rb +101 -0
  72. data.tar.gz.sig +1 -1
  73. metadata +64 -47
  74. metadata.gz.sig +0 -0
  75. data/contrib/hoetemplate/.autotest.erb +0 -23
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
2
4
 
3
5
  BEGIN {
4
6
  require 'pathname'
@@ -95,5 +97,127 @@ describe Strelka, "mixins" do
95
97
  end
96
98
 
97
99
 
100
+ describe Strelka::Delegation do
101
+
102
+ before( :all ) do
103
+ setup_logging( :fatal )
104
+ end
105
+ after( :all ) do
106
+ reset_logging()
107
+ end
108
+
109
+ describe "method delegation" do
110
+ before( :all ) do
111
+ @testclass = Class.new do
112
+ extend Strelka::Delegation
113
+
114
+ def initialize( obj )
115
+ @obj = obj
116
+ end
117
+
118
+ def_method_delegators :demand_loaded_object, :delegated_method
119
+ def_method_delegators :nonexistant_method, :erroring_delegated_method
120
+
121
+ def demand_loaded_object
122
+ return @obj
123
+ end
124
+ end
125
+ end
126
+
127
+ before( :each ) do
128
+ @subobj = mock( "delegate" )
129
+ @obj = @testclass.new( @subobj )
130
+ end
131
+
132
+
133
+ it "can be used to set up delegation through a method" do
134
+ @subobj.should_receive( :delegated_method )
135
+ @obj.delegated_method
136
+ end
137
+
138
+ it "passes any arguments through to the delegate object's method" do
139
+ @subobj.should_receive( :delegated_method ).with( :arg1, :arg2 )
140
+ @obj.delegated_method( :arg1, :arg2 )
141
+ end
142
+
143
+ it "allows delegation to the delegate object's method with a block" do
144
+ @subobj.should_receive( :delegated_method ).with( :arg1 ).
145
+ and_yield( :the_block_argument )
146
+ blockarg = nil
147
+ @obj.delegated_method( :arg1 ) {|arg| blockarg = arg }
148
+ blockarg.should == :the_block_argument
149
+ end
150
+
151
+ it "reports errors from its caller's perspective", :ruby_1_8_only => true do
152
+ begin
153
+ @obj.erroring_delegated_method
154
+ rescue NoMethodError => err
155
+ err.message.should =~ /nonexistant_method/
156
+ err.backtrace.first.should =~ /#{__FILE__}/
157
+ rescue ::Exception => err
158
+ fail "Expected a NoMethodError, but got a %p (%s)" % [ err.class, err.message ]
159
+ else
160
+ fail "Expected a NoMethodError, but no exception was raised."
161
+ end
162
+ end
163
+
164
+ end
165
+
166
+ describe "instance variable delegation (ala Forwardable)" do
167
+ before( :all ) do
168
+ @testclass = Class.new do
169
+ extend Strelka::Delegation
170
+
171
+ def initialize( obj )
172
+ @obj = obj
173
+ end
174
+
175
+ def_ivar_delegators :@obj, :delegated_method
176
+ def_ivar_delegators :@glong, :erroring_delegated_method
177
+
178
+ end
179
+ end
180
+
181
+ before( :each ) do
182
+ @subobj = mock( "delegate" )
183
+ @obj = @testclass.new( @subobj )
184
+ end
185
+
186
+
187
+ it "can be used to set up delegation through a method" do
188
+ @subobj.should_receive( :delegated_method )
189
+ @obj.delegated_method
190
+ end
191
+
192
+ it "passes any arguments through to the delegate's method" do
193
+ @subobj.should_receive( :delegated_method ).with( :arg1, :arg2 )
194
+ @obj.delegated_method( :arg1, :arg2 )
195
+ end
196
+
197
+ it "allows delegation to the delegate's method with a block" do
198
+ @subobj.should_receive( :delegated_method ).with( :arg1 ).
199
+ and_yield( :the_block_argument )
200
+ blockarg = nil
201
+ @obj.delegated_method( :arg1 ) {|arg| blockarg = arg }
202
+ blockarg.should == :the_block_argument
203
+ end
204
+
205
+ it "reports errors from its caller's perspective", :ruby_1_8_only => true do
206
+ begin
207
+ @obj.erroring_delegated_method
208
+ rescue NoMethodError => err
209
+ err.message.should =~ /`erroring_delegated_method' for nil/
210
+ err.backtrace.first.should =~ /#{__FILE__}/
211
+ rescue ::Exception => err
212
+ fail "Expected a NoMethodError, but got a %p (%s)" % [ err.class, err.message ]
213
+ else
214
+ fail "Expected a NoMethodError, but no exception was raised."
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+
98
222
  end
99
223
 
@@ -13,13 +13,13 @@ require 'rspec'
13
13
  require 'spec/lib/helpers'
14
14
 
15
15
  require 'strelka'
16
- require 'strelka/app/paramvalidator'
16
+ require 'strelka/paramvalidator'
17
17
 
18
18
 
19
19
  #####################################################################
20
20
  ### C O N T E X T S
21
21
  #####################################################################
22
- describe Strelka::App::ParamValidator do
22
+ describe Strelka::ParamValidator do
23
23
 
24
24
  TEST_PROFILE = {
25
25
  :required => [ :required ],
@@ -55,7 +55,7 @@ describe Strelka::App::ParamValidator do
55
55
  end
56
56
 
57
57
  before(:each) do
58
- @validator = Strelka::App::ParamValidator.new( TEST_PROFILE )
58
+ @validator = Strelka::ParamValidator.new( TEST_PROFILE )
59
59
  end
60
60
 
61
61
  after( :all ) do
@@ -83,7 +83,7 @@ describe Strelka::App::ParamValidator do
83
83
  required: $stderr,
84
84
  }
85
85
  }
86
- val = Strelka::App::ParamValidator.new( profile )
86
+ val = Strelka::ParamValidator.new( profile )
87
87
 
88
88
  expect {
89
89
  val.validate( required: '1' )
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
2
4
 
3
5
  BEGIN {
4
6
  require 'pathname'
@@ -11,14 +13,14 @@ require 'rspec'
11
13
  require 'spec/lib/helpers'
12
14
 
13
15
  require 'strelka'
14
- require 'strelka/app/defaultrouter'
16
+ require 'strelka/router/default'
15
17
 
16
18
 
17
19
  #####################################################################
18
20
  ### C O N T E X T S
19
21
  #####################################################################
20
22
 
21
- describe Strelka::App::DefaultRouter do
23
+ describe Strelka::Router::Default do
22
24
 
23
25
  before( :all ) do
24
26
  setup_logging( :fatal )
@@ -26,7 +28,7 @@ describe Strelka::App::DefaultRouter do
26
28
  end
27
29
 
28
30
  before( :each ) do
29
- @router = Strelka::App::Router.create( 'default' )
31
+ @router = Strelka::Router.create( 'default' )
30
32
  end
31
33
 
32
34
  after( :all ) do
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
2
4
 
3
5
  BEGIN {
4
6
  require 'pathname'
@@ -11,14 +13,14 @@ require 'rspec'
11
13
  require 'spec/lib/helpers'
12
14
 
13
15
  require 'strelka'
14
- require 'strelka/app/exclusiverouter'
16
+ require 'strelka/router/exclusive'
15
17
 
16
18
 
17
19
  #####################################################################
18
20
  ### C O N T E X T S
19
21
  #####################################################################
20
22
 
21
- describe Strelka::App::ExclusiveRouter do
23
+ describe Strelka::Router::Exclusive do
22
24
 
23
25
  before( :all ) do
24
26
  setup_logging( :fatal )
@@ -26,7 +28,7 @@ describe Strelka::App::ExclusiveRouter do
26
28
  end
27
29
 
28
30
  before( :each ) do
29
- @router = Strelka::App::ExclusiveRouter.new
31
+ @router = Strelka::Router::Exclusive.new
30
32
  end
31
33
 
32
34
  after( :all ) do
@@ -1,8 +1,10 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
2
4
 
3
5
  BEGIN {
4
6
  require 'pathname'
5
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
7
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent
6
8
  $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
7
9
  }
8
10
 
@@ -11,14 +13,14 @@ require 'rspec'
11
13
  require 'spec/lib/helpers'
12
14
 
13
15
  require 'strelka'
14
- require 'strelka/app/router'
16
+ require 'strelka/router'
15
17
 
16
18
 
17
19
  #####################################################################
18
20
  ### C O N T E X T S
19
21
  #####################################################################
20
22
 
21
- describe Strelka::App::Router do
23
+ describe Strelka::Router do
22
24
 
23
25
  before( :all ) do
24
26
  setup_logging( :fatal )
@@ -30,14 +32,14 @@ describe Strelka::App::Router do
30
32
  end
31
33
 
32
34
 
33
- it "looks for plugins under strelka/app" do
34
- Strelka::App::Router.derivative_dirs.should include( 'strelka/app' )
35
+ it "looks for plugins under strelka/router" do
36
+ Strelka::Router.derivative_dirs.should include( 'strelka/router' )
35
37
  end
36
38
 
37
39
 
38
40
  it "is abstract" do
39
41
  expect {
40
- Strelka::App::Router.new
42
+ Strelka::Router.new
41
43
  }.to raise_error()
42
44
  end
43
45
 
@@ -0,0 +1,210 @@
1
+ # -*- rspec -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
7
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
8
+ }
9
+
10
+ require 'rspec'
11
+
12
+ require 'spec/lib/helpers'
13
+
14
+ require 'strelka'
15
+ require 'strelka/session/default'
16
+
17
+
18
+ #####################################################################
19
+ ### C O N T E X T S
20
+ #####################################################################
21
+
22
+ describe Strelka::Session::Default do
23
+
24
+ before( :all ) do
25
+ @request_factory = Mongrel2::RequestFactory.new( route: '/hungry' )
26
+ setup_logging( :fatal )
27
+ end
28
+
29
+ before( :each ) do
30
+ described_class.cookie_name = described_class::DEFAULT_COOKIE_NAME
31
+ end
32
+
33
+ after( :each ) do
34
+ described_class.sessions.clear
35
+ end
36
+
37
+ after( :all ) do
38
+ reset_logging()
39
+ end
40
+
41
+ it "has distinct duplicates" do
42
+ original = Strelka::Session.create( 'default', 'the_session_id' )
43
+ copy = original.dup
44
+ copy[:foom] = 1
45
+ original[:foom].should == {}
46
+ end
47
+
48
+
49
+ it "can be configured to store its session ID in a different cookie" do
50
+ described_class.configure( :cookie_name => 'buh-mahlon' )
51
+ described_class.cookie_name.should == 'buh-mahlon'
52
+ end
53
+
54
+ it "can load sessions from and save sessions to its in-memory store" do
55
+ session_data = { :namespace => {'the' => 'stuff'} }
56
+ described_class.save_session_data( 'the_key', session_data )
57
+
58
+ loaded = described_class.load_session_data( 'the_key' )
59
+ loaded.should_not equal( session_data )
60
+ loaded.should == session_data
61
+ end
62
+
63
+ it "generates a session-id if one isn't available in the request" do
64
+ req = @request_factory.get( '/hungry/what-is-in-a-fruit-bowl?' )
65
+ described_class.get_session_id( req ).should =~ /^[[:xdigit:]]+$/
66
+ end
67
+
68
+ it "rejects invalid session-ids" do
69
+ session_cookie = 'strelka-sessionid=gibberish'
70
+ req = @request_factory.get( '/hungry/what-is-in-a-fruit-bowl?', :cookie => session_cookie )
71
+ described_class.get_session_id( req ).should =~ /^[[:xdigit:]]+$/
72
+ end
73
+
74
+ it "accepts and reuses an existing valid session-id" do
75
+ session_id = '3422067061a5790be374c81118d9ed3f'
76
+ session_cookie = "strelka-sessionid=%s" % [ session_id ]
77
+ req = @request_factory.get( '/hungry/what-is-in-a-fruit-bowl?', :cookie => session_cookie )
78
+ described_class.get_session_id( req ).should == session_id
79
+ end
80
+
81
+
82
+ it "can save itself to the store and set the response's session ID" do
83
+ req = @request_factory.get( '/hungry/hungry/hippos' )
84
+ response = req.response
85
+ session_id = '3422067061a5790be374c81118d9ed3f'
86
+ session_data = { :namespace => {'fruit' => 'bowl'} }
87
+ session = described_class.new( session_id, session_data )
88
+
89
+ session.save( response )
90
+
91
+ described_class.sessions.should == { session_id => session_data }
92
+ response.header_data.should =~ /Set-Cookie: #{described_class::DEFAULT_COOKIE_NAME}=#{session_id}/i
93
+ end
94
+
95
+ describe "with no namespace set (the 'nil' namespace)" do
96
+
97
+ subject { Strelka::Session.create('default', 'the_session_id') }
98
+
99
+ before( :each ) do
100
+ subject.namespace = nil
101
+ end
102
+
103
+ after( :each ) do
104
+ subject.namespace = nil
105
+ subject.clear
106
+ end
107
+
108
+ it "accesses the hash of namespaces" do
109
+ subject.namespace = :foo
110
+ subject[:number] = 18
111
+ subject.namespace = 'bar'
112
+ subject[:number] = 28
113
+
114
+ subject.namespace = nil
115
+
116
+ subject.keys.should have( 2 ).members
117
+ subject.keys.should include( :foo, :bar )
118
+ subject.values.should all_be_a( Hash )
119
+ subject[:foo][:number].should == 18
120
+ subject[:bar][:number].should == 28
121
+ end
122
+
123
+ it "accesses namespaces via a struct-like interface" do
124
+ subject.namespace = :meat
125
+ subject.testkey = true
126
+ subject.namespace = :greet
127
+ subject.testkey = true
128
+ subject.namespace = nil
129
+
130
+ subject.meat[ :testkey ].should be_true
131
+ subject.greet[ :testkey ].should be_true
132
+ subject.pork[ :testkey ].should be_nil
133
+ end
134
+
135
+ it "is Enumerable (over the hash of namespaces)" do
136
+ subject.namespace = :meta
137
+ subject.create_me = :yes
138
+ subject.namespace = :tetra
139
+ subject.create_me = :yes
140
+ subject.namespace = nil
141
+
142
+ subject.map {|k,v| k }.should include( :meta, :tetra )
143
+ end
144
+
145
+ it "can merge namespaces into the session" do
146
+ subject.merge!( :app1 => {:foom => 88}, :app2 => {:foom => 188} )
147
+ subject.app1[:foom].should == 88
148
+ subject.app2[:foom].should == 188
149
+ end
150
+
151
+ end
152
+
153
+
154
+ describe "with a namespace set" do
155
+
156
+ subject { Strelka::Session.create('default', 'the_session_id') }
157
+
158
+ before( :each ) do
159
+ subject.namespace = :meat
160
+ end
161
+
162
+ after( :each ) do
163
+ subject.namespace = nil
164
+ subject.clear
165
+ end
166
+
167
+ it "accesses the namespaced hash" do
168
+ subject[:number] = 18
169
+ subject[:not_a_number] = 'woo'
170
+
171
+ subject.keys.should have( 2 ).members
172
+ subject.keys.should include( :number, :not_a_number )
173
+ subject[:number].should == 18
174
+ subject[:not_a_number].should == 'woo'
175
+ end
176
+
177
+ it "accesses values via a struct-like interface" do
178
+ subject.testkey = true
179
+
180
+ subject.testkey.should be_true
181
+ subject.i_do_not_exist.should be_nil
182
+ end
183
+
184
+ it "is Enumerable (over the namespaced hash)" do
185
+ subject.namespace = :meta
186
+ subject.create_me = :yes
187
+ subject.destroy_me = :yes
188
+ subject.whip_me = :definitely
189
+ subject.beat_me = :indubitably
190
+
191
+ banner = subject.each_with_object('Hey!') do |(k,v),accum|
192
+ accum << "#{k} "
193
+ end
194
+
195
+ banner.should =~ /create_me/
196
+ banner.should =~ /destroy_me/
197
+ banner.should =~ /whip_me/
198
+ banner.should =~ /beat_me/
199
+ end
200
+
201
+ it "can merge a hash into the namespace" do
202
+ subject.merge!( :app1 => {:foom => 88}, :app2 => {:foom => 188} )
203
+ subject.app1[:foom].should == 88
204
+ subject.app2[:foom].should == 188
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+
@@ -0,0 +1,101 @@
1
+ # -*- rspec -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent
7
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
8
+ }
9
+
10
+ require 'rspec'
11
+
12
+ require 'spec/lib/helpers'
13
+
14
+ require 'strelka'
15
+ require 'strelka/session'
16
+
17
+
18
+ #####################################################################
19
+ ### C O N T E X T S
20
+ #####################################################################
21
+
22
+ describe Strelka::Session do
23
+
24
+ before( :all ) do
25
+ setup_logging( :fatal )
26
+ @request_factory = Mongrel2::RequestFactory.new( route: '/user' )
27
+ end
28
+
29
+ after( :all ) do
30
+ reset_logging()
31
+ end
32
+
33
+
34
+ it "looks for plugins under strelka/session" do
35
+ described_class.derivative_dirs.should include( 'strelka/session' )
36
+ end
37
+
38
+
39
+ it "is abstract" do
40
+ expect {
41
+ described_class.new
42
+ }.to raise_error( /private method/i )
43
+ end
44
+
45
+
46
+ it "accepts configuration options" do
47
+ described_class.configure( :cookie_name => 'animal-crackers' )
48
+ end
49
+
50
+
51
+ it "can be asked to load an instance of itself by session ID" do
52
+ # By default, loading always fails
53
+ described_class.load( 'the_session_id' ).should be_nil()
54
+ end
55
+
56
+
57
+ describe "a concrete subclass with no method overrides" do
58
+
59
+ subject { Class.new(described_class).new('an_id') }
60
+
61
+ it "raises NotImplementedErrors when #[] is called" do
62
+ expect {
63
+ subject[ :foo ]
64
+ }.to raise_error(NotImplementedError)
65
+ end
66
+
67
+ it "raises NotImplementedErrors if they don't implement #[]=" do
68
+ expect {
69
+ subject[ :foo ] = 1
70
+ }.to raise_error(NotImplementedError)
71
+ end
72
+
73
+ it "raises NotImplementedErrors if they don't implement #key?" do
74
+ expect {
75
+ subject.key?( :foo )
76
+ }.to raise_error(NotImplementedError)
77
+ end
78
+
79
+ it "raises NotImplementedErrors if they don't implement #delete" do
80
+ expect {
81
+ subject.delete( :foo )
82
+ }.to raise_error(NotImplementedError)
83
+ end
84
+
85
+ it "raises NotImplementedErrors if they don't implement #namepace=" do
86
+ expect {
87
+ subject.namespace = :myapp
88
+ }.to raise_error(NotImplementedError)
89
+ end
90
+
91
+ it "raises NotImplementedErrors if they don't implement #namepace" do
92
+ expect {
93
+ subject.namespace
94
+ }.to raise_error(NotImplementedError)
95
+ end
96
+
97
+ end
98
+
99
+
100
+ end
101
+
data.tar.gz.sig CHANGED
@@ -1 +1 @@
1
- L:HH0�ˢ���3Z��g'Ĕ<\G��W���T+�x � �4�ɼFm+���s.��O%�,_`�
1
+ Hy?�8�x�v�x���>��= 魝_ 4�9��X�% �/<�E[0