Fix tests for new search parsing (and reformat)

This commit is contained in:
RumovZ 2020-11-14 19:13:09 +01:00
parent 836977aac8
commit 9e53481003
2 changed files with 32 additions and 31 deletions

View File

@ -18,7 +18,6 @@ use nom::{
use regex::{Captures, Regex}; use regex::{Captures, Regex};
use std::{borrow::Cow, num}; use std::{borrow::Cow, num};
struct ParseError {} struct ParseError {}
impl From<num::ParseIntError> for ParseError { impl From<num::ParseIntError> for ParseError {
@ -221,7 +220,7 @@ fn search_node_for_text(s: &str) -> ParseResult<SearchNode> {
fn unquoted_term(s: &str) -> IResult<&str, Node> { fn unquoted_term(s: &str) -> IResult<&str, Node> {
map_res( map_res(
verify( verify(
escaped(is_not("\"() \u{3000}\\"), '\\', none_of(" \u{3000}")), escaped(is_not("\"() \u{3000}\\"), '\\', none_of(" \u{3000}")),
|s: &str| !s.is_empty(), |s: &str| !s.is_empty(),
), ),
|text: &str| -> ParseResult<Node> { |text: &str| -> ParseResult<Node> {
@ -259,7 +258,7 @@ fn partially_quoted_term(s: &str) -> IResult<&str, Node> {
map_res( map_res(
separated_pair( separated_pair(
verify( verify(
escaped(is_not("\"(): \u{3000}\\"), '\\', none_of(": \u{3000}")), escaped(is_not("\"(): \u{3000}\\"), '\\', none_of(": \u{3000}")),
|s: &str| !s.is_empty(), |s: &str| !s.is_empty(),
), ),
char(':'), char(':'),
@ -472,19 +471,17 @@ fn unescape_to_glob(txt: &str) -> ParseResult<Cow<str>> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"\\.|[*%]").unwrap(); static ref RE: Regex = Regex::new(r"\\.|[*%]").unwrap();
} }
Ok(RE.replace_all(&txt, |caps: &Captures| { Ok(RE.replace_all(&txt, |caps: &Captures| match &caps[0] {
match &caps[0] { r"\\" => r"\\",
r"\\" => r"\\", "\\\"" => "\"",
"\\\"" => "\"", r"\:" => ":",
r"\:" => ":", r"\*" => "*",
r"\*" => "*", r"\_" => r"\_",
r"\_" => r"\_", r"\(" => "(",
r"\(" => "(", r"\)" => ")",
r"\)" => ")", "*" => "%",
"*" => "%", "%" => r"\%",
"%" => r"\%", _ => unreachable!(),
_ => unreachable!(),
}
})) }))
} }
} }
@ -512,12 +509,12 @@ fn unescape_to_custom_re<'a>(txt: &'a str, wildcard: &str) -> ParseResult<Option
|caps: &Captures| { |caps: &Captures| {
let s = &caps[0]; let s = &caps[0];
match s { match s {
r"\\" | r"\*" | r"\(" | r"\)" => s.to_string(), "\\" | r"\*" | r"\(" | r"\)" => s.to_string(),
"\\\"" => "\"".to_string(), "\\\"" => "\"".to_string(),
r"\:" => ":".to_string(), r"\:" => ":".to_string(),
r"*" => format!("{}*", wildcard), "*" => format!("{}*", wildcard),
"_" => wildcard.to_string(), "_" => wildcard.to_string(),
r"\_" => r"_".to_string(), r"\_" => "_".to_string(),
s => regex::escape(s), s => regex::escape(s),
} }
}, },
@ -544,8 +541,8 @@ mod test {
#[test] #[test]
fn parsing() -> Result<()> { fn parsing() -> Result<()> {
use Node::*; use Node::*;
use SearchNode::*;
use OptionalRe::*; use OptionalRe::*;
use SearchNode::*;
assert_eq!(parse("")?, vec![Search(SearchNode::WholeCollection)]); assert_eq!(parse("")?, vec![Search(SearchNode::WholeCollection)]);
assert_eq!(parse(" ")?, vec![Search(SearchNode::WholeCollection)]); assert_eq!(parse(" ")?, vec![Search(SearchNode::WholeCollection)]);
@ -607,7 +604,7 @@ mod test {
assert_eq!( assert_eq!(
parse(r#""field:va\"lue""#)?, parse(r#""field:va\"lue""#)?,
vec![Search(SingleField { vec![Search(SingleField {
field: Text("foo".into()), field: Text("field".into()),
text: "va\"lue".into(), text: "va\"lue".into(),
is_re: false is_re: false
})] })]
@ -623,7 +620,9 @@ mod test {
assert_eq!(parse("added:3")?, vec![Search(AddedInDays(3))]); assert_eq!(parse("added:3")?, vec![Search(AddedInDays(3))]);
assert_eq!( assert_eq!(
parse("card:front")?, parse("card:front")?,
vec![Search(CardTemplate(TemplateKind::Name(Text("front".into()))))] vec![Search(CardTemplate(TemplateKind::Name(Text(
"front".into()
))))]
); );
assert_eq!( assert_eq!(
parse("card:3")?, parse("card:3")?,
@ -640,8 +639,11 @@ mod test {
vec![Search(Deck("default one".into()))] vec![Search(Deck("default one".into()))]
); );
assert_eq!(parse("note:basic")?, vec![Search(NoteType("basic".into()))]); assert_eq!(
assert_eq!(parse("tag:hard")?, vec![Search(Tag("hard".into()))]); parse("note:basic")?,
vec![Search(NoteType(Text("basic".into())))]
);
assert_eq!(parse("tag:hard")?, vec![Search(Tag(Text("hard".into())))]);
assert_eq!( assert_eq!(
parse("nid:1237123712,2,3")?, parse("nid:1237123712,2,3")?,
vec![Search(NoteIDs("1237123712,2,3".into()))] vec![Search(NoteIDs("1237123712,2,3".into()))]

View File

@ -1,7 +1,7 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use super::parser::{Node, PropertyKind, SearchNode, StateKind, OptionalRe, TemplateKind}; use super::parser::{Node, OptionalRe, PropertyKind, SearchNode, StateKind, TemplateKind};
use crate::{ use crate::{
card::{CardQueue, CardType}, card::{CardQueue, CardType},
collection::Collection, collection::Collection,
@ -597,10 +597,9 @@ mod test {
vec!["%te%st%".into()] vec!["%te%st%".into()]
) )
); );
assert_eq!(s(ctx, "te%st").1, vec!["%te%st%".to_string()]); assert_eq!(s(ctx, "te%st").1, vec![r"%te\%st%".to_string()]);
// user should be able to escape sql wildcards // user should be able to escape wildcards
assert_eq!(s(ctx, r#"te\%s\_t"#).1, vec!["%te\\%s\\_t%".to_string()]); assert_eq!(s(ctx, r#"te\*s\_t"#).1, vec!["%te*s\\_t%".to_string()]);
assert_eq!(s(ctx, r#"te\*s\_t"#).1, vec!["%te\\*s\\_t%".to_string()]);
// qualified search // qualified search
assert_eq!( assert_eq!(
@ -682,10 +681,10 @@ mod test {
// wildcards force a regexp search // wildcards force a regexp search
assert_eq!( assert_eq!(
s(ctx, r"tag:o*n\*et%w\%oth_re\_e"), s(ctx, r"tag:o*n\*et%w%oth_re\_e"),
( (
"(n.tags regexp ?)".into(), "(n.tags regexp ?)".into(),
vec![r"(?i).* o.*n\*et.*w%oth.re_e .*".into()] vec![r"(?i).* o\S*n\*et%w%oth\Sre_e .*".into()]
) )
); );
assert_eq!(s(ctx, "tag:none"), ("(n.tags = '')".into(), vec![])); assert_eq!(s(ctx, "tag:none"), ("(n.tags = '')".into(), vec![]));