xenon-routing 0.0.4 → 0.0.5

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/{xenon-routing/lib → lib}/xenon/api.rb +20 -11
  3. data/{xenon-routing/lib → lib}/xenon/marshallers.rb +24 -14
  4. data/{xenon-routing/lib → lib}/xenon/request.rb +10 -2
  5. data/{xenon-routing/lib → lib}/xenon/response.rb +0 -0
  6. data/{xenon-routing/lib → lib}/xenon/routing.rb +0 -0
  7. data/{xenon-routing/lib → lib}/xenon/routing/context.rb +0 -0
  8. data/{xenon-routing/lib → lib}/xenon/routing/directives.rb +1 -0
  9. data/{xenon-routing/lib → lib}/xenon/routing/header_directives.rb +0 -0
  10. data/lib/xenon/routing/marshalling_directives.rb +24 -0
  11. data/{xenon-routing/lib → lib}/xenon/routing/method_directives.rb +10 -4
  12. data/{xenon-routing/lib → lib}/xenon/routing/param_directives.rb +0 -0
  13. data/{xenon-routing/lib → lib}/xenon/routing/path_directives.rb +0 -0
  14. data/{xenon-routing/lib → lib}/xenon/routing/route_directives.rb +0 -0
  15. data/{xenon-routing/lib → lib}/xenon/routing/security_directives.rb +6 -0
  16. data/{xenon-routing/lib → lib}/xenon/routing_version.rb +0 -0
  17. data/{xenon-http/spec → spec}/spec_helper.rb +0 -0
  18. data/{xenon-routing/xenon-routing.gemspec → xenon-routing.gemspec} +2 -2
  19. metadata +25 -80
  20. data/.codeclimate.yml +0 -18
  21. data/.gitignore +0 -25
  22. data/.rspec +0 -3
  23. data/.travis.yml +0 -6
  24. data/Gemfile +0 -20
  25. data/Guardfile +0 -16
  26. data/LICENSE +0 -22
  27. data/README.md +0 -116
  28. data/Rakefile +0 -40
  29. data/VERSION +0 -1
  30. data/examples/hello_world/config.ru +0 -3
  31. data/examples/hello_world/hello_world.rb +0 -27
  32. data/xenon-http/lib/xenon/auth.rb +0 -63
  33. data/xenon-http/lib/xenon/errors.rb +0 -5
  34. data/xenon-http/lib/xenon/etag.rb +0 -48
  35. data/xenon-http/lib/xenon/headers.rb +0 -112
  36. data/xenon-http/lib/xenon/headers/accept.rb +0 -34
  37. data/xenon-http/lib/xenon/headers/accept_charset.rb +0 -59
  38. data/xenon-http/lib/xenon/headers/accept_encoding.rb +0 -63
  39. data/xenon-http/lib/xenon/headers/accept_language.rb +0 -59
  40. data/xenon-http/lib/xenon/headers/authorization.rb +0 -50
  41. data/xenon-http/lib/xenon/headers/cache_control.rb +0 -56
  42. data/xenon-http/lib/xenon/headers/content_type.rb +0 -23
  43. data/xenon-http/lib/xenon/headers/if_match.rb +0 -53
  44. data/xenon-http/lib/xenon/headers/if_modified_since.rb +0 -22
  45. data/xenon-http/lib/xenon/headers/if_none_match.rb +0 -53
  46. data/xenon-http/lib/xenon/headers/if_range.rb +0 -45
  47. data/xenon-http/lib/xenon/headers/if_unmodified_since.rb +0 -22
  48. data/xenon-http/lib/xenon/headers/user_agent.rb +0 -65
  49. data/xenon-http/lib/xenon/headers/www_authenticate.rb +0 -71
  50. data/xenon-http/lib/xenon/http.rb +0 -7
  51. data/xenon-http/lib/xenon/http_version.rb +0 -3
  52. data/xenon-http/lib/xenon/media_type.rb +0 -162
  53. data/xenon-http/lib/xenon/parsers/basic_rules.rb +0 -86
  54. data/xenon-http/lib/xenon/parsers/header_rules.rb +0 -60
  55. data/xenon-http/lib/xenon/parsers/media_type.rb +0 -53
  56. data/xenon-http/lib/xenon/quoted_string.rb +0 -20
  57. data/xenon-http/spec/xenon/etag_spec.rb +0 -19
  58. data/xenon-http/spec/xenon/headers/accept_charset_spec.rb +0 -31
  59. data/xenon-http/spec/xenon/headers/accept_encoding_spec.rb +0 -40
  60. data/xenon-http/spec/xenon/headers/accept_language_spec.rb +0 -33
  61. data/xenon-http/spec/xenon/headers/accept_spec.rb +0 -54
  62. data/xenon-http/spec/xenon/headers/authorization_spec.rb +0 -47
  63. data/xenon-http/spec/xenon/headers/cache_control_spec.rb +0 -64
  64. data/xenon-http/spec/xenon/headers/if_match_spec.rb +0 -73
  65. data/xenon-http/spec/xenon/headers/if_modified_since_spec.rb +0 -19
  66. data/xenon-http/spec/xenon/headers/if_none_match_spec.rb +0 -79
  67. data/xenon-http/spec/xenon/headers/if_range_spec.rb +0 -45
  68. data/xenon-http/spec/xenon/headers/if_unmodified_since_spec.rb +0 -19
  69. data/xenon-http/spec/xenon/headers/user_agent_spec.rb +0 -67
  70. data/xenon-http/spec/xenon/headers/www_authenticate_spec.rb +0 -43
  71. data/xenon-http/spec/xenon/media_type_spec.rb +0 -267
  72. data/xenon-http/xenon-http.gemspec +0 -25
  73. data/xenon-routing/spec/spec_helper.rb +0 -94
  74. data/xenon.gemspec +0 -26
@@ -1,60 +0,0 @@
1
- require 'xenon/quoted_string'
2
- require 'xenon/parsers/basic_rules'
3
-
4
- module Xenon
5
- module Parsers
6
-
7
- module HeaderRules
8
- include Parslet, BasicRules
9
-
10
- # http://tools.ietf.org/html/rfc7230#section-3.2.6
11
- rule(:list_sep) { str(',') >> sp? }
12
- rule(:param_sep) { str(';') >> sp? }
13
- rule(:obs_text) { match(/[\u0080-\u00ff]/)}
14
- rule(:qdtext) { htab | sp | match(/[\u0021\u0023-\u005b\u005d-\u007e]/) | obs_text }
15
- rule(:quoted_pair) { str('\\') >> (htab | sp | vchar | obs_text) }
16
- rule(:quoted_string) { (dquote >> (qdtext | quoted_pair).repeat >> dquote).as(:quoted_string) }
17
- rule(:ctext) { htab | sp | match(/[\u0021-\u0027\u002a-\u005b\u005d-\u007e]/) | obs_text }
18
- rule(:comment) { (str('(') >> (ctext | quoted_pair | comment).repeat >> str(')')).as(:comment) }
19
-
20
- # http://tools.ietf.org/html/rfc7231#section-5.3.1
21
- rule(:weight_value) { (digit >> (str('.') >> digit.repeat(0, 3)).maybe).as(:q) }
22
- rule(:weight) { param_sep >> str('q') >> sp? >> str('=') >> sp? >> weight_value >> sp? }
23
- end
24
-
25
- module AuthHeaderRules
26
- include Parslet, HeaderRules
27
-
28
- rule(:token68) { ((alpha | digit | match(/[\-\._~\+\/]/)) >> str('=').repeat).repeat(1).as(:token) }
29
- rule(:auth_scheme) { token.as(:auth_scheme) }
30
- rule(:name) { token.as(:name) }
31
- rule(:value) { token.as(:value) }
32
- rule(:auth_param) { (name >> bws >> str('=') >> bws >> (token | quoted_string).as(:value)).as(:auth_param) }
33
- rule(:auth_params) { (auth_param.maybe >> (ows >> comma >> ows >> auth_param).repeat).as(:auth_params) }
34
- end
35
-
36
- module ETagHeaderRules
37
- include Parslet, HeaderRules
38
-
39
- # http://tools.ietf.org/html/rfc7232#section-2.3
40
- rule(:wildcard) { str('*').as(:wildcard) }
41
- rule(:weak) { str('W/').as(:weak) }
42
- rule(:etagc) { str('!') | match(/[\u0023-\u007e#-~]/) | obs_text }
43
- rule(:opaque_tag) { dquote >> etagc.repeat.as(:opaque_tag) >> dquote }
44
- rule(:etag) { (weak.maybe >> opaque_tag).as(:etag) }
45
- end
46
-
47
- class HeaderTransform < BasicTransform
48
- using QuotedString
49
-
50
- rule(quoted_string: simple(:qs)) { qs.unquote }
51
- rule(comment: simple(:c)) { c.uncomment }
52
- end
53
-
54
- class ETagHeaderTransform < HeaderTransform
55
- rule(etag: { opaque_tag: simple(:t), weak: simple(:w) }) { Xenon::ETag.new(t, weak: true) }
56
- rule(etag: { opaque_tag: simple(:t) }) { Xenon::ETag.new(t) }
57
- end
58
-
59
- end
60
- end
@@ -1,53 +0,0 @@
1
- require 'xenon/parsers/basic_rules'
2
-
3
- module Xenon
4
- module Parsers
5
-
6
- # note this uses the rules from https://tools.ietf.org/html/rfc6838 not http://tools.ietf.org/html/rfc7231
7
- # because the latter is slightly ambiguous, e.g. a token can include * so */json would parse correctly
8
- module MediaTypeRules
9
- include Parslet, BasicRules
10
-
11
- rule(:restricted_name_first) { match(/[a-zA-Z0-9]/) }
12
- rule(:restricted_name_chars) { match(/[a-zA-Z0-9!#\$&\-\^_\.\+]/).repeat(0, 126) }
13
- rule(:restricted_name) { restricted_name_first >> restricted_name_chars }
14
-
15
- rule(:type) { restricted_name.as(:type) }
16
- rule(:slash) { str('/') }
17
- rule(:subtype) { restricted_name.as(:subtype) >> sp? }
18
-
19
- rule(:param_sep) { str(';') >> sp? }
20
- rule(:param_name) { restricted_name.as(:param_name) >> sp? }
21
- rule(:equals) { str('=') >> sp? }
22
- rule(:param_value) { token.as(:param_value) >> sp? } # not quite correct but probably correct enough
23
- rule(:param) { param_sep >> param_name >> (equals >> param_value).maybe >> sp? }
24
- rule(:params) { param.repeat.as(:params) }
25
-
26
- rule(:media_type) { (type >> slash >> subtype >> params).as(:media_type) >> sp? }
27
-
28
- rule(:wildcard) { str('*') }
29
- rule(:wild_media_range) { wildcard.as(:type) >> slash >> wildcard.as(:subtype) >> params }
30
- rule(:root_media_range) { type >> slash >> (wildcard.as(:subtype) | subtype) >> params }
31
- rule(:media_range) { (wild_media_range | root_media_range).as(:media_range) >> sp? }
32
- end
33
-
34
- class MediaType < Parslet::Parser
35
- include MediaTypeRules
36
- root(:media_type)
37
- end
38
-
39
- class MediaRange < Parslet::Parser
40
- include MediaTypeRules
41
- root(:media_range)
42
- end
43
-
44
- class MediaTypeTransform < Parslet::Transform
45
- rule(param_name: simple(:n), param_value: simple(:v)) { [n.str, v.str] }
46
- rule(param_name: simple(:n)) { [n.str, nil] }
47
- rule(type: simple(:t), subtype: simple(:s), params: subtree(:p)) { { type: t.str, subtype: s.str, params: Hash[p] } }
48
- rule(media_type: subtree(:mt)) { Xenon::MediaType.new(mt[:type], mt[:subtype], mt[:params])}
49
- rule(media_range: subtree(:mr)) { Xenon::MediaRange.new(mr[:type], mr[:subtype], mr[:params])}
50
- end
51
-
52
- end
53
- end
@@ -1,20 +0,0 @@
1
- module Xenon
2
- module QuotedString
3
- refine String do
4
- def quote
5
- qs = gsub(/([\\"])/, '\\\\\1')
6
- self == qs ? self : %{"#{qs}"}
7
- end
8
-
9
- def unquote
10
- qs = start_with?('"') && end_with?('"') ? self[1..-2] : self
11
- qs.gsub(/\\(.)/, '\1')
12
- end
13
-
14
- def uncomment
15
- qs = start_with?('(') && end_with?(')') ? self[1..-2] : self
16
- qs.gsub(/\\(.)/, '\1')
17
- end
18
- end
19
- end
20
- end
@@ -1,19 +0,0 @@
1
- require 'xenon/etag'
2
-
3
- describe Xenon::ETag do
4
-
5
- describe '::parse' do
6
- it 'can parse a strong etag' do
7
- etag = Xenon::ETag.parse('"xyzzy"')
8
- expect(etag.opaque_tag).to eq 'xyzzy'
9
- expect(etag).to be_strong
10
- end
11
-
12
- it 'can parse a weak etag' do
13
- etag = Xenon::ETag.parse('W/"xyzzy"')
14
- expect(etag.opaque_tag).to eq 'xyzzy'
15
- expect(etag).to be_weak
16
- end
17
- end
18
-
19
- end
@@ -1,31 +0,0 @@
1
- require 'xenon/headers/accept_charset'
2
-
3
- describe Xenon::Headers::AcceptCharset do
4
-
5
- context '::parse' do
6
- it 'can parse a basic charset range' do
7
- header = Xenon::Headers::AcceptCharset.parse('unicode-1-1;q=0.8')
8
- expect(header.charset_ranges.size).to eq(1)
9
- expect(header.charset_ranges[0].to_s).to eq('unicode-1-1; q=0.8')
10
- end
11
-
12
- it 'can parse the example from RFC 7231 § 5.3.3 with the right precedence' do
13
- header = Xenon::Headers::AcceptCharset.parse('iso-8859-5, unicode-1-1;q=0.8')
14
- expect(header.charset_ranges.size).to eq(2)
15
- expect(header.charset_ranges[0].to_s).to eq('iso-8859-5')
16
- expect(header.charset_ranges[1].to_s).to eq('unicode-1-1; q=0.8')
17
- end
18
- end
19
-
20
- context '#merge' do
21
- it 'can merge two headers with the right precedence' do
22
- h1 = Xenon::Headers::AcceptCharset.parse('unicode-1-1;q=0.8')
23
- h2 = Xenon::Headers::AcceptCharset.parse('iso-8859-5')
24
- header = h1.merge(h2)
25
- expect(header.charset_ranges.size).to eq(2)
26
- expect(header.charset_ranges[0].to_s).to eq('iso-8859-5')
27
- expect(header.charset_ranges[1].to_s).to eq('unicode-1-1; q=0.8')
28
- end
29
- end
30
-
31
- end
@@ -1,40 +0,0 @@
1
- require 'xenon/headers/accept_encoding'
2
-
3
- describe Xenon::Headers::AcceptEncoding do
4
-
5
- context '::parse' do
6
- %w(identity compress x-compress deflate gzip x-gzip *).each do |cc|
7
- it "can parse the #{cc} content coding" do
8
- header = Xenon::Headers::AcceptEncoding.parse(cc)
9
- expect(header.coding_ranges.size).to eq(1)
10
- expect(header.coding_ranges[0].to_s).to eq(cc)
11
- end
12
- end
13
-
14
- it 'can parse the fifth example from RFC 7231 § 5.3.4 with the right precedence' do
15
- header = Xenon::Headers::AcceptEncoding.parse('gzip;q=1.0, identity; q=0.5, *;q=0')
16
- expect(header.coding_ranges.size).to eq(3)
17
- expect(header.coding_ranges[0].to_s).to eq('gzip')
18
- expect(header.coding_ranges[1].to_s).to eq('identity; q=0.5')
19
- expect(header.coding_ranges[2].to_s).to eq('*; q=0.0')
20
- end
21
-
22
- it 'parses an empty header as containing no codings' do
23
- header = Xenon::Headers::AcceptEncoding.parse('')
24
- expect(header.coding_ranges.size).to eq(0)
25
- end
26
- end
27
-
28
- context '#merge' do
29
- it 'can merge two headers with the right precedence' do
30
- h1 = Xenon::Headers::AcceptEncoding.parse('identity; q=0.5')
31
- h2 = Xenon::Headers::AcceptEncoding.parse('gzip;q=1.0, *;q=0')
32
- header = h1.merge(h2)
33
- expect(header.coding_ranges.size).to eq(3)
34
- expect(header.coding_ranges[0].to_s).to eq('gzip')
35
- expect(header.coding_ranges[1].to_s).to eq('identity; q=0.5')
36
- expect(header.coding_ranges[2].to_s).to eq('*; q=0.0')
37
- end
38
- end
39
-
40
- end
@@ -1,33 +0,0 @@
1
- require 'xenon/headers/accept_language'
2
-
3
- describe Xenon::Headers::AcceptLanguage do
4
-
5
- context '::parse' do
6
- it 'can parse a basic language range' do
7
- header = Xenon::Headers::AcceptLanguage.parse('en-gb;q=0.8')
8
- expect(header.language_ranges.size).to eq(1)
9
- expect(header.language_ranges[0].to_s).to eq('en-gb; q=0.8')
10
- end
11
-
12
- it 'can parse the example from RFC 7231 § 5.3.5 with the right precedence' do
13
- header = Xenon::Headers::AcceptLanguage.parse('da, en-gb;q=0.8, en;q=0.7')
14
- expect(header.language_ranges.size).to eq(3)
15
- expect(header.language_ranges[0].to_s).to eq('da')
16
- expect(header.language_ranges[1].to_s).to eq('en-gb; q=0.8')
17
- expect(header.language_ranges[2].to_s).to eq('en; q=0.7')
18
- end
19
- end
20
-
21
- context '#merge' do
22
- it 'can merge two headers with the right precedence' do
23
- h1 = Xenon::Headers::AcceptLanguage.parse('da, en;q=0.7')
24
- h2 = Xenon::Headers::AcceptLanguage.parse('en-gb;q=0.8')
25
- header = h1.merge(h2)
26
- expect(header.language_ranges.size).to eq(3)
27
- expect(header.language_ranges[0].to_s).to eq('da')
28
- expect(header.language_ranges[1].to_s).to eq('en-gb; q=0.8')
29
- expect(header.language_ranges[2].to_s).to eq('en; q=0.7')
30
- end
31
- end
32
-
33
- end
@@ -1,54 +0,0 @@
1
- require 'xenon/headers/accept'
2
-
3
- describe Xenon::Headers::Accept do
4
-
5
- context '::parse' do
6
- it 'can parse a basic accept range' do
7
- header = Xenon::Headers::Accept.parse('text/plain; q=0.5')
8
- expect(header.media_ranges.size).to eq(1)
9
- expect(header.media_ranges[0].to_s).to eq('text/plain; q=0.5')
10
- end
11
-
12
- it 'can parse the first example from RFC 7231 § 5.3.2 with the right precedence' do
13
- header = Xenon::Headers::Accept.parse('text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c')
14
- expect(header.media_ranges.size).to eq(4)
15
- expect(header.media_ranges[0].to_s).to eq('text/html')
16
- expect(header.media_ranges[1].to_s).to eq('text/x-c')
17
- expect(header.media_ranges[2].to_s).to eq('text/x-dvi; q=0.8')
18
- expect(header.media_ranges[3].to_s).to eq('text/plain; q=0.5')
19
- end
20
-
21
- it 'can parse the second example from RFC 7231 § 5.3.2 with the right precedence' do
22
- header = Xenon::Headers::Accept.parse('text/*, text/plain, text/plain;format=flowed, */*')
23
- expect(header.media_ranges.size).to eq(4)
24
- expect(header.media_ranges[0].to_s).to eq('text/plain; format=flowed')
25
- expect(header.media_ranges[1].to_s).to eq('text/plain')
26
- expect(header.media_ranges[2].to_s).to eq('text/*')
27
- expect(header.media_ranges[3].to_s).to eq('*/*')
28
- end
29
-
30
- it 'can parse the third example from RFC 7231 § 5.3.2 with the right precedence' do
31
- header = Xenon::Headers::Accept.parse('text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
32
- expect(header.media_ranges.size).to eq(5)
33
- expect(header.media_ranges[0].to_s).to eq('text/html; level=1')
34
- expect(header.media_ranges[1].to_s).to eq('text/html; level=2; q=0.4')
35
- expect(header.media_ranges[2].to_s).to eq('text/html; q=0.7')
36
- expect(header.media_ranges[3].to_s).to eq('text/*; q=0.3')
37
- expect(header.media_ranges[4].to_s).to eq('*/*; q=0.5')
38
- end
39
- end
40
-
41
- context '#merge' do
42
- it 'can merge two headers with the right precedence' do
43
- h1 = Xenon::Headers::Accept.parse('text/plain; q=0.5, text/html')
44
- h2 = Xenon::Headers::Accept.parse('text/x-c, text/x-dvi; q=0.8')
45
- header = h1.merge(h2)
46
- expect(header.media_ranges.size).to eq(4)
47
- expect(header.media_ranges[0].to_s).to eq('text/html')
48
- expect(header.media_ranges[1].to_s).to eq('text/x-c')
49
- expect(header.media_ranges[2].to_s).to eq('text/x-dvi; q=0.8')
50
- expect(header.media_ranges[3].to_s).to eq('text/plain; q=0.5')
51
- end
52
- end
53
-
54
- end
@@ -1,47 +0,0 @@
1
- require 'xenon/headers/authorization'
2
-
3
- describe Xenon::Headers::Authorization do
4
-
5
- context '::parse' do
6
- it 'can parse Basic credentials' do
7
- header = Xenon::Headers::Authorization.parse('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==')
8
- expect(header.credentials.class).to eq(Xenon::BasicCredentials)
9
- expect(header.credentials.username).to eq('Aladdin')
10
- expect(header.credentials.password).to eq('open sesame')
11
- end
12
-
13
- it 'can parse Digest credentials' do
14
- header = Xenon::Headers::Authorization.parse('Digest username="Mufasa"' +
15
- ', realm="testrealm@host.com"' +
16
- ', nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"' +
17
- ', uri="/dir/index.html"' +
18
- ', qop=auth' +
19
- ', nc=00000001' +
20
- ', cnonce="0a4f113b"' +
21
- ', response="6629fae49393a05397450978507c4ef1"' +
22
- ', opaque="5ccc069c403ebaf9f0171e9517f40e41"')
23
- expect(header.credentials.class).to eq(Xenon::GenericCredentials)
24
- expect(header.credentials.scheme).to eq('Digest')
25
- expect(header.credentials.token).to eq(nil)
26
- expect(header.credentials.params).to eq(
27
- 'username' => 'Mufasa',
28
- 'realm' => 'testrealm@host.com',
29
- 'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
30
- 'uri' => '/dir/index.html',
31
- 'qop' => 'auth',
32
- 'nc' => '00000001',
33
- 'cnonce' => '0a4f113b',
34
- 'response' => '6629fae49393a05397450978507c4ef1',
35
- 'opaque' => '5ccc069c403ebaf9f0171e9517f40e41')
36
- end
37
-
38
- it 'can parse Bearer credentials' do
39
- header = Xenon::Headers::Authorization.parse('Bearer eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.')
40
- expect(header.credentials.class).to eq(Xenon::GenericCredentials)
41
- expect(header.credentials.scheme).to eq('Bearer')
42
- expect(header.credentials.token).to eq('eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.')
43
- expect(header.credentials.params).to eq({})
44
- end
45
- end
46
-
47
- end
@@ -1,64 +0,0 @@
1
- require 'xenon/headers/cache_control'
2
-
3
- describe Xenon::Headers::CacheControl do
4
-
5
- context '::parse' do
6
- ['max-age', 'max-stale', 'min-fresh', 's-maxage'].each do |dir|
7
- it "can parse the #{dir} directive" do
8
- header = Xenon::Headers::CacheControl.parse("#{dir}=5")
9
- expect(header.directives.size).to eq(1)
10
- expect(header.directives[0].to_s).to eq("#{dir}=5")
11
- end
12
-
13
- it "can parse the #{dir} directive with a quoted value" do # should not be sent by clients but is permitted
14
- header = Xenon::Headers::CacheControl.parse("#{dir}=\"5\"")
15
- expect(header.directives.size).to eq(1)
16
- expect(header.directives[0].to_s).to eq("#{dir}=5")
17
- end
18
- end
19
-
20
- ['no-cache', 'no-store', 'no-transform', 'only-if-cached', 'must-revalidate', 'public', 'proxy-revalidate'].each do |dir|
21
- it "can parse the #{dir} directive" do
22
- header = Xenon::Headers::CacheControl.parse("#{dir}")
23
- expect(header.directives.size).to eq(1)
24
- expect(header.directives[0].to_s).to eq("#{dir}")
25
- end
26
- end
27
-
28
- it "can parse the private directive with no field names" do
29
- header = Xenon::Headers::CacheControl.parse('private')
30
- expect(header.directives.size).to eq(1)
31
- expect(header.directives[0].to_s).to eq('private')
32
- end
33
-
34
- # TODO: private directive with field names
35
-
36
- it 'can parse extension directives with quoted string values' do
37
- header = Xenon::Headers::CacheControl.parse('ext="hello \"world\""')
38
- expect(header.directives.size).to eq(1)
39
- expect(header.directives[0].name).to eq('ext')
40
- expect(header.directives[0].value).to eq("hello \"world\"")
41
- end
42
-
43
- it 'can parse more complex directives' do
44
- header = Xenon::Headers::CacheControl.parse('public, max-age=3600, must-revalidate')
45
- expect(header.directives.size).to eq(3)
46
- expect(header.directives[0].to_s).to eq('public')
47
- expect(header.directives[1].to_s).to eq('max-age=3600')
48
- expect(header.directives[2].to_s).to eq('must-revalidate')
49
- end
50
- end
51
-
52
- context '#merge' do
53
- it 'can merge two headers and maintain directive order' do
54
- h1 = Xenon::Headers::CacheControl.parse('public, max-age=3600')
55
- h2 = Xenon::Headers::CacheControl.parse('must-revalidate')
56
- header = h1.merge(h2)
57
- expect(header.directives.size).to eq(3)
58
- expect(header.directives[0].to_s).to eq('public')
59
- expect(header.directives[1].to_s).to eq('max-age=3600')
60
- expect(header.directives[2].to_s).to eq('must-revalidate')
61
- end
62
- end
63
-
64
- end
@@ -1,73 +0,0 @@
1
- require 'xenon/headers/if_match'
2
-
3
- describe Xenon::Headers::IfMatch do
4
-
5
- context '::parse' do
6
- it 'can parse a single etag' do
7
- header = Xenon::Headers::IfMatch.parse('"xyzzy"')
8
- expect(header.etags.size).to eq(1)
9
- expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
10
- end
11
-
12
- it 'can parse multiple etags' do
13
- header = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx", "c3piozzzz"')
14
- expect(header.etags.size).to eq(3)
15
- expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
16
- expect(header.etags[1]).to eq(Xenon::ETag.new('r2d2xxxx'))
17
- expect(header.etags[2]).to eq(Xenon::ETag.new('c3piozzzz'))
18
- end
19
-
20
- it 'can parse a wildcard header' do
21
- header = Xenon::Headers::IfMatch.parse('*')
22
- expect(header.etags.size).to eq(0)
23
- end
24
- end
25
-
26
- context '#merge' do
27
- it 'can merge two headers and maintain etag order' do
28
- h1 = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx"')
29
- h2 = Xenon::Headers::IfMatch.parse('"c3piozzzz"')
30
- header = h1.merge(h2)
31
- expect(header.etags.size).to eq(3)
32
- expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
33
- expect(header.etags[1]).to eq(Xenon::ETag.new('r2d2xxxx'))
34
- expect(header.etags[2]).to eq(Xenon::ETag.new('c3piozzzz'))
35
- end
36
-
37
- it 'raises a protocol error when trying to merge into a wildcard header' do
38
- h1 = Xenon::Headers::IfMatch.parse('*')
39
- h2 = Xenon::Headers::IfMatch.parse('"c3piozzzz"')
40
- expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
41
- end
42
-
43
- it 'raises a protocol error when trying to merge a wildcard into a header' do
44
- h1 = Xenon::Headers::IfMatch.parse('"xyzzy"')
45
- h2 = Xenon::Headers::IfMatch.parse('*')
46
- expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
47
- end
48
-
49
- it 'raises a protocol error when trying to merge two wildcard headers' do
50
- h1 = Xenon::Headers::IfMatch.parse('*')
51
- h2 = Xenon::Headers::IfMatch.parse('*')
52
- expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
53
- end
54
- end
55
-
56
- context '#to_s' do
57
- it 'returns the string representation a single etag' do
58
- header = Xenon::Headers::IfMatch.parse('"xyzzy"')
59
- expect(header.to_s).to eq('"xyzzy"')
60
- end
61
-
62
- it 'returns the string representation of multiple etags' do
63
- header = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx", "c3piozzzz"')
64
- expect(header.to_s).to eq('"xyzzy", "r2d2xxxx", "c3piozzzz"')
65
- end
66
-
67
- it 'returns the string representation of a wildcard header' do
68
- header = Xenon::Headers::IfMatch.wildcard
69
- expect(header.to_s).to eq('*')
70
- end
71
- end
72
-
73
- end