webmachine 1.2.2 → 1.3.0
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 +7 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +13 -11
- data/README.md +85 -89
- data/Rakefile +0 -1
- data/documentation/adapters.md +39 -0
- data/documentation/authentication-and-authorization.md +37 -0
- data/documentation/configurator.md +19 -0
- data/documentation/error-handling.md +86 -0
- data/documentation/examples.md +215 -0
- data/documentation/how-it-works.md +76 -0
- data/documentation/routes.md +97 -0
- data/documentation/validation.md +159 -0
- data/documentation/versioning-apis.md +74 -0
- data/documentation/visual-debugger.md +38 -0
- data/examples/application.rb +2 -2
- data/examples/debugger.rb +1 -1
- data/lib/webmachine.rb +3 -1
- data/lib/webmachine/adapter.rb +7 -13
- data/lib/webmachine/adapters.rb +1 -2
- data/lib/webmachine/adapters/httpkit.rb +74 -0
- data/lib/webmachine/adapters/lazy_request_body.rb +1 -2
- data/lib/webmachine/adapters/rack.rb +37 -21
- data/lib/webmachine/adapters/reel.rb +21 -23
- data/lib/webmachine/adapters/webrick.rb +16 -16
- data/lib/webmachine/application.rb +2 -2
- data/lib/webmachine/chunked_body.rb +3 -4
- data/lib/webmachine/constants.rb +75 -0
- data/lib/webmachine/decision/conneg.rb +12 -10
- data/lib/webmachine/decision/flow.rb +31 -21
- data/lib/webmachine/decision/fsm.rb +10 -18
- data/lib/webmachine/decision/helpers.rb +9 -37
- data/lib/webmachine/dispatcher.rb +13 -10
- data/lib/webmachine/dispatcher/route.rb +18 -8
- data/lib/webmachine/errors.rb +7 -1
- data/lib/webmachine/header_negotiation.rb +25 -0
- data/lib/webmachine/headers.rb +7 -2
- data/lib/webmachine/locale/en.yml +7 -5
- data/lib/webmachine/media_type.rb +10 -8
- data/lib/webmachine/request.rb +44 -15
- data/lib/webmachine/resource.rb +1 -1
- data/lib/webmachine/resource/callbacks.rb +6 -4
- data/lib/webmachine/spec/IO_response.body +1 -0
- data/lib/webmachine/spec/adapter_lint.rb +70 -36
- data/lib/webmachine/spec/test_resource.rb +10 -4
- data/lib/webmachine/streaming/fiber_encoder.rb +1 -5
- data/lib/webmachine/streaming/io_encoder.rb +6 -0
- data/lib/webmachine/trace.rb +1 -0
- data/lib/webmachine/trace/fsm.rb +20 -10
- data/lib/webmachine/trace/resource_proxy.rb +2 -0
- data/lib/webmachine/translation.rb +2 -1
- data/lib/webmachine/version.rb +3 -3
- data/memory_test.rb +37 -0
- data/spec/spec_helper.rb +9 -9
- data/spec/webmachine/adapter_spec.rb +14 -15
- data/spec/webmachine/adapters/httpkit_spec.rb +10 -0
- data/spec/webmachine/adapters/rack_spec.rb +6 -6
- data/spec/webmachine/adapters/reel_spec.rb +15 -11
- data/spec/webmachine/adapters/webrick_spec.rb +2 -2
- data/spec/webmachine/application_spec.rb +18 -17
- data/spec/webmachine/chunked_body_spec.rb +3 -3
- data/spec/webmachine/configuration_spec.rb +5 -5
- data/spec/webmachine/cookie_spec.rb +13 -13
- data/spec/webmachine/decision/conneg_spec.rb +48 -42
- data/spec/webmachine/decision/falsey_spec.rb +4 -4
- data/spec/webmachine/decision/flow_spec.rb +194 -144
- data/spec/webmachine/decision/fsm_spec.rb +17 -17
- data/spec/webmachine/decision/helpers_spec.rb +20 -20
- data/spec/webmachine/dispatcher/route_spec.rb +73 -27
- data/spec/webmachine/dispatcher_spec.rb +34 -24
- data/spec/webmachine/errors_spec.rb +1 -1
- data/spec/webmachine/etags_spec.rb +19 -19
- data/spec/webmachine/events_spec.rb +6 -6
- data/spec/webmachine/headers_spec.rb +14 -14
- data/spec/webmachine/media_type_spec.rb +36 -36
- data/spec/webmachine/request_spec.rb +33 -33
- data/spec/webmachine/resource/authentication_spec.rb +6 -6
- data/spec/webmachine/response_spec.rb +12 -12
- data/spec/webmachine/trace/fsm_spec.rb +8 -8
- data/spec/webmachine/trace/resource_proxy_spec.rb +9 -9
- data/spec/webmachine/trace/trace_store_spec.rb +5 -5
- data/spec/webmachine/trace_spec.rb +3 -3
- data/webmachine.gemspec +2 -6
- metadata +48 -206
- data/lib/webmachine/adapters/hatetepe.rb +0 -108
- data/lib/webmachine/adapters/mongrel.rb +0 -127
- data/lib/webmachine/dispatcher/not_found_resource.rb +0 -5
- data/lib/webmachine/fiber18.rb +0 -88
- data/spec/webmachine/adapters/hatetepe_spec.rb +0 -60
- data/spec/webmachine/adapters/mongrel_spec.rb +0 -16
@@ -6,28 +6,28 @@ describe Webmachine::ETag do
|
|
6
6
|
|
7
7
|
subject { etag }
|
8
8
|
|
9
|
-
it {
|
10
|
-
it {
|
9
|
+
it { is_expected.to eq(etag_str) }
|
10
|
+
it { is_expected.to be_kind_of(described_class) }
|
11
11
|
its(:to_s) { should == '"deadbeef12345678"' }
|
12
12
|
its(:etag) { should == '"deadbeef12345678"' }
|
13
|
-
it {
|
13
|
+
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
14
14
|
|
15
15
|
context "when the original etag is unquoted" do
|
16
16
|
let(:etag_str) { 'deadbeef12345678' }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to eq(etag_str) }
|
19
19
|
its(:to_s) { should == '"deadbeef12345678"' }
|
20
20
|
its(:etag) { should == '"deadbeef12345678"' }
|
21
|
-
it {
|
21
|
+
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
22
22
|
end
|
23
23
|
|
24
24
|
context "when the original etag contains unbalanced quotes" do
|
25
25
|
let(:etag_str) { 'deadbeef"12345678' }
|
26
26
|
|
27
|
-
it {
|
27
|
+
it { is_expected.to eq(etag_str) }
|
28
28
|
its(:to_s) { should == '"deadbeef\\"12345678"' }
|
29
29
|
its(:etag) { should == '"deadbeef\\"12345678"' }
|
30
|
-
it {
|
30
|
+
it { is_expected.to eq(described_class.new(etag_str.dup)) }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -37,39 +37,39 @@ describe Webmachine::WeakETag do
|
|
37
37
|
|
38
38
|
subject { weak_etag }
|
39
39
|
|
40
|
-
it {
|
41
|
-
it {
|
40
|
+
it { is_expected.to eq(strong_etag) }
|
41
|
+
it { is_expected.to be_kind_of(described_class) }
|
42
42
|
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
43
43
|
its(:etag) { should == '"deadbeef12345678"' }
|
44
|
-
it {
|
44
|
+
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
45
45
|
|
46
46
|
context "when the original etag is unquoted" do
|
47
47
|
let(:strong_etag) { 'deadbeef12345678' }
|
48
48
|
|
49
|
-
it {
|
50
|
-
it {
|
49
|
+
it { is_expected.to eq(strong_etag) }
|
50
|
+
it { is_expected.to be_kind_of(described_class) }
|
51
51
|
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
52
52
|
its(:etag) { should == '"deadbeef12345678"' }
|
53
|
-
it {
|
53
|
+
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
54
54
|
end
|
55
55
|
|
56
56
|
context "when the original etag contains unbalanced quotes" do
|
57
57
|
let(:strong_etag) { 'deadbeef"12345678' }
|
58
58
|
|
59
|
-
it {
|
60
|
-
it {
|
59
|
+
it { is_expected.to eq(strong_etag) }
|
60
|
+
it { is_expected.to be_kind_of(described_class) }
|
61
61
|
its(:to_s) { should == 'W/"deadbeef\\"12345678"' }
|
62
62
|
its(:etag) { should == '"deadbeef\\"12345678"' }
|
63
|
-
it {
|
63
|
+
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
64
64
|
end
|
65
65
|
|
66
66
|
context "when the original etag is already a weak tag" do
|
67
67
|
let(:strong_etag) { 'W/"deadbeef12345678"' }
|
68
68
|
|
69
|
-
it {
|
70
|
-
it {
|
69
|
+
it { is_expected.to eq(strong_etag) }
|
70
|
+
it { is_expected.to be_kind_of(described_class) }
|
71
71
|
its(:to_s) { should == 'W/"deadbeef12345678"' }
|
72
72
|
its(:etag) { should == '"deadbeef12345678"' }
|
73
|
-
it {
|
73
|
+
it { is_expected.to eq(described_class.new(strong_etag.dup)) }
|
74
74
|
end
|
75
75
|
end
|
@@ -3,20 +3,20 @@ require 'spec_helper'
|
|
3
3
|
describe Webmachine::Events do
|
4
4
|
describe ".backend" do
|
5
5
|
it "defaults to AS::Notifications" do
|
6
|
-
described_class.backend.
|
6
|
+
expect(described_class.backend).to be(AS::Notifications)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe ".publish" do
|
11
11
|
it "calls the backend" do
|
12
|
-
described_class.backend.
|
12
|
+
expect(described_class.backend).to receive(:publish).with('test.event', 1, 'two')
|
13
13
|
described_class.publish('test.event', 1, 'two')
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe ".instrument" do
|
18
18
|
it "calls the backend" do
|
19
|
-
described_class.backend.
|
19
|
+
expect(described_class.backend).to receive(:instrument).with(
|
20
20
|
'test.event', {}
|
21
21
|
).and_yield
|
22
22
|
|
@@ -26,7 +26,7 @@ describe Webmachine::Events do
|
|
26
26
|
|
27
27
|
describe ".subscribe" do
|
28
28
|
it "calls the backend" do
|
29
|
-
described_class.backend.
|
29
|
+
expect(described_class.backend).to receive(:subscribe).with(
|
30
30
|
'test.event'
|
31
31
|
).and_yield
|
32
32
|
|
@@ -38,7 +38,7 @@ describe Webmachine::Events do
|
|
38
38
|
it "calls the backend" do
|
39
39
|
callback = Proc.new { }
|
40
40
|
|
41
|
-
described_class.backend.
|
41
|
+
expect(described_class.backend).to receive(:subscribed).with(
|
42
42
|
callback, 'test.event'
|
43
43
|
).and_yield
|
44
44
|
|
@@ -50,7 +50,7 @@ describe Webmachine::Events do
|
|
50
50
|
it "calls the backend" do
|
51
51
|
subscriber = described_class.subscribe('test.event') { }
|
52
52
|
|
53
|
-
described_class.backend.
|
53
|
+
expect(described_class.backend).to receive(:unsubscribe).with(subscriber)
|
54
54
|
|
55
55
|
described_class.unsubscribe(subscriber)
|
56
56
|
end
|
@@ -3,14 +3,14 @@ require 'spec_helper'
|
|
3
3
|
describe Webmachine::Headers do
|
4
4
|
it "should set and access values insensitive to case" do
|
5
5
|
subject['Content-TYPE'] = "text/plain"
|
6
|
-
subject['CONTENT-TYPE'].
|
7
|
-
subject.delete('CoNtEnT-tYpE').
|
6
|
+
expect(subject['CONTENT-TYPE']).to eq('text/plain')
|
7
|
+
expect(subject.delete('CoNtEnT-tYpE')).to eq('text/plain')
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "#from_cgi" do
|
11
11
|
it "should understand the Content-Length header" do
|
12
12
|
headers = described_class.from_cgi("CONTENT_LENGTH" => 14)
|
13
|
-
headers["content-length"].
|
13
|
+
expect(headers["content-length"]).to eq(14)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -22,10 +22,10 @@ describe Webmachine::Headers do
|
|
22
22
|
'Accept', 'application/json'
|
23
23
|
]
|
24
24
|
|
25
|
-
headers.to_hash.
|
25
|
+
expect(headers.to_hash).to eq({
|
26
26
|
'content-type' => 'application/json',
|
27
27
|
'accept' => 'application/json'
|
28
|
-
}
|
28
|
+
})
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -38,10 +38,10 @@ describe Webmachine::Headers do
|
|
38
38
|
]
|
39
39
|
]
|
40
40
|
|
41
|
-
headers.to_hash.
|
41
|
+
expect(headers.to_hash).to eq({
|
42
42
|
'content-type' => 'application/json',
|
43
43
|
'accept' => 'application/json'
|
44
|
-
}
|
44
|
+
})
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -52,10 +52,10 @@ describe Webmachine::Headers do
|
|
52
52
|
'Accept' => 'application/json'
|
53
53
|
]
|
54
54
|
|
55
|
-
headers.to_hash.
|
55
|
+
expect(headers.to_hash).to eq({
|
56
56
|
'content-type' => 'application/json',
|
57
57
|
'accept' => 'application/json'
|
58
|
-
}
|
58
|
+
})
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -64,7 +64,7 @@ describe Webmachine::Headers do
|
|
64
64
|
subject { described_class['Content-Type' => 'application/json'] }
|
65
65
|
|
66
66
|
it "returns the value for the given key" do
|
67
|
-
subject.fetch('conTent-tYpe').
|
67
|
+
expect(subject.fetch('conTent-tYpe')).to eq('application/json')
|
68
68
|
end
|
69
69
|
|
70
70
|
context "acessing a missing key" do
|
@@ -74,13 +74,13 @@ describe Webmachine::Headers do
|
|
74
74
|
|
75
75
|
context "and a default value given" do
|
76
76
|
it "returns the default value if the key does not exist" do
|
77
|
-
subject.fetch('accept', 'text/html').
|
77
|
+
expect(subject.fetch('accept', 'text/html')).to eq('text/html')
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
81
|
context "and a block given" do
|
82
82
|
it "passes the value to the block and returns the block's result" do
|
83
|
-
subject.fetch('access') {|k| "#{k} not found"}.
|
83
|
+
expect(subject.fetch('access') {|k| "#{k} not found"}).to eq('access not found')
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -89,11 +89,11 @@ describe Webmachine::Headers do
|
|
89
89
|
context "filtering with #grep" do
|
90
90
|
subject { described_class["content-type" => "text/plain", "etag" => '"abcdef1234567890"'] }
|
91
91
|
it "should filter keys by the given pattern" do
|
92
|
-
subject.grep(/content/i).
|
92
|
+
expect(subject.grep(/content/i)).to include("content-type")
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should return a Headers instance" do
|
96
|
-
subject.grep(/etag/i).
|
96
|
+
expect(subject.grep(/etag/i)).to be_instance_of(described_class)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
@@ -5,53 +5,53 @@ describe Webmachine::MediaType do
|
|
5
5
|
subject { described_class.new("application/xml", {"charset" => "UTF-8"}) }
|
6
6
|
|
7
7
|
context "equivalence" do
|
8
|
-
it {
|
9
|
-
it {
|
8
|
+
it { is_expected.to eq(raw_type) }
|
9
|
+
it { is_expected.to eq(described_class.parse(raw_type)) }
|
10
10
|
end
|
11
11
|
|
12
12
|
context "when it is the wildcard type" do
|
13
13
|
subject { described_class.new("*/*") }
|
14
|
-
it {
|
14
|
+
it { is_expected.to be_matches_all }
|
15
15
|
end
|
16
16
|
|
17
17
|
context "parsing a type" do
|
18
18
|
it "should return MediaTypes untouched" do
|
19
|
-
described_class.parse(subject).
|
19
|
+
expect(described_class.parse(subject)).to equal(subject)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should parse a String" do
|
23
23
|
type = described_class.parse(raw_type)
|
24
|
-
type.
|
25
|
-
type.type.
|
26
|
-
type.params.
|
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
27
|
end
|
28
28
|
|
29
29
|
it "should parse a type/params pair" do
|
30
30
|
type = described_class.parse(["application/xml", {"charset" => "UTF-8"}])
|
31
|
-
type.
|
32
|
-
type.type.
|
33
|
-
type.params.
|
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
34
|
end
|
35
35
|
|
36
36
|
it "should parse a type/params pair where the type has some params in the string" do
|
37
37
|
type = described_class.parse(["application/xml;version=1", {"charset" => "UTF-8"}])
|
38
|
-
type.
|
39
|
-
type.type.
|
40
|
-
type.params.
|
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
41
|
end
|
42
42
|
|
43
43
|
it "should parse a type/params pair with params and whitespace in the string" do
|
44
44
|
type = described_class.parse(["multipart/form-data; boundary=----------------------------2c46a7bec2b9", {"charset" => "UTF-8"}])
|
45
|
-
type.
|
46
|
-
type.type.
|
47
|
-
type.params.
|
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
48
|
end
|
49
49
|
|
50
50
|
it "should parse a type/params pair where type has single-token params" do
|
51
51
|
type = described_class.parse(["text/html;q=1;rdfa", {"charset" => "UTF-8"}])
|
52
|
-
type.
|
53
|
-
type.type.
|
54
|
-
type.params.
|
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
55
|
end
|
56
56
|
|
57
57
|
it "should raise an error when given an invalid type/params pair" do
|
@@ -62,24 +62,24 @@ describe Webmachine::MediaType do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
describe "matching a requested type" do
|
65
|
-
it {
|
66
|
-
it {
|
67
|
-
it {
|
68
|
-
it {
|
69
|
-
it {
|
70
|
-
it {
|
71
|
-
it {
|
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
72
|
|
73
|
-
it {
|
74
|
-
it {
|
75
|
-
it {
|
76
|
-
it {
|
77
|
-
it {
|
78
|
-
it {
|
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
79
|
|
80
|
-
it {
|
81
|
-
it {
|
82
|
-
it {
|
83
|
-
it {
|
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
84
|
end
|
85
85
|
end
|
@@ -11,47 +11,47 @@ describe Webmachine::Request do
|
|
11
11
|
|
12
12
|
it "should provide access to the headers via brackets" do
|
13
13
|
subject.headers['Accept'] = "*/*"
|
14
|
-
subject["accept"].
|
14
|
+
expect(subject["accept"]).to eq("*/*")
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should provide access to the cookies" do
|
18
18
|
subject.headers['Cookie'] = 'name=value;name2=value2';
|
19
|
-
subject.cookies.
|
19
|
+
expect(subject.cookies).to eq({ 'name' => 'value', 'name2' => 'value2' })
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should handle cookies with extra whitespace" do
|
23
23
|
subject.headers['Cookie'] = 'name = value; name2 = value2';
|
24
|
-
subject.cookies.
|
24
|
+
expect(subject.cookies).to eq({ 'name' => 'value', 'name2' => 'value2' })
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should provide access to the headers via underscored methods" do
|
28
28
|
subject.headers["Accept-Encoding"] = "identity"
|
29
|
-
subject.accept_encoding.
|
30
|
-
subject.content_md5.
|
29
|
+
expect(subject.accept_encoding).to eq("identity")
|
30
|
+
expect(subject.content_md5).to be_nil
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should calculate a base URI" do
|
34
|
-
subject.base_uri.
|
34
|
+
expect(subject.base_uri).to eq(URI.parse("http://localhost:8080/"))
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should provide a hash of query parameters" do
|
38
38
|
subject.uri.query = "foo=bar&baz=bam"
|
39
|
-
subject.query.
|
39
|
+
expect(subject.query).to eq({"foo" => "bar", "baz" => "bam"})
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should handle = being encoded as a query value." do
|
43
43
|
subject.uri.query = "foo=bar%3D%3D"
|
44
|
-
subject.query.
|
44
|
+
expect(subject.query).to eq({ "foo" => "bar=="})
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should treat '+' characters in query parameters as spaces" do
|
48
48
|
subject.uri.query = "a%20b=foo+bar&c+d=baz%20quux"
|
49
|
-
subject.query.
|
49
|
+
expect(subject.query).to eq({"a b" => "foo bar", "c d" => "baz quux"})
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should handle a query parameter value of nil" do
|
53
53
|
subject.uri.query = nil
|
54
|
-
subject.query.
|
54
|
+
expect(subject.query).to eq({})
|
55
55
|
end
|
56
56
|
|
57
57
|
describe '#has_body?' do
|
@@ -67,31 +67,31 @@ describe Webmachine::Request do
|
|
67
67
|
context "when body is nil" do
|
68
68
|
let(:body) { nil }
|
69
69
|
|
70
|
-
it {
|
70
|
+
it { is_expected.to be(false) }
|
71
71
|
end
|
72
72
|
|
73
73
|
context "when body is an empty string" do
|
74
74
|
let(:body) { '' }
|
75
75
|
|
76
|
-
it {
|
76
|
+
it { is_expected.to be(false) }
|
77
77
|
end
|
78
78
|
|
79
79
|
context "when body is not empty" do
|
80
80
|
let(:body) { 'foo' }
|
81
81
|
|
82
|
-
it {
|
82
|
+
it { is_expected.to be(true) }
|
83
83
|
end
|
84
84
|
|
85
85
|
context "when body is an empty LazyRequestBody" do
|
86
86
|
let(:body) { Webmachine::Adapters::LazyRequestBody.new(wreq.new('')) }
|
87
87
|
|
88
|
-
it {
|
88
|
+
it { is_expected.to be(false) }
|
89
89
|
end
|
90
90
|
|
91
91
|
context "when body is a LazyRequestBody" do
|
92
92
|
let(:body) { Webmachine::Adapters::LazyRequestBody.new(wreq.new('foo')) }
|
93
93
|
|
94
|
-
it {
|
94
|
+
it { is_expected.to be(true) }
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -101,13 +101,13 @@ describe Webmachine::Request do
|
|
101
101
|
context "when the request was issued via HTTPS" do
|
102
102
|
let(:uri) { URI.parse("https://localhost.com:8080/some/resource") }
|
103
103
|
|
104
|
-
it {
|
104
|
+
it { is_expected.to be(true) }
|
105
105
|
end
|
106
106
|
|
107
107
|
context "when the request was not issued via HTTPS" do
|
108
108
|
let(:uri) { URI.parse("http://localhost.com:8080/some/resource") }
|
109
109
|
|
110
|
-
it {
|
110
|
+
it { is_expected.to be(false) }
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -117,13 +117,13 @@ describe Webmachine::Request do
|
|
117
117
|
context "when the request method is GET" do
|
118
118
|
let(:http_method) { "GET" }
|
119
119
|
|
120
|
-
it {
|
120
|
+
it { is_expected.to be(true) }
|
121
121
|
end
|
122
122
|
|
123
123
|
context "when the request method is not GET" do
|
124
124
|
let(:http_method) { "POST" }
|
125
125
|
|
126
|
-
it {
|
126
|
+
it { is_expected.to be(false) }
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
@@ -133,13 +133,13 @@ describe Webmachine::Request do
|
|
133
133
|
context "when the request method is HEAD" do
|
134
134
|
let(:http_method) { "HEAD" }
|
135
135
|
|
136
|
-
it {
|
136
|
+
it { is_expected.to be(true) }
|
137
137
|
end
|
138
138
|
|
139
139
|
context "when the request method is not HEAD" do
|
140
140
|
let(:http_method) { "GET" }
|
141
141
|
|
142
|
-
it {
|
142
|
+
it { is_expected.to be(false) }
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
@@ -149,13 +149,13 @@ describe Webmachine::Request do
|
|
149
149
|
context "when the request method is POST" do
|
150
150
|
let(:http_method) { "POST" }
|
151
151
|
|
152
|
-
it {
|
152
|
+
it { is_expected.to be(true) }
|
153
153
|
end
|
154
154
|
|
155
155
|
context "when the request method is not POST" do
|
156
156
|
let(:http_method) { "GET" }
|
157
157
|
|
158
|
-
it {
|
158
|
+
it { is_expected.to be(false) }
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
@@ -165,13 +165,13 @@ describe Webmachine::Request do
|
|
165
165
|
context "when the request method is PUT" do
|
166
166
|
let(:http_method) { "PUT" }
|
167
167
|
|
168
|
-
it {
|
168
|
+
it { is_expected.to be(true) }
|
169
169
|
end
|
170
170
|
|
171
171
|
context "when the request method is not PUT" do
|
172
172
|
let(:http_method) { "GET" }
|
173
173
|
|
174
|
-
it {
|
174
|
+
it { is_expected.to be(false) }
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
@@ -181,13 +181,13 @@ describe Webmachine::Request do
|
|
181
181
|
context "when the request method is DELETE" do
|
182
182
|
let(:http_method) { "DELETE" }
|
183
183
|
|
184
|
-
it {
|
184
|
+
it { is_expected.to be(true) }
|
185
185
|
end
|
186
186
|
|
187
187
|
context "when the request method is not DELETE" do
|
188
188
|
let(:http_method) { "GET" }
|
189
189
|
|
190
|
-
it {
|
190
|
+
it { is_expected.to be(false) }
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
@@ -197,13 +197,13 @@ describe Webmachine::Request do
|
|
197
197
|
context "when the request method is TRACE" do
|
198
198
|
let(:http_method) { "TRACE" }
|
199
199
|
|
200
|
-
it {
|
200
|
+
it { is_expected.to be(true) }
|
201
201
|
end
|
202
202
|
|
203
203
|
context "when the request method is not TRACE" do
|
204
204
|
let(:http_method) { "GET" }
|
205
205
|
|
206
|
-
it {
|
206
|
+
it { is_expected.to be(false) }
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
@@ -213,13 +213,13 @@ describe Webmachine::Request do
|
|
213
213
|
context "when the request method is CONNECT" do
|
214
214
|
let(:http_method) { "CONNECT" }
|
215
215
|
|
216
|
-
it {
|
216
|
+
it { is_expected.to be(true) }
|
217
217
|
end
|
218
218
|
|
219
219
|
context "when the request method is not CONNECT" do
|
220
220
|
let(:http_method) { "GET" }
|
221
221
|
|
222
|
-
it {
|
222
|
+
it { is_expected.to be(false) }
|
223
223
|
end
|
224
224
|
end
|
225
225
|
|
@@ -229,13 +229,13 @@ describe Webmachine::Request do
|
|
229
229
|
context "when the request method is OPTIONS" do
|
230
230
|
let(:http_method) { "OPTIONS" }
|
231
231
|
|
232
|
-
it {
|
232
|
+
it { is_expected.to be(true) }
|
233
233
|
end
|
234
234
|
|
235
235
|
context "when the request method is not OPTIONS" do
|
236
236
|
let(:http_method) { "GET" }
|
237
237
|
|
238
|
-
it {
|
238
|
+
it { is_expected.to be(false) }
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|