webmachine 1.6.0 → 2.0.0.beta
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -5
- data/documentation/adapters.md +2 -11
- data/examples/debugger.rb +5 -3
- data/examples/logging.rb +2 -2
- data/examples/webrick.rb +2 -2
- data/lib/webmachine/adapter.rb +0 -3
- data/lib/webmachine/adapters/lazy_request_body.rb +1 -1
- data/lib/webmachine/adapters/rack.rb +38 -34
- data/lib/webmachine/adapters/rack_mapped.rb +1 -2
- data/lib/webmachine/adapters/webrick.rb +11 -12
- data/lib/webmachine/adapters.rb +0 -2
- data/lib/webmachine/application.rb +2 -2
- data/lib/webmachine/chunked_body.rb +1 -1
- data/lib/webmachine/configuration.rb +1 -1
- data/lib/webmachine/constants.rb +12 -12
- data/lib/webmachine/cookie.rb +20 -18
- data/lib/webmachine/decision/conneg.rb +24 -24
- data/lib/webmachine/decision/falsey.rb +0 -1
- data/lib/webmachine/decision/flow.rb +19 -20
- data/lib/webmachine/decision/fsm.rb +4 -4
- data/lib/webmachine/decision/helpers.rb +21 -21
- data/lib/webmachine/dispatcher/route.rb +28 -28
- data/lib/webmachine/dispatcher.rb +3 -2
- data/lib/webmachine/errors.rb +7 -8
- data/lib/webmachine/etags.rb +2 -1
- data/lib/webmachine/header_negotiation.rb +5 -6
- data/lib/webmachine/headers.rb +5 -5
- data/lib/webmachine/media_type.rb +5 -5
- data/lib/webmachine/quoted_string.rb +3 -3
- data/lib/webmachine/request.rb +7 -10
- data/lib/webmachine/rescueable_exception.rb +3 -3
- data/lib/webmachine/resource/authentication.rb +3 -4
- data/lib/webmachine/resource/callbacks.rb +3 -3
- data/lib/webmachine/resource/encodings.rb +3 -9
- data/lib/webmachine/resource.rb +1 -1
- data/lib/webmachine/response.rb +7 -9
- data/lib/webmachine/spec/adapter_lint.rb +67 -69
- data/lib/webmachine/spec/test_resource.rb +22 -22
- data/lib/webmachine/streaming/encoder.rb +3 -2
- data/lib/webmachine/streaming/io_encoder.rb +4 -3
- data/lib/webmachine/trace/fsm.rb +25 -18
- data/lib/webmachine/trace/resource_proxy.rb +10 -9
- data/lib/webmachine/trace/static/http-headers-status-v3.png +0 -0
- data/lib/webmachine/trace/trace_resource.rb +22 -24
- data/lib/webmachine/trace.rb +7 -6
- data/lib/webmachine/translation.rb +3 -3
- data/lib/webmachine/version.rb +1 -1
- metadata +52 -86
- data/.gitignore +0 -31
- data/Gemfile +0 -46
- data/Guardfile +0 -11
- data/RELEASING.md +0 -21
- data/Rakefile +0 -44
- data/lib/webmachine/adapters/httpkit.rb +0 -74
- data/lib/webmachine/adapters/reel.rb +0 -113
- data/memory_test.rb +0 -37
- data/spec/spec_helper.rb +0 -56
- data/spec/webmachine/adapter_spec.rb +0 -39
- data/spec/webmachine/adapters/httpkit_spec.rb +0 -10
- data/spec/webmachine/adapters/rack_mapped_spec.rb +0 -71
- data/spec/webmachine/adapters/rack_spec.rb +0 -62
- data/spec/webmachine/adapters/reel_spec.rb +0 -76
- data/spec/webmachine/adapters/webrick_spec.rb +0 -12
- data/spec/webmachine/application_spec.rb +0 -74
- data/spec/webmachine/chunked_body_spec.rb +0 -30
- data/spec/webmachine/configuration_spec.rb +0 -27
- data/spec/webmachine/cookie_spec.rb +0 -99
- data/spec/webmachine/decision/conneg_spec.rb +0 -166
- data/spec/webmachine/decision/falsey_spec.rb +0 -8
- data/spec/webmachine/decision/flow_spec.rb +0 -1148
- data/spec/webmachine/decision/fsm_spec.rb +0 -163
- data/spec/webmachine/decision/helpers_spec.rb +0 -216
- data/spec/webmachine/dispatcher/rfc3986_percent_decode_spec.rb +0 -22
- data/spec/webmachine/dispatcher/route_spec.rb +0 -248
- data/spec/webmachine/dispatcher_spec.rb +0 -104
- data/spec/webmachine/errors_spec.rb +0 -13
- data/spec/webmachine/etags_spec.rb +0 -75
- data/spec/webmachine/events_spec.rb +0 -58
- data/spec/webmachine/headers_spec.rb +0 -99
- data/spec/webmachine/media_type_spec.rb +0 -85
- data/spec/webmachine/request_spec.rb +0 -273
- data/spec/webmachine/rescueable_exception_spec.rb +0 -15
- data/spec/webmachine/resource/authentication_spec.rb +0 -68
- data/spec/webmachine/response_spec.rb +0 -51
- data/spec/webmachine/trace/fsm_spec.rb +0 -37
- data/spec/webmachine/trace/resource_proxy_spec.rb +0 -34
- data/spec/webmachine/trace/trace_store_spec.rb +0 -29
- data/spec/webmachine/trace_spec.rb +0 -17
- data/webmachine.gemspec +0 -25
@@ -1,104 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::Dispatcher do
|
4
|
-
let(:dispatcher) { Webmachine.application.dispatcher }
|
5
|
-
let(:request) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/"), Webmachine::Headers["accept" => "*/*"], "") }
|
6
|
-
let(:request2) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/hello/bob.html"), Webmachine::Headers["accept" => "*/*"], "") }
|
7
|
-
let(:response) { Webmachine::Response.new }
|
8
|
-
let(:resource) do
|
9
|
-
Class.new(Webmachine::Resource) do
|
10
|
-
def to_html; "hello world!"; end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
let(:resource2) do
|
14
|
-
Class.new(Webmachine::Resource) do
|
15
|
-
def to_html; "goodbye, cruel world"; end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
let(:resource3) do
|
19
|
-
Class.new(Webmachine::Resource) do
|
20
|
-
def to_html
|
21
|
-
name, format = request.path_info[:captures]
|
22
|
-
"Hello #{name} with #{format}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
let(:fsm){ double }
|
27
|
-
|
28
|
-
before { dispatcher.reset }
|
29
|
-
|
30
|
-
it "should add routes from a block" do
|
31
|
-
_resource = resource
|
32
|
-
expect(Webmachine.routes do
|
33
|
-
add [:*], _resource
|
34
|
-
end).to eq(Webmachine)
|
35
|
-
expect(dispatcher.routes.size).to eq(1)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should add routes" do
|
39
|
-
expect {
|
40
|
-
dispatcher.add_route [:*], resource
|
41
|
-
}.to_not raise_error
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should have add_route return the newly created route" do
|
45
|
-
route = dispatcher.add_route [:*], resource
|
46
|
-
expect(route).to be_instance_of Webmachine::Dispatcher::Route
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should route to the proper resource" do
|
50
|
-
dispatcher.add_route ["goodbye"], resource2
|
51
|
-
dispatcher.add_route [:*], resource
|
52
|
-
expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource), request, response).and_return(fsm)
|
53
|
-
expect(fsm).to receive(:run)
|
54
|
-
dispatcher.dispatch(request, response)
|
55
|
-
end
|
56
|
-
it "should handle regex path segments in route definition" do
|
57
|
-
dispatcher.add_route ["hello", /(.*)\.(.*)/], resource3
|
58
|
-
expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource3), request2, response).and_return(fsm)
|
59
|
-
expect(fsm).to receive(:run)
|
60
|
-
dispatcher.dispatch(request2, response)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should apply route to request before creating the resource" do
|
64
|
-
route = dispatcher.add_route [:*], resource
|
65
|
-
applied = false
|
66
|
-
|
67
|
-
expect(route).to receive(:apply) { applied = true }
|
68
|
-
expect(resource).to(receive(:new) do
|
69
|
-
expect(applied).to be(true)
|
70
|
-
resource2.new(request, response)
|
71
|
-
end)
|
72
|
-
|
73
|
-
dispatcher.dispatch(request, response)
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should add routes with guards" do
|
77
|
-
dispatcher.add [], lambda {|req| req.method == "POST" }, resource
|
78
|
-
dispatcher.add [:*], resource2 do |req|
|
79
|
-
!req.query.empty?
|
80
|
-
end
|
81
|
-
request.uri.query = "?foo=bar"
|
82
|
-
expect(dispatcher.routes.size).to eq(2)
|
83
|
-
expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource2), request, response).and_return(fsm)
|
84
|
-
expect(fsm).to receive(:run)
|
85
|
-
dispatcher.dispatch(request, response)
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should respond with a valid resource for a 404" do
|
89
|
-
dispatcher.dispatch(request, response)
|
90
|
-
expect(response.code).to eq(404)
|
91
|
-
expect(response.body).to_not be_empty
|
92
|
-
expect(response.headers).to have_key('Content-Length')
|
93
|
-
expect(response.headers).to have_key('Date')
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should respond with a valid resource for a 404 with a custom Accept header" do
|
97
|
-
request.headers['Accept'] = "application/json"
|
98
|
-
dispatcher.dispatch(request, response)
|
99
|
-
expect(response.code).to eq(404)
|
100
|
-
expect(response.body).to_not be_empty
|
101
|
-
expect(response.headers).to have_key('Content-Length')
|
102
|
-
expect(response.headers).to have_key('Date')
|
103
|
-
end
|
104
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "Webmachine errors" do
|
4
|
-
describe ".render_error" do
|
5
|
-
it "sets the given response code on the response object" do
|
6
|
-
req = double('request', :method => 'GET').as_null_object
|
7
|
-
res = Webmachine::Response.new
|
8
|
-
|
9
|
-
Webmachine.render_error(404, req, res)
|
10
|
-
expect(res.code).to eq(404)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::ETag do
|
4
|
-
let(:etag_str){ '"deadbeef12345678"' }
|
5
|
-
let(:etag) { described_class.new etag_str }
|
6
|
-
|
7
|
-
subject { etag }
|
8
|
-
|
9
|
-
it { is_expected.to eq(etag_str) }
|
10
|
-
it { is_expected.to be_kind_of(described_class) }
|
11
|
-
its(:to_s) { should == '"deadbeef12345678"' }
|
12
|
-
its(:etag) { should == '"deadbeef12345678"' }
|
13
|
-
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
14
|
-
|
15
|
-
context "when the original etag is unquoted" do
|
16
|
-
let(:etag_str) { 'deadbeef12345678' }
|
17
|
-
|
18
|
-
it { is_expected.to eq(etag_str) }
|
19
|
-
its(:to_s) { should == '"deadbeef12345678"' }
|
20
|
-
its(:etag) { should == '"deadbeef12345678"' }
|
21
|
-
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
22
|
-
end
|
23
|
-
|
24
|
-
context "when the original etag contains unbalanced quotes" do
|
25
|
-
let(:etag_str) { 'deadbeef"12345678' }
|
26
|
-
|
27
|
-
it { is_expected.to eq(etag_str) }
|
28
|
-
its(:to_s) { should == '"deadbeef\\"12345678"' }
|
29
|
-
its(:etag) { should == '"deadbeef\\"12345678"' }
|
30
|
-
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe Webmachine::WeakETag do
|
35
|
-
let(:strong_etag){ '"deadbeef12345678"' }
|
36
|
-
let(:weak_etag) { described_class.new strong_etag }
|
37
|
-
|
38
|
-
subject { weak_etag }
|
39
|
-
|
40
|
-
it { is_expected.to eq(strong_etag) }
|
41
|
-
it { is_expected.to be_kind_of(described_class) }
|
42
|
-
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
43
|
-
its(:etag) { should == '"deadbeef12345678"' }
|
44
|
-
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
45
|
-
|
46
|
-
context "when the original etag is unquoted" do
|
47
|
-
let(:strong_etag) { 'deadbeef12345678' }
|
48
|
-
|
49
|
-
it { is_expected.to eq(strong_etag) }
|
50
|
-
it { is_expected.to be_kind_of(described_class) }
|
51
|
-
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
52
|
-
its(:etag) { should == '"deadbeef12345678"' }
|
53
|
-
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when the original etag contains unbalanced quotes" do
|
57
|
-
let(:strong_etag) { 'deadbeef"12345678' }
|
58
|
-
|
59
|
-
it { is_expected.to eq(strong_etag) }
|
60
|
-
it { is_expected.to be_kind_of(described_class) }
|
61
|
-
its(:to_s) { should == 'W/"deadbeef\\"12345678"' }
|
62
|
-
its(:etag) { should == '"deadbeef\\"12345678"' }
|
63
|
-
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
64
|
-
end
|
65
|
-
|
66
|
-
context "when the original etag is already a weak tag" do
|
67
|
-
let(:strong_etag) { 'W/"deadbeef12345678"' }
|
68
|
-
|
69
|
-
it { is_expected.to eq(strong_etag) }
|
70
|
-
it { is_expected.to be_kind_of(described_class) }
|
71
|
-
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
72
|
-
its(:etag) { should == '"deadbeef12345678"' }
|
73
|
-
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
74
|
-
end
|
75
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::Events do
|
4
|
-
describe ".backend" do
|
5
|
-
it "defaults to AS::Notifications" do
|
6
|
-
expect(described_class.backend).to be(AS::Notifications)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe ".publish" do
|
11
|
-
it "calls the backend" do
|
12
|
-
expect(described_class.backend).to receive(:publish).with('test.event', 1, 'two')
|
13
|
-
described_class.publish('test.event', 1, 'two')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe ".instrument" do
|
18
|
-
it "calls the backend" do
|
19
|
-
expect(described_class.backend).to receive(:instrument).with(
|
20
|
-
'test.event', {}
|
21
|
-
).and_yield
|
22
|
-
|
23
|
-
described_class.instrument('test.event') { }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe ".subscribe" do
|
28
|
-
it "calls the backend" do
|
29
|
-
expect(described_class.backend).to receive(:subscribe).with(
|
30
|
-
'test.event'
|
31
|
-
).and_yield
|
32
|
-
|
33
|
-
described_class.subscribe('test.event') { }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe ".subscribed" do
|
38
|
-
it "calls the backend" do
|
39
|
-
callback = Proc.new { }
|
40
|
-
|
41
|
-
expect(described_class.backend).to receive(:subscribed).with(
|
42
|
-
callback, 'test.event'
|
43
|
-
).and_yield
|
44
|
-
|
45
|
-
described_class.subscribed(callback, 'test.event') { }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe ".unsubscribe" do
|
50
|
-
it "calls the backend" do
|
51
|
-
subscriber = described_class.subscribe('test.event') { }
|
52
|
-
|
53
|
-
expect(described_class.backend).to receive(:unsubscribe).with(subscriber)
|
54
|
-
|
55
|
-
described_class.unsubscribe(subscriber)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::Headers do
|
4
|
-
it "should set and access values insensitive to case" do
|
5
|
-
subject['Content-TYPE'] = "text/plain"
|
6
|
-
expect(subject['CONTENT-TYPE']).to eq('text/plain')
|
7
|
-
expect(subject.delete('CoNtEnT-tYpE')).to eq('text/plain')
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#from_cgi" do
|
11
|
-
it "should understand the Content-Length header" do
|
12
|
-
headers = described_class.from_cgi("CONTENT_LENGTH" => 14)
|
13
|
-
expect(headers["content-length"]).to eq(14)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe ".[]" do
|
18
|
-
context "Webmachine::Headers['Content-Type', 'application/json']" do
|
19
|
-
it "creates a hash with lowercase keys" do
|
20
|
-
headers = described_class[
|
21
|
-
'Content-Type', 'application/json',
|
22
|
-
'Accept', 'application/json'
|
23
|
-
]
|
24
|
-
|
25
|
-
expect(headers.to_hash).to eq({
|
26
|
-
'content-type' => 'application/json',
|
27
|
-
'accept' => 'application/json'
|
28
|
-
})
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context "Webmachine::Headers[[['Content-Type', 'application/json']]]" do
|
33
|
-
it "creates a hash with lowercase keys" do
|
34
|
-
headers = described_class[
|
35
|
-
[
|
36
|
-
['Content-Type', 'application/json'],
|
37
|
-
['Accept', 'application/json']
|
38
|
-
]
|
39
|
-
]
|
40
|
-
|
41
|
-
expect(headers.to_hash).to eq({
|
42
|
-
'content-type' => 'application/json',
|
43
|
-
'accept' => 'application/json'
|
44
|
-
})
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "Webmachine::Headers['Content-Type' => 'application/json']" do
|
49
|
-
it "creates a hash with lowercase keys" do
|
50
|
-
headers = described_class[
|
51
|
-
'Content-Type' => 'application/json',
|
52
|
-
'Accept' => 'application/json'
|
53
|
-
]
|
54
|
-
|
55
|
-
expect(headers.to_hash).to eq({
|
56
|
-
'content-type' => 'application/json',
|
57
|
-
'accept' => 'application/json'
|
58
|
-
})
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "#fetch" do
|
64
|
-
subject { described_class['Content-Type' => 'application/json'] }
|
65
|
-
|
66
|
-
it "returns the value for the given key" do
|
67
|
-
expect(subject.fetch('conTent-tYpe')).to eq('application/json')
|
68
|
-
end
|
69
|
-
|
70
|
-
context "acessing a missing key" do
|
71
|
-
it "raises an IndexError" do
|
72
|
-
expect { subject.fetch('accept') }.to raise_error(IndexError)
|
73
|
-
end
|
74
|
-
|
75
|
-
context "and a default value given" do
|
76
|
-
it "returns the default value if the key does not exist" do
|
77
|
-
expect(subject.fetch('accept', 'text/html')).to eq('text/html')
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context "and a block given" do
|
82
|
-
it "passes the value to the block and returns the block's result" do
|
83
|
-
expect(subject.fetch('access') {|k| "#{k} not found"}).to eq('access not found')
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context "filtering with #grep" do
|
90
|
-
subject { described_class["content-type" => "text/plain", "etag" => '"abcdef1234567890"'] }
|
91
|
-
it "should filter keys by the given pattern" do
|
92
|
-
expect(subject.grep(/content/i)).to include("content-type")
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should return a Headers instance" do
|
96
|
-
expect(subject.grep(/etag/i)).to be_instance_of(described_class)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::MediaType do
|
4
|
-
let(:raw_type){ "application/xml;charset=UTF-8" }
|
5
|
-
subject { described_class.new("application/xml", {"charset" => "UTF-8"}) }
|
6
|
-
|
7
|
-
context "equivalence" do
|
8
|
-
it { is_expected.to eq(raw_type) }
|
9
|
-
it { is_expected.to eq(described_class.parse(raw_type)) }
|
10
|
-
end
|
11
|
-
|
12
|
-
context "when it is the wildcard type" do
|
13
|
-
subject { described_class.new("*/*") }
|
14
|
-
it { is_expected.to be_matches_all }
|
15
|
-
end
|
16
|
-
|
17
|
-
context "parsing a type" do
|
18
|
-
it "should return MediaTypes untouched" do
|
19
|
-
expect(described_class.parse(subject)).to equal(subject)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should parse a String" do
|
23
|
-
type = described_class.parse(raw_type)
|
24
|
-
expect(type).to be_kind_of(described_class)
|
25
|
-
expect(type.type).to eq("application/xml")
|
26
|
-
expect(type.params).to eq({"charset" => "UTF-8"})
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should parse a type/params pair" do
|
30
|
-
type = described_class.parse(["application/xml", {"charset" => "UTF-8"}])
|
31
|
-
expect(type).to be_kind_of(described_class)
|
32
|
-
expect(type.type).to eq("application/xml")
|
33
|
-
expect(type.params).to eq({"charset" => "UTF-8"})
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should parse a type/params pair where the type has some params in the string" do
|
37
|
-
type = described_class.parse(["application/xml;version=1", {"charset" => "UTF-8"}])
|
38
|
-
expect(type).to be_kind_of(described_class)
|
39
|
-
expect(type.type).to eq("application/xml")
|
40
|
-
expect(type.params).to eq({"charset" => "UTF-8", "version" => "1"})
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should parse a type/params pair with params and whitespace in the string" do
|
44
|
-
type = described_class.parse(["multipart/form-data; boundary=----------------------------2c46a7bec2b9", {"charset" => "UTF-8"}])
|
45
|
-
expect(type).to be_kind_of(described_class)
|
46
|
-
expect(type.type).to eq("multipart/form-data")
|
47
|
-
expect(type.params).to eq({"boundary" => "----------------------------2c46a7bec2b9", "charset" => "UTF-8"})
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should parse a type/params pair where type has single-token params" do
|
51
|
-
type = described_class.parse(["text/html;q=1;rdfa", {"charset" => "UTF-8"}])
|
52
|
-
expect(type).to be_kind_of(described_class)
|
53
|
-
expect(type.type).to eq("text/html")
|
54
|
-
expect(type.params).to eq({"q" => "1", "rdfa" => "", "charset" => "UTF-8"})
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should raise an error when given an invalid type/params pair" do
|
58
|
-
expect {
|
59
|
-
described_class.parse([false, "blah"])
|
60
|
-
}.to raise_error(ArgumentError)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "matching a requested type" do
|
65
|
-
it { is_expected.to be_exact_match("application/xml;charset=UTF-8") }
|
66
|
-
it { is_expected.to be_exact_match("application/*;charset=UTF-8") }
|
67
|
-
it { is_expected.to be_exact_match("*/*;charset=UTF-8") }
|
68
|
-
it { is_expected.to be_exact_match("*;charset=UTF-8") }
|
69
|
-
it { is_expected.not_to be_exact_match("text/xml") }
|
70
|
-
it { is_expected.not_to be_exact_match("application/xml") }
|
71
|
-
it { is_expected.not_to be_exact_match("application/xml;version=1") }
|
72
|
-
|
73
|
-
it { is_expected.to be_type_matches("application/xml") }
|
74
|
-
it { is_expected.to be_type_matches("application/*") }
|
75
|
-
it { is_expected.to be_type_matches("*/*") }
|
76
|
-
it { is_expected.to be_type_matches("*") }
|
77
|
-
it { is_expected.not_to be_type_matches("text/xml") }
|
78
|
-
it { is_expected.not_to be_type_matches("text/*") }
|
79
|
-
|
80
|
-
it { is_expected.to be_params_match({}) }
|
81
|
-
it { is_expected.to be_params_match({"charset" => "UTF-8"}) }
|
82
|
-
it { is_expected.not_to be_params_match({"charset" => "Windows-1252"}) }
|
83
|
-
it { is_expected.not_to be_params_match({"version" => "3"}) }
|
84
|
-
end
|
85
|
-
end
|