refactor(hyper): add tests and refactor to increase coverage
This commit is contained in:
@@ -16,12 +16,15 @@ header! {
|
|||||||
#[doc="# Example values"]
|
#[doc="# Example values"]
|
||||||
#[doc="* `bytes`"]
|
#[doc="* `bytes`"]
|
||||||
#[doc="* `none`"]
|
#[doc="* `none`"]
|
||||||
|
#[doc="* `unknown-unit`"]
|
||||||
#[doc="```"]
|
#[doc="```"]
|
||||||
(AcceptRanges, "Accept-Ranges") => (RangeUnit)+
|
(AcceptRanges, "Accept-Ranges") => (RangeUnit)+
|
||||||
|
|
||||||
test_acccept_ranges {
|
test_acccept_ranges {
|
||||||
test_header!(test1, vec![b"bytes"]);
|
test_header!(test1, vec![b"bytes"]);
|
||||||
test_header!(test2, vec![b"none"]);
|
test_header!(test2, vec![b"none"]);
|
||||||
|
test_header!(test3, vec![b"unknown-unit"]);
|
||||||
|
test_header!(test4, vec![b"bytes, unknown-unit"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,9 @@
|
|||||||
use header::{Header, HeaderFormat};
|
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
|
||||||
pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
|
pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
|
||||||
|
|
||||||
/// `Connection` header, defined in [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.1)
|
|
||||||
///
|
|
||||||
/// The `Connection` header field allows the sender to indicate desired
|
|
||||||
/// control options for the current connection. In order to avoid
|
|
||||||
/// confusing downstream recipients, a proxy or gateway MUST remove or
|
|
||||||
/// replace any received connection options before forwarding the
|
|
||||||
/// message.
|
|
||||||
///
|
|
||||||
/// # ABNF
|
|
||||||
/// ```plain
|
|
||||||
/// Connection = 1#connection-option
|
|
||||||
/// connection-option = token
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Example values
|
|
||||||
/// * `close`
|
|
||||||
/// * `upgrade`
|
|
||||||
/// * `keep-alive`
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub struct Connection(pub Vec<ConnectionOption>);
|
|
||||||
|
|
||||||
deref!(Connection => Vec<ConnectionOption>);
|
|
||||||
|
|
||||||
/// Values that can be in the `Connection` header.
|
/// Values that can be in the `Connection` header.
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum ConnectionOption {
|
pub enum ConnectionOption {
|
||||||
@@ -50,11 +25,11 @@ pub enum ConnectionOption {
|
|||||||
impl FromStr for ConnectionOption {
|
impl FromStr for ConnectionOption {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<ConnectionOption, ()> {
|
fn from_str(s: &str) -> Result<ConnectionOption, ()> {
|
||||||
Ok(match s {
|
match s {
|
||||||
"keep-alive" => KeepAlive,
|
"keep-alive" => Ok(KeepAlive),
|
||||||
"close" => Close,
|
"close" => Ok(Close),
|
||||||
s => ConnectionHeader(UniCase(s.to_string())),
|
s => Ok(ConnectionHeader(UniCase(s.to_string())))
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,25 +38,36 @@ impl Display for ConnectionOption {
|
|||||||
f.write_str(match *self {
|
f.write_str(match *self {
|
||||||
KeepAlive => "keep-alive",
|
KeepAlive => "keep-alive",
|
||||||
Close => "close",
|
Close => "close",
|
||||||
ConnectionHeader(UniCase(ref s)) => s,
|
ConnectionHeader(UniCase(ref s)) => s.as_ref()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Header for Connection {
|
header! {
|
||||||
fn header_name() -> &'static str {
|
#[doc="`Connection` header, defined in"]
|
||||||
"Connection"
|
#[doc="[RFC7230](http://tools.ietf.org/html/rfc7230#section-6.1)"]
|
||||||
}
|
#[doc=""]
|
||||||
|
#[doc="The `Connection` header field allows the sender to indicate desired"]
|
||||||
|
#[doc="control options for the current connection. In order to avoid"]
|
||||||
|
#[doc="confusing downstream recipients, a proxy or gateway MUST remove or"]
|
||||||
|
#[doc="replace any received connection options before forwarding the"]
|
||||||
|
#[doc="message."]
|
||||||
|
#[doc=""]
|
||||||
|
#[doc="# ABNF"]
|
||||||
|
#[doc="```plain"]
|
||||||
|
#[doc="Connection = 1#connection-option"]
|
||||||
|
#[doc="connection-option = token"]
|
||||||
|
#[doc=""]
|
||||||
|
#[doc="# Example values"]
|
||||||
|
#[doc="* `close`"]
|
||||||
|
#[doc="* `keep-alive`"]
|
||||||
|
#[doc="* `upgrade`"]
|
||||||
|
(Connection, "Connection") => (ConnectionOption)+
|
||||||
|
|
||||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Connection> {
|
test_connection {
|
||||||
from_comma_delimited(raw).map(|vec| Connection(vec))
|
test_header!(test1, vec![b"close"]);
|
||||||
}
|
test_header!(test2, vec![b"keep-alive"]);
|
||||||
}
|
test_header!(test3, vec![b"upgrade"]);
|
||||||
|
|
||||||
impl HeaderFormat for Connection {
|
|
||||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let Connection(ref parts) = *self;
|
|
||||||
fmt_comma_delimited(f, &parts[..])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,9 +65,11 @@ impl Display for IfRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_range {
|
mod test_if_range {
|
||||||
|
use std::str;
|
||||||
use header::*;
|
use header::*;
|
||||||
use super::IfRange as HeaderField;
|
use super::IfRange as HeaderField;
|
||||||
test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]);
|
test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]);
|
||||||
test_header!(test2, vec![b"\"xyzzy\""]);
|
test_header!(test2, vec![b"\"xyzzy\""]);
|
||||||
|
test_header!(test3, vec![b"this-is-invalid"], None::<IfRange>);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,8 +256,6 @@ macro_rules! header {
|
|||||||
if raw.len() == 1 {
|
if raw.len() == 1 {
|
||||||
if raw[0] == b"*" {
|
if raw[0] == b"*" {
|
||||||
return Some($id::Any)
|
return Some($id::Any)
|
||||||
} else if raw[0] == b"" {
|
|
||||||
return None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$crate::header::parsing::from_comma_delimited(raw).map(|vec| $id::Items(vec))
|
$crate::header::parsing::from_comma_delimited(raw).map(|vec| $id::Items(vec))
|
||||||
|
|||||||
@@ -6,13 +6,8 @@ use std::fmt::{self, Display};
|
|||||||
// 2. in the range %x23 to %x7E, or
|
// 2. in the range %x23 to %x7E, or
|
||||||
// 3. in the range %x80 to %xFF
|
// 3. in the range %x80 to %xFF
|
||||||
fn check_slice_validity(slice: &str) -> bool {
|
fn check_slice_validity(slice: &str) -> bool {
|
||||||
for c in slice.bytes() {
|
slice.bytes().all(|c|
|
||||||
match c {
|
c == b'\x21' || (c >= b'\x23' && c <= b'\x7e') | (c >= b'\x80' && c <= b'\xff'))
|
||||||
b'\x21' | b'\x23' ... b'\x7e' | b'\x80' ... b'\xff' => (),
|
|
||||||
_ => { return false; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An entity tag, defined in [RFC7232](https://tools.ietf.org/html/rfc7232#section-2.3)
|
/// An entity tag, defined in [RFC7232](https://tools.ietf.org/html/rfc7232#section-2.3)
|
||||||
|
|||||||
@@ -83,4 +83,9 @@ mod tests {
|
|||||||
fn test_asctime() {
|
fn test_asctime() {
|
||||||
assert_eq!("Sun Nov 7 08:48:37 1994".parse(), Ok(NOV_07));
|
assert_eq!("Sun Nov 7 08:48:37 1994".parse(), Ok(NOV_07));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_date() {
|
||||||
|
assert_eq!("this-is-no-date".parse(), Err::<HttpDate, ()>(()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ impl fmt::Display for Method {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use error::Error;
|
||||||
use super::Method;
|
use super::Method;
|
||||||
use super::Method::{Get, Post, Put, Extension};
|
use super::Method::{Get, Post, Put, Extension};
|
||||||
|
|
||||||
@@ -150,6 +151,11 @@ mod tests {
|
|||||||
assert_eq!(Get, FromStr::from_str("GET").unwrap());
|
assert_eq!(Get, FromStr::from_str("GET").unwrap());
|
||||||
assert_eq!(Extension("MOVE".to_string()),
|
assert_eq!(Extension("MOVE".to_string()),
|
||||||
FromStr::from_str("MOVE").unwrap());
|
FromStr::from_str("MOVE").unwrap());
|
||||||
|
let x: Result<Method, _> = FromStr::from_str("");
|
||||||
|
if let Err(Error::Method) = x {
|
||||||
|
} else {
|
||||||
|
panic!("An empty method is invalid!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user