ur 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '09cd35887d4f337c01a55526c85dec4d0473ed24532d920960890cccc44f3f52'
4
+ data.tar.gz: e6cb70fe2d62dd42864c6fd6b2b6cf7c9ebf3f0c73744e0fa8a952618e1d8b1e
5
+ SHA512:
6
+ metadata.gz: 3e1b5884244f923e22e6570d3e87ce7b3d70771987845bff06da886bb86ed9d29623cbdbf6c55ed943b53529e1506d53f5b995704de177a279c566e8770986f0
7
+ data.tar.gz: 040554fff56b914de9343fb4abd7e5175557224c34632385efaa5794125587f1ea4ae31f5cf8c9b761d20d8b881a320abcee4ebd49cd2614f25680dcce534d09
@@ -0,0 +1 @@
1
+ SimpleCov.start
@@ -0,0 +1 @@
1
+ --main README.md --markup=markdown {lib}/**/*.rb
@@ -0,0 +1,5 @@
1
+ # v0.0.1
2
+
3
+ - Ur, Ur::Request, Ur::Response, Ur::Processing
4
+ - Rack and Faraday integration
5
+ - Ur::Middleware, FaradayMiddleware, RackMiddleware
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Ethan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # Ur ᚒ
2
+
3
+ Ur: Unified Request/Response Representation in Ruby
4
+
5
+ ## Usage with middleware
6
+
7
+ Rack middleware:
8
+
9
+ ```ruby
10
+ class MyRackMiddleware
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ # do things before the request
17
+
18
+ ur = Ur.from_rack_request(env)
19
+
20
+ # set additional properties of the ur, for example:
21
+ ur.logger = my_logger
22
+
23
+ rack_response = ur.with_rack_response(@app, env) do
24
+ # do things after the response
25
+ end
26
+ rack_response
27
+ end
28
+ end
29
+ ```
30
+
31
+ Faraday middleware:
32
+
33
+ ```ruby
34
+ class MyFaradayMiddleware < ::Faraday::Middleware
35
+ def call(request_env)
36
+ # do things before the request
37
+
38
+ ur = Ur.from_faraday_request(request_env)
39
+
40
+ # set additional properties of the ur, for example:
41
+ ur.logger = my_logger
42
+
43
+ ur.faraday_on_complete(@app, request_env) do |response_env|
44
+ # do things after the response
45
+ end
46
+ end
47
+ end
48
+ ```
49
+
50
+ ## License
51
+
52
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,150 @@
1
+ require "ur/version"
2
+
3
+ require 'jsi'
4
+ require 'time'
5
+ require 'addressable/uri'
6
+
7
+ Ur = JSI.class_for_schema({
8
+ id: 'https://schemas.ur.unth.net/ur',
9
+ type: 'object',
10
+ properties: {
11
+ bound: {
12
+ type: 'string',
13
+ description: %q([rfc2616] Inbound and outbound refer to the request and response paths for messages: "inbound" means "traveling toward the origin server", and "outbound" means "traveling toward the user agent"),
14
+ enum: ['inbound', 'outbound'],
15
+ },
16
+ request: {
17
+ type: 'object',
18
+ properties: {
19
+ method: {type: 'string', description: 'HTTP ', example: 'POST'},
20
+ uri: {type: 'string', example: 'https://example.com/foo?bar=baz'},
21
+ headers: {type: 'object'},
22
+ body: {type: 'string'},
23
+ },
24
+ },
25
+ response: {
26
+ type: 'object',
27
+ properties: {
28
+ status: {type: 'integer', example: 200},
29
+ headers: {type: 'object'},
30
+ body: {type: 'string'},
31
+ },
32
+ },
33
+ processing: {
34
+ type: 'object',
35
+ properties: {
36
+ began_at_s: {type: 'string'},
37
+ duration: {type: 'number'},
38
+ tags: {type: 'array', items: {type: 'string'}}
39
+ },
40
+ },
41
+ },
42
+ })
43
+ class Ur
44
+ VERSION = UR_VERSION
45
+
46
+ autoload :RequestAndResponse, 'ur/request_and_response'
47
+ autoload :Middleware, 'ur/middleware'
48
+ autoload :FaradayMiddleware, 'ur/middleware'
49
+ autoload :RackMiddleware, 'ur/middleware'
50
+
51
+ Request = JSI.class_for_schema(self.schema['properties']['request'])
52
+ Response = JSI.class_for_schema(self.schema['properties']['response'])
53
+ Processing = JSI.class_for_schema(self.schema['properties']['processing'])
54
+ require 'ur/request'
55
+ require 'ur/response'
56
+ require 'ur/processing'
57
+
58
+ class << self
59
+ def from_rack_request(request_env)
60
+ if request_env.is_a?(Rack::Request)
61
+ rack_request = request_env
62
+ env = request_env.env
63
+ else
64
+ rack_request = Rack::Request.new(request_env)
65
+ env = request_env
66
+ end
67
+
68
+ Ur.new({}).tap do |ur|
69
+ ur.processing.begin!
70
+ ur.bound = 'inbound'
71
+ ur.request['method'] = rack_request.request_method
72
+ ur.request.headers = env.map do |(key, value)|
73
+ http_match = key.match(/\AHTTP_/)
74
+ if http_match
75
+ name = http_match.post_match.downcase
76
+ {name => value}
77
+ else
78
+ name = %w(content_type content_length).detect { |sname| sname.downcase == key.downcase }
79
+ if name
80
+ {name => value}
81
+ end
82
+ end
83
+ end.compact.inject({}, &:update)
84
+ ur.request.addressable_uri = Addressable::URI.new(
85
+ :scheme => rack_request.scheme,
86
+ :host => rack_request.host,
87
+ :port => rack_request.port,
88
+ :path => rack_request.path,
89
+ :query => (rack_request.query_string unless rack_request.query_string.empty?)
90
+ )
91
+ env["rack.input"].rewind
92
+ ur.request.body = env["rack.input"].read
93
+ env["rack.input"].rewind
94
+ end
95
+ end
96
+
97
+ def from_faraday_request(request_env, logger: nil)
98
+ Ur.new({}).tap do |ur|
99
+ ur.processing.begin!
100
+ ur.bound = 'outbound'
101
+ ur.request['method'] = request_env[:method].to_s
102
+ ur.request.headers = request_env[:request_headers]
103
+ ur.request.uri = request_env[:url].normalize.to_s
104
+ ur.request.set_body_from_faraday(request_env)
105
+ end
106
+ end
107
+ end
108
+
109
+ def initialize(ur = {}, *a, &b)
110
+ super(ur, *a, &b)
111
+ unless instance.respond_to?(:to_hash)
112
+ raise(TypeError, "expected hash argument. got: #{ur.pretty_inspect.chomp}")
113
+ end
114
+ self.request = {} if self.request.nil?
115
+ self.response = {} if self.response.nil?
116
+ self.processing = {} if self.processing.nil?
117
+ end
118
+
119
+ def logger=(logger)
120
+ if logger && logger.formatter.respond_to?(:current_tags)
121
+ processing.tags = logger.formatter.current_tags.dup
122
+ end
123
+ end
124
+
125
+ def with_rack_response(app, env)
126
+ status, response_headers, response_body = app.call(env)
127
+
128
+ response.status = status
129
+ response.headers = response_headers
130
+ response.body = response_body.to_enum.to_a.join('')
131
+
132
+ response_body_proxy = ::Rack::BodyProxy.new(response_body) do
133
+ processing.finish!
134
+
135
+ yield
136
+ end
137
+ [status, response_headers, response_body_proxy]
138
+ end
139
+
140
+ def faraday_on_complete(app, request_env, &block)
141
+ app.call(request_env).on_complete do |response_env|
142
+ response.status = response_env[:status]
143
+ response.headers = response_env[:response_headers]
144
+ response.set_body_from_faraday(response_env)
145
+ processing.finish!
146
+
147
+ yield(response_env)
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,42 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ module Middleware
5
+ def initialize(app, options = {})
6
+ @app = app
7
+ @options = options
8
+ end
9
+ attr_reader :app
10
+ attr_reader :options
11
+
12
+ def invoke_callback(name, *a, &b)
13
+ if @options[name]
14
+ @options[name].call(*a, &b)
15
+ end
16
+ end
17
+ end
18
+
19
+ class FaradayMiddleware < ::Faraday::Middleware
20
+ include Ur::Middleware
21
+ def call(request_env)
22
+ ur = Ur.from_faraday_request(request_env)
23
+ invoke_callback(:before_request, ur)
24
+ ur.logger = options[:logger] if options[:logger]
25
+ ur.faraday_on_complete(@app, request_env) do |response_env|
26
+ invoke_callback(:after_response, ur)
27
+ end
28
+ end
29
+ end
30
+
31
+ class RackMiddleware
32
+ include Ur::Middleware
33
+ def call(env)
34
+ ur = Ur.from_rack_request(env)
35
+ invoke_callback(:before_request, ur)
36
+ ur.logger = options[:logger] if options[:logger]
37
+ ur.with_rack_response(@app, env) do
38
+ invoke_callback(:after_response, ur)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,29 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ class Processing
5
+ def began_at
6
+ began_at_s ? Time.parse(began_at_s) : nil
7
+ end
8
+ def began_at=(time)
9
+ self.began_at_s = time ? time.utc.iso8601(6) : nil
10
+ end
11
+
12
+ attr_accessor :began_at_ns
13
+
14
+ def begin!
15
+ self.began_at ||= Time.now
16
+ self.began_at_ns ||= Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
17
+ end
18
+ def finish!
19
+ return if duration
20
+ if began_at_ns
21
+ now_ns = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
22
+ self.duration = (now_ns - began_at_ns) * 1e-9
23
+ elsif began_at
24
+ now = Time.now
25
+ self.duration = (now.to_f - began_at.to_f)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ class Request
5
+ include RequestAndResponse
6
+
7
+ def addressable_uri
8
+ uri ? Addressable::URI.parse(uri) : nil
9
+ end
10
+ def addressable_uri=(auri)
11
+ self.uri = auri ? auri.normalize.to_s : nil
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ module RequestAndResponse
5
+ module FaradayEntity
6
+ def set_body_from_faraday(env)
7
+ if env[:raw_body].respond_to?(:to_str)
8
+ self.body = env[:raw_body].to_str.dup
9
+ elsif env[:body].respond_to?(:to_str)
10
+ self.body = env[:body].to_str.dup
11
+ elsif env[:body].respond_to?(:read) && env[:body].respond_to?(:rewind)
12
+ env[:body].rewind
13
+ self.body = env[:body].read
14
+ env[:body].rewind
15
+ elsif env[:body]
16
+ # TODO not good
17
+ self['body_parsed'] = env[:body]
18
+ end
19
+ end
20
+ end
21
+ include FaradayEntity
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ class Response
5
+ include RequestAndResponse
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ UR_VERSION = "0.0.1"
@@ -0,0 +1,22 @@
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
+ def assert_json_equal(exp, act, *a)
15
+ assert_equal(JSI::Typelike.as_json(exp), JSI::Typelike.as_json(act), *a)
16
+ end
17
+ end
18
+
19
+ # register this to be the base class for specs instead of Minitest::Spec
20
+ Minitest::Spec.register_spec_type(//, UrSpec)
21
+
22
+ require 'ur'
@@ -0,0 +1,79 @@
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.use(Faraday::Adapter::Rack, -> (env) { [200, {'Content-Type' => 'text/plain'}, ['ᚒ']] })
13
+ end
14
+ res = faraday_conn.get('/')
15
+ assert_equal('ᚒ', res.body)
16
+ assert_instance_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.use(Faraday::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_instance_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.use(Faraday::Adapter::Rack, -> (env) { [200, {'Content-Type' => 'application/json'}, ['{}']] })
48
+ end
49
+ res = faraday_conn.post('/', {'a' => 'b'})
50
+ assert_equal({}, res.body)
51
+ assert_instance_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.use(Faraday::Adapter::Rack, -> (env) { [200, {'Content-Type' => 'application/json'}, ['{}']] })
67
+ end
68
+ res = faraday_conn.post('/', {'a' => 'b'})
69
+ assert_equal({}, res.body)
70
+ assert_instance_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
@@ -0,0 +1,11 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'Ur processing' do
4
+ it 'sets duration from began_at' do
5
+ ur = Ur.new
6
+ ur.processing.began_at = Time.now
7
+ ur.processing.finish!
8
+ assert_instance_of(Float, ur.processing.duration)
9
+ assert_operator(ur.processing.duration, :>, 0)
10
+ end
11
+ end
@@ -0,0 +1,29 @@
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_instance_of(Time, ur.processing.began_at)
14
+ assert_nil(ur.processing.duration)
15
+ assert(ur.validate)
16
+ end
17
+ it 'builds from a rack request' do
18
+ env = Rack::Request.new(Rack::MockRequest.env_for('https://ur.unth.net/', {'HTTP_FOO' => 'bar'}))
19
+ ur = Ur.from_rack_request(env)
20
+ assert_equal('inbound', ur.bound)
21
+ assert_equal('GET', ur.request['method'])
22
+ assert_equal('bar', ur.request.headers['foo'])
23
+ assert_equal('https://ur.unth.net/', ur.request.uri)
24
+ assert(ur.response.empty?)
25
+ assert_instance_of(Time, ur.processing.began_at)
26
+ assert_nil(ur.processing.duration)
27
+ assert(ur.validate)
28
+ end
29
+ end
@@ -0,0 +1,105 @@
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({})
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_instance_of(Time, ur.processing.began_at)
41
+ assert_nil(ur.processing.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.processing.began_at)
55
+ assert_instance_of(Float, ur.processing.duration)
56
+ assert_operator(ur.processing.duration, :>, 0)
57
+ assert_equal(['ur_test_rack'], ur.processing.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_instance_of(Time, ur.processing.began_at)
75
+ assert_nil(ur.processing.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.processing.began_at)
89
+ assert_instance_of(Float, ur.processing.duration)
90
+ assert_operator(ur.processing.duration, :>, 0)
91
+ assert_equal(['ur_test_faraday'], ur.processing.tags.to_a)
92
+ assert(ur.validate)
93
+ end,
94
+ )
95
+ builder.use(Faraday::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
@@ -0,0 +1,43 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "ur/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ur"
8
+ spec.version = UR_VERSION
9
+ spec.authors = ["Ethan"]
10
+ spec.email = ["ethan@unth"]
11
+
12
+ spec.summary = 'ur: unified request representation'
13
+ 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.'
14
+ spec.homepage = "https://github.com/notEthan/ur"
15
+ spec.license = "MIT"
16
+
17
+ ignore_files = %w(.gitignore .travis.yml Gemfile test)
18
+ ignore_files_re = %r{\A(#{ignore_files.map { |f| Regexp.escape(f) }.join('|')})(/|\z)}
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(ignore_files_re) }
23
+ spec.test_files = `git ls-files -z test`.split("\x0") + [
24
+ '.simplecov',
25
+ ]
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_dependency "jsi", "~> 0.0.2"
32
+ spec.add_dependency "addressable", "~> 2.0"
33
+ spec.add_development_dependency "rack"
34
+ spec.add_development_dependency "rack-test"
35
+ spec.add_development_dependency "faraday"
36
+ spec.add_development_dependency "faraday_middleware"
37
+ spec.add_development_dependency "activesupport"
38
+ spec.add_development_dependency "bundler", "~> 1.16"
39
+ spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "minitest", "~> 5.0"
41
+ spec.add_development_dependency "minitest-reporters"
42
+ spec.add_development_dependency "simplecov"
43
+ end
metadata ADDED
@@ -0,0 +1,240 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ur
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ethan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jsi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
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: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.16'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.16'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '10.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '10.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: minitest
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '5.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '5.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: minitest-reporters
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
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: ur provides a unified representation of a request and response. it can
182
+ be interpreted from rack, faraday, or potentially other sources, and provides a
183
+ consistent interface to access the attributes inherent to the request and additional
184
+ useful parsers and computation from the request.
185
+ email:
186
+ - ethan@unth
187
+ executables: []
188
+ extensions: []
189
+ extra_rdoc_files: []
190
+ files:
191
+ - ".simplecov"
192
+ - ".yardopts"
193
+ - CHANGELOG.md
194
+ - LICENSE.txt
195
+ - README.md
196
+ - Rakefile.rb
197
+ - lib/ur.rb
198
+ - lib/ur/middleware.rb
199
+ - lib/ur/processing.rb
200
+ - lib/ur/request.rb
201
+ - lib/ur/request_and_response.rb
202
+ - lib/ur/response.rb
203
+ - lib/ur/version.rb
204
+ - test/test_helper.rb
205
+ - test/ur_faraday_test.rb
206
+ - test/ur_processing_test.rb
207
+ - test/ur_rack_test.rb
208
+ - test/ur_test.rb
209
+ - ur.gemspec
210
+ homepage: https://github.com/notEthan/ur
211
+ licenses:
212
+ - MIT
213
+ metadata: {}
214
+ post_install_message:
215
+ rdoc_options: []
216
+ require_paths:
217
+ - lib
218
+ required_ruby_version: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ required_rubygems_version: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: '0'
228
+ requirements: []
229
+ rubyforge_project:
230
+ rubygems_version: 2.7.7
231
+ signing_key:
232
+ specification_version: 4
233
+ summary: 'ur: unified request representation'
234
+ test_files:
235
+ - test/test_helper.rb
236
+ - test/ur_faraday_test.rb
237
+ - test/ur_processing_test.rb
238
+ - test/ur_rack_test.rb
239
+ - test/ur_test.rb
240
+ - ".simplecov"