ur 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08e517b90ad97d890764bc228d8836e7e48d7f8250ed7c3a4878368b77b2deb2'
4
- data.tar.gz: e87aedb3a622a5606bff0370cc1a06f43d98be53488389c1902e989226760cd1
3
+ metadata.gz: 1161e5f2e2219053fc4c54e541feb0d4c6efa1c1af930365e526a88bc0973e1b
4
+ data.tar.gz: b42e166ae62f0a651d5425147e64b1d200c09862869188b8f95e52454f7b8e97
5
5
  SHA512:
6
- metadata.gz: '069f50e6768b41beb13830308fd3a3d18845c32fc38f6e95755b8f929ba88e20efcfce8f84abf50ed393a93f9c2971bb7b280e5793d43098c06dc034f136487c'
7
- data.tar.gz: 42c005bf4853f4bb946a2bd143696c84fa84c6f933b71a6425505722aab150f290ab21265ac2b6e9fdaa313e0207becb46f5a14ff20a7cd2c18e4daa53d12084
6
+ metadata.gz: 17187f65ff16035e72fc7d7e0b9468bd970d337b1f8173fbc2dde15f420ad406aa33ecb440b4b65e0dffb921279660fdedb48b4bb320ce3e4e9a411eec3a21da
7
+ data.tar.gz: 8c8d0f0c86af8a97c18dc794e69b84634421607a7e6715120b90fd3d9f74bdd1848a5c422598dbc06fdb0ea7ce4ac474e76b761ec7e2243fdb87b2aa812af292
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v0.2.1
2
+
3
+ - JSI v0.6.0
4
+
1
5
  # v0.2.0
2
6
 
3
7
  - Ur uses JSI schema modules instead of classes
@@ -21,12 +21,15 @@ module Ur
21
21
  # https://tools.ietf.org/html/rfc2045#section-5.1
22
22
  # - Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
23
23
  # https://tools.ietf.org/html/rfc2046
24
+ # - Additional Media Type Structured Syntax Suffixes
25
+ # https://tools.ietf.org/html/rfc6839
24
26
  class ContentType < String
25
27
  # the character ranges in this SHOULD be significantly more restrictive,
26
- # and the /<subtype> construct should not be optional. however, we'll aim
28
+ # and the `/<subtype>` construct should not be optional. however, we'll aim
27
29
  # to match whatever media type we are given.
28
30
  #
29
31
  # example:
32
+ #
30
33
  # MEDIA_TYPE_REGEXP.match('application/vnd.github+json').named_captures
31
34
  # =>
32
35
  # {
@@ -38,6 +41,7 @@ module Ur
38
41
  # }
39
42
  #
40
43
  # example of being more permissive than the spec allows:
44
+ #
41
45
  # MEDIA_TYPE_REGEXP.match('where the %$*! am I').named_captures
42
46
  # =>
43
47
  # {
@@ -116,44 +120,53 @@ module Ur
116
120
  freeze
117
121
  end
118
122
 
119
- # @return [String, nil] the media type of this content type.
120
- # e.g. "application/vnd.github+json" in content-type: application/vnd.github+json; charset="utf-8"
123
+ # the media type of this content type.
124
+ # e.g. `"application/vnd.github+json"` in `content-type: application/vnd.github+json; charset="utf-8"`
125
+ # @return [String, nil]
121
126
  attr_reader :media_type
122
127
 
123
- # @return [String, nil] the 'type' portion of our media type.
124
- # e.g. "application" in content-type: application/vnd.github+json; charset="utf-8"
128
+ # the 'type' portion of our media type.
129
+ # e.g. `"application"` in `content-type: application/vnd.github+json; charset="utf-8"`
130
+ # @return [String, nil]
125
131
  attr_reader :type
126
132
 
127
- # @return [String, nil] the 'subtype' portion of our media type.
128
- # e.g. "vnd.github+json" in content-type: application/vnd.github+json; charset="utf-8"
133
+ # the 'subtype' portion of our media type.
134
+ # e.g. `"vnd.github+json"` in `content-type: application/vnd.github+json; charset="utf-8"`
135
+ # @return [String, nil]
129
136
  attr_reader :subtype
130
137
 
131
- # @return [String, nil] the 'facet' portion of our media type.
132
- # e.g. "vnd" in content-type: application/vnd.github+json; charset="utf-8"
138
+ # the 'facet' portion of our media type.
139
+ # e.g. `"vnd"` in `content-type: application/vnd.github+json; charset="utf-8"`
140
+ # @return [String, nil]
133
141
  attr_reader :facet
134
142
 
135
- # @return [String, nil] the 'suffix' portion of our media type.
136
- # e.g. "json" in content-type: application/vnd.github+json; charset="utf-8"
143
+ # the 'suffix' portion of our media type.
144
+ # e.g. `"json"` in `content-type: application/vnd.github+json; charset="utf-8"`
145
+ # @return [String, nil]
137
146
  attr_reader :suffix
138
147
 
139
- # @return [Hash<String, String>] parameters of this content type.
140
- # e.g. {"charset" => "utf-8"} in content-type: application/vnd.github+json; charset="utf-8"
148
+ # parameters of this content type.
149
+ # e.g. `{"charset" => "utf-8"}` in `content-type: application/vnd.github+json; charset="utf-8"`
150
+ # @return [Hash<String, String>]
141
151
  attr_reader :parameters
142
152
 
153
+ # is the 'type' portion of our media type equal (case-insensitive) to the given other_type
143
154
  # @param other_type
144
- # @return [Boolean] is the 'type' portion of our media type equal (case-insensitive) to the given other_type
155
+ # @return [Boolean]
145
156
  def type?(other_type)
146
157
  type && type.casecmp?(other_type)
147
158
  end
148
159
 
160
+ # is the 'subtype' portion of our media type equal (case-insensitive) to the given other_subtype
149
161
  # @param other_subtype
150
- # @return [Boolean] is the 'subtype' portion of our media type equal (case-insensitive) to the given other_subtype
162
+ # @return [Boolean]
151
163
  def subtype?(other_subtype)
152
164
  subtype && subtype.casecmp?(other_subtype)
153
165
  end
154
166
 
167
+ # is the 'suffix' portion of our media type equal (case-insensitive) to the given other_suffix
155
168
  # @param other_suffix
156
- # @return [Boolean] is the 'suffix' portion of our media type equal (case-insensitive) to the given other_suffix
169
+ # @return [Boolean]
157
170
  def suffix?(other_suffix)
158
171
  suffix && suffix.casecmp?(other_suffix)
159
172
  end
@@ -173,11 +186,12 @@ module Ur
173
186
  ecmascript
174
187
  ).map(&:freeze).freeze
175
188
 
189
+ # does this content type appear to be binary?
190
+ # this library makes its best guess based on a very incomplete knowledge
191
+ # of which media types indicate binary or text.
176
192
  # @param unknown [Boolean] return this value when we have no idea whether
177
193
  # our media type is binary or text.
178
- # @return [Boolean] does this content type appear to be binary?
179
- # this library makes its best guess based on a very incomplete knowledge
180
- # of which media types indicate binary or text.
194
+ # @return [Boolean]
181
195
  def binary?(unknown: true)
182
196
  return false if type_text?
183
197
 
@@ -192,52 +206,62 @@ module Ur
192
206
  return unknown
193
207
  end
194
208
 
195
- # @return [Boolean] is this a JSON content type?
209
+ # is this a JSON content type?
210
+ # @return [Boolean]
196
211
  def json?
197
212
  suffix ? suffix.casecmp?('json') : subtype ? subtype.casecmp?('json') : false
198
213
  end
199
214
 
200
- # @return [Boolean] is this an XML content type?
215
+ # is this an XML content type?
216
+ # @return [Boolean]
201
217
  def xml?
202
218
  suffix ? suffix.casecmp?('xml'): subtype ? subtype.casecmp?('xml') : false
203
219
  end
204
220
 
205
- # @return [Boolean] is this a x-www-form-urlencoded content type?
221
+ # is this a `x-www-form-urlencoded` content type?
222
+ # @return [Boolean]
206
223
  def form_urlencoded?
207
224
  suffix ? suffix.casecmp?('x-www-form-urlencoded'): subtype ? subtype.casecmp?('x-www-form-urlencoded') : false
208
225
  end
209
226
 
210
- # @return [Boolean] is the 'type' portion of our media type 'text'
227
+ # is the 'type' portion of our media type 'text'
228
+ # @return [Boolean]
211
229
  def type_text?
212
230
  type && type.casecmp?('text')
213
231
  end
214
232
 
215
- # @return [Boolean] is the 'type' portion of our media type 'image'
233
+ # is the 'type' portion of our media type 'image'
234
+ # @return [Boolean]
216
235
  def type_image?
217
236
  type && type.casecmp?('image')
218
237
  end
219
238
 
220
- # @return [Boolean] is the 'type' portion of our media type 'audio'
239
+ # is the 'type' portion of our media type 'audio'
240
+ # @return [Boolean]
221
241
  def type_audio?
222
242
  type && type.casecmp?('audio')
223
243
  end
224
244
 
225
- # @return [Boolean] is the 'type' portion of our media type 'video'
245
+ # is the 'type' portion of our media type 'video'
246
+ # @return [Boolean]
226
247
  def type_video?
227
248
  type && type.casecmp?('video')
228
249
  end
229
250
 
230
- # @return [Boolean] is the 'type' portion of our media type 'application'
251
+ # is the 'type' portion of our media type 'application'
252
+ # @return [Boolean]
231
253
  def type_application?
232
254
  type && type.casecmp?('application')
233
255
  end
234
256
 
235
- # @return [Boolean] is the 'type' portion of our media type 'message'
257
+ # is the 'type' portion of our media type 'message'
258
+ # @return [Boolean]
236
259
  def type_message?
237
260
  type && type.casecmp?('message')
238
261
  end
239
262
 
240
- # @return [Boolean] is the 'type' portion of our media type 'multipart'
263
+ # is the 'type' portion of our media type 'multipart'
264
+ # @return [Boolean]
241
265
  def type_multipart?
242
266
  type && type.casecmp?('multipart')
243
267
  end
@@ -25,9 +25,10 @@ module Ur
25
25
  end
26
26
  include FaradayEntity
27
27
 
28
- # @return [Ur::ContentType] the string value of the content type header. returns an
28
+ # the string value of the content type header. returns an
29
29
  # {Ur::ContentType}, a subclass of String which additionally parses the Content-Type
30
30
  # according to relevant RFCs.
31
+ # @return [Ur::ContentType]
31
32
  def content_type
32
33
  headers.each do |k, v|
33
34
  return ContentType.new(v) if k =~ /\Acontent[-_]type\z/i
@@ -40,17 +41,20 @@ module Ur
40
41
  content_type ? content_type.media_type : nil
41
42
  end
42
43
 
43
- # @return [Boolean] is our content type JSON?
44
+ # is our content type JSON?
45
+ # @return [Boolean]
44
46
  def json?
45
47
  content_type && content_type.json?
46
48
  end
47
49
 
48
- # @return [Boolean] is our content type XML?
50
+ # is our content type XML?
51
+ # @return [Boolean]
49
52
  def xml?
50
53
  content_type && content_type.xml?
51
54
  end
52
55
 
53
- # @return [Boolean] is our content type x-www-form-urlencoded?
56
+ # is our content type `x-www-form-urlencoded`?
57
+ # @return [Boolean]
54
58
  def form_urlencoded?
55
59
  content_type && content_type.form_urlencoded?
56
60
  end
data/lib/ur/sub_ur.rb CHANGED
@@ -5,7 +5,7 @@ require 'ur' unless Object.const_defined?(:Ur)
5
5
  module Ur
6
6
  module SubUr
7
7
  def ur
8
- parent_jsis.detect { |p| p.is_a?(::Ur) }
8
+ jsi_parent_nodes.detect { |p| p.is_a?(::Ur) }
9
9
  end
10
10
  end
11
11
  end
data/lib/ur/version.rb CHANGED
@@ -1 +1 @@
1
- UR_VERSION = "0.2.0".freeze
1
+ UR_VERSION = "0.2.1".freeze
data/lib/ur.rb CHANGED
@@ -6,9 +6,10 @@ require 'jsi'
6
6
  require 'time'
7
7
  require 'addressable/uri'
8
8
  require 'pathname'
9
+ require 'yaml'
9
10
 
10
11
  UR_ROOT = Pathname.new(__FILE__).dirname.parent.expand_path
11
- Ur = JSI::Schema.new(YAML.load_file(UR_ROOT.join('resources/ur.schema.yml'))).jsi_schema_module
12
+ Ur = JSI.new_schema_module(YAML.load_file(UR_ROOT.join('resources/ur.schema.yml')))
12
13
  module Ur
13
14
  VERSION = UR_VERSION
14
15
 
@@ -19,9 +20,9 @@ module Ur
19
20
  autoload :RackMiddleware, 'ur/middleware'
20
21
  autoload :Faraday, 'ur/faraday'
21
22
 
22
- Request = self.schema.properties['request'].jsi_schema_module
23
- Response = self.schema.properties['response'].jsi_schema_module
24
- Metadata = self.schema.properties['metadata'].jsi_schema_module
23
+ Request = self.properties['request']
24
+ Response = self.properties['response']
25
+ Metadata = self.properties['metadata']
25
26
  require 'ur/request'
26
27
  require 'ur/response'
27
28
  require 'ur/metadata'
@@ -34,8 +35,7 @@ module Ur
34
35
  raise(TypeError, "expected hash for ur instance. got: #{instance.pretty_inspect.chomp}")
35
36
  end
36
37
 
37
- ur_class = JSI.class_for_schemas(Set[schema] + schemas)
38
- ur_class.new(instance, options).tap do |ur|
38
+ JSI::SchemaSet[schema, *schemas].new_jsi(instance, **options).tap do |ur|
39
39
  ur.request = {} if ur.request.nil?
40
40
  ur.response = {} if ur.response.nil?
41
41
  ur.metadata = {} if ur.metadata.nil?
@@ -1,3 +1,4 @@
1
+ $schema: http://json-schema.org/draft-07/schema
1
2
  $id: https://schemas.ur.unth.net/ur
2
3
  type: object
3
4
  properties:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ur
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-06 00:00:00.000000000 Z
11
+ date: 2022-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsi
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
19
+ version: 0.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.4'
26
+ version: 0.6.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,148 +38,19 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rack
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rack-test
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: faraday
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: faraday_middleware
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: activesupport
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rake
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: minitest
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: minitest-reporters
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: simplecov
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
41
  description: ur provides a unified representation of a request and response. it can
168
42
  be interpreted from rack, faraday, or potentially other sources, and provides a
169
43
  consistent interface to access the attributes inherent to the request and additional
170
44
  useful parsers and computation from the request.
171
45
  email:
172
- - ethan@unth
46
+ - ethan.ur@unth.net
173
47
  executables: []
174
48
  extensions: []
175
49
  extra_rdoc_files: []
176
50
  files:
177
- - ".simplecov"
178
- - ".yardopts"
179
51
  - CHANGELOG.md
180
52
  - LICENSE.md
181
53
  - README.md
182
- - Rakefile.rb
183
54
  - lib/ur.rb
184
55
  - lib/ur/content_type.rb
185
56
  - lib/ur/faraday.rb
@@ -191,15 +62,7 @@ files:
191
62
  - lib/ur/response.rb
192
63
  - lib/ur/sub_ur.rb
193
64
  - lib/ur/version.rb
194
- - resources/icons/LGPL-3.0.png
195
65
  - resources/ur.schema.yml
196
- - test/content_type_test.rb
197
- - test/test_helper.rb
198
- - test/ur_faraday_test.rb
199
- - test/ur_metadata_test.rb
200
- - test/ur_rack_test.rb
201
- - test/ur_test.rb
202
- - ur.gemspec
203
66
  homepage: https://github.com/notEthan/ur
204
67
  licenses:
205
68
  - LGPL-3.0
@@ -219,15 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
82
  - !ruby/object:Gem::Version
220
83
  version: '0'
221
84
  requirements: []
222
- rubygems_version: 3.0.6
85
+ rubygems_version: 3.1.2
223
86
  signing_key:
224
87
  specification_version: 4
225
88
  summary: 'ur: unified request representation'
226
- test_files:
227
- - test/content_type_test.rb
228
- - test/test_helper.rb
229
- - test/ur_faraday_test.rb
230
- - test/ur_metadata_test.rb
231
- - test/ur_rack_test.rb
232
- - test/ur_test.rb
233
- - ".simplecov"
89
+ test_files: []
data/.simplecov DELETED
@@ -1 +0,0 @@
1
- SimpleCov.start
data/.yardopts DELETED
@@ -1 +0,0 @@
1
- --main README.md --markup=markdown {lib}/**/*.rb
data/Rakefile.rb DELETED
@@ -1,9 +0,0 @@
1
- require "rake/testtask"
2
-
3
- Rake::TestTask.new(:test) do |t|
4
- t.libs << "test"
5
- t.libs << "lib"
6
- t.test_files = FileList["test/**/*_test.rb"]
7
- end
8
-
9
- task :default => :test
Binary file
@@ -1,342 +0,0 @@
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
data/test/test_helper.rb DELETED
@@ -1,33 +0,0 @@
1
- proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('../lib', File.dirname(__FILE__)))
2
-
3
- require 'simplecov'
4
- require 'byebug'
5
-
6
- # NO EXPECTATIONS
7
- ENV["MT_NO_EXPECTATIONS"] = ''
8
-
9
- require 'minitest/autorun'
10
- require 'minitest/reporters'
11
- Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
12
-
13
- class UrSpec < Minitest::Spec
14
- if ENV['UR_TEST_ALPHA']
15
- # :nocov:
16
- define_singleton_method(:test_order) { :alpha }
17
- # :nocov:
18
- end
19
-
20
- def assert_json_equal(exp, act, *a)
21
- assert_equal(JSI::Typelike.as_json(exp), JSI::Typelike.as_json(act), *a)
22
- end
23
-
24
- def assert_equal exp, act, msg = nil
25
- msg = message(msg, E) { diff exp, act }
26
- assert exp == act, msg
27
- end
28
- end
29
-
30
- # register this to be the base class for specs instead of Minitest::Spec
31
- Minitest::Spec.register_spec_type(//, UrSpec)
32
-
33
- require 'ur'
@@ -1,79 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'faraday'
3
- require 'faraday_middleware'
4
-
5
- describe 'Ur faraday integration' do
6
- it 'integrates, basic usage' do
7
- ur = nil
8
- faraday_conn = ::Faraday.new('https://ur.unth.net/') do |builder|
9
- builder.use(Ur::FaradayMiddleware,
10
- after_response: -> (ur_) { ur = ur_ },
11
- )
12
- builder.adapter(:rack, -> (env) { [200, {'Content-Type' => 'text/plain'}, ['ᚒ']] })
13
- end
14
- res = faraday_conn.get('/')
15
- assert_equal('ᚒ', res.body)
16
- assert_kind_of(Ur, ur)
17
- assert_equal('get', ur.request['method'])
18
- assert_equal('text/plain', ur.response.headers['Content-Type'])
19
- assert_equal('ᚒ', ur.response.body)
20
- assert(ur.validate)
21
- end
22
- it 'integrates, IO body' do
23
- ur = nil
24
- faraday_conn = ::Faraday.new('https://ur.unth.net/') do |builder|
25
- builder.use(Ur::FaradayMiddleware,
26
- after_response: -> (ur_) { ur = ur_ },
27
- )
28
- builder.adapter(:rack, -> (env) { [200, {'Content-Type' => 'text/plain'}, ['☺']] })
29
- end
30
- res = faraday_conn.post('/', StringIO.new('hello!'))
31
- assert_equal('☺', res.body)
32
- assert_kind_of(Ur, ur)
33
- assert_equal('post', ur.request['method'])
34
- assert_equal('hello!', ur.request.body)
35
- assert_equal('text/plain', ur.response.headers['Content-Type'])
36
- assert_equal('☺', ur.response.body)
37
- assert(ur.validate)
38
- end
39
- it 'integrates, faraday middleware munges the json bodies but uses preserve_raw' do
40
- ur = nil
41
- faraday_conn = ::Faraday.new('https://ur.unth.net/') do |builder|
42
- builder.request :json
43
- builder.use(Ur::FaradayMiddleware,
44
- after_response: -> (ur_) { ur = ur_ },
45
- )
46
- builder.response :json, preserve_raw: true
47
- builder.adapter(:rack, -> (env) { [200, {'Content-Type' => 'application/json'}, ['{}']] })
48
- end
49
- res = faraday_conn.post('/', {'a' => 'b'})
50
- assert_equal({}, res.body)
51
- assert_kind_of(Ur, ur)
52
- assert_equal('post', ur.request['method'])
53
- assert_equal('{"a":"b"}', ur.request.body)
54
- assert_equal('application/json', ur.response.headers['Content-Type'])
55
- assert_equal('{}', ur.response.body)
56
- assert(ur.validate)
57
- end
58
- it 'integrates, faraday middleware munges the json bodies and does not preserve_raw' do
59
- ur = nil
60
- faraday_conn = ::Faraday.new('https://ur.unth.net/') do |builder|
61
- builder.use(Ur::FaradayMiddleware,
62
- after_response: -> (ur_) { ur = ur_ },
63
- )
64
- builder.request :json
65
- builder.response :json
66
- builder.adapter(:rack, -> (env) { [200, {'Content-Type' => 'application/json'}, ['{}']] })
67
- end
68
- res = faraday_conn.post('/', {'a' => 'b'})
69
- assert_equal({}, res.body)
70
- assert_kind_of(Ur, ur)
71
- assert_equal('post', ur.request['method'])
72
- assert_nil(ur.request.body) # no good
73
- assert_json_equal({"a" => "b"}, ur.request['body_parsed']) # best we get here
74
- assert_equal('application/json', ur.response.headers['Content-Type'])
75
- assert_nil(ur.response.body) # no good
76
- assert_json_equal({}, ur.response['body_parsed']) # best we get here
77
- assert(ur.validate)
78
- end
79
- end
@@ -1,11 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- describe 'Ur metadata' do
4
- it 'sets duration from began_at' do
5
- ur = Ur.new
6
- ur.metadata.began_at = Time.now
7
- ur.metadata.finish!
8
- assert_instance_of(Float, ur.metadata.duration)
9
- assert_operator(ur.metadata.duration, :>, 0)
10
- end
11
- end
data/test/ur_rack_test.rb DELETED
@@ -1,25 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'rack'
3
-
4
- describe 'Ur rack integration' do
5
- it 'builds from a rack env' do
6
- env = Rack::MockRequest.env_for('https://ur.unth.net/', {'HTTP_FOO' => 'bar'})
7
- ur = Ur.from_rack_request(env)
8
- assert_equal('inbound', ur.bound)
9
- assert_equal('GET', ur.request['method'])
10
- assert_equal('bar', ur.request.headers['foo'])
11
- assert_equal('https://ur.unth.net/', ur.request.uri)
12
- assert(ur.response.empty?)
13
- assert(ur.validate)
14
- end
15
- it 'builds from a rack request' do
16
- env = Rack::Request.new(Rack::MockRequest.env_for('https://ur.unth.net/', {'HTTP_FOO' => 'bar'}))
17
- ur = Ur.from_rack_request(env)
18
- assert_equal('inbound', ur.bound)
19
- assert_equal('GET', ur.request['method'])
20
- assert_equal('bar', ur.request.headers['foo'])
21
- assert_equal('https://ur.unth.net/', ur.request.uri)
22
- assert(ur.response.empty?)
23
- assert(ur.validate)
24
- end
25
- end
data/test/ur_test.rb DELETED
@@ -1,105 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'faraday'
3
- require 'active_support/tagged_logging'
4
-
5
- describe 'Ur' do
6
- it 'has a valid schema' do
7
- Ur.schema.validate_schema!
8
- end
9
-
10
- it 'initializes' do
11
- Ur.new_jsi({})
12
- end
13
-
14
- it 'would prefer not to initialize' do
15
- assert_raises(TypeError) { Ur.new("hello!") }
16
- end
17
-
18
- it 'integrates with rack and faraday middlewares' do
19
- rack_app = proc do |env|
20
- [200, {'Content-Type' => 'text/plain'}, ['ᚒ']]
21
- end
22
- client_logger = ActiveSupport::TaggedLogging.new(Logger.new(StringIO.new))
23
- server_logger = ActiveSupport::TaggedLogging.new(Logger.new(StringIO.new))
24
- called_rack_before_request = false
25
- called_rack_after_response = false
26
- called_faraday_before_request = false
27
- called_faraday_after_response = false
28
- rack_app = Ur::RackMiddleware.new(rack_app, logger: server_logger,
29
- before_request: -> (ur) do
30
- called_rack_before_request = true
31
-
32
- server_logger.push_tags 'ur_test_rack'
33
-
34
- assert_equal('inbound', ur.bound)
35
- assert_equal('GET', ur.request['method'])
36
- assert_equal('ur.unth.net', ur.request.headers['host'])
37
- assert_equal('bar', ur.request.headers['foo'])
38
- assert_equal('https://ur.unth.net/', ur.request.uri)
39
- assert(ur.response.empty?)
40
- assert_nil(ur.metadata.began_at)
41
- assert_nil(ur.metadata.duration)
42
- assert(ur.validate)
43
- end,
44
- after_response: -> (ur) do
45
- called_rack_after_response = true
46
-
47
- server_logger.pop_tags
48
-
49
- assert_equal('inbound', ur.bound)
50
- assert_equal('GET', ur.request['method'])
51
- assert_equal(200, ur.response.status)
52
- assert_equal('text/plain', ur.response.headers['Content-Type'])
53
- assert_equal('ᚒ', ur.response.body)
54
- assert_instance_of(Time, ur.metadata.began_at)
55
- assert_instance_of(Float, ur.metadata.duration)
56
- assert_operator(ur.metadata.duration, :>, 0)
57
- assert_equal(['ur_test_rack'], ur.metadata.tags.to_a)
58
- assert(ur.validate)
59
- end,
60
- )
61
- faraday_conn = ::Faraday.new('https://ur.unth.net/') do |builder|
62
- builder.use(Ur::FaradayMiddleware, logger: client_logger,
63
- before_request: -> (ur) do
64
- called_faraday_before_request = true
65
-
66
- client_logger.push_tags 'ur_test_faraday'
67
-
68
- assert_equal('outbound', ur.bound)
69
- assert_equal('get', ur.request['method'])
70
- assert_equal('bar', ur.request.headers['foo'])
71
- assert_equal('https://ur.unth.net/', ur.request.uri)
72
- assert_equal(Addressable::URI.parse('https://ur.unth.net/'), ur.request.addressable_uri)
73
- assert(ur.response.empty?)
74
- assert_nil(ur.metadata.began_at)
75
- assert_nil(ur.metadata.duration)
76
- assert(ur.validate)
77
- end,
78
- after_response: -> (ur) do
79
- called_faraday_after_response = true
80
-
81
- client_logger.pop_tags
82
-
83
- assert_equal('outbound', ur.bound)
84
- assert_equal('get', ur.request['method'])
85
- assert_equal(200, ur.response.status)
86
- assert_equal('text/plain', ur.response.headers['Content-Type'])
87
- assert_equal('ᚒ', ur.response.body)
88
- assert_instance_of(Time, ur.metadata.began_at)
89
- assert_instance_of(Float, ur.metadata.duration)
90
- assert_operator(ur.metadata.duration, :>, 0)
91
- assert_equal(['ur_test_faraday'], ur.metadata.tags.to_a)
92
- assert(ur.validate)
93
- end,
94
- )
95
- builder.adapter(:rack, rack_app)
96
- end
97
- res = faraday_conn.get('/', nil, {'Foo' => 'bar'})
98
- assert(called_rack_before_request)
99
- assert(called_rack_after_response)
100
- assert(called_faraday_before_request)
101
- assert(called_faraday_after_response)
102
- assert_equal(200, res.status)
103
- assert_equal('ᚒ', res.body)
104
- end
105
- end
data/ur.gemspec DELETED
@@ -1,33 +0,0 @@
1
- lib = File.expand_path("../lib", __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "ur/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "ur"
7
- spec.version = UR_VERSION
8
- spec.authors = ["Ethan"]
9
- spec.email = ["ethan@unth"]
10
-
11
- spec.summary = 'ur: unified request representation'
12
- spec.description = 'ur provides a unified representation of a request and response. it can be interpreted from rack, faraday, or potentially other sources, and provides a consistent interface to access the attributes inherent to the request and additional useful parsers and computation from the request.'
13
- spec.homepage = "https://github.com/notEthan/ur"
14
- spec.license = "LGPL-3.0"
15
-
16
- ignore_files = %w(.gitignore .travis.yml Gemfile test)
17
- ignore_files_re = %r{\A(#{ignore_files.map { |f| Regexp.escape(f) }.join('|')})(/|\z)}
18
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(ignore_files_re) }
19
- spec.test_files = `git ls-files -z test`.split("\x0") + ['.simplecov']
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_dependency "jsi", "~> 0.4"
23
- spec.add_dependency "addressable", "~> 2.0"
24
- spec.add_development_dependency "rack"
25
- spec.add_development_dependency "rack-test"
26
- spec.add_development_dependency "faraday"
27
- spec.add_development_dependency "faraday_middleware"
28
- spec.add_development_dependency "activesupport"
29
- spec.add_development_dependency "rake"
30
- spec.add_development_dependency "minitest"
31
- spec.add_development_dependency "minitest-reporters"
32
- spec.add_development_dependency "simplecov"
33
- end