diff --git a/integration/tests_ok/options.hurl b/integration/tests_ok/options.hurl new file mode 100644 index 00000000000..01b870da978 --- /dev/null +++ b/integration/tests_ok/options.hurl @@ -0,0 +1,5 @@ +GET http://localhost:8000/options/hello +[Options] +insecure: true + +HTTP/* 200 diff --git a/integration/tests_ok/options.py b/integration/tests_ok/options.py new file mode 100644 index 00000000000..d12430426f7 --- /dev/null +++ b/integration/tests_ok/options.py @@ -0,0 +1,6 @@ +from app import app + + +@app.route("/options/hello") +def options_hello(): + return "Hello!" diff --git a/packages/hurl_core/src/ast/core.rs b/packages/hurl_core/src/ast/core.rs index b7cd669f219..1ba76874785 100644 --- a/packages/hurl_core/src/ast/core.rs +++ b/packages/hurl_core/src/ast/core.rs @@ -222,7 +222,7 @@ pub enum SectionValue { Cookies(Vec), Captures(Vec), Asserts(Vec), - Options(Vec) + Options(Vec), } #[derive(Clone, Debug, PartialEq, Eq)] @@ -667,30 +667,21 @@ pub struct Variable { #[derive(Clone, Debug, PartialEq, Eq)] pub enum EntryOption { - Insecure { - name: OptionName, - value: OptionValue, - }, - CaCertificate { - name: OptionName, - value: OptionValue, - } + Insecure(InsecureOption), + CaCertificate(CaCertificateOption), } #[derive(Clone, Debug, PartialEq, Eq)] -pub struct OptionName { +pub struct InsecureOption { pub line_terminators: Vec, pub space0: Whitespace, - pub name: String, pub space1: Whitespace, + pub space2: Whitespace, + pub value: Template, + pub line_terminator0: LineTerminator, } #[derive(Clone, Debug, PartialEq, Eq)] -pub enum OptionValue { - Bool { - value: bool - }, - String { - value: String - } -} \ No newline at end of file +pub struct CaCertificateOption { + pub value: Template, +} diff --git a/packages/hurl_core/src/format/html.rs b/packages/hurl_core/src/format/html.rs index 80d2e9d7fe9..0a71b3cea19 100644 --- a/packages/hurl_core/src/format/html.rs +++ b/packages/hurl_core/src/format/html.rs @@ -233,7 +233,7 @@ impl Htmlable for KeyValue { impl Htmlable for EntryOption { fn to_html(&self) -> String { - "TODO".to_string() + "TODO".to_string() } } diff --git a/packages/hurl_core/src/parser/error.rs b/packages/hurl_core/src/parser/error.rs index 3121bffd37a..be795f1a462 100644 --- a/packages/hurl_core/src/parser/error.rs +++ b/packages/hurl_core/src/parser/error.rs @@ -60,7 +60,7 @@ pub enum ParseError { InvalidCookieAttribute, OddNumberOfHexDigits, UrlIllegalCharacter(char), - OptionName {name: String}, + InvalidOption, } impl Error { diff --git a/packages/hurl_core/src/parser/sections.rs b/packages/hurl_core/src/parser/sections.rs index 4fafc4de4a2..4d6a2dd9166 100644 --- a/packages/hurl_core/src/parser/sections.rs +++ b/packages/hurl_core/src/parser/sections.rs @@ -156,7 +156,6 @@ fn section_value_options(reader: &mut Reader) -> ParseResult<'static, SectionVal Ok(SectionValue::Options(options)) } - fn cookie(reader: &mut Reader) -> ParseResult<'static, Cookie> { // let start = reader.state.clone(); let line_terminators = optional_line_terminators(reader)?; @@ -343,36 +342,35 @@ fn assert(reader: &mut Reader) -> ParseResult<'static, Assert> { } fn option(reader: &mut Reader) -> ParseResult<'static, EntryOption> { - choice( - vec![ - option_insecure, - option_cacert, - ], - reader, - ) + choice(vec![option_insecure, option_cacert], reader) } - fn option_insecure(reader: &mut Reader) -> ParseResult<'static, EntryOption> { - let start = reader.state.clone(); - Err(Error { - pos: start.pos, - recoverable: false, - inner: ParseError::OptionName { - name: "insecure".to_string(), - }, - }) + let line_terminators = optional_line_terminators(reader)?; + let space0 = zero_or_more_spaces(reader)?; + try_literal("insecure", reader)?; + let space1 = zero_or_more_spaces(reader)?; + // Why recover? and not try_literal ? + recover(|reader1| literal(":", reader1), reader)?; + let space2 = zero_or_more_spaces(reader)?; + let value = unquoted_template(reader)?; + let line_terminator0 = line_terminator(reader)?; + + let option = InsecureOption { + line_terminators, + space0, + space1, + space2, + value, + line_terminator0, + }; + + Ok(EntryOption::Insecure(option)) } fn option_cacert(reader: &mut Reader) -> ParseResult<'static, EntryOption> { - let start = reader.state.clone(); - Err(Error { - pos: start.pos, - recoverable: false, - inner: ParseError::OptionName { - name: "cacert".to_string(), - }, - }) + try_literal("cacert", reader)?; + unimplemented!() } #[cfg(test)] @@ -517,9 +515,9 @@ mod tests { quotes: false, elements: vec![TemplateElement::String { value: "Bar".to_string(), - encoded: "Bar".to_string() + encoded: "Bar".to_string(), }], - source_info: SourceInfo::init(1, 6, 1, 9) + source_info: SourceInfo::init(1, 6, 1, 9), } ); } @@ -532,7 +530,7 @@ mod tests { error.pos, Pos { line: 1, - column: 11 + column: 11, } ); assert!(!error.recoverable); @@ -715,7 +713,7 @@ mod tests { error.pos, Pos { line: 1, - column: 32 + column: 32, } ); assert_eq!( diff --git a/packages/hurlfmt/src/format/token.rs b/packages/hurlfmt/src/format/token.rs index 46d53c7b758..94b5c074218 100644 --- a/packages/hurlfmt/src/format/token.rs +++ b/packages/hurlfmt/src/format/token.rs @@ -272,6 +272,12 @@ impl Tokenizable for SectionValue { items.iter().flat_map(|e| e.tokenize()).collect(), ); } + SectionValue::Options(items) => { + add_tokens( + &mut tokens, + items.iter().flat_map(|e| e.tokenize()).collect(), + ); + } } tokens } @@ -852,3 +858,9 @@ impl Tokenizable for JsonObjectElement { tokens } } + +impl Tokenizable for EntryOption { + fn tokenize(&self) -> Vec { + vec![] + } +} diff --git a/packages/hurlfmt/src/linter/rules.rs b/packages/hurlfmt/src/linter/rules.rs index 979e238eb34..cd7a8cce43e 100644 --- a/packages/hurlfmt/src/linter/rules.rs +++ b/packages/hurlfmt/src/linter/rules.rs @@ -185,17 +185,23 @@ impl Lintable for SectionValue { SectionValue::Cookies(cookies) => { SectionValue::Cookies(cookies.iter().map(|e| e.lint()).collect()) } + SectionValue::Options(options) => { + SectionValue::Options(options.iter().map(|e| e.lint()).collect()) + } } } } fn section_value_index(section_value: SectionValue) -> u32 { match section_value { - SectionValue::QueryParams(_) => 0, - SectionValue::BasicAuth(_) => 1, - SectionValue::FormParams(_) => 2, - SectionValue::MultipartFormData(_) => 3, - SectionValue::Cookies(_) => 3, + // Request sections + SectionValue::Options(_) => 0, + SectionValue::QueryParams(_) => 1, + SectionValue::BasicAuth(_) => 2, + SectionValue::FormParams(_) => 3, + SectionValue::MultipartFormData(_) => 4, + SectionValue::Cookies(_) => 5, + // Response sections SectionValue::Captures(_) => 0, SectionValue::Asserts(_) => 1, } @@ -525,6 +531,7 @@ impl Lintable for PredicateValue { } } } + impl Lintable for RawString { fn errors(&self) -> Vec { let errors = vec![]; @@ -801,6 +808,17 @@ impl Lintable