Codebase list ruby-http-form-data / cabe298
Imported Upstream version 1.0.1 Balasankar C 8 years ago
26 changed file(s) with 961 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 /.bundle/
1 /.yardoc
2 /Gemfile.lock
3 /_yardoc/
4 /coverage/
5 /doc/
6 /pkg/
7 /spec/reports/
8 /tmp/
9 *.bundle
10 *.so
11 *.o
12 *.a
13 mkmf.log
0 --color
1 --require spec_helper
0 ## Styles ######################################################################
1
2 Style/AlignParameters:
3 EnforcedStyle: with_fixed_indentation
4
5 Style/BracesAroundHashParameters:
6 Enabled: false
7
8 # Broken (2014-12-15). Use `yardstick` gem instead.
9 # See: https://github.com/bbatsov/rubocop/issues/947
10 # TODO: Enable back once cop is fixed.
11 Style/Documentation:
12 Enabled: false
13
14 Style/EmptyLineBetweenDefs:
15 AllowAdjacentOneLineDefs: true
16
17 Style/Encoding:
18 EnforcedStyle: when_needed
19
20 Style/HashSyntax:
21 EnforcedStyle: hash_rockets
22
23 Style/IndentHash:
24 EnforcedStyle: consistent
25
26 # New lambda syntax is as ugly to me as new syntax of Hash.
27 Style/Lambda:
28 Enabled: false
29
30 Style/MultilineOperationIndentation:
31 EnforcedStyle: indented
32
33 # A bit useless restriction, that makes impossible aligning code like this:
34 #
35 # redis do |conn|
36 # conn.hset :k1, now
37 # conn.hincrby :k2, 123
38 # end
39 SingleSpaceBeforeFirstArg:
40 Enabled: false
41
42 Style/StringLiterals:
43 EnforcedStyle: double_quotes
44
45 # Not all trivial readers/writers can be defined with attr_* methods
46 #
47 # class Example < SimpleDelegator
48 # def __getobj__
49 # @obj
50 # end
51 #
52 # def __setobj__(obj)
53 # @obj = obj
54 # end
55 # end
56 Style/TrivialAccessors:
57 Enabled: false
58
59 ## Metrics #####################################################################
60
61 Metrics/MethodLength:
62 CountComments: false
63 Max: 15
0 bundler_args: --without development doc
1 env:
2 global:
3 - JRUBY_OPTS="$JRUBY_OPTS --debug"
4 language: ruby
5 rvm:
6 - 1.9.3
7 - 2.0.0
8 - 2.1
9 - 2.2
10 - jruby-19mode
11 - jruby-head
12 - rbx-2
13 - ruby-head
14 matrix:
15 allow_failures:
16 - rvm: jruby-head
17 - rvm: ruby-head
18 fast_finish: true
19 sudo: false
0 --markup-provider=redcarpet
1 --markup=markdown
0 ## 1.0.1 (2015-03-31)
1
2 * Fix usage of URI module.
3
4
5 ## 1.0.0 (2015-01-04)
6
7 * Gem renamed to `http-form_data` as `FormData` is not top-level citizen
8 anymore: `FormData -> HTTP::FormData`.
9
10
11 ## 0.1.0 (2015-01-02)
12
13 * Move repo under `httprb` organization on GitHub.
14 * Add `nil` support to `FormData#ensure_hash`.
15
16
17 ## 0.0.1 (2014-12-15)
18
19 * First release ever!
0 source "https://rubygems.org"
1
2 gem "rake"
3
4 group :development do
5 gem "pry"
6 gem "guard"
7 gem "guard-rspec", :require => false
8 end
9
10 group :test do
11 gem "coveralls"
12 gem "rspec", "~> 3.1"
13 gem "simplecov", ">= 0.9"
14 gem "rubocop", "~> 0.28.0"
15 end
16
17 group :doc do
18 gem "yard"
19 gem "redcarpet"
20 end
21
22 # Specify your gem's dependencies in form_data.gemspec
23 gemspec
0 guard :rspec, :cmd => "bundle exec rspec" do
1 require "guard/rspec/dsl"
2 dsl = Guard::RSpec::Dsl.new(self)
3
4 # RSpec files
5 rspec = dsl.rspec
6 watch(rspec.spec_helper) { rspec.spec_dir }
7 watch(rspec.spec_support) { rspec.spec_dir }
8 watch(rspec.spec_files)
9
10 # Ruby files
11 ruby = dsl.ruby
12 dsl.watch_spec_files_for(ruby.lib_files)
13 end
0 Copyright (c) 2015 Aleksey V Zapparov
1
2 MIT License
3
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 "Software"), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0 # FormData
1
2 [![Gem Version](https://badge.fury.io/rb/http-form_data.png)](http://rubygems.org/gems/http-form_data)
3 [![Build Status](https://secure.travis-ci.org/httprb/form_data.rb.png?branch=master)](http://travis-ci.org/httprb/form_data.rb)
4 [![Code Climate](https://codeclimate.com/github/httprb/form_data.rb.png)](https://codeclimate.com/github/httprb/form_data.rb)
5 [![Coverage Status](https://coveralls.io/repos/httprb/form_data.rb/badge.png?branch=master)](https://coveralls.io/r/httprb/form_data.rb)
6
7 Utility-belt to build form data request bodies.
8
9
10 ## Installation
11
12 Add this line to your application's Gemfile:
13
14 ```ruby
15 gem 'http-form_data'
16 ```
17
18 And then execute:
19
20 $ bundle
21
22 Or install it yourself as:
23
24 $ gem install http-form_data
25
26
27 ## Usage
28
29 ``` ruby
30 require "http/form_data"
31
32 form = HTTP::FormData.create({
33 :username => "ixti",
34 :avatar_file => HTTP::FormData::File.new("/home/ixti/avatar.png")
35 })
36
37 # Assuming socket is an open socket to some HTTP server
38 socket << "POST /some-url HTTP/1.1\r\n"
39 socket << "Host: example.com\r\n"
40 socket << "Content-Type: #{form.content_type}\r\n"
41 socket << "Content-Length: #{form.content_length}\r\n"
42 socket << "\r\n"
43 socket << form.to_s
44 ```
45
46
47 ## Supported Ruby Versions
48
49 This library aims to support and is [tested against][ci] the following Ruby
50 versions:
51
52 * Ruby 1.9.3
53 * Ruby 2.0.0
54 * Ruby 2.1.x
55 * Ruby 2.2.x
56
57 If something doesn't work on one of these versions, it's a bug.
58
59 This library may inadvertently work (or seem to work) on other Ruby versions,
60 however support will only be provided for the versions listed above.
61
62 If you would like this library to support another Ruby version or
63 implementation, you may volunteer to be a maintainer. Being a maintainer
64 entails making sure all tests run and pass on that implementation. When
65 something breaks on your implementation, you will be responsible for providing
66 patches in a timely fashion. If critical issues for a particular implementation
67 exist at the time of a major release, support for that Ruby version may be
68 dropped.
69
70
71 ## Contributing
72
73 1. Fork it ( https://github.com/httprb/form_data.rb/fork )
74 2. Create your feature branch (`git checkout -b my-new-feature`)
75 3. Commit your changes (`git commit -am 'Add some feature'`)
76 4. Push to the branch (`git push origin my-new-feature`)
77 5. Create a new Pull Request
78
79
80 ## Copyright
81
82 Copyright (c) 2015 Aleksey V Zapparov.
83 See [LICENSE.txt][license] for further details.
84
85
86 [ci]: http://travis-ci.org/httprb/form_data.rb
87 [license]: https://github.com/httprb/form_data.rb/blob/master/LICENSE.txt
0 #!/usr/bin/env rake
1
2 require "bundler/gem_tasks"
3
4 require "rspec/core/rake_task"
5 RSpec::Core::RakeTask.new
6
7 begin
8 require "rubocop/rake_task"
9 RuboCop::RakeTask.new
10 rescue LoadError
11 task :rubocop do
12 $stderr.puts "RuboCop is disabled"
13 end
14 end
15
16 task :default => [:spec, :rubocop]
0 # coding: utf-8
1 lib = File.expand_path("../lib", __FILE__)
2 $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3 require "http/form_data/version"
4
5 Gem::Specification.new do |spec|
6 spec.name = "http-form_data"
7 spec.version = HTTP::FormData::VERSION
8 spec.homepage = "https://github.com/httprb/form_data.rb"
9 spec.authors = ["Aleksey V Zapparov"]
10 spec.email = ["ixti@member.fsf.org"]
11 spec.license = "MIT"
12 spec.summary = "http-form_data-#{HTTP::FormData::VERSION}"
13 spec.description = <<-DESC.gsub(/^\s+> /m, "").gsub("\n", " ").strip
14 > Utility-belt to build form data request bodies.
15 > Provides support for `application/x-www-form-urlencoded` and
16 > `multipart/form-data` types.
17 DESC
18
19 spec.files = `git ls-files -z`.split("\x0")
20 spec.executables = spec.files.grep(/^bin\//).map { |f| File.basename(f) }
21 spec.test_files = spec.files.grep(/^(test|spec|features)\//)
22 spec.require_paths = ["lib"]
23
24 spec.add_development_dependency "bundler", "~> 1.7"
25 end
0 module HTTP
1 module FormData
2 # Represents file form param.
3 #
4 # @example Usage with StringIO
5 #
6 # io = StringIO.new "foo bar baz"
7 # FormData::File.new io, :filename => "foobar.txt"
8 #
9 # @example Usage with IO
10 #
11 # File.open "/home/ixti/avatar.png" do |io|
12 # FormData::File.new io
13 # end
14 #
15 # @example Usage with pathname
16 #
17 # FormData::File.new "/home/ixti/avatar.png"
18 class File
19 # Default MIME type
20 DEFAULT_MIME = "application/octet-stream".freeze
21
22 attr_reader :mime_type, :filename
23
24 # @see DEFAULT_MIME
25 # @param [String, StringIO, File] file_or_io Filename or IO instance.
26 # @param [#to_h] opts
27 # @option opts [#to_s] :mime_type (DEFAULT_MIME)
28 # @option opts [#to_s] :filename
29 # When `file` is a String, defaults to basename of `file`.
30 # When `file` is a File, defaults to basename of `file`.
31 # When `file` is a StringIO, defaults to `"stream-{object_id}"`
32 def initialize(file_or_io, opts = {})
33 @file_or_io = file_or_io
34
35 opts = FormData.ensure_hash opts
36
37 @mime_type = opts.fetch(:mime_type) { DEFAULT_MIME }
38 @filename = opts.fetch :filename do
39 case file_or_io
40 when String then ::File.basename file_or_io
41 when ::File then ::File.basename file_or_io.path
42 else "stream-#{file_or_io.object_id}"
43 end
44 end
45 end
46
47 # Returns content size.
48 #
49 # @return [Fixnum]
50 def size
51 with_io(&:size)
52 end
53
54 # Returns content of a file of IO.
55 #
56 # @return [String]
57 def to_s
58 with_io(&:read)
59 end
60
61 private
62
63 # @yield [io] Gives IO instance to the block
64 # @return result of yielded block
65 def with_io
66 if @file_or_io.is_a?(::File) || @file_or_io.is_a?(StringIO)
67 yield @file_or_io
68 else
69 ::File.open(@file_or_io) { |io| yield io }
70 end
71 end
72 end
73 end
74 end
0 module HTTP
1 module FormData
2 class Multipart
3 # Utility class to represent multi-part chunks
4 class Param
5 # @param [#to_s] name
6 # @param [FormData::File, #to_s] value
7 def initialize(name, value)
8 @name, @value = name.to_s, value
9
10 @header = "Content-Disposition: form-data; name=#{@name.inspect}"
11
12 return unless file?
13
14 @header << "; filename=#{value.filename.inspect}"
15 @header << CRLF
16 @header << "Content-Type: #{value.mime_type}"
17 end
18
19 # Returns body part with headers and data.
20 #
21 # @example With {FormData::File} value
22 #
23 # Content-Disposition: form-data; name="avatar"; filename="avatar.png"
24 # Content-Type: application/octet-stream
25 #
26 # ...data of avatar.png...
27 #
28 # @example With non-{FormData::File} value
29 #
30 # Content-Disposition: form-data; name="username"
31 #
32 # ixti
33 #
34 # @return [String]
35 def to_s
36 "#{@header}#{CRLF * 2}#{@value}"
37 end
38
39 # Calculates size of a part (headers + body).
40 #
41 # @return [Fixnum]
42 def size
43 size = @header.bytesize + (CRLF.bytesize * 2)
44
45 if file?
46 size + @value.size
47 else
48 size + @value.to_s.bytesize
49 end
50 end
51
52 # Flattens given `data` Hash into an array of `Param`'s.
53 # Nested array are unwinded.
54 # Behavior is similar to `URL.encode_www_form`.
55 #
56 # @param [Hash] data
57 # @return [Array<FormData::MultiPart::Param>]
58 def self.coerce(data)
59 params = []
60
61 data.each do |name, values|
62 Array(values).each do |value|
63 params << new(name, value)
64 end
65 end
66
67 params
68 end
69
70 private
71
72 # Tells whenever value is a {FormData::File} or not.
73 #
74 # @return [Boolean]
75 def file?
76 @value.is_a? FormData::File
77 end
78 end
79 end
80 end
81 end
0 # stdlib
1 require "securerandom"
2
3 # internal
4 require "http/form_data/multipart/param"
5
6 module HTTP
7 module FormData
8 # `multipart/form-data` form data.
9 class Multipart
10 # @param [#to_h, Hash] data form data key-value Hash
11 def initialize(data)
12 @parts = Param.coerce FormData.ensure_hash data
13 @boundary = ("-" * 21) << SecureRandom.hex(21)
14 @content_length = nil
15 end
16
17 # Returns content to be used for HTTP request body.
18 #
19 # @return [String]
20 def to_s
21 head + @parts.map(&:to_s).join(glue) + tail
22 end
23
24 # Returns MIME type to be used for HTTP request `Content-Type` header.
25 #
26 # @return [String]
27 def content_type
28 "multipart/form-data; boundary=#{@boundary}"
29 end
30
31 # Returns form data content size to be used for HTTP request
32 # `Content-Length` header.
33 #
34 # @return [Fixnum]
35 def content_length
36 unless @content_length
37 @content_length = head.bytesize + tail.bytesize
38 @content_length += @parts.map(&:size).reduce(:+)
39 @content_length += (glue.bytesize * (@parts.count - 1))
40 end
41
42 @content_length
43 end
44
45 private
46
47 # @return [String]
48 def head
49 @head ||= "--#{@boundary}#{CRLF}"
50 end
51
52 # @return [String]
53 def glue
54 @glue ||= "#{CRLF}--#{@boundary}#{CRLF}"
55 end
56
57 # @return [String]
58 def tail
59 @tail ||= "#{CRLF}--#{@boundary}--"
60 end
61 end
62 end
63 end
0 require "uri"
1
2 module HTTP
3 module FormData
4 # `application/x-www-form-urlencoded` form data.
5 class Urlencoded
6 # @param [#to_h, Hash] data form data key-value Hash
7 def initialize(data)
8 @data = FormData.ensure_hash data
9 end
10
11 # Returns content to be used for HTTP request body.
12 #
13 # @return [String]
14 def to_s
15 ::URI.encode_www_form @data
16 end
17
18 # Returns MIME type to be used for HTTP request `Content-Type` header.
19 #
20 # @return [String]
21 def content_type
22 "application/x-www-form-urlencoded"
23 end
24
25 # Returns form data content size to be used for HTTP request
26 # `Content-Length` header.
27 #
28 # @return [Fixnum]
29 def content_length
30 to_s.bytesize
31 end
32 end
33 end
34 end
0 module HTTP
1 module FormData
2 # Gem version.
3 VERSION = "1.0.1"
4 end
5 end
0 require "http/form_data/file"
1 require "http/form_data/multipart"
2 require "http/form_data/urlencoded"
3 require "http/form_data/version"
4
5 # http.rb namespace.
6 # @see https://github.com/httprb/http.rb
7 module HTTP
8 # Utility-belt to build form data request bodies.
9 # Provides support for `application/x-www-form-urlencoded` and
10 # `multipart/form-data` types.
11 #
12 # @example Usage
13 #
14 # form = FormData.create({
15 # :username => "ixti",
16 # :avatar_file => FormData::File.new("/home/ixti/avatar.png")
17 # })
18 #
19 # # Assuming socket is an open socket to some HTTP server
20 # socket << "POST /some-url HTTP/1.1\r\n"
21 # socket << "Host: example.com\r\n"
22 # socket << "Content-Type: #{form.content_type}\r\n"
23 # socket << "Content-Length: #{form.content_length}\r\n"
24 # socket << "\r\n"
25 # socket << form.to_s
26 module FormData
27 # CRLF
28 CRLF = "\r\n".freeze
29
30 # Generic FormData error.
31 class Error < StandardError; end
32
33 class << self
34 # FormData factory. Automatically selects best type depending on given
35 # `data` Hash.
36 #
37 # @param [#to_h, Hash] data
38 # @return [Multipart] if any of values is a {FormData::File}
39 # @return [Urlencoded] otherwise
40 def create(data)
41 data = ensure_hash data
42 klass = multipart?(data) ? Multipart : Urlencoded
43
44 klass.new data
45 end
46
47 # Coerce `obj` to Hash.
48 #
49 # @note Internal usage helper, to workaround lack of `#to_h` on Ruby < 2.1
50 # @raise [Error] `obj` can't be coerced.
51 # @return [Hash]
52 def ensure_hash(obj)
53 case
54 when obj.nil? then {}
55 when obj.is_a?(Hash) then obj
56 when obj.respond_to?(:to_h) then obj.to_h
57 else fail Error, "#{obj.inspect} is neither Hash nor responds to :to_h"
58 end
59 end
60
61 private
62
63 # Tells whenever data contains multipart data or not.
64 #
65 # @param [Hash] data
66 # @return [Boolean]
67 def multipart?(data)
68 data.any? do |_, v|
69 next true if v.is_a? FormData::File
70 v.respond_to?(:to_ary) && v.to_ary.any? { |e| e.is_a? FormData::File }
71 end
72 end
73 end
74 end
75 end
0 The HTTP Gem is an easy-to-use client library for making requests from Ruby.
0 # coding: utf-8
1
2 RSpec.describe HTTP::FormData::File do
3 let(:opts) { nil }
4
5 describe "#size" do
6 subject { described_class.new(file, opts).size }
7
8 context "when file given as a String" do
9 let(:file) { fixture("the-http-gem.info").to_s }
10 it { is_expected.to eq fixture("the-http-gem.info").size }
11 end
12
13 context "when file given as StringIO" do
14 let(:file) { StringIO.new "привет мир!" }
15 it { is_expected.to eq 20 }
16 end
17
18 context "when file given as File" do
19 let(:file) { fixture("the-http-gem.info").open }
20 after { file.close }
21 it { is_expected.to eq fixture("the-http-gem.info").size }
22 end
23 end
24
25 describe "#to_s" do
26 subject { described_class.new(file, opts).to_s }
27
28 context "when file given as a String" do
29 let(:file) { fixture("the-http-gem.info").to_s }
30 it { is_expected.to eq fixture("the-http-gem.info").read }
31 end
32
33 context "when file given as StringIO" do
34 let(:file) { StringIO.new "привет мир!" }
35 it { is_expected.to eq "привет мир!" }
36 end
37
38 context "when file given as File" do
39 let(:file) { fixture("the-http-gem.info").open }
40 after { file.close }
41 it { is_expected.to eq fixture("the-http-gem.info").read }
42 end
43 end
44
45 describe "#filename" do
46 subject { described_class.new(file, opts).filename }
47
48 context "when file given as a String" do
49 let(:file) { fixture("the-http-gem.info").to_s }
50
51 it { is_expected.to eq ::File.basename file }
52
53 context "and filename given with options" do
54 let(:opts) { { :filename => "foobar.txt" } }
55 it { is_expected.to eq "foobar.txt" }
56 end
57 end
58
59 context "when file given as StringIO" do
60 let(:file) { StringIO.new }
61
62 it { is_expected.to eq "stream-#{file.object_id}" }
63
64 context "and filename given with options" do
65 let(:opts) { { :filename => "foobar.txt" } }
66 it { is_expected.to eq "foobar.txt" }
67 end
68 end
69
70 context "when file given as File" do
71 let(:file) { fixture("the-http-gem.info").open }
72 after { file.close }
73
74 it { is_expected.to eq "the-http-gem.info" }
75
76 context "and filename given with options" do
77 let(:opts) { { :filename => "foobar.txt" } }
78 it { is_expected.to eq "foobar.txt" }
79 end
80 end
81 end
82
83 describe "#mime_type" do
84 subject { described_class.new(StringIO.new, opts).mime_type }
85
86 it { is_expected.to eq "application/octet-stream" }
87
88 context "when it was given with options" do
89 let(:opts) { { :mime_type => "application/json" } }
90 it { is_expected.to eq "application/json" }
91 end
92 end
93 end
0 RSpec.describe HTTP::FormData::Multipart do
1 let(:file) { HTTP::FormData::File.new fixture "the-http-gem.info" }
2 let(:params) { { :foo => :bar, :baz => file } }
3 let(:boundary) { /-{21}[a-f0-9]{42}/ }
4 subject(:form_data) { HTTP::FormData::Multipart.new params }
5
6 describe "#content_type" do
7 subject { form_data.content_type }
8 it { is_expected.to match(/^multipart\/form-data; boundary=#{boundary}$/) }
9 end
10
11 describe "#content_length" do
12 subject { form_data.content_length }
13 it { is_expected.to eq form_data.to_s.bytesize }
14 end
15
16 describe "#to_s" do
17 def disposition(params)
18 params = params.map { |k, v| "#{k}=#{v.inspect}" }.join("; ")
19 "Content-Disposition: form-data; #{params}"
20 end
21
22 let(:crlf) { "\r\n" }
23
24 it "properly generates multipart data" do
25 boundary_value = form_data.content_type[/(#{boundary})$/, 1]
26
27 expect(form_data.to_s).to eq [
28 "--#{boundary_value}#{crlf}",
29 "#{disposition 'name' => 'foo'}#{crlf}",
30 "#{crlf}bar#{crlf}",
31 "--#{boundary_value}#{crlf}",
32 "#{disposition 'name' => 'baz', 'filename' => file.filename}#{crlf}",
33 "Content-Type: #{file.mime_type}#{crlf}",
34 "#{crlf}#{file}#{crlf}",
35 "--#{boundary_value}--"
36 ].join("")
37 end
38 end
39 end
0 # coding: utf-8
1
2 RSpec.describe HTTP::FormData::Urlencoded do
3 let(:data) { { "foo[bar]" => "test" } }
4 subject(:form_data) { HTTP::FormData::Urlencoded.new data }
5
6 describe "#content_type" do
7 subject { form_data.content_type }
8 it { is_expected.to eq "application/x-www-form-urlencoded" }
9 end
10
11 describe "#content_length" do
12 subject { form_data.content_length }
13 it { is_expected.to eq form_data.to_s.bytesize }
14
15 context "with unicode chars" do
16 let(:data) { { "foo[bar]" => "тест" } }
17 it { is_expected.to eq form_data.to_s.bytesize }
18 end
19 end
20
21 describe "#to_s" do
22 subject { form_data.to_s }
23 it { is_expected.to eq "foo%5Bbar%5D=test" }
24
25 context "with unicode chars" do
26 let(:data) { { "foo[bar]" => "тест" } }
27 it { is_expected.to eq "foo%5Bbar%5D=%D1%82%D0%B5%D1%81%D1%82" }
28 end
29 end
30 end
0 RSpec.describe HTTP::FormData do
1 describe ".create" do
2 subject { HTTP::FormData.create params }
3
4 context "when form has no files" do
5 let(:params) { { :foo => :bar } }
6 it { is_expected.to be_a HTTP::FormData::Urlencoded }
7 end
8
9 context "when form has at least one file param" do
10 let(:gemspec) { HTTP::FormData::File.new "gemspec" }
11 let(:params) { { :foo => :bar, :baz => gemspec } }
12 it { is_expected.to be_a HTTP::FormData::Multipart }
13 end
14
15 context "when form has file in an array param" do
16 let(:gemspec) { HTTP::FormData::File.new "gemspec" }
17 let(:params) { { :foo => :bar, :baz => [gemspec] } }
18 it { is_expected.to be_a HTTP::FormData::Multipart }
19 end
20 end
21
22 describe ".ensure_hash" do
23 subject(:ensure_hash) { HTTP::FormData.ensure_hash data }
24
25 context "when Hash given" do
26 let(:data) { { :foo => :bar } }
27 it { is_expected.to eq :foo => :bar }
28 end
29
30 context "when #to_h given" do
31 let(:data) { double(:to_h => { :foo => :bar }) }
32 it { is_expected.to eq :foo => :bar }
33 end
34
35 context "when nil given" do
36 let(:data) { nil }
37 it { is_expected.to eq({}) }
38 end
39
40 context "when neither Hash nor #to_h given" do
41 let(:data) { double }
42 it "fails with HTTP::FormData::Error" do
43 expect { ensure_hash }.to raise_error HTTP::FormData::Error
44 end
45 end
46 end
47 end
0 # coding: utf-8
1
2 require "simplecov"
3 require "coveralls"
4
5 SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6 SimpleCov::Formatter::HTMLFormatter,
7 Coveralls::SimpleCov::Formatter
8 ]
9
10 SimpleCov.start { add_filter "/spec/" }
11
12 require "http/form_data"
13 require "support/fixtures_helper"
14
15 # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16 RSpec.configure do |config|
17 config.expect_with :rspec do |expectations|
18 # This option will default to `true` in RSpec 4. It makes the `description`
19 # and `failure_message` of custom matchers include text for helper methods
20 # defined using `chain`, e.g.:
21 # be_bigger_than(2).and_smaller_than(4).description
22 # # => "be bigger than 2 and smaller than 4"
23 # ...rather than:
24 # # => "be bigger than 2"
25 expectations.include_chain_clauses_in_custom_matcher_descriptions = true
26 end
27
28 config.mock_with :rspec do |mocks|
29 # Prevents you from mocking or stubbing a method that does not exist on
30 # a real object. This is generally recommended, and will default to
31 # `true` in RSpec 4.
32 mocks.verify_partial_doubles = true
33 end
34
35 # These two settings work together to allow you to limit a spec run
36 # to individual examples or groups you care about by tagging them with
37 # `:focus` metadata. When nothing is tagged with `:focus`, all examples
38 # get run.
39 config.filter_run :focus
40 config.run_all_when_everything_filtered = true
41
42 # Limits the available syntax to the non-monkey patched syntax that is
43 # recommended. For more details, see:
44 # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
45 # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
46 # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
47 config.disable_monkey_patching!
48
49 # This setting enables warnings. It's recommended, but in some cases may
50 # be too noisy due to issues in dependencies.
51 config.warnings = true
52
53 # Many RSpec users commonly either run the entire suite or an individual
54 # file, and it's useful to allow more verbose output when running an
55 # individual spec file.
56 if config.files_to_run.one?
57 # Use the documentation formatter for detailed output,
58 # unless a formatter has already been configured
59 # (e.g. via a command-line flag).
60 config.default_formatter = "doc"
61 end
62
63 # Print the 10 slowest examples and example groups at the
64 # end of the spec run, to help surface which specs are running
65 # particularly slow.
66 config.profile_examples = 10
67
68 # Run specs in random order to surface order dependencies. If you find an
69 # order dependency and want to debug it, you can fix the order by providing
70 # the seed, which is printed after each run.
71 # --seed 1234
72 config.order = :random
73
74 # Seed global randomization in this process using the `--seed` CLI option.
75 # Setting this allows you to use `--seed` to deterministically reproduce
76 # test failures related to randomization by passing the same `--seed` value
77 # as the one that triggered the failure.
78 Kernel.srand config.seed
79
80 # Include common helpers
81 config.include FixturesHelper
82 end
0 # coding: utf-8
1
2 require "pathname"
3
4 module FixturesHelper
5 def fixture(filename)
6 fixtures_root.join filename
7 end
8
9 def fixtures_root
10 @fixtures_root ||= Pathname.new(__FILE__).join("../../fixtures").realpath
11 end
12 end