http_fp 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 850b1b6981a06a01b80d3bd85977c2e5d53c27d1
4
+ data.tar.gz: 970d21732d1ac8e56458ec0ab9d7aeddda38b935
5
+ SHA512:
6
+ metadata.gz: ec15f9f91bac213932505fa2baef913b2fe709e72e8b423f037754e8f25d7313cadc72d8bab16ab0208c004f922e75195424a84773d3362cb958be5237885720
7
+ data.tar.gz: ff47e1c252f0abe9b85cbfe601ff4e1223e8844d55c4838a7556c1afd1669e784ebc72a07749829fe1931b2e2a6b7db78237d4135ae2a30dc67db10e72f27e4a
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ # These two are temporary
16
+ btrfly.rb
17
+ coucou.txt
@@ -0,0 +1 @@
1
+ 2.1.2
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in http_fp.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 Martin Chabot
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,107 @@
1
+ # HttpFp
2
+
3
+ Functional http client in Ruby.
4
+
5
+ ## Usage
6
+
7
+ ### Basics
8
+
9
+ #### The Request Structure
10
+
11
+ In order to query an HTTP server you will need to build a request hash.
12
+
13
+ Here's an example of a request:
14
+
15
+ ```ruby
16
+ {:proto=>"HTTP/1.1",
17
+ :host=>"http://api.github.com",
18
+ :path=>"/users/martinos/repos",
19
+ :query=>{},
20
+ :header=>
21
+ {"accept"=>"application/json",
22
+ "Content-Type"=>"application/json",
23
+ "user-agent"=>"paw/3.0.11 (macintosh; os x/10.11.6) gcdhttprequest"},
24
+ :method=>"GET",
25
+ :body=>""}
26
+ ```
27
+
28
+ To build that request you can use builder functions and the function composition operator ([`>>~`](https://github.com/martinos/http_fp/blob/master/lib/http_fp/operators.rb#L4)). Every builder function adds values to the response object. Example:
29
+
30
+ ```ruby
31
+ query = verb.("get") >>~
32
+ with_path.("/users/martinos/repos") >>~
33
+ with_host.("https://api.github.com") >>~
34
+ add_headers.(json_headers)
35
+ ```
36
+ The `query` variable is a builder function that is created by combining multiple builder functions together.
37
+
38
+ This `query` function takes a hash as a parameter, and returns a hash decorated by the builders.
39
+
40
+ To demonstrate how it works, we need an initialized request (`empty_req`). Here's the `empty_req`:
41
+
42
+ ```ruby
43
+ pp empty_req
44
+ # =>
45
+ {:proto=>"HTTP/1.1",
46
+ :host=>"http://example.com",
47
+ :path=>"/",
48
+ :query=>{},
49
+ :header=>{},
50
+ :method=>"GET",
51
+ :body=>""}
52
+ ```
53
+
54
+ <<<<<<< HEAD
55
+ We apply the `empty_req` to the query that we've built.
56
+ ```ruby
57
+ pp query.(empty_req)
58
+ # =>
59
+ {:proto=>"HTTP/1.1",
60
+ :host=>"https://api.github.com",
61
+ :path=>"/users/martinos/repos",
62
+ :query=>{},
63
+ :header=>
64
+ {"accept"=>"application/json",
65
+ "Content-Type"=>"application/json",
66
+ "user-agent"=>"paw/3.0.11 (macintosh; os x/10.11.6) gcdhttprequest"},
67
+ :method=>"GET",
68
+ :body=>""}
69
+ ```
70
+ In order to `run` the query, you can combine the query with a "server" function (lambda) that takes a "request", sends it to the server and returns a http "response".
71
+
72
+ ```ruby
73
+ HttpFp::NetHttp.server.(query.(empty_req))
74
+
75
+ # =>
76
+ {:status=>"200",
77
+ :header=>
78
+ {"server"=>["GitHub.com"],
79
+ "date"=>["Sun, 04 Jun 2017 02:20:05 GMT"],
80
+ "content-type"=>["application/json; charset=utf-8"],
81
+ "vary"=>["Accept", "Accept-Encoding"],
82
+ ...},
83
+ }
84
+ :body => "{...}"
85
+ }
86
+
87
+ ```
88
+
89
+ You can also use the pipe operator ([`>>+`](https://github.com/martinos/http_fp/blob/master/lib/http_fp/operators.rb#L8)) and the run function. The `run_` function takes a function as parameter and applies the `empty_req` to it.
90
+
91
+ Here is it's definition:
92
+ ```ruby
93
+ run_ = -> fn { fn.(empty_req) }
94
+ ```
95
+
96
+ ```run
97
+ query >>~ HttpFp::NetHttp.server >>+ run_
98
+ ```
99
+
100
+
101
+ ## Contributing
102
+
103
+ 1. Fork it ( https://github.com/martinos/http_fp/fork )
104
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
105
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
106
+ 4. Push to the branch (`git push origin my-new-feature`)
107
+ 5. Create a new Pull Request
@@ -0,0 +1,11 @@
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
11
+
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'http_fp/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "http_fp"
8
+ spec.version = HttpFp::VERSION
9
+ spec.authors = ["Martin Chabot"]
10
+ spec.email = ["chabotm@gmail.com"]
11
+ spec.summary = %q{Http client that levrage the use of fp principle}
12
+ spec.description = %q{Http client that levrage the use of fp principle}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "minitest"
23
+ spec.add_dependency "rake", "~> 10.0"
24
+ spec.add_dependency "rack"
25
+ spec.add_dependency "activesupport"
26
+ spec.add_dependency "superators19"
27
+ end
@@ -0,0 +1,42 @@
1
+ require "active_support"
2
+ require "http_fp/version"
3
+ require 'http_fp/utils'
4
+ require 'uri'
5
+ require 'base64'
6
+
7
+ module HttpFp
8
+ include Utils
9
+
10
+ mattr_accessor :verb, :with_host, :with_path, :with_query, :withUri,
11
+ :with_json, :with_headers, :add_headers, :fetch, :to_curl,
12
+ :out_curl, :json_resp, :to_uri, :empty_req, :json_headers,
13
+ :with_basic_auth, :run_
14
+
15
+ @@empty_req = {proto: "HTTP/1.1", host: "http://example.com", path: "/", query: {}, header: {}, method: "GET", body: ""}
16
+ @@empty_resp = {status: nil, header: {}, body: {}}
17
+
18
+ @@run_ = -> fn { fn.(@@empty_req) } # underscore because run conflicts with run fn in minitest
19
+ @@verb = -> verb, req { req.merge({method: verb.to_s.upcase}) }.curry
20
+ @@with_host = -> host, req { req[:host] = host; req }.curry
21
+ @@with_path = -> path, req { req[:path] = path; req }.curry
22
+ @@with_query = -> params, req { req[:query] = params ; req }.curry
23
+ @@with_json = -> hash, req { req[:body] = hash.to_json; req }.curry
24
+ @@with_headers = -> header, req { req[:header] = header ; req }.curry
25
+ @@add_headers = -> header, req { req[:header].merge!(header); req }.curry
26
+ @@with_basic_auth = -> user_name, pwd, req do
27
+ encoded = Base64.strict_encode64("#{user_name}:#{pwd}")
28
+ req >>+ add_headers.({"Authorization" => "Basic #{encoded}"})
29
+ end.curry
30
+
31
+ @@json_resp = Utils.at.(:body) >>~ Utils.parse_json
32
+ @@print = -> a { $stdout.puts a.pretty_inspect ; a }
33
+ @@to_uri = -> req {
34
+ uri = URI(req.fetch(:host))
35
+ req[:query] && uri.query = URI.encode_www_form(req[:query])
36
+ uri.path = req[:path]
37
+ uri}
38
+ @@json_headers =
39
+ {"accept" => "application/json",
40
+ 'Content-Type' => 'application/json',
41
+ "user-agent" => "paw/3.0.11 (macintosh; os x/10.11.6) gcdhttprequest"}
42
+ end
@@ -0,0 +1 @@
1
+ 2.4
@@ -0,0 +1,21 @@
1
+ require 'net/http'
2
+ require 'http_fp'
3
+
4
+ module HttpFp::Curl
5
+ include HttpFp
6
+
7
+ mattr_accessor :print_curl, :req
8
+
9
+ @@req = -> req {
10
+ first_part = %{curl -X '#{req[:method]}' '#{HttpFp::to_uri.(req).to_s}' #{req[:header].map(&@@header_to_curl).join(" ")}}
11
+ if req[:body] && !req[:body].empty?
12
+ first_part + %{\n\ -d $'#{req[:body].gsub("'", "\'")}'}
13
+ else
14
+ first_part
15
+ end
16
+ }
17
+ @@header_to_curl = -> a {
18
+ "\\\n -H '#{a[0]}: #{a[1]}'"}
19
+
20
+ @@print_curl = -> req { $stdout.puts(to_curl.(req)) ; req}.curry
21
+ end
File without changes
@@ -0,0 +1,19 @@
1
+ require 'net/http'
2
+ require 'http_fp'
3
+
4
+ module HttpFp::Httpie
5
+ include HttpFp
6
+
7
+ mattr_accessor :print_curl, :req
8
+
9
+ @@req = -> req {
10
+ first_part = %{http #{req[:method]} '#{HttpFp::to_uri.(req).to_s}' #{req[:header].map(&@@header_to_httpie).join(" ")}}
11
+ if req[:body] && !req[:body].empty?
12
+ %{echo $'#{req[:body].gsub("'", "\'")}' |\\\n#{first_part}}
13
+ else
14
+ first_part
15
+ end
16
+ }
17
+ @@header_to_httpie = -> a {
18
+ "\\\n '#{a[0]}: #{a[1]}'"}
19
+ end
@@ -0,0 +1,23 @@
1
+ require 'net/http'
2
+ require 'http_fp'
3
+
4
+ module HttpFp::NetHttp
5
+ include HttpFp
6
+ mattr_reader :method_str_to_req, :server, :net_resp
7
+
8
+ @@method_str_to_req = {"GET" => Net::HTTP::Get, "POST" => Net::HTTP::Post, "DELETE" => Net::HTTP::Delete, "PUT" => Net::HTTP::Put, "PATCH" => Net::HTTP::Patch}
9
+
10
+ @@server = -> req {
11
+ uri = to_uri.(req)
12
+ req_ = method_str_to_req.fetch(req.fetch(:method)).new(uri)
13
+ req_.set_body_internal(req[:body]) if req[:body]
14
+ header = req.fetch(:header)
15
+ header.each { |key, val| req_[key] = val }
16
+ http = Net::HTTP.new(uri.host, uri.port)
17
+ http.use_ssl = uri.scheme == 'https'
18
+ # http.set_debug_output($stdout)
19
+ @@net_resp.(http.request(req_))
20
+ }
21
+
22
+ @@net_resp = -> resp { {status: resp.code, header: resp.to_hash, body: resp.body} }
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'superators19'
2
+
3
+ class Proc
4
+ superator ">>~" do |fn|
5
+ -> a { fn.(self.(a)) }
6
+ end
7
+ end
8
+
9
+ class Object
10
+ superator ">>+" do |fn|
11
+ fn.(self)
12
+ end
13
+ end
14
+
15
+
@@ -0,0 +1,57 @@
1
+ require 'http_fp'
2
+ require 'active_support'
3
+ require 'pp'
4
+ #
5
+ # https://www.diffchecker.com/ihCGIKyG
6
+
7
+ module HttpFp::Rack
8
+ mattr_reader :to_env, :server, :rack_resp_to_resp
9
+
10
+ @@server = -> rack { to_env >>~ rack.method(:call) >>~ rack_resp_to_resp }
11
+ @@to_env = -> request {
12
+ session ||= {}
13
+ session_options ||= {}
14
+
15
+ uri = request >>+ HttpFp.to_uri
16
+ header = (request[:header] || {}).dup
17
+ body = request[:body] || ''
18
+
19
+ content_type_key, val = header.detect { |key, val| puts key; key.downcase == "content-type"}
20
+ env = {
21
+ # CGI variables specified by Rack
22
+ 'REQUEST_METHOD' => request[:method].to_s.upcase,
23
+ 'CONTENT_TYPE' => header.delete(content_type_key),
24
+ 'CONTENT_LENGTH' => body.bytesize,
25
+ 'PATH_INFO' => uri.path,
26
+ 'QUERY_STRING' => uri.query || '',
27
+ 'SERVER_NAME' => uri.host,
28
+ 'SERVER_PORT' => uri.port,
29
+ 'SCRIPT_NAME' => ""
30
+ }
31
+
32
+ env['HTTP_AUTHORIZATION'] = 'Basic ' + [uri.userinfo].pack('m').delete("\r\n") if uri.userinfo
33
+
34
+ # Rack-specific variables
35
+ env['rack.input'] = StringIO.new(body)
36
+ env['rack.errors'] = $stderr
37
+ env['rack.version'] = ::Rack::VERSION
38
+ env['rack.url_scheme'] = uri.scheme
39
+ env['rack.run_once'] = true
40
+ env['rack.session'] = session
41
+ env['rack.session.options'] = session_options
42
+
43
+ header.each { |k, v| env["HTTP_#{k.tr('-','_').upcase}"] = v }
44
+ env
45
+ }
46
+
47
+ @@rack_resp_to_resp = -> resp { {status: resp[0],
48
+ header: resp[1],
49
+ body: @@body_from_rack_response.(resp[2])} }
50
+
51
+ @@body_from_rack_response = -> response {
52
+ body = ""
53
+ response.each { |line| body << line }
54
+ response.close if response.respond_to?(:close)
55
+ body
56
+ }
57
+ end
@@ -0,0 +1,63 @@
1
+ require 'active_support'
2
+ require 'json'
3
+ require 'pp'
4
+ require 'http_fp/operators'
5
+ require 'yaml'
6
+
7
+ module Utils
8
+ mattr_accessor :parse_json, :debug, :at, :retry_fn,
9
+ :record, :player, :count_by, :cache, :red, :time,
10
+ :expired, :apply, :and_then, :default, :map, :get, :try
11
+
12
+ @@parse_json = JSON.method(:parse)
13
+ @@debug = -> print, a, b { print.(a) ; print.(b.to_s); b }.curry
14
+ @@at = -> key, hash { hash[key] }.curry
15
+ @@red = -> a { "\033[31m#{a}\033[0m" }
16
+ # ( a -> b ) -> a -> b
17
+ @@try = -> f, a { a.nil? ? nil : f.(a) }.curry
18
+ @@retry_fn = -> fn, a {
19
+ begin
20
+ fn.(a)
21
+ rescue
22
+ sleep(1)
23
+ puts "RETRYING"
24
+ @@retry_fn.(fn).(a)
25
+ end
26
+ }.curry
27
+ @@record = -> filename, to_save {
28
+ File.open(filename, "w+") { |a| a << to_save.to_yaml }
29
+ to_save
30
+ }.curry
31
+ @@play = -> filename, _params { YAML.load(File.read(filename)) }.curry
32
+ # (Float -> String -> Bool) -> String -> (a -> b) -> b
33
+ @@cache = -> expired, filename, fn, param {
34
+ if expired.(filename)
35
+ @@record.(filename).(fn.(param))
36
+ else
37
+ puts "reading from cache"
38
+ @@play.(filename).(nil)
39
+ end
40
+ }.curry
41
+ @@expired = -> sec, a { ! File.exist?(a) || (Time.now - File.mtime(a)) > sec }.curry
42
+ @@count_by = -> fn, a {
43
+ a.inject({}) do |res, a|
44
+ by = fn.(a)
45
+ res[by] ||= 0
46
+ res[by] += 1
47
+ res
48
+ end
49
+ }.curry
50
+
51
+ # (String -> String) -> String -> ( a -> b ) -> a -> b
52
+ @@time = -> print, msg, fn, a {
53
+ start_time = Time.now
54
+ res = fn.(a)
55
+ print.("Time duration for #{msg} = #{Time.now - start_time}")
56
+ res}.curry
57
+ @@apply = -> method, a { a.send(method) }.curry
58
+ @@default = -> default, a { a.nil? ? default : a }.curry
59
+ @@and_then = -> f , a { a.nil? ? nil : f.(a) }.curry
60
+ @@map = -> f, enum { enum.map(&f) }.curry
61
+ @@at = -> key, hash { hash; hash[key] }.curry
62
+ @@get = -> method, obj { obj.send(method) }.curry
63
+ end
@@ -0,0 +1,3 @@
1
+ module HttpFp
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ require 'minitest_helper'
2
+ require 'http_fp'
3
+ require 'http_fp/rack'
4
+ require 'http_fp/curl'
5
+
6
+ class HttpFp::CurlTest < Minitest::Test
7
+ include HttpFp
8
+
9
+ def setup
10
+ @curl = verb.("GET") >>~
11
+ with_path.("/coucou") >>~
12
+ with_headers.(json_headers) >>~
13
+ with_host.("https://api.github.com") >>~
14
+ with_json.({user: "martin"}) >>~
15
+ HttpFp::Curl.req >>+ run_
16
+ end
17
+
18
+ def test_should_return_a_curl_command
19
+ res = <<EOF
20
+ curl -X 'GET' 'https://api.github.com/coucou?' \\
21
+ -H 'accept: application/json' \\
22
+ -H 'Content-Type: application/json' \\
23
+ -H 'user-agent: paw/3.0.11 (macintosh; os x/10.11.6) gcdhttprequest'
24
+ -d $'{"user":"martin"}'
25
+ EOF
26
+ assert_equal res.chomp, @curl
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'minitest_helper'
2
+ require 'http_fp'
3
+ require 'http_fp/rack'
4
+ require 'http_fp/httpie'
5
+
6
+ class HttpFp::CurlTest < Minitest::Test
7
+ include HttpFp
8
+
9
+ def setup
10
+ @curl = verb.("GET") >>~
11
+ with_path.("/coucou") >>~
12
+ with_headers.(json_headers) >>~
13
+ with_host.("https://api.github.com") >>~
14
+ with_json.({user: "martin"}) >>~
15
+ HttpFp::Httpie.req >>+ run_
16
+ end
17
+
18
+ def test_should_return_a_curl_command
19
+ res = <<EOF
20
+ echo $'{"user":"martin"}' |\\
21
+ http GET 'https://api.github.com/coucou?' \\
22
+ 'accept: application/json' \\
23
+ 'Content-Type: application/json' \\
24
+ 'user-agent: paw/3.0.11 (macintosh; os x/10.11.6) gcdhttprequest'
25
+ EOF
26
+ assert_equal res.chomp, @curl
27
+ end
28
+ end
@@ -0,0 +1,61 @@
1
+ require 'minitest_helper'
2
+ require 'rack'
3
+ require 'http_fp/rack'
4
+
5
+ # https://github.com/macournoyer/thin/blob/a7d1174f47a4491a15b505407c0501cdc8d8d12c/spec/request/parser_spec.rb
6
+ # rack sample
7
+ # https://gist.github.com/a1869ea2e5db0563d5772b2eff74ff9f
8
+ class HttpFp::RackTest < MiniTest::Test
9
+ include HttpFp
10
+
11
+ def setup
12
+ @req = HttpFp.empty_req >>+ with_host.("http://localhost:3000")
13
+ end
14
+
15
+ def test_upcase_headers
16
+ req = @req >>+ add_headers.("X-invisible" => "tata")
17
+ env = Rack.to_env.(req)
18
+ assert_equal "tata", env["HTTP_X_INVISIBLE"]
19
+ end
20
+
21
+ def test_basic_headers
22
+ env = empty_req >>+ verb.("get") >>+
23
+ with_host.("https://localhost:3000") >>+
24
+ with_query.({"name" => "martin"}) >>+
25
+ with_path.("/users/1") >>+
26
+ Rack.to_env
27
+ # assert_equal "HTTP/1.1", env["SERVER_PROTOCOL"]
28
+ # assert_equal "HTTP/1.1", env["HTTP_VERSION"]
29
+ # assert_equal "/users/1", env["REQUEST_PATH"]
30
+ assert_equal "GET", env["REQUEST_METHOD"]
31
+ assert_equal 'https', env["rack.url_scheme"]
32
+ assert_equal '/users/1', env["PATH_INFO"]
33
+ end
34
+
35
+ def test_host
36
+ env = empty_req >>+
37
+ verb.("get") >>+
38
+ with_host.("https://localhost:3000") >>+
39
+ with_query.({"name" => "martin"}) >>+
40
+ with_path.("/users/1") >>+
41
+ Rack.to_env
42
+ # assert_equal "localhost:3000", env["HTTP_HOST"]
43
+ assert_equal "localhost", env["SERVER_NAME"]
44
+ assert_equal 3000, env["SERVER_PORT"]
45
+ assert_equal "name=martin", env["QUERY_STRING"]
46
+ assert_equal "", env["SCRIPT_NAME"]
47
+ end
48
+
49
+ def test_dont_prepend_HTTP_to_content_type_and_content_length
50
+ env = empty_req >>+
51
+ verb.("get") >>+
52
+ with_host.("https://localhost:3000") >>+
53
+ with_query.({"name" => "martin"}) >>+
54
+ with_path.("/users/1") >>+
55
+ add_headers.({"content-type" => "application/json"}) >>+
56
+ Rack.to_env
57
+ assert_equal "application/json", env["CONTENT_TYPE"]
58
+ assert_equal 0, env["CONTENT_LENGTH"]
59
+ end
60
+ end
61
+
@@ -0,0 +1,14 @@
1
+ require 'minitest_helper'
2
+ require 'http_fp'
3
+
4
+ class HttpFp::HttpFpTest < Minitest::Test
5
+ include HttpFp
6
+
7
+ def test_basic_auth
8
+ req = empty_req >>+ with_basic_auth.("martin").("secret")
9
+ authorization = req[:header]["Authorization"]
10
+ refute_nil authorization
11
+ assert_equal "Basic bWFydGluOnNlY3JldA==", authorization
12
+ end
13
+ end
14
+
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'http_fp'
3
+
4
+ require 'minitest/autorun'
@@ -0,0 +1,7 @@
1
+ require 'minitest_helper'
2
+
3
+ class TestHttpFp < MiniTest::Unit::TestCase
4
+ def test_that_it_has_a_version_number
5
+ refute_nil ::HttpFp::VERSION
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_fp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Martin Chabot
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
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: superators19
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Http client that levrage the use of fp principle
98
+ email:
99
+ - chabotm@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".ruby-version"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - http_fp.gemspec
112
+ - lib/http_fp.rb
113
+ - lib/http_fp/.ruby-version
114
+ - lib/http_fp/curl.rb
115
+ - lib/http_fp/http_fp.rb
116
+ - lib/http_fp/httpie.rb
117
+ - lib/http_fp/net_http.rb
118
+ - lib/http_fp/operators.rb
119
+ - lib/http_fp/rack.rb
120
+ - lib/http_fp/utils.rb
121
+ - lib/http_fp/version.rb
122
+ - test/http_fp/curl_test.rb
123
+ - test/http_fp/httpie_test.rb
124
+ - test/http_fp/rack_test.rb
125
+ - test/http_fp_test.rb
126
+ - test/minitest_helper.rb
127
+ - test/test_http_fp.rb
128
+ homepage: ''
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.6.10
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Http client that levrage the use of fp principle
152
+ test_files:
153
+ - test/http_fp/curl_test.rb
154
+ - test/http_fp/httpie_test.rb
155
+ - test/http_fp/rack_test.rb
156
+ - test/http_fp_test.rb
157
+ - test/minitest_helper.rb
158
+ - test/test_http_fp.rb