1
0
Fork 0
mirror of https://github.com/rest-client/rest-client.git synced 2022-11-09 13:49:40 -05:00
rest-client--rest-client/spec/unit/utils_spec.rb

148 lines
5.4 KiB
Ruby
Raw Normal View History

require_relative '_lib'
describe RestClient::Utils do
describe '.get_encoding_from_headers' do
it 'assumes no encoding by default for text' do
headers = {:content_type => 'text/plain'}
expect(RestClient::Utils.get_encoding_from_headers(headers)).
to eq nil
end
it 'returns nil on failures' do
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'blah'})).to eq nil
expect(RestClient::Utils.get_encoding_from_headers(
{})).to eq nil
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'foo; bar=baz'})).to eq nil
end
it 'handles various charsets' do
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'text/plain; charset=UTF-8'})).to eq 'UTF-8'
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'application/json; charset=ISO-8859-1'})).
to eq 'ISO-8859-1'
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'text/html; charset=windows-1251'})).
to eq 'windows-1251'
expect(RestClient::Utils.get_encoding_from_headers(
{:content_type => 'text/html; charset="UTF-16"'})).
to eq 'UTF-16'
end
end
describe '.cgi_parse_header' do
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
it 'parses headers', :unless => RUBY_VERSION.start_with?('2.0') do
expect(RestClient::Utils.cgi_parse_header('text/plain')).
to eq ['text/plain', {}]
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
expect(RestClient::Utils.cgi_parse_header('text/vnd.just.made.this.up')).
to eq ['text/vnd.just.made.this.up', {}]
expect(RestClient::Utils.cgi_parse_header('text/plain;charset=us-ascii')).
to eq ['text/plain', {'charset' => 'us-ascii'}]
expect(RestClient::Utils.cgi_parse_header('text/plain ; charset="us-ascii"')).
to eq ['text/plain', {'charset' => 'us-ascii'}]
expect(RestClient::Utils.cgi_parse_header(
'text/plain ; charset="us-ascii"; another=opt')).
to eq ['text/plain', {'charset' => 'us-ascii', 'another' => 'opt'}]
expect(RestClient::Utils.cgi_parse_header(
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
'foo/bar; filename="silly.txt"')).
to eq ['foo/bar', {'filename' => 'silly.txt'}]
expect(RestClient::Utils.cgi_parse_header(
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
'foo/bar; filename="strange;name"')).
to eq ['foo/bar', {'filename' => 'strange;name'}]
expect(RestClient::Utils.cgi_parse_header(
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
'foo/bar; filename="strange;name";size=123')).to eq \
['foo/bar', {'filename' => 'strange;name', 'size' => '123'}]
expect(RestClient::Utils.cgi_parse_header(
Add dependency on http-accept for Content-Type. The previous "Content-Type" header parser was ported from Python and was not very idiomatic Ruby. While fast and correct per the RFCs, it was triggering bugs in Ruby MRI that we could probably work around. Ideally someone would fix the bugs in Ruby MRI, but I haven't had time to track them down. Switch to using HTTP::Accept for parsing the media-type charset out of the "Content-Type" header. Also relax the tests since HTTP::Accept is somewhat stricter in the input it will accept. As a result, rest-client will now ignore Content-Type headers with a trailing `;` character. (This is invalid per the RFCs, so impact is likely to be small in comparison to fixing the Ruby 2.4 memory leak.) I also tried using https://github.com/httprb/content_type.rb but it is significantly slower (caused 2x blowup in time on a simple benchmark) and doesn't correctly handle content-types containing '.' characters. Fixes: #523 (occasional MRI segfault) Fixes: #611 (MRI 2.4.* memory leak) * Unfortunately, HTTP::Accept does not support Ruby 2.0 due to its use of named capture groups in StringScanner, which was added in Ruby 2.1. Because rest-client still supports Ruby 2.0, fall back on the old logic when running on Ruby 2.0. Even though Ruby 2.0 is unsupported, it probably still sees wide use since it is the system Ruby even on macOS Sierra. * Don't bother running tests for .cgi_parse_header on Ruby 2.0. Still keep the higher level tests that will exercise the deprecated code.
2017-07-04 23:46:03 -04:00
'foo/bar; name="files"; filename="fo\\"o;bar"')).to eq \
['foo/bar', {'name' => 'files', 'filename' => 'fo"o;bar'}]
end
end
describe '.encode_query_string' do
it 'handles simple hashes' do
{
{foo: 123, bar: 456} => 'foo=123&bar=456',
{'foo' => 123, 'bar' => 456} => 'foo=123&bar=456',
{foo: 'abc', bar: 'one two'} => 'foo=abc&bar=one+two',
{escaped: '1+2=3'} => 'escaped=1%2B2%3D3',
{'escaped + key' => 'foo'} => 'escaped+%2B+key=foo',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles simple arrays' do
{
{foo: [1, 2, 3]} => 'foo[]=1&foo[]=2&foo[]=3',
{foo: %w{a b c}, bar: [1, 2, 3]} => 'foo[]=a&foo[]=b&foo[]=c&bar[]=1&bar[]=2&bar[]=3',
{foo: ['one two', 3]} => 'foo[]=one+two&foo[]=3',
{'a+b' => [1,2,3]} => 'a%2Bb[]=1&a%2Bb[]=2&a%2Bb[]=3',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles nested hashes' do
{
{outer: {foo: 123, bar: 456}} => 'outer[foo]=123&outer[bar]=456',
{outer: {foo: [1, 2, 3], bar: 'baz'}} => 'outer[foo][]=1&outer[foo][]=2&outer[foo][]=3&outer[bar]=baz',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles null and empty values' do
{
{string: '', empty: nil, list: [], hash: {}, falsey: false } =>
'string=&empty&list&hash&falsey=false',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles nested nulls' do
{
{foo: {string: '', empty: nil}} => 'foo[string]=&foo[empty]',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles deep nesting' do
{
{coords: [{x: 1, y: 0}, {x: 2}, {x: 3}]} => 'coords[][x]=1&coords[][y]=0&coords[][x]=2&coords[][x]=3',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles multiple fields with the same name using ParamsArray' do
{
RestClient::ParamsArray.new([[:foo, 1], [:foo, 2], [:foo, 3]]) => 'foo=1&foo=2&foo=3',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
it 'handles nested ParamsArrays' do
{
{foo: RestClient::ParamsArray.new([[:a, 1], [:a, 2]])} => 'foo[a]=1&foo[a]=2',
RestClient::ParamsArray.new([[:foo, {a: 1}], [:foo, {a: 2}]]) => 'foo[a]=1&foo[a]=2',
}.each_pair do |input, expected|
expect(RestClient::Utils.encode_query_string(input)).to eq expected
end
end
end
end