ur 0.0.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|