sinatra-contrib 2.0.0.rc1 → 2.0.0.rc2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -1
  3. data/lib/sinatra/decompile.rb +5 -0
  4. data/lib/sinatra/runner.rb +155 -0
  5. data/lib/sinatra/webdav.rb +93 -0
  6. data/sinatra-contrib.gemspec +5 -199
  7. metadata +13 -175
  8. data/spec/capture_spec.rb +0 -100
  9. data/spec/config_file/key_value.yml +0 -7
  10. data/spec/config_file/key_value.yml.erb +0 -6
  11. data/spec/config_file/key_value_override.yml +0 -2
  12. data/spec/config_file/missing_env.yml +0 -4
  13. data/spec/config_file/with_envs.yml +0 -7
  14. data/spec/config_file/with_nested_envs.yml +0 -11
  15. data/spec/config_file_spec.rb +0 -76
  16. data/spec/content_for/different_key.erb +0 -1
  17. data/spec/content_for/different_key.erubis +0 -1
  18. data/spec/content_for/different_key.haml +0 -2
  19. data/spec/content_for/different_key.slim +0 -2
  20. data/spec/content_for/footer.erb +0 -3
  21. data/spec/content_for/footer.erubis +0 -3
  22. data/spec/content_for/footer.haml +0 -2
  23. data/spec/content_for/footer.slim +0 -2
  24. data/spec/content_for/layout.erb +0 -1
  25. data/spec/content_for/layout.erubis +0 -1
  26. data/spec/content_for/layout.haml +0 -1
  27. data/spec/content_for/layout.slim +0 -1
  28. data/spec/content_for/multiple_blocks.erb +0 -4
  29. data/spec/content_for/multiple_blocks.erubis +0 -4
  30. data/spec/content_for/multiple_blocks.haml +0 -8
  31. data/spec/content_for/multiple_blocks.slim +0 -8
  32. data/spec/content_for/multiple_yields.erb +0 -3
  33. data/spec/content_for/multiple_yields.erubis +0 -3
  34. data/spec/content_for/multiple_yields.haml +0 -3
  35. data/spec/content_for/multiple_yields.slim +0 -3
  36. data/spec/content_for/passes_values.erb +0 -1
  37. data/spec/content_for/passes_values.erubis +0 -1
  38. data/spec/content_for/passes_values.haml +0 -1
  39. data/spec/content_for/passes_values.slim +0 -1
  40. data/spec/content_for/same_key.erb +0 -1
  41. data/spec/content_for/same_key.erubis +0 -1
  42. data/spec/content_for/same_key.haml +0 -2
  43. data/spec/content_for/same_key.slim +0 -2
  44. data/spec/content_for/takes_values.erb +0 -1
  45. data/spec/content_for/takes_values.erubis +0 -1
  46. data/spec/content_for/takes_values.haml +0 -3
  47. data/spec/content_for/takes_values.slim +0 -3
  48. data/spec/content_for_spec.rb +0 -241
  49. data/spec/cookies_spec.rb +0 -826
  50. data/spec/custom_logger_spec.rb +0 -43
  51. data/spec/extension_spec.rb +0 -32
  52. data/spec/json_spec.rb +0 -115
  53. data/spec/link_header_spec.rb +0 -99
  54. data/spec/multi_route_spec.rb +0 -59
  55. data/spec/namespace/foo.erb +0 -1
  56. data/spec/namespace/nested/foo.erb +0 -1
  57. data/spec/namespace_spec.rb +0 -791
  58. data/spec/okjson.rb +0 -581
  59. data/spec/reloader/app.rb.erb +0 -40
  60. data/spec/reloader_spec.rb +0 -465
  61. data/spec/required_params_spec.rb +0 -68
  62. data/spec/respond_with/bar.erb +0 -1
  63. data/spec/respond_with/bar.json.erb +0 -1
  64. data/spec/respond_with/baz.yajl +0 -1
  65. data/spec/respond_with/foo.html.erb +0 -1
  66. data/spec/respond_with/not_html.sass +0 -2
  67. data/spec/respond_with_spec.rb +0 -317
  68. data/spec/spec_helper.rb +0 -7
  69. data/spec/streaming_spec.rb +0 -415
@@ -1,68 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- describe Sinatra::RequiredParams do
4
- context "#required_params" do
5
- context "simple keys" do
6
- before do
7
- mock_app do
8
- helpers Sinatra::RequiredParams
9
- get('/') { required_params(:p1, :p2) }
10
- end
11
- end
12
- it 'return 400 if required params do not exist' do
13
- get('/')
14
- expect(last_response.status).to eq(400)
15
- end
16
- it 'return 400 if required params do not exist partially' do
17
- get('/', :p1 => 1)
18
- expect(last_response.status).to eq(400)
19
- end
20
- it 'return 200 if required params exist' do
21
- get('/', :p1 => 1, :p2 => 2)
22
- expect(last_response.status).to eq(200)
23
- end
24
- it 'return 200 if required params exist with array' do
25
- get('/', :p1 => 1, :p2 => [31, 32, 33])
26
- expect(last_response.status).to eq(200)
27
- end
28
- end
29
- context "hash keys" do
30
- before do
31
- mock_app do
32
- helpers Sinatra::RequiredParams
33
- get('/') { required_params(:p1, :p2 => :p21) }
34
- end
35
- end
36
- it 'return 400 if required params do not exist' do
37
- get('/')
38
- expect(last_response.status).to eq(400)
39
- end
40
- it 'return 200 if required params exist' do
41
- get('/', :p1 => 1, :p2 => {:p21 => 21})
42
- expect(last_response.status).to eq(200)
43
- end
44
- end
45
- context "complex keys" do
46
- before do
47
- mock_app do
48
- helpers Sinatra::RequiredParams
49
- get('/') { required_params(:p1 => [:p11, {:p12 => :p121, :p122 => [:p123, {:p124 => :p1241}]}]) }
50
- end
51
- end
52
- it 'return 400 if required params do not exist' do
53
- get('/')
54
- expect(last_response.status).to eq(400)
55
- end
56
- it 'return 200 if required params exist' do
57
- get('/', :p1 => {:p11 => 11, :p12 => {:p121 => 121}, :p122 => {:p123 => 123, :p124 => {:p1241 => 1241}}})
58
- expect(last_response.status).to eq(200)
59
- end
60
- end
61
- end
62
-
63
- context "#_required_params" do
64
- it "is invisible" do
65
- expect { _required_params }.to raise_error(NameError)
66
- end
67
- end
68
- end
@@ -1 +0,0 @@
1
- guten Tag!
@@ -1 +0,0 @@
1
- json!
@@ -1 +0,0 @@
1
- json = "yajl!"
@@ -1 +0,0 @@
1
- Hello <%= name %>!
@@ -1,2 +0,0 @@
1
- body
2
- color: red
@@ -1,317 +0,0 @@
1
- require 'multi_json'
2
-
3
- require 'spec_helper'
4
- require 'okjson'
5
-
6
- describe Sinatra::RespondWith do
7
- def provides(*args)
8
- @provides = args
9
- end
10
-
11
- def respond_app(&block)
12
- types = @provides
13
- mock_app do
14
- set :app_file, __FILE__
15
- set :views, root + '/respond_with'
16
- register Sinatra::RespondWith
17
- respond_to(*types) if types
18
- class_eval(&block)
19
- end
20
- end
21
-
22
- def respond_to(*args, &block)
23
- respond_app { get('/') { respond_to(*args, &block) } }
24
- end
25
-
26
- def respond_with(*args, &block)
27
- respond_app { get('/') { respond_with(*args, &block) } }
28
- end
29
-
30
- def req(*types)
31
- p = types.shift if types.first.is_a? String and types.first.start_with? '/'
32
- accept = types.map { |t| Sinatra::Base.mime_type(t).to_s }.join ','
33
- get (p || '/'), {}, 'HTTP_ACCEPT' => accept
34
- end
35
-
36
- describe "Helpers#respond_to" do
37
- it 'allows defining handlers by file extensions' do
38
- respond_to do |format|
39
- format.html { "html!" }
40
- format.json { "json!" }
41
- end
42
-
43
- expect(req(:html).body).to eq("html!")
44
- expect(req(:json).body).to eq("json!")
45
- end
46
-
47
- it 'respects quality' do
48
- respond_to do |format|
49
- format.html { "html!" }
50
- format.json { "json!" }
51
- end
52
-
53
- expect(req("text/html;q=0.7, application/json;q=0.3").body).to eq("html!")
54
- expect(req("text/html;q=0.3, application/json;q=0.7").body).to eq("json!")
55
- end
56
-
57
- it 'allows using mime types' do
58
- respond_to do |format|
59
- format.on('text/html') { "html!" }
60
- format.json { "json!" }
61
- end
62
-
63
- expect(req(:html).body).to eq("html!")
64
- end
65
-
66
- it 'allows using wildcards in format matchers' do
67
- respond_to do |format|
68
- format.on('text/*') { "text!" }
69
- format.json { "json!" }
70
- end
71
-
72
- expect(req(:html).body).to eq("text!")
73
- end
74
-
75
- it 'allows using catch all wildcards in format matchers' do
76
- respond_to do |format|
77
- format.on('*/*') { "anything!" }
78
- format.json { "json!" }
79
- end
80
-
81
- expect(req(:html).body).to eq("anything!")
82
- end
83
-
84
- it 'prefers concret over generic' do
85
- respond_to do |format|
86
- format.on('text/*') { "text!" }
87
- format.on('*/*') { "anything!" }
88
- format.json { "json!" }
89
- end
90
-
91
- expect(req(:json).body).to eq("json!")
92
- expect(req(:html).body).to eq("text!")
93
- end
94
-
95
- it 'does not set up default handlers' do
96
- respond_to
97
- expect(req).not_to be_ok
98
- expect(status).to eq(500)
99
- expect(body).to eq("Unknown template engine")
100
- end
101
- end
102
-
103
- describe "Helpers#respond_with" do
104
- describe "matching" do
105
- it 'allows defining handlers by file extensions' do
106
- respond_with(:ignore) do |format|
107
- format.html { "html!" }
108
- format.json { "json!" }
109
- end
110
-
111
- expect(req(:html).body).to eq("html!")
112
- expect(req(:json).body).to eq("json!")
113
- end
114
-
115
- it 'respects quality' do
116
- respond_with(:ignore) do |format|
117
- format.html { "html!" }
118
- format.json { "json!" }
119
- end
120
-
121
- expect(req("text/html;q=0.7, application/json;q=0.3").body).to eq("html!")
122
- expect(req("text/html;q=0.3, application/json;q=0.7").body).to eq("json!")
123
- end
124
-
125
- it 'allows using mime types' do
126
- respond_with(:ignore) do |format|
127
- format.on('text/html') { "html!" }
128
- format.json { "json!" }
129
- end
130
-
131
- expect(req(:html).body).to eq("html!")
132
- end
133
-
134
- it 'allows using wildcards in format matchers' do
135
- respond_with(:ignore) do |format|
136
- format.on('text/*') { "text!" }
137
- format.json { "json!" }
138
- end
139
-
140
- expect(req(:html).body).to eq("text!")
141
- end
142
-
143
- it 'allows using catch all wildcards in format matchers' do
144
- respond_with(:ignore) do |format|
145
- format.on('*/*') { "anything!" }
146
- format.json { "json!" }
147
- end
148
-
149
- expect(req(:html).body).to eq("anything!")
150
- end
151
-
152
- it 'prefers concret over generic' do
153
- respond_with(:ignore) do |format|
154
- format.on('text/*') { "text!" }
155
- format.on('*/*') { "anything!" }
156
- format.json { "json!" }
157
- end
158
-
159
- expect(req(:json).body).to eq("json!")
160
- expect(req(:html).body).to eq("text!")
161
- end
162
- end
163
-
164
- describe "default behavior" do
165
- it 'converts objects to json out of the box' do
166
- respond_with 'a' => 'b'
167
- expect(OkJson.decode(req(:json).body)).to eq({'a' => 'b'})
168
- end
169
-
170
- it 'handles multiple routes correctly' do
171
- respond_app do
172
- get('/') { respond_with 'a' => 'b' }
173
- get('/:name') { respond_with 'a' => params[:name] }
174
- end
175
- expect(OkJson.decode(req('/', :json).body)).to eq({'a' => 'b'})
176
- expect(OkJson.decode(req('/b', :json).body)).to eq({'a' => 'b'})
177
- expect(OkJson.decode(req('/c', :json).body)).to eq({'a' => 'c'})
178
- end
179
-
180
- it "calls to_EXT if available" do
181
- respond_with Struct.new(:to_pdf).new("hello")
182
- expect(req(:pdf).body).to eq("hello")
183
- end
184
-
185
- it 'results in a 500 if format cannot be produced' do
186
- respond_with({})
187
- expect(req(:html)).not_to be_ok
188
- expect(status).to eq(500)
189
- expect(body).to eq("Unknown template engine")
190
- end
191
- end
192
-
193
- describe 'templates' do
194
- it 'looks for templates with name.target.engine' do
195
- respond_with :foo, :name => 'World'
196
- expect(req(:html)).to be_ok
197
- expect(body).to eq("Hello World!")
198
- end
199
-
200
- it 'looks for templates with name.engine for specific engines' do
201
- respond_with :bar
202
- expect(req(:html)).to be_ok
203
- expect(body).to eq("guten Tag!")
204
- end
205
-
206
- it 'does not use name.engine for engines producing other formats' do
207
- respond_with :not_html
208
- expect(req(:html)).not_to be_ok
209
- expect(status).to eq(500)
210
- expect(body).to eq("Unknown template engine")
211
- end
212
-
213
- it 'falls back to #json if no template is found' do
214
- respond_with :foo, :name => 'World'
215
- expect(req(:json)).to be_ok
216
- expect(OkJson.decode(body)).to eq({'name' => 'World'})
217
- end
218
-
219
- it 'favors templates over #json' do
220
- respond_with :bar, :name => 'World'
221
- expect(req(:json)).to be_ok
222
- expect(body).to eq('json!')
223
- end
224
-
225
- it 'falls back to to_EXT if no template is found' do
226
- object = {:name => 'World'}
227
- def object.to_pdf; "hi" end
228
- respond_with :foo, object
229
- expect(req(:pdf)).to be_ok
230
- expect(body).to eq("hi")
231
- end
232
-
233
- unless defined? JRUBY_VERSION
234
- it 'uses yajl for json' do
235
- respond_with :baz
236
- expect(req(:json)).to be_ok
237
- expect(body).to eq("\"yajl!\"")
238
- end
239
- end
240
- end
241
-
242
- describe 'customizing' do
243
- it 'allows customizing' do
244
- respond_with(:foo, :name => 'World') { |f| f.html { 'html!' }}
245
- expect(req(:html)).to be_ok
246
- expect(body).to eq("html!")
247
- end
248
-
249
- it 'falls back to default behavior if none matches' do
250
- respond_with(:foo, :name => 'World') { |f| f.json { 'json!' }}
251
- expect(req(:html)).to be_ok
252
- expect(body).to eq("Hello World!")
253
- end
254
-
255
- it 'favors generic rule over default behavior' do
256
- respond_with(:foo, :name => 'World') { |f| f.on('*/*') { 'generic!' }}
257
- expect(req(:html)).to be_ok
258
- expect(body).to eq("generic!")
259
- end
260
- end
261
-
262
- describe "inherited" do
263
- it "registers RespondWith in an inherited app" do
264
- app = Sinatra.new do
265
- set :app_file, __FILE__
266
- set :views, root + '/respond_with'
267
- register Sinatra::RespondWith
268
-
269
- get '/a' do
270
- respond_with :json
271
- end
272
- end
273
-
274
- self.app = Sinatra.new(app)
275
- expect(req('/a', :json)).not_to be_ok
276
- end
277
- end
278
- end
279
-
280
- describe :respond_to do
281
- it 'acts as global provides condition' do
282
- respond_app do
283
- respond_to :json, :html
284
- get('/a') { 'ok' }
285
- get('/b') { 'ok' }
286
- end
287
-
288
- expect(req('/b', :xml)).not_to be_ok
289
- expect(req('/b', :html)).to be_ok
290
- end
291
-
292
- it 'still allows provides' do
293
- respond_app do
294
- respond_to :json, :html
295
- get('/a') { 'ok' }
296
- get('/b', :provides => :json) { 'ok' }
297
- end
298
-
299
- expect(req('/b', :html)).not_to be_ok
300
- expect(req('/b', :json)).to be_ok
301
- end
302
-
303
- it 'plays well with namespaces' do
304
- respond_app do
305
- register Sinatra::Namespace
306
- namespace '/a' do
307
- respond_to :json
308
- get { 'json' }
309
- end
310
- get('/b') { 'anything' }
311
- end
312
-
313
- expect(req('/a', :html)).not_to be_ok
314
- expect(req('/b', :html)).to be_ok
315
- end
316
- end
317
- end
@@ -1,7 +0,0 @@
1
- ENV['RACK_ENV'] = 'test'
2
- require 'sinatra/contrib'
3
-
4
- RSpec.configure do |config|
5
- config.expect_with :rspec
6
- config.include Sinatra::TestHelpers
7
- end
@@ -1,415 +0,0 @@
1
- require 'backports'
2
- require 'spec_helper'
3
-
4
- describe Sinatra::Streaming do
5
- def stream(&block)
6
- rack_middleware = @use
7
- out = nil
8
- mock_app do
9
- rack_middleware.each { |args| use(*args) }
10
- helpers Sinatra::Streaming
11
- get('/') { out = stream(&block) }
12
- end
13
- get('/')
14
- out
15
- end
16
-
17
- def use(*args)
18
- @use << args
19
- end
20
-
21
- before do
22
- @use = []
23
- end
24
-
25
- context 'stream test helper' do
26
- it 'runs the given block' do
27
- ran = false
28
- stream { ran = true }
29
- expect(ran).to be true
30
- end
31
-
32
- it 'returns the stream object' do
33
- out = stream { }
34
- expect(out).to be_a(Sinatra::Helpers::Stream)
35
- end
36
-
37
- it 'fires a request against that stream' do
38
- stream { |out| out << "Hello World!" }
39
- expect(last_response).to be_ok
40
- expect(body).to eq("Hello World!")
41
- end
42
-
43
- it 'passes the stream object to the block' do
44
- passed = nil
45
- returned = stream { |out| passed = out }
46
- expect(passed).to eq(returned)
47
- end
48
- end
49
-
50
- context Sinatra::Streaming::Stream do
51
- it 'should extend the stream object' do
52
- out = stream { }
53
- expect(out).to be_a(Sinatra::Streaming::Stream)
54
- end
55
-
56
- it 'should not extend stream objects of other apps' do
57
- out = nil
58
- mock_app { get('/') { out = stream { }}}
59
- get('/')
60
- expect(out).to be_a(Sinatra::Helpers::Stream)
61
- expect(out).not_to be_a(Sinatra::Streaming::Stream)
62
- end
63
- end
64
-
65
- context 'app' do
66
- it 'is the app instance the stream was created from' do
67
- out = stream { }
68
- expect(out.app).to be_a(Sinatra::Base)
69
- end
70
- end
71
-
72
- context 'lineno' do
73
- it 'defaults to 0' do
74
- expect(stream { }.lineno).to eq(0)
75
- end
76
-
77
- it 'does not increase on write' do
78
- stream do |out|
79
- out << "many\nlines\n"
80
- expect(out.lineno).to eq(0)
81
- end
82
- end
83
-
84
- it 'is writable' do
85
- out = stream { }
86
- out.lineno = 10
87
- expect(out.lineno).to eq(10)
88
- end
89
- end
90
-
91
- context 'pos' do
92
- it 'defaults to 0' do
93
- expect(stream { }.pos).to eq(0)
94
- end
95
-
96
- it 'increases when writing data' do
97
- stream do |out|
98
- expect(out.pos).to eq(0)
99
- out << 'hi'
100
- expect(out.pos).to eq(2)
101
- end
102
- end
103
-
104
- it 'is writable' do
105
- out = stream { }
106
- out.pos = 10
107
- expect(out.pos).to eq(10)
108
- end
109
-
110
- it 'aliased to #tell' do
111
- out = stream { }
112
- expect(out.tell).to eq(0)
113
- out.pos = 10
114
- expect(out.tell).to eq(10)
115
- end
116
- end
117
-
118
- context 'closed' do
119
- it 'returns false while streaming' do
120
- stream { |out| expect(out).not_to be_closed }
121
- end
122
-
123
- it 'returns true after streaming' do
124
- expect(stream {}).to be_closed
125
- end
126
- end
127
-
128
- context 'map!' do
129
- it 'applies transformations later' do
130
- stream do |out|
131
- out.map! { |s| s.upcase }
132
- out << 'ok'
133
- end
134
- expect(body).to eq("OK")
135
- end
136
-
137
- it 'is chainable' do
138
- stream do |out|
139
- out.map! { |s| s.upcase }
140
- out.map! { |s| s.reverse }
141
- out << 'ok'
142
- end
143
- expect(body).to eq("KO")
144
- end
145
-
146
- it 'works with middleware' do
147
- middleware = Class.new do
148
- def initialize(app) @app = app end
149
- def call(env)
150
- status, headers, body = @app.call(env)
151
- body.map! { |s| s.upcase }
152
- [status, headers, body]
153
- end
154
- end
155
-
156
- use middleware
157
- stream { |out| out << "ok" }
158
- expect(body).to eq("OK")
159
- end
160
-
161
- it 'modifies each value separately' do
162
- stream do |out|
163
- out.map! { |s| s.reverse }
164
- out << "ab" << "cd"
165
- end
166
- expect(body).to eq("badc")
167
- end
168
- end
169
-
170
- context 'map' do
171
- it 'works with middleware' do
172
- middleware = Class.new do
173
- def initialize(app) @app = app end
174
- def call(env)
175
- status, headers, body = @app.call(env)
176
- [status, headers, body.map(&:upcase)]
177
- end
178
- end
179
-
180
- use middleware
181
- stream { |out| out << "ok" }
182
- expect(body).to eq("OK")
183
- end
184
-
185
- it 'is chainable' do
186
- middleware = Class.new do
187
- def initialize(app) @app = app end
188
- def call(env)
189
- status, headers, body = @app.call(env)
190
- [status, headers, body.map(&:upcase).map(&:reverse)]
191
- end
192
- end
193
-
194
- use middleware
195
- stream { |out| out << "ok" }
196
- expect(body).to eq("KO")
197
- end
198
-
199
- it 'can be written as each.map' do
200
- middleware = Class.new do
201
- def initialize(app) @app = app end
202
- def call(env)
203
- status, headers, body = @app.call(env)
204
- [status, headers, body.each.map(&:upcase)]
205
- end
206
- end
207
-
208
- use middleware
209
- stream { |out| out << "ok" }
210
- expect(body).to eq("OK")
211
- end
212
-
213
- it 'does not modify the original body' do
214
- stream do |out|
215
- out.map { |s| s.reverse }
216
- out << 'ok'
217
- end
218
- expect(body).to eq('ok')
219
- end
220
- end
221
-
222
- context 'write' do
223
- it 'writes to the stream' do
224
- stream { |out| out.write 'hi' }
225
- expect(body).to eq('hi')
226
- end
227
-
228
- it 'returns the number of bytes' do
229
- stream do |out|
230
- expect(out.write('hi')).to eq(2)
231
- expect(out.write('hello')).to eq(5)
232
- end
233
- end
234
-
235
- it 'accepts non-string objects' do
236
- stream do |out|
237
- expect(out.write(12)).to eq(2)
238
- end
239
- end
240
-
241
- it 'should be aliased to syswrite' do
242
- stream { |out| expect(out.syswrite('hi')).to eq(2) }
243
- expect(body).to eq('hi')
244
- end
245
-
246
- it 'should be aliased to write_nonblock' do
247
- stream { |out| expect(out.write_nonblock('hi')).to eq(2) }
248
- expect(body).to eq('hi')
249
- end
250
- end
251
-
252
- context 'print' do
253
- it 'writes to the stream' do
254
- stream { |out| out.print('hi') }
255
- expect(body).to eq('hi')
256
- end
257
-
258
- it 'accepts multiple arguments' do
259
- stream { |out| out.print(1, 2, 3, 4) }
260
- expect(body).to eq('1234')
261
- end
262
-
263
- it 'returns nil' do
264
- stream { |out| expect(out.print('hi')).to be_nil }
265
- end
266
- end
267
-
268
- context 'printf' do
269
- it 'writes to the stream' do
270
- stream { |out| out.printf('hi') }
271
- expect(body).to eq('hi')
272
- end
273
-
274
- it 'interpolates the format string' do
275
- stream { |out| out.printf("%s: %d", "answer", 42) }
276
- expect(body).to eq('answer: 42')
277
- end
278
-
279
- it 'returns nil' do
280
- stream { |out| expect(out.printf('hi')).to be_nil }
281
- end
282
- end
283
-
284
- context 'putc' do
285
- it 'writes the first character of a string' do
286
- stream { |out| out.putc('hi') }
287
- expect(body).to eq('h')
288
- end
289
-
290
- it 'writes the character corresponding to an integer' do
291
- stream { |out| out.putc(42) }
292
- expect(body).to eq('*')
293
- end
294
-
295
- it 'returns nil' do
296
- stream { |out| expect(out.putc('hi')).to be_nil }
297
- end
298
- end
299
-
300
- context 'puts' do
301
- it 'writes to the stream' do
302
- stream { |out| out.puts('hi') }
303
- expect(body).to eq("hi\n")
304
- end
305
-
306
- it 'accepts multiple arguments' do
307
- stream { |out| out.puts(1, 2, 3, 4) }
308
- expect(body).to eq("1\n2\n3\n4\n")
309
- end
310
-
311
- it 'returns nil' do
312
- stream { |out| expect(out.puts('hi')).to be_nil }
313
- end
314
- end
315
-
316
- context 'close' do
317
- it 'sets #closed? to true' do
318
- stream do |out|
319
- out.close
320
- expect(out).to be_closed
321
- end
322
- end
323
-
324
- it 'sets #closed_write? to true' do
325
- stream do |out|
326
- expect(out).not_to be_closed_write
327
- out.close
328
- expect(out).to be_closed_write
329
- end
330
- end
331
-
332
- it 'fires callbacks' do
333
- stream do |out|
334
- fired = false
335
- out.callback { fired = true }
336
- out.close
337
- expect(fired).to be true
338
- end
339
- end
340
-
341
- it 'prevents from further writing' do
342
- stream do |out|
343
- out.close
344
- expect { out << 'hi' }.to raise_error(IOError, 'not opened for writing')
345
- end
346
- end
347
- end
348
-
349
- context 'close_read' do
350
- it 'raises the appropriate exception' do
351
- expect { stream { |out| out.close_read }}.
352
- to raise_error(IOError, "closing non-duplex IO for reading")
353
- end
354
- end
355
-
356
- context 'closed_read?' do
357
- it('returns true') { stream { |out| expect(out).to be_closed_read }}
358
- end
359
-
360
- context 'rewind' do
361
- it 'resets pos' do
362
- stream do |out|
363
- out << 'hi'
364
- out.rewind
365
- expect(out.pos).to eq(0)
366
- end
367
- end
368
-
369
- it 'resets lineno' do
370
- stream do |out|
371
- out.lineno = 10
372
- out.rewind
373
- expect(out.lineno).to eq(0)
374
- end
375
- end
376
- end
377
-
378
- raises = %w[
379
- bytes eof? eof getbyte getc gets read read_nonblock readbyte readchar
380
- readline readlines readpartial sysread ungetbyte ungetc
381
- ]
382
-
383
- enum = %w[chars each_line each_byte each_char lines]
384
- dummies = %w[flush fsync internal_encoding pid]
385
-
386
- raises.each do |method|
387
- context method do
388
- it 'raises the appropriate exception' do
389
- expect { stream { |out| out.public_send(method) }}.
390
- to raise_error(IOError, "not opened for reading")
391
- end
392
- end
393
- end
394
-
395
- enum.each do |method|
396
- context method do
397
- it 'creates an Enumerator' do
398
- stream { |out| expect(out.public_send(method)).to be_a(Enumerator) }
399
- end
400
-
401
- it 'calling each raises the appropriate exception' do
402
- expect { stream { |out| out.public_send(method).each { }}}.
403
- to raise_error(IOError, "not opened for reading")
404
- end
405
- end
406
- end
407
-
408
- dummies.each do |method|
409
- context method do
410
- it 'returns nil' do
411
- stream { |out| expect(out.public_send(method)).to be_nil }
412
- end
413
- end
414
- end
415
- end