ur 0.0.2 → 0.2.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 +4 -4
- data/CHANGELOG.md +17 -0
- data/LICENSE.md +169 -0
- data/README.md +17 -3
- data/Rakefile.rb +0 -1
- data/lib/ur.rb +46 -72
- data/lib/ur/content_type.rb +245 -0
- data/lib/ur/faraday.rb +3 -1
- data/lib/ur/faraday/yield_ur.rb +8 -14
- data/lib/ur/{processing.rb → metadata.rb} +9 -4
- data/lib/ur/middleware.rb +18 -5
- data/lib/ur/request.rb +4 -2
- data/lib/ur/request_and_response.rb +27 -8
- data/lib/ur/response.rb +4 -2
- data/lib/ur/sub_ur.rb +4 -2
- data/lib/ur/version.rb +1 -1
- data/resources/icons/LGPL-3.0.png +0 -0
- data/resources/ur.schema.yml +50 -0
- data/test/content_type_test.rb +342 -0
- data/test/test_helper.rb +11 -0
- data/test/ur_faraday_test.rb +8 -8
- data/test/ur_metadata_test.rb +11 -0
- data/test/ur_rack_test.rb +0 -4
- data/test/ur_test.rb +14 -14
- data/ur.gemspec +7 -17
- metadata +24 -35
- data/LICENSE.txt +0 -21
- data/lib/ur/content_type_attrs.rb +0 -83
- data/test/ur_processing_test.rb +0 -11
data/lib/ur/faraday.rb
CHANGED
data/lib/ur/faraday/yield_ur.rb
CHANGED
@@ -1,18 +1,12 @@
|
|
1
|
-
|
2
|
-
module Faraday
|
3
|
-
class YieldUr < ::Faraday::Middleware
|
4
|
-
def initialize(app, options = {}, &block)
|
5
|
-
@app = app
|
6
|
-
@options = options
|
7
|
-
@yield_to = block
|
8
|
-
end
|
1
|
+
# frozen_string_literal: true
|
9
2
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
module Ur
|
4
|
+
module Faraday
|
5
|
+
# Faraday middleware which yields an Ur to the given block
|
6
|
+
class YieldUr < ::Ur::FaradayMiddleware
|
7
|
+
def initialize(app, **options, &block)
|
8
|
+
raise(ArgumentError, "no block given to yield ur") unless block
|
9
|
+
super(app, options.merge(after_response: block))
|
16
10
|
end
|
17
11
|
end
|
18
12
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ur' unless Object.const_defined?(:Ur)
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
module Ur
|
6
|
+
module Metadata
|
5
7
|
include SubUr
|
6
8
|
|
7
9
|
def began_at
|
@@ -13,10 +15,13 @@ class Ur
|
|
13
15
|
|
14
16
|
attr_accessor :began_at_ns
|
15
17
|
|
18
|
+
# sets began_at from the current time
|
16
19
|
def begin!
|
17
|
-
self.began_at
|
18
|
-
self.began_at_ns
|
20
|
+
self.began_at = Time.now
|
21
|
+
self.began_at_ns = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
19
22
|
end
|
23
|
+
|
24
|
+
# sets the duration from the current time and began_at
|
20
25
|
def finish!
|
21
26
|
return if duration
|
22
27
|
if began_at_ns
|
data/lib/ur/middleware.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ur' unless Object.const_defined?(:Ur)
|
2
4
|
|
3
|
-
|
5
|
+
module Ur
|
4
6
|
module Middleware
|
5
7
|
def initialize(app, options = {})
|
6
8
|
@app = app
|
@@ -9,6 +11,15 @@ class Ur
|
|
9
11
|
attr_reader :app
|
10
12
|
attr_reader :options
|
11
13
|
|
14
|
+
def begin_request(ur)
|
15
|
+
ur.metadata.begin!
|
16
|
+
end
|
17
|
+
|
18
|
+
def finish_request(ur)
|
19
|
+
ur.logger_tags(@options[:logger])
|
20
|
+
ur.metadata.finish!
|
21
|
+
end
|
22
|
+
|
12
23
|
def invoke_callback(name, *a, &b)
|
13
24
|
if @options[name]
|
14
25
|
@options[name].call(*a, &b)
|
@@ -19,10 +30,11 @@ class Ur
|
|
19
30
|
class FaradayMiddleware < ::Faraday::Middleware
|
20
31
|
include Ur::Middleware
|
21
32
|
def call(request_env)
|
22
|
-
ur = Ur.from_faraday_request(request_env)
|
33
|
+
ur = Ur.from_faraday_request(request_env, @options.select { |k, _| [:schemas].include?(k) })
|
23
34
|
invoke_callback(:before_request, ur)
|
24
|
-
ur
|
35
|
+
begin_request(ur)
|
25
36
|
ur.faraday_on_complete(@app, request_env) do |response_env|
|
37
|
+
finish_request(ur)
|
26
38
|
invoke_callback(:after_response, ur)
|
27
39
|
end
|
28
40
|
end
|
@@ -31,10 +43,11 @@ class Ur
|
|
31
43
|
class RackMiddleware
|
32
44
|
include Ur::Middleware
|
33
45
|
def call(env)
|
34
|
-
ur = Ur.from_rack_request(env)
|
46
|
+
ur = Ur.from_rack_request(env, @options.select { |k, _| [:schemas].include?(k) })
|
35
47
|
invoke_callback(:before_request, ur)
|
36
|
-
ur
|
48
|
+
begin_request(ur)
|
37
49
|
ur.with_rack_response(@app, env) do
|
50
|
+
finish_request(ur)
|
38
51
|
invoke_callback(:after_response, ur)
|
39
52
|
end
|
40
53
|
end
|
data/lib/ur/request.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ur' unless Object.const_defined?(:Ur)
|
2
4
|
|
3
|
-
|
5
|
+
module Ur
|
6
|
+
# functionality common to Request and Response
|
4
7
|
module RequestAndResponse
|
8
|
+
# functionality for handling request/response entities from Faraday
|
5
9
|
module FaradayEntity
|
10
|
+
# @param env [Faraday::Env] faraday env passed to middleware #call
|
6
11
|
def set_body_from_faraday(env)
|
7
12
|
if env[:raw_body].respond_to?(:to_str)
|
8
13
|
self.body = env[:raw_body].to_str.dup
|
@@ -20,20 +25,34 @@ class Ur
|
|
20
25
|
end
|
21
26
|
include FaradayEntity
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
+
# @return [Ur::ContentType] the string value of the content type header. returns an
|
29
|
+
# {Ur::ContentType}, a subclass of String which additionally parses the Content-Type
|
30
|
+
# according to relevant RFCs.
|
28
31
|
def content_type
|
29
32
|
headers.each do |k, v|
|
30
|
-
return v if k =~ /\Acontent[-_]type\z/i
|
33
|
+
return ContentType.new(v) if k =~ /\Acontent[-_]type\z/i
|
31
34
|
end
|
32
35
|
nil
|
33
36
|
end
|
34
37
|
|
38
|
+
# the media type of the content type
|
35
39
|
def media_type
|
36
|
-
|
40
|
+
content_type ? content_type.media_type : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Boolean] is our content type JSON?
|
44
|
+
def json?
|
45
|
+
content_type && content_type.json?
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Boolean] is our content type XML?
|
49
|
+
def xml?
|
50
|
+
content_type && content_type.xml?
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Boolean] is our content type x-www-form-urlencoded?
|
54
|
+
def form_urlencoded?
|
55
|
+
content_type && content_type.form_urlencoded?
|
37
56
|
end
|
38
57
|
end
|
39
58
|
end
|
data/lib/ur/response.rb
CHANGED
data/lib/ur/sub_ur.rb
CHANGED
data/lib/ur/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
UR_VERSION = "0.0.
|
1
|
+
UR_VERSION = "0.2.0".freeze
|
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
$id: https://schemas.ur.unth.net/ur
|
2
|
+
type: object
|
3
|
+
properties:
|
4
|
+
bound:
|
5
|
+
type: string
|
6
|
+
description: '[RFC7230] The terms "inbound" and "outbound" are used to describe directional requirements in relation to the request route: "inbound" means toward the origin server and "outbound" means toward the user agent.'
|
7
|
+
enum:
|
8
|
+
- inbound
|
9
|
+
- outbound
|
10
|
+
request:
|
11
|
+
type: object
|
12
|
+
properties:
|
13
|
+
method:
|
14
|
+
type: string
|
15
|
+
description: '[RFC7230] The method token indicates the request method to be performed on the target resource.'
|
16
|
+
example: POST
|
17
|
+
uri:
|
18
|
+
type: string
|
19
|
+
format: uri
|
20
|
+
example: https://example.com/foo?bar=baz
|
21
|
+
headers:
|
22
|
+
type: object
|
23
|
+
body:
|
24
|
+
type: string
|
25
|
+
response:
|
26
|
+
type: object
|
27
|
+
properties:
|
28
|
+
status:
|
29
|
+
type: integer
|
30
|
+
description: >
|
31
|
+
The status-code element is a 3-digit integer code describing the
|
32
|
+
result of the server's attempt to understand and satisfy the client's
|
33
|
+
corresponding request.
|
34
|
+
example: 200
|
35
|
+
headers:
|
36
|
+
type: object
|
37
|
+
body:
|
38
|
+
type: string
|
39
|
+
metadata:
|
40
|
+
type: object
|
41
|
+
properties:
|
42
|
+
began_at_s:
|
43
|
+
type: string
|
44
|
+
format: date-time
|
45
|
+
duration:
|
46
|
+
type: number
|
47
|
+
tags:
|
48
|
+
type: array
|
49
|
+
items:
|
50
|
+
type: string
|
@@ -0,0 +1,342 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe 'Ur::ContentType' do
|
4
|
+
let(:content_type) { Ur::ContentType.new(content_type_str) }
|
5
|
+
describe 'application/vnd.github+json; charset="utf-8"' do
|
6
|
+
let(:content_type_str) { 'application/vnd.github+json; charset="utf-8"' }
|
7
|
+
it 'parses' do
|
8
|
+
assert_equal(content_type, content_type_str)
|
9
|
+
|
10
|
+
assert_equal('application/vnd.github+json', content_type.media_type)
|
11
|
+
|
12
|
+
assert_equal('application', content_type.type)
|
13
|
+
assert(content_type.type?('Application'))
|
14
|
+
assert(content_type.type_application?)
|
15
|
+
|
16
|
+
assert_equal('vnd.github+json', content_type.subtype)
|
17
|
+
assert_equal('vnd', content_type.facet)
|
18
|
+
assert_equal('json', content_type.suffix)
|
19
|
+
|
20
|
+
assert_equal({'charset' => 'utf-8'}, content_type.parameters)
|
21
|
+
assert_equal('utf-8', content_type.parameters['CharSet'])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
describe 'no subtype' do
|
25
|
+
let(:content_type_str) { 'application; charset="utf-8"' }
|
26
|
+
it 'will allow it' do
|
27
|
+
assert_equal(content_type, content_type_str)
|
28
|
+
|
29
|
+
assert_equal('application', content_type.media_type)
|
30
|
+
|
31
|
+
assert_equal('application', content_type.type)
|
32
|
+
assert(content_type.type?('Application'))
|
33
|
+
|
34
|
+
assert_equal(nil, content_type.subtype)
|
35
|
+
assert_equal(nil, content_type.facet)
|
36
|
+
assert_equal(nil, content_type.suffix)
|
37
|
+
|
38
|
+
assert_equal({'charset' => 'utf-8'}, content_type.parameters)
|
39
|
+
assert_equal('utf-8', content_type.parameters['CharSet'])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
describe 'no facet' do
|
43
|
+
let(:content_type_str) { 'application/github+json; charset="utf-8"' }
|
44
|
+
it 'parses' do
|
45
|
+
assert_equal(content_type, content_type_str)
|
46
|
+
|
47
|
+
assert_equal('application/github+json', content_type.media_type)
|
48
|
+
|
49
|
+
assert_equal('application', content_type.type)
|
50
|
+
assert(content_type.type?('Application'))
|
51
|
+
|
52
|
+
assert_equal('github+json', content_type.subtype)
|
53
|
+
assert_equal(nil, content_type.facet)
|
54
|
+
assert_equal('json', content_type.suffix)
|
55
|
+
|
56
|
+
assert_equal({'charset' => 'utf-8'}, content_type.parameters)
|
57
|
+
assert_equal('utf-8', content_type.parameters['CharSet'])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
describe 'no suffix' do
|
61
|
+
let(:content_type_str) { 'application/vnd.github.json; charset="utf-8"' }
|
62
|
+
it 'parses' do
|
63
|
+
assert_equal(content_type, content_type_str)
|
64
|
+
|
65
|
+
assert_equal('application/vnd.github.json', content_type.media_type)
|
66
|
+
|
67
|
+
assert_equal('application', content_type.type)
|
68
|
+
assert(content_type.type?('Application'))
|
69
|
+
|
70
|
+
assert_equal('vnd.github.json', content_type.subtype)
|
71
|
+
assert_equal('vnd', content_type.facet)
|
72
|
+
assert_equal(nil, content_type.suffix)
|
73
|
+
|
74
|
+
assert_equal({'charset' => 'utf-8'}, content_type.parameters)
|
75
|
+
assert_equal('utf-8', content_type.parameters['CharSet'])
|
76
|
+
end
|
77
|
+
describe('[invalid] quote in type') do
|
78
|
+
let(:content_type_str) { 'applic"ation/foo; foo=bar' }
|
79
|
+
it('gives up') do
|
80
|
+
assert_equal('applic', content_type.type)
|
81
|
+
assert_equal(nil, content_type.subtype)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
describe('[invalid] backslash in type') do
|
85
|
+
let(:content_type_str) { 'applicati\on/foo; foo=bar' }
|
86
|
+
it('parses') do
|
87
|
+
assert_equal('applicati\\on', content_type.type)
|
88
|
+
assert_equal('foo', content_type.subtype)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
describe('[invalid] quote in subtype') do
|
92
|
+
let(:content_type_str) { 'application/f"oo; foo=bar' }
|
93
|
+
it('gives up') do
|
94
|
+
assert_equal('application', content_type.type)
|
95
|
+
assert_equal('f', content_type.subtype)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
describe('[invalid] backslash in subtype') do
|
99
|
+
let(:content_type_str) { 'application/fo\\o; foo=bar' }
|
100
|
+
it('parses') do
|
101
|
+
assert_equal('application', content_type.type)
|
102
|
+
assert_equal('fo\\o', content_type.subtype)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
describe 'parameters' do
|
107
|
+
describe 'basic usage' do
|
108
|
+
let(:content_type_str) { 'application/foo; charset="utf-8"; foo=bar' }
|
109
|
+
it('parses') do
|
110
|
+
assert_equal({'charset' => 'utf-8', 'foo' => 'bar'}, content_type.parameters)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
describe 'params with capitalization' do
|
114
|
+
let(:content_type_str) { 'application/foo; Charset="utf-8"; FOO=bar' }
|
115
|
+
it('parses') do
|
116
|
+
assert_equal({'charset' => 'utf-8', 'foo' => 'bar'}, content_type.parameters)
|
117
|
+
assert_equal('utf-8', content_type.parameters['CharSet'])
|
118
|
+
assert_equal('utf-8', content_type.parameters['Charset'])
|
119
|
+
assert_equal('bar', content_type.parameters['foo'])
|
120
|
+
assert_equal('bar', content_type.parameters['FOO'])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
describe 'repeated params' do
|
124
|
+
let(:content_type_str) { 'application/foo; foo="first"; foo=second' }
|
125
|
+
it('will just overwrite') do
|
126
|
+
assert_equal({'foo' => 'second'}, content_type.parameters)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
describe 'repeated params, different capitalization' do
|
130
|
+
let(:content_type_str) { 'application/foo; FOO=first; Foo=second' }
|
131
|
+
it('will just overwrite') do
|
132
|
+
assert_equal({'foo' => 'second'}, content_type.parameters)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
describe 'empty strings' do
|
136
|
+
let(:content_type_str) { 'application/foo; empty1=; empty2=""' }
|
137
|
+
it('parses') do
|
138
|
+
assert_equal({'empty1' => '', 'empty2' => ''}, content_type.parameters)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
describe 'empty strings with whitespace' do
|
142
|
+
let(:content_type_str) { 'application/foo; empty1= ; empty2="" ' }
|
143
|
+
it('parses') do
|
144
|
+
assert_equal({'empty1' => '', 'empty2' => ''}, content_type.parameters)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
describe('[invalid] opening quote only') do
|
148
|
+
let(:content_type_str) { 'application/foo; foo=1; bar="' }
|
149
|
+
it('parses') do
|
150
|
+
assert_equal({'foo' => '1', 'bar' => ''}, content_type.parameters)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
describe('[invalid] backlash with no character') do
|
154
|
+
let(:content_type_str) { 'application/foo; foo=1; bar="\\' }
|
155
|
+
it('parses') do
|
156
|
+
assert_equal({'foo' => '1', 'bar' => ''}, content_type.parameters)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
describe('[invalid] extra following quoted string') do
|
160
|
+
let(:content_type_str) { 'application/foo; foo="1" 2; bar=3' }
|
161
|
+
it('sorta parses') do
|
162
|
+
assert_equal({'foo' => '1 2', 'bar' => '3'}, content_type.parameters)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
describe('[invalid] quotes silliness') do
|
166
|
+
let(:content_type_str) { 'application/foo; foo="1" 2 "3 4" "5 " ; bar=3' }
|
167
|
+
it('sorta parses') do
|
168
|
+
assert_equal({'foo' => '1 2 3 4 5 ', 'bar' => '3'}, content_type.parameters)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
describe('[invalid] backlash quote') do
|
172
|
+
let(:content_type_str) { 'application/foo; foo=1; bar="\\"' }
|
173
|
+
it('parses') do
|
174
|
+
assert_equal({'foo' => '1', 'bar' => '"'}, content_type.parameters)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
describe('[invalid] trailing ;') do
|
178
|
+
let(:content_type_str) { 'application/foo; foo=bar;' }
|
179
|
+
it('parses') do
|
180
|
+
assert_equal({'foo' => 'bar'}, content_type.parameters)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
describe('[invalid] extra ; inline') do
|
184
|
+
let(:content_type_str) { 'application/foo; ; ; foo=bar' }
|
185
|
+
it('parses') do
|
186
|
+
assert_equal({'foo' => 'bar'}, content_type.parameters)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
describe('[invalid] whitespace around the =') do
|
190
|
+
let(:content_type_str) { 'application/foo; foo = bar; baz = qux' }
|
191
|
+
it('parses') do
|
192
|
+
assert_equal({'foo ' => ' bar', 'baz ' => ' qux'}, content_type.parameters)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
describe('whitespace before the ;') do
|
196
|
+
let(:content_type_str) { 'application/foo; foo=bar ; baz=qux' }
|
197
|
+
it('parses') do
|
198
|
+
assert_equal({'foo' => 'bar', 'baz' => 'qux'}, content_type.parameters)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
describe('no media_type') do
|
202
|
+
let(:content_type_str) { '; foo=bar' }
|
203
|
+
it('parses') do
|
204
|
+
assert_equal({'foo' => 'bar'}, content_type.parameters)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
describe('[invalid] quote in parameter name') do
|
208
|
+
let(:content_type_str) { 'application/foo; fo"o=bar' }
|
209
|
+
it('gives up') do
|
210
|
+
assert_equal({}, content_type.parameters)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
describe('[invalid] backslash in parameter name') do
|
214
|
+
let(:content_type_str) { 'application/foo; fo\\o=bar' }
|
215
|
+
it('parses') do
|
216
|
+
assert_equal({'fo\\o' => 'bar'}, content_type.parameters)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
describe 'binary?' do
|
221
|
+
binary_content_type_strs = [
|
222
|
+
'audio/ogg',
|
223
|
+
'Audio/OGG; foo=bar',
|
224
|
+
'VIDEO/foo+bar',
|
225
|
+
]
|
226
|
+
binary_content_type_strs.each do |binary_content_type_str|
|
227
|
+
describe(binary_content_type_str) do
|
228
|
+
let(:content_type_str) { binary_content_type_str }
|
229
|
+
it 'is binary' do
|
230
|
+
assert(content_type.binary?(unknown: false))
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
not_binary_content_type_strs = [
|
235
|
+
'text/anything',
|
236
|
+
'TEXT/plain; charset=foo',
|
237
|
+
'application/JSON',
|
238
|
+
'media/foo+Json; foo="bar"',
|
239
|
+
]
|
240
|
+
not_binary_content_type_strs.each do |not_binary_content_type_str|
|
241
|
+
describe(not_binary_content_type_str) do
|
242
|
+
let(:content_type_str) { not_binary_content_type_str }
|
243
|
+
it 'is not binary' do
|
244
|
+
assert(!content_type.binary?(unknown: true))
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
unknown_content_type_strs = [
|
249
|
+
'foo',
|
250
|
+
'foo/bar; note="not application/json"',
|
251
|
+
'application/jsonisnotthis',
|
252
|
+
'application/octet-stream',
|
253
|
+
]
|
254
|
+
unknown_content_type_strs.each do |unknown_content_type_str|
|
255
|
+
describe(unknown_content_type_str) do
|
256
|
+
let(:content_type_str) { unknown_content_type_str }
|
257
|
+
it 'is unknown' do
|
258
|
+
assert(content_type.binary?(unknown: true))
|
259
|
+
assert(!content_type.binary?(unknown: false))
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
describe 'json?' do
|
265
|
+
json_content_type_strs = [
|
266
|
+
'application/json',
|
267
|
+
'Application/Json; charset=EBCDIC',
|
268
|
+
'Text/json',
|
269
|
+
'MEDIA/JSON',
|
270
|
+
'media/foo.bar+json',
|
271
|
+
'media/foo.bar+json; foo=',
|
272
|
+
]
|
273
|
+
json_content_type_strs.each do |json_content_type_str|
|
274
|
+
describe(json_content_type_str) do
|
275
|
+
let(:content_type_str) { json_content_type_str }
|
276
|
+
it 'is json' do
|
277
|
+
assert(content_type.json?)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
not_json_content_type_strs = [
|
282
|
+
'json',
|
283
|
+
'foo/bar; note="not application/json"',
|
284
|
+
'application/jsonisnotthis',
|
285
|
+
'text/json+xml', # I don't even know what I'm trying for here
|
286
|
+
]
|
287
|
+
not_json_content_type_strs.each do |not_json_content_type_str|
|
288
|
+
describe(not_json_content_type_str) do
|
289
|
+
let(:content_type_str) { not_json_content_type_str }
|
290
|
+
it 'is not json' do
|
291
|
+
assert(!content_type.json?)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
describe 'xml?' do
|
297
|
+
xml_content_type_strs = [
|
298
|
+
'application/xml',
|
299
|
+
'Application/Xml; charset=EBCDIC',
|
300
|
+
'Text/xml',
|
301
|
+
'MEDIA/XML',
|
302
|
+
'media/foo.bar+xml',
|
303
|
+
'media/foo.bar+xml; foo=',
|
304
|
+
]
|
305
|
+
xml_content_type_strs.each do |xml_content_type_str|
|
306
|
+
describe(xml_content_type_str) do
|
307
|
+
let(:content_type_str) { xml_content_type_str }
|
308
|
+
it 'is xml' do
|
309
|
+
assert(content_type.xml?)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
not_xml_content_type_strs = [
|
314
|
+
'xml',
|
315
|
+
'foo/bar; note="not application/xml"',
|
316
|
+
'application/xmlisnotthis',
|
317
|
+
'text/xml+json', # I don't even know what I'm trying for here
|
318
|
+
]
|
319
|
+
not_xml_content_type_strs.each do |not_xml_content_type_str|
|
320
|
+
describe(not_xml_content_type_str) do
|
321
|
+
let(:content_type_str) { not_xml_content_type_str }
|
322
|
+
it 'is not xml' do
|
323
|
+
assert(!content_type.xml?)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
describe 'form_urlencoded?' do
|
329
|
+
describe('application/x-www-form-urlencoded') do
|
330
|
+
let(:content_type_str) { 'application/x-www-form-urlencoded' }
|
331
|
+
it 'is form_urlencoded' do
|
332
|
+
assert(content_type.form_urlencoded?)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
describe('application/foo') do
|
336
|
+
let(:content_type_str) { 'application/foo' }
|
337
|
+
it 'is not form_urlencoded' do
|
338
|
+
assert(!content_type.form_urlencoded?)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|