add wildcard for http status code

in order to ignore implict assert on status code
This commit is contained in:
Fabrice Reix 2020-11-03 20:34:12 +01:00
parent cf7a4f215d
commit 698b6dcca6
9 changed files with 88 additions and 34 deletions

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,11 @@
GET http://localhost:8000/assert-status-code
HTTP/1.0 201
# simply check that the status code is not 200
# do not run implicit assert of http response version and code
GET http://localhost:8000/assert-status-code
HTTP/* *
[Asserts]
status not equals 200

View File

View File

@ -0,0 +1,8 @@
# coding=utf-8
from tests import app
from flask import Response
@app.route("/assert-status-code")
def assert_status_code():
return Response('', status=201)

View File

@ -44,11 +44,13 @@ pub fn eval_asserts(
}); });
let status = response.clone().status; let status = response.clone().status;
if let StatusValue::Specific(v) = status.value {
asserts.push(AssertResult::Status { asserts.push(AssertResult::Status {
actual: u64::from(http_response.status), actual: http_response.status as u64,
expected: status.value as u64, expected: v as u64,
source_info: status.source_info, source_info: status.source_info,
}); });
}
for header in response.clone().headers { for header in response.clone().headers {
match eval_template(header.value.clone(), variables) { match eval_template(header.value.clone(), variables) {
@ -247,7 +249,7 @@ mod tests {
}, },
space0: whitespace.clone(), space0: whitespace.clone(),
status: Status { status: Status {
value: 200, value: StatusValue::Specific(200),
source_info: SourceInfo::init(2, 10, 2, 13), source_info: SourceInfo::init(2, 10, 2, 13),
}, },
space1: whitespace.clone(), space1: whitespace.clone(),

View File

@ -186,7 +186,7 @@ fn test_hello() {
}, },
space0: whitespace.clone(), space0: whitespace.clone(),
status: Status { status: Status {
value: 200, value: StatusValue::Specific(200),
source_info: source_info.clone(), source_info: source_info.clone(),
}, },
space1: whitespace.clone(), space1: whitespace.clone(),

View File

@ -146,12 +146,6 @@ impl Method {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Status {
pub value: u64,
pub source_info: SourceInfo,
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Version { pub struct Version {
pub value: VersionValue, pub value: VersionValue,
@ -177,6 +171,27 @@ impl VersionValue {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Status {
pub value: StatusValue,
pub source_info: SourceInfo,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum StatusValue {
Any,
Specific(u64),
}
impl fmt::Display for StatusValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StatusValue::Any => write!(f, "*"),
StatusValue::Specific(v) => write!(f, "{}", v.to_string()),
}
}
}
type Header = KeyValue; type Header = KeyValue;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -264,23 +264,25 @@ fn version(reader: &mut Reader) -> ParseResult<'static, Version> {
} }
fn status(reader: &mut Reader) -> ParseResult<'static, Status> { fn status(reader: &mut Reader) -> ParseResult<'static, Status> {
let start = reader.state.clone(); let start = reader.state.pos.clone();
match natural(reader) { let value = match try_literal("*", reader) {
Ok(value) => Ok(Status { Ok(_) => StatusValue::Any,
value, Err(_) => match natural(reader) {
source_info: SourceInfo::init( Ok(value) => StatusValue::Specific(value),
start.pos.line, Err(_) => {
start.pos.column, return Err(Error {
reader.state.pos.line, pos: start.clone(),
reader.state.pos.column,
),
}),
Err(_) => Err(Error {
pos: start.pos,
recoverable: false, recoverable: false,
inner: ParseError::Status {}, inner: ParseError::Status {},
}), })
} }
},
};
let end = reader.state.pos.clone();
Ok(Status {
value,
source_info: SourceInfo { start, end },
})
} }
fn body(reader: &mut Reader) -> ParseResult<'static, Body> { fn body(reader: &mut Reader) -> ParseResult<'static, Body> {
@ -351,7 +353,7 @@ mod tests {
let mut reader = Reader::init("GET http://google.fr\nHTTP/1.1 200"); let mut reader = Reader::init("GET http://google.fr\nHTTP/1.1 200");
let e = entry(&mut reader).unwrap(); let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method::Get); assert_eq!(e.request.method, Method::Get);
assert_eq!(e.response.unwrap().status.value, 200); assert_eq!(e.response.unwrap().status.value, StatusValue::Specific(200));
} }
#[test] #[test]
@ -560,7 +562,7 @@ mod tests {
let r = response(&mut reader).unwrap(); let r = response(&mut reader).unwrap();
assert_eq!(r.version.value, VersionValue::Version11); assert_eq!(r.version.value, VersionValue::Version11);
assert_eq!(r.status.value, 200); assert_eq!(r.status.value, StatusValue::Specific(200));
} }
#[test] #[test]
@ -715,9 +717,13 @@ mod tests {
#[test] #[test]
fn test_status() { fn test_status() {
let mut reader = Reader::init("*");
let s = status(&mut reader).unwrap();
assert_eq!(s.value, StatusValue::Any);
let mut reader = Reader::init("200"); let mut reader = Reader::init("200");
let s = status(&mut reader).unwrap(); let s = status(&mut reader).unwrap();
assert_eq!(s.value, 200); assert_eq!(s.value, StatusValue::Specific(200));
let mut reader = Reader::init("xxx"); let mut reader = Reader::init("xxx");
let result = status(&mut reader); let result = status(&mut reader);

View File

@ -124,7 +124,7 @@ impl Tokenizable for Response {
add_tokens(&mut tokens, self.space0.tokenize()); add_tokens(&mut tokens, self.space0.tokenize());
add_tokens(&mut tokens, self.version.tokenize()); add_tokens(&mut tokens, self.version.tokenize());
add_tokens(&mut tokens, self.space1.tokenize()); add_tokens(&mut tokens, self.space1.tokenize());
tokens.push(Token::Status(self.status.value.to_string())); add_tokens(&mut tokens, self.status.tokenize());
add_tokens(&mut tokens, self.line_terminator0.tokenize()); add_tokens(&mut tokens, self.line_terminator0.tokenize());
add_tokens( add_tokens(
&mut tokens, &mut tokens,
@ -141,6 +141,17 @@ impl Tokenizable for Response {
} }
} }
impl Tokenizable for Status {
fn tokenize(&self) -> Vec<Token> {
let mut tokens: Vec<Token> = vec![];
match self.value.clone() {
StatusValue::Any => tokens.push(Token::Status("*".to_string())),
StatusValue::Specific(v) => tokens.push(Token::Status(v.to_string())),
}
tokens
}
}
impl Tokenizable for Version { impl Tokenizable for Version {
fn tokenize(&self) -> Vec<Token> { fn tokenize(&self) -> Vec<Token> {
let mut tokens: Vec<Token> = vec![]; let mut tokens: Vec<Token> = vec![];